statusbar.cpp (10242B)
1 // Copyright (c) 2003 - 2009 Anselm R Garbe <anselm@garbe.us> 2 // See LICENSE for license details. 3 4 extern "C" { 5 #include <assert.h> 6 } 7 8 #include "statusbar.h" 9 10 #include "binder.h" 11 #include "client.h" 12 #include "cursors.h" 13 #include "draw.h" 14 #include "kernel.h" 15 #include "inputbar.h" 16 #include "label.h" 17 #include "logger.h" 18 #include "rectangle.h" 19 #include "workspace.h" 20 #include "monitor.h" 21 #include "theme.h" 22 #include "util.h" 23 #include "xcore.h" 24 25 StatusBar::StatusBar(Monitor *monitor, Rectangle *rect) 26 : Bar(monitor, rect) 27 { 28 text_ = "window manager improved - " + string(__WMI_VERSION); 29 buttonPressed_ = false; 30 } 31 32 void StatusBar::illuminate() { 33 34 if (!isVisible()) { 35 return; 36 } 37 38 LOGDEBUG("going to draw border"); 39 drawBorder(); 40 41 unsigned int offsetX = 1; 42 43 label_->setAlignment(Label::CENTER); 44 label_->setText(""); 45 label_->setX(offsetX); 46 label_->setWidth(width() - 2); 47 label_->update(theme_->BAR_BACKGROUND, theme_->BAR_TEXT, 48 theme_->BAR_SHINE, theme_->BAR_SHADOW); 49 50 updateInputModeButton(&offsetX); 51 updateWorkspacePager(&offsetX); 52 updateStatus(&offsetX); 53 updateMeters(offsetX); 54 55 XCORE->sync(); 56 } 57 58 StatusBar::~StatusBar() { 59 } 60 61 void StatusBar::updateInputModeButton(unsigned int *offsetX) { 62 63 if (!isButtonVisible_) { 64 return; 65 } 66 67 // input mode button 68 label_->setX(*offsetX); 69 label_->setText(""); 70 label_->setWidth(monitor()->buttonWidth()); 71 if (!buttonPressed_) { 72 73 Draw::drawInputModeButton(window(), gc(), label_, 74 theme_->BUTTON_BACKGROUND_NORMAL, 75 theme_->BUTTON_SHINE_BORDER_NORMAL, 76 theme_->BUTTON_SHADOW_BORDER_NORMAL, 77 theme_->BUTTON_SHINE_FIGURE_NORMAL, 78 theme_->BUTTON_SHADOW_FIGURE_NORMAL); 79 } 80 else { 81 82 Draw::drawInputModeButton(window(), gc(), label_, 83 theme_->BUTTON_BACKGROUND_PRESSED, 84 theme_->BUTTON_SHINE_BORDER_PRESSED, 85 theme_->BUTTON_SHADOW_BORDER_PRESSED, 86 theme_->BUTTON_SHINE_FIGURE_PRESSED, 87 theme_->BUTTON_SHADOW_FIGURE_PRESSED); 88 } 89 *offsetX += monitor()->buttonWidth() + 2; 90 } 91 92 unsigned int StatusBar::calculateWorkspaceWidth() { 93 94 // workspace pager stuff 95 Workspace *focusedWorkspace = monitor()->focused(); 96 assert(focusedWorkspace); 97 98 // first determine maximum workspace label width 99 unsigned int workspaceWidth = 0; 100 for (LWorkspace::iterator it = monitor()->begin(); 101 it != monitor()->end(); it++) 102 { 103 Workspace *workspace = *it; 104 label_->setText(workspace->name()); 105 label_->adjustWidth(); 106 if (label_->width() > workspaceWidth) { 107 workspaceWidth = label_->width(); 108 } 109 } 110 111 return workspaceWidth; 112 } 113 114 void StatusBar::updateWorkspacePager(unsigned int *offsetX) { 115 116 // workspace pager stuff 117 Workspace *focusedWorkspace = monitor()->focused(); 118 assert(focusedWorkspace); 119 unsigned int workspaceWidth = calculateWorkspaceWidth(); 120 unsigned int i = 0; 121 label_->setWidth(workspaceWidth); 122 for (LWorkspace::iterator it = monitor()->begin(); 123 it != monitor()->end(); it++) 124 { 125 Workspace *workspace = *it; 126 label_->setX(i * workspaceWidth + *offsetX); 127 label_->setText(workspace->name()); 128 if (workspace == focusedWorkspace) { 129 label_->update(theme_->LABEL_BACKGROUND_FOCUSSED, 130 theme_->LABEL_TEXT_FOCUSSED, 131 theme_->LABEL_SHINE_FOCUSSED, 132 theme_->LABEL_SHADOW_FOCUSSED, 133 true, true); 134 } 135 else if (workspace->requestsFocus()) { 136 label_->update(theme_->FOCUSREQ_BACKGROUND, 137 theme_->FOCUSREQ_TEXT, 138 theme_->FOCUSREQ_SHINE, 139 theme_->FOCUSREQ_SHADOW, 140 true, true); 141 } 142 else { 143 label_->update(theme_->LABEL_BACKGROUND_NORMAL, 144 theme_->LABEL_TEXT_NORMAL, 145 theme_->LABEL_SHINE_NORMAL, 146 theme_->LABEL_SHADOW_NORMAL, 147 true, true); 148 } 149 i++; 150 } 151 *offsetX += i * workspaceWidth + 2; 152 } 153 154 unsigned int StatusBar::calculateMetersWidth() { 155 156 unsigned int result = 0; 157 if (meterText_ != "") { 158 string percentage = ""; 159 string text = ""; 160 bool isPercentage = true; 161 unsigned int meterWidth = monitor()->buttonWidth() / 2; 162 for (string::iterator it = meterText_.begin(); 163 it != meterText_.end(); ) 164 { 165 166 char c = *it; 167 it++; 168 bool isEndreached = it == meterText_.end(); 169 if (c == '%') { 170 isPercentage = false; 171 } 172 if ((c == ',') || isEndreached) { 173 if (isEndreached && (c != '%')) { 174 text += c; 175 } 176 isPercentage = true; 177 result += 2 + meterWidth; 178 if (text != "") { 179 label_->setAlignment(Label::LEFT); 180 label_->setText(text); 181 result += label_->textWidth(); 182 } 183 text = ""; 184 percentage = ""; 185 } 186 else if (isPercentage && (c == '!')) { 187 // do nothing here 188 } 189 else if (c != '%') { 190 if (isPercentage) { 191 percentage += c; 192 } 193 else { 194 text += c; 195 } 196 } 197 } 198 } 199 return result; 200 } 201 202 void StatusBar::updateMeters(unsigned int offsetX) { 203 204 if (meterText_ != "") { 205 206 string percentage = ""; 207 string text = ""; 208 bool isPercentage = true; 209 bool isNegotiated = false; 210 unsigned int meterWidth = monitor()->buttonWidth() / 2; 211 label_->setX(offsetX); 212 label_->setWidth(0); 213 for (string::iterator it = meterText_.begin(); 214 it != meterText_.end(); ) 215 { 216 217 char c = *it; 218 it++; 219 bool isEndreached = it == meterText_.end(); 220 if (c == '%') { 221 isPercentage = false; 222 } 223 if ((c == ',') || isEndreached) { 224 if (isEndreached && (c != '%')) { 225 text += c; 226 } 227 label_->setX(label_->x() + label_->width() + 2); 228 label_->setWidth(meterWidth); 229 int percent = Util::strToUInt(percentage); 230 if (percent < 0) { 231 percent = 0; 232 } 233 else if (percent > 99) { 234 percent = 99; 235 } 236 Draw::drawMeter(window(), gc(), label_, percent, 237 theme_->METER_BACKGROUND, 238 isNegotiated ? theme_->METER_FIGURE_LOW : theme_->METER_FIGURE_HIGH, 239 theme_->METER_FIGURE_NORMAL, 240 isNegotiated ? theme_->METER_FIGURE_HIGH : theme_->METER_FIGURE_LOW, 241 theme_->METER_BORDER_SHINE, 242 theme_->METER_BORDER_SHADOW); 243 if (text != "") { 244 label_->setAlignment(Label::LEFT); 245 label_->setX(label_->x() + label_->width()); 246 label_->setText(text); 247 label_->adjustWidth(); 248 label_->update(theme_->BAR_BACKGROUND, theme_->BAR_TEXT, 249 theme_->BAR_SHINE, theme_->BAR_SHADOW); 250 } 251 text = ""; 252 percentage = ""; 253 isPercentage = true; 254 isNegotiated = false; 255 } 256 else if (isPercentage && (c == '!')) { 257 isNegotiated = true; 258 } 259 else if (c != '%') { 260 261 if (isPercentage) { 262 percentage += c; 263 } 264 else { 265 text += c; 266 } 267 } 268 } 269 } 270 } 271 272 void StatusBar::updateStatus(unsigned int *offsetX) { 273 274 unsigned int metersWidth = calculateMetersWidth(); 275 276 // user defined status text 277 label_->setAlignment(Label::RIGHT); 278 label_->setX(*offsetX); 279 label_->setWidth(width() - *offsetX - metersWidth - 5); 280 label_->setText(text_); 281 label_->update(theme_->BAR_BACKGROUND, theme_->BAR_TEXT, 282 theme_->BAR_SHINE, theme_->BAR_SHADOW); 283 284 *offsetX = label_->x() + label_->width() + 2; 285 } 286 287 void StatusBar::handleButtonRelease(XButtonEvent *event) { 288 289 // TODO: make buttons customizable 290 if (buttonPressed_) { 291 if (event->button == Button1) { 292 LOGDEBUG("toggling interactive mode"); 293 monitor()->inputBar()->runKey(KERNEL->defaultPrompt()); 294 buttonPressed_ = false; 295 } 296 } 297 } 298 299 void StatusBar::handleButtonPress(XButtonEvent *event) { 300 301 if ((event->window != window())) { 302 return; 303 } 304 305 XCORE->raise(window()); 306 307 // TODO: make buttons customizable 308 if (event->button == Button1) { 309 invokeClickedThing(event->x); 310 } 311 else if (event->button == Button4) { 312 monitor()->focus(monitor()->prev()); 313 } 314 else if (event->button == Button5) { 315 monitor()->focus(monitor()->next()); 316 } 317 } 318 319 void StatusBar::handleMotionNotify(XMotionEvent *event) { 320 321 if (buttonPressed_) { 322 buttonPressed_ = false; 323 illuminate(); 324 } 325 } 326 327 void StatusBar::invokeClickedThing(int xPosition) { 328 329 if (isButtonVisible_) { 330 if (xPosition < (int)monitor()->buttonWidth() + 1) { 331 buttonPressed_ = true; 332 illuminate(); 333 return; 334 } 335 xPosition -= (monitor()->buttonWidth() + 3); 336 } 337 338 unsigned int workspaceNum = xPosition / calculateWorkspaceWidth(); 339 if (workspaceNum < monitor()->size()) { 340 monitor()->focusWorkspaceNum(workspaceNum); 341 } 342 illuminate(); 343 } 344 345 void StatusBar::setText(const string text) { 346 text_ = text; 347 } 348 349 void StatusBar::setMeterText(const string meterText) { 350 meterText_ = meterText; 351 }