xref: /haiku/src/apps/pulse/CPUButton.cpp (revision e04f6f31b08f57dfd8a75d3f399666b76f23b22a)
142f6e06fSWim van der Meer //*****************************************************************************
252a38012Sejakowatz //
352a38012Sejakowatz //	File:		CPUButton.cpp
452a38012Sejakowatz //
552a38012Sejakowatz //	Written by:	Daniel Switkin
652a38012Sejakowatz //
752a38012Sejakowatz //	Copyright 1999, Be Incorporated
852a38012Sejakowatz //
942f6e06fSWim van der Meer //*****************************************************************************
104ccfb086SAxel Dörfler 
1152a38012Sejakowatz #include "CPUButton.h"
1287df8902SIngo Weinhold 
1387df8902SIngo Weinhold #include <stdlib.h>
142ee53d23SPhilippe Saint-Pierre #include <string.h>
1587df8902SIngo Weinhold 
1687df8902SIngo Weinhold #include <Alert.h>
1742f6e06fSWim van der Meer #include <Catalog.h>
18e20b1568SPhilippe Saint-Pierre #include <Dragger.h>
19e20b1568SPhilippe Saint-Pierre #include <PopUpMenu.h>
2055f0b964SSiarzhuk Zharski #include <TextView.h>
21e20b1568SPhilippe Saint-Pierre #include <ViewPrivate.h>
2287df8902SIngo Weinhold 
2387df8902SIngo Weinhold #include <syscalls.h>
2487df8902SIngo Weinhold 
2552a38012Sejakowatz #include "PulseApp.h"
2652a38012Sejakowatz #include "PulseView.h"
2752a38012Sejakowatz #include "Common.h"
2852a38012Sejakowatz 
29546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
30546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "CPUButton"
3142f6e06fSWim van der Meer 
3252a38012Sejakowatz 
CPUButton(BRect rect,const char * name,const char * label,BMessage * message)334ccfb086SAxel Dörfler CPUButton::CPUButton(BRect rect, const char *name, const char *label, BMessage *message)
344ccfb086SAxel Dörfler 	: BControl(rect, name, label, message, B_FOLLOW_NONE, B_WILL_DRAW)
354ccfb086SAxel Dörfler {
3652a38012Sejakowatz 	SetValue(B_CONTROL_ON);
3752a38012Sejakowatz 	SetViewColor(B_TRANSPARENT_COLOR);
384ccfb086SAxel Dörfler 	fReplicant = false;
394ccfb086SAxel Dörfler 
404ccfb086SAxel Dörfler 	_InitData();
4152a38012Sejakowatz }
4252a38012Sejakowatz 
434ccfb086SAxel Dörfler 
CPUButton(BMessage * message)444ccfb086SAxel Dörfler CPUButton::CPUButton(BMessage *message)
454ccfb086SAxel Dörfler 	: BControl(message)
464ccfb086SAxel Dörfler {
474ccfb086SAxel Dörfler 	fReplicant = true;
48e20b1568SPhilippe Saint-Pierre 
49e20b1568SPhilippe Saint-Pierre 	/* We remove the dragger if we are in deskbar */
50e20b1568SPhilippe Saint-Pierre 	if (CountChildren() > 1)
51e20b1568SPhilippe Saint-Pierre 		RemoveChild(ChildAt(1));
52e20b1568SPhilippe Saint-Pierre 
53431bbe1cSPhilippe Saint-Pierre 	ResizeTo(CPUBUTTON_WIDTH, CPUBUTTON_HEIGHT);
54e20b1568SPhilippe Saint-Pierre 
554ccfb086SAxel Dörfler 	_InitData();
5652a38012Sejakowatz }
5752a38012Sejakowatz 
584ccfb086SAxel Dörfler 
~CPUButton()594ccfb086SAxel Dörfler CPUButton::~CPUButton()
604ccfb086SAxel Dörfler {
614ccfb086SAxel Dörfler }
624ccfb086SAxel Dörfler 
634ccfb086SAxel Dörfler 
644ccfb086SAxel Dörfler void
_InitData()654ccfb086SAxel Dörfler CPUButton::_InitData()
664ccfb086SAxel Dörfler {
674ccfb086SAxel Dörfler 	fOffColor.red = fOffColor.green = fOffColor.blue = 184;
684ccfb086SAxel Dörfler 	fOffColor.alpha = 255;
694ccfb086SAxel Dörfler 
704ccfb086SAxel Dörfler 	fCPU = atoi(Label()) - 1;
714ccfb086SAxel Dörfler }
724ccfb086SAxel Dörfler 
734ccfb086SAxel Dörfler 
74e20b1568SPhilippe Saint-Pierre void
_AddDragger()75e20b1568SPhilippe Saint-Pierre CPUButton::_AddDragger()
76e20b1568SPhilippe Saint-Pierre {
77e20b1568SPhilippe Saint-Pierre 	BRect rect(Bounds());
78e20b1568SPhilippe Saint-Pierre 	rect.top = rect.bottom - 7;
79e20b1568SPhilippe Saint-Pierre 	rect.left = rect.right - 7;
80e20b1568SPhilippe Saint-Pierre 	BDragger* dragger = new BDragger(rect, this,
81e20b1568SPhilippe Saint-Pierre 		B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
82e20b1568SPhilippe Saint-Pierre 	AddChild(dragger);
83e20b1568SPhilippe Saint-Pierre }
84e20b1568SPhilippe Saint-Pierre 
85e20b1568SPhilippe Saint-Pierre 
864ccfb086SAxel Dörfler //! Redraw the button depending on whether it's up or down
874ccfb086SAxel Dörfler void
Draw(BRect rect)884ccfb086SAxel Dörfler CPUButton::Draw(BRect rect)
894ccfb086SAxel Dörfler {
9052a38012Sejakowatz 	bool value = (bool)Value();
914ccfb086SAxel Dörfler 	SetHighColor(value ? fOnColor : fOffColor);
9252a38012Sejakowatz 
93e20b1568SPhilippe Saint-Pierre 	if (!fReplicant) {
94e20b1568SPhilippe Saint-Pierre 		SetLowColor(Parent()->LowColor());
95e20b1568SPhilippe Saint-Pierre 		FillRect(Bounds(), B_SOLID_LOW);
96e20b1568SPhilippe Saint-Pierre 	}
97e20b1568SPhilippe Saint-Pierre 
9852a38012Sejakowatz 	BRect bounds = Bounds();
99431bbe1cSPhilippe Saint-Pierre 	if (fReplicant && !fReplicantInDeskbar) {
100431bbe1cSPhilippe Saint-Pierre 		bounds.bottom -= 4;
101431bbe1cSPhilippe Saint-Pierre 		bounds.right -= 4;
102431bbe1cSPhilippe Saint-Pierre 	} else if (!fReplicant) {
103e20b1568SPhilippe Saint-Pierre 		bounds.bottom -= 7;
104e20b1568SPhilippe Saint-Pierre 		bounds.right -= 7;
105e20b1568SPhilippe Saint-Pierre 	}
10652a38012Sejakowatz 	BRect color_rect(bounds);
10752a38012Sejakowatz 	color_rect.InsetBy(2, 2);
10852a38012Sejakowatz 	if (value) {
10952a38012Sejakowatz 		color_rect.bottom -= 1;
11052a38012Sejakowatz 		color_rect.right -= 1;
11152a38012Sejakowatz 	}
11252a38012Sejakowatz 	FillRect(bounds);
11352a38012Sejakowatz 
1144ccfb086SAxel Dörfler 	if (value)
1154ccfb086SAxel Dörfler 		SetHighColor(80, 80, 80);
1164ccfb086SAxel Dörfler 	else
1174ccfb086SAxel Dörfler 		SetHighColor(255, 255, 255);
1184ccfb086SAxel Dörfler 
11952a38012Sejakowatz 	BPoint start(0, 0);
12052a38012Sejakowatz 	BPoint end(bounds.right, 0);
12152a38012Sejakowatz 	StrokeLine(start, end);
12252a38012Sejakowatz 	end.Set(0, bounds.bottom);
12352a38012Sejakowatz 	StrokeLine(start, end);
12452a38012Sejakowatz 
1254ccfb086SAxel Dörfler 	if (value)
1264ccfb086SAxel Dörfler 		SetHighColor(32, 32, 32);
1274ccfb086SAxel Dörfler 	else
1284ccfb086SAxel Dörfler 		SetHighColor(216, 216, 216);
1294ccfb086SAxel Dörfler 
13052a38012Sejakowatz 	start.Set(1, 1);
13152a38012Sejakowatz 	end.Set(bounds.right - 1, 1);
13252a38012Sejakowatz 	StrokeLine(start, end);
13352a38012Sejakowatz 	end.Set(1, bounds.bottom - 1);
13452a38012Sejakowatz 	StrokeLine(start, end);
13552a38012Sejakowatz 
1364ccfb086SAxel Dörfler 	if (value)
1374ccfb086SAxel Dörfler 		SetHighColor(216, 216, 216);
1384ccfb086SAxel Dörfler 	else
1394ccfb086SAxel Dörfler 		SetHighColor(80, 80, 80);
1404ccfb086SAxel Dörfler 
14152a38012Sejakowatz 	start.Set(bounds.left + 1, bounds.bottom - 1);
14252a38012Sejakowatz 	end.Set(bounds.right - 1, bounds.bottom - 1);
14352a38012Sejakowatz 	StrokeLine(start, end);
14452a38012Sejakowatz 	start.Set(bounds.right - 1, bounds.top + 1);
14552a38012Sejakowatz 	StrokeLine(start, end);
14652a38012Sejakowatz 
1474ccfb086SAxel Dörfler 	if (value)
1484ccfb086SAxel Dörfler 		SetHighColor(255, 255, 255);
1494ccfb086SAxel Dörfler 	else
1504ccfb086SAxel Dörfler 		SetHighColor(32, 32, 32);
1514ccfb086SAxel Dörfler 
15252a38012Sejakowatz 	start.Set(bounds.left, bounds.bottom);
15352a38012Sejakowatz 	end.Set(bounds.right, bounds.bottom);
15452a38012Sejakowatz 	StrokeLine(start, end);
15552a38012Sejakowatz 	start.Set(bounds.right, bounds.top);
15652a38012Sejakowatz 	StrokeLine(start, end);
15752a38012Sejakowatz 
15852a38012Sejakowatz 	if (value) {
15952a38012Sejakowatz 		SetHighColor(0, 0, 0);
16052a38012Sejakowatz 		start.Set(bounds.left + 2, bounds.bottom - 2);
16152a38012Sejakowatz 		end.Set(bounds.right - 2, bounds.bottom - 2);
16252a38012Sejakowatz 		StrokeLine(start, end);
16352a38012Sejakowatz 		start.Set(bounds.right - 2, bounds.top + 2);
16452a38012Sejakowatz 		StrokeLine(start, end);
16552a38012Sejakowatz 	}
16652a38012Sejakowatz 
16752a38012Sejakowatz 	// Try to keep the text centered
16852a38012Sejakowatz 	BFont font;
16952a38012Sejakowatz 	GetFont(&font);
17052a38012Sejakowatz 	int label_width = (int)font.StringWidth(Label());
17152a38012Sejakowatz 	int rect_width = bounds.IntegerWidth() - 1;
17252a38012Sejakowatz 	int rect_height = bounds.IntegerHeight();
17352a38012Sejakowatz 	font_height fh;
17452a38012Sejakowatz 	font.GetHeight(&fh);
17552a38012Sejakowatz 	int label_height = (int)fh.ascent;
17652a38012Sejakowatz 	int x_pos = (int)(((double)(rect_width - label_width) / 2.0) + 0.5);
17752a38012Sejakowatz 	int y_pos = (rect_height - label_height) / 2 + label_height;
17852a38012Sejakowatz 
17952a38012Sejakowatz 	MovePenTo(x_pos, y_pos);
18052a38012Sejakowatz 	SetHighColor(0, 0, 0);
18152a38012Sejakowatz 	SetDrawingMode(B_OP_OVER);
18252a38012Sejakowatz 	DrawString(Label());
18352a38012Sejakowatz }
18452a38012Sejakowatz 
1854ccfb086SAxel Dörfler 
1864ccfb086SAxel Dörfler //! Track the mouse without blocking the window
1874ccfb086SAxel Dörfler void
MouseDown(BPoint point)1884ccfb086SAxel Dörfler CPUButton::MouseDown(BPoint point)
1894ccfb086SAxel Dörfler {
190e20b1568SPhilippe Saint-Pierre 	BPoint mousePosition;
191e20b1568SPhilippe Saint-Pierre 	uint32 mouseButtons;
192e20b1568SPhilippe Saint-Pierre 
193e20b1568SPhilippe Saint-Pierre 	GetMouse(&mousePosition, &mouseButtons);
194e20b1568SPhilippe Saint-Pierre 
195e20b1568SPhilippe Saint-Pierre 	if ((B_PRIMARY_MOUSE_BUTTON & mouseButtons) != 0) {
19652a38012Sejakowatz 		SetValue(!Value());
19752a38012Sejakowatz 		SetTracking(true);
19852a38012Sejakowatz 		SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
199e20b1568SPhilippe Saint-Pierre 	} else if ((B_SECONDARY_MOUSE_BUTTON & mouseButtons) != 0
200e20b1568SPhilippe Saint-Pierre 		&& fReplicantInDeskbar) {
20142f6e06fSWim van der Meer 		BPopUpMenu *menu = new BPopUpMenu(B_TRANSLATE("Deskbar menu"));
20242f6e06fSWim van der Meer 		menu->AddItem(new BMenuItem(B_TRANSLATE("About Pulse" B_UTF8_ELLIPSIS),
203e20b1568SPhilippe Saint-Pierre 			new BMessage(B_ABOUT_REQUESTED)));
204e20b1568SPhilippe Saint-Pierre 		menu->AddSeparatorItem();
20542f6e06fSWim van der Meer 		menu->AddItem(new BMenuItem(B_TRANSLATE("Remove replicant"),
206e20b1568SPhilippe Saint-Pierre 			new BMessage(kDeleteReplicant)));
207e20b1568SPhilippe Saint-Pierre 		menu->SetTargetForItems(this);
208e20b1568SPhilippe Saint-Pierre 
209e20b1568SPhilippe Saint-Pierre 		ConvertToScreen(&point);
210e20b1568SPhilippe Saint-Pierre 		menu->Go(point, true, true, true);
211e20b1568SPhilippe Saint-Pierre 	}
21252a38012Sejakowatz }
21352a38012Sejakowatz 
2144ccfb086SAxel Dörfler 
2154ccfb086SAxel Dörfler void
MouseUp(BPoint point)2164ccfb086SAxel Dörfler CPUButton::MouseUp(BPoint point)
2174ccfb086SAxel Dörfler {
218e20b1568SPhilippe Saint-Pierre 	if (IsTracking()) {
2194ccfb086SAxel Dörfler 		if (Bounds().Contains(point))
2204ccfb086SAxel Dörfler 			Invoke();
2214ccfb086SAxel Dörfler 
22252a38012Sejakowatz 		SetTracking(false);
22352a38012Sejakowatz 	}
224e20b1568SPhilippe Saint-Pierre }
22552a38012Sejakowatz 
2264ccfb086SAxel Dörfler 
2274ccfb086SAxel Dörfler void
MouseMoved(BPoint point,uint32 transit,const BMessage * message)2284ccfb086SAxel Dörfler CPUButton::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
2294ccfb086SAxel Dörfler {
23052a38012Sejakowatz 	if (IsTracking()) {
2314ccfb086SAxel Dörfler 		if (transit == B_ENTERED_VIEW || transit == B_EXITED_VIEW)
2324ccfb086SAxel Dörfler 			SetValue(!Value());
23352a38012Sejakowatz 	}
23452a38012Sejakowatz }
23552a38012Sejakowatz 
23652a38012Sejakowatz 
2374ccfb086SAxel Dörfler status_t
Invoke(BMessage * message)2384ccfb086SAxel Dörfler CPUButton::Invoke(BMessage *message)
2394ccfb086SAxel Dörfler {
2404ccfb086SAxel Dörfler 	if (!LastEnabledCPU(fCPU)) {
24187df8902SIngo Weinhold 		_kern_set_cpu_enabled(fCPU, Value());
24252a38012Sejakowatz 	} else {
24355f0b964SSiarzhuk Zharski 		BAlert *alert = new BAlert(B_TRANSLATE("Info"),
24455f0b964SSiarzhuk Zharski 			B_TRANSLATE("You can't disable the last active CPU."),
24555f0b964SSiarzhuk Zharski 			B_TRANSLATE("OK"));
246aed35104SHumdinger 		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
24752a38012Sejakowatz 		alert->Go(NULL);
24852a38012Sejakowatz 		SetValue(!Value());
24952a38012Sejakowatz 	}
25052a38012Sejakowatz 
25152a38012Sejakowatz 	return B_OK;
25252a38012Sejakowatz }
25352a38012Sejakowatz 
2544ccfb086SAxel Dörfler 
2554ccfb086SAxel Dörfler CPUButton *
Instantiate(BMessage * data)2564ccfb086SAxel Dörfler CPUButton::Instantiate(BMessage *data)
2574ccfb086SAxel Dörfler {
2584ccfb086SAxel Dörfler 	if (!validate_instantiation(data, "CPUButton"))
2594ccfb086SAxel Dörfler 		return NULL;
2604ccfb086SAxel Dörfler 
26152a38012Sejakowatz 	return new CPUButton(data);
26252a38012Sejakowatz }
26352a38012Sejakowatz 
2644ccfb086SAxel Dörfler 
2654ccfb086SAxel Dörfler status_t
Archive(BMessage * data,bool deep) const2664ccfb086SAxel Dörfler CPUButton::Archive(BMessage *data, bool deep) const
2674ccfb086SAxel Dörfler {
26852a38012Sejakowatz 	BControl::Archive(data, deep);
26952a38012Sejakowatz 	data->AddString("add_on", APP_SIGNATURE);
27052a38012Sejakowatz 	data->AddString("class", "CPUButton");
27152a38012Sejakowatz 	return B_OK;
27252a38012Sejakowatz }
27352a38012Sejakowatz 
2744ccfb086SAxel Dörfler 
2754ccfb086SAxel Dörfler void
MessageReceived(BMessage * message)2764ccfb086SAxel Dörfler CPUButton::MessageReceived(BMessage *message)
2774ccfb086SAxel Dörfler {
27852a38012Sejakowatz 	switch (message->what) {
27952a38012Sejakowatz 		case B_ABOUT_REQUESTED: {
280*e04f6f31SAdrien Destugues 			be_app->PostMessage(B_ABOUT_REQUESTED);
28152a38012Sejakowatz 			break;
28252a38012Sejakowatz 		}
28352a38012Sejakowatz 		case PV_REPLICANT_PULSE: {
28452a38012Sejakowatz 			// Make sure we're consistent with our CPU
28587df8902SIngo Weinhold 			if (_kern_cpu_enabled(fCPU) != Value() && !IsTracking())
2864ccfb086SAxel Dörfler 				SetValue(!Value());
28752a38012Sejakowatz 			break;
28852a38012Sejakowatz 		}
289e20b1568SPhilippe Saint-Pierre 		case kDeleteReplicant: {
290e20b1568SPhilippe Saint-Pierre 			Window()->PostMessage(kDeleteReplicant, this, NULL);
291e20b1568SPhilippe Saint-Pierre 			break;
292e20b1568SPhilippe Saint-Pierre 		}
29352a38012Sejakowatz 		default:
29452a38012Sejakowatz 			BControl::MessageReceived(message);
29552a38012Sejakowatz 			break;
29652a38012Sejakowatz 	}
29752a38012Sejakowatz }
29852a38012Sejakowatz 
2994ccfb086SAxel Dörfler 
3004ccfb086SAxel Dörfler void
UpdateColors(int32 color)3014ccfb086SAxel Dörfler CPUButton::UpdateColors(int32 color)
3024ccfb086SAxel Dörfler {
3034ccfb086SAxel Dörfler 	fOnColor.red = (color & 0xff000000) >> 24;
3044ccfb086SAxel Dörfler 	fOnColor.green = (color & 0x00ff0000) >> 16;
3054ccfb086SAxel Dörfler 	fOnColor.blue = (color & 0x0000ff00) >> 8;
30652a38012Sejakowatz 	Draw(Bounds());
30752a38012Sejakowatz }
30852a38012Sejakowatz 
3094ccfb086SAxel Dörfler 
3104ccfb086SAxel Dörfler void
AttachedToWindow()3114ccfb086SAxel Dörfler CPUButton::AttachedToWindow()
3124ccfb086SAxel Dörfler {
31352a38012Sejakowatz 	SetTarget(this);
31452a38012Sejakowatz 	SetFont(be_plain_font);
31552a38012Sejakowatz 	SetFontSize(10);
31652a38012Sejakowatz 
317e20b1568SPhilippe Saint-Pierre 	fReplicantInDeskbar = false;
318e20b1568SPhilippe Saint-Pierre 
3194ccfb086SAxel Dörfler 	if (fReplicant) {
320919d3b76SPhilippe Saint-Pierre 		if (strcmp(Window()->Title(), B_TRANSLATE("Deskbar"))) {
321431bbe1cSPhilippe Saint-Pierre 			// Make room for dragger
322431bbe1cSPhilippe Saint-Pierre 			ResizeBy(4, 4);
323431bbe1cSPhilippe Saint-Pierre 
324e20b1568SPhilippe Saint-Pierre 			_AddDragger();
325e20b1568SPhilippe Saint-Pierre 		} else
326e20b1568SPhilippe Saint-Pierre 			fReplicantInDeskbar = true;
327e20b1568SPhilippe Saint-Pierre 
32852a38012Sejakowatz 		Prefs *prefs = new Prefs();
32952a38012Sejakowatz 		UpdateColors(prefs->normal_bar_color);
33052a38012Sejakowatz 		delete prefs;
33152a38012Sejakowatz 	} else {
33252a38012Sejakowatz 		PulseApp *pulseapp = (PulseApp *)be_app;
333*e04f6f31SAdrien Destugues 		UpdateColors(pulseapp->fPrefs->normal_bar_color);
334e20b1568SPhilippe Saint-Pierre 		_AddDragger();
33552a38012Sejakowatz 	}
33652a38012Sejakowatz 
33752a38012Sejakowatz 	BMessenger messenger(this);
3384ccfb086SAxel Dörfler 	fPulseRunner = new BMessageRunner(messenger, new BMessage(PV_REPLICANT_PULSE),
33952a38012Sejakowatz 		200000, -1);
34052a38012Sejakowatz }
34152a38012Sejakowatz 
3424ccfb086SAxel Dörfler 
3434ccfb086SAxel Dörfler void
DetachedFromWindow()3444ccfb086SAxel Dörfler CPUButton::DetachedFromWindow()
3454ccfb086SAxel Dörfler {
3464ccfb086SAxel Dörfler 	delete fPulseRunner;
34752a38012Sejakowatz }
348