jlpt and grade added as kanjisearch filters
[aoi.git] / src / gui_widgets.hxx
blob7c9a739a8d3967ff6ade857c8bfafd77beac81ce
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 _GUI_WIDGETS_HXX
18 #define _GUI_WIDGETS_HXX
20 #include <cmath>
21 #include <FL/Fl.H>
22 #include <FL/Fl_Group.H>
23 #include <FL/fl_draw.H>
24 #include <FL/Fl_Box.H>
25 #include <FL/Fl_Input.H>
26 #include <FL/Fl_Menu_Item.H>
28 #include <vector>
29 #include <string>
31 #include "datatypes.hxx"
32 #include "gui_settings.hxx"
34 using std::vector;
35 using std::string;
36 using aoi::Kanji;
38 namespace aoi_ui{
40 // replacement for Fl_Widget::measure_label()
41 inline int text_height ( const char *s, int wrap_width )
43 return ceil(fl_width(s)/wrap_width)*fl_height();
47 XXX: po X sec se sam schova
48 class Notify : public Fl_Box
50 private:
51 string text_;
52 public:
53 Notify (int x, int y, int w, int h, const char *l=0): Fl_Box(x,y,w,h,l){};
54 ~Notify();
59 class Infolabel : public Fl_Box
61 private:
62 string label_;
64 public:
65 Infolabel ( int x, int y, int w, int h, const char *l=0 ): Fl_Box(x,y,w,h,l){};
67 inline void set ( const string &s ) {
68 label_ = s;
69 label(label_.c_str());
75 class Entry : public Fl_Input
77 private:
78 bool innerlabel_visible_ = true;
79 const char *innerlabel_;
80 public:
81 Entry ( int x, int y, int w, int h, const char *l="Label")
82 : Fl_Input(x,y,w,h,0), innerlabel_(l)
84 when(FL_WHEN_ENTER_KEY_ALWAYS);
86 ~Entry(){};
88 void draw ()
90 if (input_type() == FL_HIDDEN_INPUT) return;
91 Fl_Boxtype b = box();
92 if (damage() & FL_DAMAGE_ALL)
93 draw_box(b, color());
94 if ( strlen(value()) == 0 && innerlabel_visible_ ) {
95 // clear background
96 fl_color(color());
97 fl_rectf( x()+Fl::box_dx(b), y()+Fl::box_dy(b),
98 w()-Fl::box_dw(b), h()-Fl::box_dh(b) );
99 // draw grayed text
100 fl_font(textfont(), textsize());
101 fl_color(FL_GRAY);
102 fl_draw( innerlabel_,
103 x()+Fl::box_dx(b)+3,
104 y()+h()-Fl::box_dy(b)-Fl::box_dh(b)-fl_descent()
107 else
108 Fl_Input_::drawtext(x()+Fl::box_dx(b), y()+Fl::box_dy(b),
109 w()-Fl::box_dw(b), h()-Fl::box_dh(b) );
112 // copy to clipboard
113 static void scb_copy (Fl_Widget*, void *userdata) {
114 Entry *in = (Entry*)userdata;
115 in->copy(0); // text selection clipboard
116 in->copy(1); // copy/paste clipboard
119 // paste from selection buffer (middle click, 0)
120 static void scb_paste0 (Fl_Widget*, void *userdata) {
121 Entry *in = (Entry*)userdata;
122 Fl::paste(*in, 0);
125 // paste from clipboard (1)
126 static void scb_paste1 (Fl_Widget*, void *userdata) {
127 Entry *in = (Entry*)userdata;
128 Fl::paste(*in, 1);
131 int handle ( int event )
133 unsigned int mods = Fl::event_state() & FL_CTRL;
134 auto key = Fl::event_key();
135 switch ( event )
137 case FL_PUSH:
139 innerlabel_visible_ = false;
140 redraw();
141 if ( Fl::event_button() == FL_RIGHT_MOUSE ) {
142 Fl_Menu_Item menu[] = {
143 { "Copy", 0, scb_copy, (void*)this },
144 { "Paste (clipboard)", 0, scb_paste1, (void*)this },
145 { "Paste (selection)", 0, scb_paste0, (void*)this },
146 { 0 }
148 const Fl_Menu_Item *m = menu->popup(Fl::event_x(), Fl::event_y(),0,0,0);
149 if ( m )
150 m->do_callback(0, m->user_data());
151 return 1;
153 break;
155 case FL_KEYBOARD:
156 if ( mods && (key=='m' || key=='l') ) // ignore Ctrl-M and Ctrl-L
157 return 0;
158 case FL_RELEASE:
159 if ( Fl::event_button() == FL_RIGHT_MOUSE )
160 return 1;
161 case FL_UNFOCUS:
162 innerlabel_visible_ = true;
163 redraw();
164 break;
165 default:
166 break;
168 return Fl_Input::handle(event);
172 class KanjiInfo : public Fl_Group
174 private:
175 Fl_Box *kanjibox_;
176 int padding_ = 5;
177 bool autoresize_ = false;
178 Fl_Font font_a_ = FL_HELVETICA + FL_BOLD;
179 Fl_Font font_b_ = FL_HELVETICA;
180 Fl_Font font_kanji_ = FONT_KANJI;
181 int size_a_ = 12;
182 int size_b_ = 12;
183 Kanji kanji_;
184 vector<string> strings_;
186 inline int draw_caption_label ( string a, string b, int xx, int yy,
187 int wa, int wb, // width of strings
188 int rh /*row height*/)
190 if ( !b.size() )
191 return 0;
192 strings_.push_back(a);
193 strings_.push_back(b);
194 Fl_Box *bx = new Fl_Box( xx, yy, wa, rh, a.c_str() );
195 bx->align(FL_ALIGN_LEFT+FL_ALIGN_INSIDE);
196 bx->labelfont( font_a_ );
197 bx->labelsize( size_a_ );
198 bx = new Fl_Box( xx+wa+5, yy, wa, rh, b.c_str() );
199 bx->align(FL_ALIGN_LEFT+FL_ALIGN_INSIDE);
200 bx->labelfont( font_b_ );
201 bx->labelsize( size_b_ );
202 return rh;
205 inline int draw_box ( Fl_Font f, int size, string ss, int xx, int yy, int ww, int hh ){
206 if ( ss.size() ){
207 strings_.push_back(ss);
208 Fl_Box *b = new Fl_Box( xx, yy, ww, hh, ss.c_str() );
209 b->labelfont(f);
210 b->labelsize(size);
211 b->align(FL_ALIGN_INSIDE+FL_ALIGN_WRAP);
212 b->size(b->w(),text_height(ss.c_str(),ww));
213 return b->h();
215 return 0;
218 public:
219 KanjiInfo( int x, int y, int w, int h, const char *l=0): Fl_Group(x,y,w,h,l) {};
220 ~KanjiInfo(){};
221 void set_data ( const Kanji &k );
222 inline void autoresize ( bool b ) { autoresize_=b; };
223 inline bool autoresize () const { return autoresize_; };
224 inline void font_a ( Fl_Font f, int s ) { font_a_=f; size_a_=s; };
225 inline void font_b ( Fl_Font f, int s ) { font_b_=f; size_b_=s; };
226 inline void font_kanji ( Fl_Font f ) { font_kanji_=f; };
229 class ComponentView : public Fl_Widget
231 public:
232 enum CellType {
233 CELL,
234 CELL_LABEL,
235 CELL_HIGHLIGHTED,
236 CELL_SELECTED_1,
237 CELL_SELECTED_2
239 struct Cell {
240 string str;
241 CellType type;
242 Cell ( const string &s, CellType t=CELL): str(s), type(t){};
244 private:
245 vector<Cell> cells_;
246 int cell_size_;
247 Fl_Font font_cell_ = FL_HELVETICA;
248 Fl_Font font_label_ = FL_HELVETICA;
249 int fsize_cell_ = 12;
250 int fsize_label_ = 12;
251 Fl_Color color_fg_ = FL_BLACK;
252 Fl_Color color_bg_ = FL_WHITE;
253 Fl_Color color_fg_label_ = FL_WHITE;
254 Fl_Color color_bg_label_ = FL_BLACK;
255 Fl_Color color_highlight_ = FL_YELLOW;
256 Fl_Color color_select1_ = fl_rgb_color(0x64,0x95,0xED);
257 Fl_Color color_select2_ = fl_rgb_color(0xe9,0x96,0x7a);
258 int rows_;
259 int cols_;
261 void set_cellsize ();
263 public:
264 ComponentView ( int x, int y, int w, int h, const char *l=0 );
265 ~ComponentView(){};
267 int handle ( int event );
268 void draw ();
269 void set_data ( const vector<Cell> &d={});
270 void set_highlight ( const string &components );
271 void font_cell ( Fl_Font f=FL_HELVETICA, int s=16 );
272 void font_label ( Fl_Font f=FL_HELVETICA, int s=16 );
273 inline vector<string> selected1 () { return cells_by_type(CELL_SELECTED_1); };
274 inline vector<string> selected2 () { return cells_by_type(CELL_SELECTED_2); };
275 vector<string> cells_by_type ( CellType t );
278 } // namespace aoi_ui
279 #endif //_GUI_WIDGETS_HXX