xref: /haiku/src/preferences/appearance/LookAndFeelSettingsView.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
1 /*
2  *  Copyright 2010-2012 Haiku, Inc. All rights reserved.
3  *  Distributed under the terms of the MIT license.
4  *
5  *	Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  *		Alexander von Gluck <kallisti5@unixzen.com>
8  *		John Scipione <jscipione@gmail.com>
9  *		Ryan Leavengood <leavengood@gmail.com>
10  */
11 
12 
13 #include "LookAndFeelSettingsView.h"
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 
18 #include <Alert.h>
19 #include <Alignment.h>
20 #include <Box.h>
21 #include <Button.h>
22 #include <Catalog.h>
23 #include <CheckBox.h>
24 #include <InterfaceDefs.h>
25 #include <LayoutBuilder.h>
26 #include <Locale.h>
27 #include <MenuField.h>
28 #include <MenuItem.h>
29 #include <PopUpMenu.h>
30 #include <ScrollBar.h>
31 #include <StringView.h>
32 #include <Size.h>
33 #include <Slider.h>
34 #include <SpaceLayoutItem.h>
35 #include <StringView.h>
36 #include <TextView.h>
37 
38 #include "APRWindow.h"
39 #include "FakeScrollBar.h"
40 
41 
42 #undef B_TRANSLATION_CONTEXT
43 #define B_TRANSLATION_CONTEXT "DecorSettingsView"
44 	// This was not renamed to keep from breaking translations
45 
46 
47 static const int32 kMsgSetDecor = 'deco';
48 static const int32 kMsgDecorInfo = 'idec';
49 
50 static const int32 kMsgDoubleScrollBarArrows = 'dsba';
51 
52 static const int32 kMsgArrowStyleSingle = 'mass';
53 static const int32 kMsgArrowStyleDouble = 'masd';
54 
55 static const int32 kMsgKnobStyleNone = 'mksn';
56 static const int32 kMsgKnobStyleDots = 'mksd';
57 static const int32 kMsgKnobStyleLines = 'mksl';
58 
59 static const bool kDefaultDoubleScrollBarArrowsSetting = false;
60 
61 
62 //	#pragma mark -
63 
64 
65 LookAndFeelSettingsView::LookAndFeelSettingsView(const char* name)
66 	:
67 	BView(name, 0),
68 	fDecorInfoButton(NULL),
69 	fDecorMenuField(NULL),
70 	fDecorMenu(NULL)
71 {
72 	// Decorator menu
73 	_BuildDecorMenu();
74 	fDecorMenuField = new BMenuField("decorator",
75 		B_TRANSLATE("Decorator:"), fDecorMenu);
76 
77 	fDecorInfoButton = new BButton(B_TRANSLATE("About"),
78 		new BMessage(kMsgDecorInfo));
79 
80 	// scroll bar arrow style
81 	BBox* arrowStyleBox = new BBox("arrow style");
82 	arrowStyleBox->SetLabel(B_TRANSLATE("Arrow style"));
83 
84 	fSavedDoubleArrowsValue = _DoubleScrollBarArrows();
85 
86 	fArrowStyleSingle = new FakeScrollBar(true, false,
87 		new BMessage(kMsgArrowStyleSingle));
88 	fArrowStyleDouble = new FakeScrollBar(true, true,
89 		new BMessage(kMsgArrowStyleDouble));
90 
91 	BView* arrowStyleView;
92 	arrowStyleView = BLayoutBuilder::Group<>()
93 		.AddGroup(B_VERTICAL, 1)
94 			.Add(new BStringView("single", B_TRANSLATE("Single:")))
95 			.Add(fArrowStyleSingle)
96 			.AddStrut(B_USE_DEFAULT_SPACING)
97 			.Add(new BStringView("double", B_TRANSLATE("Double:")))
98 			.Add(fArrowStyleDouble)
99 			.SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING,
100 				B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
101 			.End()
102 		.View();
103 	arrowStyleBox->AddChild(arrowStyleView);
104 	arrowStyleBox->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT,
105 		B_ALIGN_VERTICAL_CENTER));
106 	arrowStyleBox->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
107 
108 	BStringView* scrollBarLabel
109 		= new BStringView("scroll bar", B_TRANSLATE("Scroll bar:"));
110 	scrollBarLabel->SetExplicitAlignment(
111 		BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP));
112 
113 	// control layout
114 	BLayoutBuilder::Grid<>(this, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
115 		.Add(fDecorMenuField->CreateLabelLayoutItem(), 0, 0)
116 		.Add(fDecorMenuField->CreateMenuBarLayoutItem(), 1, 0)
117 		.Add(fDecorInfoButton, 2, 0)
118 		.Add(scrollBarLabel, 0, 1)
119 		.Add(arrowStyleBox, 1, 1)
120 		.AddGlue(0, 2)
121 		.SetInsets(B_USE_WINDOW_SPACING);
122 
123 	// TODO : Decorator Preview Image?
124 }
125 
126 
127 LookAndFeelSettingsView::~LookAndFeelSettingsView()
128 {
129 }
130 
131 
132 void
133 LookAndFeelSettingsView::AttachedToWindow()
134 {
135 	AdoptParentColors();
136 
137 	if (Parent() == NULL)
138 		SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
139 
140 	fDecorMenu->SetTargetForItems(this);
141 	fDecorInfoButton->SetTarget(this);
142 	fArrowStyleSingle->SetTarget(this);
143 	fArrowStyleDouble->SetTarget(this);
144 
145 	if (fSavedDoubleArrowsValue)
146 		fArrowStyleDouble->SetValue(B_CONTROL_ON);
147 	else
148 		fArrowStyleSingle->SetValue(B_CONTROL_ON);
149 }
150 
151 
152 void
153 LookAndFeelSettingsView::MessageReceived(BMessage *msg)
154 {
155 	switch (msg->what) {
156 		case kMsgSetDecor:
157 		{
158 			BString newDecor;
159 			if (msg->FindString("decor", &newDecor) == B_OK)
160 				_SetDecor(newDecor);
161 			break;
162 		}
163 
164 		case kMsgDecorInfo:
165 		{
166 			DecorInfo* decor = fDecorUtility.FindDecorator(fCurrentDecor);
167 			if (decor == NULL)
168 				break;
169 
170 			BString authorsText(decor->Authors().String());
171 			authorsText.ReplaceAll(", ", "\n\t");
172 
173 			BString infoText(B_TRANSLATE("%decorName\n\n"
174 				"Authors:\n\t%decorAuthors\n\n"
175 				"URL: %decorURL\n"
176 				"License: %decorLic\n\n"
177 				"%decorDesc\n"));
178 
179 
180 			infoText.ReplaceFirst("%decorName", decor->Name().String());
181 			infoText.ReplaceFirst("%decorAuthors", authorsText.String());
182 			infoText.ReplaceFirst("%decorLic", decor->LicenseName().String());
183 			infoText.ReplaceFirst("%decorURL", decor->SupportURL().String());
184 			infoText.ReplaceFirst("%decorDesc", decor->ShortDescription().String());
185 
186 			BAlert *infoAlert = new BAlert(B_TRANSLATE("About decorator"),
187 				infoText.String(), B_TRANSLATE("OK"));
188 			infoAlert->SetFlags(infoAlert->Flags() | B_CLOSE_ON_ESCAPE);
189 			infoAlert->Go();
190 
191 			break;
192 		}
193 
194 		case kMsgArrowStyleSingle:
195 			_SetDoubleScrollBarArrows(false);
196 			break;
197 
198 		case kMsgArrowStyleDouble:
199 			_SetDoubleScrollBarArrows(true);
200 			break;
201 
202 		default:
203 			BView::MessageReceived(msg);
204 			break;
205 	}
206 }
207 
208 
209 void
210 LookAndFeelSettingsView::_BuildDecorMenu()
211 {
212 	fDecorMenu = new BPopUpMenu(B_TRANSLATE("Choose Decorator"));
213 
214 	// collect the current system decor settings
215 	int32 count = fDecorUtility.CountDecorators();
216 	for (int32 i = 0; i < count; ++i) {
217 		DecorInfo* decorator = fDecorUtility.DecoratorAt(i);
218 		if (decorator == NULL) {
219 			fprintf(stderr, "Decorator : error NULL entry @ %" B_PRId32
220 				" / %" B_PRId32 "\n", i, count);
221 			continue;
222 		}
223 
224 		BString decorName = decorator->Name();
225 
226 		BMessage* message = new BMessage(kMsgSetDecor);
227 		message->AddString("decor", decorName);
228 
229 		BMenuItem* item = new BMenuItem(decorName, message);
230 
231 		fDecorMenu->AddItem(item);
232 	}
233 
234 	_AdoptToCurrentDecor();
235 }
236 
237 
238 void
239 LookAndFeelSettingsView::_SetDecor(const BString& name)
240 {
241 	_SetDecor(fDecorUtility.FindDecorator(name));
242 }
243 
244 
245 void
246 LookAndFeelSettingsView::_SetDecor(DecorInfo* decorInfo)
247 {
248 	if (fDecorUtility.SetDecorator(decorInfo) == B_OK) {
249 		_AdoptToCurrentDecor();
250 		Window()->PostMessage(kMsgUpdate);
251 	}
252 }
253 
254 
255 void
256 LookAndFeelSettingsView::_AdoptToCurrentDecor()
257 {
258 	fCurrentDecor = fDecorUtility.CurrentDecorator()->Name();
259 	if (fSavedDecor.Length() == 0)
260 		fSavedDecor = fCurrentDecor;
261 	_AdoptInterfaceToCurrentDecor();
262 }
263 
264 void
265 LookAndFeelSettingsView::_AdoptInterfaceToCurrentDecor()
266 {
267 	BMenuItem* item = fDecorMenu->FindItem(fCurrentDecor);
268 	if (item != NULL)
269 		item->SetMarked(true);
270 }
271 
272 
273 bool
274 LookAndFeelSettingsView::_DoubleScrollBarArrows()
275 {
276 	scroll_bar_info info;
277 	get_scroll_bar_info(&info);
278 
279 	return info.double_arrows;
280 }
281 
282 
283 void
284 LookAndFeelSettingsView::_SetDoubleScrollBarArrows(bool doubleArrows)
285 {
286 	scroll_bar_info info;
287 	get_scroll_bar_info(&info);
288 
289 	info.double_arrows = doubleArrows;
290 	set_scroll_bar_info(&info);
291 
292 	if (doubleArrows)
293 		fArrowStyleDouble->SetValue(B_CONTROL_ON);
294 	else
295 		fArrowStyleSingle->SetValue(B_CONTROL_ON);
296 
297 	Window()->PostMessage(kMsgUpdate);
298 }
299 
300 
301 bool
302 LookAndFeelSettingsView::IsDefaultable()
303 {
304 	return fCurrentDecor != fDecorUtility.DefaultDecorator()->Name()
305 		|| _DoubleScrollBarArrows() != false;
306 }
307 
308 
309 void
310 LookAndFeelSettingsView::SetDefaults()
311 {
312 	_SetDecor(fDecorUtility.DefaultDecorator());
313 	_SetDoubleScrollBarArrows(false);
314 }
315 
316 
317 bool
318 LookAndFeelSettingsView::IsRevertable()
319 {
320 	return fCurrentDecor != fSavedDecor
321 		|| _DoubleScrollBarArrows() != fSavedDoubleArrowsValue;
322 }
323 
324 
325 void
326 LookAndFeelSettingsView::Revert()
327 {
328 	if (IsRevertable()) {
329 		_SetDecor(fSavedDecor);
330 		_SetDoubleScrollBarArrows(fSavedDoubleArrowsValue);
331 	}
332 }
333