xref: /haiku/src/preferences/time/ClockView.cpp (revision e5d65858f2361fe0552495b61620c84dcee6bc00)
1 /*
2  * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		John Scipione <jscipione@gmail.com>
7  */
8 
9 
10 #include "ClockView.h"
11 
12 #include <Alignment.h>
13 #include <Box.h>
14 #include <Catalog.h>
15 #include <CheckBox.h>
16 #include <ControlLook.h>
17 #include <LayoutBuilder.h>
18 #include <Locale.h>
19 #include <Message.h>
20 #include <Messenger.h>
21 #include <RadioButton.h>
22 #include <SpaceLayoutItem.h>
23 #include <Window.h>
24 
25 #include "TimeMessages.h"
26 
27 
28 static const char* kDeskbarSignature = "application/x-vnd.Be-TSKB";
29 static const float kIndentSpacing
30 	= be_control_look->DefaultItemSpacing() * 2.3;
31 
32 
33 #undef B_TRANSLATION_CONTEXT
34 #define B_TRANSLATION_CONTEXT "Time"
35 
36 
37 ClockView::ClockView(const char* name)
38 	:
39 	BView(name, 0),
40 	fCachedShowClock(B_CONTROL_ON),
41 	fCachedShowSeconds(B_CONTROL_OFF),
42 	fCachedShowDayOfWeek(B_CONTROL_OFF),
43 	fCachedShowTimeZone(B_CONTROL_OFF)
44 {
45 	fShowClock = new BCheckBox(B_TRANSLATE("Show clock in Deskbar"),
46 		new BMessage(kShowHideTime));
47 	fShowSeconds = new BCheckBox(B_TRANSLATE("Display time with seconds"),
48 		new BMessage(kShowSeconds));
49 	fShowDayOfWeek = new BCheckBox(B_TRANSLATE("Show day of week"),
50 		new BMessage(kShowDayOfWeek));
51 	fShowTimeZone = new BCheckBox(B_TRANSLATE("Show time zone"),
52 		new BMessage(kShowTimeZone));
53 
54 	BView* view = BLayoutBuilder::Group<>(B_VERTICAL, 0)
55 		.Add(fShowSeconds)
56 		.Add(fShowDayOfWeek)
57 		.Add(fShowTimeZone)
58 		.AddGlue()
59 		.SetInsets(B_USE_DEFAULT_SPACING)
60 		.View();
61 
62 	BBox* showClockBox = new BBox("show clock box");
63 	showClockBox->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP));
64 	showClockBox->SetLabel(fShowClock);
65 	showClockBox->AddChild(view);
66 
67 	BLayoutBuilder::Group<>(this)
68 		.AddGroup(B_VERTICAL, 0)
69 			.Add(showClockBox)
70 		.End()
71 		.SetInsets(B_USE_DEFAULT_SPACING);
72 }
73 
74 
75 ClockView::~ClockView()
76 {
77 }
78 
79 
80 void
81 ClockView::AttachedToWindow()
82 {
83 	if (Parent())
84 		SetViewColor(Parent()->ViewColor());
85 
86 	fShowClock->SetTarget(this);
87 	fShowSeconds->SetTarget(this);
88 	fShowDayOfWeek->SetTarget(this);
89 	fShowTimeZone->SetTarget(this);
90 
91 	// Disable these controls initially, they'll be enabled
92 	// when we get a response from Deskbar.
93 	fShowClock->SetEnabled(false);
94 	fShowSeconds->SetEnabled(false);
95 	fShowDayOfWeek->SetEnabled(false);
96 	fShowTimeZone->SetEnabled(false);
97 
98 	// Ask Deskbar for current clock settings, it will reply
99 	// asynchronously in MesssageReceived() below.
100 	BMessenger* messenger = new BMessenger(kDeskbarSignature);
101 	BMessenger replyMessenger(this);
102 	BMessage* message = new BMessage(kGetClockSettings);
103 	messenger->SendMessage(message, replyMessenger);
104 }
105 
106 
107 void
108 ClockView::MessageReceived(BMessage* message)
109 {
110 	switch (message->what) {
111 		case kGetClockSettings:
112 		{
113 			// Get current clock settings from Deskbar
114 			bool showClock;
115 			bool showSeconds;
116 			bool showDayOfWeek;
117 			bool showTimeZone;
118 
119 			if (message->FindBool("showSeconds", &showSeconds) == B_OK) {
120 				fCachedShowSeconds = showSeconds
121 					? B_CONTROL_ON : B_CONTROL_OFF;
122 				fShowSeconds->SetValue(fCachedShowSeconds);
123 				fShowSeconds->SetEnabled(true);
124 			}
125 
126 			if (message->FindBool("showDayOfWeek", &showDayOfWeek) == B_OK) {
127 				fCachedShowDayOfWeek = showDayOfWeek
128 					? B_CONTROL_ON : B_CONTROL_OFF;
129 				fShowDayOfWeek->SetValue(fCachedShowDayOfWeek);
130 				fShowDayOfWeek->SetEnabled(true);
131 			}
132 
133 			if (message->FindBool("showTimeZone", &showTimeZone) == B_OK) {
134 				fCachedShowTimeZone = showTimeZone
135 					? B_CONTROL_ON : B_CONTROL_OFF;
136 				fShowTimeZone->SetValue(fCachedShowTimeZone);
137 				fShowTimeZone->SetEnabled(true);
138 			}
139 
140 			// do this one last because it might disable the others
141 			if (message->FindBool("showClock", &showClock) == B_OK) {
142 				fCachedShowClock = showClock ? B_CONTROL_ON : B_CONTROL_OFF;
143 				fShowClock->SetValue(fCachedShowClock);
144 				fShowClock->SetEnabled(true);
145 				fShowSeconds->SetEnabled(showClock);
146 				fShowDayOfWeek->SetEnabled(showClock);
147 				fShowTimeZone->SetEnabled(showClock);
148 			}
149 			break;
150 		}
151 
152 		case kShowHideTime:
153 		{
154 			bool showClock;
155 			if (message->FindBool("showClock", &showClock) == B_OK) {
156 				// message originated from Deskbar, handle special
157 				fShowClock->SetValue(showClock ? B_CONTROL_ON : B_CONTROL_OFF);
158 				fShowSeconds->SetEnabled(showClock);
159 				fShowDayOfWeek->SetEnabled(showClock);
160 				fShowTimeZone->SetEnabled(showClock);
161 
162 				Window()->PostMessage(kMsgChange);
163 				break;
164 					// don't fall through
165 			}
166 			showClock = fShowClock->Value() == B_CONTROL_ON;
167 			fShowSeconds->SetEnabled(showClock);
168 			fShowDayOfWeek->SetEnabled(showClock);
169 			fShowTimeZone->SetEnabled(showClock);
170 		}
171 		// fall-through
172 		case kShowSeconds:
173 		case kShowDayOfWeek:
174 		case kShowTimeZone:
175 		{
176 			BMessenger* messenger = new BMessenger(kDeskbarSignature);
177 			messenger->SendMessage(message);
178 
179 			Window()->PostMessage(kMsgChange);
180 
181 			break;
182 		}
183 
184 		case kMsgRevert:
185 			_Revert();
186 			break;
187 
188 		default:
189 			BView::MessageReceived(message);
190 			break;
191 	}
192 }
193 
194 
195 bool
196 ClockView::CheckCanRevert()
197 {
198 	return fShowClock->Value() != fCachedShowClock
199 		|| fShowSeconds->Value() != fCachedShowSeconds
200 		|| fShowDayOfWeek->Value() != fCachedShowDayOfWeek
201 		|| fShowTimeZone->Value() != fCachedShowTimeZone;
202 }
203 
204 
205 void
206 ClockView::_Revert()
207 {
208 	if (fShowClock->Value() != fCachedShowClock) {
209 		fShowClock->SetValue(fCachedShowClock);
210 		fShowClock->Invoke();
211 	}
212 
213 	if (fShowSeconds->Value() != fCachedShowSeconds) {
214 		fShowSeconds->SetValue(fCachedShowSeconds);
215 		fShowSeconds->Invoke();
216 	}
217 
218 	if (fShowDayOfWeek->Value() != fCachedShowDayOfWeek) {
219 		fShowDayOfWeek->SetValue(fCachedShowDayOfWeek);
220 		fShowDayOfWeek->Invoke();
221 	}
222 
223 	if (fShowTimeZone->Value() != fCachedShowTimeZone) {
224 		fShowTimeZone->SetValue(fCachedShowTimeZone);
225 		fShowTimeZone->Invoke();
226 	}
227 }
228