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 Window* wnd = this;
00063 while(wnd != 0 && (wnd->GetRunTimeType() & 8))
00064 {
00065 wnd->DisplayFunc();
00066 wnd = wnd->GetParent();
00067 }
00068 }
00069
00070
00071
00072
00073 void RemoveWindow(Window* child, bool destroy=false)
00074 {
00075 for (int i=0; i < (int) mChildWindows.size(); i++)
00076 if (child == mChildWindows[i])
00077 {
00078 mChildWindows.erase(mChildWindows.begin() + i);
00079 if (destroy)
00080 delete child;
00081 HandleLayoutChange();
00082 return;
00083 }
00084 }
00085
00086 void DropDown(bool mode=true)
00087 {
00088 mIsDropped = mode;
00089 if (mPlusMinText)
00090 mPlusMinText->SetText(mIsDropped ? "-" : "+");
00091 HandleLayoutChange();
00092 }
00093
00094 void SetClosedHeight(int h) { mClosedHeight = h; }
00095 bool IsDropped() const { return mIsDropped; }
00096 void ShowLines(bool show=true) { mShowLines = show; }
00097 void LinePattern(short pat) { mLinePattern = pat; }
00098 void Spacing(int nPix) { mSpacing = nPix; }
00099
00100 Window* HeaderWindow() { return mHeaderWindow; }
00101 StaticText* HeaderText() { return mHeaderText; }
00102 StaticText* PlusMinText() { return mPlusMinText; }
00103
00104
00105
00106 virtual void
00107 WindowMouseEvent(Window *src, int msg, int but, int state, int x, int y,
00108 void* listenerData)
00109 {
00110 if (but==oglLeftButton)
00111 {
00112 if ((src == mPlusMinText && msg == oglMouseDown))
00113 DropDown(!mIsDropped);
00114 else if(src != mPlusMinText && msg == oglMouseDblClick)
00115 DropDown(!mIsDropped);
00116 }
00117 }
00118
00119
00120
00121 virtual void
00122 DisplayFunc()
00123 {
00124 OGC myOGC;
00125 int curY = WndHeight();
00126 int nY = curY-mHeaderHeight-2, nW = 0, nH = 0;
00127 int lineX, topLineY = nY;
00128 bool itemLines = (mShowLines && mIsDropped);
00129
00130 mHeaderWindow->SetDimensions(RETAIN, nY, RETAIN, mHeaderHeight);
00131
00132 if (mShowLines)
00133 {
00134 OGCSave(&myOGC);
00135 SetStipple(mLinePattern);
00136 SetSolidLineColor(mForeGroundColor);
00137 lineX = mHeaderWindow->WndX();
00138 DrawLine(lineX, nY+7, 0, nY+7);
00139 lineX += 6;
00140 }
00141
00142 for (int i=0 ; i < (int) mChildWindows.size() ; i++)
00143 {
00144 int cX, cY, cW, cH;
00145 Window* child = mChildWindows[i];
00146
00147 if (!HasTags((TAGABLE*)child->GetOGLWND(), visibleTag))
00148 continue;
00149
00150 child->GetDimensions(cX,cY,cW,cH);
00151
00152 nH += cH + ((i==0) ? 4 : mSpacing);
00153 curY -= cH + ((i==0) ? 4 : mSpacing);
00154
00155 child->SetDimensions(RETAIN, curY, RETAIN, RETAIN);
00156
00157 if ((i>0) && itemLines)
00158 {
00159 if (lineX < cX )
00160 DrawLine(lineX, curY+cH-11, cX-2, curY+cH-11);
00161 if (lineX > cX+cW)
00162 DrawLine(lineX, curY+cH-11, cX+cW+2, curY+cH-11);
00163 nY = curY+cH-9;
00164 }
00165
00166 if ((i<1) || (mIsDropped && (nW < cX+cW)))
00167 nW = cX+cW;
00168 }
00169 if (itemLines)
00170 DrawLine(lineX, nY, lineX, topLineY);
00171
00172 nY = WndY() + WndHeight() - (mIsDropped ? nH : mClosedHeight);
00173 nH = mIsDropped ? nH : mClosedHeight;
00174
00175 SetDimensions(WndX(), nY, nW+2, nH);
00176
00177 if (mShowLines) OGCRestore(&myOGC);
00178
00179 Window::DisplayFunc();
00180 }
00181
00182
00183 private :
00184
00185 Window* mHeaderWindow;
00186 StaticText* mPlusMinText;
00187 StaticText* mHeaderText;
00188 std::vector<Window*> mChildWindows;
00189 bool mShowLines;
00190 short mLinePattern;
00191 bool mIsDropped;
00192 int mHeaderHeight;
00193 int mClosedHeight;
00194 int mSpacing;
00195
00196 void
00197 Init(int w, int h, strconst txt, int options)
00198 {
00199 int hdrX = 2;
00200 int hdrTxtX = 4;
00201 bool plMin = (options & 1) ? true : false;
00202
00203 mRunTimeType |= 8;
00204 mHeaderHeight = 16;
00205 mPlusMinText = 0;
00206 mIsDropped = false;
00207 mShowLines = (options & 2) ? true : false;
00208 mLinePattern = (short) oglDot;
00209 mRunTimeType |= 8;
00210 mSpacing = 2;
00211 mClosedHeight = h;
00212
00213 mHeaderWindow = new Window(this, hdrX, 0, w-hdrX, mHeaderHeight);
00214 mHeaderWindow->SetWindowListener(this);
00215
00216 if (plMin)
00217 {
00218 mPlusMinText = new StaticText(mHeaderWindow, 0, 3, 13, 13, "+");
00219 mPlusMinText->SetBorderType(BEV_LINE);
00220 mPlusMinText->SetDoStateFeedback(true);
00221 mPlusMinText->SetWindowListener(this);
00222 hdrTxtX = 14;
00223 }
00224
00225 mHeaderText = new StaticText(mHeaderWindow, hdrTxtX, 0, w-hdrTxtX-2,
00226 16, txt);
00227 mHeaderText->SetAlign(oglLeftAlign, oglBottomAlign);
00228 mHeaderText->SetNoMouseInput(true);
00229 mHeaderText->SetWindowListener(this);
00230
00231 AddWindow(mHeaderWindow, 0);
00232 DropDown(false);
00233 }
00234 };
00235
00236 }
00237
00238 #endif // DropDownWindow_h