00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _FL_TABLE_H
00030 #define _FL_TABLE_H
00031
00032 #include <corelib/ncbistd.hpp>
00033 #include <gui/gui_export.h>
00034
00035 #include <sys/types.h>
00036 #include <string.h>
00037 #ifdef _WIN32
00038 #include <malloc.h>
00039 #else
00040 #include <stdlib.h>
00041 #endif
00042
00043 #include <FL/Fl.H>
00044 #include <FL/Fl_Group.H>
00045 #include <FL/Fl_Scroll.H>
00046 #include <FL/Fl_Box.H>
00047 #include <FL/Fl_Scrollbar.H>
00048
00049 class Fl_Table : public Fl_Group
00050 {
00051 public:
00052 enum TableContext
00053 {
00054 CONTEXT_NONE = 0,
00055 CONTEXT_STARTPAGE = 0x01,
00056 CONTEXT_ENDPAGE = 0x02,
00057 CONTEXT_ROW_HEADER = 0x04,
00058 CONTEXT_COL_HEADER = 0x08,
00059 CONTEXT_CELL = 0x10,
00060 CONTEXT_TABLE = 0x20,
00061 CONTEXT_RC_RESIZE = 0x40
00062 };
00063
00064 private:
00065 int _rows, _cols,
00066 _row_header_w,
00067 _col_header_h,
00068 _row_position,
00069 _col_position;
00070
00071 char _row_header,
00072 _col_header,
00073 _row_resize,
00074 _col_resize;
00075 int
00076 _row_resize_min,
00077 _col_resize_min;
00078
00079
00080 int _redraw_toprow, _redraw_botrow,
00081 _redraw_leftcol, _redraw_rightcol;
00082
00083 Fl_Color _row_header_color,
00084 _col_header_color;
00085
00086 int _auto_drag;
00087 int _selecting;
00088
00089
00090 class IntVector
00091 {
00092 int *arr;
00093 unsigned int _size;
00094 void init()
00095 { arr = NULL; _size = 0; }
00096 void copy(int *newarr, unsigned int newsize)
00097 { size(newsize); memcpy(arr, newarr, newsize * sizeof(int)); }
00098 public:
00099 IntVector() { init(); }
00100 ~IntVector() { if ( arr ) free(arr); arr = NULL; }
00101 IntVector(IntVector&o) { init(); copy(o.arr, o._size); }
00102 IntVector& operator=(IntVector&o)
00103 { init(); copy(o.arr, o._size); return(*this); }
00104 int operator[](int x) const { return(arr[x]); }
00105 int& operator[](int x) { return(arr[x]); }
00106 unsigned int size() { return(_size); }
00107 void size(unsigned int count)
00108 {
00109 if ( count != _size )
00110 { arr = (int*)realloc(arr, count * sizeof(int)); _size = count; }
00111 }
00112 int pop_back() { int tmp = arr[_size-1]; _size--; return(tmp); }
00113 void push_back(int val) { unsigned int x = _size; size(_size+1); arr[x] = val; }
00114 int back() { return(arr[_size-1]); }
00115 };
00116
00117 IntVector
00118 _colwidths,
00119 _rowheights;
00120
00121 Fl_Cursor _last_cursor;
00122
00123
00124 TableContext _callback_context;
00125 int _callback_row, _callback_col;
00126
00127
00128
00129
00130
00131 int _resizing_col,
00132 _resizing_row,
00133 _dragging_x,
00134 _dragging_y,
00135 _last_row;
00136
00137
00138 void _redraw_cell(TableContext context, int R, int C);
00139
00140 void _start_auto_drag();
00141 void _stop_auto_drag();
00142 void _auto_drag_cb();
00143 static void _auto_drag_cb2(void *d);
00144
00145
00146 protected:
00147 enum ResizeFlag
00148 {
00149 RESIZE_NONE = 0,
00150 RESIZE_COL_LEFT = 1,
00151 RESIZE_COL_RIGHT = 2,
00152 RESIZE_ROW_ABOVE = 3,
00153 RESIZE_ROW_BELOW = 4
00154 };
00155
00156 int table_w, table_h;
00157 int toprow, botrow,
00158 leftcol, rightcol;
00159
00160
00161 int current_row, current_col;
00162 int select_row, select_col;
00163
00164
00165 int toprow_scrollpos,
00166 leftcol_scrollpos;
00167
00168
00169 int tix, tiy, tiw, tih,
00170 tox, toy, tow, toh,
00171 wix, wiy, wiw, wih;
00172
00173 Fl_Scroll *table;
00174 Fl_Scrollbar *vscrollbar,
00175 *hscrollbar;
00176
00177
00178 int handle(int e);
00179
00180
00181 void recalc_dimensions();
00182 void table_resized();
00183 void table_scrolled();
00184 void get_bounds(TableContext context,
00185 int &X, int &Y, int &W, int &H);
00186 void change_cursor(Fl_Cursor newcursor);
00187 TableContext cursor2rowcol(int &R, int &C, ResizeFlag &resizeflag);
00188
00189 int find_cell(TableContext context,
00190 int R, int C, int &X, int &Y, int &W, int &H);
00191 int row_col_clamp(TableContext context, int &R, int &C);
00192
00193
00194
00195 virtual void draw_cell(TableContext context, int R=0, int C=0,
00196 int X=0, int Y=0, int W=0, int H=0)
00197 { }
00198
00199 long row_scroll_position(int row);
00200 long col_scroll_position(int col);
00201
00202 int is_fltk_container()
00203 { return( Fl_Group::children() > 3 ); }
00204
00205 static void scroll_cb(Fl_Widget*,void*);
00206
00207 void damage_zone(int r1, int c1, int r2, int c2, int r3 = 0, int c3 = 0);
00208
00209 void redraw_range(int toprow, int botrow, int leftcol, int rightcol)
00210 {
00211 if ( _redraw_toprow == -1 )
00212 {
00213
00214 _redraw_toprow = toprow;
00215 _redraw_botrow = botrow;
00216 _redraw_leftcol = leftcol;
00217 _redraw_rightcol = rightcol;
00218 }
00219 else
00220 {
00221
00222 if ( toprow < _redraw_toprow ) _redraw_toprow = toprow;
00223 if ( botrow > _redraw_botrow ) _redraw_botrow = botrow;
00224 if ( leftcol < _redraw_leftcol ) _redraw_leftcol = leftcol;
00225 if ( rightcol > _redraw_rightcol ) _redraw_rightcol = rightcol;
00226 }
00227
00228
00229 damage(FL_DAMAGE_CHILD);
00230 }
00231
00232 public:
00233 Fl_Table(int X, int Y, int W, int H, const char *l=0);
00234 ~Fl_Table();
00235
00236 virtual void clear() { rows(0); cols(0); }
00237
00238
00239
00240
00241
00242 inline void table_box(Fl_Boxtype val) { table->box(val); table_resized(); }
00243 inline Fl_Boxtype table_box( void ) { return(table->box()); }
00244
00245 virtual void rows(int val);
00246 inline int rows() const
00247 { return(_rows); }
00248
00249 virtual void cols(int val);
00250 inline int cols() const
00251 { return(_cols); }
00252
00253 inline void visible_cells(int& r1, int& r2, int& c1, int& c2)
00254 { r1 = toprow; r2 = botrow; c1 = leftcol; c2 = rightcol; }
00255
00256
00257 int is_interactive_resize()
00258 { return(_resizing_row != -1 || _resizing_col != -1); }
00259
00260 inline int row_resize()
00261 { return(_row_resize); }
00262 void row_resize(int flag)
00263 { _row_resize = flag; }
00264
00265 inline int col_resize()
00266 { return(_col_resize); }
00267 void col_resize(int flag)
00268 { _col_resize = flag; }
00269
00270 inline int col_resize_min()
00271 { return(_col_resize_min); }
00272 void col_resize_min(int val)
00273 { _col_resize_min = ( val < 1 ) ? 1 : val; }
00274
00275 inline int row_resize_min()
00276 { return(_row_resize_min); }
00277 void row_resize_min(int val)
00278 { _row_resize_min = ( val < 1 ) ? 1 : val; }
00279
00280 inline int row_header()
00281 { return(_row_header); }
00282 void row_header(int flag)
00283 { _row_header = flag; table_resized(); redraw(); }
00284
00285 inline int col_header()
00286 { return(_col_header); }
00287 void col_header(int flag)
00288 { _col_header = flag; table_resized(); redraw(); }
00289
00290 inline void col_header_height(int height)
00291 { _col_header_h = height; table_resized(); redraw(); }
00292 inline int col_header_height()
00293 { return(_col_header_h); }
00294
00295 inline void row_header_width(int width)
00296 { _row_header_w = width; table_resized(); redraw(); }
00297 inline int row_header_width()
00298 { return(_row_header_w); }
00299
00300 inline void row_header_color(Fl_Color val)
00301 { _row_header_color = val; redraw(); }
00302 inline Fl_Color row_header_color()
00303 { return(_row_header_color); }
00304
00305 inline void col_header_color(Fl_Color val)
00306 { _col_header_color = val; redraw(); }
00307 inline Fl_Color col_header_color()
00308 { return(_col_header_color); }
00309
00310 void row_height(const int* row_ht_arr, int size, int start = 0);
00311 void row_height(int row, int height);
00312 inline int row_height(int row)
00313 { return((row<0 || row>=(int)_rowheights.size()) ? 0 : _rowheights[row]); }
00314
00315 void col_width(int col, int width);
00316 inline int col_width(int col)
00317 { return((col<0 || col>=(int)_colwidths.size()) ? 0 : _colwidths[col]); }
00318
00319 void row_height_all(int height)
00320 { for ( int r=0; r<rows(); r++ ) row_height(r, height); }
00321 void col_width_all(int width)
00322 { for ( int c=0; c<cols(); c++ ) col_width(c, width); }
00323
00324 void row_position(int row);
00325 void col_position(int col);
00326 int row_position()
00327 { return(_row_position); }
00328 int col_position()
00329 { return(_col_position); }
00330
00331 inline void top_row(int row)
00332 { row_position(row); }
00333 inline int top_row()
00334 { return(row_position()); }
00335
00336 int is_selected(int r, int c);
00337 void get_selection(int& s_top, int& s_left, int& s_bottom, int& s_right);
00338 void set_selection(int s_top, int s_left, int s_bottom, int s_right);
00339 int move_cursor(int R, int C);
00340
00341 void resize(int X, int Y, int W, int H);
00342 void draw(void);
00343
00344
00345 void init_sizes() { table->init_sizes(); table->redraw(); }
00346 void add(Fl_Widget& w) { table->add(w); }
00347 void add(Fl_Widget* w) { table->add(w); }
00348 void insert(Fl_Widget& w, int n) { table->insert(w,n); }
00349 void insert(Fl_Widget& w, Fl_Widget* w2) { table->insert(w,w2); }
00350 void remove(Fl_Widget& w) { table->remove(w); }
00351 void begin() { table->begin(); }
00352 void end()
00353 {
00354 table->end();
00355
00356
00357
00358
00359 if ( table->children() > 2 ) { table->show(); }
00360 else { table->hide(); }
00361
00362 Fl_Group::current((Fl_Group*)(Fl_Group::parent()));
00363 }
00364 Fl_Widget * const *array()
00365 { return(table->array()); }
00366 Fl_Widget *child(int n) const
00367 { return(table->child(n)); }
00368 int children() const
00369 { return(table->children()-2); }
00370 int find(const Fl_Widget *w) const
00371 { return(table->find(w)); }
00372 int find(const Fl_Widget &w) const
00373 { return(table->find(w)); }
00374
00375
00376 int callback_row() { return(_callback_row); }
00377 int callback_col() { return(_callback_col); }
00378 TableContext callback_context() { return(_callback_context); }
00379 void do_callback(TableContext context, int row, int col)
00380 {
00381 _callback_context = context;
00382 _callback_row = row;
00383 _callback_col = col;
00384 Fl_Widget::do_callback();
00385 }
00386 };
00387
00388
00389 #endif
00390
00391