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