Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

Menu.h

Go to the documentation of this file.
00001 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00002 // Menu.h
00003 // NOTE: First attempt, still immature: Work in progress.
00004 //       In future Menu creation only through MenuTopPane::CreateMenu
00005 //       That way better control over menus and possible to handle
00006 //       menu destruction.
00007 //       In future menus will become refCounted.
00008 // NOTE!!!!! Because of above: No backward compatibility promissed
00009 //           Use at your own risk!!!
00010 //
00011 // Author: Richard van Balen
00012 
00013 #ifndef OglGui_Menu_h
00014 #define OglGui_Menu_h
00015 
00016 #ifndef OglGui_MenuTopPane_h
00017 #include "OglGui/MenuTopPane.h"
00018 #endif
00019 
00020 #ifndef OglGui_MenuListener_h
00021 #include "OglGui/MenuListener.h"
00022 #endif
00023 
00024 namespace OglGui
00025 {
00026 
00027 class Menu : public Window
00028 {
00029 public:
00030     static const int DISABLED   = 1;   
00031     static const int CHECKED    = 2;
00032     static const int SEPARATOR  = 4;
00033 
00034     Menu(MenuTopPane* parent, int menuIdx=0, int w=100) :
00035         Window(parent, 0,0,w,20)
00036     {
00037         Init(parent, menuIdx);
00038     }
00039 
00040     void SetMenuListener(MenuListener* l, void* userData)
00041     {
00042         mMenuListener = l;
00043         mListenerData = userData;
00044     }
00045 
00046     void  ActiveItemBackground(ULONG col)   { mActiveBg = col; }
00047     ULONG ActiveItemBackground()            { return mActiveBg; }
00048 
00049     void SetCornerColors(ULONG lT, ULONG rT, ULONG rB, ULONG lB)
00050     {
00051         if (lT!=RETAIN) mLeftTopCol  = lT;
00052         if (rT!=RETAIN) mRightTopCol = rT;
00053         if (rB!=RETAIN) mRightBotCol = rB;
00054         if (lB!=RETAIN) mLeftBotCol  = lB;
00055     }
00056 
00057     void SetOptions(int itemIdx, int options, bool mode)
00058     {
00059         for (int i=0; i<mItemNames.size(); i++)
00060             if (mItemIdxs[i]==itemIdx)
00061                 SetArrayIndexOption(i,options,mode);
00062     }
00063     void SetOptions(strconst itemName, int options, bool mode)
00064     {
00065         for (int i=0; i<mItemNames.size(); i++)
00066             if (mItemNames[i]==itemName)
00067                 SetArrayIndexOption(i,options,mode);
00068     }
00069 
00070     void AddItem(strconst item, int idx=0, int insertAt=-1, int options=0)
00071     {
00072         InsertItem(item, 0, idx, insertAt, options);
00073     }
00074 
00075     void AddMenu(Menu* menu, strconst item, int idx=0, int insertAt=-1,
00076                  int options=0)
00077     {
00078         InsertItem(item, menu, idx, insertAt, options);
00079     }
00080 
00081     void InsertItem(strconst str, Menu* menu, int idx=0, int insertAt=-1,
00082                     int options=0)
00083     {
00084         if (insertAt==-1 || insertAt>mItemNames.size()-1)
00085             insertAt = mItemNames.size();
00086 
00087         mItemNames.insert(mItemNames.begin()+insertAt,str);
00088         mItemIdxs.insert(mItemIdxs.begin()+insertAt,idx);
00089         mSubMenus.insert(mSubMenus.begin()+insertAt,menu);
00090         mItemOptions.insert(mItemOptions.begin()+insertAt,options);
00091 
00092         HandleLayout();
00093     }
00094 
00095     void HandleLayout()
00096     {
00097         SetDimensions(W(),mItemHeight*mItemNames.size());
00098     }
00099 
00100     void Open(int topX, int topY, int pW=100)
00101     {
00102         mMenuTopPane->Open();
00103         CloseSubMenu();
00104         if (topY-H()<0)
00105             topY = H();
00106         if (topX+W()>GetParent()->W())
00107             topX -= pW+W()-2;
00108         if (topX<0)
00109             topX = 0;
00110         SetDimensions(topX,topY-H(),RETAIN,RETAIN);
00111         SetVisible(true);
00112     }
00113 
00114     void Close()
00115     {
00116         SetVisible(false);
00117         mCurItem = -1;
00118         CloseSubMenu();
00119     }
00120 
00121     void CloseSubMenu()
00122     {
00123         if (!mCurSubMenu)
00124             return;
00125         mCurSubMenu->Close();
00126         mCurSubMenu = 0;
00127     }
00128 
00129 
00130     virtual void InitDisplayFunc()
00131     {
00132         Window::InitDisplayFunc();
00133         OGC myOGC;
00134         OGCSave(&myOGC);
00135         int bInfo[3];
00136         oglSys.StartBlend(bInfo);
00137         SetFillColors(mLeftTopCol,mRightTopCol,mRightBotCol,mLeftBotCol,0);
00138         FillRectangle(0,0,W(),H());
00139         oglSys.EndBlend(bInfo);
00140         OGCRestore(&myOGC);
00141     }
00142 
00143     virtual void DisplayFunc()
00144     {
00145         OGC myOGC;
00146         OGCSave(&myOGC);
00147         for (int i=0; i < mItemNames.size(); i++)
00148             DrawMenuItem(i);
00149         OGCRestore(&myOGC);
00150     }
00151 
00152     virtual void MouseFunc(int msg, int btn, int state, int x, int y)
00153     {
00154         if (msg==oglMouseMove)
00155         {
00156             mCurItem = -1;
00157             if (x>0 && x<W() && y>0 && y<H())
00158                 mCurItem = (H()-y)/mItemHeight;
00159         }
00160 
00161         if (msg==oglMouseDown && IsEnabled(mCurItem) && !IsSubMenu(mCurItem))
00162         {
00163             mMenuTopPane->Hide();
00164             ActivateListener();
00165         }
00166 
00167         if (msg==oglMouseLeave && !mCurSubMenu)
00168             mCurItem=-1;
00169 
00170         CloseSubMenu();
00171 
00172         if (IsEnabled(mCurItem) && IsSubMenu(mCurItem))
00173         {
00174             mCurSubMenu = mSubMenus[mCurItem];
00175             int iY = H()-mCurItem*mItemHeight;
00176             mCurSubMenu->Open(X()+W(),Y()+iY,W());
00177         }
00178     }
00179 
00180     bool IsSubMenu(int arrIdx)
00181     {
00182         if (arrIdx<0 || arrIdx>mSubMenus.size()-1)
00183             return false;
00184         return mSubMenus[arrIdx] != 0;
00185     }
00186 
00187     bool IsEnabled(int arrIdx)      { return !IsOptionOn(arrIdx, DISABLED); }
00188     bool IsChecked(int arrIdx)      { return IsOptionOn(arrIdx, CHECKED); }
00189     bool IsSeparator(int arrIdx)    { return IsOptionOn(arrIdx, SEPARATOR); }
00190 
00191     bool IsOptionOn(int arrIdx, int option)
00192     {
00193         if (arrIdx<0 || arrIdx>mItemOptions.size()-1)
00194             return false;
00195         return (mItemOptions[arrIdx] & option) ? true : false;
00196     }
00197 
00198 protected:
00199 
00200     void ActivateListener()
00201     {
00202         mMenuTopPane->ActivateListener(this,mMenuIdx,
00203                                             mItemNames[mCurItem],
00204                                             mItemIdxs[mCurItem],
00205                                             mListenerData);
00206         if (!mMenuListener)
00207             return;
00208         mMenuListener->OnMenuItem(this,mMenuIdx,
00209                                   mItemNames[mCurItem],
00210                                   mItemIdxs[mCurItem],
00211                                   mListenerData);
00212     }
00213 
00214     void SetArrayIndexOption(int arrIdx, int option, bool mode)
00215     {
00216         if (arrIdx<0 || arrIdx>mItemNames.size()-1)
00217             return;
00218         if (mode)
00219             mItemOptions[arrIdx] |= option;
00220         else
00221             mItemOptions[arrIdx] &= ~option;
00222     }
00223 
00224 
00225     void DrawMenuItem(int idx)
00226     {
00227         int y = H() - (idx+1)*mItemHeight;
00228         if (idx==mCurItem && IsEnabled(idx))
00229         {
00230             SetSolidFillColor(mActiveBg);
00231             FillRectangle(0,y,W(),mItemHeight);
00232             SetSolidLineColor(oglBLACK);
00233             DrawRectangle(0,y,W(),mItemHeight);
00234         }
00235         ULONG color = IsEnabled(idx) ? oglBLACK : oglLIGHTGREY;
00236         oglSys.PosColPrintf(mOglWnd,12,y+4,color,mItemNames[idx].c_str());
00237         if (IsSubMenu(idx))
00238             oglSys.PosColPrintf(mOglWnd,W()-12,y+4,color,">");
00239         if (IsChecked(idx))
00240         {
00241             SetSolidLineColor(oglBLACK);
00242             DrawLine(3,y+8,6,y+5);
00243             DrawLine(5,y+5,11,y+11);
00244         }
00245         if (IsSeparator(idx))
00246         {
00247             SetSolidLineColor(oglLIGHTGREY);
00248             DrawLine(0,y-2,W(),y-2);
00249         }
00250     }
00251 
00252 private:
00253     void Init(MenuTopPane* parent, int menuIdx)
00254     {
00255         mMenuIdx = menuIdx;
00256         mMenuListener = 0;
00257         mListenerData = 0;
00258 
00259         mItemHeight = 20;
00260         mCurItem = -1;
00261         mCurSubMenu = 0;
00262         mMenuTopPane = parent;
00263 
00264         mActiveBg = 0xffb4b4ff;
00265 
00266         mLeftTopCol = mRightTopCol = mRightBotCol = mLeftBotCol = 0xe0ffffff;
00267 
00268         SetAllowScaling(false);
00269         SetVisible(false);
00270         SetBorderType(BEV_ETCHED);
00271         oglSys.SetAllMouseMotion(mOglWnd, 1);
00272     }
00273 
00274     MenuListener*               mMenuListener;
00275     void*                       mListenerData;
00276 
00277     std::vector<std::string>    mItemNames;
00278     std::vector<int>            mItemIdxs;
00279     std::vector<unsigned char>  mItemOptions;
00280     std::vector<Menu*>          mSubMenus;
00281 
00282     MenuTopPane*                mMenuTopPane;
00283     Menu*                       mCurSubMenu;
00284     int                         mCurItem;
00285     int                         mMenuIdx;
00286     int                         mItemHeight;
00287 
00288     ULONG                       mActiveBg;
00289     ULONG                       mLeftTopCol;
00290     ULONG                       mRightTopCol;
00291     ULONG                       mRightBotCol;
00292     ULONG                       mLeftBotCol;
00293 };
00294 
00295 } // Namespace OglGui
00296 #endif
00297 

Generated on Fri Mar 19 09:31:36 2010 for ImpalaSrc by  doxygen 1.5.1