00001 // This is core/vgui/vgui_grid_tableau.h 00002 #ifndef vgui_grid_tableau_h_ 00003 #define vgui_grid_tableau_h_ 00004 //: 00005 // \file 00006 // \author K.Y.McGaul 00007 // \brief A tableau which renders its child tableaux as a rectangular grid. 00008 // 00009 // Contains classes: vgui_grid_tableau vgui_grid_tableau_data 00010 // 00011 // \verbatim 00012 // Modifications 00013 // K.Y.McGaul 20-JAN-2000 Initial version. 00014 // K.Y.McGaul 11-FEB-2000 Added a clear_tableau to the empty grid positions. 00015 // K.Y.McGaul 21-FEB-2002 Added comments and documentation. 00016 // \endverbatim 00017 00018 #include <vcl_vector.h> 00019 #include <vbl/vbl_array_2d.h> 00020 #include "vgui_grid_tableau_sptr.h" 00021 #include <vgui/vgui_poly_tableau.h> 00022 #include <vgui/vgui_event_condition.h> 00023 00024 //: Data required by each rectangle in the grid of vgui_grid_tableau. 00025 struct vgui_grid_tableau_data 00026 { 00027 //: Handle returned by poly_tableau. 00028 int handle; 00029 //: Position of our tableau in the array of tableaux (`tabs') 00030 int tab_pos; 00031 //: True if this is a default tableau (not set by the user) 00032 bool is_default; 00033 //: Time last left clicked on (-1 if not selected) 00034 int time_selected; 00035 }; 00036 00037 bool operator==(vgui_grid_tableau_data const &a, 00038 vgui_grid_tableau_data const &b); 00039 00040 //: A tableau which renders its child tableaux as a rectangular grid. 00041 // 00042 // It is derived from vgui_poly_tableau but unlike vgui_poly_tableau, the 00043 // child tableaux of vgui_grid_tableau can only be laid out in an m by n 00044 // rectangular grid. Rows and columns are numbered starting from 0 with 00045 // (0,0) in the top left and (m-1,n-1) in the bottom right. 00046 // 00047 // The default behaviour of vgui_grid is to keep a list of every tableau 00048 // added to the grid (using add_next to add to the next free position 00049 // or add_at to add at a specific grid position). Users can flip through 00050 // this list of tableaux, 'tabs', by clicking in the grid position they 00051 // wish to change, and using PageUp and PageDown to go through the list. 00052 // When a new tableau is added using add_at the old tableau at that position 00053 // is kept in the 'tabs' list and can still be viewed by using PageUp and 00054 // PageDown. Each grid position provides a view of the deck of tableaux kept 00055 // in 'tabs'. A tableau will only be removed from 'tabs' by using remove_at. 00056 // 00057 // By default, the user can make the grid larger or smaller by using 00058 // (CTRL) + and - to add and remove (rows and) columns. 00059 // 00060 // These default behaviours can be changed using set_uses_paging_events and 00061 // set_grid_size_changeable. This stops vgui_grid using the events, but 00062 // still passes them down to the child tableaux. By disabling PageUp and 00063 // PageDown you can prevent users from changing the displayed tableau - this 00064 // could also be useful if you want to show two vgui_deck tableau and so want 00065 // the PageUp and PageDown events to pass through vgui_grid and be used by the 00066 // child decks. Disabling plus and minus events gives a grid tableau of fixed 00067 // size. 00068 // 00069 // This tableau was originally written for xcv, so look at this application 00070 // to get a better idea what it does. 00071 class vgui_grid_tableau : public vgui_poly_tableau 00072 { 00073 public: 00074 typedef vgui_grid_tableau_data grid_data; 00075 00076 //: Returns the type name of the tableau ("vgui_grid_tableau" in this case). 00077 vcl_string type_name() const { return "vgui_grid_tableau"; } 00078 00079 //: Constructor - don't use this, use vgui_grid_tableau_new. 00080 // Takes the initial number of columns and rows. 00081 vgui_grid_tableau(unsigned initial_columns = 1, unsigned initial_rows = 1) 00082 { init(initial_columns, initial_rows); } 00083 00084 //: Constructor - don't use this, use vgui_grid_tableau_new. 00085 // This creates a bi-tab, taking the two tableaux as parameters. 00086 vgui_grid_tableau(vgui_tableau_sptr const& l, vgui_tableau_sptr const& r); 00087 00088 //: Constructor - don't use this, use vgui_grid_tableau_new. 00089 // This creates a tri-tab, taking the three tableau as parameters. 00090 vgui_grid_tableau(vgui_tableau_sptr const& l, vgui_tableau_sptr const& m, 00091 vgui_tableau_sptr const& r); 00092 00093 //: Given the column number, returns the x coord for that column. 00094 float get_x(unsigned index); 00095 00096 //: Given the row number, returns the y coord for that row. 00097 float get_y(unsigned index); 00098 00099 //: Get the width of each column. 00100 float get_w(); 00101 00102 //: Get the height of each row. 00103 float get_h(); 00104 00105 //: Adds a tableau to the next free space in the grid and the list of tableaux 00106 void add_next(vgui_tableau_sptr const& tab); 00107 00108 //: Adds a tableau to the next free space and returns the grid location 00109 void add_next(vgui_tableau_sptr const& tab, unsigned& col, unsigned& row); 00110 00111 //: Add (or replace the tableau at the given position with) the given tableau. 00112 void add_at(vgui_tableau_sptr const& tab, unsigned col_pos, unsigned row_pos); 00113 00114 //: Removes the tableau at the given grid coordinates from the display 00115 void remove_at(unsigned col_pos, unsigned row_pos); 00116 00117 //: Returns the number of rows in the grid. 00118 unsigned rows() const { return nb_rows; } 00119 00120 //: Returns the number of columns in the grid. 00121 unsigned cols() const { return nb_cols; } 00122 00123 //: Returns a pointer to the tableau at the given position. 00124 vgui_tableau_sptr get_tableau_at(unsigned col_pos, unsigned row_pos); 00125 00126 //: Returns the list of tableaux. 00127 vcl_vector<vgui_tableau_sptr> get_tableau_list() { return tabs; } 00128 00129 //: Returns the active tableau, this is the tableau with the mouse in. 00130 void get_active_position(unsigned* col_pos, unsigned* row_pos); 00131 00132 //: Returns the most recently selected column and row positions. 00133 void get_last_selected_position(unsigned* col_pos, unsigned* row_pos); 00134 00135 //: Gets the positions and times of selection of the selected tableaux. 00136 int get_selected_positions(vcl_vector<int>* col_pos, vcl_vector<int>* row_pos, 00137 vcl_vector<int>* times); 00138 00139 //: Select a certain tableau 00140 void set_selected(int r, int c, bool onoff = true); 00141 00142 //: True to allow the grid size to change, false to have fixed size. 00143 void set_grid_size_changeable(bool v) { 00144 cond_row_add .enable(v); 00145 cond_row_remove.enable(v); 00146 cond_col_add .enable(v); 00147 cond_col_remove.enable(v); 00148 grid_size_changeable = v; 00149 } 00150 00151 //: True to use paging events, false to ignore them. 00152 void set_uses_paging_events(bool v) { 00153 cond_flip_fwd.enable(v); 00154 cond_flip_bwd.enable(v); 00155 } 00156 00157 //: True to use mouse down events, false to ignore them. 00158 void set_frames_selectable(bool v) { 00159 cond_select .enable(v); 00160 cond_deselect.enable(v); 00161 } 00162 00163 //: Only allow one grid cell to be selected at a time, others are deselected 00164 void set_unique_selected(bool u) {unique_selected_ = u;} 00165 00166 //: Use this to emulate the deprecated bitab and tritab: 00167 void emulate_ntab() { 00168 set_grid_size_changeable(false); 00169 set_uses_paging_events(false); 00170 set_frames_selectable(false); 00171 } 00172 00173 //: Redraw the grid keeping each tableau in its current row and column. 00174 void layout_grid(); 00175 00176 //: Redraw the grid of tableaux packing them in without gaps. 00177 // Fill each row from top left downwards. 00178 void layout_grid2(); 00179 00180 //: Add an empty column to the RHS of the grid. 00181 void add_column(); 00182 00183 //: Remove last column on RHS of the grid. 00184 void remove_column(); 00185 00186 //: Add an empty row to the bottom of the grid. 00187 void add_row(); 00188 00189 //: Remove last row on the bottom of the grid 00190 void remove_row(); 00191 00192 //: Flip forwards through the list of tableaux. 00193 void page_up(); 00194 00195 //: Flip backwards through the list of tableaux. 00196 void page_down(); 00197 00198 //: Handle any events matching the {vgui_event_condition}s. 00199 bool handle(const vgui_event&); 00200 00201 //: Window coordinates of the cell bounding box at col, row 00202 bool cell_bounding_box(unsigned col, unsigned row, 00203 float& xmin, float& ymin, float& xmax, float& ymax); 00204 00205 protected: 00206 //: Destructor - called by vgui_grid_tableau_sptr. 00207 ~vgui_grid_tableau() {} 00208 00209 private: 00210 // The number of rows and columns can be changed. 00211 vgui_event_condition cond_row_add; // CTRL = 00212 vgui_event_condition cond_row_remove; // CTRL - 00213 vgui_event_condition cond_col_add; // = 00214 vgui_event_condition cond_col_remove; // - 00215 00216 // One can flip through the list of tableaux. 00217 vgui_event_condition cond_flip_fwd; // PGUP 00218 vgui_event_condition cond_flip_bwd; // PGDN 00219 00220 // Frames can be selected and deselected. 00221 vgui_event_condition cond_select; // left mouse button 00222 vgui_event_condition cond_deselect; // middle mouse button 00223 00224 int INCREMENT_COLS; // Amount to increase the number of columns 00225 int INCREMENT_ROWS; // Amount to increase the number of rows. 00226 00227 bool grid_size_changeable; // Whether the grid size is allowed to change. 00228 00229 unsigned nb_cols; 00230 unsigned max_cols; 00231 unsigned nb_rows; 00232 unsigned max_rows; 00233 unsigned last_selected[2]; // stores col_pos, row_pos of last selected tableau 00234 bool unique_selected_; 00235 vgui_tableau_sptr default_tab; 00236 00237 vcl_vector<vgui_tableau_sptr> tabs; 00238 vbl_array_2d<grid_data> grid_pos; 00239 00240 //: Initialisation called by all constructors. 00241 void init(unsigned initial_cols, unsigned initial_rows); 00242 00243 //: Adds the default tableau to the given space in the grid. 00244 // (but not to the vcl_list of tableaux). 00245 void add_default(unsigned col_pos, unsigned row_pos); 00246 00247 //: Make the current tableau selected by saving the current time. 00248 void select_current(int time); 00249 00250 //: Mark the current table as deselected by setting the time to -1. 00251 void deselect_current(); 00252 }; 00253 00254 //: Create a smart pointer to a vgui_grid_tableau. 00255 struct vgui_grid_tableau_new : public vgui_grid_tableau_sptr { 00256 typedef vgui_grid_tableau_sptr base; 00257 vgui_grid_tableau_new(unsigned initial_columns = 1, unsigned initial_rows = 1) 00258 : base(new vgui_grid_tableau(initial_columns,initial_rows)) {} 00259 vgui_grid_tableau_new(vgui_tableau_sptr const& l, vgui_tableau_sptr const& r) 00260 : base(new vgui_grid_tableau(l, r)) {} 00261 vgui_grid_tableau_new(vgui_tableau_sptr const& l, vgui_tableau_sptr const& m, 00262 vgui_tableau_sptr const& r) 00263 : base(new vgui_grid_tableau(l, m, r)) {} 00264 }; 00265 00266 #endif // vgui_grid_tableau_h_