OPT added to MAkefile; KanjiView::Cell constructor: fg,bg changed to int (Fl_Color...
[aoi.git] / src / gui_dicview.hxx
blobd32ba051abea95442679cfeb46016da67a841422
1 /*
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/>.
17 #ifndef _DICVIEW_HXX
18 #define _DICVIEW_HXX
20 #include <FL/Fl_Table_Row.H>
21 #include <FL/fl_draw.H>
22 #include <map>
23 #include <string>
24 #include <vector>
25 #include <stdexcept>
27 /*! \file gui_dicview.hxx
28 * PREDEFINED TAGS:
29 * <br>
30 * <sep>
31 * <default>
33 * \warning FL_FLAT_BOX causes errors in redrawing
36 namespace aoi_ui {
38 using std::vector;
39 using std::map;
40 using std::string;
42 /*!
43 * The style of the part of the text in the DicView.
45 struct TextStyle
47 enum Separator {
48 SEPARATOR_NONE,
49 SEPARATOR_SQUARE
52 enum NewlineStyle {
53 NEWLINE_NONE,
54 NEWLINE_AFTER
57 Fl_Font font;
58 float relsize; //!< relative size of the text. See DicView::font_size_
59 Fl_Color color;
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; }
76 /*!
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
83 private:
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
90 /*!
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 );
97 protected:
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)
110 /*!
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()
114 * \see TextStyle
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,
123 int W=0, int H=0 );
125 public:
126 DicView(int x, int y, int w, int h, const char *l=0 );
127 ~DicView(){};
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>
137 * to the tag table.
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"));
152 /*!
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;
158 int len = strlen(d);
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 )
167 int n = R*cols()+C;
168 int ret;
169 try {
170 ret = ids_.at(n);
172 catch ( std::out_of_range ) {
173 ret = -1;
175 return ret;
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 )
187 int R = -1;
188 int C = -1;
189 int w = 0;
190 int h = 0;
191 // check rows
192 for ( int r=0; r < rows(); r++ ){
193 int nh = h + row_height(r);
194 if ( y>h && y<nh ){
195 R = r;
196 break;
198 h = nh;
200 // check columns
201 for ( int c=0; c < cols(); c++ ){
202 int nw = w + col_width(c);
203 if ( x>w && x<nw ) {
204 C = c;
205 break;
207 w = nw;
209 int ret = R*cols()+C;
210 if ( R == -1 || C == -1 || ret > int(data_.size())-1 )
211 return -1;
212 return ret;
216 //! Returns row at the y-coordinate.
217 inline int row_at_y ( int y ){
218 int R = 0;
219 int C = 0;
220 ResizeFlag flag;
221 cursor2rowcol( R, C, flag );
222 return R;
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) )
241 return r;
242 return -1;
245 /*!
246 * Sets the base size of the text. All text sizes of the styles are derived
247 * from these value.
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; }
264 /*!
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; }
271 /*!
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; }
278 /*!
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; }
285 /*!
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 ) {}
309 } //namespace aoi_ui
310 #endif // _DICVIEW_HXX