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_