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

mmsmenuwidget.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/mmsmenuwidget.h"
00034 #include "mmsgui/mmssliderwidget.h"
00035 #include <string.h>
00036 
00037 #define MMSMENUWIDGET_ANIM_MAX_OFFSET       20
00038 #define MMSMENUWIDGET_ANIM_STEPS_PER_SECOND (getSmoothDelay()>=100)?MMSMENUWIDGET_ANIM_MAX_OFFSET * 1000 / getSmoothDelay():MMSMENUWIDGET_ANIM_MAX_OFFSET * 5
00039 
00040 MMSMenuWidget::MMSMenuWidget(MMSWindow *root, string className, MMSTheme *theme) : MMSWidget::MMSWidget() {
00041     // initialize the callbacks
00042     onSelectItem = new sigc::signal<void, MMSWidget*>;
00043     onBeforeScroll = new sigc::signal<void, MMSWidget*>;
00044 
00045     // initialize the animation callbacks
00046     this->onBeforeAnimation_connection  = this->pulser.onBeforeAnimation.connect(sigc::mem_fun(this, &MMSMenuWidget::onBeforeAnimation));
00047     this->onAnimation_connection        = this->pulser.onAnimation.connect(sigc::mem_fun(this, &MMSMenuWidget::onAnimation));
00048     this->onAfterAnimation_connection   = this->pulser.onAfterAnimation.connect(sigc::mem_fun(this, &MMSMenuWidget::onAfterAnimation));
00049 
00050     create(root, className, theme);
00051 }
00052 
00053 MMSMenuWidget::~MMSMenuWidget() {
00054     // delete the callbacks
00055     if (onSelectItem) delete onSelectItem;
00056     if (onBeforeScroll) delete onBeforeScroll;
00057 
00058     // disconnect callbacks from pulser
00059     this->onBeforeAnimation_connection.disconnect();
00060     this->onAnimation_connection.disconnect();
00061     this->onAfterAnimation_connection.disconnect();
00062 
00063     if (this->itemTemplate)
00064         delete this->itemTemplate;
00065 }
00066 
00067 bool MMSMenuWidget::create(MMSWindow *root, string className, MMSTheme *theme) {
00068     this->type = MMSWIDGETTYPE_MENU;
00069     this->className = className;
00070 
00071     // init attributes for drawable widgets
00072     this->da = new MMSWIDGET_DRAWABLE_ATTRIBUTES;
00073     if (theme) this->da->theme = theme; else this->da->theme = globalTheme;
00074     this->menuWidgetClass = this->da->theme->getMenuWidgetClass(className);
00075     this->da->baseWidgetClass = &(this->da->theme->menuWidgetClass.widgetClass);
00076     if (this->menuWidgetClass) this->da->widgetClass = &(this->menuWidgetClass->widgetClass); else this->da->widgetClass = NULL;
00077 
00078     this->selimage = NULL;
00079     this->itemTemplate = NULL;
00080 
00081     this->item_w = 0;
00082     this->item_h = 0;
00083     this->x = 0;
00084     this->y = 0;
00085     this->px = 0;
00086     this->py = 0;
00087     this->v_items = 0;
00088     this->h_items = 0;
00089 
00090     this->firstFocus = false;
00091     this->firstSelection = false;
00092 
00093     this->zoomselwidth = 0;
00094     this->zoomselheight = 0;
00095     this->zoomselshiftx = 0;
00096     this->zoomselshifty = 0;
00097 
00098     this->smooth_scrolling = getSmoothScrolling();
00099     this->scrolling_offset = 0;
00100 
00101     this->smooth_selection = getSmoothSelection();
00102     this->selection_offset_x = 0;
00103     this->selection_offset_y = 0;
00104 
00105     this->frame_delay = 0;
00106     this->frame_delay_set = false;
00107 
00108     this->parent_window = NULL;
00109     this->curr_submenu = -1;
00110     this->parent_menu = NULL;
00111     this->back_item = -1;
00112 
00113     return MMSWidget::create(root, true, false, true, true, true, false, true);
00114 }
00115 
00116 MMSWidget *MMSMenuWidget::copyWidget() {
00117     /* create widget */
00118     MMSMenuWidget *newWidget = new MMSMenuWidget(this->rootwindow, className);
00119 
00120     newWidget->className = this->className;
00121     newWidget->menuWidgetClass = this->menuWidgetClass;
00122     newWidget->myMenuWidgetClass = this->myMenuWidgetClass;
00123 
00124     newWidget->selimage = this->selimage;
00125     newWidget->itemTemplate = this->itemTemplate;
00126 
00127     newWidget->item_w = this->item_w;     /* width of an item */
00128     newWidget->item_h = this->item_h;     /* height of an item */
00129     newWidget->v_items = this->v_items;    /* number of visible vertical items */
00130     newWidget->h_items = this->h_items;    /* number of visible horizontal items */
00131 
00132     //! x position of the selected item
00133     newWidget->x = this->x;
00134     //! y position of the selected item
00135     newWidget->y = this->y;
00136     //! scroll x-offset
00137     newWidget->px = this->px;
00138     //! scroll y-offset
00139     newWidget->py = this->py;
00140 
00141     newWidget->firstFocus = this->firstFocus;
00142     newWidget->firstSelection = this->firstSelection;
00143 
00144     newWidget->zoomsel = this->zoomsel;     /* should the selected item zoomed? */
00145     newWidget->zoomselwidth = this->zoomselwidth;   /* this value will be added to item_w for the selected item */
00146     newWidget->zoomselheight = this->zoomselheight; /* this value will be added to item_h for the selected item */
00147     newWidget->zoomselshiftx = this->zoomselshiftx; /* x-move the unselected items around the selected item */
00148     newWidget->zoomselshifty = this->zoomselshifty; /* y-move the unselected items around the selected item */
00149     newWidget->smooth_scrolling = this->smooth_scrolling;
00150     newWidget->scrolling_offset = this->scrolling_offset;
00151     newWidget->smooth_selection = this->smooth_selection;
00152     newWidget->selection_offset_x = this->selection_offset_x;
00153     newWidget->selection_offset_y = this->selection_offset_y;
00154 
00155     newWidget->frame_delay = this->frame_delay;
00156     newWidget->frame_delay_set = this->frame_delay_set;
00157 
00158     newWidget->pulser_mode = this->pulser_mode;
00159     newWidget->anim_offset = this->anim_offset;
00160     newWidget->anim_jumpover = this->anim_jumpover;
00161     newWidget->anim_factor = this->anim_factor;
00162 
00163     newWidget->virtualGeom = this->virtualGeom;
00164 
00165     newWidget->parent_window = this->parent_window;
00166     newWidget->iteminfos = this->iteminfos;
00167     newWidget->curr_submenu = this->curr_submenu;
00168     newWidget->parent_menu = this->parent_menu;
00169     newWidget->back_item = this->back_item;
00170 
00171     /* copy base widget */
00172     MMSWidget::copyWidget((MMSWidget*)newWidget);
00173 
00174     /* reload my images */
00175     newWidget->selimage = NULL;
00176 
00177     if (drawable) {
00178         if (this->rootwindow) {
00179             string path, name;
00180 
00181             if (!newWidget->getSelImagePath(path)) path = "";
00182             if (!newWidget->getSelImageName(name)) name = "";
00183             newWidget->selimage = this->rootwindow->im->getImage(path, name);
00184         }
00185     }
00186 
00187     return newWidget;
00188 }
00189 
00190 bool MMSMenuWidget::init() {
00191     // init widget basics
00192     if (!MMSWidget::init())
00193         return false;
00194 
00195     // load my images
00196     string path, name;
00197     if (!getSelImagePath(path)) path = "";
00198     if (!getSelImageName(name)) name = "";
00199     this->selimage = this->rootwindow->im->getImage(path, name);
00200 
00201     return true;
00202 }
00203 
00204 bool MMSMenuWidget::release() {
00205     // release widget basics
00206     if (!MMSWidget::release())
00207         return false;
00208 
00209     // release my images
00210     this->rootwindow->im->releaseImage(this->selimage);
00211     this->selimage = NULL;
00212 
00213     return true;
00214 }
00215 
00216 
00217 void MMSMenuWidget::lock() {
00218     if (this->surface)
00219         this->surface->lock();
00220 }
00221 
00222 void MMSMenuWidget::unlock() {
00223     if (this->surface)
00224         this->surface->unlock();
00225 }
00226 
00227 
00228 
00229 bool MMSMenuWidget::draw(bool *backgroundFilled) {
00230 
00231     bool myBackgroundFilled = false;
00232 
00233     if(!surface)
00234         return false;
00235 
00236     if (backgroundFilled) {
00237         if (this->has_own_surface)
00238             *backgroundFilled = false;
00239     }
00240     else
00241         backgroundFilled = &myBackgroundFilled;
00242 
00243     // lock
00244     lock();
00245 
00246     // draw widget basics
00247     if (MMSWidget::draw(backgroundFilled)) {
00248         // update window surface with an area of surface
00249         updateWindowSurfaceWithSurface(!*backgroundFilled);
00250     }
00251 
00252     // unlock
00253     unlock();
00254 
00255     // draw widgets debug frame
00256     return MMSWidget::drawDebug();
00257 }
00258 
00259 
00260 void MMSMenuWidget::add(MMSWidget *widget) {
00261     // no widget to be added here, see newItem()
00262 }
00263 
00264 
00265 
00266 void MMSMenuWidget::adjustVirtualRect() {
00267     /* we use a virtual rectangle to support smooth move of items outside widgets inner geometry */
00268     /* per default the rectangles are the same */
00269     this->virtualGeom = this->innerGeom;
00270 
00271     /* if smooth scrolling we need to adjust the virtual rect */
00272     if (this->smooth_scrolling) {
00273         if (getFixedPos() >= 0) {
00274             /* menu with fixed selection */
00275             if (getCols() == 1) {
00276                 /* fixed vertical menu */
00277                 int rih = item_h + getItemVMargin() * 2;
00278                 int used_h = this->h_items * rih + this->zoomselwidth;
00279                 int min_h = this->virtualGeom.h + rih;
00280                 while (used_h < min_h) {
00281                     used_h+=rih;
00282                     this->v_items++;
00283                 }
00284                 this->virtualGeom.y-= (used_h - this->virtualGeom.h)/2;
00285                 this->virtualGeom.h = used_h;
00286             }
00287             else {
00288                 /* fixed horizontal menu */
00289                 int riw = item_w + getItemHMargin() * 2;
00290                 int used_w = this->h_items * riw + this->zoomselwidth;
00291                 int min_w = this->virtualGeom.w + riw;
00292                 while (used_w < min_w) {
00293                     used_w+=riw;
00294                     this->h_items++;
00295                 }
00296                 this->virtualGeom.x-= (used_w - this->virtualGeom.w)/2;
00297                 this->virtualGeom.w = used_w;
00298             }
00299         }
00300     }
00301 }
00302 
00303 bool MMSMenuWidget::getConfig(bool *firstTime) {
00304     unsigned int rest;
00305 
00306     if (!isGeomSet()) {
00307         /* i must have my geometry */
00308         MMSWindow *root = getRootWindow();
00309         if (root) {
00310             root->recalculateChildren();
00311         }
00312         else
00313             return false;
00314     }
00315 
00316     /* check if config already set */
00317     if (this->item_w) {
00318         if (firstTime) *firstTime = false;
00319 
00320         /* we need to adjust the virtual rect */
00321         adjustVirtualRect();
00322 
00323         return true;
00324     }
00325     else
00326         if (firstTime) *firstTime = true;
00327 
00328     /* not set, fill my variables */
00329     if (getItemWidth() != "")
00330         getPixelFromSizeHint(&this->item_w, getItemWidth(), this->innerGeom.w, 0);
00331     else
00332         this->item_w = this->innerGeom.w;
00333 
00334     if (getItemHeight() != "")
00335         getPixelFromSizeHint(&this->item_h, getItemHeight(), this->innerGeom.h, 0);
00336     else
00337         this->item_h = this->innerGeom.h;
00338 
00339     if (this->item_w <= 0) {
00340         /* it seems that width should be a factor of height */
00341         getPixelFromSizeHint(&this->item_w, getItemWidth(), this->innerGeom.w, this->item_h);
00342     }
00343     else {
00344         /* it seems that height should be a factor of width */
00345         getPixelFromSizeHint(&this->item_h, getItemHeight(), this->innerGeom.h, this->item_w);
00346     }
00347 
00348     if (getZoomSelWidth() != "")
00349         getPixelFromSizeHint((int*)&this->zoomselwidth, getZoomSelWidth(), this->item_w, 0);
00350     else
00351         this->zoomselwidth = 0;
00352 
00353     if (getZoomSelHeight() != "")
00354         getPixelFromSizeHint((int*)&this->zoomselheight, getZoomSelHeight(), this->item_h, 0);
00355     else
00356         this->zoomselheight = 0;
00357 
00358     this->zoomsel = ((this->zoomselwidth)||(this->zoomselheight));
00359 
00360     if (this->zoomsel) {
00361         if (getZoomSelShiftX() != "")
00362             getPixelFromSizeHint((int*)&this->zoomselshiftx, getZoomSelShiftX(), this->zoomselwidth, 0);
00363         else
00364             this->zoomselshiftx = 0;
00365 
00366         if (getZoomSelShiftY() != "")
00367             getPixelFromSizeHint((int*)&this->zoomselshifty, getZoomSelShiftY(), this->zoomselheight, 0);
00368         else
00369             this->zoomselshifty = 0;
00370     }
00371 
00372 
00373     /* calculate visible horizontal items */
00374     this->h_items = (this->innerGeom.w - this->zoomselwidth) / this->item_w;
00375     rest = (this->innerGeom.w - this->zoomselwidth) % this->item_w;
00376     do {
00377         if (this->h_items * getItemHMargin() * 2 <= rest)
00378             break;
00379         this->h_items--;
00380         rest+=item_w;
00381     } while (this->h_items > 0);
00382     if (this->h_items == 0) {
00383         this->h_items = 1;
00384         this->item_w-=getItemHMargin() * 2;
00385     }
00386 
00387     /* calculate visible vertical items */
00388     this->v_items = (this->innerGeom.h - this->zoomselheight) / this->item_h;
00389     rest = (this->innerGeom.h - this->zoomselheight) % this->item_h;
00390     do {
00391         if (this->v_items * getItemVMargin() * 2 <= rest)
00392             break;
00393         this->v_items--;
00394         rest+=item_h;
00395     } while (this->v_items > 0);
00396     if (this->v_items == 0) {
00397         this->v_items = 1;
00398         this->item_h-=getItemVMargin() * 2;
00399     }
00400 
00401     /* columns */
00402     if (getCols()==0)
00403         setCols(this->h_items);
00404 
00405     /* we need to adjust the virtual rect */
00406     adjustVirtualRect();
00407 
00408     return true;
00409 }
00410 
00411 
00412 
00413 void MMSMenuWidget::drawchildren(bool toRedrawOnly, bool *backgroundFilled, MMSFBRectangle *rect2update) {
00414 
00415     if ((toRedrawOnly) && (this->toRedraw==false) && (this->redrawChildren==false))
00416         return;
00417 
00418     if (!this->visible)
00419         return;
00420 
00421     // lock me
00422     lock();
00423 
00424     if (this->selimage) {
00425         // draw the selection image behind the items
00426         MMSWidget *w = getSelectedItem();
00427         if (w) {
00428             MMSFBRectangle wgeom = w->getGeometry();
00429             wgeom.x+=selection_offset_x-innerGeom.x;
00430             wgeom.y+=selection_offset_y-innerGeom.y;
00431             if (getCols()==1) {
00432                 if (smooth_scrolling)
00433                     wgeom.y-=scrolling_offset;
00434             }
00435             else {
00436                 if (smooth_scrolling)
00437                     wgeom.x-=scrolling_offset;
00438             }
00439             this->surface->setBlittingFlagsByBrightnessAlphaAndOpacity(brightness, 255, opacity);
00440             this->selimage->lock();
00441             this->surface->stretchBlit(selimage, NULL, &wgeom);
00442             this->selimage->unlock();
00443         }
00444     }
00445 
00446     // draw the items
00447     MMSWidget::drawchildren(toRedrawOnly, backgroundFilled, rect2update);
00448 
00449     // unlock me
00450     unlock();
00451 }
00452 
00453 void MMSMenuWidget::recalculateChildren() {
00454     MMSFBRectangle rect;
00455     bool         firstTime;
00456     int          item_hmargin;
00457     int          item_vmargin;
00458     unsigned int cols;
00459     int          fixedpos, realpos;
00460 
00461     /* check something first */
00462     if(this->children.empty())
00463         return;
00464 
00465     if(!isGeomSet())
00466         return;
00467 
00468     if (!getConfig(&firstTime))
00469         return;
00470 
00471     // lock me
00472     lock();
00473 
00474     /* get values */
00475     item_hmargin = getItemHMargin();
00476     item_vmargin = getItemVMargin();
00477     cols = getCols();
00478     fixedpos = getFixedPos();
00479 
00480     /* normal menu or fixed selection? */
00481     if (fixedpos < 0) {
00482         /* normal menu */
00483         /* item pos with margin */
00484         int item_xx = this->virtualGeom.x + item_hmargin;
00485         int item_yy = this->virtualGeom.y + item_vmargin;
00486 
00487         /* item width/height with margin */
00488         int item_ww = item_w + item_hmargin * 2;
00489         int item_hh = item_h + item_vmargin * 2;
00490 
00491         /* menu pos */
00492         int menu_xx = this->virtualGeom.x + this->virtualGeom.w - item_w - item_hmargin;
00493         int menu_yy = this->virtualGeom.y + this->virtualGeom.h - item_h - item_vmargin;
00494 
00495         /* calc some help values if the selected item should zoomed in */
00496         int selected_item = 0, rows_before = 0, rows_after = 0, selected_col = 0;
00497         if (this->zoomsel) {
00498             selected_item = getSelected();
00499             rows_before = (selected_item / cols) * cols;
00500             rows_after = rows_before + cols;
00501             selected_col = selected_item % cols;
00502         }
00503 
00504         /* through all items */
00505         for(int i = 0; i < (int)this->children.size(); i++) {
00506             rect.x = item_xx + (i % (int)cols - (int)px) * item_ww;
00507             rect.y = item_yy + (i / (int)cols - (int)py) * item_hh;
00508             rect.w = item_w;
00509             rect.h = item_h;
00510 
00511             if (cols==1) {
00512                 if (smooth_scrolling)
00513                     rect.y+=scrolling_offset;
00514             }
00515             else {
00516                 if (smooth_scrolling)
00517                     rect.x+=scrolling_offset;
00518             }
00519 
00520             bool visibleBefore = this->children.at(i)->isVisible();
00521             bool visibleAfter = (!((rect.x < item_xx) || (rect.y < item_yy) || (rect.x > menu_xx) || (rect.y > menu_yy)));
00522 
00523             if (!visibleAfter) {
00524                 // checking for smooth scrolling
00525                 if (smooth_scrolling) {
00526                     if (cols==1) {
00527                         // draw parts of items before and after
00528                         visibleAfter = (!((rect.x < item_xx) || (rect.y <= item_yy - item_hh) || (rect.x > menu_xx) || (rect.y >= menu_yy + item_hh)));
00529                     }
00530                     else {
00531                         // draw parts of items before and after
00532                         visibleAfter = (!((rect.x <= item_xx - item_ww) || (rect.y < item_yy) || (rect.x >= menu_xx + item_ww) || (rect.y > menu_yy)));
00533                     }
00534                 }
00535             }
00536 
00537             if (visibleBefore || visibleAfter) {
00538                 if (visibleAfter) {
00539                     /* the item is visible, set geometry for it */
00540                     if (this->zoomsel) {
00541                         /* the selected item should zoomed in, so i have to align the items around it */
00542                         if (cols == 1) {
00543                             /* menu with one column (vertical) */
00544                             if (i > selected_item)
00545                                 rect.y+=this->zoomselheight;
00546 
00547                             if (i == selected_item) {
00548                                 rect.w+=this->zoomselwidth;
00549                                 rect.h+=this->zoomselheight;
00550                             }
00551                             else {
00552                                 int xxx = this->zoomselwidth / 2;
00553                                 rect.x+=xxx;
00554                                 if (this->zoomselshiftx > 0) {
00555                                     xxx+=this->zoomselwidth % 2;
00556                                     if (this->zoomselshiftx < xxx)
00557                                         xxx=this->zoomselshiftx;
00558                                 }
00559                                 else {
00560                                     xxx*=-1;
00561                                     if (this->zoomselshiftx > xxx)
00562                                         xxx=this->zoomselshiftx;
00563                                 }
00564                                 rect.x+=xxx;
00565                             }
00566                         }
00567                         else {
00568                             /* menu with columns and rows */
00569                             if (i < rows_before) {
00570                                 /* the rows before */
00571                                 if (i > selected_col)
00572                                     rect.x+=this->zoomselwidth;
00573 
00574                                 if (i == selected_col) {
00575                                     int xxx = this->zoomselwidth / 2;
00576                                     rect.x+=xxx;
00577                                     if (this->zoomselshiftx > 0) {
00578                                         xxx+=this->zoomselwidth % 2;
00579                                         if (this->zoomselshiftx < xxx)
00580                                             xxx=this->zoomselshiftx;
00581                                     }
00582                                     else {
00583                                         xxx*=-1;
00584                                         if (this->zoomselshiftx > xxx)
00585                                             xxx=this->zoomselshiftx;
00586                                     }
00587                                     rect.x+=xxx;
00588 
00589                                 }
00590                             }
00591                             else
00592                             if (i < rows_after) {
00593                                 /* current row */
00594                                 if (i > selected_item)
00595                                     rect.x+=this->zoomselwidth;
00596 
00597                                 if (i == selected_item) {
00598                                     rect.w+=this->zoomselwidth;
00599                                     rect.h+=this->zoomselheight;
00600                                 }
00601                                 else {
00602                                     int yyy = this->zoomselheight / 2;
00603                                     rect.y+=yyy;
00604                                     if (this->zoomselshifty > 0) {
00605                                         yyy+=this->zoomselheight % 2;
00606                                         if (this->zoomselshifty < yyy)
00607                                             yyy=this->zoomselshifty;
00608                                     }
00609                                     else {
00610                                         yyy*=-1;
00611                                         if (this->zoomselshifty > yyy)
00612                                             yyy=this->zoomselshifty;
00613                                     }
00614                                     rect.y+=yyy;
00615                                 }
00616                             }
00617                             else {
00618                                 /* the rows after */
00619                                 rect.y+=this->zoomselheight;
00620 
00621                                 if (i > selected_col)
00622                                     rect.x+=this->zoomselwidth;
00623 
00624                                 if (i == selected_col) {
00625                                     int xxx = this->zoomselwidth / 2;
00626                                     rect.x+=xxx;
00627                                     if (this->zoomselshiftx > 0) {
00628                                         xxx+=this->zoomselwidth % 2;
00629                                         if (this->zoomselshiftx < xxx)
00630                                             xxx=this->zoomselshiftx;
00631                                     }
00632                                     else {
00633                                         xxx*=-1;
00634                                         if (this->zoomselshiftx > xxx)
00635                                             xxx=this->zoomselshiftx;
00636                                     }
00637                                     rect.x+=xxx;
00638 
00639                                 }
00640                             }
00641                         }
00642                     }
00643 
00644 
00645 //DEBUGOUT("rect=%s,%d,%d,%d,%d\n", this->children.at(i)->getName().c_str(),rect.x,rect.y,rect.w,rect.h);
00646 //DEBUGOUT("rectx=%d,%d\n", this->innerGeom.x,this->innerGeom.y);
00647 //DEBUGOUT("rectx=%d,%d\n", this->virtualGeom.x,this->virtualGeom.y);
00648 
00649 //                  rect.x+=this->innerGeom.x;
00650 //                  rect.y+=this->innerGeom.y;
00651 
00652                     this->children.at(i)->setGeometry(rect);
00653 
00654                 }
00655 
00656                 /* switch the visibility */
00657                 this->children.at(i)->setVisible(visibleAfter, false);
00658             }
00659 
00660 
00661             if ((i+1)%cols==0)
00662                 selected_col+=cols;
00663 
00664         }
00665     }
00666     else {
00667         /* menu with fixed selection */
00668         if (cols == 1) {
00669             /* menu with one column (vertical) */
00670             if (fixedpos >= this->v_items)
00671                 fixedpos = (this->v_items - 1) / 2;
00672 
00673             /* item pos with margin */
00674             int item_xx = this->virtualGeom.x + item_hmargin;
00675             int item_yy = this->virtualGeom.y + item_vmargin;
00676 
00677             /* item height with margin */
00678             int item_hh = item_h + item_vmargin * 2;
00679 
00680             /* menu pos */
00681             int menu_yy = this->virtualGeom.y + this->virtualGeom.h - item_h - item_vmargin;
00682 
00683             /* check if the number of children is less than visible vertical items */
00684             int lessItems = (int)this->v_items - (int)this->children.size();
00685             if (lessItems > 0) {
00686                 /* yes, I have to recalculate the temporary menu area around the fixedpos */
00687                 int items_above = (lessItems * (100 * fixedpos) / (this->v_items - 1) + 50) / 100;
00688                 item_yy+= items_above * item_hh;
00689                 fixedpos-= items_above;
00690                 menu_yy-= (lessItems - items_above) * item_hh;
00691             }
00692 
00693             /* through all items */
00694             for(int i = 0; i < (int)this->children.size(); i++) {
00695                 rect.x = item_xx;
00696                 rect.y = item_yy + (i + fixedpos - (int)py) * item_hh;
00697                 rect.w = item_w;
00698                 rect.h = item_h;
00699 
00700                 bool visibleBefore = this->children.at(i)->isVisible();
00701                 bool visibleAfter = (!((rect.y < item_yy) || (rect.y > menu_yy)));
00702                 if (visibleAfter)
00703                     realpos = (rect.y - item_yy) / item_hh;
00704                 else
00705                     realpos = -1;
00706 
00707                 if (!visibleAfter) {
00708                     /* the item is will not visible, but fixedpos is set, try with it */
00709                     if (rect.y < item_yy) {
00710                         /* items after, added at bottom of the menu */
00711                         rect.y = item_yy + (i + (int)this->children.size() + fixedpos - (int)py) * item_hh;
00712                         visibleAfter = (!((rect.y < item_yy) || (rect.y > menu_yy)));
00713                         if (visibleAfter)
00714                             realpos = (rect.y - item_yy) / item_hh;
00715                     }
00716                     else {
00717                         /* items before, added at top of the menu */
00718                         int ic = (int)this->children.size() - fixedpos + (int)py;
00719                         if (i >= ic) {
00720                             /* try if it can be visible from top of menu */
00721                             rect.y = item_yy + (i - ic) * item_hh;
00722                             visibleAfter = (!((rect.y < item_yy) || (rect.y > menu_yy)));
00723                             if (visibleAfter)
00724                                 realpos = (rect.y - item_yy) / item_hh;
00725                         }
00726                     }
00727                 }
00728 
00729                 if (visibleBefore || visibleAfter) {
00730                     if (visibleAfter) {
00731                         /* the item is visible, set geometry for it */
00732                         if (this->zoomsel) {
00733                             /* the selected item should zoomed in, so i have to align the items around it */
00734                             if (realpos > fixedpos)
00735                                 rect.y+=this->zoomselheight;
00736 
00737                             if (realpos == fixedpos) {
00738                                 rect.w+=this->zoomselwidth;
00739                                 rect.h+=this->zoomselheight;
00740                             }
00741                             else {
00742                                 int xxx = this->zoomselwidth / 2;
00743                                 rect.x+=xxx;
00744                                 if (this->zoomselshiftx > 0) {
00745                                     xxx+=this->zoomselwidth % 2;
00746                                     if (this->zoomselshiftx < xxx)
00747                                         xxx=this->zoomselshiftx;
00748                                 }
00749                                 else {
00750                                     xxx*=-1;
00751                                     if (this->zoomselshiftx > xxx)
00752                                         xxx=this->zoomselshiftx;
00753                                 }
00754                                 rect.x+=xxx;
00755                             }
00756                         }
00757 
00758                         this->children.at(i)->setGeometry(rect);
00759 
00760                         /* dim down and/or increase transparency */
00761                         int bn = 255;
00762                         int op = 255;
00763                         if (realpos < fixedpos) {
00764                             /* pos before selected item */
00765                             int dim_top = getDimTop();
00766                             if (dim_top > 0)
00767                                 if (realpos+1 < fixedpos) {
00768                                     bn = 255 - dim_top + ((realpos * dim_top * 10) / (fixedpos - 1) + 5) / 10;
00769                                 }
00770                             int trans_top = getTransTop();
00771                             if (trans_top > 0)
00772                                 if (realpos+1 < fixedpos) {
00773                                     op = 255 - trans_top + ((realpos * trans_top * 10) / (fixedpos - 1) + 5) / 10;
00774                                 }
00775                         }
00776                         else
00777                         if (realpos > fixedpos) {
00778                             /* pos after selected item */
00779                             int dim_bottom = getDimBottom();
00780                             if (dim_bottom > 0)
00781                                 if (realpos-1 > fixedpos) {
00782                                     bn = 255 - (((realpos - fixedpos - 1) * dim_bottom * 10) / (this->v_items - fixedpos - 2) + 5) / 10;
00783                                 }
00784                             int trans_bottom = getTransBottom();
00785                             if (trans_bottom > 0)
00786                                 if (realpos-1 > fixedpos) {
00787                                     op = 255 - (((realpos - fixedpos - 1) * trans_bottom * 10) / (this->v_items - fixedpos - 2) + 5) / 10;
00788                                 }
00789                         }
00790 
00791                         /* check if focused */
00792                         if ((!isFocused())&&(this->firstFocus)) {
00793                             bn-= getDimItems();
00794                             op-= getTransItems();
00795                         }
00796 
00797                         /* set brightness */
00798                         if (bn < 0) bn = 0;
00799                         if (bn > 255) bn = 255;
00800                         this->children.at(i)->setBrightness(bn, false);
00801 
00802                         /* set opacity */
00803                         if (op < 0) op = 0;
00804                         if (op > 255) op = 255;
00805                         this->children.at(i)->setOpacity(op, false);
00806                     }
00807 
00808                     /* switch the visibility */
00809                     this->children.at(i)->setVisible(visibleAfter, false);
00810                 }
00811             }
00812         }
00813         else {
00814             /* menu with one row (horizontal) */
00815             if (fixedpos >= this->h_items)
00816                 fixedpos = (this->h_items - 1) / 2;
00817 
00818             /* item pos with margin */
00819             int item_xx = this->virtualGeom.x + item_hmargin;
00820             int item_yy = this->virtualGeom.y + item_vmargin;
00821 
00822             /* item width with margin */
00823             int item_ww = item_w + item_hmargin * 2;
00824 
00825             /* menu pos */
00826             int menu_xx = this->virtualGeom.x + this->virtualGeom.w - item_w - item_hmargin;
00827 
00828             /* check if the number of children is less than visible horizontal items */
00829             int lessItems;
00830             if (cols < this->children.size())
00831                 lessItems = (int)this->h_items - (int)cols;
00832             else
00833                 lessItems = (int)this->h_items - (int)this->children.size();
00834             if (lessItems > 0) {
00835                 /* yes, I have to recalculate the temporary menu area around the fixedpos */
00836                 int items_left = (lessItems * (100 * fixedpos) / (this->h_items - 1) + 50) / 100;
00837                 item_xx+= items_left * item_ww;
00838                 fixedpos-= items_left;
00839                 menu_xx-= (lessItems - items_left) * item_ww;
00840             }
00841 
00842             /* through all items */
00843             for(int i = 0; i < (int)this->children.size(); i++) {
00844 
00845                 if (i >= (int)cols) {
00846                     /* out of first row */
00847                     this->children.at(i)->setVisible(false, false);
00848                     continue;
00849                 }
00850 
00851                 rect.x = item_xx + (i + fixedpos - (int)px) * item_ww;
00852 
00853                 if (smooth_scrolling)
00854                     rect.x+=scrolling_offset;
00855 
00856                 rect.y = item_yy;
00857                 rect.w = item_w;
00858                 rect.h = item_h;
00859 
00860                 bool visibleBefore = this->children.at(i)->isVisible();
00861                 bool visibleAfter = (!((rect.x < item_xx) || (rect.x > menu_xx)));
00862 
00863                 if (visibleAfter)
00864                     realpos = (rect.x - item_xx) / item_ww;
00865                 else
00866                     realpos = -1;
00867 
00868                 if (!visibleAfter) {
00869                     /* the item is will not visible, but fixedpos is set, try with it */
00870                     if (rect.x < item_xx) {
00871                         /* items after, added at right of the menu */
00872                         if (cols < this->children.size())
00873                             rect.x = item_xx + (i + (int)cols + fixedpos - (int)px) * item_ww;
00874                         else
00875                             rect.x = item_xx + (i + (int)this->children.size() + fixedpos - (int)px) * item_ww;
00876 
00877                         if (!smooth_scrolling)
00878                             visibleAfter = (!((rect.x < item_xx) || (rect.x > menu_xx)));
00879                         else {
00880                             rect.x+=scrolling_offset;
00881                             visibleAfter = (!((rect.x+rect.w+(int)item_hmargin < item_xx) || (rect.x-rect.w-(int)item_hmargin > menu_xx)));
00882                         }
00883 
00884                         if (visibleAfter)
00885                             realpos = (rect.x - item_xx) / item_ww;
00886                     }
00887                     else {
00888                         /* items before, added at left of the menu */
00889                         int ic;
00890                         if (cols < this->children.size())
00891                             ic = (int)cols - fixedpos + (int)px;
00892                         else
00893                             ic = (int)this->children.size() - fixedpos + (int)px;
00894 
00895                         if (i >= ic) {
00896                             /* try if it can be visible from left of menu */
00897                             rect.x = item_xx + (i - ic) * item_ww;
00898 
00899                             if (!smooth_scrolling)
00900                                 visibleAfter = (!((rect.x < item_xx) || (rect.x > menu_xx)));
00901                             else {
00902                                 rect.x+=scrolling_offset;
00903                                 visibleAfter = (!((rect.x+rect.w+(int)item_hmargin < item_xx) || (rect.x-rect.w-(int)item_hmargin > menu_xx)));
00904                             }
00905 
00906                             if (visibleAfter)
00907                                 realpos = (rect.x - item_xx) / item_ww;
00908                         }
00909                     }
00910                 }
00911 
00912                 if (visibleBefore || visibleAfter) {
00913                     if (visibleAfter) {
00914                         /* the item is visible, set geometry for it */
00915                         if (this->zoomsel) {
00916                             /* the selected item should zoomed in, so i have to align the items around it */
00917                             if (!smooth_scrolling) {
00918                                 /* smooth scrolling not desired */
00919                                 if (realpos > fixedpos) {
00920                                     rect.x+=(int)this->zoomselwidth;
00921                                 }
00922 
00923                                 if (realpos == fixedpos) {
00924                                     rect.w+=this->zoomselwidth;
00925                                     rect.h+=this->zoomselheight;
00926                                 }
00927                                 else {
00928                                     int yyy = this->zoomselheight / 2;
00929                                     rect.y+=yyy;
00930                                     if (this->zoomselshifty > 0) {
00931                                         yyy+=this->zoomselheight % 2;
00932                                         if (this->zoomselshifty < yyy)
00933                                             yyy=this->zoomselshifty;
00934                                     }
00935                                     else {
00936                                         yyy*=-1;
00937                                         if (this->zoomselshifty > yyy)
00938                                             yyy=this->zoomselshifty;
00939                                     }
00940                                     rect.y+=yyy;
00941                                 }
00942                             }
00943                             else {
00944                                 /* smooth scrolling */
00945                                 // DEBUGOUT("scroll smooth\n");
00946                                 /* get the percent of scrolling */
00947                                 int d = (10000*scrolling_offset) / (this->item_w + item_hmargin*2);
00948 
00949                                 if (realpos > fixedpos) {
00950                                     rect.x+=(int)this->zoomselwidth;
00951                                 }
00952 
00953                                 if (d>=0)
00954                                 {
00955                                     if (realpos == fixedpos) {
00956                                         /* set blend value */
00957                                         this->children.at(i)->setBlend((d*255 + 5000) / 10000, false);
00958 
00959                                         /* calculate item's rectangle */
00960                                         int dd = ((int)this->zoomselwidth * d + 5000) / 10000;
00961                                         rect.x+=dd;
00962                                         rect.y+=((((int)this->zoomselheight/2)+this->zoomselshifty) * d + 5000) / 10000;
00963                                         rect.w+=(int)this->zoomselwidth - dd;
00964                                         rect.h+=(int)this->zoomselheight - ((int)this->zoomselheight * d + 5000) / 10000;
00965                                     }
00966                                     else {
00967                                         int yyy = this->zoomselheight / 2;
00968                                         rect.y+=yyy;
00969                                         if (this->zoomselshifty > 0) {
00970                                             yyy+=this->zoomselheight % 2;
00971                                             if (this->zoomselshifty < yyy)
00972                                                 yyy=this->zoomselshifty;
00973                                         }
00974                                         else {
00975                                             yyy*=-1;
00976                                             if (this->zoomselshifty > yyy)
00977                                                 yyy=this->zoomselshifty;
00978                                         }
00979                                         rect.y+=yyy;
00980 
00981                                         if ((d>0)&&(realpos+1 == fixedpos)) {
00982                                             /* set blend value */
00983                                             this->children.at(i)->setBlend((d*255 + 5000) / 10000, false);
00984 
00985                                             /* calculate item's rectangle */
00986                                             rect.y-=((((int)this->zoomselheight/2)+this->zoomselshifty) * d + 5000) / 10000;
00987                                             rect.w+=((int)this->zoomselwidth * d + 5000) / 10000;
00988                                             rect.h+=((int)this->zoomselheight * d + 5000) / 10000;
00989                                         }
00990                                         else
00991                                             /* reset blend value */
00992                                             this->children.at(i)->setBlend(0, false);
00993                                     }
00994                                 }
00995                                 else
00996                                 {
00997                                     if (realpos+1 == fixedpos) {
00998                                         /* set blend value */
00999                                         this->children.at(i)->setBlend((d*-255 + 5000) / 10000, false);
01000 
01001                                         /* calculate item's rectangle */
01002                                         rect.y-=((((int)this->zoomselheight/2)+this->zoomselshifty) * d - 5000) / 10000;
01003                                         rect.w+=(int)this->zoomselwidth + ((int)this->zoomselwidth * d - 5000) / 10000;
01004                                         rect.h+=(int)this->zoomselheight + ((int)this->zoomselheight * d - 5000) / 10000;
01005                                     }
01006                                     else {
01007                                         int yyy = this->zoomselheight / 2;
01008                                         rect.y+=yyy;
01009                                         if (this->zoomselshifty > 0) {
01010                                             yyy+=this->zoomselheight % 2;
01011                                             if (this->zoomselshifty < yyy)
01012                                                 yyy=this->zoomselshifty;
01013                                         }
01014                                         else {
01015                                             yyy*=-1;
01016                                             if (this->zoomselshifty > yyy)
01017                                                 yyy=this->zoomselshifty;
01018                                         }
01019                                         rect.y+=yyy;
01020 
01021                                         if (realpos == fixedpos) {
01022                                             /* set blend value */
01023                                             this->children.at(i)->setBlend((d*-255 + 5000) / 10000, false);
01024 
01025                                             /* calculate item's rectangle */
01026                                             rect.x+=this->zoomselwidth+((int)this->zoomselwidth * d - 5000) / 10000;
01027                                             rect.y+=((((int)this->zoomselheight/2)+this->zoomselshifty) * d - 5000) / 10000;
01028                                             rect.w-=((int)this->zoomselwidth * d - 5000) / 10000;
01029                                             rect.h-=((int)this->zoomselheight * d - 5000) / 10000;
01030                                         }
01031                                         else
01032                                             /* reset blend value */
01033                                             this->children.at(i)->setBlend(0, false);
01034                                     }
01035                                 }
01036 
01037                             }
01038                         }
01039 
01040                         this->children.at(i)->setGeometry(rect);
01041 
01042                         /* dim down and/or increase transparency */
01043                         int bn = 255;
01044                         int op = 255;
01045                         if (realpos < fixedpos) {
01046                             /* pos before selected item */
01047                             int dim_left = getDimLeft();
01048                             if (dim_left > 0)
01049                                 if (realpos+1 < fixedpos) {
01050                                     bn = 255 - dim_left + ((realpos * dim_left * 10) / (fixedpos - 1) + 5) / 10;
01051                                 }
01052                             int trans_left = getTransLeft();
01053                             if (trans_left > 0)
01054                                 if (realpos+1 < fixedpos) {
01055                                     op = 255 - trans_left + ((realpos * trans_left * 10) / (fixedpos - 1) + 5) / 10;
01056                                 }
01057                         }
01058                         else
01059                         if (realpos > fixedpos) {
01060                             /* pos after selected item */
01061                             int dim_right = getDimRight();
01062                             if (dim_right > 0)
01063                                 if (realpos-1 > fixedpos) {
01064                                     bn = 255 - (((realpos - fixedpos - 1) * dim_right * 10) / (this->h_items - fixedpos - 2) + 5) / 10;
01065                                 }
01066                             int trans_right = getTransRight();
01067                             if (trans_right > 0)
01068                                 if (realpos-1 > fixedpos) {
01069                                     op = 255 - (((realpos - fixedpos - 1) * trans_right * 10) / (this->h_items - fixedpos - 2) + 5) / 10;
01070                                 }
01071                         }
01072 
01073                         /* check if focused */
01074                         if (!isFocused()) {
01075                             bn-= getDimItems();
01076                             op-= getTransItems();
01077                         }
01078 
01079                         /* set brightness */
01080                         if (bn < 0) bn = 0;
01081                         if (bn > 255) bn = 255;
01082                         this->children.at(i)->setBrightness(bn, false);
01083 
01084                         /* set opacity */
01085                         if (op < 0) op = 0;
01086                         if (op > 255) op = 255;
01087                         this->children.at(i)->setOpacity((unsigned char)op, false);
01088                     }
01089 
01090                     /* switch the visibility */
01091                     this->children.at(i)->setVisible(visibleAfter, false);
01092                 }
01093             }
01094         }
01095     }
01096 
01097     // unlock me
01098     unlock();
01099 
01100     return;
01101 }
01102 
01103 void MMSMenuWidget::initParentWindow(void) {
01104     if (!this->rootwindow) return;
01105 
01106     /* get the parent window */
01107     this->parent_window = NULL;
01108     string pw = getParentWindow();
01109     if (pw!="") {
01110         MMSWindow *p = this->rootwindow->getParent(true);
01111         if (p)
01112             this->parent_window = p->findWindow(pw);
01113     }
01114     if (!this->parent_window)
01115         this->parent_window = this->rootwindow;
01116 }
01117 
01118 void MMSMenuWidget::setRootWindow(MMSWindow *root, MMSWindow *parentroot) {
01119     MMSWidget::setRootWindow(root, parentroot);
01120     initParentWindow();
01121 }
01122 
01123 
01124 void MMSMenuWidget::switchArrowWidgets() {
01125     // connect arrow widgets
01126     loadArrowWidgets();
01127 
01128     // get columns
01129     unsigned int cols = getCols();
01130 
01131     // arrow support is not needed for menus with fixed selection position
01132     if (getFixedPos() >= 0) {
01133         // select the correct arrows
01134         if (cols > 1) {
01135             // horizontal menu
01136             if (this->da->leftArrowWidget)
01137                 this->da->leftArrowWidget->setSelected(true);
01138             if (this->da->rightArrowWidget)
01139                 this->da->rightArrowWidget->setSelected(true);
01140             if (this->da->upArrowWidget)
01141                 this->da->upArrowWidget->setSelected(false);
01142             if (this->da->downArrowWidget)
01143                 this->da->downArrowWidget->setSelected(false);
01144         }
01145         else {
01146             // vertical menu
01147             if (this->da->leftArrowWidget)
01148                 this->da->leftArrowWidget->setSelected(false);
01149             if (this->da->rightArrowWidget)
01150                 this->da->rightArrowWidget->setSelected(false);
01151             if (this->da->upArrowWidget)
01152                 this->da->upArrowWidget->setSelected(true);
01153             if (this->da->downArrowWidget)
01154                 this->da->downArrowWidget->setSelected(true);
01155         }
01156         return;
01157     }
01158 
01159     // switch arrow widgets
01160     if (this->da->leftArrowWidget) {
01161         if (this->px == 0)
01162             this->da->leftArrowWidget->setSelected(false);
01163         else
01164             this->da->leftArrowWidget->setSelected(true);
01165     }
01166 
01167     if (this->da->upArrowWidget) {
01168         if (this->py == 0)
01169             this->da->upArrowWidget->setSelected(false);
01170         else
01171             this->da->upArrowWidget->setSelected(true);
01172     }
01173 
01174     if (this->da->rightArrowWidget) {
01175         unsigned int columns = cols;
01176         if (columns > children.size())
01177             columns = children.size();
01178         if ((int)(columns - this->px) > this->h_items)
01179             this->da->rightArrowWidget->setSelected(true);
01180         else
01181             this->da->rightArrowWidget->setSelected(false);
01182     }
01183 
01184     if (this->da->downArrowWidget) {
01185         if ((int)(children.size() / cols + ((children.size() % cols)?1:0) - this->py) > this->v_items)
01186             this->da->downArrowWidget->setSelected(true);
01187         else
01188             this->da->downArrowWidget->setSelected(false);
01189     }
01190 }
01191 
01192 void MMSMenuWidget::emitOnReturnForParents(MMSMenuWidget *orw) {
01193     // first all parents recursive on to the stack
01194     if (this->parent_menu)
01195         this->parent_menu->emitOnReturnForParents(orw);
01196     // fire the onReturn event
01197     this->onReturn->emit(orw);
01198 }
01199 
01200 bool MMSMenuWidget::callOnReturn() {
01201 
01202     if (!switchToSubMenu()) {
01203         // call onReturn for all parents
01204         if (this->parent_menu)
01205             this->parent_menu->emitOnReturnForParents(this);
01206 
01207         // close all sub menus
01208         switchBackToParentMenu(MMSDIRECTION_NOTSET, true);
01209 
01210         // return true, so widget will call onReturn for this menu
01211         return true;
01212     }
01213 
01214     // i have switched the menu, so onReturn should not called
01215     return false;
01216 }
01217 
01218 bool MMSMenuWidget::switchToSubMenu() {
01219 
01220     // get access to the submenu struct
01221     unsigned int sel = getSelected();
01222     if (this->back_item == (int)sel) {
01223         // the user has chosen the go-back-item
01224         switchBackToParentMenu();
01225         return true;
01226     }
01227     if (sel>=this->iteminfos.size()) return false;
01228     MMSMENUITEMINFOS *sm = &(this->iteminfos.at(sel));
01229 
01230     // get access to the submenu window
01231     if ((!this->rootwindow)||(sm->name=="")) return false;
01232     if (!sm->window) {
01233         MMSWindow *p = this->parent_window->getParent();
01234         if (!p) return false;
01235         sm->window=p->findWindow(sm->name);
01236     }
01237     if (!sm->window) return false;
01238 
01239     // get access to the menu widget of the submenu window
01240     if (!sm->menu) {
01241         sm->menu = (MMSMenuWidget *)sm->window->findWidgetType(MMSWIDGETTYPE_MENU);
01242         if (!sm->menu) return false;
01243     }
01244 
01245     // switch to the other menu (window)
01246     this->curr_submenu = sel;
01247     sm->menu->parent_menu = this;
01248     sm->menu->setSelected(0);
01249     sm->window->setFocus();
01250     if (memcmp(&this->parent_window->geom, &sm->window->geom, sizeof(sm->window->geom))==0)
01251         // same geom for me and submenu, hide me
01252         this->parent_window->hide();
01253     sm->window->show();
01254     return true;
01255 }
01256 
01257 bool MMSMenuWidget::switchBackToParentMenu(MMSDIRECTION direction, bool closeall) {
01258     // check if we can go back to the parent menu
01259     if (!this->parent_menu) return false;
01260     MMSFBRectangle pgeom = this->parent_menu->parent_window->geom;
01261     MMSFBRectangle mgeom = this->parent_window->geom;
01262     switch (direction) {
01263         case MMSDIRECTION_LEFT:
01264             if (pgeom.x >= mgeom.x) return false;
01265             break;
01266         case MMSDIRECTION_RIGHT:
01267             if (pgeom.x+pgeom.w <= mgeom.x+mgeom.w) return false;
01268             break;
01269         case MMSDIRECTION_UP:
01270             if (pgeom.y >= mgeom.y) return false;
01271             break;
01272         case MMSDIRECTION_DOWN:
01273             if (pgeom.y+pgeom.h <= mgeom.y+mgeom.h) return false;
01274             break;
01275         default:
01276             break;
01277     }
01278 
01279     // okay, switch back
01280     if (this->parent_window->getFocus())
01281         this->parent_menu->parent_window->setFocus();
01282     this->parent_window->hide();
01283     this->parent_menu->parent_window->show();
01284     this->parent_menu->curr_submenu = -1;
01285     MMSMenuWidget *menu = this->parent_menu;
01286     this->parent_menu = NULL;
01287     if (closeall)
01288         menu->switchBackToParentMenu(direction, closeall);
01289     return true;
01290 }
01291 
01292 void MMSMenuWidget::setSliders() {
01293     MMSSliderWidget *s;
01294 
01295     // lock me
01296     lock();
01297 
01298     /* get columns */
01299     unsigned int cols = getCols();
01300 
01301     if(this->da->vSliderWidget && (s = dynamic_cast<MMSSliderWidget*>(this->da->vSliderWidget))) {
01302         unsigned int pos = 0;
01303         int size = (int)children.size() - 1;
01304         if (size > 0)
01305             pos = (this->y * 100) / (size / cols + ((size % cols)?1:0));
01306         s->setPosition(pos);
01307     }
01308 
01309     if ((this->da->hSliderWidget)&&(cols>1) && (s = dynamic_cast<MMSSliderWidget*>(this->da->hSliderWidget))) {
01310         unsigned int pos = 0;
01311         int size = (int)children.size() - 1;
01312         if (size >= (int)cols) size = cols - 1;
01313         if (size > 0)
01314             pos = (this->x * 100) / size;
01315         s->setPosition(pos);
01316     }
01317 
01318     // unlock me
01319     unlock();
01320 }
01321 
01322 void MMSMenuWidget::selectItem(MMSWidget *item, bool set, bool refresh, bool refreshall) {
01323 
01324     if(!item)
01325       return;
01326 
01327     // lock me
01328     lock();
01329 
01330     if (selimage) {
01331         // we have an selection image, so we have to enable refresh for specified item
01332         if (!item->checkRefreshStatus()) {
01333             item->enableRefresh(true);
01334         }
01335     }
01336 
01337     item->setSelected(set, refresh);
01338 
01339     if (refreshall) {
01340         // refresh is required
01341         enableRefresh();
01342 
01343         this->refresh();
01344     }
01345     if (set) {
01346         this->onSelectItem->emit(item);
01347     }
01348 
01349     // unlock me
01350     unlock();
01351 }
01352 
01353 
01354 
01355 
01356 #define MMSMENUWIDGET_GET_SLOOP(sloop) \
01357     { sloop = getSmoothDelay(); \
01358     if (!sloop) { sloop = 5; this->frame_delay = 0; this->frame_delay_set = true; } \
01359     else sloop = getFrameNum(sloop); }
01360 
01361 #define MMSMENUWIDGET_SSLEEP { msleep(this->frame_delay); }
01362 
01363 #define MMSMENUWIDGET_GET_SSTART { if (!this->frame_delay_set) start_ts = getMTimeStamp(); }
01364 
01365 #define MMSMENUWIDGET_GET_SEND \
01366     { if (!this->frame_delay_set) { \
01367     end_ts = getMTimeStamp(); \
01368     this->frame_delay = getFrameDelay(start_ts, end_ts); \
01369     fd_sum+= frame_delay; } }
01370 
01371 #define MMSMENUWIDGET_CALC_DELAY \
01372     { if (!this->frame_delay_set) { \
01373     this->frame_delay = fd_sum / (sloop - 1); \
01374     this->frame_delay_set = true; } }
01375 
01376 
01377 
01378 bool MMSMenuWidget::onBeforeAnimation(MMSPulser *pulser) {
01379     //unlock mmsfb as it is not necessary before the first frame draw
01380     mmsfb->unlock();
01381 
01382     // init animation
01383     switch (this->pulser_mode) {
01384     case MMSMENUWIDGET_PULSER_MODE_SCROLL_DOWN:
01385     case MMSMENUWIDGET_PULSER_MODE_SCROLL_UP:
01386         this->scrolling_offset = 0;
01387         this->anim_factor = getItemVMargin() * 2 + this->item_h;
01388         break;
01389     case MMSMENUWIDGET_PULSER_MODE_SCROLL_LEFT:
01390     case MMSMENUWIDGET_PULSER_MODE_SCROLL_RIGHT:
01391         this->scrolling_offset = 0;
01392         this->anim_factor = getItemHMargin() * 2 + this->item_w;
01393         break;
01394     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_DOWN:
01395     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_UP:
01396         this->selection_offset_x = 0;
01397         this->selection_offset_y = 0;
01398         this->anim_factor = getItemVMargin() * 2 + this->item_h;
01399         break;
01400     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_LEFT:
01401     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_RIGHT:
01402         this->selection_offset_x = 0;
01403         this->selection_offset_y = 0;
01404         this->anim_factor = getItemHMargin() * 2 + this->item_w;
01405         break;
01406     }
01407 
01408     return true;
01409 }
01410 
01411 bool MMSMenuWidget::onAnimation(MMSPulser *pulser) {
01412     // next offset
01413     switch (this->pulser_mode) {
01414     case MMSMENUWIDGET_PULSER_MODE_SCROLL_DOWN:
01415     case MMSMENUWIDGET_PULSER_MODE_SCROLL_RIGHT:
01416         this->scrolling_offset = this->anim_offset - (int)(((this->anim_factor * pulser->getOffset()) / MMSMENUWIDGET_ANIM_MAX_OFFSET) + 0.5);
01417         break;
01418     case MMSMENUWIDGET_PULSER_MODE_SCROLL_UP:
01419     case MMSMENUWIDGET_PULSER_MODE_SCROLL_LEFT:
01420         this->scrolling_offset = this->anim_offset + (int)(((this->anim_factor * pulser->getOffset()) / MMSMENUWIDGET_ANIM_MAX_OFFSET) + 0.5);
01421         break;
01422     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_DOWN:
01423         this->selection_offset_y = this->anim_offset + (int)(((this->anim_factor * pulser->getOffset()) / MMSMENUWIDGET_ANIM_MAX_OFFSET) + 0.5);
01424         this->selection_offset_y*= this->anim_jumpover + 1;
01425         break;
01426     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_UP:
01427         this->selection_offset_y = this->anim_offset - (int)(((this->anim_factor * pulser->getOffset()) / MMSMENUWIDGET_ANIM_MAX_OFFSET) + 0.5);
01428         this->selection_offset_y*= this->anim_jumpover + 1;
01429         break;
01430     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_LEFT:
01431         this->selection_offset_x = this->anim_offset - (int)(((this->anim_factor * pulser->getOffset()) / MMSMENUWIDGET_ANIM_MAX_OFFSET) + 0.5);
01432         this->selection_offset_x*= this->anim_jumpover + 1;
01433         break;
01434     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_RIGHT:
01435         this->selection_offset_x = this->anim_offset + (int)(((this->anim_factor * pulser->getOffset()) / MMSMENUWIDGET_ANIM_MAX_OFFSET) + 0.5);
01436         this->selection_offset_x*= this->anim_jumpover + 1;
01437         break;
01438     }
01439 
01440     // lock mmsfb to ensure single thread access to mmsgui
01441     mmsfb->lock();
01442 
01443     // refresh is required
01444     enableRefresh();
01445 
01446     // update screen
01447     this->refresh();
01448 
01449     // unlock mmsfb to enable other threads to
01450     // update the screen between frames
01451     mmsfb->unlock();
01452     return true;
01453 }
01454 
01455 void MMSMenuWidget::onAfterAnimation(MMSPulser *pulser) {
01456 
01457     // reset at the end of the animation
01458     switch (this->pulser_mode) {
01459     case MMSMENUWIDGET_PULSER_MODE_SCROLL_DOWN:
01460     case MMSMENUWIDGET_PULSER_MODE_SCROLL_UP:
01461     case MMSMENUWIDGET_PULSER_MODE_SCROLL_LEFT:
01462     case MMSMENUWIDGET_PULSER_MODE_SCROLL_RIGHT:
01463         this->scrolling_offset = 0;
01464         break;
01465     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_DOWN:
01466     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_UP:
01467     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_LEFT:
01468     case MMSMENUWIDGET_PULSER_MODE_MOVESEL_RIGHT:
01469         this->selection_offset_x = 0;
01470         this->selection_offset_y = 0;
01471         break;
01472     }
01473 
01474     //relock mmsfb because the last frame unlocked mmsfb
01475     mmsfb->lock();
01476     return;
01477 }
01478 
01479 
01480 void MMSMenuWidget::startAnimation(MMSMENUWIDGET_PULSER_MODE pulser_mode, double anim_offset, int anim_jumpover) {
01481 
01482     MMSSEQUENCEMODE seq_mode;
01483 
01484     // get source sequence mode
01485     switch (pulser_mode) {
01486     case MMSMENUWIDGET_PULSER_MODE_SCROLL_DOWN:
01487     case MMSMENUWIDGET_PULSER_MODE_SCROLL_UP:
01488     case MMSMENUWIDGET_PULSER_MODE_SCROLL_LEFT:
01489     case MMSMENUWIDGET_PULSER_MODE_SCROLL_RIGHT:
01490         // smooth scrolling mode
01491         seq_mode = this->smooth_scrolling;
01492         break;
01493     default:
01494         // smooth selection mode
01495         seq_mode = this->smooth_selection;
01496         break;
01497     }
01498 
01499     // save offset and jump over cnt
01500     this->anim_offset = anim_offset;
01501     this->anim_jumpover = anim_jumpover;
01502 
01503     // init pulser and start it
01504     this->pulser.setStepsPerSecond(MMSMENUWIDGET_ANIM_STEPS_PER_SECOND);
01505     switch (seq_mode) {
01506     case MMSSEQUENCEMODE_LOG:
01507         this->pulser.setMaxOffset(MMSMENUWIDGET_ANIM_MAX_OFFSET, MMSPULSER_SEQ_LOG_SOFT_START_AND_END);
01508         break;
01509     case MMSSEQUENCEMODE_LOG_SOFT_START:
01510         this->pulser.setMaxOffset(MMSMENUWIDGET_ANIM_MAX_OFFSET, MMSPULSER_SEQ_LOG_SOFT_START);
01511         break;
01512     case MMSSEQUENCEMODE_LOG_SOFT_END:
01513         this->pulser.setMaxOffset(MMSMENUWIDGET_ANIM_MAX_OFFSET, MMSPULSER_SEQ_LOG_SOFT_END);
01514         break;
01515     default:
01516         this->pulser.setMaxOffset(MMSMENUWIDGET_ANIM_MAX_OFFSET, MMSPULSER_SEQ_LINEAR);
01517         break;
01518     }
01519     this->pulser_mode = pulser_mode;
01520     this->pulser.start(false);
01521 }
01522 
01523 
01524 
01525 bool MMSMenuWidget::scrollDownEx(unsigned int count, bool refresh, bool test, bool leave_selection) {
01526     bool pyChanged = false;
01527     int oldx=0;
01528     int oldy;
01529     unsigned int cols;
01530     int fixedpos;
01531 
01532     // check something
01533     if (count==0 || children.empty()) {
01534         return false;
01535     }
01536 
01537     // get settings
01538     cols = getCols();
01539     fixedpos = getFixedPos();
01540 
01541     // test for deactivated items
01542     while((this->x + (this->y + count) * cols) < children.size()) {
01543         if(children.at(this->x + (this->y + count) * cols)->isActivated()) break;
01544         count++;
01545     }
01546 
01547     // normal menu or fixed selection?
01548     if (fixedpos < 0) {
01549         // normal menu
01550         if (!leave_selection) {
01551             // we have to change the selected menu item!!!
01552             if (this->x + (this->y + count) * cols >= children.size()) {
01553                 if (this->x == 0) {
01554                     // really nothing to scroll?
01555                     if (getVLoop()) {
01556                         // I should not give up the focus
01557                         if (this->y) {
01558                             return scrollUpEx(this->y, refresh, test, leave_selection);
01559                         }
01560                         return true;
01561                     }
01562 
01563                     return false;
01564                 }
01565 
01566                 for (int i = (int)this->x - 1; i >= 0; i--)
01567                     if (i + (this->y + count) * cols < children.size()) {
01568                         // save old and set new x selection
01569                         oldx = this->x;
01570                         if (!test)
01571                             this->x = i;
01572                         break;
01573                     }
01574 
01575                 if (!oldx) {
01576                     // really nothing to scroll?
01577                     if (getVLoop()) {
01578                         // I should not give up the focus
01579                         if (this->y) {
01580                             return scrollUpEx(this->y, refresh, test, leave_selection);
01581                         }
01582                         return true;
01583                     }
01584 
01585                     return false;
01586                 }
01587             }
01588 
01589             // in test mode we can say that we can scroll
01590             if (test) {
01591                 return true;
01592             }
01593 
01594             // callback
01595             this->onBeforeScroll->emit(this);
01596 
01597             // save old and set new y selection
01598             oldy = this->y;
01599             this->y+=count;
01600 
01601             // recalculate scroll position
01602             int ypy = this->y - this->py;
01603             if (ypy >= this->v_items) {
01604                 this->py = this->y - this->v_items + 1;
01605                 pyChanged = true;
01606             }
01607             else
01608             if (ypy < 0) {
01609                 this->py = this->y;
01610                 pyChanged = true;
01611             }
01612             if (oldx) {
01613                 if (this->x < this->px) {
01614                     this->px = this->x;
01615                     pyChanged = true;
01616                 }
01617             }
01618 
01619             // get access to widgets
01620             unsigned int olditem_index = ((oldx)?oldx:this->x) + oldy * cols;
01621             unsigned int item_index = this->x + this->y * cols;
01622             MMSWidget *olditem = (olditem_index < children.size()) ? children.at(olditem_index) : NULL;
01623             MMSWidget *item    = (item_index    < children.size()) ? children.at(item_index)    : NULL;
01624 
01625             if (!pyChanged) {
01626                 // not scrolled, switch focus between visible children
01627                 selectItem(olditem, false, true);
01628 
01629                 if ((selimage)&&(this->smooth_selection)&&(refresh)&&(oldy < this->y)) {
01630                     // do the animation
01631                     // input: animation mode, animation offset, number of menu items to jump over
01632                     startAnimation(MMSMENUWIDGET_PULSER_MODE_MOVESEL_DOWN,
01633                                             -(double)(getItemVMargin() * 2 + this->item_h),
01634                                             count - 1);
01635                 }
01636 
01637                 // switch on new selection
01638                 selectItem(item, true, refresh);
01639             }
01640             else {
01641                 // scrolled, switch focus needs recalculate children
01642                 selectItem(olditem, false, false);
01643 
01644                 if ((this->smooth_scrolling)&&(refresh)&&(oldy < this->y)) {
01645                     // do the animation
01646                     // input: animation mode, animation offset, number of menu items to jump over
01647                     startAnimation(MMSMENUWIDGET_PULSER_MODE_SCROLL_DOWN,
01648                                             (double)(getItemVMargin() * 2 + this->item_h),
01649                                             count - 1);
01650                 }
01651 
01652                 if (refresh)
01653                     recalculateChildren();
01654 
01655                 selectItem(item, true, false, refresh);
01656             }
01657         }
01658         else {
01659             // we have to leave the selected menu item asis!!!
01660             if (this->x + (this->py + this->v_items + count - 1) * cols >= children.size()) {
01661                 return false;
01662             }
01663 
01664             // in test mode we can say that we can scroll
01665             if (test) {
01666                 return true;
01667             }
01668 
01669             // recalculate scroll position
01670             this->py++;
01671 
01672             // refresh is required
01673             enableRefresh();
01674 
01675             if (refresh) {
01676                 recalculateChildren();
01677                 this->refresh();
01678             }
01679         }
01680 
01681         // set the sliders
01682         setSliders();
01683 
01684         return true;
01685     }
01686     else {
01687         // menu with fixed selection
01688         if (cols == 1) {
01689             // in test mode we can say that we can scroll
01690             if (test) {
01691                 return true;
01692             }
01693 
01694             // callback
01695             this->onBeforeScroll->emit(this);
01696 
01697             // correct menu with one column
01698             count%=children.size();
01699 
01700             // save old and set new y selection
01701             oldy = this->y;
01702             this->y+=count;
01703 
01704             if (this->y >= (int)children.size()) {
01705                 // go back to begin of the list (round robin)
01706                 this->y = this->y - children.size();
01707             }
01708 
01709             // recalculate scroll position
01710             this->py = this->y;
01711 
01712             // get access to widgets
01713             MMSWidget *olditem = (oldy    < (int)children.size()) ? children.at(oldy)    : NULL;
01714             MMSWidget *item    = (this->y < (int)children.size()) ? children.at(this->y) : NULL;
01715 
01716             // switch focus and recalculate children
01717             selectItem(olditem, false, false);
01718 
01719             if (refresh)
01720                 recalculateChildren();
01721 
01722             selectItem(item, true, false, refresh);
01723 
01724             // set the sliders
01725             setSliders();
01726 
01727             return true;
01728         }
01729         else {
01730             // menu with more than one column cannot be scrolled down in fixed selection mode
01731             return false;
01732         }
01733     }
01734 }
01735 
01736 bool MMSMenuWidget::scrollUpEx(unsigned int count, bool refresh, bool test, bool leave_selection) {
01737     bool pyChanged = false;
01738     int oldy;
01739     unsigned int cols;
01740     int fixedpos;
01741 
01742     // check something
01743     if (count==0 || children.empty()) {
01744         return false;
01745     }
01746 
01747     // get settings
01748     cols = getCols();
01749     fixedpos = getFixedPos();
01750 
01751     // test for deactivated items
01752     while(int(this->x + (this->y - count) * cols) > 0) {
01753         if(children.at(this->x + (this->y - count) * cols)->isActivated()) break;
01754         count++;
01755     }
01756 
01757     // normal menu or fixed selection?
01758     if (fixedpos < 0) {
01759         // normal menu
01760         if (!leave_selection) {
01761             // we have to change the selected menu item!!!
01762             if (this->y < (int)count) {
01763                 // really nothing to scroll?
01764                 if (getVLoop()) {
01765                     // I should not give up the focus
01766                     unsigned int lines = this->children.size() /* / cols */;
01767                     // if (this->children.size() % cols > 0) lines++;
01768                     if ((int)lines - (int)this->y > 1) {
01769                         return scrollDownEx(lines - this->y - 1, refresh, test, leave_selection);
01770                     }
01771                     return true;
01772                 }
01773 
01774                 return false;
01775             }
01776 
01777             // in test mode we can say that we can scroll
01778             if (test) {
01779                 return true;
01780             }
01781 
01782             // callback
01783             this->onBeforeScroll->emit(this);
01784 
01785             // save old and set new y selection
01786             oldy = this->y;
01787             this->y-=count;
01788 
01789             // recalculate scroll position
01790             int ypy = this->y - this->py;
01791             if (ypy < 0) {
01792                 this->py = this->y;
01793                 pyChanged = true;
01794             }
01795             else
01796             if (ypy >= this->v_items) {
01797                 this->py = this->y - this->v_items + 1;
01798                 pyChanged = true;
01799             }
01800 
01801             // get access to widgets
01802             unsigned int olditem_index = this->x + oldy * cols;
01803             unsigned int item_index = this->x + this->y * cols;
01804             MMSWidget *olditem = (olditem_index < children.size()) ? children.at(olditem_index) : NULL;
01805             MMSWidget *item    = (item_index    < children.size()) ? children.at(item_index)    : NULL;
01806 
01807             if (!pyChanged) {
01808                 // not scrolled, switch focus between visible children
01809                 selectItem(olditem, false, true);
01810 
01811                 // selection animation?
01812                 if ((selimage)&&(this->smooth_selection)&&(refresh)&&(oldy > this->y)) {
01813                     // do the animation
01814                     // input: animation mode, animation offset, number of menu items to jump over
01815                     startAnimation(MMSMENUWIDGET_PULSER_MODE_MOVESEL_UP,
01816                                             getItemVMargin() * 2 + this->item_h,
01817                                             count - 1);
01818                 }
01819 
01820                 // switch on new selection
01821                 selectItem(item, true, refresh);
01822             }
01823             else {
01824                 // scrolled, switch focus needs recalculate children
01825                 selectItem(olditem, false, false);
01826 
01827                 if ((this->smooth_scrolling)&&(refresh)&&(oldy > this->y)) {
01828                     // do the animation
01829                     // input: animation mode, animation offset, number of menu items to jump over
01830                     startAnimation(MMSMENUWIDGET_PULSER_MODE_SCROLL_UP,
01831                                             -(double)(getItemVMargin() * 2 + this->item_h),
01832                                             count - 1);
01833                 }
01834 
01835                 if (refresh)
01836                     recalculateChildren();
01837 
01838                 selectItem(item, true, false, refresh);
01839             }
01840         }
01841         else {
01842             // we have to leave the selected menu item asis!!!
01843             if (this->py < (int)count) {
01844                 return false;
01845             }
01846 
01847             // in test mode we can say that we can scroll
01848             if (test) {
01849                 return true;
01850             }
01851 
01852             // recalculate scroll position
01853             this->py--;
01854 
01855             // refresh is required
01856             enableRefresh();
01857 
01858             if (refresh) {
01859                 recalculateChildren();
01860                 this->refresh();
01861             }
01862         }
01863 
01864         // set the sliders
01865         setSliders();
01866 
01867         return true;
01868     }
01869     else {
01870         // menu with fixed selection
01871         if (cols == 1) {
01872             // in test mode we can say that we can scroll
01873             if (test) {
01874                 return true;
01875             }
01876 
01877             // callback
01878             this->onBeforeScroll->emit(this);
01879 
01880             // correct menu with one column
01881             count%=children.size();
01882 
01883             // save old and set new y selection
01884             oldy = this->y;
01885             this->y-=count;
01886 
01887             if ((int)this->y < 0) {
01888                 // go back to end of the list (round robin)
01889                 this->y = children.size() + (int)this->y;
01890             }
01891 
01892             // recalculate scroll position
01893             this->py = this->y;
01894 
01895             // get access to widgets
01896             MMSWidget *olditem = (oldy    < (int)children.size()) ? children.at(oldy)    : NULL;
01897             MMSWidget *item    = (this->y < (int)children.size()) ? children.at(this->y) : NULL;
01898 
01899             // switch focus and recalculate children
01900             selectItem(olditem, false, false);
01901 
01902             if (refresh)
01903                 recalculateChildren();
01904 
01905             selectItem(item, true, false, refresh);
01906 
01907             // set the sliders
01908             setSliders();
01909 
01910             return true;
01911         }
01912         else {
01913             // menu with more than one column cannot be scrolled up in fixed selection mode
01914             return false;
01915         }
01916     }
01917 }
01918 
01919 
01920 bool MMSMenuWidget::scrollRightEx(unsigned int count, bool refresh, bool test, bool leave_selection) {
01921     bool pxChanged = false;
01922     int oldx;
01923     int oldy=0;
01924     unsigned int cols;
01925     int fixedpos;
01926 
01927     // check something
01928     if (count==0 || children.empty()) {
01929         return false;
01930     }
01931 
01932     // get settings
01933     cols = getCols();
01934     fixedpos = getFixedPos();
01935 
01936     // normal menu or fixed selection?
01937     if (fixedpos < 0) {
01938         // normal menu
01939         if (!leave_selection) {
01940             // we have to change the selected menu item!!!
01941             if (this->x + count + this->y * cols >= children.size()) {
01942                 if ((this->x + count >= cols) || (this->y == 0)) {
01943                     // really nothing to scroll?
01944                     if (getHLoop()) {
01945                         // I should not give up the focus
01946                         if (this->x) {
01947                             if (children.size() <= cols) {
01948                                 return scrollLeftEx(this->x, refresh, test, leave_selection);
01949                             }
01950                             else {
01951                                 if (!scrollLeftEx(this->x, false, test, leave_selection)) {
01952                                     return false;
01953                                 }
01954                                 return scrollUpEx(1, refresh, test, leave_selection);
01955                             }
01956                         }
01957                         else {
01958                             return true;
01959                         }
01960                     }
01961 
01962                     return false;
01963                 }
01964 
01965                 for (int i = (int)this->y - 1; i >= 0; i--)
01966                     if (this->x + count + i * cols < children.size()) {
01967                         oldy = this->y;
01968                         if (!test)
01969                             this->y = i;
01970                         break;
01971                     }
01972 
01973                 if (!oldy) {
01974                     // really nothing to scroll?
01975                     if (getHLoop()) {
01976                         // I should not give up the focus
01977                         if (this->x) {
01978                             return scrollLeftEx(this->x, refresh, test, leave_selection);
01979                         }
01980                         return true;
01981                     }
01982 
01983                     return false;
01984                 }
01985             }
01986             else
01987             if (this->x + count >= cols) {
01988                 // really nothing to scroll?
01989                 if (getHLoop()) {
01990                     // I should not give up the focus
01991                     if (this->x) {
01992                         if (children.size() <= cols) {
01993                             return scrollLeftEx(this->x, refresh, test, leave_selection);
01994                         }
01995                         else {
01996                             if (!scrollLeftEx(this->x, false, test, leave_selection)) {
01997                                 return false;
01998                             }
01999                             return scrollDownEx(1, refresh, test, leave_selection);
02000                         }
02001                     }
02002                     else {
02003                         return true;
02004                     }
02005                 }
02006 
02007                 return false;
02008             }
02009 
02010             // in test mode we can say that we can scroll
02011             if (test) {
02012                 return true;
02013             }
02014 
02015             // callback
02016             this->onBeforeScroll->emit(this);
02017 
02018             // save old and set new x selection
02019             oldx = this->x;
02020             this->x+=count;
02021 
02022             // recalculate scroll position
02023             int xpx = this->x - this->px;
02024             if (xpx >= this->h_items) {
02025                 this->px = this->x - this->h_items + 1;
02026                 pxChanged = true;
02027             }
02028             else
02029             if (xpx < 0) {
02030                 this->px = this->x;
02031                 pxChanged = true;
02032             }
02033             if (oldy) {
02034                 if (this->y < this->py) {
02035                     this->py = this->y;
02036                     pxChanged = true;
02037                 }
02038             }
02039 
02040             // get access to widgets
02041             unsigned int olditem_index = oldx + ((oldy)?oldy:this->y) * cols;
02042             unsigned int item_index = this->x + this->y * cols;
02043             MMSWidget *olditem = (olditem_index < children.size()) ? children.at(olditem_index) : NULL;
02044             MMSWidget *item    = (item_index    < children.size()) ? children.at(item_index)    : NULL;
02045 
02046             if (!pxChanged) {
02047                 // not scrolled, switch focus between visible children
02048                 selectItem(olditem, false, true);
02049 
02050                 if ((selimage)&&(this->smooth_selection)&&(refresh)&&(oldx < this->x)) {
02051                     // do the animation
02052                     // input: animation mode, animation offset, number of menu items to jump over
02053                     startAnimation(MMSMENUWIDGET_PULSER_MODE_MOVESEL_RIGHT,
02054                                             -(double)(getItemHMargin() * 2 + this->item_w),
02055                                             count - 1);
02056                 }
02057 
02058                 // switch on new selection
02059                 selectItem(item, true, refresh);
02060             }
02061             else {
02062                 // scrolled, switch focus needs recalculate children
02063                 selectItem(olditem, false, false);
02064 
02065                 if ((this->smooth_scrolling)&&(refresh)&&(oldx < this->x)) {
02066                     // do the animation
02067                     // input: animation mode, animation offset, number of menu items to jump over
02068                     startAnimation(MMSMENUWIDGET_PULSER_MODE_SCROLL_RIGHT,
02069                                             getItemHMargin() * 2 + this->item_w,
02070                                             count - 1);
02071                 }
02072 
02073                 if (refresh)
02074                     recalculateChildren();
02075 
02076                 selectItem(item, true, false, refresh);
02077             }
02078         }
02079         else {
02080             // we have to leave the selected menu item asis!!!
02081             if (this->px + this->h_items + count - 1 >= ((cols<=children.size())?cols:children.size())) {
02082                 return false;
02083             }
02084 
02085             // in test mode we can say that we can scroll
02086             if (test) {
02087                 return true;
02088             }
02089 
02090             // recalculate scroll position
02091             this->px++;
02092 
02093             // refresh is required
02094             enableRefresh();
02095 
02096             if (refresh) {
02097                 recalculateChildren();
02098                 this->refresh();
02099             }
02100         }
02101 
02102         // set the sliders
02103         setSliders();
02104 
02105         return true;
02106     }
02107     else {
02108         // menu with fixed selection
02109         if (cols > 1) {
02110             // in test mode we can say that we can scroll
02111             if (test) {
02112                 return true;
02113             }
02114 
02115             // callback
02116             this->onBeforeScroll->emit(this);
02117 
02118             if ((this->smooth_scrolling)&&(refresh)) {
02119                 // do the animation
02120                 // input: animation mode, animation offset, number of menu items to jump over
02121                 startAnimation(MMSMENUWIDGET_PULSER_MODE_SCROLL_RIGHT, 0, count - 1);
02122             }
02123 
02124             // correct menu with more than one column
02125             count%=cols;
02126 
02127             // save old and set new x selection
02128             oldx = this->x;
02129             this->x+=count;
02130 
02131             if (this->x >= (int)cols) {
02132                 // go back to begin of the first row (round robin)
02133                 this->x = this->x - cols;
02134             }
02135 
02136             if (this->x >= (int)children.size()) {
02137                 // go back to begin of the list (round robin)
02138                 this->x = this->x - children.size();
02139             }
02140 
02141             // recalculate scroll position
02142             this->px = this->x;
02143 
02144             // get access to widgets
02145             MMSWidget *olditem = (oldx    < (int)children.size()) ? children.at(oldx)    : NULL;
02146             MMSWidget *item    = (this->x < (int)children.size()) ? children.at(this->x) : NULL;
02147 
02148             if ((smooth_scrolling)&&(refresh)) {
02149                 // reset the blend value
02150                 olditem->setBlend(0, false);
02151                 item->setBlend(0, false);
02152             }
02153 
02154             // switch focus and recalculate children
02155             selectItem(olditem, false, false);
02156 
02157             if (refresh)
02158                 recalculateChildren();
02159 
02160             selectItem(item, true, false, refresh);
02161 
02162             // set the sliders
02163             setSliders();
02164 
02165             return true;
02166         }
02167         else {
02168             // menu with only one column cannot be scrolled right in fixed selection mode
02169             return false;
02170         }
02171     }
02172 }
02173 
02174 bool MMSMenuWidget::scrollLeftEx(unsigned int count, bool refresh, bool test, bool leave_selection) {
02175     bool pxChanged = false;
02176     int oldx;
02177     unsigned int cols;
02178     int fixedpos;
02179 
02180     // check something
02181     if (count==0 || children.empty()) {
02182         return false;
02183     }
02184 
02185     // get settings
02186     cols = getCols();
02187     fixedpos = getFixedPos();
02188 
02189     // normal menu or fixed selection?
02190     if (fixedpos < 0) {
02191         // normal menu
02192         if (!leave_selection) {
02193             if (this->x < (int)count) {
02194                 // really nothing to scroll?
02195                 if (getHLoop()) {
02196                     // I should not give up the focus
02197                     unsigned int columns;
02198                     if (cols < this->children.size())
02199                         columns = cols;
02200                     else
02201                         columns = this->children.size();
02202                     if ((int)columns - (int)this->x > 1) {
02203                         if (children.size() <= cols) {
02204                             return scrollRightEx(columns - this->x - 1, refresh, test, leave_selection);
02205                         }
02206                         else {
02207                             if (!scrollRightEx(columns - this->x - 1, false, test, leave_selection)) {
02208                                 return false;
02209                             }
02210                             if (this->y > 0) {
02211                                 return scrollUpEx(1, refresh, test, leave_selection);
02212                             }
02213                             else {
02214                                 return scrollDownEx((children.size() - cols) / cols, refresh, test, leave_selection);
02215                             }
02216                         }
02217                     }
02218                     else {
02219                         return true;
02220                     }
02221                 }
02222 
02223                 return false;
02224             }
02225 
02226             // in test mode we can say that we can scroll
02227             if (test) {
02228                 return true;
02229             }
02230 
02231             // callback
02232             this->onBeforeScroll->emit(this);
02233 
02234             // save old and set new x selection
02235             oldx = this->x;
02236             this->x-=count;
02237 
02238             // recalculate scroll position
02239             int xpx = this->x - this->px;
02240             if (xpx < 0) {
02241                 this->px = this->x;
02242                 pxChanged = true;
02243             }
02244             else
02245             if (xpx >= this->h_items) {
02246                 this->px = this->x - this->h_items + 1;
02247                 pxChanged = true;
02248             }
02249 
02250             // get access to widgets
02251             unsigned int olditem_index = oldx + this->y * cols;
02252             unsigned int item_index = this->x + this->y * cols;
02253             MMSWidget *olditem = (olditem_index < children.size()) ? children.at(olditem_index) : NULL;
02254             MMSWidget *item    = (item_index    < children.size()) ? children.at(item_index)    : NULL;
02255 
02256             if (!pxChanged) {
02257                 // not scrolled, switch focus between visible children
02258                 selectItem(olditem, false, true);
02259 
02260                 if ((selimage)&&(this->smooth_selection)&&(refresh)&&(oldx > this->x)) {
02261                     // do the animation
02262                     // input: animation mode, animation offset, number of menu items to jump over
02263                     startAnimation(MMSMENUWIDGET_PULSER_MODE_MOVESEL_LEFT,
02264                                             getItemHMargin() * 2 + this->item_w,
02265                                             count - 1);
02266                 }
02267 
02268                 // switch on new selection
02269                 selectItem(item, true, refresh);
02270             }
02271             else {
02272                 // scrolled, switch focus needs recalculate children
02273                 selectItem(olditem, false, false);
02274 
02275                 if ((this->smooth_scrolling)&&(refresh)&&(oldx > this->x)) {
02276                     // do the animation
02277                     // input: animation mode, animation offset, number of menu items to jump over
02278                     startAnimation(MMSMENUWIDGET_PULSER_MODE_SCROLL_LEFT,
02279                                             -(double)(getItemHMargin() * 2 + this->item_w),
02280                                             count - 1);
02281                 }
02282 
02283                 if (refresh)
02284                     recalculateChildren();
02285 
02286                 selectItem(item, true, false, refresh);
02287             }
02288         }
02289         else {
02290             // we have to leave the selected menu item asis!!!
02291             if (this->px < (int)count) {
02292                 return false;
02293             }
02294 
02295             // in test mode we can say that we can scroll
02296             if (test) {
02297                 return true;
02298             }
02299 
02300             // recalculate scroll position
02301             this->px--;
02302 
02303             // refresh is required
02304             enableRefresh();
02305 
02306             if (refresh) {
02307                 recalculateChildren();
02308                 this->refresh();
02309             }
02310         }
02311 
02312         // set the sliders
02313         setSliders();
02314 
02315         return true;
02316     }
02317     else {
02318         // menu with fixed selection
02319         if (cols > 1) {
02320             // in test mode we can say that we can scroll
02321             if (test) {
02322                 return true;
02323             }
02324 
02325             // callback
02326             this->onBeforeScroll->emit(this);
02327 
02328             if ((this->smooth_scrolling)&&(refresh)) {
02329                 // do the animation
02330                 // input: animation mode, animation offset, number of menu items to jump over
02331                 startAnimation(MMSMENUWIDGET_PULSER_MODE_SCROLL_LEFT, 0, count - 1);
02332             }
02333 
02334 
02335             // correct menu with more than one column
02336             count%=cols;
02337 
02338             // save old and set new x selection
02339             oldx = this->x;
02340             this->x-=count;
02341 
02342             if ((int)this->x < 0) {
02343                 // go back to end of the first row (round robin)
02344                 this->x = (int)cols + (int)this->x;
02345 
02346                 if (this->x >= (int)children.size()) {
02347                     // go back to begin of the list (round robin)
02348                     this->x = children.size() - (cols - this->x);
02349                 }
02350             }
02351 
02352             // recalculate scroll position
02353             this->px = this->x;
02354 
02355             // get access to widgets
02356             MMSWidget *olditem = (oldx    < (int)children.size()) ? children.at(oldx)    : NULL;
02357             MMSWidget *item    = (this->x < (int)children.size()) ? children.at(this->x) : NULL;
02358 
02359             if ((smooth_scrolling)&&(refresh)) {
02360                 /* reset the blend value */
02361                 olditem->setBlend(0, false);
02362                 item->setBlend(0, false);
02363             }
02364 
02365             // switch focus and recalculate children
02366             selectItem(olditem, false, false);
02367 
02368             if (refresh)
02369                 recalculateChildren();
02370 
02371             selectItem(item, true, false, refresh);
02372 
02373             // set the sliders
02374             setSliders();
02375 
02376             return true;
02377         }
02378         else {
02379             // menu with only one column cannot be scrolled right in fixed selection mode
02380             return false;
02381         }
02382     }
02383 }
02384 
02385 bool MMSMenuWidget::scrollDown(unsigned int count, bool refresh, bool test, bool leave_selection) {
02386 
02387     if (this->children.size()==0)
02388         return false;
02389 
02390     if ((!test)&&(smooth_scrolling)&&(refresh)) {
02391         int fixedpos = getFixedPos();
02392         if (fixedpos >= 0) {
02393             if (getCols() == 1) {
02394                 /* this is a vertical menu and we have to check which is the shortest way - up or down scrolling */
02395                 /* it's important to know because of smooth scrolling */
02396                 count = count % this->children.size();
02397                 if (fixedpos >= this->v_items)
02398                     fixedpos = (this->v_items - 1) / 2;
02399 
02400                 if (count > (this->children.size() / 2) - (fixedpos - ((this->v_items - 1) / 2))) {
02401                     count = this->v_items-count;
02402                     while (count--)
02403                         scrollUpEx(1, refresh, test, leave_selection);
02404                     return true;
02405                 }
02406 
02407                 while (count--)
02408                     scrollDownEx(1, refresh, test, leave_selection);
02409                 return true;
02410             }
02411         }
02412     }
02413 
02414 ////
02415 /*  if (!test) {
02416     static int iii=0;
02417     bool jjj=false;
02418     if (iii<1) {
02419     printf("start:%d\n", time(NULL));
02420     iii++;
02421     jjj=true;
02422     }
02423     if (this->name=="loc_menu") {
02424         int gggg=0;
02425         while (gggg++<20) {
02426             int ggggg = 0;
02427             while (ggggg++<15)
02428                 scrollDownEx(1, true, false, false);
02429             while (ggggg-->0)
02430                 scrollUpEx(1, true, false, false);
02431         }
02432     }
02433     if (jjj) {
02434     printf("end:%d\n", time(NULL));
02435     }
02436     }*/
02437 ////
02438 
02439 
02440     bool ret = scrollDownEx(count, refresh, test, leave_selection);
02441 
02442     if ((!ret)&&(!test))
02443         // nothing to scroll
02444         if (this->parent_menu) {
02445             // if we have a parent menu, we do only leave this menu if we switch back to the parent
02446             switchBackToParentMenu(MMSDIRECTION_DOWN);
02447             return true;
02448         }
02449 
02450     return ret;
02451 }
02452 
02453 bool MMSMenuWidget::scrollUp(unsigned int count, bool refresh, bool test, bool leave_selection) {
02454 
02455     if (this->children.size()==0)
02456         return false;
02457 
02458     if ((!test)&&(smooth_scrolling)&&(refresh)) {
02459         int fixedpos = getFixedPos();
02460         if (fixedpos >= 0) {
02461             if (getCols() == 1) {
02462                 /* this is a vertical menu and we have to check which is the shortest way - up or down scrolling */
02463                 /* it's important to know because of smooth scrolling */
02464                 count = count % this->children.size();
02465                 if (fixedpos >= this->v_items)
02466                     fixedpos = (this->v_items - 1) / 2;
02467 
02468                 if (count > (this->children.size() / 2) - (fixedpos - ((this->v_items - 1) / 2))) {
02469                     count = this->v_items-count;
02470                     while (count--)
02471                         scrollDownEx(1, refresh, test, leave_selection);
02472                     return true;
02473                 }
02474 
02475                 while (count--)
02476                     scrollUpEx(1, refresh, test, leave_selection);
02477                 return true;
02478             }
02479         }
02480     }
02481 
02482     bool ret = scrollUpEx(count, refresh, test, leave_selection);
02483 
02484     if ((!ret)&&(!test))
02485         // nothing to scroll
02486         if (this->parent_menu) {
02487             // if we have a parent menu, we do only leave this menu if we switch back to the parent
02488             switchBackToParentMenu(MMSDIRECTION_UP);
02489             return true;
02490         }
02491 
02492     return ret;
02493 }
02494 
02495 bool MMSMenuWidget::scrollRight(unsigned int count, bool refresh, bool test, bool leave_selection) {
02496 
02497     if (this->children.size()==0)
02498         return false;
02499 
02500     ////
02501 /*      if (!test) {
02502         static int iiii=0;
02503         bool jjj=false;
02504         if (iiii<1) {
02505         printf("startX:%d\n", time(NULL));
02506         iiii++;
02507         jjj=true;
02508         }
02509         if (this->name=="switcher_menu") {
02510             int gggg=0;
02511             while (gggg++<1000) {
02512                 scrollRightEx(1, true, false, false);
02513             }
02514         }
02515         if (jjj) {
02516         printf("endX:%d\n", time(NULL));
02517         }
02518         }*/
02519     ////
02520 
02521 
02522     if ((!test)&&(smooth_scrolling)&&(refresh)) {
02523         int fixedpos = getFixedPos();
02524         if (fixedpos >= 0) {
02525             if (getCols() != 1) {
02526                 /* this is a horizontal menu and we have to check which is the shortest way - left or right scrolling */
02527                 /* it's important to know because of smooth scrolling */
02528                 count = count % this->children.size();
02529                 if (fixedpos >= this->h_items)
02530                     fixedpos = (this->h_items - 1) / 2;
02531 
02532                 if (count > (this->children.size() / 2) - (fixedpos - ((this->h_items - 1) / 2))) {
02533                     count = this->children.size()-count;
02534                     while (count--)
02535                         scrollLeftEx(1, refresh, test, leave_selection);
02536                     return true;
02537                 }
02538 
02539                 while (count--)
02540                     scrollRightEx(1, refresh, test, leave_selection);
02541                 return true;
02542             }
02543         }
02544     }
02545 
02546     bool ret = scrollRightEx(count, refresh, test, leave_selection);
02547 
02548     if ((!ret)&&(!test))
02549         // nothing to scroll
02550         if (this->parent_menu) {
02551             // if we have a parent menu, we do only leave this menu if we switch back to the parent
02552             switchBackToParentMenu(MMSDIRECTION_RIGHT);
02553             return true;
02554         }
02555 
02556     return ret;
02557 }
02558 
02559 bool MMSMenuWidget::scrollLeft(unsigned int count, bool refresh, bool test, bool leave_selection) {
02560 
02561     if (this->children.size()==0)
02562         return false;
02563 
02564     if ((!test)&&(smooth_scrolling)&&(refresh)) {
02565         int fixedpos = getFixedPos();
02566         if (fixedpos >= 0) {
02567             if (getCols() != 1) {
02568                 /* this is a horizontal menu and we have to check which is the shortest way - left or right scrolling */
02569                 /* it's important to know because of smooth scrolling */
02570                 count = count % this->children.size();
02571                 if (fixedpos >= this->h_items)
02572                     fixedpos = (this->h_items - 1) / 2;
02573 
02574                 if (count > (this->children.size() / 2) - (fixedpos - ((this->h_items - 1) / 2))) {
02575                     count = this->children.size()-count;
02576                     while (count--)
02577                         scrollRightEx(1, refresh, test, leave_selection);
02578                     return true;
02579                 }
02580 
02581                 while (count--)
02582                     scrollLeftEx(1, refresh, test, leave_selection);
02583                 return true;
02584             }
02585         }
02586     }
02587 
02588     bool ret = scrollLeftEx(count, refresh, test, leave_selection);
02589 
02590     if ((!ret)&&(!test))
02591         // nothing to scroll
02592         if (this->parent_menu) {
02593             // if we have a parent menu, we do only leave this menu if we switch back to the parent
02594             switchBackToParentMenu(MMSDIRECTION_LEFT);
02595             return true;
02596         }
02597 
02598     return ret;
02599 }
02600 
02601 bool MMSMenuWidget::scrollTo(int posx, int posy, bool refresh, bool *changed, MMSWIDGET_SCROLL_MODE mode, MMSFBRectangle *inputrect) {
02602 
02603     // searching the affected menu item
02604     for (unsigned int i = 0; i < this->children.size(); i++) {
02605         if (!this->children.at(i)->isVisible())
02606             continue;
02607         MMSFBRectangle mygeom = this->children.at(i)->getGeometry();
02608         if   ((posx >= mygeom.x)&&(posy >= mygeom.y)
02609             &&(posx < mygeom.x + mygeom.w)&&(posy < mygeom.y + mygeom.h)) {
02610             switch (mode) {
02611             case MMSWIDGET_SCROLL_MODE_SETSELECTED:
02612                 // that's the right menu item, scroll smooth to the position
02613                 setSelected(i, refresh, changed, false);
02614                 break;
02615             case MMSWIDGET_SCROLL_MODE_SETSELECTED | MMSWIDGET_SCROLL_MODE_RMPRESSED:
02616                 // that's the right menu item, scroll smooth to the position
02617                 this->children.at(i)->setPressed(false, refresh);
02618                 setSelected(i, refresh, changed, false);
02619                 break;
02620             case MMSWIDGET_SCROLL_MODE_SETPRESSED:
02621                 // that's the right menu item, set pressed status
02622                 if (changed) *changed = true;
02623                 if (inputrect) *inputrect = mygeom;
02624                 this->children.at(i)->setPressed(true, refresh);
02625                 break;
02626             case MMSWIDGET_SCROLL_MODE_RMPRESSED:
02627                 // that's the right menu item, remove pressed status
02628                 if (changed) *changed = true;
02629                 this->children.at(i)->setPressed(false, refresh);
02630                 break;
02631             }
02632             return true;
02633         }
02634     }
02635 
02636     return false;
02637 }
02638 
02639 void MMSMenuWidget::setItemTemplate(MMSWidget *itemTemplate) {
02640     bool b;
02641 
02642     if (!itemTemplate)
02643         throw MMSWidgetError(0, "item template not set");
02644 
02645     /* we need menu items which can be selected */
02646     if (!itemTemplate->getSelectable(b))
02647         throw MMSWidgetError(0, "widget cannot be selected");
02648     if (!b)
02649         throw MMSWidgetError(0, "widget cannot be selected");
02650 
02651     /* we need menu items which can be selected and we must switch focusable off */
02652     if (itemTemplate->getFocusable(b))
02653         if (b)
02654             itemTemplate->setFocusable(false, false);
02655     itemTemplate->unsetFocusableForAllChildren(false);
02656     itemTemplate->setVisible(false, false);
02657 
02658     /* item template can be set once only */
02659     if (this->itemTemplate)
02660         throw MMSWidgetError(0, "item template can be set once only");
02661 
02662     this->itemTemplate = itemTemplate;
02663 }
02664 
02665 MMSWidget *MMSMenuWidget::getItemTemplate() {
02666     return this->itemTemplate;
02667 }
02668 
02669 MMSWidget *MMSMenuWidget::newItem(int item, MMSWidget *widget) {
02670     MMSMENUITEMINFOS    iteminfo;
02671 
02672     if (!widget) {
02673         // no widget given, create widget from template
02674         if (!this->itemTemplate)
02675             throw MMSWidgetError(0, "item template not set");
02676 
02677         widget = itemTemplate->copyWidget();
02678     }
02679 
02680     // lock me
02681     lock();
02682 
02683     widget->setParent(this);
02684     widget->setRootWindow(this->rootwindow);
02685     iteminfo.name = "";
02686     iteminfo.window = NULL;
02687     iteminfo.menu = NULL;
02688     if (item > 0) {
02689         if (item > (int)this->children.size())
02690             item = -1;
02691     }
02692     if (item < 0) {
02693         // push new item at the end of the list
02694         this->children.push_back(widget);
02695         this->iteminfos.push_back(iteminfo);
02696     }
02697     else {
02698         // get currently selected icon
02699         unsigned int sitem = getSelected();
02700 
02701         // insert at position item
02702         this->children.insert(this->children.begin() + item, widget);
02703         this->iteminfos.insert(this->iteminfos.begin() + item, iteminfo);
02704 
02705         if (item <= (int)sitem) {
02706             // item before the selected item inserted, so have to change the selection
02707             setSelected(sitem + 1, false);
02708         }
02709     }
02710 
02711     recalculateChildren();
02712 
02713     if (widget->isVisible()) {
02714         // refresh is required
02715         enableRefresh();
02716 
02717         if (this->isVisible()) this->refresh();
02718     }
02719 
02720     // unlock me
02721     unlock();
02722 
02723     return widget;
02724 }
02725 
02726 
02727 void MMSMenuWidget::deleteItem(unsigned int item) {
02728 
02729     // lock me
02730     lock();
02731 
02732     // check size
02733     if (item >= this->children.size()) {
02734         // unlock me
02735         unlock();
02736 
02737         return;
02738     }
02739 
02740     // get currently selected icon
02741     unsigned int sitem = getSelected();
02742 
02743     // delete item
02744     delete this->children.at(item);
02745     this->children.erase(this->children.begin()+item);
02746     this->iteminfos.erase(this->iteminfos.begin()+item);
02747 
02748     // recalc and refresh
02749     recalculateChildren();
02750 
02751     if (item < sitem) {
02752         // item before the selected item was deleted, so have to change the selection
02753         setSelected(sitem - 1, false);
02754     }
02755     else
02756     if (item == sitem) {
02757         // selected item was deleted, so we have to select the item at this position
02758         if (sitem < this->children.size())
02759             setSelected(sitem, false);
02760         else
02761         if (sitem > 0)
02762             setSelected(sitem - 1, false);
02763     }
02764 
02765     // refresh is required
02766     enableRefresh();
02767 
02768     this->refresh();
02769 
02770     // unlock me
02771     unlock();
02772 }
02773 
02774 
02775 void MMSMenuWidget::clear() {
02776     // lock me
02777     lock();
02778 
02779     for(int i = (int)this->children.size() - 1; i >= 0 ; i--) {
02780         delete this->children.at(i);
02781         this->children.erase(this->children.end()-1);
02782         this->iteminfos.erase(this->iteminfos.end()-1);
02783     }
02784 
02785     this->x = 0;
02786     this->y = 0;
02787     this->px = 0;
02788     this->py = 0;
02789     this->firstFocus = false;
02790     this->firstSelection = false;
02791 
02792     recalculateChildren();
02793 
02794     // refresh is required
02795     enableRefresh();
02796 
02797     this->refresh();
02798 
02799     // unlock me
02800     unlock();
02801 }
02802 
02803 void MMSMenuWidget::setFocus(bool set, bool refresh, MMSInputEvent *inputevent) {
02804     /* switch the brightness of the menu items */
02805     if (set) {
02806         /* get the focus -> dim up and/or decrease transparency */
02807         if ((!MMSWidget::isFocused())&&(this->firstFocus)) {
02808             for (unsigned int i = 0; i < children.size(); i++) {
02809                 children.at(i)->setBrightness(children.at(i)->getBrightness() + getDimItems(), false);
02810                 children.at(i)->setOpacity(children.at(i)->getOpacity() + getTransItems(), false);
02811             }
02812         }
02813     }
02814     else {
02815         /* loose the focus -> dim down and/or increase transparency */
02816         if ((MMSWidget::isFocused())||(!this->firstFocus)) {
02817             for (unsigned int i = 0; i < children.size(); i++) {
02818                 children.at(i)->setBrightness(children.at(i)->getBrightness() - getDimItems(), false);
02819                 children.at(i)->setOpacity(children.at(i)->getOpacity() - getTransItems(), false);
02820             }
02821         }
02822     }
02823     this->firstFocus = true;
02824 
02825     /* set the focus */
02826     if (!this->firstSelection) {
02827         if (!children.empty()) {
02828             MMSWidget::setFocus(set, false, inputevent);
02829             string inputmode = "";
02830             getInputModeEx(inputmode);
02831             if (strToUpr(inputmode) == "CLICK")
02832                 selectItem(children.at(0), false, refresh);
02833             else
02834                 selectItem(children.at(0), true, refresh);
02835         }
02836         else
02837             MMSWidget::setFocus(set, refresh, inputevent);
02838         this->firstSelection = true;
02839     }
02840     else {
02841         MMSWidget::setFocus(set, refresh, inputevent);
02842         string inputmode = "";
02843         getInputModeEx(inputmode);
02844         if (strToUpr(inputmode) == "CLICK")
02845             selectItem(getSelectedItem(), false, refresh);
02846     }
02847 }
02848 
02849 bool MMSMenuWidget::setSelected(unsigned int item, bool refresh, bool *changed, bool joined) {
02850     bool c = false;
02851     if (changed)
02852         *changed = c;
02853 
02854     if (!getConfig())
02855         return false;
02856 
02857     if (item >= children.size())
02858         return false;
02859 
02860     if (!this->firstSelection) {
02861         if (item == 0)
02862             if (!children.empty())
02863                 selectItem(children.at(0), refresh);
02864         this->firstSelection = true;
02865     }
02866 
02867     unsigned int cols = getCols();
02868     unsigned int mx = item % cols;
02869     unsigned int my = item / cols;
02870 
02871     // scroll left-down
02872     if (((int)mx < this->x)&&((int)my > this->y)) {
02873         if (scrollLeft(this->x - mx, false))
02874             scrollDown(my - this->y, refresh);
02875         c = true;
02876     }
02877     else
02878     // scroll right-down
02879     if (((int)mx > this->x)&&((int)my > this->y)) {
02880         if (scrollRight(mx - this->x, false))
02881             scrollDown(my - this->y, refresh);
02882         c = true;
02883     }
02884     else
02885     // scroll left-up
02886     if (((int)mx < this->x)&&((int)my < this->y)) {
02887         if (scrollUp(this->y - my, false))
02888             scrollLeft(this->x - mx, refresh);
02889         c = true;
02890     }
02891     else
02892     // scroll right-up
02893     if (((int)mx > this->x)&&((int)my < this->y)) {
02894         if (scrollUp(this->y - my, false))
02895             scrollRight(mx - this->x, refresh);
02896         c = true;
02897     }
02898     else
02899     // scroll down
02900     if ((int)my > this->y) {
02901         scrollDown(my - this->y, refresh);
02902         c = true;
02903     }
02904     else
02905     // scroll up
02906     if ((int)my < this->y) {
02907         scrollUp(this->y - my, refresh);
02908         c = true;
02909     }
02910     else
02911     // scroll left
02912     if ((int)mx < this->x) {
02913         scrollLeft(this->x - mx, refresh);
02914         c = true;
02915     }
02916     else
02917     // scroll right
02918     if ((int)mx > this->x) {
02919         scrollRight(mx - this->x, refresh);
02920         c = true;
02921     }
02922 
02923     if (!c) {
02924         // preventive set selected true to reset it
02925         MMSWidget *item = getSelectedItem();
02926         if (item)
02927             item->setSelected(true);
02928     }
02929 
02930     if (changed)
02931         *changed = c;
02932 
02933     return true;
02934 }
02935 
02936 bool MMSMenuWidget::setSelected(unsigned int item, bool refresh) {
02937     return setSelected(item, refresh, NULL, false);
02938 }
02939 
02940 unsigned int MMSMenuWidget::getSelected() {
02941     return (this->x + this->y * getCols());
02942 }
02943 
02944 MMSWidget *MMSMenuWidget::getItem(unsigned int item) {
02945     if (item < this->children.size())
02946         return this->children.at(item);
02947     return NULL;
02948 }
02949 
02950 MMSWidget *MMSMenuWidget::getSelectedItem() {
02951     return getItem(getSelected());
02952 }
02953 
02954 unsigned int MMSMenuWidget::getSize() {
02955     return this->children.size();
02956 }
02957 
02958 unsigned int MMSMenuWidget::getVItems() {
02959     return this->v_items;
02960 }
02961 
02962 unsigned int MMSMenuWidget::getHItems() {
02963     return this->h_items;
02964 }
02965 
02966 
02967 
02968 bool MMSMenuWidget::setSubMenuName(unsigned int item, const char *name) {
02969     if (item >= this->iteminfos.size()) return false;
02970     iteminfos.at(item).name = name;
02971     iteminfos.at(item).window = NULL;
02972     return true;
02973 }
02974 
02975 bool MMSMenuWidget::setSubMenuName(unsigned int item, string &name) {
02976     return setSubMenuName(item, name.c_str());
02977 }
02978 
02979 bool MMSMenuWidget::setBackItem(unsigned int item) {
02980 /*  if ((item!=-1)&&(item >= this->children.size())) return false;   -- item is unsigned (mattmax) */
02981     if (item >= this->children.size()) return false;
02982     this->back_item = item;
02983     return true;
02984 }
02985 
02986 
02987 /***********************************************/
02988 /* begin of theme access methods (get methods) */
02989 /***********************************************/
02990 
02991 #define GETMENU(x) \
02992     if (this->myMenuWidgetClass.is##x()) return myMenuWidgetClass.get##x(); \
02993     else if ((menuWidgetClass)&&(menuWidgetClass->is##x())) return menuWidgetClass->get##x(); \
02994     else return this->da->theme->menuWidgetClass.get##x();
02995 
02996 #define GETMENU_X(x,y) \
02997     if (this->myMenuWidgetClass.is##x()) { y = myMenuWidgetClass.get##x(); return true; } \
02998     else if ((menuWidgetClass)&&(menuWidgetClass->is##x())) { y = menuWidgetClass->get##x(); return true; } \
02999     else { y = this->da->theme->menuWidgetClass.get##x(); return true; }
03000 
03001 MMSTaffFile *MMSMenuWidget::getTAFF() {
03002     MMSTaffFile *node;
03003     if ((node=myMenuWidgetClass.getTAFF()))
03004         return node;
03005     if ((menuWidgetClass)&&((node=menuWidgetClass->getTAFF())))
03006         return node;
03007     return this->da->theme->menuWidgetClass.getTAFF();
03008 }
03009 
03010 string MMSMenuWidget::getItemWidth() {
03011     GETMENU(ItemWidth);
03012 }
03013 
03014 string MMSMenuWidget::getItemHeight() {
03015     GETMENU(ItemHeight);
03016 }
03017 
03018 unsigned int MMSMenuWidget::getItemHMargin() {
03019     GETMENU(ItemHMargin);
03020 }
03021 
03022 unsigned int MMSMenuWidget::getItemVMargin() {
03023     GETMENU(ItemVMargin);
03024 }
03025 
03026 unsigned int MMSMenuWidget::getCols() {
03027     if (this->myMenuWidgetClass.isCols())
03028         return myMenuWidgetClass.getCols();
03029     else if ((menuWidgetClass)&&(menuWidgetClass->isCols()))
03030         return menuWidgetClass->getCols();
03031     else
03032         return this->da->theme->menuWidgetClass.getCols();
03033 
03034 
03035     //GETMENU(Cols);
03036 }
03037 
03038 unsigned int MMSMenuWidget::getDimItems() {
03039     GETMENU(DimItems);
03040 }
03041 
03042 int MMSMenuWidget::getFixedPos() {
03043     GETMENU(FixedPos);
03044 }
03045 
03046 bool MMSMenuWidget::getHLoop() {
03047     GETMENU(HLoop);
03048 }
03049 
03050 bool MMSMenuWidget::getVLoop() {
03051     GETMENU(VLoop);
03052 }
03053 
03054 unsigned int MMSMenuWidget::getTransItems() {
03055     GETMENU(TransItems);
03056 }
03057 
03058 unsigned int MMSMenuWidget::getDimTop() {
03059     GETMENU(DimTop);
03060 }
03061 
03062 unsigned int MMSMenuWidget::getDimBottom() {
03063     GETMENU(DimBottom);
03064 }
03065 
03066 unsigned int MMSMenuWidget::getDimLeft() {
03067     GETMENU(DimLeft);
03068 }
03069 
03070 unsigned int MMSMenuWidget::getDimRight() {
03071     GETMENU(DimRight);
03072 }
03073 
03074 unsigned int MMSMenuWidget::getTransTop() {
03075     GETMENU(TransTop);
03076 }
03077 
03078 unsigned int MMSMenuWidget::getTransBottom() {
03079     GETMENU(TransBottom);
03080 }
03081 
03082 unsigned int MMSMenuWidget::getTransLeft() {
03083     GETMENU(TransLeft);
03084 }
03085 
03086 unsigned int MMSMenuWidget::getTransRight() {
03087     GETMENU(TransRight);
03088 }
03089 
03090 string MMSMenuWidget::getZoomSelWidth() {
03091     GETMENU(ZoomSelWidth);
03092 }
03093 
03094 string MMSMenuWidget::getZoomSelHeight() {
03095     GETMENU(ZoomSelHeight);
03096 }
03097 
03098 string MMSMenuWidget::getZoomSelShiftX() {
03099     GETMENU(ZoomSelShiftX);
03100 }
03101 
03102 string MMSMenuWidget::getZoomSelShiftY() {
03103     GETMENU(ZoomSelShiftY);
03104 }
03105 
03106 MMSSEQUENCEMODE MMSMenuWidget::getSmoothScrolling() {
03107     GETMENU(SmoothScrolling);
03108 }
03109 
03110 string MMSMenuWidget::getParentWindow() {
03111     GETMENU(ParentWindow);
03112 }
03113 
03114 bool MMSMenuWidget::getSelImagePath(string &selimagepath) {
03115     GETMENU_X(SelImagePath, selimagepath);
03116 }
03117 
03118 bool MMSMenuWidget::getSelImageName(string &selimagename) {
03119     GETMENU_X(SelImageName, selimagename);
03120 }
03121 
03122 MMSSEQUENCEMODE MMSMenuWidget::getSmoothSelection() {
03123     GETMENU(SmoothSelection);
03124 }
03125 
03126 unsigned int MMSMenuWidget::getSmoothDelay() {
03127     GETMENU(SmoothDelay);
03128 }
03129 
03130 /***********************************************/
03131 /* begin of theme access methods (set methods) */
03132 /***********************************************/
03133 
03134 void MMSMenuWidget::setItemWidth(string itemwidth, bool refresh) {
03135     myMenuWidgetClass.setItemWidth(itemwidth);
03136 
03137     // refresh is required
03138     enableRefresh();
03139 
03140     if (refresh)
03141         this->refresh();
03142 }
03143 
03144 void MMSMenuWidget::setItemHeight(string itemheight, bool refresh) {
03145     myMenuWidgetClass.setItemHeight(itemheight);
03146 
03147     // refresh is required
03148     enableRefresh();
03149 
03150     if (refresh)
03151         this->refresh();
03152 }
03153 
03154 void MMSMenuWidget::setItemHMargin(unsigned int itemhmargin, bool refresh) {
03155     myMenuWidgetClass.setItemHMargin(itemhmargin);
03156 
03157     // refresh is required
03158     enableRefresh();
03159 
03160     if (refresh)
03161         this->refresh();
03162 }
03163 
03164 void MMSMenuWidget::setItemVMargin(unsigned int itemvmargin, bool refresh) {
03165     myMenuWidgetClass.setItemVMargin(itemvmargin);
03166 
03167     // refresh is required
03168     enableRefresh();
03169 
03170     if (refresh)
03171         this->refresh();
03172 }
03173 
03174 void MMSMenuWidget::setCols(unsigned int cols, bool refresh) {
03175     myMenuWidgetClass.setCols(cols);
03176 
03177     // refresh is required
03178     enableRefresh();
03179 
03180     if (refresh)
03181         this->refresh();
03182 }
03183 
03184 void MMSMenuWidget::setDimItems(unsigned int dimitems, bool refresh) {
03185     myMenuWidgetClass.setDimItems(dimitems);
03186 
03187     // refresh is required
03188     enableRefresh();
03189 
03190     if (refresh)
03191         this->refresh();
03192 }
03193 
03194 void MMSMenuWidget::setFixedPos(int fixedpos, bool refresh) {
03195     myMenuWidgetClass.setFixedPos(fixedpos);
03196 
03197     // refresh is required
03198     enableRefresh();
03199 
03200     if (refresh)
03201         this->refresh();
03202 }
03203 
03204 void MMSMenuWidget::setHLoop(bool hloop) {
03205     myMenuWidgetClass.setHLoop(hloop);
03206 }
03207 
03208 void MMSMenuWidget::setVLoop(bool vloop) {
03209     myMenuWidgetClass.setVLoop(vloop);
03210 }
03211 
03212 void MMSMenuWidget::setTransItems(unsigned int transitems, bool refresh) {
03213     myMenuWidgetClass.setTransItems(transitems);
03214 
03215     // refresh is required
03216     enableRefresh();
03217 
03218     if (refresh)
03219         this->refresh();
03220 }
03221 
03222 void MMSMenuWidget::setDimTop(unsigned int dimtop, bool refresh) {
03223     myMenuWidgetClass.setDimTop(dimtop);
03224 
03225     // refresh is required
03226     enableRefresh();
03227 
03228     if (refresh)
03229         this->refresh();
03230 }
03231 
03232 void MMSMenuWidget::setDimBottom(unsigned int dimbottom, bool refresh) {
03233     myMenuWidgetClass.setDimBottom(dimbottom);
03234 
03235     // refresh is required
03236     enableRefresh();
03237 
03238     if (refresh)
03239         this->refresh();
03240 }
03241 
03242 void MMSMenuWidget::setDimLeft(unsigned int dimleft, bool refresh) {
03243     myMenuWidgetClass.setDimLeft(dimleft);
03244 
03245     // refresh is required
03246     enableRefresh();
03247 
03248     if (refresh)
03249         this->refresh();
03250 }
03251 
03252 void MMSMenuWidget::setDimRight(unsigned int dimright, bool refresh) {
03253     myMenuWidgetClass.setDimRight(dimright);
03254 
03255     // refresh is required
03256     enableRefresh();
03257 
03258     if (refresh)
03259         this->refresh();
03260 }
03261 
03262 void MMSMenuWidget::setTransTop(unsigned int transtop, bool refresh) {
03263     myMenuWidgetClass.setTransTop(transtop);
03264 
03265     // refresh is required
03266     enableRefresh();
03267 
03268     if (refresh)
03269         this->refresh();
03270 }
03271 
03272 void MMSMenuWidget::setTransBottom(unsigned int transbottom, bool refresh) {
03273     myMenuWidgetClass.setTransBottom(transbottom);
03274 
03275     // refresh is required
03276     enableRefresh();
03277 
03278     if (refresh)
03279         this->refresh();
03280 }
03281 
03282 void MMSMenuWidget::setTransLeft(unsigned int transleft, bool refresh) {
03283     myMenuWidgetClass.setTransLeft(transleft);
03284 
03285     // refresh is required
03286     enableRefresh();
03287 
03288     if (refresh)
03289         this->refresh();
03290 }
03291 
03292 void MMSMenuWidget::setTransRight(unsigned int transright, bool refresh) {
03293     myMenuWidgetClass.setTransRight(transright);
03294 
03295     // refresh is required
03296     enableRefresh();
03297 
03298     if (refresh)
03299         this->refresh();
03300 }
03301 
03302 void MMSMenuWidget::setZoomSelWidth(string zoomselwidth, bool refresh) {
03303     myMenuWidgetClass.setZoomSelWidth(zoomselwidth);
03304 
03305     // refresh is required
03306     enableRefresh();
03307 
03308     if (refresh)
03309         this->refresh();
03310 }
03311 
03312 void MMSMenuWidget::setZoomSelHeight(string zoomselheight, bool refresh) {
03313     myMenuWidgetClass.setZoomSelHeight(zoomselheight);
03314 
03315     // refresh is required
03316     enableRefresh();
03317 
03318     if (refresh)
03319         this->refresh();
03320 }
03321 
03322 void MMSMenuWidget::setZoomSelShiftX(string zoomselshiftx, bool refresh) {
03323     myMenuWidgetClass.setZoomSelShiftX(zoomselshiftx);
03324 
03325     // refresh is required
03326     enableRefresh();
03327 
03328     if (refresh)
03329         this->refresh();
03330 }
03331 
03332 void MMSMenuWidget::setZoomSelShiftY(string zoomselshifty, bool refresh) {
03333     myMenuWidgetClass.setZoomSelShiftY(zoomselshifty);
03334 
03335     // refresh is required
03336     enableRefresh();
03337 
03338     if (refresh)
03339         this->refresh();
03340 }
03341 
03342 void MMSMenuWidget::setSmoothScrolling(MMSSEQUENCEMODE seq_mode) {
03343     myMenuWidgetClass.setSmoothScrolling(seq_mode);
03344     this->smooth_scrolling = seq_mode;
03345 }
03346 
03347 void MMSMenuWidget::setParentWindow(string parentwindow) {
03348     myMenuWidgetClass.setParentWindow(parentwindow);
03349     initParentWindow();
03350 }
03351 
03352 void MMSMenuWidget::setSelImagePath(string selimagepath, bool load, bool refresh) {
03353     myMenuWidgetClass.setSelImagePath(selimagepath);
03354     if (load)
03355         if (this->rootwindow) {
03356             this->rootwindow->im->releaseImage(this->selimage);
03357             string path, name;
03358             if (!getSelImagePath(path)) path = "";
03359             if (!getSelImageName(name)) name = "";
03360             this->selimage = this->rootwindow->im->getImage(path, name);
03361         }
03362 
03363 
03364     // refresh is required
03365     enableRefresh();
03366 
03367     if (refresh)
03368         this->refresh();
03369 }
03370 
03371 void MMSMenuWidget::setSelImageName(string selimagename, bool load, bool refresh) {
03372     myMenuWidgetClass.setSelImageName(selimagename);
03373     if (load)
03374         if (this->rootwindow) {
03375             this->rootwindow->im->releaseImage(this->selimage);
03376             string path, name;
03377             if (!getSelImagePath(path)) path = "";
03378             if (!getSelImageName(name)) name = "";
03379             this->selimage = this->rootwindow->im->getImage(path, name);
03380         }
03381 
03382 
03383     // refresh is required
03384     enableRefresh();
03385 
03386     if (refresh)
03387         this->refresh();
03388 }
03389 
03390 void MMSMenuWidget::setSmoothSelection(MMSSEQUENCEMODE seq_mode) {
03391     myMenuWidgetClass.setSmoothSelection(seq_mode);
03392     this->smooth_selection = seq_mode;
03393 }
03394 
03395 void MMSMenuWidget::setSmoothDelay(unsigned int smoothdelay) {
03396     myMenuWidgetClass.setSmoothDelay(smoothdelay);
03397     this->frame_delay = 0;
03398     this->frame_delay_set = false;
03399 }
03400 
03401 
03402 void MMSMenuWidget::updateFromThemeClass(MMSMenuWidgetClass *themeClass) {
03403     if (themeClass->isItemWidth())
03404         setItemWidth(themeClass->getItemWidth());
03405    if (themeClass->isItemHeight())
03406         setItemHeight(themeClass->getItemHeight());
03407    if (themeClass->isItemHMargin())
03408         setItemHMargin(themeClass->getItemHMargin());
03409    if (themeClass->isItemVMargin())
03410         setItemVMargin(themeClass->getItemVMargin());
03411    if (themeClass->isCols())
03412         setCols(themeClass->getCols());
03413    if (themeClass->isDimItems())
03414         setDimItems(themeClass->getDimItems());
03415    if (themeClass->isFixedPos())
03416         setFixedPos(themeClass->getFixedPos());
03417    if (themeClass->isHLoop())
03418         setHLoop(themeClass->getHLoop());
03419    if (themeClass->isVLoop())
03420         setVLoop(themeClass->getVLoop());
03421    if (themeClass->isTransItems())
03422         setTransItems(themeClass->getTransItems());
03423    if (themeClass->isDimTop())
03424         setDimTop(themeClass->getDimTop());
03425    if (themeClass->isDimBottom())
03426         setDimBottom(themeClass->getDimBottom());
03427    if (themeClass->isDimLeft())
03428         setDimLeft(themeClass->getDimLeft());
03429    if (themeClass->isDimRight())
03430         setDimRight(themeClass->getDimRight());
03431    if (themeClass->isTransTop())
03432         setTransTop(themeClass->getTransTop());
03433    if (themeClass->isTransBottom())
03434         setTransBottom(themeClass->getTransBottom());
03435    if (themeClass->isTransLeft())
03436         setTransLeft(themeClass->getTransLeft());
03437    if (themeClass->isTransRight())
03438         setTransRight(themeClass->getTransRight());
03439    if (themeClass->isZoomSelWidth())
03440         setZoomSelWidth(themeClass->getZoomSelWidth());
03441    if (themeClass->isZoomSelHeight())
03442         setZoomSelHeight(themeClass->getZoomSelHeight());
03443    if (themeClass->isZoomSelShiftX())
03444         setZoomSelShiftX(themeClass->getZoomSelShiftX());
03445    if (themeClass->isZoomSelShiftY())
03446         setZoomSelShiftY(themeClass->getZoomSelShiftY());
03447    if (themeClass->isSmoothScrolling())
03448         setSmoothScrolling(themeClass->getSmoothScrolling());
03449    if (themeClass->isParentWindow())
03450         setParentWindow(themeClass->getParentWindow());
03451    if (themeClass->isSelImagePath())
03452        setSelImagePath(themeClass->getSelImagePath());
03453    if (themeClass->isSelImageName())
03454        setSelImageName(themeClass->getSelImageName());
03455    if (themeClass->isSmoothSelection())
03456         setSmoothSelection(themeClass->getSmoothSelection());
03457    if (themeClass->isSmoothDelay())
03458         setSmoothDelay(themeClass->getSmoothDelay());
03459 
03460     MMSWidget::updateFromThemeClass(&(themeClass->widgetClass));
03461 }
03462 
03463 /***********************************************/
03464 /* end of theme access methods                 */
03465 /***********************************************/
03466 

Generated by doxygen