GUI:quit_fltk() simplified
[aoi.git] / src / gui.hxx
blobc959c6b136c3a5aba04b21b5289436cf0fa12c32
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 * Contains class GUI, which manages the main window and all the dialogs.
47 * \todo Separate all the functions working as interface for the App.
51 namespace aoi {
52 class App;
56 using std::vector;
57 using std::string;
58 using aoi::App;
61 namespace aoi_ui {
63 class GUI;
65 /*!
66 * Closes all windows and quits FLTK. Used as callback in menu and MainWindow.
68 static void quit_fltk ( Fl_Widget *w, void *p )
71 Fl_Window *mainwindow = (Fl_Window*)p;
72 // hide all other windows
73 Fl_Window *win = Fl::next_window( mainwindow );
74 while ( win ){
75 win->hide();
76 win = Fl::next_window( mainwindow );
78 // hide main window and thus exit program
79 mainwindow->hide();
81 while(Fl::first_window())
82 Fl::first_window()->hide();
86 /*!
87 * Centers the window w on the first visible window or on its parent if the
88 * parent is not nullptr.
89 * If the w is smaller than parent then positions w on top left corner od parent.
90 * Works only on the hidden w.
91 * \param ontop if true then w is brought to the front
92 * \todo does not work after start
93 * \todo check whether ontop works (in creating dictionary)
95 static void center_window ( Fl_Window *w, Fl_Window *parent=nullptr, bool ontop=true)
97 if ( w->visible() )
98 return;
99 if ( !parent )
100 parent = Fl::first_window();
101 if ( !parent )
102 return;
103 // new position
104 int nx = (parent->w() - w->w())/2;
105 int ny = (parent->h() - w->h())/2;
106 if ( nx < 10 ) nx=10;
107 if ( ny < 10 ) ny=10;
108 w->position( parent->x_root()+nx, parent->y_root()+ny );
109 // should ensure, that w will be on top ...
110 if (ontop){
111 w->hide();
112 w->show();
117 /*!
118 * Dialog for the testing of romanization (both hiragana and katakana).
119 * Shows the input and output field.
121 class DialogRomanizationTest : public Fl_Double_Window
123 private:
124 Fl_Input *input_ = nullptr;
125 Fl_Input *output_ = nullptr;
126 Fl_Choice *choice_ = nullptr;
127 Fl_Button *b_close_ = nullptr;
128 string buff_;
129 public:
130 DialogRomanizationTest( int w=300, int h=180 );
131 ~DialogRomanizationTest(){};
132 void cb_input ();
133 inline static void scb_input( Fl_Widget *w, void *p )
134 { ((DialogRomanizationTest*)p)->cb_input(); }
135 inline static void scb_close ( Fl_Widget *w, void *p )
136 { ((DialogRomanizationTest*)p)->hide(); }
140 /*! Container for all MainWindow related widgets.
141 * Handles global shortcuts
142 * ALL THE CONFIGURATIONS OF ITS WIDGETS SHOULD BE DONE IN GUI::GUI()
144 class MainWindow : public Fl_Double_Window
146 private:
147 GUI *parent_ = nullptr;
148 public:
149 Fl_Menu_Button *b_menu_ = nullptr;
150 Fl_Button *b_toggle_view_ = nullptr; // switch between dictionary and kanjiview
152 Fl_Group *grp_dictionary_ = nullptr;
153 Fl_Group *grp_kanjidic_ = nullptr;
155 // grp_dictionary_
156 DicView *dic_view_ = nullptr;
157 Entry *dic_input_ = nullptr;
158 Fl_Check_Button *cb_verb_ = nullptr;
159 Fl_Check_Button *cb_adj_ = nullptr;
160 Fl_Check_Button *cb_noun_ = nullptr;
161 Fl_Check_Button *cb_expr_ = nullptr;
163 // grp_kanjidic_
164 Label *l_knj_results = nullptr;
165 Entry *e_skip = nullptr;
166 Entry *e_strokes = nullptr;
167 Entry *e_jlpt = nullptr;
168 Entry *e_grade = nullptr;
169 KanjiView *knj_view_ = nullptr;
170 Fl_Choice *knj_orderby_ = nullptr;
171 ComponentView *compo_view_ = nullptr;
172 Fl_Button *b_knj_clear_ = nullptr;
173 Fl_Button *b_knj_search_ = nullptr;
174 Fl_Check_Button *cb_knj_jis208 = nullptr;
175 // toggle sort components by strokes / by freq
176 Fl_Check_Button *cb_knj_components = nullptr;
179 MainWindow ( GUI *parent, int w, int h );
180 ~MainWindow() {};
182 int handle ( int event );
187 * Encapsulates the MainWindow and all dialogs.
188 * Provides interface for class App.
189 * \sa App
191 class GUI
193 private:
194 aoi::App *parent_;
196 int font_base_size_ = 12;
197 string fontname_kanji_ = "";
198 string help_file_ = "";
200 MainWindow *main_window_ = nullptr;
202 DialogFontTest *dlg_fonts_ = nullptr;
203 DialogDownload *dlg_download_ = nullptr;
204 DialogProgress *dlg_progress_ = nullptr;
205 KanjiPopupWindow *popup_ = nullptr;
206 Fl_Help_Dialog *dlg_help_ = nullptr;
207 DialogEditWord *dlg_edit_word_ = nullptr;
208 ManageDBDialog *dlg_manage_db_ = nullptr;
210 //! Prevents closing MainWindow when ESC pressed.
211 inline static void scb_main_window_ ( Fl_Widget *w, void *f )
213 if ( Fl::event() == FL_SHORTCUT ){
214 switch ( Fl::event_key() ){
215 case FL_Escape: // dont close main window on ESC
216 case 'm':
217 return;
220 quit_fltk( w, (void*)w );
224 void change_cursor ( Fl_Cursor c = FL_CURSOR_DEFAULT );
227 public:
229 GUI ( aoi::App *parent );
230 ~GUI ();
233 * Sets FONT_KANJI a FL_SYMBOL (needed in Fl_Help_Dialog).
234 * Initialize fonts in all relevant widgets and dialogs.
236 void init_fonts();
239 * Sets FL_BACKGROUND_COLOR, FL_BACKGROUND2_COLOR, FL_FOREGROUND_COLOR
240 * and FL_SELECTION_COLOR
242 void init_colors();
245 * Displays simple window with the text <i>s</i> and 2 buttons
246 * (default: <b>Yes</b> and </b>No</b>). String <i>s</i> may contain
247 * newlines ('\n').
248 * \return pressed button number (0 for the first, 1 for the second)
250 inline int choice ( const string &s, const string &btn1="Yes",
251 const string &btn2="No" ){
252 return fl_choice( s.c_str(), btn1.c_str(), btn2.c_str(), 0);
256 //! Shows MainWindow and returns Fl::run()
257 int run ( int argc, char **argv );
259 //! Reset checkboxes for filtering pos in dictionary (noun,verb, adj, exp)
260 void reset_filters ();
263 * Shows and sets modal dialog with progress.
265 inline void progress ( float percent, const string &message ){
266 if ( ! dlg_progress_->visible() )
267 dlg_progress_->show();
268 center_window( dlg_progress_ );
269 dlg_progress_->progress( percent, message );
271 //! Hides modal progress dialog.
272 inline void progress_hide (){
273 dlg_progress_->init();
274 dlg_progress_->hide();
275 Fl::check();
279 * Shows simple textview with HTML 2.0 support.
281 inline void show_html ( const string &s ){
282 DialogHtmlView *d = new DialogHtmlView(600,400);
283 d->set(s);
284 d->show();
287 inline void alert ( const char *msg ) { fl_alert("%s",msg); };
288 inline void alert ( const string &s ) { alert(s.c_str()); };
290 /*!
291 * Shows download dialog for given url.
292 * \return name(path) of the downloaded file
294 inline string download_dialog ( const string &url ){
295 string fname = utils::guess_fname_from_url(url);
296 dlg_download_->set_names ( url, fname );
297 center_window( dlg_download_ );
298 dlg_download_->run();
299 return fname;
302 //! Shows no. of found dictionary results in DicView header.
303 inline void set_dic_results ( const string &s )
304 { main_window_->dic_view_->headers( {"","",s} ); };
306 // XXX: does not work
307 //! Shows no. of found kanji results in label.
308 inline void set_kanji_results ( const string &s ) {
309 main_window_->l_knj_results->show();
310 main_window_->l_knj_results->set(s);
313 //! Shows <i>Manage database</i> dialog.
314 inline ManageDBDialog *dlg_manage_db (){
315 center_window( dlg_manage_db_, main_window_);
316 return dlg_manage_db_;
319 /*!
320 * Copy userdata to clipboard and selection buffer (middle button on Linux).
322 static void scb_copy ( Fl_Widget *w, void *userdata ) {
323 const char *d = (const char*)userdata;
324 int len = strlen(d);
325 Fl::copy( d, len, 0);
326 Fl::copy( d, len, 1);
330 //! Change the cursor to WAIT (hourglass).
331 inline void cursor_wait () { change_cursor(FL_CURSOR_WAIT); };
332 //! Change the cursor to default (arrow).
333 inline void cursor_default () { change_cursor(); }
335 //! Returns the status of checkbox above the list of the components
336 inline bool sort_components_by_strokes () const {
337 return main_window_->cb_knj_components->value();
340 //! Shows <i>Font</i> dialog.
341 int select_font () {
342 center_window( dlg_fonts_ );
343 return dlg_fonts_->run();
346 //! Shows <i>Romanization test</i> dialog.
347 void show_romanization_test ()
349 DialogRomanizationTest *d = new DialogRomanizationTest();
350 d->show();
353 //! Shows dialog <i>Settings</i>.
354 void show_settings ();
356 /*!
357 * Popups the (context) menu in DicView.
358 * \param did JMdict id of the word.
359 * \param things List of kanji in the word.
360 * \param notes If false then item <i>Notes</i> will be grayed out.
361 * \param examples If false then item <i>Examples</i> will be grayed out.
363 void dicview_menu ( int did, const vector<string> &things,
364 bool notes=false, bool examples=false );
366 /*! Shows the <i>Edit word</i> dialog.
368 void edit_word ( const aoi::DicWord &w );
370 //! Popups KanjiPopupWindow in KanjiView.
371 void popup_kanji ( const Kanji &k );
373 * Tells App to find kanji <i>k</a> in the database
374 * and call popup_kanji( const Kanji &k ).
376 void popup_kanji ( const string &k );
378 //! Sets the file serving as index for the help.
379 inline void help_file ( const string &s ) { help_file_ = s; };
380 /*! Sets the name of the font that will be used for non ASCII characters.
381 * \note the font should be able to display JIS X 208/212/213
383 inline void fontname_kanji ( const string &s )
384 { fontname_kanji_=s; init_fonts(); };
385 //! The base size of the fonts. All other sized are derived from this value.
386 inline void font_base_size ( int s )
387 { font_base_size_=s; init_fonts(); };
388 //! Returns the content of the input field "SKIP"
389 inline string skip () const { return main_window_->e_skip->value(); };
390 //! Return the selected sort mode (in kanjiview)
391 inline int sort_mode () const { return main_window_->knj_orderby_->value(); };
392 //! Returns the content of the input field "Strokes" (#)
393 inline const char *strokes () const { return main_window_->e_strokes->value(); };
394 //! Returns the content of the input field "JLPT"
395 inline const char *jlpt () const { return main_window_->e_jlpt->value(); };
396 //! Returns the content of the input field "Grade" (Grd.)
397 inline const char *grade () const { return main_window_->e_grade->value(); };
398 //! Returns all the components selected by the leftclick.
399 inline vector<string> components_include () const
400 { return main_window_->compo_view_->selected1(); };
401 //! Returns all the components selected by the rightclick.
402 inline vector<string> components_exclude () const
403 { return main_window_->compo_view_->selected2(); };
404 //! Highlights all the components that are the part of the currently selected kanji.
405 inline void highlight_components ( const string &comps )
406 { main_window_->compo_view_->set_highlight(comps); }
408 /*! Displays the fileselection dialog. On the Windows it should be the native
409 * dialog, on the Linux the FLTK's.
410 * \returns path or ""
412 string ask_file (){
413 Fl_Native_File_Chooser fnfc;
414 fnfc.title("Pick a file");
415 fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
416 switch ( fnfc.show() ) {
417 case -1:
418 throw std::runtime_error( fnfc.errmsg() );
419 break;
420 case 1:
421 return "";
423 return fnfc.filename();
426 //! Returns selected fitlers for listview as string ( "noun", "verb", "adj", "expr")
427 vector<string> listview_filters ();
429 inline int dicview_selected_rowid () const
430 { return main_window_->dic_view_->selected_row_id(); };
432 inline void set_components ( const vector<ComponentView::Cell> &v )
433 { main_window_->compo_view_->set_data(v); };
435 inline void set_listview ( const vector<string> &d, const vector<int> &r={} )
436 { main_window_->dic_view_->set_data(d,r); };
437 inline void register_tag_dicview ( const string &tag, const TextStyle &style )
438 { main_window_->dic_view_->register_tag(tag,style); };
440 inline void set_kanjiview ( const vector<KanjiView::Cell> &d )
441 { main_window_->knj_view_->set_data(d); };
443 inline const char *get_dic_input () const
444 { return main_window_->dic_input_->value(); };
446 void cb_toggle_group ();
447 void cb_knj_clear ();
448 void cb_show_help (){
449 dlg_help_->load(help_file_.c_str());
450 dlg_help_->show();
452 void cb_jis208_toggle ();
454 inline static void scb_menu_show_kanji ( Fl_Widget *w, void *p ){
455 char name[64]; // the last picked menu item
456 if ( ((Fl_Menu_*)w)->item_pathname(name, sizeof(name)-1) == 0 )
457 // menu item is in the form: "Kanji/Show"
458 ((GUI*)p)->popup_kanji( strtok( name, "/" ) );
460 inline static void scb_knj_clear ( Fl_Widget *w, void *f )
461 {((GUI *)f)->cb_knj_clear(); }
462 inline static void scb_toggle_group(Fl_Widget *w, void *f)
463 {((GUI *)f)->cb_toggle_group();}
464 inline static void scb_show_help(Fl_Widget *w, void *f)
465 {((GUI *)f)->cb_show_help();}
466 inline static void scb_jis208_toggle(Fl_Widget *w, void *f)
467 {((GUI *)f)->cb_jis208_toggle();}
468 inline static void scb_test_romanization ( Fl_Widget *w, void *p )
469 {((GUI*)p)->show_romanization_test(); }
470 inline static void scb_test_fonts ( Fl_Widget *w, void *p )
471 {((GUI*)p)->select_font(); }
472 inline static void scb_show_settings ( Fl_Widget *w, void *p )
473 {((GUI*)p)->show_settings(); }
477 } // namespace
479 #endif // _GUI_HXX