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

DropDownWindow.h

Go to the documentation of this file.
00001 #ifndef OglGui_DropDownWindow_h
00002 #define OglGui_DropDownWindow_h
00003 
00004 // RvB: Note: I could have used the WndAdded function of Window
00005 // but then an outsider could not provide for an animated background.
00006 // Therefore chosen for AddWnd when an item wants to be known to the
00007 // DropDownWindow.
00008 // Also note: Deliberately chosen for very loose layout rules allowing
00009 // the items inside maximum flexibility.
00010 //
00011 // Maybe I should create the header in a virtual function.
00012 // That way others could provide for alternative headers.
00013 // I could even have a final argument in the constructor with a
00014 // header creator function pointer that defaults to 0
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     // Must be called when a child window has been deleted
00074     // from the DropDownWindow.
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 // Listeners
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 // Overloaded standard OGL functions
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; // Allowing for partially opened in closed state
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 } // namespace OglGui
00243 
00244 #endif // DropDownWindow_h

Generated on Thu Jan 13 09:04:50 2011 for ImpalaSrc by  doxygen 1.5.1