00001
00002
00003
00004
00005
00006 #include <list>
00007 #include <string>
00008 #include <sstream>
00009
00010 #include "clientbar.h"
00011
00012 #include "client.h"
00013 #include "cursors.h"
00014 #include "draw.h"
00015 #include "frame.h"
00016 #include "label.h"
00017 #include "logger.h"
00018 #include "menu.h"
00019 #include "monitor.h"
00020 #include "theme.h"
00021 #include "thing.h"
00022 #include "validators.h"
00023 #include "workspace.h"
00024 #include "xcore.h"
00025
00026 ClientBar::ClientBar(Monitor *monitor, Rectangle *rect)
00027 : Bar(monitor, rect)
00028 {
00029 isModeButtonPressed_ = isMenuButtonPressed_ = false;
00030 mode_ = PAGER;
00031 menu_ = new Menu(monitor);
00032 }
00033
00034 ClientBar::~ClientBar() {
00035 }
00036
00037 void ClientBar::illuminate() {
00038
00039 if (!isVisible()) {
00040 return;
00041 }
00042
00043 LOGDEBUG("going to draw border");
00044 drawBorder();
00045
00046 label_->setText("");
00047 label_->setX(1);
00048 label_->setWidth(width() - 2);
00049 label_->update(theme_->BAR_BACKGROUND, theme_->BAR_TEXT,
00050 theme_->BAR_SHINE, theme_->BAR_SHADOW);
00051
00052 updateMenuButton();
00053 if (mode_ == PAGER) {
00054 updateClientPager();
00055 }
00056 else {
00057 updateClientInfo();
00058 }
00059 updateModeButton();
00060 }
00061
00062
00063 void ClientBar::updateClientPager() {
00064
00065 Workspace *workspace = monitor()->focused();
00066 CClient *clients = workspace->floatingClients();
00067 if (clients->size() > 0) {
00068 unsigned int offsetX = isButtonVisible_ ? monitor()->buttonWidth() + 3 : 1;
00069 unsigned int clientsWidth = width() - 2;
00070 if (isButtonVisible_) {
00071 clientsWidth -= (2 * monitor()->buttonWidth() + 4);
00072 }
00073 unsigned int i = 0;
00074 unsigned int clientWidth = clientsWidth / clients->size();
00075 label_->setWidth(clientWidth);
00076 for (LClient::iterator it = clients->begin(); it != clients->end(); ) {
00077 Client *client = *it;
00078 it++;
00079
00080 label_->setX(offsetX + i * clientWidth);
00081 if (it == clients->end()) {
00082
00083 label_->setWidth(width() - label_->x()
00084 - (isButtonVisible_ ? monitor()->buttonWidth() + 3 : 1));
00085 }
00086 unsigned long shine, shadow;
00087 label_->setText(client->name());
00088 if (client->isFocused()) {
00089 shine = theme_->TAB_SHINE_ACTIVE_FOCUSSED;
00090 shadow = theme_->TAB_SHADOW_ACTIVE_FOCUSSED;
00091 label_->update(theme_->TAB_BACKGROUND_ACTIVE_FOCUSSED,
00092 theme_->TAB_TEXT_ACTIVE_FOCUSSED,
00093 shine, shadow, true, true);
00094 }
00095 else if (client->requestsFocus()) {
00096 shine = theme_->FOCUSREQ_SHINE;
00097 shadow = theme_->FOCUSREQ_SHADOW;
00098 label_->update(theme_->FOCUSREQ_BACKGROUND,
00099 theme_->FOCUSREQ_TEXT,
00100 shine, shadow, true, true);
00101 }
00102 else {
00103 shine = theme_->TAB_SHINE_ACTIVE_NORMAL;
00104 shadow = theme_->TAB_SHADOW_ACTIVE_NORMAL;
00105 label_->update(theme_->TAB_BACKGROUND_ACTIVE_NORMAL,
00106 theme_->TAB_TEXT_ACTIVE_NORMAL,
00107 shine, shadow, true, true);
00108 }
00109
00110 if (client->mode() == Client::STICKY) {
00111 Draw::drawStickyNotifier(window(), gc(), label_,
00112 shine, shadow,
00113 label_->textWidth());
00114 }
00115 i++;
00116 }
00117 }
00118 }
00119
00120 void ClientBar::updateMenuButton() {
00121
00122
00123 if (!isButtonVisible_) {
00124 return;
00125 }
00126
00127 label_->setText("");
00128 label_->setX(1);
00129 label_->setWidth(monitor()->buttonWidth());
00130 if (isMenuButtonPressed_) {
00131 Draw::drawMenuButton(window(), gc(), label_,
00132 theme_->BUTTON_BACKGROUND_PRESSED,
00133 theme_->BUTTON_SHINE_BORDER_PRESSED,
00134 theme_->BUTTON_SHADOW_BORDER_PRESSED,
00135 theme_->BUTTON_SHINE_FIGURE_PRESSED,
00136 theme_->BUTTON_SHADOW_FIGURE_PRESSED);
00137 }
00138 else {
00139 Draw::drawMenuButton(window(), gc(), label_,
00140 theme_->BUTTON_BACKGROUND_NORMAL,
00141 theme_->BUTTON_SHINE_BORDER_NORMAL,
00142 theme_->BUTTON_SHADOW_BORDER_NORMAL,
00143 theme_->BUTTON_SHINE_FIGURE_NORMAL,
00144 theme_->BUTTON_SHADOW_FIGURE_NORMAL);
00145 }
00146 }
00147
00148 void ClientBar::updateModeButton() {
00149
00150
00151 if (!isButtonVisible_) {
00152 return;
00153 }
00154
00155 Workspace *workspace = monitor()->focused();
00156
00157 label_->setText("");
00158 label_->setX(width() - monitor()->buttonWidth() - 1);
00159 label_->setWidth(monitor()->buttonWidth());
00160 if (isModeButtonPressed_) {
00161 if (workspace->isFrameMode()) {
00162 Draw::drawFloatButton(window(), gc(), label_,
00163 theme_->BUTTON_BACKGROUND_PRESSED,
00164 theme_->BUTTON_SHINE_BORDER_PRESSED,
00165 theme_->BUTTON_SHADOW_BORDER_PRESSED,
00166 theme_->BUTTON_SHINE_FIGURE_PRESSED,
00167 theme_->BUTTON_SHADOW_FIGURE_PRESSED,
00168 workspace->floatingClients()->size());
00169 }
00170 else {
00171 Draw::drawMaxButton(window(), gc(), label_,
00172 theme_->BUTTON_BACKGROUND_PRESSED,
00173 theme_->BUTTON_SHINE_BORDER_PRESSED,
00174 theme_->BUTTON_SHADOW_BORDER_PRESSED,
00175 theme_->BUTTON_SHINE_FIGURE_PRESSED,
00176 theme_->BUTTON_SHADOW_FIGURE_PRESSED,
00177 workspace->focusedFrame() &&
00178 workspace->focusedFrame()->size());
00179 }
00180 }
00181 else {
00182 if (workspace->isFrameMode()) {
00183 Draw::drawFloatButton(window(), gc(), label_,
00184 theme_->BUTTON_BACKGROUND_NORMAL,
00185 theme_->BUTTON_SHINE_BORDER_NORMAL,
00186 theme_->BUTTON_SHADOW_BORDER_NORMAL,
00187 theme_->BUTTON_SHINE_FIGURE_NORMAL,
00188 theme_->BUTTON_SHADOW_FIGURE_NORMAL,
00189 workspace->floatingClients()->size());
00190 }
00191 else {
00192 Draw::drawMaxButton(window(), gc(), label_,
00193 theme_->BUTTON_BACKGROUND_NORMAL,
00194 theme_->BUTTON_SHINE_BORDER_NORMAL,
00195 theme_->BUTTON_SHADOW_BORDER_NORMAL,
00196 theme_->BUTTON_SHINE_FIGURE_NORMAL,
00197 theme_->BUTTON_SHADOW_FIGURE_NORMAL,
00198 workspace->focusedFrame() &&
00199 workspace->focusedFrame()->size());
00200 }
00201 }
00202 }
00203
00204 void ClientBar::updateClientInfo() {
00205
00206
00207 Workspace *focusedWorkspace = monitor()->focused();
00208 Client *client = focusedWorkspace->topClient();
00209 unsigned int offsetX = isButtonVisible_ ? monitor()->buttonWidth() + 3 : 1;
00210 unsigned int clientInfoWidth = width() - 2;
00211 if (isButtonVisible_) {
00212 clientInfoWidth -= (2 * monitor()->buttonWidth() + 4);
00213 }
00214 label_->setX(offsetX);
00215 label_->setWidth(clientInfoWidth);
00216 label_->setText(client ? client->name() : "");
00217 label_->update(theme_->LABEL_BACKGROUND_FOCUSSED,
00218 theme_->LABEL_TEXT_FOCUSSED,
00219 theme_->LABEL_SHINE_FOCUSSED,
00220 theme_->LABEL_SHADOW_FOCUSSED,
00221 true, true);
00222 if (client->mode() == Client::STICKY) {
00223 Draw::drawStickyNotifier(window(), gc(), label_,
00224 theme_->LABEL_SHINE_FOCUSSED,
00225 theme_->LABEL_SHADOW_FOCUSSED,
00226 label_->textWidth());
00227 }
00228 }
00229
00230 void ClientBar::handleButtonRelease(XButtonEvent *event) {
00231
00232 if ((event->window != window())) {
00233 return;
00234 }
00235
00236 if (isModeButtonPressed_) {
00237 isModeButtonPressed_ = false;
00238 Workspace *ws = monitor()->focused();
00239 if ((event->button == Button1) &&
00240 Validators::instance()->validateToggleMode())
00241 {
00242 ws->toggleMode();
00243 }
00244 illuminate();
00245 }
00246 else if (isMenuButtonPressed_) {
00247 toggleMenuMode();
00248 }
00249 }
00250
00251 void ClientBar::toggleMenuMode() {
00252
00253 if (menu_->isVisible()) {
00254 menu_->hide();
00255 isMenuButtonPressed_ = false;
00256 }
00257 else {
00258 menu_->show();
00259 }
00260 illuminate();
00261 }
00262
00263 void ClientBar::handleButtonPress(XButtonEvent *event) {
00264
00265 if ((event->window != window())) {
00266 return;
00267 }
00268
00269 XCORE->raise(window());
00270
00271
00272 if (event->button == Button1) {
00273 invokeClickedThing(event->x);
00274 }
00275 else if (event->button == Button4) {
00276 monitor()->focused()->cycleClientPrev();
00277 }
00278 else if (event->button == Button5) {
00279 monitor()->focused()->cycleClientNext();
00280 }
00281 }
00282
00283 void ClientBar::handleMotionNotify(XMotionEvent *event) {
00284
00285 if (isModeButtonPressed_) {
00286 isModeButtonPressed_ = false;
00287 illuminate();
00288 }
00289 }
00290
00291 void ClientBar::invokeClickedThing(int xPosition) {
00292
00293 if (isButtonVisible_) {
00294 if (xPosition < (int)(monitor()->buttonWidth() + 1)) {
00295 isMenuButtonPressed_ = true;
00296 }
00297 else if (xPosition > (int)(width() - monitor()->buttonWidth() - 2)) {
00298 isModeButtonPressed_ = true;
00299 }
00300 illuminate();
00301 if (isModeButtonPressed_ || isMenuButtonPressed_) {
00302 return;
00303 }
00304 }
00305
00306 if (mode_ != PAGER) {
00307 illuminate();
00308 return;
00309 }
00310
00311 Workspace *workspace = monitor()->focused();
00312 unsigned int clientsWidth = width() - 2;
00313 if (isButtonVisible_) {
00314 clientsWidth -= (2 * monitor()->buttonWidth() + 4);
00315 xPosition -= (monitor()->buttonWidth() + 3);
00316 }
00317 else {
00318 xPosition -= 1;
00319 }
00320
00321 CClient *clients = workspace->floatingClients();
00322 if (!clients->size()) {
00323 return;
00324 }
00325
00326 unsigned int clientNum = xPosition / (clientsWidth / clients->size());
00327 unsigned i = 0;
00328 for (LClient::iterator it = clients->begin(); it != clients->end(); it++) {
00329 if (i == clientNum) {
00330 workspace->focus(*it);
00331 illuminate();
00332 return;
00333 }
00334 i++;
00335 }
00336 }
00337
00338 Menu *ClientBar::menu() const {
00339 return menu_;
00340 }
00341
00342 void ClientBar::setMode(ClientBar::Mode mode) {
00343 mode_ = mode;
00344 }
00345
00346 ClientBar::Mode ClientBar::mode() const {
00347 return mode_;
00348 }