xref: /haiku/src/preferences/appearance/APRView.cpp (revision f75a7bf508f3156d63a14f8fd77c5e0ca4d08c42)
1 /*
2  * Copyright 2002-2008, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		DarkWyrm (darkwyrm@earthlink.net)
7  *		Rene Gollent (rene@gollent.com)
8  */
9 #include <OS.h>
10 #include <Directory.h>
11 #include <Alert.h>
12 #include <Messenger.h>
13 #include <storage/Path.h>
14 #include <Entry.h>
15 #include <File.h>
16 #include <stdio.h>
17 
18 #include <InterfaceDefs.h>
19 
20 #include "APRView.h"
21 #include "APRWindow.h"
22 #include "defs.h"
23 #include "ColorWell.h"
24 #include "ColorWhichItem.h"
25 #include "ColorSet.h"
26 
27 
28 #define COLOR_DROPPED 'cldp'
29 #define DECORATOR_CHANGED 'dcch'
30 
31 namespace BPrivate
32 {
33 	int32 count_decorators(void);
34 	status_t set_decorator(const int32 &index);
35 	int32 get_decorator(void);
36 	status_t get_decorator_name(const int32 &index, BString &name);
37 	status_t get_decorator_preview(const int32 &index, BBitmap *bitmap);
38 }
39 
40 APRView::APRView(const BRect &frame, const char *name, int32 resize, int32 flags)
41  :	BView(frame,name,resize,flags),
42  	fDefaultSet(ColorSet::DefaultColorSet()),
43  	fDecorMenu(NULL)
44 {
45 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
46 
47 	BRect rect(Bounds().InsetByCopy(kBorderSpace,kBorderSpace));
48 
49 	#ifdef HAIKU_TARGET_PLATFORM_HAIKU
50 
51 	fDecorMenu = new BMenu("Window Style");
52 	int32 decorCount = BPrivate::count_decorators();
53 	if (decorCount > 1) {
54 		for (int32 i = 0; i < decorCount; i++) {
55 			BString name;
56 			BPrivate::get_decorator_name(i, name);
57 			if (name.CountChars() < 1)
58 				continue;
59 			fDecorMenu->AddItem(new BMenuItem(name.String(),
60 								new BMessage(DECORATOR_CHANGED)));
61 		}
62 
63 		BMenuField *field = new BMenuField(rect, "menufield", "Window Style",
64 										fDecorMenu, B_FOLLOW_RIGHT |
65 										B_FOLLOW_TOP);
66 		AddChild(field);
67 		field->SetDivider(be_plain_font->StringWidth("Window style: ") + 5);
68 		field->ResizeToPreferred();
69 		field->MoveTo(Bounds().right - field->Bounds().Width(), 10);
70 		rect = Bounds().InsetByCopy(10,10);
71 		rect.OffsetTo(10, field->Frame().bottom + 10);
72 	}
73 	BMenuItem *marked = fDecorMenu->ItemAt(BPrivate::get_decorator());
74 	if (marked)
75 		marked->SetMarked(true);
76 	else
77 	{
78 		marked = fDecorMenu->FindItem("Default");
79 		if (marked)
80 			marked->SetMarked(true);
81 	}
82 
83 	#endif
84 
85 	// Set up list of color fAttributes
86 	rect.right -= B_V_SCROLL_BAR_WIDTH;
87 	rect.bottom = rect.top + 75;
88 	fAttrList = new BListView(rect,"AttributeList", B_SINGLE_SELECTION_LIST,
89 							B_FOLLOW_ALL_SIDES);
90 
91 	fScrollView = new BScrollView("ScrollView",fAttrList, B_FOLLOW_ALL_SIDES,
92 		0, false, true);
93 	AddChild(fScrollView);
94 	fScrollView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
95 
96 	fAttrList->SetSelectionMessage(new BMessage(ATTRIBUTE_CHOSEN));
97 
98 	for (int32 i = 0; i < color_description_count(); i++) {
99 		const ColorDescription& description = *get_color_description(i);
100 		const char* text = description.text;
101 		color_which which = description.which;
102 		fAttrList->AddItem(new ColorWhichItem(text, which));
103 	}
104 
105 	rect = fScrollView->Frame();
106 	BRect wellrect(0, 0, 50, 50);
107 	wellrect.OffsetBy(rect.left, rect.bottom + kBorderSpace);
108 	fColorWell = new ColorWell(wellrect, new BMessage(COLOR_DROPPED),
109 		B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
110 	AddChild(fColorWell);
111 
112 	fPicker = new BColorControl(BPoint(wellrect.right + kBorderSpace, wellrect.top),
113 			B_CELLS_32x8, 5.0, "fPicker", new BMessage(UPDATE_COLOR));
114 	fPicker->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
115 	AddChild(fPicker);
116 
117 	// bottom align ColorWell and ColorPicker
118 	float bottom = Bounds().bottom - kBorderSpace;
119 	float colorWellBottom = fColorWell->Frame().bottom;
120 	float pickerBottom = fPicker->Frame().bottom;
121 	float delta = bottom - max_c(colorWellBottom, pickerBottom);
122 	fColorWell->MoveBy(0, delta);
123 	fPicker->MoveBy(0, delta);
124 	fScrollView->ResizeBy(0, delta);
125 	// since this view is not attached to a window yet,
126 	// we have to resize the fScrollView children too
127 	fScrollView->ScrollBar(B_VERTICAL)->ResizeBy(0, delta);
128 	fAttrList->ResizeBy(0, delta);
129 }
130 
131 APRView::~APRView(void)
132 {
133 }
134 
135 void
136 APRView::AttachedToWindow(void)
137 {
138 	fPicker->SetTarget(this);
139 	fAttrList->SetTarget(this);
140 	fColorWell->SetTarget(this);
141 
142 	if (fDecorMenu)
143 		fDecorMenu->SetTargetForItems(BMessenger(this));
144 
145 	LoadSettings();
146 	fAttrList->Select(0);
147 }
148 
149 void
150 APRView::MessageReceived(BMessage *msg)
151 {
152 	if (msg->WasDropped()) {
153 		rgb_color *color;
154 		ssize_t size;
155 
156 		if (msg->FindData("RGBColor", (type_code)'RGBC', (const void**)&color, &size) == B_OK) {
157 			SetCurrentColor(*color);
158 		}
159 	}
160 
161 	switch(msg->what) {
162 		case DECORATOR_CHANGED: {
163 			int32 index = fDecorMenu->IndexOf(fDecorMenu->FindMarked());
164 			#ifdef HAIKU_TARGET_PLATFORM_HAIKU
165 			if (index >= 0)
166 				BPrivate::set_decorator(index);
167 			#endif
168 			break;
169 		}
170 		case UPDATE_COLOR: {
171 			// Received from the color fPicker when its color changes
172 			rgb_color color = fPicker->ValueAsColor();
173 			SetCurrentColor(color);
174 
175 			Window()->PostMessage(kMsgUpdate);
176 			break;
177 		}
178 		case ATTRIBUTE_CHOSEN: {
179 			// Received when the user chooses a GUI fAttribute from the list
180 
181 			ColorWhichItem *item = (ColorWhichItem*)
182 										fAttrList->ItemAt(fAttrList->CurrentSelection());
183 
184 			if (item == NULL)
185 				break;
186 
187 			fWhich = item->ColorWhich();
188 			rgb_color color = fCurrentSet.GetColor(fWhich);
189 			SetCurrentColor(color);
190 
191 			Window()->PostMessage(kMsgUpdate);
192 			break;
193 		}
194 		case REVERT_SETTINGS: {
195 			fCurrentSet = fPrevSet;
196 
197 			UpdateControls();
198 			UpdateAllColors();
199 
200 			Window()->PostMessage(kMsgUpdate);
201 			break;
202 		}
203 		case DEFAULT_SETTINGS: {
204 			fCurrentSet = ColorSet::DefaultColorSet();
205 
206 			UpdateControls();
207 			UpdateAllColors();
208 
209 			BMenuItem *item = fDecorMenu->FindItem("Default");
210 			if (item)
211 			{
212 				item->SetMarked(true);
213 				#ifdef HAIKU_TARGET_PLATFORM_HAIKU
214 				BPrivate::set_decorator(fDecorMenu->IndexOf(item));
215 				#endif
216 			}
217 			Window()->PostMessage(kMsgUpdate);
218 			break;
219 		}
220 		default:
221 			BView::MessageReceived(msg);
222 			break;
223 	}
224 }
225 
226 void APRView::LoadSettings(void)
227 {
228 	for (int32 i = 0; i < color_description_count(); i++) {
229 		color_which which = get_color_description(i)->which;
230 		fCurrentSet.SetColor(which, ui_color(which));
231 	}
232 
233 	fPrevSet = fCurrentSet;
234 }
235 
236 bool APRView::IsDefaultable(void)
237 {
238 	return fCurrentSet != fDefaultSet;
239 }
240 
241 void APRView::UpdateAllColors(void)
242 {
243 	for (int32 i = 0; i < color_description_count(); i++) {
244 		color_which which = get_color_description(i)->which;
245 		rgb_color color = fCurrentSet.GetColor(which);
246 		set_ui_color(which, color);
247 	}
248 }
249 
250 
251 void
252 APRView::SetCurrentColor(rgb_color color)
253 {
254 	fCurrentSet.SetColor(fWhich, color);
255 	set_ui_color(fWhich, color);
256 	UpdateControls();
257 }
258 
259 
260 void
261 APRView::UpdateControls()
262 {
263 	rgb_color color = fCurrentSet.GetColor(fWhich);
264 	fPicker->SetValue(color);
265 	fColorWell->SetColor(color);
266 	fColorWell->Invalidate();
267 }
268