git-svn-id: file:///srv/svn/repos/haiku/trunk/current@656 a95241bf-73f2-0310-859d-f6bbb57e9c96
406 lines
11 KiB
C++
406 lines
11 KiB
C++
/*
|
|
APRView.cpp: The Appearance app's color handler
|
|
|
|
Handles all the grunt work. Color settings are stored in a BMessage to
|
|
allow for easy transition to and from disk. The messy details are in the
|
|
hard-coded strings to translate the enumerated color_which defines to
|
|
strings and such, but even those should be easy to maintain.
|
|
*/
|
|
#include <OS.h>
|
|
#include "APRView.h"
|
|
#include "PortLink.h"
|
|
#include "defs.h"
|
|
#include <Directory.h>
|
|
#include <File.h>
|
|
#include <stdio.h>
|
|
|
|
void SetRGBColor(rgb_color *col,uint8 r, uint8 g, uint8 b, uint8 a=255);
|
|
void PrintRGBColor(rgb_color col);
|
|
|
|
APRView::APRView(BRect frame, const char *name, int32 resize, int32 flags)
|
|
:BView(frame,name,resize,flags)
|
|
{
|
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
|
|
// Set up list of color attributes
|
|
attrlist=new BListView(BRect(10,10,110,110),"AttributeList");
|
|
|
|
scrollview=new BScrollView("ScrollView",attrlist, B_FOLLOW_LEFT |
|
|
B_FOLLOW_TOP, 0, false, true);
|
|
AddChild(scrollview);
|
|
scrollview->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
|
|
attrlist->SetSelectionMessage(new BMessage(ATTRIBUTE_CHOSEN));
|
|
|
|
attrlist->AddItem(new BStringItem("Window Background"));
|
|
attrlist->AddItem(new BStringItem("Menu Background"));
|
|
attrlist->AddItem(new BStringItem("Selected Menu Background"));
|
|
attrlist->AddItem(new BStringItem("Menu Text"));
|
|
attrlist->AddItem(new BStringItem("Selected Menu Text"));
|
|
attrlist->AddItem(new BStringItem("Window Tab"));
|
|
attrlist->AddItem(new BStringItem("Keyboard Navigation"));
|
|
attrlist->AddItem(new BStringItem("Desktop Color"));
|
|
|
|
picker=new BColorControl(BPoint(scrollview->Frame().right+20,scrollview->Frame().top),B_CELLS_32x8,5.0,"Picker",
|
|
new BMessage(UPDATE_COLOR));
|
|
AddChild(picker);
|
|
|
|
BRect cvrect=picker->Frame();
|
|
cvrect.OffsetBy(picker->Bounds().Width()+10,0);
|
|
cvrect.right=Bounds().right-10;
|
|
|
|
colorview=new BView(cvrect,"ColorView",B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW);
|
|
colorview->SetViewColor(picker->ValueAsColor());
|
|
AddChild(colorview);
|
|
|
|
cvrect.Set(0,0,50,25);
|
|
cvrect.OffsetBy(scrollview->Frame().right+20,
|
|
scrollview->Frame().bottom-cvrect.Height());
|
|
|
|
defaults=new BButton(cvrect,"DefaultsButton","Defaults",
|
|
new BMessage(DEFAULT_SETTINGS),B_FOLLOW_LEFT |B_FOLLOW_TOP,
|
|
B_WILL_DRAW | B_NAVIGABLE);
|
|
AddChild(defaults);
|
|
|
|
cvrect.OffsetBy(70,0);
|
|
revert=new BButton(cvrect,"RevertButton","Revert",
|
|
new BMessage(REVERT_SETTINGS),B_FOLLOW_LEFT |B_FOLLOW_TOP,
|
|
B_WILL_DRAW | B_NAVIGABLE);
|
|
AddChild(revert);
|
|
// Eventually we might want to have this disabled at the start and
|
|
// enabled when the user makes changes and such. Then again, maybe we won't.
|
|
// revert->SetEnabled(false);
|
|
|
|
cvrect.OffsetBy(70,0);
|
|
try_settings=new BButton(cvrect,"TryButton","Try",
|
|
new BMessage(TRY_SETTINGS),B_FOLLOW_LEFT |B_FOLLOW_TOP,
|
|
B_WILL_DRAW | B_NAVIGABLE);
|
|
AddChild(try_settings);
|
|
|
|
// Eventually we might want to have this disabled at the start and
|
|
// enabled when the user makes changes and such. Then again, maybe we won't.
|
|
// try_settings->SetEnabled(false);
|
|
|
|
cvrect.OffsetBy(70,0);
|
|
apply=new BButton(cvrect,"ApplyButton","Apply",
|
|
new BMessage(APPLY_SETTINGS),B_FOLLOW_LEFT |B_FOLLOW_TOP,
|
|
B_WILL_DRAW | B_NAVIGABLE);
|
|
AddChild(apply);
|
|
|
|
attribute=B_PANEL_BACKGROUND_COLOR;
|
|
attrstring="PANEL_BACKGROUND";
|
|
LoadSettings();
|
|
picker->SetValue(GetColorFromMessage(&settings,attrstring.String()));
|
|
|
|
}
|
|
|
|
APRView::~APRView(void)
|
|
{
|
|
}
|
|
|
|
void APRView::AttachedToWindow(void)
|
|
{
|
|
picker->SetTarget(this);
|
|
attrlist->SetTarget(this);
|
|
apply->SetTarget(this);
|
|
defaults->SetTarget(this);
|
|
try_settings->SetTarget(this);
|
|
revert->SetTarget(this);
|
|
attrlist->Select(0);
|
|
}
|
|
|
|
void APRView::MessageReceived(BMessage *msg)
|
|
{
|
|
switch(msg->what)
|
|
{
|
|
case UPDATE_COLOR:
|
|
{
|
|
rgb_color col=picker->ValueAsColor();
|
|
|
|
colorview->SetViewColor(col);
|
|
colorview->Invalidate();
|
|
|
|
// Update current attribute here
|
|
settings.ReplaceData(attrstring.String(),(type_code)'RGBC',
|
|
&col,sizeof(rgb_color));
|
|
break;
|
|
}
|
|
case ATTRIBUTE_CHOSEN:
|
|
{
|
|
attribute=SelectionToAttribute(attrlist->CurrentSelection());
|
|
attrstring=SelectionToString(attrlist->CurrentSelection());
|
|
|
|
rgb_color col=GetColorFromMessage(&settings,attrstring.String(),0);
|
|
picker->SetValue(col);
|
|
colorview->SetViewColor(col);
|
|
colorview->Invalidate();
|
|
break;
|
|
}
|
|
case APPLY_SETTINGS:
|
|
{
|
|
SaveSettings();
|
|
NotifyServer();
|
|
break;
|
|
}
|
|
case TRY_SETTINGS:
|
|
{
|
|
// Tell server to apply settings here without saving them.
|
|
// Theoretically, the user can set this temporarily and keep it
|
|
// until the next boot.
|
|
NotifyServer();
|
|
break;
|
|
}
|
|
case REVERT_SETTINGS:
|
|
{
|
|
LoadSettings();
|
|
rgb_color col=GetColorFromMessage(&settings,attrstring.String(),0);
|
|
picker->SetValue(col);
|
|
colorview->SetViewColor(col);
|
|
colorview->Invalidate();
|
|
break;
|
|
}
|
|
case DEFAULT_SETTINGS:
|
|
{
|
|
SetDefaults();
|
|
rgb_color col=GetColorFromMessage(&settings,attrstring.String(),0);
|
|
picker->SetValue(col);
|
|
colorview->SetViewColor(col);
|
|
colorview->Invalidate();
|
|
break;
|
|
}
|
|
default:
|
|
BView::MessageReceived(msg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
color_which APRView::SelectionToAttribute(int32 index)
|
|
{
|
|
switch(index)
|
|
{
|
|
case 0:
|
|
return B_PANEL_BACKGROUND_COLOR;
|
|
break; // not necessary, but do it anyway. ;)
|
|
case 1:
|
|
return B_MENU_BACKGROUND_COLOR;
|
|
break; // not necessary, but do it anyway. ;)
|
|
case 2:
|
|
return B_MENU_SELECTION_BACKGROUND_COLOR;
|
|
break; // not necessary, but do it anyway. ;)
|
|
case 3:
|
|
return B_MENU_ITEM_TEXT_COLOR;
|
|
break; // not necessary, but do it anyway. ;)
|
|
case 4:
|
|
return B_MENU_SELECTED_ITEM_TEXT_COLOR;
|
|
break; // not necessary, but do it anyway. ;)
|
|
case 5:
|
|
return B_WINDOW_TAB_COLOR;
|
|
break; // not necessary, but do it anyway. ;)
|
|
case 6:
|
|
return B_KEYBOARD_NAVIGATION_COLOR;
|
|
break; // not necessary, but do it anyway. ;)
|
|
default:
|
|
return B_DESKTOP_COLOR;
|
|
break; // not necessary, but do it anyway. ;)
|
|
}
|
|
|
|
}
|
|
|
|
void APRView::SaveSettings(void)
|
|
{
|
|
BString path(SETTINGS_DIR);
|
|
path+="SystemColors";
|
|
printf("%s\n",path.String());
|
|
BFile file(path.String(),B_READ_WRITE|B_CREATE_FILE|B_ERASE_FILE);
|
|
|
|
settings.Flatten(&file);
|
|
}
|
|
|
|
void APRView::LoadSettings(void)
|
|
{
|
|
settings.MakeEmpty();
|
|
|
|
BDirectory dir,newdir;
|
|
if(dir.SetTo(SETTINGS_DIR)==B_ENTRY_NOT_FOUND)
|
|
create_directory(SETTINGS_DIR,0777);
|
|
|
|
BString path(SETTINGS_DIR);
|
|
path+="SystemColors";
|
|
BFile file(path.String(),B_READ_ONLY);
|
|
|
|
if(file.InitCheck()==B_OK)
|
|
{
|
|
if(settings.Unflatten(&file)==B_OK)
|
|
{
|
|
// Get the color for the current attribute here
|
|
return;
|
|
}
|
|
printf("Error unflattening settings file %s\n",path.String());
|
|
}
|
|
|
|
// If we get this far, we have encountered an error, so reset the settings
|
|
// to the defaults
|
|
SetDefaults();
|
|
}
|
|
|
|
void APRView::SetDefaults(void)
|
|
{
|
|
settings.MakeEmpty();
|
|
rgb_color col={216,216,216,255};
|
|
settings.AddData("PANEL_BACKGROUND",(type_code)'RGBC',&col,sizeof(rgb_color));
|
|
|
|
SetRGBColor(&col,219,219,219,0);
|
|
settings.AddData("MENU_BACKGROUND",(type_code)'RGBC',&col,sizeof(rgb_color));
|
|
|
|
SetRGBColor(&col,115,120,184);
|
|
settings.AddData("MENU_SELECTION_BACKGROUND",(type_code)'RGBC',&col,sizeof(rgb_color));
|
|
|
|
SetRGBColor(&col,0,0,0);
|
|
settings.AddData("MENU_ITEM_TEXT",(type_code)'RGBC',&col,sizeof(rgb_color));
|
|
|
|
SetRGBColor(&col,255,255,255);
|
|
settings.AddData("MENU_SELECTED_ITEM_TEXT",(type_code)'RGBC',&col,sizeof(rgb_color));
|
|
|
|
SetRGBColor(&col,255,203,0);
|
|
settings.AddData("WINDOW_TAB",(type_code)'RGBC',&col,sizeof(rgb_color));
|
|
|
|
SetRGBColor(&col,0,0,229);
|
|
settings.AddData("KEYBOARD_NAVIGATION",(type_code)'RGBC',&col,sizeof(rgb_color));
|
|
|
|
SetRGBColor(&col,51,102,160);
|
|
settings.AddData("DESKTOP",(type_code)'RGBC',&col,sizeof(rgb_color));
|
|
}
|
|
|
|
void APRView::NotifyServer(void)
|
|
{
|
|
// Send a message to the app_server with the settings which we have.
|
|
// While it might be worthwhile to someday have a separate protocol for
|
|
// updating just one color, for now, we just need something to get things
|
|
// done. Extract all the colors from the settings BMessage, attach them
|
|
// to a PortLink message and fire it off to the server.
|
|
|
|
// Name taken from ServerProtocol.h
|
|
port_id serverport=find_port("OBappserver");
|
|
|
|
if(serverport==B_NAME_NOT_FOUND)
|
|
return;
|
|
|
|
PortLink *pl=new PortLink(serverport);
|
|
|
|
// 'suic'==SET_UI_COLORS message from ServerProtocol.h
|
|
pl->SetOpCode('suic');
|
|
|
|
rgb_color col;
|
|
col=GetColorFromMessage(&settings,"PANEL_BACKGROUND");
|
|
pl->Attach(&col,sizeof(rgb_color));
|
|
col=GetColorFromMessage(&settings,"MENU_BACKGROUND");
|
|
pl->Attach(&col,sizeof(rgb_color));
|
|
col=GetColorFromMessage(&settings,"MENU_SELECTION_BACKGROUND");
|
|
pl->Attach(&col,sizeof(rgb_color));
|
|
col=GetColorFromMessage(&settings,"MENU_ITEM_TEXT");
|
|
pl->Attach(&col,sizeof(rgb_color));
|
|
col=GetColorFromMessage(&settings,"MENU_SELECTED_ITEM_TEXT");
|
|
pl->Attach(&col,sizeof(rgb_color));
|
|
col=GetColorFromMessage(&settings,"WINDOW_TAB");
|
|
pl->Attach(&col,sizeof(rgb_color));
|
|
col=GetColorFromMessage(&settings,"KEYBOARD_NAVIGATION");
|
|
pl->Attach(&col,sizeof(rgb_color));
|
|
col=GetColorFromMessage(&settings,"DESKTOP_COLOR");
|
|
pl->Attach(&col,sizeof(rgb_color));
|
|
|
|
pl->Flush();
|
|
delete pl;
|
|
}
|
|
|
|
rgb_color APRView::GetColorFromMessage(BMessage *msg, const char *name, int32 index=0)
|
|
{
|
|
// Simple function to do the dirty work of getting an rgb_color from
|
|
// a message
|
|
rgb_color *col,rcolor={0,0,0,0};
|
|
uint8 *ptr;
|
|
ssize_t size;
|
|
|
|
if(msg->FindData(name,(type_code)'RGBC',index,(const void**)&ptr,&size)==B_OK)
|
|
{
|
|
col=(rgb_color*)ptr;
|
|
rcolor=*col;
|
|
}
|
|
return rcolor;
|
|
}
|
|
|
|
const char *APRView::AttributeToString(color_which attr)
|
|
{
|
|
switch(attr)
|
|
{
|
|
case B_PANEL_BACKGROUND_COLOR:
|
|
return "PANEL_BACKGROUND";
|
|
break;
|
|
case B_MENU_BACKGROUND_COLOR:
|
|
return "MENU_BACKGROUND";
|
|
break;
|
|
case B_MENU_SELECTION_BACKGROUND_COLOR:
|
|
return "MENU_SELECTION_BACKGROUND";
|
|
break;
|
|
case B_MENU_ITEM_TEXT_COLOR:
|
|
return "MENU_ITEM_TEXT";
|
|
break;
|
|
case B_MENU_SELECTED_ITEM_TEXT_COLOR:
|
|
return "MENU_SELECTED_ITEM_TEXT";
|
|
break;
|
|
case B_WINDOW_TAB_COLOR:
|
|
return "WINDOW_TAB";
|
|
break;
|
|
case B_KEYBOARD_NAVIGATION_COLOR:
|
|
return "KEYBOARD_NAVIGATION";
|
|
break;
|
|
default:
|
|
return "DESKTOP_COLOR";
|
|
break;
|
|
}
|
|
}
|
|
|
|
const char *APRView::SelectionToString(int32 index)
|
|
{
|
|
switch(index)
|
|
{
|
|
case 0:
|
|
return "PANEL_BACKGROUND";
|
|
break;
|
|
case 1:
|
|
return "MENU_BACKGROUND";
|
|
break;
|
|
case 2:
|
|
return "MENU_SELECTION_BACKGROUND";
|
|
break;
|
|
case 3:
|
|
return "MENU_ITEM_TEXT";
|
|
break;
|
|
case 4:
|
|
return "MENU_SELECTED_ITEM_TEXT";
|
|
break;
|
|
case 5:
|
|
return "WINDOW_TAB";
|
|
break;
|
|
case 6:
|
|
return "KEYBOARD_NAVIGATION";
|
|
break;
|
|
default:
|
|
return "DESKTOP_COLOR";
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SetRGBColor(rgb_color *col,uint8 r, uint8 g, uint8 b, uint8 a=255)
|
|
{
|
|
col->red=r;
|
|
col->green=g;
|
|
col->blue=b;
|
|
col->alpha=a;
|
|
}
|
|
|
|
void PrintRGBColor(rgb_color col)
|
|
{
|
|
printf("RGB Color (%d,%d,%d,%d)\n",col.red,col.green,col.blue,col.alpha);
|
|
}
|
|
|