Fl_Box -> aoi_ui::Label
[aoi.git] / src / gui.hxx
blob128d026266598be820c90f0a52a4c8427f6fd523
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_HXX
18 #define _GUI_HXX
20 #include <cmath>
21 #include <vector>
22 #include <string>
23 #include <map>
25 #include <FL/Fl.H>
26 #include <FL/Fl_Double_Window.H>
27 #include <FL/Fl_Group.H>
28 #include <FL/Fl_Tile.H>
29 #include <FL/Fl_Menu_Button.H>
30 #include <FL/Fl_Button.H>
31 #include <FL/fl_ask.H>
32 #include <FL/Fl_Choice.H>
33 #include <FL/Fl_Native_File_Chooser.H>
34 #include <FL/Fl_Check_Button.H>
35 #include <FL/Fl_Help_Dialog.H>
36 #include <FL/Fl_Widget.H>
38 #include "aoi.hxx"
39 #include "gui_settings.hxx"
40 #include "gui_widgets.hxx"
41 #include "gui_dialogs.hxx"
42 #include "gui_dicview.hxx"
43 #include "gui_kanjiview.hxx"
45 /*! \file gui.hxx
46 * \date 2013/06/19
50 namespace aoi {
51 class App;
54 using std::vector;
55 using std::string;
56 using aoi::App;
59 namespace aoi_ui {
61 class GUI;
63 /*!
64 * Closes all windows and quits FLTK. Used as callback in menu and MainWindow.
66 static void quit_fltk ( Fl_Widget *w, void *p )
68 Fl_Window *mainwindow = (Fl_Window*)p;
69 // hide all other windows
70 Fl_Window *win = Fl::next_window( mainwindow );
71 while ( win ){
72 win->hide();
73 win = Fl::next_window( mainwindow );
75 // hide main window and thus exit program
76 mainwindow->hide();
80 static Fl_Window *last_window ()
82 Fl_Window *w = Fl::first_window();
83 Fl_Window *last = w;
84 while (w){
85 last = w;
86 w = Fl::next_window(w);
88 return last;
92 /*!
93 * Centers window w on first visible window or on parent if parent is not nullptr.
94 * If the w is smaller than parent then positions w on top left corner od parent.
95 * Works only on hidden w.
96 * \param ontop if true then w is brought to the front
97 * \todo does not work after start
98 * \todo check whether ontop works (in creating dictionary)
100 static void center_window ( Fl_Window *w, Fl_Window *parent=nullptr, bool ontop=true)
102 if ( w->visible() )
103 return;
104 if ( !parent )
105 parent = Fl::first_window();
106 if ( !parent )
107 return;
108 // new position
109 int nx = (parent->w() - w->w())/2;
110 int ny = (parent->h() - w->h())/2;
111 if ( nx < 10 ) nx=10;
112 if ( ny < 10 ) ny=10;
113 w->position( parent->x_root()+nx, parent->y_root()+ny );
114 // should ensure, that w will be on top ...
115 if (ontop){
116 w->hide();
117 w->show();
123 /*!
124 * Dialog for the testing of romanization (both hiragana and katakana).
125 * Shows input and output field.
127 class DialogRomanizationTest : public Fl_Double_Window
129 private:
130 Fl_Input *input_ = nullptr;
131 Fl_Input *output_ = nullptr;
132 Fl_Choice *choice_ = nullptr;
133 Fl_Button *b_close_ = nullptr;
134 string buff_;
135 public:
136 DialogRomanizationTest( int w=300, int h=180 );
137 ~DialogRomanizationTest(){};
138 void cb_input ();
139 inline static void scb_input( Fl_Widget *w, void *p )
140 { ((DialogRomanizationTest*)p)->cb_input(); }
141 inline static void scb_close ( Fl_Widget *w, void *p )
142 { ((DialogRomanizationTest*)p)->hide(); }
146 /*! Works as container for all MainWindow related widgets
147 * and handles global shortcuts
148 * ALL CONFIGURATIONS OF ITS WIDGETS SHOULD BE DONE IN GUI::GUI()
150 class MainWindow : public Fl_Double_Window
152 private:
153 GUI *parent_ = nullptr;
154 public:
155 Fl_Menu_Button *b_menu_ = nullptr;
156 Fl_Button *b_toggle_view_ = nullptr; // switch between dictionary and kanjiview
158 Fl_Group *grp_dictionary_ = nullptr;
159 Fl_Group *grp_kanjidic_ = nullptr;
161 // grp_dictionary_
162 DicView *dic_view_ = nullptr;
163 Entry *dic_input_ = nullptr;
164 Fl_Check_Button *cb_verb_ = nullptr;
165 Fl_Check_Button *cb_adj_ = nullptr;
166 Fl_Check_Button *cb_noun_ = nullptr;
167 Fl_Check_Button *cb_expr_ = nullptr;
169 // grp_kanjidic_
170 Label *l_knj_results = nullptr;
171 Entry *e_skip = nullptr;
172 Entry *e_strokes = nullptr;
173 Entry *e_jlpt = nullptr;
174 Entry *e_grade = nullptr;
175 KanjiView *knj_view_ = nullptr;
176 Fl_Choice *knj_orderby_ = nullptr;
177 ComponentView *compo_view_ = nullptr;
178 Fl_Button *b_knj_clear_ = nullptr;
179 Fl_Button *b_knj_search_ = nullptr;
180 Fl_Check_Button *cb_knj_jis208 = nullptr;
181 // toggle sort components by strokes / by freq
182 Fl_Check_Button *cb_knj_components = nullptr;
185 MainWindow ( GUI *parent, int w, int h );
186 ~MainWindow() {};
188 int handle ( int event );
193 * Encapsulates MainWindow and all dialogs.
194 * Provides interface for class App.
195 * \sa App
197 class GUI
199 private:
200 aoi::App *parent_;
202 int font_base_size_ = 12;
203 string fontname_kanji_ = "";
204 string help_file_ = "";
206 MainWindow *main_window_ = nullptr;
208 DialogFontTest *dlg_fonts_ = nullptr;
209 DialogDownload *dlg_download_ = nullptr;
210 DialogProgress *dlg_progress_ = nullptr;
211 KanjiPopupWindow *popup_ = nullptr;
212 Fl_Help_Dialog *dlg_help_ = nullptr;
213 DialogEditWord *dlg_edit_word_ = nullptr;
214 ManageDBDialog *dlg_manage_db_ = nullptr;
216 //! Prevents closing MainWindow when ESC pressed.
217 inline static void scb_main_window_ ( Fl_Widget *w, void *f )
219 if ( Fl::event() == FL_SHORTCUT ){
220 switch ( Fl::event_key() ){
221 case FL_Escape: // dont close main window on ESC
222 case 'm':
223 return;
226 quit_fltk( w, (void*)w );
230 void change_cursor ( Fl_Cursor c = FL_CURSOR_DEFAULT );
233 public:
235 GUI ( aoi::App *parent );
236 ~GUI (){};
239 * Sets FONT_KANJI a FL_SYMBOL (needed in Fl_Help_Dialog).
240 * Initialize fonts in all relevant widgets and dialogs.
242 void init_fonts();
245 * Sets FL_BACKGROUND_COLOR, FL_BACKGROUND2_COLOR, FL_FOREGROUND_COLOR
246 * and FL_SELECTION_COLOR
248 void init_colors();
251 * Displays simple window with the text <i>s</i> and 2 buttons
252 * (default: <b>Yes</b> and </b>No</b>). String <i>s</i> may contain
253 * newlines ('\n').
254 * \return pressed button number (0 for the first, 1 for the second)
256 inline int choice ( const string &s, const string &btn1="Yes",
257 const string &btn2="No" ){
258 return fl_choice( s.c_str(), btn1.c_str(), btn2.c_str(), 0);
262 //! Shows MainWindow and returns Fl::run()
263 int run ( int argc, char **argv );
265 //! Reset checkboxes for filtering pos in dictionary (noun,verb, adj, exp)
266 void reset_filters ();
269 * Shows and sets modal dialog with progress.
271 inline void progress ( float percent, const string &message ){
272 if ( ! dlg_progress_->visible() )
273 dlg_progress_->show();
274 center_window( dlg_progress_ );
275 dlg_progress_->progress( percent, message );
277 //! Hides modal progress dialog.
278 inline void progress_hide (){
279 dlg_progress_->init();
280 dlg_progress_->hide();
281 Fl::check();
285 * Shows simple textview with HTML 2.0 support.
287 inline void show_html ( const string &s ){
288 DialogHtmlView *d = new DialogHtmlView(600,400);
289 d->set(s);
290 d->show();
293 inline void alert ( const char *msg ) { fl_alert("%s",msg); };
294 inline void alert ( const string &s ) { alert(s.c_str()); };
296 /*!
297 * Shows download dialog for given url.
298 * \return name(path) of the downloaded file
300 inline string download_dialog ( const string &url ){
301 string fname = utils::guess_fname_from_url(url);
302 dlg_download_->set_names ( url, fname );
303 center_window( dlg_download_ );
304 dlg_download_->run();
305 return fname;
308 //! Shows no. of found dictionary results in DicView header.
309 inline void set_dic_results ( const string &s )
310 { main_window_->dic_view_->headers( {"","",s} ); };
312 // XXX: does not work
313 //! Shows no. of found kanji results in label.
314 inline void set_kanji_results ( const string &s ) {
315 main_window_->l_knj_results->show();
316 main_window_->l_knj_results->set(s);
319 //! Shows <i>Manage database</i> dialog.
320 inline ManageDBDialog *dlg_manage_db (){
321 center_window( dlg_manage_db_, main_window_);
322 return dlg_manage_db_;
325 /*!
326 * Copy userdata to clipboard and selection buffer (middle button on Linux).
328 static void scb_copy ( Fl_Widget *w, void *userdata ) {
329 const char *d = (const char*)userdata;
330 int len = strlen(d);
331 Fl::copy( d, len, 0);
332 Fl::copy( d, len, 1);
336 //! Change cursor to WAIT (hourglass).
337 inline void cursor_wait () { change_cursor(FL_CURSOR_WAIT); };
338 //! Change cursor to default (arrow).
339 inline void cursor_default () { change_cursor(); }
341 inline bool sort_components_by_strokes () const {
342 return main_window_->cb_knj_components->value();
345 //! Shows <i>Font</i> dialog.
346 int select_font () {
347 center_window( dlg_fonts_ );
348 return dlg_fonts_->run();
351 //! Shows <i>Romanization test</i> dialog.
352 void show_romanization_test ()
354 DialogRomanizationTest *d = new DialogRomanizationTest();
355 d->show();
358 //! Shows dialog <i>Settings</i>.
359 void show_settings ();
361 /*!
362 * Popus menu (context) menu in DicView.
363 * \param did JMdict id of the word.
364 * \param things List of kanji in the word.
365 * \param notes If false then item <i>Notes</i> will be grayed out.
366 * \param examples If false then item <i>Examples</i> will be grayed out.
368 void dicview_menu ( int did, const vector<string> &things, bool notes=false, bool examples=false );
370 // XXX
371 void edit_word ( const aoi::DicWord &w );
373 //! Popups KanjiPopupWindow in KanjiView.
374 void popup_kanji ( const Kanji &k );
376 // interface for App (controller)
377 inline void help_file ( const string &s ) { help_file_ = s; };
378 inline void fontname_kanji ( const string &s )
379 { fontname_kanji_=s; init_fonts(); };
380 inline void font_base_size ( int s )
381 { font_base_size_=s; init_fonts(); };
382 inline string skip () const { return main_window_->e_skip->value(); };
383 inline int sort_mode () const { return main_window_->knj_orderby_->value(); };
384 inline const char *strokes () const { return main_window_->e_strokes->value(); };
385 inline const char *jlpt () const { return main_window_->e_jlpt->value(); };
386 inline const char *grade () const { return main_window_->e_grade->value(); };
387 inline vector<string> components_include () const
388 { return main_window_->compo_view_->selected1(); };
389 inline vector<string> components_exclude () const
390 { return main_window_->compo_view_->selected2(); };
391 inline void highlight_components ( const string &comps )
392 { main_window_->compo_view_->set_highlight(comps); }
394 string ask_file (){
395 Fl_Native_File_Chooser fnfc;
396 fnfc.title("Pick a file");
397 fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
398 switch ( fnfc.show() ) {
399 case -1:
400 throw std::runtime_error( fnfc.errmsg() );
401 break;
402 case 1:
403 return "";
405 return fnfc.filename();
408 vector<string> listview_filters ();
410 inline int dicview_selected_rowid () const
411 { return main_window_->dic_view_->selected_row_id(); };
413 inline void set_components ( const vector<ComponentView::Cell> &v )
414 { main_window_->compo_view_->set_data(v); };
416 inline void set_listview ( const vector<string> &d, const vector<int> &r={} )
417 { main_window_->dic_view_->set_data(d,r); };
418 inline void register_tag_dicview ( const string &tag, const TextStyle &style )
419 { main_window_->dic_view_->register_tag(tag,style); };
421 inline void set_kanjiview ( const vector<KanjiView::Cell> &d )
422 { main_window_->knj_view_->set_data(d); };
424 inline const char *get_dic_input () const
425 { return main_window_->dic_input_->value(); };
427 void cb_toggle_group ();
428 void cb_knj_clear ();
429 void cb_show_help (){
430 dlg_help_->load(help_file_.c_str());
431 dlg_help_->show();
433 void cb_jis208_toggle ();
435 //! See popup_kanji()
436 inline static void scb_knj_clear ( Fl_Widget *w, void *f )
437 {((GUI *)f)->cb_knj_clear(); }
438 inline static void scb_toggle_group(Fl_Widget *w, void *f)
439 {((GUI *)f)->cb_toggle_group();};
440 inline static void scb_show_help(Fl_Widget *w, void *f)
441 {((GUI *)f)->cb_show_help();};
442 inline static void scb_jis208_toggle(Fl_Widget *w, void *f)
443 {((GUI *)f)->cb_jis208_toggle();};
444 inline static void scb_test_romanization ( Fl_Widget *w, void *p )
445 {((GUI*)p)->show_romanization_test(); }
446 inline static void scb_test_fonts ( Fl_Widget *w, void *p )
447 {((GUI*)p)->select_font(); }
448 inline static void scb_show_settings ( Fl_Widget *w, void *p )
449 {((GUI*)p)->show_settings(); }
453 } // namespace
455 #endif // _GUI_HXX