2 // "$Id: Fl_Table_Row.cxx 7950 2010-12-05 01:22:53Z greg.ercolano $"
4 // Fl_Table_Row -- A row oriented table widget
6 // A class specializing in a table of rows.
7 // Handles row-specific selection behavior.
9 // Copyright 2002 by Greg Ercolano.
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Library General Public
13 // License as published by the Free Software Foundation; either
14 // version 2 of the License, or (at your option) any later version.
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Library General Public License for more details.
21 // You should have received a copy of the GNU Library General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 // Please report all bugs and problems to "erco at seriss dot com".
30 // o Row headings (only column headings supported currently)
33 #include <stdio.h> // for debugging
35 #include <FL/fl_draw.H>
36 #include <FL/Fl_Table_Row.H>
39 int Fl_Table_Row::row_selected(int row
) {
40 if ( row
< 0 || row
>= rows() ) return(-1);
41 return(_rowselect
[row
]);
44 // Change row selection type
45 void Fl_Table_Row::type(TableRowSelectMode val
) {
47 switch ( _selectmode
) {
49 for ( int row
=0; row
<rows(); row
++ ) {
57 for ( int row
=0; row
<rows(); row
++ ) {
58 if ( _rowselect
[row
] ) {
59 if ( ++count
> 1 ) { // only one allowed
72 // Change selection state for row
75 // 0 - clear selection
77 // 2 - toggle selection
80 // 0 - selection state did not change
81 // 1 - selection state changed
82 // -1 - row out of range or incorrect selection mode
84 int Fl_Table_Row::select_row(int row
, int flag
) {
86 if ( row
< 0 || row
>= rows() ) { return(-1); }
87 switch ( _selectmode
) {
93 for ( int t
=0; t
<rows(); t
++ ) {
95 oldval
= _rowselect
[row
];
96 if ( flag
== 2 ) { _rowselect
[row
] ^= 1; }
97 else { _rowselect
[row
] = flag
; }
98 if ( oldval
!= _rowselect
[row
] ) {
99 redraw_range(row
, row
, leftcol
, rightcol
);
103 else if ( _rowselect
[t
] ) {
105 redraw_range(t
, t
, leftcol
, rightcol
);
112 int oldval
= _rowselect
[row
];
113 if ( flag
== 2 ) { _rowselect
[row
] ^= 1; }
114 else { _rowselect
[row
] = flag
; }
115 if ( _rowselect
[row
] != oldval
) { // select state changed?
116 if ( row
>= toprow
&& row
<= botrow
) { // row visible?
117 // Extend partial redraw range
118 redraw_range(row
, row
, leftcol
, rightcol
);
127 // Select all rows to a known state
128 void Fl_Table_Row::select_all_rows(int flag
) {
129 switch ( _selectmode
) {
134 if ( flag
!= 0 ) return;
140 for ( int row
=0; row
<(int)_rowselect
.size(); row
++ ) {
141 _rowselect
[row
] ^= 1;
145 for ( int row
=0; row
<(int)_rowselect
.size(); row
++ ) {
146 changed
|= (_rowselect
[row
] != flag
)?1:0;
147 _rowselect
[row
] = flag
;
157 // Set number of rows
158 void Fl_Table_Row::rows(int val
) {
160 while ( val
> (int)_rowselect
.size() ) { _rowselect
.push_back(0); } // enlarge
161 while ( val
< (int)_rowselect
.size() ) { _rowselect
.pop_back(); } // shrink
164 // #include "eventnames.h" // debugging
165 // #include <stdio.h>
168 int Fl_Table_Row::handle(int event
) {
170 // fprintf(stderr, "** EVENT: %s: EVENT XY=%d,%d\n",
171 // eventnames[event], Fl::event_x(), Fl::event_y()); // debugging
173 // Let base class handle event
174 int ret
= Fl_Table::handle(event
);
176 // The following code disables cell selection.. why was it added? -erco 05/18/03
177 // if ( ret ) { _last_y = Fl::event_y(); return(1); } // base class 'handled' it (eg. column resize)
179 int shiftstate
= (Fl::event_state() & FL_CTRL
) ? FL_CTRL
:
180 (Fl::event_state() & FL_SHIFT
) ? FL_SHIFT
: 0;
182 // Which row/column are we over?
183 int R
, C
; // row/column being worked on
184 ResizeFlag resizeflag
; // which resizing area are we over? (0=none)
185 TableContext context
= cursor2rowcol(R
, C
, resizeflag
);
188 if ( Fl::event_button() == 1 ) {
189 _last_push_x
= Fl::event_x(); // save regardless of context
190 _last_push_y
= Fl::event_y(); // " "
192 // Handle selection in table.
193 // Select cell under cursor, and enable drag selection mode.
195 if ( context
== CONTEXT_CELL
) {
196 // Ctrl key? Toggle selection state
197 switch ( shiftstate
) {
199 select_row(R
, 2); // toggle
204 if ( _last_row
> -1 ) {
205 int srow
= R
, erow
= _last_row
;
210 for ( int row
= srow
; row
<= erow
; row
++ ) {
218 select_all_rows(0); // clear all previous selections
224 _dragging_select
= 1;
225 ret
= 1; // FL_PUSH handled (ensures FL_DRAG will be sent)
226 // redraw(); // redraw() handled by select_row()
232 if ( _dragging_select
) {
233 // Dragged off table edges? Handle scrolling
234 int offtop
= toy
- _last_y
; // >0 if off top of table
235 int offbot
= _last_y
- (toy
+ toh
); // >0 if off bottom of table
237 if ( offtop
> 0 && row_position() > 0 ) {
238 // Only scroll in upward direction
239 int diff
= _last_y
- Fl::event_y();
244 row_position(row_position() - diff
);
245 context
= CONTEXT_CELL
; C
= 0; R
= row_position(); // HACK: fake it
246 if ( R
< 0 || R
> rows() ) { ret
= 1; break; } // HACK: ugly
248 else if ( offbot
> 0 && botrow
< rows() ) {
249 // Only scroll in downward direction
250 int diff
= Fl::event_y() - _last_y
;
255 row_position(row_position() + diff
);
256 context
= CONTEXT_CELL
; C
= 0; R
= botrow
; // HACK: fake it
257 if ( R
< 0 || R
> rows() ) { ret
= 1; break; } // HACK: ugly
259 if ( context
== CONTEXT_CELL
) {
260 switch ( shiftstate
) {
262 if ( R
!= _last_row
) { // toggle if dragged to new row
263 select_row(R
, 2); // 2=toggle
270 if ( _last_row
> -1 ) {
271 int srow
= R
, erow
= _last_row
;
276 for ( int row
= srow
; row
<= erow
; row
++ ) {
282 ret
= 1; // drag handled
290 if ( Fl::event_button() == 1 ) {
291 _dragging_select
= 0;
292 ret
= 1; // release handled
293 // Clicked off edges of data table?
294 // A way for user to clear the current selection.
296 int databot
= tiy
+ table_h
,
297 dataright
= tix
+ table_w
;
299 ( _last_push_x
> dataright
&& Fl::event_x() > dataright
) ||
300 ( _last_push_y
> databot
&& Fl::event_y() > databot
)
302 select_all_rows(0); // clear previous selections
310 _last_y
= Fl::event_y();
315 // End of "$Id: Fl_Table_Row.cxx 7950 2010-12-05 01:22:53Z greg.ercolano $".