xref: /haiku/src/preferences/time/ClockView.cpp (revision 22440f4105cafc95cc1d49f9bc65bb395c527d86)
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 		.SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET))
56 		.Add(fShowSeconds)
57 		.Add(fShowDayOfWeek)
58 		.Add(fShowTimeZone)
59 		.AddGlue()
60 		.SetInsets(B_USE_DEFAULT_SPACING)
61 		.View();
62 
63 	BBox* showClockBox = new BBox("show clock box");
64 	showClockBox->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP));
65 	showClockBox->SetLabel(fShowClock);
66 	showClockBox->AddChild(view);
67 
68 	BLayoutBuilder::Group<>(this)
69 		.AddGroup(B_VERTICAL, 0)
70 			.Add(showClockBox)
71 		.End()
72 		.SetInsets(B_USE_DEFAULT_SPACING);
73 }
74 
75 
76 ClockView::~ClockView()
77 {
78 }
79 
80 
81 void
82 ClockView::AttachedToWindow()
83 {
84 	if (Parent())
85 		SetViewColor(Parent()->ViewColor());
86 
87 	fShowClock->SetTarget(this);
88 	fShowSeconds->SetTarget(this);
89 	fShowDayOfWeek->SetTarget(this);
90 	fShowTimeZone->SetTarget(this);
91 
92 	// Disable these controls initially, they'll be enabled
93 	// when we get a response from Deskbar.
94 	fShowClock->SetEnabled(false);
95 	fShowSeconds->SetEnabled(false);
96 	fShowDayOfWeek->SetEnabled(false);
97 	fShowTimeZone->SetEnabled(false);
98 
99 	// Ask Deskbar for current clock settings, it will reply
100 	// asynchronously in MesssageReceived() below.
101 	BMessenger* messenger = new BMessenger(kDeskbarSignature);
102 	BMessenger replyMessenger(this);
103 	BMessage* message = new BMessage(kGetClockSettings);
104 	messenger->SendMessage(message, replyMessenger);
105 }
106 
107 
108 void
109 ClockView::MessageReceived(BMessage* message)
110 {
111 	switch (message->what) {
112 		case kGetClockSettings:
113 		{
114 			// Get current clock settings from Deskbar
115 			bool showClock;
116 			bool showSeconds;
117 			bool showDayOfWeek;
118 			bool showTimeZone;
119 
120 			if (message->FindBool("showSeconds", &showSeconds) == B_OK) {
121 				fCachedShowSeconds = showSeconds
122 					? B_CONTROL_ON : B_CONTROL_OFF;
123 				fShowSeconds->SetValue(fCachedShowSeconds);
124 				fShowSeconds->SetEnabled(true);
125 			}
126 
127 			if (message->FindBool("showDayOfWeek", &showDayOfWeek) == B_OK) {
128 				fCachedShowDayOfWeek = showDayOfWeek
129 					? B_CONTROL_ON : B_CONTROL_OFF;
130 				fShowDayOfWeek->SetValue(fCachedShowDayOfWeek);
131 				fShowDayOfWeek->SetEnabled(true);
132 			}
133 
134 			if (message->FindBool("showTimeZone", &showTimeZone) == B_OK) {
135 				fCachedShowTimeZone = showTimeZone
136 					? B_CONTROL_ON : B_CONTROL_OFF;
137 				fShowTimeZone->SetValue(fCachedShowTimeZone);
138 				fShowTimeZone->SetEnabled(true);
139 			}
140 
141 			// do this one last because it might disable the others
142 			if (message->FindBool("showClock", &showClock) == B_OK) {
143 				fCachedShowClock = showClock ? B_CONTROL_ON : B_CONTROL_OFF;
144 				fShowClock->SetValue(fCachedShowClock);
145 				fShowClock->SetEnabled(true);
146 				fShowSeconds->SetEnabled(showClock);
147 				fShowDayOfWeek->SetEnabled(showClock);
148 				fShowTimeZone->SetEnabled(showClock);
149 			}
150 			break;
151 		}
152 
153 		case kShowHideTime:
154 		{
155 			bool showClock;
156 			if (message->FindBool("showClock", &showClock) == B_OK) {
157 				// message originated from Deskbar, handle special
158 				fShowClock->SetValue(showClock ? B_CONTROL_ON : B_CONTROL_OFF);
159 				fShowSeconds->SetEnabled(showClock);
160 				fShowDayOfWeek->SetEnabled(showClock);
161 				fShowTimeZone->SetEnabled(showClock);
162 
163 				Window()->PostMessage(kMsgChange);
164 				break;
165 					// don't fall through
166 			}
167 			showClock = fShowClock->Value() == B_CONTROL_ON;
168 			fShowSeconds->SetEnabled(showClock);
169 			fShowDayOfWeek->SetEnabled(showClock);
170 			fShowTimeZone->SetEnabled(showClock);
171 		}
172 		// fall-through
173 		case kShowSeconds:
174 		case kShowDayOfWeek:
175 		case kShowTimeZone:
176 		{
177 			BMessenger* messenger = new BMessenger(kDeskbarSignature);
178 			messenger->SendMessage(message);
179 
180 			Window()->PostMessage(kMsgChange);
181 
182 			break;
183 		}
184 
185 		case kMsgRevert:
186 			_Revert();
187 			break;
188 
189 		default:
190 			BView::MessageReceived(message);
191 			break;
192 	}
193 }
194 
195 
196 bool
197 ClockView::CheckCanRevert()
198 {
199 	return fShowClock->Value() != fCachedShowClock
200 		|| fShowSeconds->Value() != fCachedShowSeconds
201 		|| fShowDayOfWeek->Value() != fCachedShowDayOfWeek
202 		|| fShowTimeZone->Value() != fCachedShowTimeZone;
203 }
204 
205 
206 void
207 ClockView::_Revert()
208 {
209 	if (fShowClock->Value() != fCachedShowClock) {
210 		fShowClock->SetValue(fCachedShowClock);
211 		fShowClock->Invoke();
212 	}
213 
214 	if (fShowSeconds->Value() != fCachedShowSeconds) {
215 		fShowSeconds->SetValue(fCachedShowSeconds);
216 		fShowSeconds->Invoke();
217 	}
218 
219 	if (fShowDayOfWeek->Value() != fCachedShowDayOfWeek) {
220 		fShowDayOfWeek->SetValue(fCachedShowDayOfWeek);
221 		fShowDayOfWeek->Invoke();
222 	}
223 
224 	if (fShowTimeZone->Value() != fCachedShowTimeZone) {
225 		fShowTimeZone->SetValue(fCachedShowTimeZone);
226 		fShowTimeZone->Invoke();
227 	}
228 }
229