1/*
2 * Copyright 2002-2009, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT license.
4 *
5 * Copyright 1999, Be Incorporated. All Rights Reserved.
6 * This file may be used under the terms of the Be Sample Code License.
7 *
8 * Written by:	Daniel Switkin
9 */
10
11
12#include "ConfigView.h"
13#include "Common.h"
14#include "PulseApp.h"
15#include "PrefsWindow.h"
16
17#include <Catalog.h>
18#include <CheckBox.h>
19#include <RadioButton.h>
20#include <TextControl.h>
21
22#include <ctype.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26
27#undef B_TRANSLATION_CONTEXT
28#define B_TRANSLATION_CONTEXT "ConfigView"
29
30
31RTColorControl::RTColorControl(BPoint point, BMessage *message)
32	: BColorControl(point, B_CELLS_32x8, 6, "ColorControl", message, false)
33{
34}
35
36
37/*!
38	Send a message every time the color changes, not just
39	when the mouse button is released
40*/
41void
42RTColorControl::SetValue(int32 color)
43{
44	BColorControl::SetValue(color);
45	Invoke();
46}
47
48
49//	#pragma mark -
50
51
52/*!
53	A single class for all three prefs views, needs to be
54	customized below to give each control the right message
55*/
56ConfigView::ConfigView(BRect rect, const char *name, uint32 mode, BMessenger& target,
57		Prefs *prefs)
58	: BBox(rect, name, B_FOLLOW_NONE, B_WILL_DRAW),
59	fMode(mode),
60	fTarget(target),
61	fPrefs(prefs),
62	fFirstTimeAttached(true)
63{
64	fFadeCheckBox = NULL;
65	fActiveButton = fIdleButton = fFrameButton = NULL;
66	fIconWidthControl = NULL;
67
68	SetLabel(B_TRANSLATE("Bar colors"));
69
70	font_height fontHeight;
71	be_bold_font->GetHeight(&fontHeight);
72
73	fColorControl = new RTColorControl(BPoint(10, 5.0f + fontHeight.ascent
74		+ fontHeight.descent), new BMessage(fMode));
75	fColorControl->ResizeToPreferred();
76	AddChild(fColorControl);
77
78	rect = fColorControl->Frame();
79	rect.top = rect.bottom + 10.0f;
80	rect.bottom = rect.top + 15.0f;
81
82	if (mode == PRV_NORMAL_CHANGE_COLOR) {
83		// normal mode
84
85		fFadeCheckBox = new BCheckBox(rect, "FadeColors",
86			B_TRANSLATE("Fade colors"), new BMessage(PRV_NORMAL_FADE_COLORS));
87		fFadeCheckBox->ResizeToPreferred();
88		AddChild(fFadeCheckBox);
89
90		fColorControl->SetValue(fPrefs->normal_bar_color);
91		fFadeCheckBox->SetValue(fPrefs->normal_fade_colors);
92	} else if (mode == PRV_MINI_CHANGE_COLOR) {
93		// mini mode
94
95		fActiveButton = new BRadioButton(rect, "ActiveColor",
96			B_TRANSLATE("Active color"), new BMessage(PRV_MINI_ACTIVE));
97		fActiveButton->ResizeToPreferred();
98		fActiveButton->SetValue(B_CONTROL_ON);
99		AddChild(fActiveButton);
100
101		rect.left = fActiveButton->Frame().right + 5.0f;
102		fIdleButton = new BRadioButton(rect, "IdleColor",
103			B_TRANSLATE("Idle color"), new BMessage(PRV_MINI_IDLE));
104		fIdleButton->ResizeToPreferred();
105		AddChild(fIdleButton);
106
107		rect.left = fIdleButton->Frame().right + 5.0f;
108		fFrameButton = new BRadioButton(rect, "FrameColor",
109			B_TRANSLATE("Frame color"),	new BMessage(PRV_MINI_FRAME));
110		fFrameButton->ResizeToPreferred();
111		AddChild(fFrameButton);
112
113		fColorControl->SetValue(fPrefs->mini_active_color);
114	} else {
115		// deskbar mode
116		fActiveButton = new BRadioButton(rect, "ActiveColor",
117			B_TRANSLATE("Active color"), new BMessage(PRV_DESKBAR_ACTIVE));
118		fActiveButton->ResizeToPreferred();
119		fActiveButton->SetValue(B_CONTROL_ON);
120		AddChild(fActiveButton);
121
122		rect.left = fActiveButton->Frame().right + 5.0f;
123		fIdleButton = new BRadioButton(rect, "IdleColor",
124			B_TRANSLATE("Idle color"), new BMessage(PRV_DESKBAR_IDLE));
125		fIdleButton->ResizeToPreferred();
126		AddChild(fIdleButton);
127
128		rect.left = fIdleButton->Frame().right + 5.0f;
129		fFrameButton = new BRadioButton(rect, "FrameColor",
130			B_TRANSLATE("Frame color"),	new BMessage(PRV_DESKBAR_FRAME));
131		fFrameButton->ResizeToPreferred();
132		AddChild(fFrameButton);
133
134		rect.left = fColorControl->Frame().left;
135		rect.top = fActiveButton->Frame().bottom + 5.0f;
136
137		char temp[10];
138		snprintf(temp, sizeof(temp), "%d", fPrefs->deskbar_icon_width);
139		fIconWidthControl = new BTextControl(rect, "Width",
140			B_TRANSLATE("Width of icon:"), temp,
141			new BMessage(PRV_DESKBAR_ICON_WIDTH));
142		AddChild(fIconWidthControl);
143		fIconWidthControl->SetDivider(be_plain_font->StringWidth(
144			fIconWidthControl->Label()) + 5.0f);
145
146		for (int c = 0; c < 256; c++) {
147			if (!isdigit(c))
148				fIconWidthControl->TextView()->DisallowChar(c);
149		}
150		fIconWidthControl->TextView()->SetMaxBytes(2);
151
152		float width, height;
153		fIconWidthControl->GetPreferredSize(&width, &height);
154		fIconWidthControl->ResizeTo(fIconWidthControl->Divider() + 32.0f
155			+ fIconWidthControl->StringWidth("999"), height);
156
157		fColorControl->SetValue(fPrefs->deskbar_active_color);
158	}
159}
160
161
162void
163ConfigView::GetPreferredSize(float* _width, float* _height)
164{
165	float right, bottom;
166
167	if (fMode == PRV_NORMAL_CHANGE_COLOR) {
168		// normal mode
169		bottom = fFadeCheckBox->Frame().bottom;
170		right = fFadeCheckBox->Frame().right;
171	} else if (fMode == PRV_MINI_CHANGE_COLOR) {
172		// mini mode
173		bottom = fIdleButton->Frame().bottom;
174		right = fFrameButton->Frame().right;
175	} else {
176		// deskbar mode
177		bottom = fIconWidthControl->Frame().bottom;
178		right = fFrameButton->Frame().right;
179	}
180
181	if (right < fColorControl->Frame().right)
182		right = fColorControl->Frame().right;
183	if (right < 300)
184		right = 300;
185
186	if (_width)
187		*_width = right + 10.0f;
188	if (_height)
189		*_height = bottom + 8.0f;
190}
191
192
193void
194ConfigView::AttachedToWindow()
195{
196	BView::AttachedToWindow();
197
198	// AttachedToWindow() gets called every time this tab is brought
199	// to the front, but we only want this initialization to happen once
200	if (fFirstTimeAttached) {
201		AdoptParentColors();
202
203		if (Parent() == NULL)
204			SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
205
206		BMessenger messenger(this);
207		fColorControl->SetTarget(messenger);
208		if (fFadeCheckBox != NULL)
209			fFadeCheckBox->SetTarget(messenger);
210		if (fActiveButton != NULL)
211			fActiveButton->SetTarget(messenger);
212		if (fIdleButton != NULL)
213			fIdleButton->SetTarget(messenger);
214		if (fFrameButton != NULL)
215			fFrameButton->SetTarget(messenger);
216		if (fIconWidthControl != NULL)
217			fIconWidthControl->SetTarget(messenger);
218
219		fFirstTimeAttached = false;
220	}
221}
222
223
224void
225ConfigView::MessageReceived(BMessage *message)
226{
227	switch (message->what) {
228		// These two send the color and the status of the fade checkbox together
229		case PRV_NORMAL_FADE_COLORS:
230		case PRV_NORMAL_CHANGE_COLOR:
231		{
232			bool fade_colors = (bool)fFadeCheckBox->Value();
233			int32 bar_color = fColorControl->Value();
234			message->AddInt32("color", bar_color);
235			message->AddBool("fade", fade_colors);
236			fPrefs->normal_fade_colors = fade_colors;
237			fPrefs->normal_bar_color = bar_color;
238
239			fTarget.SendMessage(message);
240			break;
241		}
242		// Share the single color control among three values
243		case PRV_MINI_ACTIVE:
244			fColorControl->SetValue(fPrefs->mini_active_color);
245			break;
246		case PRV_MINI_IDLE:
247			fColorControl->SetValue(fPrefs->mini_idle_color);
248			break;
249		case PRV_MINI_FRAME:
250			fColorControl->SetValue(fPrefs->mini_frame_color);
251			break;
252		case PRV_MINI_CHANGE_COLOR: {
253			int32 color = fColorControl->Value();
254			if (fActiveButton->Value())
255				fPrefs->mini_active_color = color;
256			else if (fIdleButton->Value())
257				fPrefs->mini_idle_color = color;
258			else
259				fPrefs->mini_frame_color = color;
260
261			message->AddInt32("active_color", fPrefs->mini_active_color);
262			message->AddInt32("idle_color", fPrefs->mini_idle_color);
263			message->AddInt32("frame_color", fPrefs->mini_frame_color);
264			fTarget.SendMessage(message);
265			break;
266		}
267		case PRV_DESKBAR_ACTIVE:
268			fColorControl->SetValue(fPrefs->deskbar_active_color);
269			break;
270		case PRV_DESKBAR_IDLE:
271			fColorControl->SetValue(fPrefs->deskbar_idle_color);
272			break;
273		case PRV_DESKBAR_FRAME:
274			fColorControl->SetValue(fPrefs->deskbar_frame_color);
275			break;
276		case PRV_DESKBAR_ICON_WIDTH:
277			UpdateDeskbarIconWidth();
278			break;
279		case PRV_DESKBAR_CHANGE_COLOR: {
280			int32 color = fColorControl->Value();
281			if (fActiveButton->Value())
282				fPrefs->deskbar_active_color = color;
283			else if (fIdleButton->Value())
284				fPrefs->deskbar_idle_color = color;
285			else
286				fPrefs->deskbar_frame_color = color;
287
288			message->AddInt32("active_color", fPrefs->deskbar_active_color);
289			message->AddInt32("idle_color", fPrefs->deskbar_idle_color);
290			message->AddInt32("frame_color", fPrefs->deskbar_frame_color);
291			fTarget.SendMessage(message);
292			break;
293		}
294		case PRV_BOTTOM_DEFAULTS:
295			_ResetDefaults();
296			break;
297		default:
298			BView::MessageReceived(message);
299			break;
300	}
301}
302
303
304void
305ConfigView::UpdateDeskbarIconWidth()
306{
307	// Make sure the width shows at least one pixel per CPU and
308	// that it will fit in the tray in any Deskbar orientation
309	int width = atoi(fIconWidthControl->Text());
310	int min_width = GetMinimumViewWidth();
311	if (width < min_width || width > 50) {
312		char temp[12];
313		if (width < min_width) {
314			snprintf(temp, 12, "%d", min_width);
315			width = min_width;
316		} else {
317			strcpy(temp, "50");
318			width = 50;
319		}
320		fIconWidthControl->SetText(temp);
321	}
322
323	fPrefs->deskbar_icon_width = width;
324
325	BMessage message(PRV_DESKBAR_ICON_WIDTH);
326	message.AddInt32("width", width);
327	fTarget.SendMessage(&message);
328}
329
330
331void
332ConfigView::_ResetDefaults()
333{
334	if (fMode == PRV_NORMAL_CHANGE_COLOR) {
335		fColorControl->SetValue(DEFAULT_NORMAL_BAR_COLOR);
336		fFadeCheckBox->SetValue(DEFAULT_NORMAL_FADE_COLORS);
337	} else if (fMode == PRV_MINI_CHANGE_COLOR) {
338		fPrefs->mini_active_color = DEFAULT_MINI_ACTIVE_COLOR;
339		fPrefs->mini_idle_color = DEFAULT_MINI_IDLE_COLOR;
340		fPrefs->mini_frame_color = DEFAULT_MINI_FRAME_COLOR;
341		if (fActiveButton->Value())
342			fColorControl->SetValue(DEFAULT_MINI_ACTIVE_COLOR);
343		else if (fIdleButton->Value())
344			fColorControl->SetValue(DEFAULT_MINI_IDLE_COLOR);
345		else
346			fColorControl->SetValue(DEFAULT_MINI_FRAME_COLOR);
347
348		BMessage *message = new BMessage(PRV_MINI_CHANGE_COLOR);
349		message->AddInt32("active_color", DEFAULT_MINI_ACTIVE_COLOR);
350		message->AddInt32("idle_color", DEFAULT_MINI_IDLE_COLOR);
351		message->AddInt32("frame_color", DEFAULT_MINI_FRAME_COLOR);
352		fTarget.SendMessage(message);
353	} else {
354		fPrefs->deskbar_active_color = DEFAULT_DESKBAR_ACTIVE_COLOR;
355		fPrefs->deskbar_idle_color = DEFAULT_DESKBAR_IDLE_COLOR;
356		fPrefs->deskbar_frame_color = DEFAULT_DESKBAR_FRAME_COLOR;
357		if (fActiveButton->Value())
358			fColorControl->SetValue(DEFAULT_DESKBAR_ACTIVE_COLOR);
359		else if (fIdleButton->Value())
360			fColorControl->SetValue(DEFAULT_DESKBAR_IDLE_COLOR);
361		else
362			fColorControl->SetValue(DEFAULT_DESKBAR_FRAME_COLOR);
363
364		BMessage *message = new BMessage(PRV_DESKBAR_CHANGE_COLOR);
365		message->AddInt32("active_color", DEFAULT_DESKBAR_ACTIVE_COLOR);
366		message->AddInt32("idle_color", DEFAULT_DESKBAR_IDLE_COLOR);
367		message->AddInt32("frame_color", DEFAULT_DESKBAR_FRAME_COLOR);
368		fTarget.SendMessage(message);
369
370		char temp[10];
371		snprintf(temp, 10, "%d", DEFAULT_DESKBAR_ICON_WIDTH);
372		fIconWidthControl->SetText(temp);
373		// Need to force the model message to be sent
374		fIconWidthControl->Invoke();
375	}
376}
377