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