clientbar.cpp (10313B)
1 // Copyright (c) 2003 - 2009 Anselm R Garbe <anselm@garbe.us> 2 // See LICENSE for license details. 3 4 #include <list> 5 #include <string> 6 #include <sstream> 7 8 #include "clientbar.h" 9 10 #include "client.h" 11 #include "cursors.h" 12 #include "draw.h" 13 #include "frame.h" 14 #include "label.h" 15 #include "logger.h" 16 #include "menu.h" 17 #include "monitor.h" 18 #include "theme.h" 19 #include "thing.h" 20 #include "validators.h" 21 #include "workspace.h" 22 #include "xcore.h" 23 24 ClientBar::ClientBar(Monitor *monitor, Rectangle *rect) 25 : Bar(monitor, rect) 26 { 27 isModeButtonPressed_ = isMenuButtonPressed_ = false; 28 mode_ = PAGER; 29 menu_ = new Menu(monitor); 30 } 31 32 ClientBar::~ClientBar() { 33 } 34 35 void ClientBar::illuminate() { 36 37 if (!isVisible()) { 38 return; 39 } 40 41 LOGDEBUG("going to draw border"); 42 drawBorder(); 43 44 label_->setText(""); 45 label_->setX(1); 46 label_->setWidth(width() - 2); 47 label_->update(theme_->BAR_BACKGROUND, theme_->BAR_TEXT, 48 theme_->BAR_SHINE, theme_->BAR_SHADOW); 49 50 updateMenuButton(); 51 if (mode_ == PAGER) { 52 updateClientPager(); 53 } 54 else { 55 updateClientInfo(); 56 } 57 updateModeButton(); 58 } 59 60 61 void ClientBar::updateClientPager() { 62 63 Workspace *workspace = monitor()->focused(); 64 CClient *clients = workspace->floatingClients(); 65 if (clients->size() > 0) { 66 unsigned int offsetX = isButtonVisible_ ? monitor()->buttonWidth() + 3 : 1; 67 unsigned int clientsWidth = width() - 2; 68 if (isButtonVisible_) { 69 clientsWidth -= (2 * monitor()->buttonWidth() + 4); 70 } 71 unsigned int i = 0; 72 unsigned int clientWidth = clientsWidth / clients->size(); 73 label_->setWidth(clientWidth); 74 for (LClient::iterator it = clients->begin(); it != clients->end(); ) { 75 Client *client = *it; 76 it++; 77 78 label_->setX(offsetX + i * clientWidth); 79 if (it == clients->end()) { 80 // FIX for right button irretations 81 label_->setWidth(width() - label_->x() 82 - (isButtonVisible_ ? monitor()->buttonWidth() + 3 : 1)); 83 } 84 unsigned long shine, shadow; 85 label_->setText(client->name()); 86 if (client->isFocused()) { 87 shine = theme_->TAB_SHINE_ACTIVE_FOCUSSED; 88 shadow = theme_->TAB_SHADOW_ACTIVE_FOCUSSED; 89 label_->update(theme_->TAB_BACKGROUND_ACTIVE_FOCUSSED, 90 theme_->TAB_TEXT_ACTIVE_FOCUSSED, 91 shine, shadow, true, true); 92 } 93 else if (client->requestsFocus()) { 94 shine = theme_->FOCUSREQ_SHINE; 95 shadow = theme_->FOCUSREQ_SHADOW; 96 label_->update(theme_->FOCUSREQ_BACKGROUND, 97 theme_->FOCUSREQ_TEXT, 98 shine, shadow, true, true); 99 } 100 else { 101 shine = theme_->TAB_SHINE_ACTIVE_NORMAL; 102 shadow = theme_->TAB_SHADOW_ACTIVE_NORMAL; 103 label_->update(theme_->TAB_BACKGROUND_ACTIVE_NORMAL, 104 theme_->TAB_TEXT_ACTIVE_NORMAL, 105 shine, shadow, true, true); 106 } 107 108 if (client->mode() == Client::STICKY) { 109 Draw::drawStickyNotifier(window(), gc(), label_, 110 shine, shadow, 111 label_->textWidth()); 112 } 113 i++; 114 } 115 } 116 } 117 118 void ClientBar::updateMenuButton() { 119 120 // button stuff 121 if (!isButtonVisible_) { 122 return; 123 } 124 125 label_->setText(""); 126 label_->setX(1); 127 label_->setWidth(monitor()->buttonWidth()); 128 if (isMenuButtonPressed_) { 129 Draw::drawMenuButton(window(), gc(), label_, 130 theme_->BUTTON_BACKGROUND_PRESSED, 131 theme_->BUTTON_SHINE_BORDER_PRESSED, 132 theme_->BUTTON_SHADOW_BORDER_PRESSED, 133 theme_->BUTTON_SHINE_FIGURE_PRESSED, 134 theme_->BUTTON_SHADOW_FIGURE_PRESSED); 135 } 136 else { 137 Draw::drawMenuButton(window(), gc(), label_, 138 theme_->BUTTON_BACKGROUND_NORMAL, 139 theme_->BUTTON_SHINE_BORDER_NORMAL, 140 theme_->BUTTON_SHADOW_BORDER_NORMAL, 141 theme_->BUTTON_SHINE_FIGURE_NORMAL, 142 theme_->BUTTON_SHADOW_FIGURE_NORMAL); 143 } 144 } 145 146 void ClientBar::updateModeButton() { 147 148 // button stuff 149 if (!isButtonVisible_) { 150 return; 151 } 152 153 Workspace *workspace = monitor()->focused(); 154 155 label_->setText(""); 156 label_->setX(width() - monitor()->buttonWidth() - 1); 157 label_->setWidth(monitor()->buttonWidth()); 158 if (isModeButtonPressed_) { 159 if (workspace->isFrameMode()) { 160 Draw::drawFloatButton(window(), gc(), label_, 161 theme_->BUTTON_BACKGROUND_PRESSED, 162 theme_->BUTTON_SHINE_BORDER_PRESSED, 163 theme_->BUTTON_SHADOW_BORDER_PRESSED, 164 theme_->BUTTON_SHINE_FIGURE_PRESSED, 165 theme_->BUTTON_SHADOW_FIGURE_PRESSED, 166 workspace->floatingClients()->size()); 167 } 168 else { 169 Draw::drawMaxButton(window(), gc(), label_, 170 theme_->BUTTON_BACKGROUND_PRESSED, 171 theme_->BUTTON_SHINE_BORDER_PRESSED, 172 theme_->BUTTON_SHADOW_BORDER_PRESSED, 173 theme_->BUTTON_SHINE_FIGURE_PRESSED, 174 theme_->BUTTON_SHADOW_FIGURE_PRESSED, 175 workspace->focusedFrame() && 176 workspace->focusedFrame()->size()); 177 } 178 } 179 else { 180 if (workspace->isFrameMode()) { 181 Draw::drawFloatButton(window(), gc(), label_, 182 theme_->BUTTON_BACKGROUND_NORMAL, 183 theme_->BUTTON_SHINE_BORDER_NORMAL, 184 theme_->BUTTON_SHADOW_BORDER_NORMAL, 185 theme_->BUTTON_SHINE_FIGURE_NORMAL, 186 theme_->BUTTON_SHADOW_FIGURE_NORMAL, 187 workspace->floatingClients()->size()); 188 } 189 else { 190 Draw::drawMaxButton(window(), gc(), label_, 191 theme_->BUTTON_BACKGROUND_NORMAL, 192 theme_->BUTTON_SHINE_BORDER_NORMAL, 193 theme_->BUTTON_SHADOW_BORDER_NORMAL, 194 theme_->BUTTON_SHINE_FIGURE_NORMAL, 195 theme_->BUTTON_SHADOW_FIGURE_NORMAL, 196 workspace->focusedFrame() && 197 workspace->focusedFrame()->size()); 198 } 199 } 200 } 201 202 void ClientBar::updateClientInfo() { 203 204 // client info stuff 205 Workspace *focusedWorkspace = monitor()->focused(); 206 Client *client = focusedWorkspace->topClient(); 207 unsigned int offsetX = isButtonVisible_ ? monitor()->buttonWidth() + 3 : 1; 208 unsigned int clientInfoWidth = width() - 2; 209 if (isButtonVisible_) { 210 clientInfoWidth -= (2 * monitor()->buttonWidth() + 4); 211 } 212 label_->setX(offsetX); 213 label_->setWidth(clientInfoWidth); 214 label_->setText(client ? client->name() : ""); 215 label_->update(theme_->LABEL_BACKGROUND_FOCUSSED, 216 theme_->LABEL_TEXT_FOCUSSED, 217 theme_->LABEL_SHINE_FOCUSSED, 218 theme_->LABEL_SHADOW_FOCUSSED, 219 true, true); 220 if (client->mode() == Client::STICKY) { 221 Draw::drawStickyNotifier(window(), gc(), label_, 222 theme_->LABEL_SHINE_FOCUSSED, 223 theme_->LABEL_SHADOW_FOCUSSED, 224 label_->textWidth()); 225 } 226 } 227 228 void ClientBar::handleButtonRelease(XButtonEvent *event) { 229 230 if ((event->window != window())) { 231 return; 232 } 233 234 if (isModeButtonPressed_) { 235 isModeButtonPressed_ = false; 236 Workspace *ws = monitor()->focused(); 237 if ((event->button == Button1) && 238 Validators::instance()->validateToggleMode()) 239 { 240 ws->toggleMode(); 241 } 242 illuminate(); 243 } 244 else if (isMenuButtonPressed_) { 245 toggleMenuMode(); 246 } 247 } 248 249 void ClientBar::toggleMenuMode() { 250 251 if (menu_->isVisible()) { 252 menu_->hide(); 253 isMenuButtonPressed_ = false; 254 } 255 else { 256 menu_->show(); 257 } 258 illuminate(); 259 } 260 261 void ClientBar::handleButtonPress(XButtonEvent *event) { 262 263 if ((event->window != window())) { 264 return; 265 } 266 267 XCORE->raise(window()); 268 269 // TODO: make buttons customizable 270 if (event->button == Button1) { 271 invokeClickedThing(event->x); 272 } 273 else if (event->button == Button4) { 274 monitor()->focused()->cycleClientPrev(); 275 } 276 else if (event->button == Button5) { 277 monitor()->focused()->cycleClientNext(); 278 } 279 } 280 281 void ClientBar::handleMotionNotify(XMotionEvent *event) { 282 283 if (isModeButtonPressed_) { 284 isModeButtonPressed_ = false; 285 illuminate(); 286 } 287 } 288 289 void ClientBar::invokeClickedThing(int xPosition) { 290 291 if (isButtonVisible_) { 292 if (xPosition < (int)(monitor()->buttonWidth() + 1)) { 293 isMenuButtonPressed_ = true; 294 } 295 else if (xPosition > (int)(width() - monitor()->buttonWidth() - 2)) { 296 isModeButtonPressed_ = true; 297 } 298 illuminate(); 299 if (isModeButtonPressed_ || isMenuButtonPressed_) { 300 return; 301 } 302 } 303 304 if (mode_ != PAGER) { 305 illuminate(); 306 return; 307 } 308 309 Workspace *workspace = monitor()->focused(); 310 unsigned int clientsWidth = width() - 2; 311 if (isButtonVisible_) { 312 clientsWidth -= (2 * monitor()->buttonWidth() + 4); 313 xPosition -= (monitor()->buttonWidth() + 3); 314 } 315 else { 316 xPosition -= 1; 317 } 318 319 CClient *clients = workspace->floatingClients(); 320 if (!clients->size()) { 321 return; 322 } 323 324 unsigned int clientNum = xPosition / (clientsWidth / clients->size()); 325 unsigned i = 0; 326 for (LClient::iterator it = clients->begin(); it != clients->end(); it++) { 327 if (i == clientNum) { 328 workspace->focus(*it); 329 illuminate(); 330 return; 331 } 332 i++; 333 } 334 } 335 336 Menu *ClientBar::menu() const { 337 return menu_; 338 } 339 340 void ClientBar::setMode(ClientBar::Mode mode) { 341 mode_ = mode; 342 } 343 344 ClientBar::Mode ClientBar::mode() const { 345 return mode_; 346 }