00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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 }
00296 #endif
00297