Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

mmswindowmanager.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
00031  **************************************************************************/
00032 
00033 #include "mmsgui/mmswindowmanager.h"
00034 #include "mmsgui/fb/mmsfbwindowmanager.h"
00035 
00036 
00037 MMSWindowManager::MMSWindowManager(MMSFBRectangle vrect) {
00038     // init me
00039     this->vrect = vrect;
00040     this->toplevel = NULL;
00041     this->anim_saved_screen = NULL;
00042 
00043     // add language changed callback
00044     this->onTargetLangChanged_connection = this->translator.onTargetLangChanged.connect(sigc::mem_fun(this, &MMSWindowManager::onTargetLangChanged));
00045 
00046     // add theme changed callback
00047     this->onThemeChanged_connection = this->themeManager.onThemeChanged.connect(sigc::mem_fun(this, &MMSWindowManager::onThemeChanged));
00048 
00049     // add animation callbacks
00050     this->onAnimation_connection = this->pulser.onAnimation.connect(sigc::mem_fun(this, &MMSWindowManager::onAnimation));
00051     this->onAfterAnimation_connection = this->pulser.onAfterAnimation.connect(sigc::mem_fun(this, &MMSWindowManager::onAfterAnimation));
00052 }
00053 
00054 MMSWindowManager::~MMSWindowManager() {
00055     // disconnect my callbacks
00056     this->onTargetLangChanged_connection.disconnect();
00057     this->onThemeChanged_connection.disconnect();
00058     this->onAnimation_connection.disconnect();
00059     this->onAfterAnimation_connection.disconnect();
00060 }
00061 
00062 void MMSWindowManager::reset() {
00063     mmsfbwindowmanager->reset();
00064 }
00065 
00066 MMSFBRectangle MMSWindowManager::getVRect() {
00067     return this->vrect;
00068 }
00069 
00070 void MMSWindowManager::addWindow(MMSWindow *window) {
00071     // add window to list
00072     this->windows.push_back(window);
00073 }
00074 
00075 void MMSWindowManager::removeWindow(MMSWindow *window){
00076     // search for the window and erase it
00077     for(unsigned int i = 0; i < windows.size(); i++) {
00078         if(window != windows.at(i))
00079             continue;
00080         windows.erase(windows.begin()+i);
00081         if (window == this->toplevel)
00082             this->toplevel = NULL;
00083         return;
00084     }
00085 }
00086 
00087 bool MMSWindowManager::lowerToBottom(MMSWindow *window) {
00088     return window->lowerToBottom();
00089 }
00090 
00091 bool MMSWindowManager::raiseToTop(MMSWindow *window) {
00092     // searching for popup windows and count it
00093     int cnt = 0;
00094 /*    for(unsigned int i = 0; i < windows.size(); i++) {
00095         if (windows.at(i)->getType() == MMSWINDOWTYPE_POPUPWINDOW) {
00096             if (windows.at(i)->isShown()) cnt++;
00097         }
00098     }
00099 */
00100     // raise window to top, cnt number of windows are over it
00101     return window->raiseToTop(cnt);
00102 }
00103 
00104 bool MMSWindowManager::hideAllMainWindows(bool goback) {
00105     bool ret = false;
00106 
00107     // searching for main windows
00108     for(unsigned int i = 0; i < windows.size(); i++) {
00109         if (windows.at(i)->getType() == MMSWINDOWTYPE_MAINWINDOW) {
00110             if (windows.at(i)->isShown()) {
00111                 if (this->toplevel == windows.at(i)) {
00112                     removeWindowFromToplevel(windows.at(i));
00113                     windows.at(i)->hide(goback, true);
00114                 }
00115                 else
00116                     windows.at(i)->hide(false, true);
00117                 ret = true;
00118             }
00119         }
00120     }
00121 
00122     // return true if at least one main window was found
00123     return ret;
00124 }
00125 
00126 bool MMSWindowManager::hideAllPopupWindows(bool except_modal) {
00127     bool ret = false;
00128 
00129     // searching for popup windows
00130     for(unsigned int i = 0; i < windows.size(); i++) {
00131         if (windows.at(i)->getType() == MMSWINDOWTYPE_POPUPWINDOW) {
00132             if (windows.at(i)->isShown()) {
00133                 if (except_modal) {
00134                     // hide only non-modal popups
00135                     bool modal;
00136                     if (windows.at(i)->getModal(modal)) {
00137                         if (modal)
00138                             continue;
00139                     }
00140                 }
00141                 windows.at(i)->hide(false, true);
00142                 ret = true;
00143             }
00144         }
00145     }
00146 
00147     // return true if at least one popup window was found
00148     return ret;
00149 }
00150 
00151 bool MMSWindowManager::hideAllRootWindows(bool willshown) {
00152     bool ret = false;
00153 
00154     // search for root windows
00155     for(unsigned int i = 0; i < windows.size(); i++)
00156         if (windows.at(i)->getType() == MMSWINDOWTYPE_ROOTWINDOW)
00157             if (windows.at(i)->isShown()) {
00158                 if (this->toplevel == windows.at(i)) {
00159                     removeWindowFromToplevel(windows.at(i));
00160                     windows.at(i)->hide(false, true);
00161                 }
00162                 else
00163                     windows.at(i)->hide(false, true);
00164                 ret = true;
00165             }
00166 
00167     // if at least one root window was hidden and no other will shown, show the default root window
00168     if ((ret)&&(!willshown)) {
00169         showBackgroundWindow();
00170     }
00171 
00172     // return true if at least one root window was found
00173     return ret;
00174 }
00175 
00176 bool MMSWindowManager::setToplevelWindow(MMSWindow *window) {
00177     if (window->getType() == MMSWINDOWTYPE_POPUPWINDOW) {
00178         // set popup window as toplevel if it is in modal mode
00179         bool modal;
00180         if (window->getModal(modal)) {
00181             if (modal) {
00182                 this->toplevel = window;
00183                 return true;
00184             }
00185         }
00186 
00187         // popup window is not set as toplevel
00188         return false;
00189     }
00190 
00191     if (window->getType() != MMSWINDOWTYPE_MAINWINDOW && window->getType() != MMSWINDOWTYPE_ROOTWINDOW) {
00192         // this type cannot be set as toplevel
00193         return false;
00194     }
00195 
00196     if (this->toplevel) {
00197         // check current toplevel window
00198         if (this->toplevel->getType() == MMSWINDOWTYPE_POPUPWINDOW) {
00199             if (this->toplevel->isShown()&&(!this->toplevel->willHide())) {
00200                 // current toplevel window is already shown and keep the toplevel status
00201                 return false;
00202             }
00203         }
00204     }
00205 
00206     if (window->getType() == MMSWINDOWTYPE_MAINWINDOW) {
00207         // searching for active popup window
00208         for(unsigned int i = 0; i < windows.size(); i++) {
00209             if (windows.at(i)->getType() == MMSWINDOWTYPE_POPUPWINDOW) {
00210                 if (windows.at(i)->isShown()&&(!windows.at(i)->willHide())) {
00211                     // set active popup window as toplevel
00212                     bool modal;
00213                     if (windows.at(i)->getModal(modal)) {
00214                         if (modal) {
00215                             this->toplevel = windows.at(i);
00216                             return false;
00217                         }
00218                     }
00219                 }
00220             }
00221         }
00222     }
00223 
00224     if (window->getType() == MMSWINDOWTYPE_ROOTWINDOW) {
00225         // searching for active main window
00226         for(unsigned int i = 0; i < windows.size(); i++) {
00227             if (windows.at(i)->getType() == MMSWINDOWTYPE_MAINWINDOW) {
00228                 if (windows.at(i)->isShown()&&(!windows.at(i)->willHide())) {
00229                     // set active main window as toplevel
00230                     this->toplevel = windows.at(i);
00231                     return false;
00232                 }
00233             }
00234         }
00235     }
00236 
00237     // set new toplevel window
00238     this->toplevel = window;
00239     return true;
00240 }
00241 
00242 MMSWindow *MMSWindowManager::getToplevelWindow() {
00243     return this->toplevel;
00244 }
00245 
00246 void MMSWindowManager::removeWindowFromToplevel(MMSWindow *window) {
00247     // toplevel window?
00248     if (this->toplevel != window)
00249         return;
00250 
00251     if (window->getType() == MMSWINDOWTYPE_POPUPWINDOW) {
00252         MMSWindow *firstMainWindow = NULL;
00253         // a popup window will be hidden, so try to find an active
00254         // popup or main window to get the toplevel status
00255         for(vector<MMSWindow*>::iterator i = this->windows.begin(); i != this->windows.end(); ++i) {
00256             bool focusable;
00257             MMSWINDOWTYPE type = (*i)->getType();
00258             if(
00259                 ((*i) != window) &&
00260                 ((*i)->isShown()) &&
00261                 (*i)->getFocusable(focusable) &&
00262                 focusable
00263             ) {
00264                 if(type == MMSWINDOWTYPE_POPUPWINDOW) {
00265                     this->toplevel = *i;
00266                     return;
00267                 } else if(!firstMainWindow && (type == MMSWINDOWTYPE_MAINWINDOW)) {
00268                     firstMainWindow = *i;
00269                 }
00270             }
00271         }
00272         if(firstMainWindow) {
00273             this->toplevel = firstMainWindow;
00274             return;
00275         }
00276     }
00277 
00278     if ((window->getType() == MMSWINDOWTYPE_MAINWINDOW) || (window->getType() == MMSWINDOWTYPE_POPUPWINDOW)) {
00279         // a main or popup window will be hidden, so try to find an active
00280         // root window to get the toplevel status
00281         for(vector<MMSWindow*>::iterator i = this->windows.begin(); i != this->windows.end(); ++i) {
00282             if(
00283                 ((*i)->getType() == MMSWINDOWTYPE_ROOTWINDOW) &&
00284                 ((*i)->isShown())
00285             ) {
00286                     this->toplevel = *i;
00287                     return;
00288             }
00289         }
00290     }
00291 
00292     // no window found, no toplevel :)
00293     this->toplevel = NULL;
00294 }
00295 
00296 void MMSWindowManager::setBackgroundWindow(MMSWindow *window) {
00297     if (window) {
00298         this->backgroundwindow = window;
00299     }
00300     showBackgroundWindow();
00301 }
00302 
00303 MMSWindow *MMSWindowManager::getBackgroundWindow() {
00304     return this->backgroundwindow;
00305 }
00306 
00307 void MMSWindowManager::showBackgroundWindow() {
00308     if (this->backgroundwindow) {
00309         unsigned int opacity;
00310         if (this->backgroundwindow->getOpacity(opacity))
00311             if (opacity) {
00312                 this->backgroundwindow->show();
00313                 this->backgroundwindow->waitUntilShown();
00314             }
00315     }
00316 }
00317 
00318 void MMSWindowManager::setPointerPosition(int pointer_posx, int pointer_posy, bool pressed) {
00319     mmsfbwindowmanager->setPointerPosition(pointer_posx, pointer_posy, pressed);
00320 }
00321 
00322 MMSTranslator *MMSWindowManager::getTranslator() {
00323     return &this->translator;
00324 }
00325 
00326 void MMSWindowManager::onTargetLangChanged(MMSLanguage lang) {
00327     // the language has changed, inform all windows
00328     for (unsigned int i = 0; i < this->windows.size(); i++) {
00329         this->windows.at(i)->targetLangChanged(lang);
00330     }
00331 }
00332 
00333 MMSThemeManager *MMSWindowManager::getThemeManager() {
00334     return &this->themeManager;
00335 }
00336 
00337 bool MMSWindowManager::onAnimation(MMSPulser *pulser) {
00338     // get new opacity
00339     int opacity = 255 - pulser->getOffset();
00340     // animation finished?
00341     if (opacity <= 0) {
00342         // yes
00343         return false;
00344     }
00345 
00346     // set new opacity
00347     this->anim_saved_screen->setOpacity(opacity);
00348 
00349     return true;
00350 }
00351 
00352 void MMSWindowManager::onAfterAnimation(MMSPulser *pulser) {
00353     // animation finished
00354     if (this->anim_saved_screen) {
00355         // delete the temporary window
00356         this->anim_saved_screen->hide();
00357         delete this->anim_saved_screen;
00358         this->anim_saved_screen = NULL;
00359     }
00360 }
00361 
00362 void MMSWindowManager::onThemeChanged(string themeName, bool fade_in) {
00363     // get access to the layer
00364     MMSFBLayer *layer = mmsfbmanager.getGraphicsLayer();
00365     this->anim_saved_screen = NULL;
00366 
00367     if (fade_in) {
00368         // create a temporary window to save the screen
00369         // so we can have a nice animation while switching the theme
00370         if (layer) {
00371             MMSFBSurfacePixelFormat pixelformat;
00372             layer->getPixelFormat(&pixelformat);
00373             int w, h;
00374             layer->getResolution(&w, &h);
00375             layer->createWindow(&this->anim_saved_screen, 0, 0, w, h,
00376                                 pixelformat, isAlphaPixelFormat(pixelformat), 0);
00377         }
00378     }
00379 
00380     if (this->anim_saved_screen) {
00381         // get a screenshot
00382         this->anim_saved_screen->getScreenshot();
00383 
00384         // show the saved screen
00385         this->anim_saved_screen->raiseToTop();
00386         this->anim_saved_screen->setOpacity(255);
00387         this->anim_saved_screen->show();
00388     }
00389 
00390     // the theme has changed, inform all windows
00391     for (unsigned int i = 0; i < this->windows.size(); i++) {
00392         this->windows.at(i)->themeChanged(themeName);
00393     }
00394 
00395     if (this->anim_saved_screen) {
00396         // do the animation
00397         this->pulser.setMaxOffset(255,MMSPULSER_SEQ_LINEAR);
00398         this->pulser.setStepsPerSecond(255);
00399         this->pulser.start(false);
00400     }
00401 }
00402 
00403 unsigned int MMSWindowManager::printStack(char *buffer) {
00404     if (!buffer) {
00405         char buffer[50*1024];
00406         memset((void*)buffer, ' ', sizeof(buffer));
00407         char *ptr = buffer;
00408 
00409         // print header
00410         int cnt;
00411         cnt = sprintf(ptr, "NAME                             THIS     STATE         OPACITY OWN_SURFACE\n");
00412         ptr[cnt] = ' ';
00413         ptr+= cnt;
00414         cnt = sprintf(ptr, "---------------------------------------------------------------------------\n");
00415         ptr[cnt] = ' ';
00416         ptr+= cnt;
00417 
00418         for (unsigned int i = 0; i < this->windows.size(); i++) {
00419             ptr += this->windows.at(i)->printStack(ptr);
00420         }
00421 
00422         *ptr = 0;
00423         printf("%s", buffer);
00424         return (unsigned int)(ptr - buffer);
00425     }
00426     else {
00427         char *ptr = buffer;
00428 
00429         // print header
00430         int cnt;
00431         cnt = sprintf(ptr, "NAME                             THIS     STATE         OPACITY OWN_SURFACE\n");
00432         ptr[cnt] = ' ';
00433         ptr+= cnt;
00434         cnt = sprintf(ptr, "---------------------------------------------------------------------------\n");
00435         ptr[cnt] = ' ';
00436         ptr+= cnt;
00437 
00438         for (unsigned int i = 0; i < this->windows.size(); i++) {
00439             ptr += this->windows.at(i)->printStack(ptr);
00440         }
00441 
00442         *ptr = 0;
00443         return (unsigned int)(ptr - buffer);
00444     }
00445 }
00446 

Generated by doxygen