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