xref: /haiku/src/apps/pulse/CPUButton.cpp (revision 3cb015b1ee509d69c643506e8ff573808c86dcfc)
1 //****************************************************************************************
2 //
3 //	File:		CPUButton.cpp
4 //
5 //	Written by:	Daniel Switkin
6 //
7 //	Copyright 1999, Be Incorporated
8 //
9 //****************************************************************************************
10 
11 
12 #include "CPUButton.h"
13 #include "PulseApp.h"
14 #include "PulseView.h"
15 #include "Common.h"
16 #include <interface/Alert.h>
17 #include <stdlib.h>
18 
19 
20 CPUButton::CPUButton(BRect rect, const char *name, const char *label, BMessage *message)
21 	: BControl(rect, name, label, message, B_FOLLOW_NONE, B_WILL_DRAW)
22 {
23 	SetValue(B_CONTROL_ON);
24 	SetViewColor(B_TRANSPARENT_COLOR);
25 	fReplicant = false;
26 
27 	_InitData();
28 }
29 
30 
31 CPUButton::CPUButton(BMessage *message)
32 	: BControl(message)
33 {
34 	fReplicant = true;
35 	_InitData();
36 }
37 
38 
39 CPUButton::~CPUButton()
40 {
41 }
42 
43 
44 void
45 CPUButton::_InitData()
46 {
47 	fOffColor.red = fOffColor.green = fOffColor.blue = 184;
48 	fOffColor.alpha = 255;
49 
50 	fCPU = atoi(Label()) - 1;
51 }
52 
53 
54 //! Redraw the button depending on whether it's up or down
55 void
56 CPUButton::Draw(BRect rect)
57 {
58 	bool value = (bool)Value();
59 	SetHighColor(value ? fOnColor : fOffColor);
60 
61 	BRect bounds = Bounds();
62 	BRect color_rect(bounds);
63 	color_rect.InsetBy(2, 2);
64 	if (value) {
65 		color_rect.bottom -= 1;
66 		color_rect.right -= 1;
67 	}
68 	FillRect(bounds);
69 
70 	if (value)
71 		SetHighColor(80, 80, 80);
72 	else
73 		SetHighColor(255, 255, 255);
74 
75 	BPoint start(0, 0);
76 	BPoint end(bounds.right, 0);
77 	StrokeLine(start, end);
78 	end.Set(0, bounds.bottom);
79 	StrokeLine(start, end);
80 
81 	if (value)
82 		SetHighColor(32, 32, 32);
83 	else
84 		SetHighColor(216, 216, 216);
85 
86 	start.Set(1, 1);
87 	end.Set(bounds.right - 1, 1);
88 	StrokeLine(start, end);
89 	end.Set(1, bounds.bottom - 1);
90 	StrokeLine(start, end);
91 
92 	if (value)
93 		SetHighColor(216, 216, 216);
94 	else
95 		SetHighColor(80, 80, 80);
96 
97 	start.Set(bounds.left + 1, bounds.bottom - 1);
98 	end.Set(bounds.right - 1, bounds.bottom - 1);
99 	StrokeLine(start, end);
100 	start.Set(bounds.right - 1, bounds.top + 1);
101 	StrokeLine(start, end);
102 
103 	if (value)
104 		SetHighColor(255, 255, 255);
105 	else
106 		SetHighColor(32, 32, 32);
107 
108 	start.Set(bounds.left, bounds.bottom);
109 	end.Set(bounds.right, bounds.bottom);
110 	StrokeLine(start, end);
111 	start.Set(bounds.right, bounds.top);
112 	StrokeLine(start, end);
113 
114 	if (value) {
115 		SetHighColor(0, 0, 0);
116 		start.Set(bounds.left + 2, bounds.bottom - 2);
117 		end.Set(bounds.right - 2, bounds.bottom - 2);
118 		StrokeLine(start, end);
119 		start.Set(bounds.right - 2, bounds.top + 2);
120 		StrokeLine(start, end);
121 	}
122 
123 	// Try to keep the text centered
124 	BFont font;
125 	GetFont(&font);
126 	int label_width = (int)font.StringWidth(Label());
127 	int rect_width = bounds.IntegerWidth() - 1;
128 	int rect_height = bounds.IntegerHeight();
129 	font_height fh;
130 	font.GetHeight(&fh);
131 	int label_height = (int)fh.ascent;
132 	int x_pos = (int)(((double)(rect_width - label_width) / 2.0) + 0.5);
133 	int y_pos = (rect_height - label_height) / 2 + label_height;
134 
135 	MovePenTo(x_pos, y_pos);
136 	SetHighColor(0, 0, 0);
137 	SetDrawingMode(B_OP_OVER);
138 	DrawString(Label());
139 }
140 
141 
142 //! Track the mouse without blocking the window
143 void
144 CPUButton::MouseDown(BPoint point)
145 {
146 	SetValue(!Value());
147 	SetTracking(true);
148 	SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
149 }
150 
151 
152 void
153 CPUButton::MouseUp(BPoint point)
154 {
155 	if (Bounds().Contains(point))
156 		Invoke();
157 
158 	SetTracking(false);
159 }
160 
161 
162 void
163 CPUButton::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
164 {
165 	if (IsTracking()) {
166 		if (transit == B_ENTERED_VIEW || transit == B_EXITED_VIEW)
167 			SetValue(!Value());
168 	}
169 }
170 
171 
172 status_t
173 CPUButton::Invoke(BMessage *message)
174 {
175 	if (!LastEnabledCPU(fCPU)) {
176 		_kset_cpu_state_(fCPU, Value());
177 	} else {
178 		BAlert *alert = new BAlert(NULL, "You can't disable the last active CPU.", "OK");
179 		alert->Go(NULL);
180 		SetValue(!Value());
181 	}
182 
183 	return B_OK;
184 }
185 
186 
187 CPUButton *
188 CPUButton::Instantiate(BMessage *data)
189 {
190 	if (!validate_instantiation(data, "CPUButton"))
191 		return NULL;
192 
193 	return new CPUButton(data);
194 }
195 
196 
197 status_t
198 CPUButton::Archive(BMessage *data, bool deep) const
199 {
200 	BControl::Archive(data, deep);
201 	data->AddString("add_on", APP_SIGNATURE);
202 	data->AddString("class", "CPUButton");
203 	return B_OK;
204 }
205 
206 
207 void
208 CPUButton::MessageReceived(BMessage *message)
209 {
210 	switch (message->what) {
211 		case B_ABOUT_REQUESTED: {
212 			BAlert *alert = new BAlert("Info", "Pulse\n\nBy David Ramsey and Arve Hjønnevåg\nRevised by Daniel Switkin", "OK");
213 			// Use the asynchronous version so we don't block the window's thread
214 			alert->Go(NULL);
215 			break;
216 		}
217 		case PV_REPLICANT_PULSE: {
218 			// Make sure we're consistent with our CPU
219 			if (_kget_cpu_state_(fCPU) != Value() && !IsTracking())
220 				SetValue(!Value());
221 			break;
222 		}
223 		default:
224 			BControl::MessageReceived(message);
225 			break;
226 	}
227 }
228 
229 
230 void
231 CPUButton::UpdateColors(int32 color)
232 {
233 	fOnColor.red = (color & 0xff000000) >> 24;
234 	fOnColor.green = (color & 0x00ff0000) >> 16;
235 	fOnColor.blue = (color & 0x0000ff00) >> 8;
236 	Draw(Bounds());
237 }
238 
239 
240 void
241 CPUButton::AttachedToWindow()
242 {
243 	SetTarget(this);
244 	SetFont(be_plain_font);
245 	SetFontSize(10);
246 
247 	if (fReplicant) {
248 		Prefs *prefs = new Prefs();
249 		UpdateColors(prefs->normal_bar_color);
250 		delete prefs;
251 	} else {
252 		PulseApp *pulseapp = (PulseApp *)be_app;
253 		UpdateColors(pulseapp->prefs->normal_bar_color);
254 	}
255 
256 	BMessenger messenger(this);
257 	fPulseRunner = new BMessageRunner(messenger, new BMessage(PV_REPLICANT_PULSE),
258 		200000, -1);
259 }
260 
261 
262 void
263 CPUButton::DetachedFromWindow()
264 {
265 	delete fPulseRunner;
266 }
267 
268