src/thing.cpp

Go to the documentation of this file.
00001 // Copyright (c) 2003 - 2004 Anselm R. Garbe <anselmg at t-online.de>
00002 // See ../LICENSE.txt for license details.
00003 //
00004 // $Id: thing.cpp 2 2007-05-16 10:38:27Z eg $
00005 
00006 #include "thing.h"
00007 
00008 #include "client.h"
00009 #include "cursors.h"
00010 #include "draw.h"
00011 #include "font.h"
00012 #include "frame.h"
00013 #include "kernel.h"
00014 #include "label.h"
00015 #include "logger.h"
00016 #include "monitor.h"
00017 #include "theme.h"
00018 #include "workspace.h"
00019 #include "xcore.h"
00020 #include "xfont.h"
00021 
00022 Thing::Thing(Monitor *monitor, Rectangle *rect, Type type)
00023     : Rectangle(*rect)
00024 {
00025     monitor_ = monitor;
00026     type_ = type;
00027     isVisible_ = false;
00028     hasDecoration_ = false;
00029     clientAreaRect_ = Rectangle(*rect);
00030     name_ = "";
00031 
00032     // view
00033     theme_ = monitor_->theme();
00034 
00035     areButtonsVisible_ =
00036         (Util::get(KERNEL->commonSettings(), "frame.buttons") == "yes");
00037 
00038     cursor_ = Cursors::NORMAL_CURSOR;
00039     prevRect_ = new Rectangle(*rect);
00040     buttonState_ = NONE;
00041 
00042     // creates frame window
00043     if (type == FRAME) {
00044         initFrameWindow();
00045         fitClientArea();
00046     }
00047     else {
00048         frameWindow_ = 0;
00049         gc_ = 0;
00050         label_ = 0;
00051         titleBarHeight_ = 0;
00052         borderWidth_ = 0;
00053     }
00054 }
00055 
00056 Thing::~Thing() {
00057     delete prevRect_;
00058 
00059     if (frameWindow_) {
00060         delete label_;
00061         XCORE->free(gc_);
00062         XCORE->destroy(frameWindow_);
00063         LOGDEBUG("frame destroyed");
00064     }
00065 }
00066 
00067 void Thing::initFrameWindow() {
00068 
00069     titleBarHeight_ =
00070         (Util::get(KERNEL->commonSettings(), "default.bar-mode")
00071          == "show") ? monitor_->titleBarHeight() : 0;
00072     borderWidth_ = 
00073         (Util::get(KERNEL->commonSettings(), "default.border-mode")
00074          == "show") ? KERNEL->borderWidth() : 0;
00075 
00076     if (type_ == CLIENT) {
00077         setX(x() - borderWidth_);
00078         setY(y() - titleBarHeight_ - borderWidth_ - 1);
00079         setWidth(width() + 2 * borderWidth_);
00080         setHeight(height() + titleBarHeight_ + 2 * borderWidth_ + 1);
00081     }
00082 
00083     XSetWindowAttributes attr;
00084     attr.background_pixmap = ParentRelative;
00085     attr.override_redirect = 1;
00086     frameWindow_ = XCORE->createWindow(this->monitor()->rootWindow(), &attr,
00087                                        x(), y(), width(), height(),
00088                                        CWOverrideRedirect | CWBackPixmap);
00089 
00090     LOGDEBUG("init GC for frame");
00091     initGC();
00092     label_ = new Label(this->monitor(), frameWindow_, Label::CENTER, gc_);
00093     label_->setY(borderWidth_);
00094     label_->setHeight(titleBarHeight_);
00095 
00096     XCORE->selectEvents(frameWindow_,
00097             ExposureMask | SubstructureRedirectMask | SubstructureNotifyMask |
00098             ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
00099 
00100     KERNEL->installCursor(Cursors::NORMAL_CURSOR, frameWindow_);
00101     hasDecoration_ = true;
00102 }
00103 
00104 Thing::Type Thing::type() const {
00105     return type_;
00106 }
00107 
00108 Monitor *Thing::monitor() const {
00109     return monitor_;
00110 }
00111 
00112 bool Thing::isVisible() const {
00113     return isVisible_;
00114 }
00115 
00116 void Thing::initGC() {
00117 
00118     if (frameWindow_) {
00119         unsigned long mask =
00120             GCForeground | GCBackground |
00121             GCFunction | GCLineWidth | GCLineStyle;
00122 
00123         XGCValues gcv;
00124         gcv.function = GXcopy;
00125         gcv.line_width = 1;
00126         gcv.line_style = LineSolid;
00127         if (monitor()->font()->type() == WFont::NORMAL) {
00128             gcv.font = ((XFont *)monitor()->font())->font()->fid;
00129             mask |= GCFont;
00130         }
00131         gc_ = XCORE->createGC(frameWindow_, mask, &gcv);
00132     }
00133 }
00134 
00135 void Thing::illuminateBorder() {
00136 
00137     if (!isVisible_ || !frameWindow_) {
00138         return;
00139     }
00140 
00141     bool focused = isFocused();
00142 
00143     if (titleBarHeight_) {
00144         label_->setText("");
00145         label_->setX(borderWidth_);
00146         label_->setWidth(width() - 2 * borderWidth_);
00147 
00148         if (focused) {
00149             label_->update(theme_->FRAME_BACKGROUND_FOCUSSED, 0,
00150                            theme_->FRAME_SHINE_FOCUSSED,
00151                            theme_->FRAME_SHADOW_FOCUSSED);
00152         }
00153         else {
00154             label_->update(theme_->FRAME_BACKGROUND_NORMAL, 0,
00155                            theme_->FRAME_SHINE_NORMAL,
00156                            theme_->FRAME_SHADOW_NORMAL);
00157         }
00158     }
00159 
00160     LOGDEBUG("drawing border");
00161     if (focused) {
00162         Draw::drawBorder(frameWindow_, gc_, monitor()->borderGC(), this,
00163                         theme_->FRAME_BACKGROUND_FOCUSSED,
00164                         theme_->FRAME_SHINE_FOCUSSED,
00165                         theme_->FRAME_SHADOW_FOCUSSED,
00166                         titleBarHeight_ + borderWidth_,
00167                         borderWidth_);
00168     }
00169     else {
00170         Draw::drawBorder(frameWindow_, gc_, monitor()->borderGC(), this,
00171                         theme_->FRAME_BACKGROUND_NORMAL,
00172                         theme_->FRAME_SHINE_NORMAL,
00173                         theme_->FRAME_SHADOW_NORMAL,
00174                         titleBarHeight_ + borderWidth_,
00175                         borderWidth_);
00176     }
00177 
00178     if (titleBarHeight_ && areButtonsVisible_ && focused) {
00179 
00180         if (type_ == FRAME && !((Frame *)this)->size()) {
00181             // no need to draw buttons
00182             return;
00183         }
00184 
00185         // detach button
00186         label_->setText("");
00187         label_->setX(width() - borderWidth_ - 3 * monitor_->buttonWidth());
00188         label_->setWidth(monitor_->buttonWidth());
00189         if (buttonState_ != MINCLIENT) {
00190 
00191             Draw::drawDetachButton(frameWindow_, gc_, label_,
00192                            theme_->BUTTON_BACKGROUND_NORMAL,
00193                            theme_->BUTTON_SHINE_BORDER_NORMAL,
00194                            theme_->BUTTON_SHADOW_BORDER_NORMAL,
00195                            theme_->BUTTON_SHINE_FIGURE_NORMAL,
00196                            theme_->BUTTON_SHADOW_FIGURE_NORMAL);
00197         }
00198         else {
00199 
00200             Draw::drawDetachButton(frameWindow_, gc_, label_,
00201                            theme_->BUTTON_BACKGROUND_PRESSED,
00202                            theme_->BUTTON_SHINE_BORDER_PRESSED,
00203                            theme_->BUTTON_SHADOW_BORDER_PRESSED,
00204                            theme_->BUTTON_SHINE_FIGURE_PRESSED,
00205                            theme_->BUTTON_SHADOW_FIGURE_PRESSED);
00206         }
00207 
00208         // (de)max client button
00209         label_->setX(label_->x() + monitor_->buttonWidth());
00210 
00211         if (buttonState_ != DEMAX) {
00212 
00213             if (type_ == CLIENT) {
00214 
00215                 Draw::drawMaxButton(frameWindow_, gc_, label_,
00216                            theme_->BUTTON_BACKGROUND_NORMAL,
00217                            theme_->BUTTON_SHINE_BORDER_NORMAL,
00218                            theme_->BUTTON_SHADOW_BORDER_NORMAL,
00219                            theme_->BUTTON_SHINE_FIGURE_NORMAL,
00220                            theme_->BUTTON_SHADOW_FIGURE_NORMAL);
00221             }
00222             else {
00223 
00224                 Draw::drawFloatButton(frameWindow_, gc_, label_,
00225                            theme_->BUTTON_BACKGROUND_NORMAL,
00226                            theme_->BUTTON_SHINE_BORDER_NORMAL,
00227                            theme_->BUTTON_SHADOW_BORDER_NORMAL,
00228                            theme_->BUTTON_SHINE_FIGURE_NORMAL,
00229                            theme_->BUTTON_SHADOW_FIGURE_NORMAL);
00230             }
00231         }
00232         else {
00233 
00234             if (type_ == CLIENT) {
00235 
00236                 Draw::drawMaxButton(frameWindow_, gc_, label_,
00237                            theme_->BUTTON_BACKGROUND_PRESSED,
00238                            theme_->BUTTON_SHINE_BORDER_PRESSED,
00239                            theme_->BUTTON_SHADOW_BORDER_PRESSED,
00240                            theme_->BUTTON_SHINE_FIGURE_PRESSED,
00241                            theme_->BUTTON_SHADOW_FIGURE_PRESSED);
00242             }
00243             else {
00244 
00245                 Draw::drawFloatButton(frameWindow_, gc_, label_,
00246                            theme_->BUTTON_BACKGROUND_PRESSED,
00247                            theme_->BUTTON_SHINE_BORDER_PRESSED,
00248                            theme_->BUTTON_SHADOW_BORDER_PRESSED,
00249                            theme_->BUTTON_SHINE_FIGURE_PRESSED,
00250                            theme_->BUTTON_SHADOW_FIGURE_PRESSED);
00251             }
00252 
00253         }
00254 
00255         // close button
00256         label_->setX(label_->x() + monitor_->buttonWidth());
00257         if (buttonState_ != CLOSE) {
00258 
00259             Draw::drawCloseButton(frameWindow_, gc_, label_,
00260                     theme_->BUTTON_BACKGROUND_NORMAL,
00261                     theme_->BUTTON_SHINE_BORDER_NORMAL,
00262                     theme_->BUTTON_SHADOW_BORDER_NORMAL,
00263                     theme_->BUTTON_SHINE_FIGURE_NORMAL,
00264                     theme_->BUTTON_SHADOW_FIGURE_NORMAL);
00265         }
00266         else {
00267 
00268             Draw::drawCloseButton(frameWindow_, gc_, label_,
00269                     theme_->BUTTON_BACKGROUND_PRESSED,
00270                     theme_->BUTTON_SHINE_BORDER_PRESSED,
00271                     theme_->BUTTON_SHADOW_BORDER_PRESSED,
00272                     theme_->BUTTON_SHINE_FIGURE_PRESSED,
00273                     theme_->BUTTON_SHADOW_FIGURE_PRESSED);
00274 
00275         }
00276     }
00277 }
00278 
00279 void Thing::handleMotionNotify(XMotionEvent *event) {
00280 
00281     if (monitor()->isThingMaximized()) {
00282         return;
00283     }
00284 
00285     Cursor cursor = cursorForXY(event->x, event->y);
00286 
00287     if (cursor != cursor_) {
00288         cursor_ = cursor;
00289         KERNEL->installCursor(cursor, frameWindow_);
00290     }
00291 
00292     if (buttonState_ != NONE) {
00293         buttonState_ = NONE;
00294         illuminate();
00295     }
00296 }
00297 
00298 void Thing::setTitleBarHeight(unsigned int titleBarHeight) {
00299     titleBarHeight_ = titleBarHeight;
00300 }
00301 
00302 void Thing::setBorderWidth(unsigned int borderWidth) {
00303     borderWidth_ = borderWidth;
00304 }
00305 
00306 unsigned int Thing::borderWidth() const {
00307     return borderWidth_;
00308 }
00309 
00310 unsigned int Thing::titleBarHeight() const {
00311     return titleBarHeight_;
00312 }
00313 
00314 Rectangle *Thing::prevRectangle() const {
00315     return prevRect_;
00316 }
00317 
00318 Thing::InvertButton Thing::buttonState() const {
00319     return buttonState_;
00320 }
00321 
00322 void Thing::setButtonState(InvertButton state) {
00323     buttonState_ = state;
00324 }
00325 
00326 void Thing::show() {
00327     if (frameWindow_) {
00328         XCORE->show(frameWindow_);
00329         isVisible_ = true;
00330     }
00331 }
00332 
00333 void Thing::hide() {
00334     if (frameWindow_) {
00335         XCORE->hide(frameWindow_);
00336         isVisible_ = false;
00337     }
00338 }
00339 
00340 void Thing::fitClientArea() {
00341 
00342     clientAreaRect_.setX(borderWidth_);
00343     clientAreaRect_.setY(titleBarHeight_ + borderWidth_ +
00344                          (titleBarHeight_ ? 1 : 0));
00345     clientAreaRect_.setWidth(width() - 2 * borderWidth_);
00346     clientAreaRect_.setHeight(height() - titleBarHeight_
00347                               - 2 * borderWidth_
00348                               - (titleBarHeight_ ? 1 : 0));
00349 }
00350 
00351 void Thing::setName(string name) {
00352     name_ = name;
00353 }
00354 
00355 string Thing::name() const {
00356     return name_;
00357 }
00358 
00359 bool Thing::hasDecoration() const {
00360     return hasDecoration_;
00361 }

Generated on Thu May 24 15:19:32 2007 for ncwm by  doxygen 1.5.1