core/vgui/vgui_poly_tableau.h
Go to the documentation of this file.
00001 // This is core/vgui/vgui_poly_tableau.h
00002 #ifndef vgui_poly_tableau_h_
00003 #define vgui_poly_tableau_h_
00004 //:
00005 // \file
00006 // \brief  Tableau which renders its children in sub-rectangles of its viewport.
00007 // \author fsm
00008 //
00009 //  Contains classes vgui_poly_tableau  vgui_poly_tableau_new
00010 //
00011 // \verbatim
00012 //  Modifications
00013 //   01-OCT-2002 K.Y.McGaul - Combined vgui_polytab_base with vgui_polytab.
00014 //                          - Added some Doxygen style comments.
00015 //                          - Moved vgui_polytab to vgui_poly_tableau.
00016 // \endverbatim
00017 
00018 #include <vgui/vgui_gl.h>
00019 #include <vgui/vgui_tableau.h>
00020 #include <vgui/vgui_parent_child_link.h>
00021 
00022 #include "vgui_poly_tableau_sptr.h"
00023 
00024 //: A tableau which renders its children into sub-rectangles of its viewport.
00025 //
00026 // Class poly_tableau is a tableau which renders its children into
00027 // sub-rectangles of its given viewport. The subrectangles are given as
00028 // relative coordinates on [0,1]x[0,1], with (0,0) being the lower left corner
00029 // and (1,1) the upper right corner.
00030 //
00031 // vgui_poly_tableau has a concept of which child is 'current', meaning
00032 // roughly which child is getting the mouse events. It automatically
00033 // switches current child, according to where the pointer is, in a
00034 // sensible way.
00035 //
00036 // vgui_poly_tableau can be used to emulate two adaptors side by side.
00037 //
00038 // Implementation notes:
00039 // Many methods take an argument "GLint const vp[4]", which is the viewport (in
00040 // the format returned by OpenGL) as it was when the last event reached the
00041 // tableau. For example, it is not possible to switch 'current' child without
00042 // knowing the viewport, because a LEAVE/ENTER pair have to be sent to the old
00043 // and new child and the viewport must be set correctly before dispatching these
00044 // events.
00045 
00046 //-----------------------------------------------------------------------------
00047 //: Viewport helper class
00048 //  The constructor takes a snapshot of the current viewport and scissor areas.
00049 //  The destructor restores that state.
00050 class vgui_poly_tableau_vp_sc_snapshot
00051 {
00052  public:
00053   GLint vp[4];
00054   GLint sc[4];
00055   bool sc_was_enabled;
00056 
00057   vgui_poly_tableau_vp_sc_snapshot() {
00058     glGetIntegerv(GL_VIEWPORT, vp);
00059 
00060     glGetIntegerv(GL_SCISSOR_BOX, sc);
00061     sc_was_enabled = glIsEnabled(GL_SCISSOR_TEST) == GL_TRUE;
00062   }
00063 
00064   ~vgui_poly_tableau_vp_sc_snapshot() {
00065     // restore viewport :
00066     glViewport(vp[0], vp[1], vp[2], vp[3]);
00067 
00068     // turn off the scissor test, if it wasn't already on, and
00069     // restore old scissor settings :
00070     if (sc_was_enabled)
00071       glEnable(GL_SCISSOR_TEST);
00072     else
00073       glDisable(GL_SCISSOR_TEST);
00074     glScissor(sc[0], sc[1], sc[2], sc[3]);
00075   }
00076 };
00077 
00078 class vgui_poly_tableau : public vgui_tableau
00079 {
00080  public:
00081   //: Constructor - don't use this, use vgui_poly_tableau_new.
00082   vgui_poly_tableau();
00083 
00084   //: Returns the type of this tableau ('vgui_poly_tableau').
00085   vcl_string type_name() const;
00086 
00087   //: Get popup menu.
00088   void get_popup(vgui_popup_params const &, vgui_menu &);
00089 
00090   //: The position, colour, etc of the child tableau.
00091   struct item
00092   {
00093     vgui_parent_child_link tab;
00094     float x,y,w,h;
00095     int outline_color[3];
00096     int id;
00097 
00098     item() { } // for stl container
00099     item(vgui_tableau* p, vgui_tableau_sptr const&c, float x, float y,
00100          float w, float h, int id =0);
00101     void set_vp(GLint const vp[4]);
00102     //: Returns true if the given position is inside the boundaries of this item
00103     bool inside(GLint const vp[4], int x, int y) const;
00104   };
00105 
00106   typedef vcl_vector<item> container;
00107   typedef container::iterator iterator;
00108   typedef container::const_iterator const_iterator;
00109 
00110   //: Returns the number of items in the list of items.
00111   unsigned size() const { return sub.size(); }
00112 
00113   //: Return an iterator pointing to the first item in the list of items.
00114   iterator begin() { return sub.begin(); }
00115 
00116   //: Return a const iterator pointing to the first item in the list of items.
00117   const_iterator begin() const { return sub.begin(); }
00118 
00119   //: Return an iterator pointing to the last item in the list of items.
00120   iterator end() { return sub.end(); }
00121 
00122   //: Return a const iterator pointing to the last item in the list of items.
00123   const_iterator end() const { return sub.end(); }
00124 
00125   //: Erase the item at the given position from the list of items.
00126   void erase(iterator );
00127 
00128   //: Adds the given tableau to the given proportion of the viewport.
00129   //  x,y,w,h specify a portion of the vgui_poly_tableau's viewport in
00130   //  coordinates which go from 0 to 1.
00131   //  Returns handle to child.
00132   int add(vgui_tableau_sptr const&, float x, float y, float w, float h);
00133 
00134   //: Remove subtableau, referred to by handle.
00135   void remove(int id);
00136 
00137   //: Move subtableau to a new location.
00138   void move(int id, float x, float y, float w, float h);
00139 
00140   //: Replace the tableau with the given ID, with the given tableau.
00141   //  Keep the same ID and do not change the value of 'current'.
00142   void replace(int id, vgui_tableau_sptr const& tab);
00143 
00144   //: Get pointer to tableau from id.
00145   vgui_tableau_sptr get(int id) const;
00146 
00147   //: Set color to outline tableau.
00148   void set_outline_color(const int id, const int r, const int g, const int b);
00149 
00150  protected:
00151   //: Destructor - called by vgui_poly_tableau_sptr.
00152   ~vgui_poly_tableau();
00153 
00154   //: Handle all events sent to this tableau.
00155   //  In particular, use draw events to draw the sub-rectangles.
00156   bool handle(vgui_event const &);
00157 
00158   //; Make sure draw events go to all children in the right order.
00159   bool handle(GLint const vp[4], vgui_event const &e);
00160 
00161   //: Misnomer - returns the index of child under the pointer's position.
00162   int get_active(GLint const vp[4], int wx, int wy) const;
00163 
00164   int get_current() const { return current; }
00165   int get_current_id();
00166   void set_current(GLint const vp[4], int index);
00167 
00168   //: Index of the item currently getting events.
00169   int current;
00170 
00171   //: List of items displayed by this tableau.
00172   vcl_vector<item> sub;
00173 
00174   bool may_switch_child;
00175 };
00176 
00177 
00178 //: Creates a smart-pointer to a vgui_poly_tableau tableau.
00179 struct vgui_poly_tableau_new : public vgui_poly_tableau_sptr
00180 {
00181   typedef vgui_poly_tableau_sptr base;
00182 
00183   //: Constructor - create a smart-pointer to an empty vgui_poly_tableau.
00184   vgui_poly_tableau_new() : base(new vgui_poly_tableau()) { }
00185 };
00186 
00187 #endif // vgui_poly_tableau_h_