xref: /haiku/src/preferences/appearance/APRView.cpp (revision 1e36cfc2721ef13a187c6f7354dc9cbc485e89d3)
1 /*
2  * Copyright 2002-2006, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		DarkWyrm (darkwyrm@earthlink.net)
7  */
8 #include <OS.h>
9 #include <Directory.h>
10 #include <Alert.h>
11 #include <Messenger.h>
12 #include <storage/Path.h>
13 #include <Entry.h>
14 #include <File.h>
15 #include <stdio.h>
16 
17 #include <InterfaceDefs.h>
18 
19 #include "APRView.h"
20 #include "defs.h"
21 #include "ColorWell.h"
22 #include "ColorWhichItem.h"
23 #include "ColorSet.h"
24 
25 //#define DEBUG_APRVIEW
26 
27 #ifdef DEBUG_APRVIEW
28 	#define STRACE(a) printf a
29 #else
30 	#define STRACE(A) /* nothing */
31 #endif
32 
33 #define COLOR_DROPPED 'cldp'
34 #define DECORATOR_CHANGED 'dcch'
35 
36 namespace BPrivate
37 {
38 	int32 count_decorators(void);
39 	status_t set_decorator(const int32 &index);
40 	int32 get_decorator(void);
41 	status_t get_decorator_name(const int32 &index, BString &name);
42 	status_t get_decorator_preview(const int32 &index, BBitmap *bitmap);
43 }
44 
45 APRView::APRView(const BRect &frame, const char *name, int32 resize, int32 flags)
46  :	BView(frame,name,resize,flags),
47  	fDecorMenu(NULL)
48 {
49 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
50 
51 	BRect rect(Bounds().InsetByCopy(10,10));
52 
53 	#ifdef HAIKU_TARGET_PLATFORM_HAIKU
54 
55 	fDecorMenu = new BMenu("Window Style");
56 	int32 decorCount = BPrivate::count_decorators();
57 	if (decorCount > 1) {
58 		for (int32 i = 0; i < decorCount; i++) {
59 			BString name;
60 			BPrivate::get_decorator_name(i, name);
61 			if (name.CountChars() < 1)
62 				continue;
63 			fDecorMenu->AddItem(new BMenuItem(name.String(),
64 								new BMessage(DECORATOR_CHANGED)));
65 		}
66 
67 		BMenuField *field = new BMenuField(rect, "menufield", "Window Style",
68 										fDecorMenu, B_FOLLOW_RIGHT |
69 										B_FOLLOW_TOP);
70 		AddChild(field);
71 		field->SetDivider(be_plain_font->StringWidth("Window style: ") + 5);
72 		field->ResizeToPreferred();
73 		field->MoveTo(Bounds().right - field->Bounds().Width(), 10);
74 		rect = Bounds().InsetByCopy(10,10);
75 		rect.OffsetTo(10, field->Frame().bottom + 10);
76 	}
77 	BMenuItem *marked = fDecorMenu->ItemAt(BPrivate::get_decorator());
78 	if (marked)
79 		marked->SetMarked(true);
80 	else
81 	{
82 		marked = fDecorMenu->FindItem("Default");
83 		if (marked)
84 			marked->SetMarked(true);
85 	}
86 
87 	#endif
88 
89 	// Set up list of color fAttributes
90 	rect.right -= B_V_SCROLL_BAR_WIDTH;
91 	rect.bottom = rect.top + 75;
92 	fAttrList = new BListView(rect,"AttributeList", B_SINGLE_SELECTION_LIST,
93 							B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
94 
95 	fScrollView = new BScrollView("ScrollView",fAttrList, B_FOLLOW_LEFT_RIGHT |
96 									B_FOLLOW_TOP, 0, false, true);
97 	AddChild(fScrollView);
98 	fScrollView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
99 
100 	fAttrList->SetSelectionMessage(new BMessage(ATTRIBUTE_CHOSEN));
101 
102 	fAttrList->AddItem(new ColorWhichItem(B_PANEL_BACKGROUND_COLOR));
103 	fAttrList->AddItem(new ColorWhichItem((color_which)B_PANEL_TEXT_COLOR));
104 	fAttrList->AddItem(new ColorWhichItem((color_which)B_DOCUMENT_BACKGROUND_COLOR));
105 	fAttrList->AddItem(new ColorWhichItem((color_which)B_DOCUMENT_TEXT_COLOR));
106 	fAttrList->AddItem(new ColorWhichItem((color_which)B_CONTROL_BACKGROUND_COLOR));
107 	fAttrList->AddItem(new ColorWhichItem((color_which)B_CONTROL_TEXT_COLOR));
108 	fAttrList->AddItem(new ColorWhichItem((color_which)B_CONTROL_BORDER_COLOR));
109 	fAttrList->AddItem(new ColorWhichItem((color_which)B_CONTROL_HIGHLIGHT_COLOR));
110 	fAttrList->AddItem(new ColorWhichItem((color_which)B_NAVIGATION_BASE_COLOR));
111 	fAttrList->AddItem(new ColorWhichItem((color_which)B_NAVIGATION_PULSE_COLOR));
112 	fAttrList->AddItem(new ColorWhichItem((color_which)B_SHINE_COLOR));
113 	fAttrList->AddItem(new ColorWhichItem((color_which)B_SHADOW_COLOR));
114 	fAttrList->AddItem(new ColorWhichItem(B_MENU_BACKGROUND_COLOR));
115 	fAttrList->AddItem(new ColorWhichItem((color_which)B_MENU_SELECTED_BACKGROUND_COLOR));
116 	fAttrList->AddItem(new ColorWhichItem(B_MENU_ITEM_TEXT_COLOR));
117 	fAttrList->AddItem(new ColorWhichItem(B_MENU_SELECTED_ITEM_TEXT_COLOR));
118 	fAttrList->AddItem(new ColorWhichItem((color_which)B_MENU_SELECTED_BORDER_COLOR));
119 	fAttrList->AddItem(new ColorWhichItem((color_which)B_TOOLTIP_BACKGROUND_COLOR));
120 
121 	fAttrList->AddItem(new ColorWhichItem((color_which)B_SUCCESS_COLOR));
122 	fAttrList->AddItem(new ColorWhichItem((color_which)B_FAILURE_COLOR));
123 	fAttrList->AddItem(new ColorWhichItem(B_WINDOW_TAB_COLOR));
124 	fAttrList->AddItem(new ColorWhichItem((color_which)B_WINDOW_TAB_TEXT_COLOR));
125 	fAttrList->AddItem(new ColorWhichItem((color_which)B_INACTIVE_WINDOW_TAB_COLOR));
126 	fAttrList->AddItem(new ColorWhichItem((color_which)B_INACTIVE_WINDOW_TAB_TEXT_COLOR));
127 
128 
129 	BRect wellrect(0,0,50,50);
130 	wellrect.OffsetTo(rect.right + 30, rect.top +
131 					(fScrollView->Bounds().Height() - wellrect.Height())/2 );
132 
133 	fColorWell = new ColorWell(wellrect,new BMessage(COLOR_DROPPED),true);
134 	AddChild(fColorWell);
135 
136 	// Center the list and color well
137 
138 	rect = fScrollView->Frame();
139 	rect.right = wellrect.right;
140 	rect.OffsetTo((Bounds().Width()-rect.Width())/2,rect.top);
141 
142 	fPicker = new BColorControl(BPoint(10,fScrollView->Frame().bottom+20),B_CELLS_32x8,5.0,"fPicker",
143 								new BMessage(UPDATE_COLOR));
144 	AddChild(fPicker);
145 
146 	fDefaults = new BButton(BRect(0,0,1,1),"DefaultsButton","Defaults",
147 							new BMessage(DEFAULT_SETTINGS),
148 							B_FOLLOW_LEFT |B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE);
149 	fDefaults->ResizeToPreferred();
150 	fDefaults->MoveTo((fPicker->Frame().right-(fDefaults->Frame().Width()*2)-20)/2,fPicker->Frame().bottom+20);
151 	AddChild(fDefaults);
152 
153 
154 	BRect cvrect(fDefaults->Frame());
155 	cvrect.OffsetBy(cvrect.Width() + 20,0);
156 
157 	fRevert = new BButton(cvrect,"RevertButton","Revert",
158 						new BMessage(REVERT_SETTINGS),
159 						B_FOLLOW_LEFT |B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE);
160 	AddChild(fRevert);
161 	fRevert->SetEnabled(false);
162 
163 }
164 
165 APRView::~APRView(void)
166 {
167 	ColorSet::SaveColorSet("/boot/home/config/settings/app_server/system_colors",fCurrentSet);
168 }
169 
170 void
171 APRView::AttachedToWindow(void)
172 {
173 	fPicker->SetTarget(this);
174 	fAttrList->SetTarget(this);
175 	fDefaults->SetTarget(this);
176 	fRevert->SetTarget(this);
177 	fColorWell->SetTarget(this);
178 
179 	fPicker->SetValue(fCurrentSet.StringToColor(fAttrString.String()));
180 
181 	if (fDecorMenu)
182 		fDecorMenu->SetTargetForItems(BMessenger(this));
183 
184 	Window()->ResizeTo(MAX(fPicker->Frame().right,fPicker->Frame().right) + 10,
185 					   fDefaults->Frame().bottom + 10);
186 	LoadSettings();
187 	fAttrList->Select(0);
188 }
189 
190 void
191 APRView::MessageReceived(BMessage *msg)
192 {
193 	if (msg->WasDropped()) {
194 		rgb_color *col;
195 		ssize_t size;
196 
197 		if (msg->FindData("RGBColor",(type_code)'RGBC',(const void**)&col,&size)==B_OK) {
198 			fPicker->SetValue(*col);
199 			fColorWell->SetColor(*col);
200 			fColorWell->Invalidate();
201 		}
202 	}
203 
204 	switch(msg->what) {
205 		case DECORATOR_CHANGED: {
206 			int32 index = fDecorMenu->IndexOf(fDecorMenu->FindMarked());
207 			#ifdef HAIKU_TARGET_PLATFORM_HAIKU
208 			if (index >= 0)
209 				BPrivate::set_decorator(index);
210 			#endif
211 			break;
212 		}
213 		case UPDATE_COLOR: {
214 			// Received from the color fPicker when its color changes
215 
216 			rgb_color col=fPicker->ValueAsColor();
217 
218 			fColorWell->SetColor(col);
219 			fColorWell->Invalidate();
220 
221 			// Update current fAttribute in the settings
222 			fCurrentSet.SetColor(fAttrString.String(),col);
223 
224 			fRevert->SetEnabled(true);
225 
226 			break;
227 		}
228 		case ATTRIBUTE_CHOSEN: {
229 			// Received when the user chooses a GUI fAttribute from the list
230 
231 			ColorWhichItem *whichitem = (ColorWhichItem*)
232 										fAttrList->ItemAt(fAttrList->CurrentSelection());
233 
234 			if (!whichitem)
235 				break;
236 
237 			fAttrString=whichitem->Text();
238 			UpdateControlsFromAttr(whichitem->Text());
239 			break;
240 		}
241 		case REVERT_SETTINGS: {
242 			fCurrentSet=fPrevSet;
243 			UpdateControlsFromAttr(fAttrString.String());
244 
245 			fRevert->SetEnabled(false);
246 
247 			break;
248 		}
249 		case DEFAULT_SETTINGS: {
250 			fCurrentSet.SetToDefaults();
251 
252 			UpdateControlsFromAttr(fAttrString.String());
253 			BMenuItem *item = fDecorMenu->FindItem("Default");
254 			if (item)
255 			{
256 				item->SetMarked(true);
257 				#ifdef HAIKU_TARGET_PLATFORM_HAIKU
258 				BPrivate::set_decorator(fDecorMenu->IndexOf(item));
259 				#endif
260 			}
261 			break;
262 		}
263 		default:
264 			BView::MessageReceived(msg);
265 			break;
266 	}
267 }
268 
269 void APRView::LoadSettings(void)
270 {
271 	// Load the current GUI color settings from disk. This is done instead of
272 	// getting them from the server at this point for testing purposes.
273 
274 	// Query the server for the current settings
275 	//BPrivate::get_system_colors(&fCurrentSet);
276 
277 	// TODO: remove this and enable the get_system_colors() call
278 	if (ColorSet::LoadColorSet("/boot/home/config/settings/app_server/system_colors",&fCurrentSet) != B_OK) {
279 		fCurrentSet.SetToDefaults();
280 		ColorSet::SaveColorSet("/boot/home/config/settings/app_server/system_colors",fCurrentSet);
281 	}
282 
283 	fPrevSet = fCurrentSet;
284 }
285 
286 void APRView::UpdateControlsFromAttr(const char *string)
287 {
288 	if (!string)
289 		return;
290 	STRACE(("Update color for %s\n",string));
291 
292 	fPicker->SetValue(fCurrentSet.StringToColor(string));
293 	fColorWell->SetColor(fPicker->ValueAsColor());
294 	fColorWell->Invalidate();
295 }
296