00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _FL_TABLE_H
00021 #define _FL_TABLE_H
00022
00023 #include <sys/types.h>
00024 #include <string.h>
00025 #ifdef WIN32
00026 #include <malloc.h>
00027 #else
00028 #include <stdlib.h>
00029 #endif
00030
00031 #include <FL/Fl.H>
00032 #include <FL/Fl_Group.H>
00033 #include <FL/Fl_Scroll.H>
00034 #include <FL/Fl_Box.H>
00035 #include <FL/Fl_Scrollbar.H>
00036
00170 class FL_EXPORT Fl_Table : public Fl_Group {
00171 public:
00177 enum TableContext {
00178 CONTEXT_NONE = 0,
00179 CONTEXT_STARTPAGE = 0x01,
00180 CONTEXT_ENDPAGE = 0x02,
00181 CONTEXT_ROW_HEADER = 0x04,
00182 CONTEXT_COL_HEADER = 0x08,
00183 CONTEXT_CELL = 0x10,
00184 CONTEXT_TABLE = 0x20,
00185 CONTEXT_RC_RESIZE = 0x40
00186 };
00187
00188 private:
00189 int _rows, _cols;
00190 int _row_header_w;
00191 int _col_header_h;
00192 int _row_position;
00193 int _col_position;
00194
00195 char _row_header;
00196 char _col_header;
00197 char _row_resize;
00198 char _col_resize;
00199 int _row_resize_min;
00200 int _col_resize_min;
00201
00202
00203 int _redraw_toprow;
00204 int _redraw_botrow;
00205 int _redraw_leftcol;
00206 int _redraw_rightcol;
00207 Fl_Color _row_header_color;
00208 Fl_Color _col_header_color;
00209
00210 int _auto_drag;
00211 int _selecting;
00212 #if FLTK_ABI_VERSION >= 10301
00213 int _scrollbar_size;
00214 #endif
00215 #if FLTK_ABI_VERSION >= 10303
00216 enum {
00217 TABCELLNAV = 1<<0,
00218 };
00219 unsigned int flags_;
00220 #endif
00221
00222
00223 class FL_EXPORT IntVector {
00224 int *arr;
00225 unsigned int _size;
00226 void init() {
00227 arr = NULL;
00228 _size = 0;
00229 }
00230 void copy(int *newarr, unsigned int newsize) {
00231 size(newsize);
00232 memcpy(arr, newarr, newsize * sizeof(int));
00233 }
00234 public:
00235 IntVector() { init(); }
00236 ~IntVector() { if ( arr ) free(arr); arr = NULL; }
00237 IntVector(IntVector&o) { init(); copy(o.arr, o._size); }
00238 IntVector& operator=(IntVector&o) {
00239 init();
00240 copy(o.arr, o._size);
00241 return(*this);
00242 }
00243 int operator[](int x) const { return(arr[x]); }
00244 int& operator[](int x) { return(arr[x]); }
00245 unsigned int size() { return(_size); }
00246 void size(unsigned int count) {
00247 if ( count != _size ) {
00248 arr = (int*)realloc(arr, count * sizeof(int));
00249 _size = count;
00250 }
00251 }
00252 int pop_back() { int tmp = arr[_size-1]; _size--; return(tmp); }
00253 void push_back(int val) { unsigned int x = _size; size(_size+1); arr[x] = val; }
00254 int back() { return(arr[_size-1]); }
00255 };
00256
00257 IntVector _colwidths;
00258 IntVector _rowheights;
00259
00260 Fl_Cursor _last_cursor;
00261
00262
00263 TableContext _callback_context;
00264 int _callback_row, _callback_col;
00265
00266
00267
00268
00269
00270 int _resizing_col;
00271 int _resizing_row;
00272 int _dragging_x;
00273 int _dragging_y;
00274 int _last_row;
00275
00276
00277 void _redraw_cell(TableContext context, int R, int C);
00278
00279 void _start_auto_drag();
00280 void _stop_auto_drag();
00281 void _auto_drag_cb();
00282 static void _auto_drag_cb2(void *d);
00283
00284 protected:
00285 enum ResizeFlag {
00286 RESIZE_NONE = 0,
00287 RESIZE_COL_LEFT = 1,
00288 RESIZE_COL_RIGHT = 2,
00289 RESIZE_ROW_ABOVE = 3,
00290 RESIZE_ROW_BELOW = 4
00291 };
00292
00293 int table_w, table_h;
00294 int toprow, botrow, leftcol, rightcol;
00295
00296
00297 int current_row, current_col;
00298 int select_row, select_col;
00299
00300
00301 int toprow_scrollpos;
00302 int leftcol_scrollpos;
00303
00304
00305 int tix, tiy, tiw, tih;
00306 int tox, toy, tow, toh;
00307 int wix, wiy, wiw, wih;
00308
00309 Fl_Scroll *table;
00310 Fl_Scrollbar *vscrollbar;
00311 Fl_Scrollbar *hscrollbar;
00312
00313
00314 int handle(int e);
00315
00316
00317 void recalc_dimensions();
00318 void table_resized();
00319 void table_scrolled();
00320 void get_bounds(TableContext context,
00321 int &X, int &Y, int &W, int &H);
00322 void change_cursor(Fl_Cursor newcursor);
00323 TableContext cursor2rowcol(int &R, int &C, ResizeFlag &resizeflag);
00324
00325 int find_cell(TableContext context,
00326 int R, int C, int &X, int &Y, int &W, int &H);
00327 int row_col_clamp(TableContext context, int &R, int &C);
00328
00329
00440 virtual void draw_cell(TableContext context, int R=0, int C=0,
00441 int X=0, int Y=0, int W=0, int H=0)
00442 { }
00443
00444 long row_scroll_position(int row);
00445 long col_scroll_position(int col);
00446
00447 int is_fltk_container() {
00448 return( Fl_Group::children() > 3 );
00449 }
00450
00451 static void scroll_cb(Fl_Widget*,void*);
00452
00453 void damage_zone(int r1, int c1, int r2, int c2, int r3 = 0, int c3 = 0);
00454
00455 void redraw_range(int topRow, int botRow, int leftCol, int rightCol) {
00456 if ( _redraw_toprow == -1 ) {
00457
00458 _redraw_toprow = topRow;
00459 _redraw_botrow = botRow;
00460 _redraw_leftcol = leftCol;
00461 _redraw_rightcol = rightCol;
00462 } else {
00463
00464 if ( topRow < _redraw_toprow ) _redraw_toprow = topRow;
00465 if ( botRow > _redraw_botrow ) _redraw_botrow = botRow;
00466 if ( leftCol < _redraw_leftcol ) _redraw_leftcol = leftCol;
00467 if ( rightCol > _redraw_rightcol ) _redraw_rightcol = rightCol;
00468 }
00469
00470
00471 damage(FL_DAMAGE_CHILD);
00472 }
00473
00474 public:
00480 Fl_Table(int X, int Y, int W, int H, const char *l=0);
00481
00486 ~Fl_Table();
00487
00493 virtual void clear() { rows(0); cols(0); table->clear(); }
00494
00495
00496
00502 inline void table_box(Fl_Boxtype val) {
00503 table->box(val);
00504 table_resized();
00505 }
00506
00510 inline Fl_Boxtype table_box( void ) {
00511 return(table->box());
00512 }
00513
00517 virtual void rows(int val);
00518
00522 inline int rows() {
00523 return(_rows);
00524 }
00525
00529 virtual void cols(int val);
00530
00534 inline int cols() {
00535 return(_cols);
00536 }
00537
00566 inline void visible_cells(int& r1, int& r2, int& c1, int& c2) {
00567 r1 = toprow;
00568 r2 = botrow;
00569 c1 = leftcol;
00570 c2 = rightcol;
00571 }
00572
00577 int is_interactive_resize() {
00578 return(_resizing_row != -1 || _resizing_col != -1);
00579 }
00580
00584 inline int row_resize() {
00585 return(_row_resize);
00586 }
00587
00594 void row_resize(int flag) {
00595 _row_resize = flag;
00596 }
00597
00601 inline int col_resize() {
00602 return(_col_resize);
00603 }
00610 void col_resize(int flag) {
00611 _col_resize = flag;
00612 }
00613
00617 inline int col_resize_min() {
00618 return(_col_resize_min);
00619 }
00620
00626 void col_resize_min(int val) {
00627 _col_resize_min = ( val < 1 ) ? 1 : val;
00628 }
00629
00633 inline int row_resize_min() {
00634 return(_row_resize_min);
00635 }
00636
00642 void row_resize_min(int val) {
00643 _row_resize_min = ( val < 1 ) ? 1 : val;
00644 }
00645
00649 inline int row_header() {
00650 return(_row_header);
00651 }
00652
00657 void row_header(int flag) {
00658 _row_header = flag;
00659 table_resized();
00660 redraw();
00661 }
00662
00666 inline int col_header() {
00667 return(_col_header);
00668 }
00669
00674 void col_header(int flag) {
00675 _col_header = flag;
00676 table_resized();
00677 redraw();
00678 }
00679
00683 inline void col_header_height(int height) {
00684 _col_header_h = height;
00685 table_resized();
00686 redraw();
00687 }
00688
00692 inline int col_header_height() {
00693 return(_col_header_h);
00694 }
00695
00699 inline void row_header_width(int width) {
00700 _row_header_w = width;
00701 table_resized();
00702 redraw();
00703 }
00704
00708 inline int row_header_width() {
00709 return(_row_header_w);
00710 }
00711
00715 inline void row_header_color(Fl_Color val) {
00716 _row_header_color = val;
00717 redraw();
00718 }
00719
00723 inline Fl_Color row_header_color() {
00724 return(_row_header_color);
00725 }
00726
00730 inline void col_header_color(Fl_Color val) {
00731 _col_header_color = val;
00732 redraw();
00733 }
00734
00738 inline Fl_Color col_header_color() {
00739 return(_col_header_color);
00740 }
00741
00748 void row_height(int row, int height);
00749
00753 inline int row_height(int row) {
00754 return((row<0 || row>=(int)_rowheights.size()) ? 0 : _rowheights[row]);
00755 }
00756
00762 void col_width(int col, int width);
00763
00767 inline int col_width(int col) {
00768 return((col<0 || col>=(int)_colwidths.size()) ? 0 : _colwidths[col]);
00769 }
00770
00775 void row_height_all(int height) {
00776 for ( int r=0; r<rows(); r++ ) {
00777 row_height(r, height);
00778 }
00779 }
00780
00785 void col_width_all(int width) {
00786 for ( int c=0; c<cols(); c++ ) {
00787 col_width(c, width);
00788 }
00789 }
00790
00794 void row_position(int row);
00795
00799 void col_position(int col);
00800
00804 int row_position() {
00805 return(_row_position);
00806 }
00807
00811 int col_position() {
00812 return(_col_position);
00813 }
00814
00820 inline void top_row(int row) {
00821 row_position(row);
00822 }
00823
00828 inline int top_row() {
00829 return(row_position());
00830 }
00831 int is_selected(int r, int c);
00832 void get_selection(int &row_top, int &col_left, int &row_bot, int &col_right);
00833 void set_selection(int row_top, int col_left, int row_bot, int col_right);
00834 int move_cursor(int R, int C, int shiftselect);
00835 int move_cursor(int R, int C);
00836
00840 void resize(int X, int Y, int W, int H);
00841 void draw(void);
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855 void init_sizes() {
00856 table->init_sizes();
00857 table->redraw();
00858 }
00859 void add(Fl_Widget& wgt) {
00860 table->add(wgt);
00861 if ( table->children() > 2 ) {
00862 table->show();
00863 } else {
00864 table->hide();
00865 }
00866 }
00867 void add(Fl_Widget* wgt) {
00868 add(*wgt);
00869 }
00870 void insert(Fl_Widget& wgt, int n) {
00871 table->insert(wgt,n);
00872 }
00873 void insert(Fl_Widget& wgt, Fl_Widget* w2) {
00874 table->insert(wgt,w2);
00875 }
00876 void remove(Fl_Widget& wgt) {
00877 table->remove(wgt);
00878 }
00879 void begin() {
00880 table->begin();
00881 }
00882 void end() {
00883 table->end();
00884
00885
00886
00887 if ( table->children() > 2 ) {
00888 table->show();
00889 } else {
00890 table->hide();
00891 }
00892 Fl_Group::current(Fl_Group::parent());
00893 }
00894 Fl_Widget * const *array() {
00895 return(table->array());
00896 }
00897
00912 Fl_Widget *child(int n) const {
00913 return(table->child(n));
00914 }
00915
00924 int children() const {
00925 return(table->children()-2);
00926 }
00927 int find(const Fl_Widget *wgt) const {
00928 return(table->find(wgt));
00929 }
00930 int find(const Fl_Widget &wgt) const {
00931 return(table->find(wgt));
00932 }
00933
00934
00940 int callback_row() {
00941 return(_callback_row);
00942 }
00943
00949 int callback_col() {
00950 return(_callback_col);
00951 }
00952
00958 TableContext callback_context() {
00959 return(_callback_context);
00960 }
00961
00962 void do_callback(TableContext context, int row, int col) {
00963 _callback_context = context;
00964 _callback_row = row;
00965 _callback_col = col;
00966 Fl_Widget::do_callback();
00967 }
00968
00969 #ifdef FL_DOXYGEN
00970
00998 void when(Fl_When flags);
00999 #endif
01000
01001 #ifdef FL_DOXYGEN
01002
01079 void callback(Fl_Widget*, void*);
01080 #endif
01081
01082 #if FLTK_ABI_VERSION >= 10301
01083
01093 int scrollbar_size() const {
01094 return(_scrollbar_size);
01095 }
01114 void scrollbar_size(int newSize) {
01115 if ( newSize != _scrollbar_size ) redraw();
01116 _scrollbar_size = newSize;
01117 }
01118 #endif
01119 #if FLTK_ABI_VERSION >= 10303
01120
01133 void tab_cell_nav(int val) {
01134 if ( val ) flags_ |= TABCELLNAV;
01135 else flags_ &= ~TABCELLNAV;
01136 }
01137
01145 int tab_cell_nav() const {
01146 return(flags_ & TABCELLNAV ? 1 : 0);
01147 }
01148 #endif
01149 };
01150
01151 #endif
01152
01153
01154
01155