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