00001
00002
00003
00004
00005
00006 extern "C" {
00007 #include <assert.h>
00008 }
00009
00010 #include "statusbar.h"
00011
00012 #include "binder.h"
00013 #include "client.h"
00014 #include "cursors.h"
00015 #include "draw.h"
00016 #include "kernel.h"
00017 #include "inputbar.h"
00018 #include "label.h"
00019 #include "logger.h"
00020 #include "rectangle.h"
00021 #include "workspace.h"
00022 #include "monitor.h"
00023 #include "theme.h"
00024 #include "util.h"
00025 #include "xcore.h"
00026
00027 #include "../version.h"
00028
00029 StatusBar::StatusBar(Monitor *monitor, Rectangle *rect)
00030 : Bar(monitor, rect)
00031 {
00032 text_ = "no cheese window manager - " + string(__NCWM_VERSION);
00033 buttonPressed_ = false;
00034 }
00035
00036 void StatusBar::illuminate() {
00037
00038 if (!isVisible()) {
00039 return;
00040 }
00041
00042 LOGDEBUG("going to draw border");
00043 drawBorder();
00044
00045 unsigned int offsetX = 1;
00046
00047 label_->setAlignment(Label::CENTER);
00048 label_->setText("");
00049 label_->setX(offsetX);
00050 label_->setWidth(width() - 2);
00051 label_->update(theme_->BAR_BACKGROUND, theme_->BAR_TEXT,
00052 theme_->BAR_SHINE, theme_->BAR_SHADOW);
00053
00054 updateInputModeButton(&offsetX);
00055 updateWorkspacePager(&offsetX);
00056 updateStatus(&offsetX);
00057 updateMeters(offsetX);
00058
00059 XCORE->sync();
00060 }
00061
00062 StatusBar::~StatusBar() {
00063 }
00064
00065 void StatusBar::updateInputModeButton(unsigned int *offsetX) {
00066
00067 if (!isButtonVisible_) {
00068 return;
00069 }
00070
00071
00072 label_->setX(*offsetX);
00073 label_->setText("");
00074 label_->setWidth(monitor()->buttonWidth());
00075 if (!buttonPressed_) {
00076
00077 Draw::drawInputModeButton(window(), gc(), label_,
00078 theme_->BUTTON_BACKGROUND_NORMAL,
00079 theme_->BUTTON_SHINE_BORDER_NORMAL,
00080 theme_->BUTTON_SHADOW_BORDER_NORMAL,
00081 theme_->BUTTON_SHINE_FIGURE_NORMAL,
00082 theme_->BUTTON_SHADOW_FIGURE_NORMAL);
00083 }
00084 else {
00085
00086 Draw::drawInputModeButton(window(), gc(), label_,
00087 theme_->BUTTON_BACKGROUND_PRESSED,
00088 theme_->BUTTON_SHINE_BORDER_PRESSED,
00089 theme_->BUTTON_SHADOW_BORDER_PRESSED,
00090 theme_->BUTTON_SHINE_FIGURE_PRESSED,
00091 theme_->BUTTON_SHADOW_FIGURE_PRESSED);
00092 }
00093 *offsetX += monitor()->buttonWidth() + 2;
00094 }
00095
00096 unsigned int StatusBar::calculateWorkspaceWidth() {
00097
00098
00099 Workspace *focusedWorkspace = monitor()->focused();
00100 assert(focusedWorkspace);
00101
00102
00103 unsigned int workspaceWidth = 0;
00104 for (LWorkspace::iterator it = monitor()->begin();
00105 it != monitor()->end(); it++)
00106 {
00107 Workspace *workspace = *it;
00108 label_->setText(workspace->name());
00109 label_->adjustWidth();
00110 if (label_->width() > workspaceWidth) {
00111 workspaceWidth = label_->width();
00112 }
00113 }
00114
00115 return workspaceWidth;
00116 }
00117
00118 void StatusBar::updateWorkspacePager(unsigned int *offsetX) {
00119
00120
00121 Workspace *focusedWorkspace = monitor()->focused();
00122 assert(focusedWorkspace);
00123 unsigned int workspaceWidth = calculateWorkspaceWidth();
00124 unsigned int i = 0;
00125 label_->setWidth(workspaceWidth);
00126 for (LWorkspace::iterator it = monitor()->begin();
00127 it != monitor()->end(); it++)
00128 {
00129 Workspace *workspace = *it;
00130 label_->setX(i * workspaceWidth + *offsetX);
00131 label_->setText(workspace->name());
00132 if (workspace == focusedWorkspace) {
00133 label_->update(theme_->LABEL_BACKGROUND_FOCUSSED,
00134 theme_->LABEL_TEXT_FOCUSSED,
00135 theme_->LABEL_SHINE_FOCUSSED,
00136 theme_->LABEL_SHADOW_FOCUSSED,
00137 true, true);
00138 }
00139 else if (workspace->requestsFocus()) {
00140 label_->update(theme_->FOCUSREQ_BACKGROUND,
00141 theme_->FOCUSREQ_TEXT,
00142 theme_->FOCUSREQ_SHINE,
00143 theme_->FOCUSREQ_SHADOW,
00144 true, true);
00145 }
00146 else {
00147 label_->update(theme_->LABEL_BACKGROUND_NORMAL,
00148 theme_->LABEL_TEXT_NORMAL,
00149 theme_->LABEL_SHINE_NORMAL,
00150 theme_->LABEL_SHADOW_NORMAL,
00151 true, true);
00152 }
00153 i++;
00154 }
00155 *offsetX += i * workspaceWidth + 2;
00156 }
00157
00158 unsigned int StatusBar::calculateMetersWidth() {
00159
00160 unsigned int result = 0;
00161 if (meterText_ != "") {
00162 string percentage = "";
00163 string text = "";
00164 bool isPercentage = true;
00165 unsigned int meterWidth = monitor()->buttonWidth() / 2;
00166 for (string::iterator it = meterText_.begin();
00167 it != meterText_.end(); )
00168 {
00169
00170 char c = *it;
00171 it++;
00172 bool isEndreached = it == meterText_.end();
00173 if (c == '%') {
00174 isPercentage = false;
00175 }
00176 if ((c == ',') || isEndreached) {
00177 if (isEndreached && (c != '%')) {
00178 text += c;
00179 }
00180 isPercentage = true;
00181 result += 2 + meterWidth;
00182 if (text != "") {
00183 label_->setAlignment(Label::LEFT);
00184 label_->setText(text);
00185 result += label_->textWidth();
00186 }
00187 text = "";
00188 percentage = "";
00189 }
00190 else if (isPercentage && (c == '!')) {
00191
00192 }
00193 else if (c != '%') {
00194 if (isPercentage) {
00195 percentage += c;
00196 }
00197 else {
00198 text += c;
00199 }
00200 }
00201 }
00202 }
00203 return result;
00204 }
00205
00206 void StatusBar::updateMeters(unsigned int offsetX) {
00207
00208 if (meterText_ != "") {
00209
00210 string percentage = "";
00211 string text = "";
00212 bool isPercentage = true;
00213 bool isNegotiated = false;
00214 unsigned int meterWidth = monitor()->buttonWidth() / 2;
00215 label_->setX(offsetX);
00216 label_->setWidth(0);
00217 for (string::iterator it = meterText_.begin();
00218 it != meterText_.end(); )
00219 {
00220
00221 char c = *it;
00222 it++;
00223 bool isEndreached = it == meterText_.end();
00224 if (c == '%') {
00225 isPercentage = false;
00226 }
00227 if ((c == ',') || isEndreached) {
00228 if (isEndreached && (c != '%')) {
00229 text += c;
00230 }
00231 label_->setX(label_->x() + label_->width() + 2);
00232 label_->setWidth(meterWidth);
00233 int percent = Util::strToUInt(percentage);
00234 if (percent < 0) {
00235 percent = 0;
00236 }
00237 else if (percent > 99) {
00238 percent = 99;
00239 }
00240 Draw::drawMeter(window(), gc(), label_, percent,
00241 theme_->METER_BACKGROUND,
00242 isNegotiated ? theme_->METER_FIGURE_LOW : theme_->METER_FIGURE_HIGH,
00243 theme_->METER_FIGURE_NORMAL,
00244 isNegotiated ? theme_->METER_FIGURE_HIGH : theme_->METER_FIGURE_LOW,
00245 theme_->METER_BORDER_SHINE,
00246 theme_->METER_BORDER_SHADOW);
00247 if (text != "") {
00248 label_->setAlignment(Label::LEFT);
00249 label_->setX(label_->x() + label_->width());
00250 label_->setText(text);
00251 label_->adjustWidth();
00252 label_->update(theme_->BAR_BACKGROUND, theme_->BAR_TEXT,
00253 theme_->BAR_SHINE, theme_->BAR_SHADOW);
00254 }
00255 text = "";
00256 percentage = "";
00257 isPercentage = true;
00258 isNegotiated = false;
00259 }
00260 else if (isPercentage && (c == '!')) {
00261 isNegotiated = true;
00262 }
00263 else if (c != '%') {
00264
00265 if (isPercentage) {
00266 percentage += c;
00267 }
00268 else {
00269 text += c;
00270 }
00271 }
00272 }
00273 }
00274 }
00275
00276 void StatusBar::updateStatus(unsigned int *offsetX) {
00277
00278 unsigned int metersWidth = calculateMetersWidth();
00279
00280
00281 label_->setAlignment(Label::RIGHT);
00282 label_->setX(*offsetX);
00283 label_->setWidth(width() - *offsetX - metersWidth - 5);
00284 label_->setText(text_);
00285 label_->update(theme_->BAR_BACKGROUND, theme_->BAR_TEXT,
00286 theme_->BAR_SHINE, theme_->BAR_SHADOW);
00287
00288 *offsetX = label_->x() + label_->width() + 2;
00289 }
00290
00291 void StatusBar::handleButtonRelease(XButtonEvent *event) {
00292
00293
00294 if (buttonPressed_) {
00295 if (event->button == Button1) {
00296 LOGDEBUG("toggling interactive mode");
00297 monitor()->inputBar()->runKey(KERNEL->defaultPrompt());
00298 buttonPressed_ = false;
00299 }
00300 }
00301 }
00302
00303 void StatusBar::handleButtonPress(XButtonEvent *event) {
00304
00305 if ((event->window != window())) {
00306 return;
00307 }
00308
00309 XCORE->raise(window());
00310
00311
00312 if (event->button == Button1) {
00313 invokeClickedThing(event->x);
00314 }
00315 else if (event->button == Button4) {
00316 monitor()->focus(monitor()->prev());
00317 }
00318 else if (event->button == Button5) {
00319 monitor()->focus(monitor()->next());
00320 }
00321 }
00322
00323 void StatusBar::handleMotionNotify(XMotionEvent *event) {
00324
00325 if (buttonPressed_) {
00326 buttonPressed_ = false;
00327 illuminate();
00328 }
00329 }
00330
00331 void StatusBar::invokeClickedThing(int xPosition) {
00332
00333 if (isButtonVisible_) {
00334 if (xPosition < (int)monitor()->buttonWidth() + 1) {
00335 buttonPressed_ = true;
00336 illuminate();
00337 return;
00338 }
00339 xPosition -= (monitor()->buttonWidth() + 3);
00340 }
00341
00342 unsigned int workspaceNum = xPosition / calculateWorkspaceWidth();
00343 if (workspaceNum < monitor()->size()) {
00344 monitor()->focusWorkspaceNum(workspaceNum);
00345 }
00346 illuminate();
00347 }
00348
00349 void StatusBar::setText(const string text) {
00350 text_ = text;
00351 }
00352
00353 void StatusBar::setMeterText(const string meterText) {
00354 meterText_ = meterText;
00355 }