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 __EDELIB_TABLEBASE_H__
00030 #define __EDELIB_TABLEBASE_H__
00031
00032 #include "edelib-global.h"
00033
00034 #include <sys/types.h>
00035 #include <string.h>
00036
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 EDELIB_NS_BEGIN
00050
00166 class EDELIB_API TableBase : public Fl_Group {
00167 public:
00172 enum TableContext {
00173 CONTEXT_NONE = 0,
00174 CONTEXT_STARTPAGE = 0x01,
00175 CONTEXT_ENDPAGE = 0x02,
00176 CONTEXT_ROW_HEADER = 0x04,
00177 CONTEXT_COL_HEADER = 0x08,
00178 CONTEXT_CELL = 0x10,
00179 CONTEXT_TABLE = 0x20,
00180 CONTEXT_RC_RESIZE = 0x40
00181 };
00182
00183 private:
00184 int _rows, _cols,
00185 _row_header_w,
00186 _col_header_h,
00187 _row_position,
00188 _col_position;
00189
00190 char _row_header,
00191 _col_header,
00192 _row_resize,
00193 _col_resize;
00194 int
00195 _row_resize_min,
00196 _col_resize_min;
00197
00198
00199 int _redraw_toprow, _redraw_botrow,
00200 _redraw_leftcol, _redraw_rightcol;
00201
00202 Fl_Color _row_header_color,
00203 _col_header_color;
00204
00205 int _auto_drag;
00206 int _selecting;
00207
00208
00209 class IntVector {
00210 private:
00211 int *arr;
00212 unsigned int _size;
00213
00214 void init() { arr = NULL; _size = 0; }
00215 void copy(int *newarr, unsigned int newsize) { size(newsize); memcpy(arr, newarr, newsize * sizeof(int)); }
00216 public:
00217 IntVector() { init(); }
00218 ~IntVector() { if ( arr ) free(arr); arr = NULL; }
00219 IntVector(IntVector&o) { init(); copy(o.arr, o._size); }
00220 IntVector& operator=(IntVector&o) { init(); copy(o.arr, o._size); return(*this); }
00221 int operator[](int x) const { return(arr[x]); }
00222 int& operator[](int x) { return(arr[x]); }
00223 unsigned int size() { return(_size); }
00224 void size(unsigned int count) {
00225 if ( count != _size )
00226 { arr = (int*)realloc(arr, count * sizeof(int)); _size = count; }
00227 }
00228 int pop_back() { int tmp = arr[_size-1]; _size--; return(tmp); }
00229 void push_back(int val) { unsigned int x = _size; size(_size+1); arr[x] = val; }
00230 int back() { return(arr[_size-1]); }
00231 };
00232
00233 IntVector
00234 _colwidths,
00235 _rowheights;
00236
00237 Fl_Cursor _last_cursor;
00238
00239
00240 TableContext _callback_context;
00241 int _callback_row, _callback_col;
00242
00243
00244
00245
00246
00247 int _resizing_col,
00248 _resizing_row,
00249 _dragging_x,
00250 _dragging_y,
00251 _last_row;
00252
00253
00254 void _redraw_cell(TableContext context, int R, int C);
00255
00256 void _start_auto_drag();
00257 void _stop_auto_drag();
00258 void _auto_drag_cb();
00259 static void _auto_drag_cb2(void *d);
00260
00261
00262 protected:
00263 #ifndef SKIP_DOCS
00264 enum ResizeFlag {
00265 RESIZE_NONE = 0,
00266 RESIZE_COL_LEFT = 1,
00267 RESIZE_COL_RIGHT = 2,
00268 RESIZE_ROW_ABOVE = 3,
00269 RESIZE_ROW_BELOW = 4
00270 };
00271
00272 int table_w, table_h;
00273 int toprow, botrow,
00274 leftcol, rightcol;
00275
00276
00277 int current_row, current_col;
00278 int select_row, select_col;
00279
00280
00281 int toprow_scrollpos,
00282 leftcol_scrollpos;
00283
00284
00285 int tix, tiy, tiw, tih,
00286 tox, toy, tow, toh,
00287 wix, wiy, wiw, wih;
00288
00289 Fl_Scroll *table;
00290 Fl_Scrollbar *vscrollbar,
00291 *hscrollbar;
00292
00293
00294 int handle(int e);
00295
00296
00297 void recalc_dimensions();
00298 void table_resized();
00299 void table_scrolled();
00300 void get_bounds(TableContext context,
00301 int &X, int &Y, int &W, int &H);
00302 void change_cursor(Fl_Cursor newcursor);
00303 TableContext cursor2rowcol(int &R, int &C, ResizeFlag &resizeflag);
00304
00305 int find_cell(TableContext context,
00306 int R, int C, int &X, int &Y, int &W, int &H);
00307 int row_col_clamp(TableContext context, int &R, int &C);
00308
00309
00310
00311 virtual void draw_cell(TableContext context, int R=0, int C=0,
00312 int X=0, int Y=0, int W=0, int H=0)
00313 { }
00314
00315 long row_scroll_position(int row);
00316 long col_scroll_position(int col);
00317
00318 int is_fltk_container()
00319 { return( Fl_Group::children() > 3 ); }
00320
00321 static void scroll_cb(Fl_Widget*,void*);
00322
00323 void damage_zone(int r1, int c1, int r2, int c2, int r3 = 0, int c3 = 0);
00324
00325 void redraw_range(int toprow, int botrow, int leftcol, int rightcol) {
00326 if ( _redraw_toprow == -1 ) {
00327
00328 _redraw_toprow = toprow;
00329 _redraw_botrow = botrow;
00330 _redraw_leftcol = leftcol;
00331 _redraw_rightcol = rightcol;
00332 } else {
00333
00334 if ( toprow < _redraw_toprow ) _redraw_toprow = toprow;
00335 if ( botrow > _redraw_botrow ) _redraw_botrow = botrow;
00336 if ( leftcol < _redraw_leftcol ) _redraw_leftcol = leftcol;
00337 if ( rightcol > _redraw_rightcol ) _redraw_rightcol = rightcol;
00338 }
00339
00340
00341 damage(FL_DAMAGE_CHILD);
00342 }
00343
00344
00345 void redraw_cell(TableContext context, int R, int C) { _redraw_cell(context, R, C); }
00346 #endif
00347
00348 public:
00353 TableBase(int X, int Y, int W, int H, const char *l=0);
00354
00358 ~TableBase();
00359
00363 virtual void clear() { rows(0); cols(0); }
00364
00369 inline void table_box(Fl_Boxtype val) { table->box(val); table_resized(); }
00370
00374 inline Fl_Boxtype table_box( void ) { return(table->box()); }
00375
00379 virtual void rows(int val);
00380
00384 inline int rows() { return _rows; }
00385
00389 virtual void cols(int val);
00390
00394 inline int cols() { return _cols; }
00395
00403 inline void visible_cells(int& r1, int& r2, int& c1, int& c2) { r1 = toprow; r2 = botrow; c1 = leftcol; c2 = rightcol; }
00404
00408 int is_interactive_resize() { return (_resizing_row != -1 || _resizing_col != -1); }
00409
00414 void row_resize(int flag) { _row_resize = flag; }
00415
00419 inline int row_resize() { return _row_resize; }
00420
00425 void col_resize(int flag) { _col_resize = flag; }
00426
00430 inline int col_resize() { return _col_resize; }
00431
00435 void col_resize_min(int val) { _col_resize_min = ( val < 1 ) ? 1 : val; }
00436
00440 inline int col_resize_min() { return _col_resize_min; }
00441
00445 void row_resize_min(int val) { _row_resize_min = ( val < 1 ) ? 1 : val; }
00446
00450 inline int row_resize_min() { return _row_resize_min; }
00451
00456 void row_header(int flag) { _row_header = flag; table_resized(); redraw(); }
00457
00461 inline int row_header() { return _row_header; }
00462
00467 void col_header(int flag) { _col_header = flag; table_resized(); redraw(); }
00468
00472 inline int col_header() { return(_col_header); }
00473
00477 inline void col_header_height(int height) { _col_header_h = height; table_resized(); redraw(); }
00478
00482 inline int col_header_height() { return _col_header_h; }
00483
00487 inline void row_header_width(int width) { _row_header_w = width; table_resized(); redraw(); }
00488
00492 inline int row_header_width() { return _row_header_w; }
00493
00497 inline void row_header_color(Fl_Color val) { _row_header_color = val; redraw(); }
00498
00502 inline Fl_Color row_header_color() { return _row_header_color; }
00503
00507 inline void col_header_color(Fl_Color val) { _col_header_color = val; redraw(); }
00508
00512 inline Fl_Color col_header_color() { return _col_header_color; }
00513
00518 void row_height(int row, int height);
00519
00523 inline int row_height(int row) { return ((row<0 || row>=(int)_rowheights.size()) ? 0 : _rowheights[row]); }
00524
00529 void col_width(int col, int width);
00530
00534 inline int col_width(int col) { return ((col<0 || col>=(int)_colwidths.size()) ? 0 : _colwidths[col]); }
00535
00539 void row_height_all(int height) { for ( int r=0; r<rows(); r++ ) row_height(r, height); }
00540
00544 void col_width_all(int width) { for ( int c=0; c<cols(); c++ ) col_width(c, width); }
00545
00549 void row_position(int row);
00550
00554 int row_position() { return _row_position; }
00555
00559 void col_position(int col);
00560
00564 int col_position() { return _col_position; }
00565
00569 inline void top_row(int row) { row_position(row); }
00570
00574 inline int top_row() { return row_position(); }
00575
00579 int is_selected(int r, int c);
00580
00587 void get_selection(int& s_top, int& s_left, int& s_bottom, int& s_right);
00588
00595 void set_selection(int s_top, int s_left, int s_bottom, int s_right);
00596
00602 int move_cursor(int R, int C);
00603
00607 void resize(int X, int Y, int W, int H);
00608
00612 void draw(void);
00613
00617 void init_sizes() { table->init_sizes(); table->redraw(); }
00618
00622 void add(Fl_Widget& w) { table->add(w); }
00623
00627 void add(Fl_Widget* w) { table->add(w); }
00628
00632 void insert(Fl_Widget& w, int n) { table->insert(w,n); }
00633
00637 void insert(Fl_Widget& w, Fl_Widget* w2) { table->insert(w,w2); }
00638
00642 void remove(Fl_Widget& w) { table->remove(w); }
00643
00647 void begin() { table->begin(); }
00648
00652 void end() {
00653 table->end();
00654
00655
00656
00657
00658 if ( table->children() > 2 )
00659 table->show();
00660 else
00661 table->hide();
00662
00663 Fl_Group::current((Fl_Group*)(Fl_Group::parent()));
00664 }
00665
00666 #ifndef SKIP_DOCS
00667 Fl_Widget * const *array() { return table->array(); }
00668 Fl_Widget *child(int n) const { return table->child(n); }
00669 int children() const { return table->children()-2; }
00670 int find(const Fl_Widget *w) const { return table->find(w); }
00671 int find(const Fl_Widget &w) const { return table->find(w); }
00672 #endif
00673
00678 int callback_row() { return _callback_row; }
00679
00684 int callback_col() { return _callback_col; }
00685
00689 TableContext callback_context() { return _callback_context; }
00690
00694 void do_callback(TableContext context, int row, int col) {
00695 _callback_context = context;
00696 _callback_row = row;
00697 _callback_col = col;
00698 Fl_Widget::do_callback();
00699 }
00700 };
00701
00702 EDELIB_NS_END
00703 #endif