2 Copyright 2013 Karel Matas
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <FL/Fl_Table_Row.H>
21 #include <FL/fl_draw.H>
27 /*! \file gui_dicview.hxx
33 * \warning FL_FLAT_BOX causes errors in redrawing
43 * The style of the part of the text in the DicView.
58 float relsize
; //!< relative size of the text. See DicView::font_size_
60 int offset_y
; //!< for subscripts
61 Separator separator
; //!< if not SEPARATOR_NONE draw the separator symbol instead of text
62 NewlineStyle newline
; //!< if not NEWLINE_NONE then append \n at the end of the string
64 //! Generic constructor.
65 TextStyle( Fl_Font fnt
=FL_TIMES
, float sz
=1.0, Fl_Color clr
=FL_BLACK
, int offy
=0,
66 Separator sep
=SEPARATOR_NONE
, NewlineStyle nl
=NEWLINE_NONE
)
67 :font(fnt
),relsize(sz
),color(clr
), offset_y(offy
), separator(sep
),newline(nl
){}
69 //! Constructor for separators.
70 TextStyle( Separator sep
): TextStyle() { separator
=sep
; }
71 //! Constructor for newlines.
72 TextStyle( NewlineStyle nl
): TextStyle() { newline
=nl
; }
77 * Widget that displays table with 3 columns. Column width can be changed by
78 * dragging the headers. Width of the last column is determined automatically.
79 * The cells are using simple markup language.
81 class DicView
: public Fl_Table_Row
84 int font_size_
= 12; //!< default font size. See font_size()
85 int cell_padding_x_
= 5;
86 int cell_padding_y_
= 5;
87 map
<string
,TextStyle
> tag_table_
; //!< tag_name:style
88 vector
<string
> headers_
; //!< text in the headers
91 * Helper function that sets the height <i>H</i> of the row <i>R</i>
92 * and forces its redraw. Called by draw_single_cell() when necessary
93 * (i.e. if the row height changes).
95 void redraw_row ( int R
, int H
);
98 Fl_Callback
*cb_leftclick_
;
99 Fl_Callback
*cb_rightclick_
;
100 Fl_Callback
*cb_doubleclick_
;
101 Fl_Callback
*cb_select_
;
102 void *cb_leftclick_data_
= nullptr;
103 void *cb_rightclick_data_
= nullptr;
104 void *cb_doubleclick_data_
= nullptr;
105 void *cb_select_data_
= nullptr;
106 vector
<int> cell_heights_
; //!< heights of the cells (size: no. of cells)
107 vector
<string
> data_
; //!< cells strings (size: no. of cells)
108 vector
<int> ids_
; //!< cell ids (size: no. of cells)
111 * Draws the content of a single cell. Parses the cells string, splits it
112 * into words, applies styles, fits the text into the cell (wraps words)
113 * \see utils::parse_markup()
115 * \return cell height
117 int draw_single_cell ( int R
, int C
, int X
, int Y
, int W
, int H
);
120 * Draws a cell or adjust the columns depending on the context
122 void draw_cell ( TableContext context
, int R
=0, int C
=0, int X
=0, int Y
=0,
126 DicView(int x
, int y
, int w
, int h
, const char *l
=0 );
130 * Resets view, sets cell data <i>d</i> and row ids <i>cell_ids</i>
132 void set_data ( const vector
<string
> &d
, const vector
<int> &cell_ids
={} );
136 * Adds the TextStyle <i>style</i> associated with the tag <i>name</i>
139 inline void register_tag ( const string
&name
, const TextStyle
&style
)
140 { tag_table_
[name
] = style
; };
142 //! Returns the TextStyle asociated with the tag <i>tag</i>
143 inline TextStyle
*get_style ( const string
&tag
= "default" ) const
145 auto mi
= tag_table_
.find(tag
);
146 if ( mi
!= tag_table_
.end() )
147 return const_cast<TextStyle
*>(&mi
->second
);
148 return const_cast<TextStyle
*>(&tag_table_
.at("default"));
153 * Copies the text <i>userdata</i> into clipboard and the selection
154 * buffer (Unix). Userdata should be const char*.
156 static void scb_copy ( Fl_Widget
*w
, void *userdata
) {
157 const char *d
= (const char*)userdata
;
159 Fl::copy( d
, len
, 0);
160 Fl::copy( d
, len
, 1);
164 //! returns id of a cell in the row <i>R</i> and column <i>C</i>
165 inline int cell_id ( int R
, int C
)
172 catch ( std::out_of_range
) {
178 //! Returns id of the selected row (id of the cell in first column)
179 inline int selected_row_id () { return cell_id( selected_row(), 0 );};
181 //! Returns id of the row <i>R</i> (id of the cell in first column)
182 inline int row_id ( int R
) { return cell_id(R
,0); };
184 //! Returns cell (index) at the position x,y,.
185 inline int cell_at_xy ( int x
, int y
)
192 for ( int r
=0; r
< rows(); r
++ ){
193 int nh
= h
+ row_height(r
);
201 for ( int c
=0; c
< cols(); c
++ ){
202 int nw
= w
+ col_width(c
);
209 int ret
= R
*cols()+C
;
210 if ( R
== -1 || C
== -1 || ret
> int(data_
.size())-1 )
216 //! Returns row at the y-coordinate.
217 inline int row_at_y ( int y
){
221 cursor2rowcol( R
, C
, flag
);
225 //! FLTKs handle() function.
226 int handle ( int event
);
228 //! Returns the base size of the text.
229 inline int font_size () const { return font_size_
;};
231 //! Returns x-padding of the cells.
232 inline int cell_padding_x () const { return cell_padding_x_
; };
234 //! Returns y-padding of the cells.
235 inline int cell_padding_y () const { return cell_padding_y_
; };
237 //! Return the selected row (index)
238 inline int selected_row () {
239 for ( int r
=0; r
<rows(); r
++ )
240 if ( row_selected(r
) )
246 * Sets the base size of the text. All text sizes of the styles are derived
248 * \see TextStyle::relsize
250 inline void font_size ( int s
) { font_size_
= s
; }
252 //! Sets both x-padding and y-padding to <i>x</i>.
253 inline void cell_padding ( int x
) { cell_padding_x_
= x
; cell_padding_y_
=x
;}
255 //! Sets the x-padding
256 inline void cell_padding_x ( int x
) { cell_padding_x_
= x
; }
258 //! Sets the y-padding
259 inline void cell_padding_y ( int y
) { cell_padding_y_
= y
; }
261 //! Sets the text strings in the column headers
262 inline void headers ( const vector
<string
> &v
) { headers_
=v
; }
265 * Sets the callback for leftclick. <i>data</i> should be pointer
266 * to the master widget (App).
268 inline void cb_leftclick ( Fl_Callback
*cb
, void *data
)
269 { cb_leftclick_
= cb
; cb_leftclick_data_
= data
; }
272 * Sets the callback for rightclick. <i>data</i> should be pointer
273 * to the master widget (App).
275 inline void cb_rightclick ( Fl_Callback
*cb
, void *data
)
276 { cb_rightclick_
= cb
; cb_rightclick_data_
= data
; }
279 * Sets the callback for doubleclick. <i>data</i> should be pointer
280 * to the master widget (App).
282 inline void cb_doubleclick( Fl_Callback
*cb
, void *data
)
283 { cb_doubleclick_
= cb
; cb_doubleclick_data_
= data
; }
286 * Sets the callback for the selection of a row.
287 * <i>data</i> should be pointer to the master widget (App).
289 inline void cb_select ( Fl_Callback
*cb
, void *data
)
290 { cb_select_
= cb
; cb_select_data_
= data
; }
292 //! Calls the callback for the leftclick
293 inline void cb_leftclick ( Fl_Widget
*w
) const
294 { cb_leftclick_(w
,cb_leftclick_data_
); }
295 //! Calls the callback for the rightclick
296 inline void cb_rightclick ( Fl_Widget
*w
) const
297 { cb_rightclick_(w
, cb_rightclick_data_
); }
298 //! Calls the callback for the doubleclick
299 inline void cb_doubleclick( Fl_Widget
*w
) const
300 { cb_doubleclick_(w
, cb_doubleclick_data_
); }
301 //! Calls the selection of a row
302 inline void cb_select ( Fl_Widget
*w
) const
303 { cb_select_(w
,cb_select_data_
); }
305 //! default (empty) callback
306 inline static void scb_general ( Fl_Widget
*w
, void *f
) {}
310 #endif // _DICVIEW_HXX