00001 #ifndef OglGui_DropDownWindow_h
00002 #define OglGui_DropDownWindow_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef OglGui_StaticText_h
00017 #include "OglGui/StaticText.h"
00018 #endif
00019
00020 namespace OglGui
00021 {
00022
00023 class DropDownWindow : public Window, WindowListener
00024 {
00025 public:
00026
00027 DropDownWindow(Window* parent, int width, int height,
00028 strconst txt, int options=PlusMinus+Lines) :
00029 Window(parent, width, height)
00030 {
00031 Init(width, height, txt, options);
00032 }
00033
00034 DropDownWindow(Window* parent, int x, int y, int width, int height,
00035 strconst txt, int options=PlusMinus+Lines) :
00036 Window(parent, x, y, width, height)
00037 {
00038 Init(width, height, txt, options);
00039 }
00040
00041 enum DDOPTIONS {
00042 PlusMinus = 1,
00043 Lines = 2,
00044 };
00045
00046 void AddWindow(Window* child, int inset=20, int insertAt=-1)
00047 {
00048 int x,y,w,h;
00049
00050 if (insertAt==-1 || insertAt > (int) mChildWindows.size()-1)
00051 mChildWindows.push_back(child);
00052 else
00053 mChildWindows.insert(mChildWindows.begin()+insertAt+1,child);
00054 child->SetAllowReposition(false);
00055 child->GetDimensions(x,y,w,h);
00056 child->SetDimensions(x+inset,y,w,h);
00057 HandleLayoutChange();
00058 }
00059
00060 void HandleLayoutChange()
00061 {
00062 if(!mInitialized)
00063 return;
00064 Window* wnd = this;
00065 while(wnd != 0 && (wnd->GetRunTimeType() & 8))
00066 {
00067 wnd->DisplayFunc();
00068 wnd = wnd->GetParent();
00069 }
00070 }
00071
00072
00073
00074
00075 void RemoveWindow(Window* child, bool destroy=false)
00076 {
00077 for (int i=0; i < (int) mChildWindows.size(); i++)
00078 if (child == mChildWindows[i])
00079 {
00080 mChildWindows.erase(mChildWindows.begin() + i);
00081 if (destroy)
00082 delete child;
00083 HandleLayoutChange();
00084 return;
00085 }
00086 }
00087
00088 void DropDown(bool mode=true)
00089 {
00090 mIsDropped = mode;
00091 if (mPlusMinText)
00092 mPlusMinText->SetText(mIsDropped ? "-" : "+");
00093 HandleLayoutChange();
00094 }
00095
00096 void SetClosedHeight(int h) { mClosedHeight = h; }
00097 bool IsDropped() const { return mIsDropped; }
00098 void ShowLines(bool show=true) { mShowLines = show; }
00099 void LinePattern(short pat) { mLinePattern = pat; }
00100 void Spacing(int nPix) { mSpacing = nPix; }
00101
00102 Window* HeaderWindow() { return mHeaderWindow; }
00103 StaticText* HeaderText() { return mHeaderText; }
00104 StaticText* PlusMinText() { return mPlusMinText; }
00105
00106
00107
00108 virtual void
00109 WindowMouseEvent(Window *src, int msg, int but, int state, int x, int y,
00110 void* listenerData)
00111 {
00112 if (but==oglLeftButton)
00113 {
00114 if ((src == mPlusMinText && msg == oglMouseDown))
00115 DropDown(!mIsDropped);
00116 else if(src != mPlusMinText && msg == oglMouseDblClick)
00117 DropDown(!mIsDropped);
00118 }
00119 }
00120
00121
00122
00123 virtual void
00124 DisplayFunc()
00125 {
00126 OGC myOGC;
00127 int curY = WndHeight();
00128 int nY = curY-mHeaderHeight-2, nW = 0, nH = 0;
00129 int lineX, topLineY = nY;
00130 bool itemLines = (mShowLines && mIsDropped);
00131
00132 mInitialized = true;
00133
00134 mHeaderWindow->SetDimensions(RETAIN, nY, RETAIN, mHeaderHeight);
00135
00136 if (mShowLines)
00137 {
00138 OGCSave(&myOGC);
00139 SetStipple(mLinePattern);
00140 SetSolidLineColor(mForeGroundColor);
00141 lineX = mHeaderWindow->WndX();
00142 DrawLine(lineX, nY+7, 0, nY+7);
00143 lineX += 6;
00144 }
00145
00146 for (int i=0 ; i < (int) mChildWindows.size() ; i++)
00147 {
00148 int cX, cY, cW, cH;
00149 Window* child = mChildWindows[i];
00150
00151 if (!HasTags((TAGABLE*)child->GetOGLWND(), visibleTag))
00152 continue;
00153
00154 child->GetDimensions(cX,cY,cW,cH);
00155
00156 nH += cH + ((i==0) ? 4 : mSpacing);
00157 curY -= cH + ((i==0) ? 4 : mSpacing);
00158
00159 child->SetDimensions(RETAIN, curY, RETAIN, RETAIN);
00160
00161 if ((i>0) && itemLines)
00162 {
00163 if (lineX < cX )
00164 DrawLine(lineX, curY+cH-11, cX-2, curY+cH-11);
00165 if (lineX > cX+cW)
00166 DrawLine(lineX, curY+cH-11, cX+cW+2, curY+cH-11);
00167 nY = curY+cH-9;
00168 }
00169
00170 if ((i<1) || (mIsDropped && (nW < cX+cW)))
00171 nW = cX+cW;
00172 }
00173 if (itemLines)
00174 DrawLine(lineX, nY, lineX, topLineY);
00175
00176 nY = WndY() + WndHeight() - (mIsDropped ? nH : mClosedHeight);
00177 nH = mIsDropped ? nH : mClosedHeight;
00178
00179 SetDimensions(WndX(), nY, nW+2, nH);
00180
00181 if (mShowLines) OGCRestore(&myOGC);
00182
00183 Window::DisplayFunc();
00184 }
00185
00186
00187 private :
00188
00189 Window* mHeaderWindow;
00190 StaticText* mPlusMinText;
00191 StaticText* mHeaderText;
00192 std::vector<Window*> mChildWindows;
00193 bool mShowLines;
00194 short mLinePattern;
00195 bool mIsDropped;
00196 int mHeaderHeight;
00197 int mClosedHeight;
00198 int mSpacing;
00199 bool mInitialized;
00200
00201 void
00202 Init(int w, int h, strconst txt, int options)
00203 {
00204 int hdrX = 2;
00205 int hdrTxtX = 4;
00206 bool plMin = (options & 1) ? true : false;
00207
00208 mRunTimeType |= 8;
00209 mHeaderHeight = 16;
00210 mPlusMinText = 0;
00211 mIsDropped = false;
00212 mShowLines = (options & 2) ? true : false;
00213 mLinePattern = (short) oglDot;
00214 mRunTimeType |= 8;
00215 mSpacing = 2;
00216 mClosedHeight = h;
00217 mInitialized = false;
00218
00219 mHeaderWindow = new Window(this, hdrX, 0, w-hdrX, mHeaderHeight);
00220 mHeaderWindow->SetWindowListener(this);
00221
00222 if (plMin)
00223 {
00224 mPlusMinText = new StaticText(mHeaderWindow, 0, 3, 13, 13, "+");
00225 mPlusMinText->SetBorderType(BEV_LINE);
00226 mPlusMinText->SetDoStateFeedback(true);
00227 mPlusMinText->SetWindowListener(this);
00228 hdrTxtX = 14;
00229 }
00230
00231 mHeaderText = new StaticText(mHeaderWindow, hdrTxtX, 0, w-hdrTxtX-2,
00232 16, txt);
00233 mHeaderText->SetAlign(oglLeftAlign, oglBottomAlign);
00234 mHeaderText->SetNoMouseInput(true);
00235 mHeaderText->SetWindowListener(this);
00236
00237 AddWindow(mHeaderWindow, 0);
00238 DropDown(false);
00239 }
00240 };
00241
00242 }
00243
00244 #endif // DropDownWindow_h