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