xref: /haiku/src/preferences/appearance/APRView.cpp (revision a4ef4a49150f118d47324242917a596a3f8f8bd5)
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 "APRView.h"
10 
11 #include <Alert.h>
12 #include <Directory.h>
13 #include <Entry.h>
14 #include <File.h>
15 #include <GroupLayoutBuilder.h>
16 #include <Messenger.h>
17 #include <Path.h>
18 #include <SpaceLayoutItem.h>
19 
20 #include <stdio.h>
21 
22 #include "APRWindow.h"
23 #include "defs.h"
24 #include "ColorWell.h"
25 #include "ColorWhichItem.h"
26 #include "ColorSet.h"
27 
28 
29 #define COLOR_DROPPED 'cldp'
30 #define DECORATOR_CHANGED 'dcch'
31 
32 namespace BPrivate
33 {
34 	int32 count_decorators(void);
35 	status_t set_decorator(const int32 &index);
36 	int32 get_decorator(void);
37 	status_t get_decorator_name(const int32 &index, BString &name);
38 	status_t get_decorator_preview(const int32 &index, BBitmap *bitmap);
39 }
40 
41 APRView::APRView(const char *name, uint32 flags)
42  :	BView(name, flags),
43  	fDefaultSet(ColorSet::DefaultColorSet()),
44  	fDecorMenu(NULL)
45 {
46 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
47 
48 	fDecorMenu = new BMenu("Window Style");
49 	int32 decorCount = BPrivate::count_decorators();
50 	if (decorCount > 1) {
51 		for (int32 i = 0; i < decorCount; i++) {
52 			BString name;
53 			BPrivate::get_decorator_name(i, name);
54 			if (name.CountChars() < 1)
55 				continue;
56 			fDecorMenu->AddItem(new BMenuItem(name.String(),
57 				new BMessage(DECORATOR_CHANGED)));
58 		}
59 
60 		BMenuField *field = new BMenuField("Window Style", fDecorMenu);
61 		// TODO: use this menu field.
62 	}
63 	BMenuItem *marked = fDecorMenu->ItemAt(BPrivate::get_decorator());
64 	if (marked)
65 		marked->SetMarked(true);
66 	else {
67 		marked = fDecorMenu->FindItem("Default");
68 		if (marked)
69 			marked->SetMarked(true);
70 	}
71 
72 	// Set up list of color attributes
73 	fAttrList = new BListView("AttributeList", B_SINGLE_SELECTION_LIST);
74 
75 	fScrollView = new BScrollView("ScrollView", fAttrList, 0, false, true);
76 	fScrollView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
77 
78 	for (int32 i = 0; i < color_description_count(); i++) {
79 		const ColorDescription& description = *get_color_description(i);
80 		const char* text = description.text;
81 		color_which which = description.which;
82 		fAttrList->AddItem(new ColorWhichItem(text, which));
83 	}
84 
85 	BRect wellrect(0, 0, 50, 50);
86 	fColorWell = new ColorWell(wellrect, new BMessage(COLOR_DROPPED), 0);
87 	fColorWell->SetExplicitAlignment(BAlignment(B_ALIGN_HORIZONTAL_CENTER,
88 		B_ALIGN_BOTTOM));
89 
90 	fPicker = new BColorControl(B_ORIGIN, B_CELLS_32x8, 8.0,
91 		"picker", new BMessage(UPDATE_COLOR));
92 
93 	SetLayout(new BGroupLayout(B_VERTICAL));
94 
95 	// TODO: Make list view and scroller use all the additional height
96 	// available!
97 	AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
98 		.Add(fScrollView)
99 		.Add(BSpaceLayoutItem::CreateVerticalStrut(5))
100 		.Add(BGroupLayoutBuilder(B_HORIZONTAL)
101 			.Add(fColorWell)
102 			.Add(BSpaceLayoutItem::CreateHorizontalStrut(5))
103 			.Add(fPicker)
104 		)
105 		.SetInsets(10, 10, 10, 10)
106 	);
107 
108 	fAttrList->SetSelectionMessage(new BMessage(ATTRIBUTE_CHOSEN));
109 }
110 
111 APRView::~APRView(void)
112 {
113 }
114 
115 void
116 APRView::AttachedToWindow(void)
117 {
118 	fPicker->SetTarget(this);
119 	fAttrList->SetTarget(this);
120 	fColorWell->SetTarget(this);
121 
122 	if (fDecorMenu)
123 		fDecorMenu->SetTargetForItems(BMessenger(this));
124 
125 	LoadSettings();
126 	fAttrList->Select(0);
127 }
128 
129 void
130 APRView::MessageReceived(BMessage *msg)
131 {
132 	if (msg->WasDropped()) {
133 		rgb_color *color;
134 		ssize_t size;
135 
136 		if (msg->FindData("RGBColor", (type_code)'RGBC', (const void**)&color, &size) == B_OK) {
137 			SetCurrentColor(*color);
138 		}
139 	}
140 
141 	switch(msg->what) {
142 		case DECORATOR_CHANGED: {
143 			int32 index = fDecorMenu->IndexOf(fDecorMenu->FindMarked());
144 			#ifdef HAIKU_TARGET_PLATFORM_HAIKU
145 			if (index >= 0)
146 				BPrivate::set_decorator(index);
147 			#endif
148 			break;
149 		}
150 		case UPDATE_COLOR: {
151 			// Received from the color fPicker when its color changes
152 			rgb_color color = fPicker->ValueAsColor();
153 			SetCurrentColor(color);
154 
155 			Window()->PostMessage(kMsgUpdate);
156 			break;
157 		}
158 		case ATTRIBUTE_CHOSEN: {
159 			// Received when the user chooses a GUI fAttribute from the list
160 
161 			ColorWhichItem *item = (ColorWhichItem*)
162 										fAttrList->ItemAt(fAttrList->CurrentSelection());
163 
164 			if (item == NULL)
165 				break;
166 
167 			fWhich = item->ColorWhich();
168 			rgb_color color = fCurrentSet.GetColor(fWhich);
169 			SetCurrentColor(color);
170 
171 			Window()->PostMessage(kMsgUpdate);
172 			break;
173 		}
174 		case REVERT_SETTINGS: {
175 			fCurrentSet = fPrevSet;
176 
177 			UpdateControls();
178 			UpdateAllColors();
179 
180 			Window()->PostMessage(kMsgUpdate);
181 			break;
182 		}
183 		case DEFAULT_SETTINGS: {
184 			fCurrentSet = ColorSet::DefaultColorSet();
185 
186 			UpdateControls();
187 			UpdateAllColors();
188 
189 			BMenuItem *item = fDecorMenu->FindItem("Default");
190 			if (item)
191 			{
192 				item->SetMarked(true);
193 				#ifdef HAIKU_TARGET_PLATFORM_HAIKU
194 				BPrivate::set_decorator(fDecorMenu->IndexOf(item));
195 				#endif
196 			}
197 			Window()->PostMessage(kMsgUpdate);
198 			break;
199 		}
200 		default:
201 			BView::MessageReceived(msg);
202 			break;
203 	}
204 }
205 
206 void APRView::LoadSettings(void)
207 {
208 	for (int32 i = 0; i < color_description_count(); i++) {
209 		color_which which = get_color_description(i)->which;
210 		fCurrentSet.SetColor(which, ui_color(which));
211 	}
212 
213 	fPrevSet = fCurrentSet;
214 }
215 
216 bool APRView::IsDefaultable(void)
217 {
218 	return fCurrentSet != fDefaultSet;
219 }
220 
221 void APRView::UpdateAllColors(void)
222 {
223 	for (int32 i = 0; i < color_description_count(); i++) {
224 		color_which which = get_color_description(i)->which;
225 		rgb_color color = fCurrentSet.GetColor(which);
226 		set_ui_color(which, color);
227 	}
228 }
229 
230 
231 void
232 APRView::SetCurrentColor(rgb_color color)
233 {
234 	fCurrentSet.SetColor(fWhich, color);
235 	set_ui_color(fWhich, color);
236 	UpdateControls();
237 }
238 
239 
240 void
241 APRView::UpdateControls()
242 {
243 	rgb_color color = fCurrentSet.GetColor(fWhich);
244 	fPicker->SetValue(color);
245 	fColorWell->SetColor(color);
246 	fColorWell->Invalidate();
247 }
248