Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

pgpopupmenu.h

Go to the documentation of this file.
00001 /*
00002     ParaGUI - crossplatform widgetset
00003     Copyright (C) 2000,2001,2002  Alexander Pipelka
00004  
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009  
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014  
00015     You should have received a copy of the GNU Library General Public
00016     License along with this library; if not, write to the Free
00017     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  
00019     Alexander Pipelka
00020     pipelka@teleweb.at
00021  
00022     Last Update:      $Author: mbickel $
00023     Update Date:      $Date: 2007-04-13 16:15:57 $
00024     Source File:      $Source: /home/cvspsrv/cvsroot/games/asc/source/libs/paragui/include/pgpopupmenu.h,v $
00025     CVS/RCS Revision: $Revision: 1.2 $
00026     Status:           $State: Exp $
00027 */
00028 
00033 #ifndef PG_POPUPMENU_H
00034 #define PG_POPUPMENU_H
00035 
00036 #include "pgthemewidget.h"
00037 #include "pgsignals.h"
00038 #include "pgstring.h"
00039 
00040 #include <string>
00041 #include <list>
00042 #ifdef HASH_MAP_INC
00043 # include HASH_MAP_INC
00044 #else
00045 # include <map>
00046 #endif
00047 
00068 class DECLSPEC PG_PopupMenu : public PG_ThemeWidget {
00069 public:
00070 
00087 class DECLSPEC MenuItem : public PG_Rect, public PG_MessageObject {
00088         public: // types
00089                 enum MI_FLAGS {
00090                     MIF_NONE = 0,
00091                     MIF_DISABLED = 0x01,
00092                     MIF_SEPARATOR = 0x02,
00093                     MIF_SUBMENU = 0x04
00094                 };
00095 
00099                 template<class datatype = PG_Pointer>
00100         class SignalSelectMenuItem : public PG_Signal1<MenuItem*, datatype> {}
00101                 ;
00102 
00103                 SignalSelectMenuItem<> sigSelectMenuItem;
00104 
00105                 typedef SigC::Slot2<bool, MenuItem*, PG_Pointer> MenuItemSlot;
00106 
00107         public: // methods
00108                 MenuItem(PG_PopupMenu *parent,
00109                          const std::string& caption,
00110                          int id,
00111                          MI_FLAGS flags);
00112                 MenuItem(PG_PopupMenu *parent,
00113                          const std::string& caption,
00114                          PG_PopupMenu *submenu);
00115                 ~MenuItem();
00116 
00117                 bool measureItem(PG_Rect* rect,  bool full = false);
00118                 bool isPointInside(int x, int y);
00119                 inline void moveTo(int x, int y);
00120 
00121                 inline SDL_Surface* getNormal() const;
00122                 inline SDL_Surface* getDisabled() const;
00123                 inline SDL_Surface* getSelected() const;
00124 
00125                 bool paintNormal(SDL_Surface *canvas, PG_Color* tcol, PG_Color* scol = NULL);
00126                 bool paintDisabled(SDL_Surface *canvas, PG_Color* tcol, PG_Color* scol = NULL);
00127                 bool paintSelected(SDL_Surface *canvas, PG_Color* tcol, PG_Color* scol = NULL);
00128 
00129                 inline void disable();
00130                 inline void enable();
00131                 inline bool isDisabled() const;
00132                 inline bool isEnabled() const;
00133                 inline void select();
00134                 inline void unselect();
00135                 inline bool isSelected() const;
00136                 inline bool isSeparator() const;
00137                 inline bool isSubMenu() const;
00138                 inline bool isMute() const;
00139 
00140                 inline int Width() const;
00141                 inline int Height() const;
00142 
00143                 inline int getId() const;
00144                 inline PG_PopupMenu *getSubMenu() const;
00145 
00146                 inline const PG_String& getCaption() const;
00147 
00148                 inline operator PG_Point const&() const;
00149 
00150         private: // methods
00151                 DLLLOCAL void initItem( const std::string& caption );
00152                 DLLLOCAL bool renderSurface(SDL_Surface *canvas, SDL_Surface **text, PG_Color* tcol, PG_Color* scol = 0);
00153                 DLLLOCAL bool isValidRect();
00154 
00155         protected: // data
00156                 unsigned      myFlags;
00157                 PG_String     myCaption;
00158                 PG_String     myRightCaption;
00159                 PG_PopupMenu *myParent;
00160 
00161                 PG_PopupMenu *mySubMenu;
00162                 int           myId;
00163 
00164                 SDL_Surface  *sNormal;
00165                 SDL_Surface  *sSelected;
00166                 SDL_Surface  *sDisabled;
00167 
00168                 bool          selected;
00169 
00170         private: // data
00171                 bool          needRecalc;
00172                 PG_Point      myPoint;
00173         };
00174 
00175 #ifndef DOXYGEN_SKIP
00176 class item_with_id : public std::unary_function<MenuItem*, bool> {
00177                 int id;
00178 
00179         public:
00180                 explicit item_with_id(int i)
00181                                 : id(i) {}
00182 
00183                 bool operator() (const MenuItem* const mi) const {
00184                         return mi->getId() == id;
00185                 }
00186         };
00187 #endif // DOXYGEN_SKIP
00188 
00189 public: // methods
00190 
00194         template<class datatype = PG_Pointer>
00195 class SignalSelectMenuItem : public PG_Signal1<MenuItem*, datatype> {}
00196         ;
00197 
00198         PG_PopupMenu(PG_Widget *parent,
00199                      int x, int y,
00200                      const std::string& caption = PG_NULLSTR,
00201                      const std::string& style = "PopupMenu");
00202 
00203         ~PG_PopupMenu();
00204 
00223         PG_PopupMenu& addMenuItem(const std::string& caption,
00224                                   int ID,
00225                                   MenuItem::MenuItemSlot,
00226                                   PG_Pointer data = NULL,
00227                                   MenuItem::MI_FLAGS flags = MenuItem::MIF_NONE);
00228 
00229         PG_PopupMenu& addMenuItem(const std::string& caption,
00230                                   int ID,
00231                                   MenuItem::MI_FLAGS flags = MenuItem::MIF_NONE);
00232 
00233         PG_PopupMenu& addMenuItem(const std::string& caption,
00234                                   PG_PopupMenu *sub,
00235                                   MenuItem::MI_FLAGS flags = MenuItem::MIF_SUBMENU);
00236 
00242         PG_PopupMenu& addSeparator();
00243 
00244         bool SetMenuItemSlot(int id, MenuItem::MenuItemSlot slot, PG_Pointer clientdata = NULL);
00245 
00246         inline int maxItemWidth() const;
00247 
00248         void disableItem(int dd);
00249         void enableItem(int id);
00250 
00262         void trackMenu(int x = -1, int y = -1);
00263         void openMenu(int x = -1, int y = -1);
00264 
00265 
00266         SignalSelectMenuItem<> sigSelectMenuItem;
00267 
00268 protected: // methods
00269 
00270         typedef std::list<MenuItem*>::iterator MII;
00271 
00272         // reimplemented
00273         void eventBlit(SDL_Surface* surface, const PG_Rect& src, const PG_Rect& dst);
00274 
00275         void eventMouseEnter();
00276         void eventMouseLeave();
00277 
00278         bool eventMouseMotion(const SDL_MouseMotionEvent *motion);
00279         bool eventMouseButtonDown(const SDL_MouseButtonEvent *button);
00280         bool eventMouseButtonUp(const SDL_MouseButtonEvent *button);
00281         bool eventKeyDown(const SDL_KeyboardEvent *key);
00282 
00283         void eventMoveWidget(int x, int y);
00284         void eventShow();
00285         void eventHide();
00286 
00287         void LoadThemeStyle(const std::string& widgettype);
00288         void LoadThemeStyle(const std::string& widgettype, const std::string& objectname);
00289 
00290         // own
00291         virtual bool getCaptionHeight(PG_Rect &rect, bool constructing = false);
00292         virtual void recalcRect();
00293         virtual void handleClick(int x, int y);
00294         virtual void enslave(PG_PopupMenu *master);
00295         virtual void liberate();
00296 
00297 private: // methods
00298 
00299         DLLLOCAL bool selectItem(MenuItem *item, MII iter);
00300         DLLLOCAL bool handleMotion(PG_Point const&);
00301         DLLLOCAL void appendItem(MenuItem *item);
00302 
00303 protected: // data
00304 
00305         std::list<MenuItem*>  items; 
00306         std::string           myCaption; 
00308         PG_Color             captionActiveColor;
00309         PG_Color             captionInactiveColor;
00310 
00311         PG_Color             miNormalColor;
00312         PG_Color             miSelectedColor;
00313         PG_Color             miDisabledColor;
00314 
00315         PG_Color             sepNormalColor;
00316         PG_Color             sepShadowColor;
00317 
00318         int                   xPadding;
00319         int                   yPadding;
00320 
00323         int                  minTabWidth;
00324 
00325         int                  separatorLineWidth;
00326 
00327 private: // data
00328         PG_Rect               captionRect;
00329         PG_Rect               actionRect;
00330 
00331         PG_Gradient          *miGradients[3];
00332         SDL_Surface          *miBackgrounds[3];
00333         PG_Draw::BkMode           miBkModes[3];
00334         Uint8                 miBlends[3];
00335         int                   itemHeight;
00336         int                   lastH;
00337         MenuItem             *selected;
00338 
00339         bool                  tracking;
00340         bool                  wasTracking;
00341         bool                  buttonDown;
00342 
00343         MII                   stop;
00344         MII                   start;
00345         MII                   current;
00346 
00347         PG_PopupMenu         *activeSub;
00348         PG_PopupMenu         *myMaster;
00349         MenuItem             *subParent;
00350 };
00351 
00352 inline int PG_PopupMenu::maxItemWidth() const {
00353         return w - xPadding;
00354 }
00355 
00356 inline void PG_PopupMenu::MenuItem::moveTo(int _x, int _y) {
00357         myPoint.x = x = _x;
00358         myPoint.y = y = _y;
00359 };
00360 
00361 inline SDL_Surface* PG_PopupMenu::MenuItem::getNormal() const {
00362         return sNormal;
00363 }
00364 
00365 inline SDL_Surface* PG_PopupMenu::MenuItem::getDisabled() const {
00366         return sDisabled;
00367 }
00368 
00369 inline SDL_Surface* PG_PopupMenu::MenuItem::getSelected() const {
00370         return sSelected;
00371 }
00372 
00373 inline void PG_PopupMenu::MenuItem::disable() {
00374         myFlags |= MIF_DISABLED;
00375 }
00376 
00377 inline void PG_PopupMenu::MenuItem::enable() {
00378         myFlags &= ~MIF_DISABLED;
00379 }
00380 
00381 inline bool PG_PopupMenu::MenuItem::isDisabled() const {
00382         return (myFlags & MIF_DISABLED);
00383 }
00384 
00385 inline bool PG_PopupMenu::MenuItem::isEnabled() const {
00386         return !(myFlags & MIF_DISABLED);
00387 }
00388 
00389 inline void PG_PopupMenu::MenuItem::select() {
00390         selected = true;
00391 }
00392 
00393 inline void PG_PopupMenu::MenuItem::unselect() {
00394         selected = false;
00395 }
00396 
00397 inline bool PG_PopupMenu::MenuItem::isSelected() const {
00398         return selected;
00399 }
00400 
00401 inline bool PG_PopupMenu::MenuItem::isSeparator() const {
00402         return ((myFlags & MIF_SEPARATOR) != 0);
00403 }
00404 
00405 inline bool PG_PopupMenu::MenuItem::isSubMenu() const {
00406         return ((myFlags & MIF_SUBMENU) != 0);
00407 }
00408 
00409 inline bool PG_PopupMenu::MenuItem::isMute() const {
00410         return ((myFlags & MIF_DISABLED) ||
00411                 (myFlags & MIF_SEPARATOR));
00412 }
00413 
00414 inline int PG_PopupMenu::MenuItem::Width() const {
00415         return w;
00416 }
00417 
00418 inline int PG_PopupMenu::MenuItem::Height() const {
00419         return h;
00420 }
00421 
00422 inline int PG_PopupMenu::MenuItem::getId() const {
00423         return myId;
00424 }
00425 
00426 inline PG_PopupMenu *PG_PopupMenu::MenuItem::getSubMenu() const {
00427         return mySubMenu;
00428 }
00429 
00430 inline const PG_String& PG_PopupMenu::MenuItem::getCaption() const {
00431         return myCaption;
00432 }
00433 
00434 inline PG_PopupMenu::MenuItem::operator PG_Point const&() const {
00435         return myPoint;
00436 }
00437 
00438 #endif // PG_POPUPMENU_H

Generated on Tue Jun 24 01:27:48 2008 for Advanced Strategic Command by  doxygen 1.4.2