152a38012Sejakowatz //**************************************************************************************** 252a38012Sejakowatz // 352a38012Sejakowatz // File: CPUButton.cpp 452a38012Sejakowatz // 552a38012Sejakowatz // Written by: Daniel Switkin 652a38012Sejakowatz // 752a38012Sejakowatz // Copyright 1999, Be Incorporated 852a38012Sejakowatz // 952a38012Sejakowatz //**************************************************************************************** 1052a38012Sejakowatz 114ccfb086SAxel Dörfler 1252a38012Sejakowatz #include "CPUButton.h" 1387df8902SIngo Weinhold 1487df8902SIngo Weinhold #include <stdlib.h> 15*2ee53d23SPhilippe Saint-Pierre #include <string.h> 1687df8902SIngo Weinhold 1787df8902SIngo Weinhold #include <Alert.h> 18e20b1568SPhilippe Saint-Pierre #include <Dragger.h> 19e20b1568SPhilippe Saint-Pierre #include <PopUpMenu.h> 20e20b1568SPhilippe Saint-Pierre 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 2952a38012Sejakowatz 304ccfb086SAxel Dörfler CPUButton::CPUButton(BRect rect, const char *name, const char *label, BMessage *message) 314ccfb086SAxel Dörfler : BControl(rect, name, label, message, B_FOLLOW_NONE, B_WILL_DRAW) 324ccfb086SAxel Dörfler { 3352a38012Sejakowatz SetValue(B_CONTROL_ON); 3452a38012Sejakowatz SetViewColor(B_TRANSPARENT_COLOR); 354ccfb086SAxel Dörfler fReplicant = false; 364ccfb086SAxel Dörfler 374ccfb086SAxel Dörfler _InitData(); 3852a38012Sejakowatz } 3952a38012Sejakowatz 404ccfb086SAxel Dörfler 414ccfb086SAxel Dörfler CPUButton::CPUButton(BMessage *message) 424ccfb086SAxel Dörfler : BControl(message) 434ccfb086SAxel Dörfler { 444ccfb086SAxel Dörfler fReplicant = true; 45e20b1568SPhilippe Saint-Pierre 46e20b1568SPhilippe Saint-Pierre /* We remove the dragger if we are in deskbar */ 47e20b1568SPhilippe Saint-Pierre if (CountChildren() > 1) 48e20b1568SPhilippe Saint-Pierre RemoveChild(ChildAt(1)); 49e20b1568SPhilippe Saint-Pierre 50e20b1568SPhilippe Saint-Pierre ResizeBy(-7, -7); 51e20b1568SPhilippe Saint-Pierre 524ccfb086SAxel Dörfler _InitData(); 5352a38012Sejakowatz } 5452a38012Sejakowatz 554ccfb086SAxel Dörfler 564ccfb086SAxel Dörfler CPUButton::~CPUButton() 574ccfb086SAxel Dörfler { 584ccfb086SAxel Dörfler } 594ccfb086SAxel Dörfler 604ccfb086SAxel Dörfler 614ccfb086SAxel Dörfler void 624ccfb086SAxel Dörfler CPUButton::_InitData() 634ccfb086SAxel Dörfler { 644ccfb086SAxel Dörfler fOffColor.red = fOffColor.green = fOffColor.blue = 184; 654ccfb086SAxel Dörfler fOffColor.alpha = 255; 664ccfb086SAxel Dörfler 674ccfb086SAxel Dörfler fCPU = atoi(Label()) - 1; 684ccfb086SAxel Dörfler } 694ccfb086SAxel Dörfler 704ccfb086SAxel Dörfler 71e20b1568SPhilippe Saint-Pierre void 72e20b1568SPhilippe Saint-Pierre CPUButton::_AddDragger() 73e20b1568SPhilippe Saint-Pierre { 74e20b1568SPhilippe Saint-Pierre BRect rect(Bounds()); 75e20b1568SPhilippe Saint-Pierre rect.top = rect.bottom - 7; 76e20b1568SPhilippe Saint-Pierre rect.left = rect.right - 7; 77e20b1568SPhilippe Saint-Pierre BDragger* dragger = new BDragger(rect, this, 78e20b1568SPhilippe Saint-Pierre B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 79e20b1568SPhilippe Saint-Pierre AddChild(dragger); 80e20b1568SPhilippe Saint-Pierre } 81e20b1568SPhilippe Saint-Pierre 82e20b1568SPhilippe Saint-Pierre 834ccfb086SAxel Dörfler //! Redraw the button depending on whether it's up or down 844ccfb086SAxel Dörfler void 854ccfb086SAxel Dörfler CPUButton::Draw(BRect rect) 864ccfb086SAxel Dörfler { 8752a38012Sejakowatz bool value = (bool)Value(); 884ccfb086SAxel Dörfler SetHighColor(value ? fOnColor : fOffColor); 8952a38012Sejakowatz 90e20b1568SPhilippe Saint-Pierre if (!fReplicant) { 91e20b1568SPhilippe Saint-Pierre SetLowColor(Parent()->LowColor()); 92e20b1568SPhilippe Saint-Pierre FillRect(Bounds(), B_SOLID_LOW); 93e20b1568SPhilippe Saint-Pierre } 94e20b1568SPhilippe Saint-Pierre 9552a38012Sejakowatz BRect bounds = Bounds(); 96e20b1568SPhilippe Saint-Pierre if (!fReplicantInDeskbar) { 97e20b1568SPhilippe Saint-Pierre bounds.bottom -= 7; 98e20b1568SPhilippe Saint-Pierre bounds.right -= 7; 99e20b1568SPhilippe Saint-Pierre } 10052a38012Sejakowatz BRect color_rect(bounds); 10152a38012Sejakowatz color_rect.InsetBy(2, 2); 10252a38012Sejakowatz if (value) { 10352a38012Sejakowatz color_rect.bottom -= 1; 10452a38012Sejakowatz color_rect.right -= 1; 10552a38012Sejakowatz } 10652a38012Sejakowatz FillRect(bounds); 10752a38012Sejakowatz 1084ccfb086SAxel Dörfler if (value) 1094ccfb086SAxel Dörfler SetHighColor(80, 80, 80); 1104ccfb086SAxel Dörfler else 1114ccfb086SAxel Dörfler SetHighColor(255, 255, 255); 1124ccfb086SAxel Dörfler 11352a38012Sejakowatz BPoint start(0, 0); 11452a38012Sejakowatz BPoint end(bounds.right, 0); 11552a38012Sejakowatz StrokeLine(start, end); 11652a38012Sejakowatz end.Set(0, bounds.bottom); 11752a38012Sejakowatz StrokeLine(start, end); 11852a38012Sejakowatz 1194ccfb086SAxel Dörfler if (value) 1204ccfb086SAxel Dörfler SetHighColor(32, 32, 32); 1214ccfb086SAxel Dörfler else 1224ccfb086SAxel Dörfler SetHighColor(216, 216, 216); 1234ccfb086SAxel Dörfler 12452a38012Sejakowatz start.Set(1, 1); 12552a38012Sejakowatz end.Set(bounds.right - 1, 1); 12652a38012Sejakowatz StrokeLine(start, end); 12752a38012Sejakowatz end.Set(1, bounds.bottom - 1); 12852a38012Sejakowatz StrokeLine(start, end); 12952a38012Sejakowatz 1304ccfb086SAxel Dörfler if (value) 1314ccfb086SAxel Dörfler SetHighColor(216, 216, 216); 1324ccfb086SAxel Dörfler else 1334ccfb086SAxel Dörfler SetHighColor(80, 80, 80); 1344ccfb086SAxel Dörfler 13552a38012Sejakowatz start.Set(bounds.left + 1, bounds.bottom - 1); 13652a38012Sejakowatz end.Set(bounds.right - 1, bounds.bottom - 1); 13752a38012Sejakowatz StrokeLine(start, end); 13852a38012Sejakowatz start.Set(bounds.right - 1, bounds.top + 1); 13952a38012Sejakowatz StrokeLine(start, end); 14052a38012Sejakowatz 1414ccfb086SAxel Dörfler if (value) 1424ccfb086SAxel Dörfler SetHighColor(255, 255, 255); 1434ccfb086SAxel Dörfler else 1444ccfb086SAxel Dörfler SetHighColor(32, 32, 32); 1454ccfb086SAxel Dörfler 14652a38012Sejakowatz start.Set(bounds.left, bounds.bottom); 14752a38012Sejakowatz end.Set(bounds.right, bounds.bottom); 14852a38012Sejakowatz StrokeLine(start, end); 14952a38012Sejakowatz start.Set(bounds.right, bounds.top); 15052a38012Sejakowatz StrokeLine(start, end); 15152a38012Sejakowatz 15252a38012Sejakowatz if (value) { 15352a38012Sejakowatz SetHighColor(0, 0, 0); 15452a38012Sejakowatz start.Set(bounds.left + 2, bounds.bottom - 2); 15552a38012Sejakowatz end.Set(bounds.right - 2, bounds.bottom - 2); 15652a38012Sejakowatz StrokeLine(start, end); 15752a38012Sejakowatz start.Set(bounds.right - 2, bounds.top + 2); 15852a38012Sejakowatz StrokeLine(start, end); 15952a38012Sejakowatz } 16052a38012Sejakowatz 16152a38012Sejakowatz // Try to keep the text centered 16252a38012Sejakowatz BFont font; 16352a38012Sejakowatz GetFont(&font); 16452a38012Sejakowatz int label_width = (int)font.StringWidth(Label()); 16552a38012Sejakowatz int rect_width = bounds.IntegerWidth() - 1; 16652a38012Sejakowatz int rect_height = bounds.IntegerHeight(); 16752a38012Sejakowatz font_height fh; 16852a38012Sejakowatz font.GetHeight(&fh); 16952a38012Sejakowatz int label_height = (int)fh.ascent; 17052a38012Sejakowatz int x_pos = (int)(((double)(rect_width - label_width) / 2.0) + 0.5); 17152a38012Sejakowatz int y_pos = (rect_height - label_height) / 2 + label_height; 17252a38012Sejakowatz 17352a38012Sejakowatz MovePenTo(x_pos, y_pos); 17452a38012Sejakowatz SetHighColor(0, 0, 0); 17552a38012Sejakowatz SetDrawingMode(B_OP_OVER); 17652a38012Sejakowatz DrawString(Label()); 17752a38012Sejakowatz } 17852a38012Sejakowatz 1794ccfb086SAxel Dörfler 1804ccfb086SAxel Dörfler //! Track the mouse without blocking the window 1814ccfb086SAxel Dörfler void 1824ccfb086SAxel Dörfler CPUButton::MouseDown(BPoint point) 1834ccfb086SAxel Dörfler { 184e20b1568SPhilippe Saint-Pierre BPoint mousePosition; 185e20b1568SPhilippe Saint-Pierre uint32 mouseButtons; 186e20b1568SPhilippe Saint-Pierre 187e20b1568SPhilippe Saint-Pierre GetMouse(&mousePosition, &mouseButtons); 188e20b1568SPhilippe Saint-Pierre 189e20b1568SPhilippe Saint-Pierre if ((B_PRIMARY_MOUSE_BUTTON & mouseButtons) != 0) { 19052a38012Sejakowatz SetValue(!Value()); 19152a38012Sejakowatz SetTracking(true); 19252a38012Sejakowatz SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); 193e20b1568SPhilippe Saint-Pierre } else if ((B_SECONDARY_MOUSE_BUTTON & mouseButtons) != 0 194e20b1568SPhilippe Saint-Pierre && fReplicantInDeskbar) { 195e20b1568SPhilippe Saint-Pierre BPopUpMenu *menu = new BPopUpMenu("Deskbar menu"); 196e20b1568SPhilippe Saint-Pierre menu->AddItem(new BMenuItem("About Pulse" B_UTF8_ELLIPSIS, 197e20b1568SPhilippe Saint-Pierre new BMessage(B_ABOUT_REQUESTED))); 198e20b1568SPhilippe Saint-Pierre menu->AddSeparatorItem(); 199e20b1568SPhilippe Saint-Pierre menu->AddItem(new BMenuItem("Remove replicant", 200e20b1568SPhilippe Saint-Pierre new BMessage(kDeleteReplicant))); 201e20b1568SPhilippe Saint-Pierre menu->SetTargetForItems(this); 202e20b1568SPhilippe Saint-Pierre 203e20b1568SPhilippe Saint-Pierre ConvertToScreen(&point); 204e20b1568SPhilippe Saint-Pierre menu->Go(point, true, true, true); 205e20b1568SPhilippe Saint-Pierre } 20652a38012Sejakowatz } 20752a38012Sejakowatz 2084ccfb086SAxel Dörfler 2094ccfb086SAxel Dörfler void 2104ccfb086SAxel Dörfler CPUButton::MouseUp(BPoint point) 2114ccfb086SAxel Dörfler { 212e20b1568SPhilippe Saint-Pierre if (IsTracking()) { 2134ccfb086SAxel Dörfler if (Bounds().Contains(point)) 2144ccfb086SAxel Dörfler Invoke(); 2154ccfb086SAxel Dörfler 21652a38012Sejakowatz SetTracking(false); 21752a38012Sejakowatz } 218e20b1568SPhilippe Saint-Pierre } 21952a38012Sejakowatz 2204ccfb086SAxel Dörfler 2214ccfb086SAxel Dörfler void 2224ccfb086SAxel Dörfler CPUButton::MouseMoved(BPoint point, uint32 transit, const BMessage *message) 2234ccfb086SAxel Dörfler { 22452a38012Sejakowatz if (IsTracking()) { 2254ccfb086SAxel Dörfler if (transit == B_ENTERED_VIEW || transit == B_EXITED_VIEW) 2264ccfb086SAxel Dörfler SetValue(!Value()); 22752a38012Sejakowatz } 22852a38012Sejakowatz } 22952a38012Sejakowatz 23052a38012Sejakowatz 2314ccfb086SAxel Dörfler status_t 2324ccfb086SAxel Dörfler CPUButton::Invoke(BMessage *message) 2334ccfb086SAxel Dörfler { 2344ccfb086SAxel Dörfler if (!LastEnabledCPU(fCPU)) { 23587df8902SIngo Weinhold _kern_set_cpu_enabled(fCPU, Value()); 23652a38012Sejakowatz } else { 23752a38012Sejakowatz BAlert *alert = new BAlert(NULL, "You can't disable the last active CPU.", "OK"); 23852a38012Sejakowatz alert->Go(NULL); 23952a38012Sejakowatz SetValue(!Value()); 24052a38012Sejakowatz } 24152a38012Sejakowatz 24252a38012Sejakowatz return B_OK; 24352a38012Sejakowatz } 24452a38012Sejakowatz 2454ccfb086SAxel Dörfler 2464ccfb086SAxel Dörfler CPUButton * 2474ccfb086SAxel Dörfler CPUButton::Instantiate(BMessage *data) 2484ccfb086SAxel Dörfler { 2494ccfb086SAxel Dörfler if (!validate_instantiation(data, "CPUButton")) 2504ccfb086SAxel Dörfler return NULL; 2514ccfb086SAxel Dörfler 25252a38012Sejakowatz return new CPUButton(data); 25352a38012Sejakowatz } 25452a38012Sejakowatz 2554ccfb086SAxel Dörfler 2564ccfb086SAxel Dörfler status_t 2574ccfb086SAxel Dörfler CPUButton::Archive(BMessage *data, bool deep) const 2584ccfb086SAxel Dörfler { 25952a38012Sejakowatz BControl::Archive(data, deep); 26052a38012Sejakowatz data->AddString("add_on", APP_SIGNATURE); 26152a38012Sejakowatz data->AddString("class", "CPUButton"); 26252a38012Sejakowatz return B_OK; 26352a38012Sejakowatz } 26452a38012Sejakowatz 2654ccfb086SAxel Dörfler 2664ccfb086SAxel Dörfler void 2674ccfb086SAxel Dörfler CPUButton::MessageReceived(BMessage *message) 2684ccfb086SAxel Dörfler { 26952a38012Sejakowatz switch (message->what) { 27052a38012Sejakowatz case B_ABOUT_REQUESTED: { 27152a38012Sejakowatz BAlert *alert = new BAlert("Info", "Pulse\n\nBy David Ramsey and Arve Hjønnevåg\nRevised by Daniel Switkin", "OK"); 27252a38012Sejakowatz // Use the asynchronous version so we don't block the window's thread 27352a38012Sejakowatz alert->Go(NULL); 27452a38012Sejakowatz break; 27552a38012Sejakowatz } 27652a38012Sejakowatz case PV_REPLICANT_PULSE: { 27752a38012Sejakowatz // Make sure we're consistent with our CPU 27887df8902SIngo Weinhold if (_kern_cpu_enabled(fCPU) != Value() && !IsTracking()) 2794ccfb086SAxel Dörfler SetValue(!Value()); 28052a38012Sejakowatz break; 28152a38012Sejakowatz } 282e20b1568SPhilippe Saint-Pierre case kDeleteReplicant: { 283e20b1568SPhilippe Saint-Pierre Window()->PostMessage(kDeleteReplicant, this, NULL); 284e20b1568SPhilippe Saint-Pierre break; 285e20b1568SPhilippe Saint-Pierre } 28652a38012Sejakowatz default: 28752a38012Sejakowatz BControl::MessageReceived(message); 28852a38012Sejakowatz break; 28952a38012Sejakowatz } 29052a38012Sejakowatz } 29152a38012Sejakowatz 2924ccfb086SAxel Dörfler 2934ccfb086SAxel Dörfler void 2944ccfb086SAxel Dörfler CPUButton::UpdateColors(int32 color) 2954ccfb086SAxel Dörfler { 2964ccfb086SAxel Dörfler fOnColor.red = (color & 0xff000000) >> 24; 2974ccfb086SAxel Dörfler fOnColor.green = (color & 0x00ff0000) >> 16; 2984ccfb086SAxel Dörfler fOnColor.blue = (color & 0x0000ff00) >> 8; 29952a38012Sejakowatz Draw(Bounds()); 30052a38012Sejakowatz } 30152a38012Sejakowatz 3024ccfb086SAxel Dörfler 3034ccfb086SAxel Dörfler void 3044ccfb086SAxel Dörfler CPUButton::AttachedToWindow() 3054ccfb086SAxel Dörfler { 30652a38012Sejakowatz SetTarget(this); 30752a38012Sejakowatz SetFont(be_plain_font); 30852a38012Sejakowatz SetFontSize(10); 30952a38012Sejakowatz 310e20b1568SPhilippe Saint-Pierre fReplicantInDeskbar = false; 311e20b1568SPhilippe Saint-Pierre 3124ccfb086SAxel Dörfler if (fReplicant) { 313e20b1568SPhilippe Saint-Pierre if (strcmp(Window()->Title(), "Deskbar")) { 314e20b1568SPhilippe Saint-Pierre // return to original size 315e20b1568SPhilippe Saint-Pierre ResizeBy(7, 7); 316e20b1568SPhilippe Saint-Pierre _AddDragger(); 317e20b1568SPhilippe Saint-Pierre } else 318e20b1568SPhilippe Saint-Pierre fReplicantInDeskbar = true; 319e20b1568SPhilippe Saint-Pierre 32052a38012Sejakowatz Prefs *prefs = new Prefs(); 32152a38012Sejakowatz UpdateColors(prefs->normal_bar_color); 32252a38012Sejakowatz delete prefs; 32352a38012Sejakowatz } else { 32452a38012Sejakowatz PulseApp *pulseapp = (PulseApp *)be_app; 32552a38012Sejakowatz UpdateColors(pulseapp->prefs->normal_bar_color); 326e20b1568SPhilippe Saint-Pierre _AddDragger(); 32752a38012Sejakowatz } 32852a38012Sejakowatz 32952a38012Sejakowatz BMessenger messenger(this); 3304ccfb086SAxel Dörfler fPulseRunner = new BMessageRunner(messenger, new BMessage(PV_REPLICANT_PULSE), 33152a38012Sejakowatz 200000, -1); 33252a38012Sejakowatz } 33352a38012Sejakowatz 3344ccfb086SAxel Dörfler 3354ccfb086SAxel Dörfler void 3364ccfb086SAxel Dörfler CPUButton::DetachedFromWindow() 3374ccfb086SAxel Dörfler { 3384ccfb086SAxel Dörfler delete fPulseRunner; 33952a38012Sejakowatz } 340