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
00030
00031 #ifndef _FL_TABLE_H
00032 #define _FL_TABLE_H
00033
00034 #include <sys/types.h>
00035 #include <string.h>
00036 #ifdef WIN32
00037 #include <malloc.h>
00038 #else
00039 #include <stdlib.h>
00040 #endif
00041
00042 #include <FL/Fl.H>
00043 #include <FL/Fl_Group.H>
00044 #include <FL/Fl_Scroll.H>
00045 #include <FL/Fl_Box.H>
00046 #include <FL/Fl_Scrollbar.H>
00047
00181 class FL_EXPORT Fl_Table : public Fl_Group {
00182 public:
00186 enum TableContext {
00187 CONTEXT_NONE = 0,
00188 CONTEXT_STARTPAGE = 0x01,
00189 CONTEXT_ENDPAGE = 0x02,
00190 CONTEXT_ROW_HEADER = 0x04,
00191 CONTEXT_COL_HEADER = 0x08,
00192 CONTEXT_CELL = 0x10,
00193 CONTEXT_TABLE = 0x20,
00194 CONTEXT_RC_RESIZE = 0x40
00195 };
00196
00197 private:
00198 int _rows, _cols;
00199 int _row_header_w;
00200 int _col_header_h;
00201 int _row_position;
00202 int _col_position;
00203
00204 char _row_header;
00205 char _col_header;
00206 char _row_resize;
00207 char _col_resize;
00208 int _row_resize_min;
00209 int _col_resize_min;
00210
00211
00212 int _redraw_toprow;
00213 int _redraw_botrow;
00214 int _redraw_leftcol;
00215 int _redraw_rightcol;
00216 Fl_Color _row_header_color;
00217 Fl_Color _col_header_color;
00218
00219 int _auto_drag;
00220 int _selecting;
00221
00222
00223 class 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); }
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
00619 inline int col_resize_min() {
00620 return(_col_resize_min);
00621 }
00622
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);
00835
00839 void resize(int X, int Y, int W, int H);
00840 void draw(void);
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854 void init_sizes() {
00855 table->init_sizes();
00856 table->redraw();
00857 }
00858 void add(Fl_Widget& w) {
00859 table->add(w);
00860 }
00861 void add(Fl_Widget* w) {
00862 table->add(w);
00863 }
00864 void insert(Fl_Widget& w, int n) {
00865 table->insert(w,n);
00866 }
00867 void insert(Fl_Widget& w, Fl_Widget* w2) {
00868 table->insert(w,w2);
00869 }
00870 void remove(Fl_Widget& w) {
00871 table->remove(w);
00872 }
00873 void begin() {
00874 table->begin();
00875 }
00876 void end() {
00877 table->end();
00878
00879
00880
00881 if ( table->children() > 2 ) {
00882 table->show();
00883 } else {
00884 table->hide();
00885 }
00886 Fl_Group::current(Fl_Group::parent());
00887 }
00888 Fl_Widget * const *array() {
00889 return(table->array());
00890 }
00891
00906 Fl_Widget *child(int n) const {
00907 return(table->child(n));
00908 }
00909
00918 int children() const {
00919 return(table->children()-2);
00920 }
00921 int find(const Fl_Widget *w) const {
00922 return(table->find(w));
00923 }
00924 int find(const Fl_Widget &w) const {
00925 return(table->find(w));
00926 }
00927
00928
00934 int callback_row() {
00935 return(_callback_row);
00936 }
00937
00943 int callback_col() {
00944 return(_callback_col);
00945 }
00946
00952 TableContext callback_context() {
00953 return(_callback_context);
00954 }
00955
00956 void do_callback(TableContext context, int row, int col) {
00957 _callback_context = context;
00958 _callback_row = row;
00959 _callback_col = col;
00960 Fl_Widget::do_callback();
00961 }
00962
00963 #if FL_DOXYGEN
00964
00992 void when(Fl_When flags);
00993 #endif
00994
00995 #if FL_DOXYGEN
00996
01073 void callback(Fl_Widget*, void*);
01074 #endif
01075 };
01076
01077 #endif
01078
01079
01080
01081