added Show word as a temp. proxy for EditWord
[aoi.git] / src / gui.hxx
blob92a098b78a92f9dda172311860da63cf0fc8d138
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_Box.H>
29 #include <FL/Fl_Tile.H>
30 #include <FL/Fl_Menu_Button.H>
31 #include <FL/Fl_Button.H>
32 #include <FL/fl_ask.H>
33 #include <FL/Fl_Choice.H>
34 #include <FL/Fl_Native_File_Chooser.H>
35 #include <FL/Fl_Check_Button.H>
36 #include <FL/Fl_Help_Dialog.H>
37 #include <FL/Fl_Widget.H>
39 #include "aoi.hxx"
40 #include "gui_settings.hxx"
41 #include "gui_widgets.hxx"
42 #include "gui_dialogs.hxx"
43 #include "gui_dicview.hxx"
44 #include "gui_kanjiview.hxx"
46 /*! \file gui.hxx
47 * \date 2013/06/19
51 namespace aoi {
52 class App;
55 using std::vector;
56 using std::string;
57 using aoi::App;
60 namespace aoi_ui {
62 class GUI;
64 /*!
65 * Closes all windows and quits FLTK. Used as callback in menu and MainWindow.
67 static void quit_fltk ( Fl_Widget *w, void *p )
69 Fl_Window *mainwindow = (Fl_Window*)p;
70 // hide all other windows
71 Fl_Window *win = Fl::next_window( mainwindow );
72 while ( win ){
73 win->hide();
74 win = Fl::next_window( mainwindow );
76 // hide main window and thus exit program
77 mainwindow->hide();
81 static Fl_Window *last_window ()
83 Fl_Window *w = Fl::first_window();
84 Fl_Window *last = w;
85 while (w){
86 last = w;
87 w = Fl::next_window(w);
89 return last;
93 /*!
94 * Centers window w on first visible window or on parent if parent is not nullptr.
95 * If the w is smaller than parent then positions w on top left corner od parent.
96 * Works only on hidden w.
97 * \param ontop if true then w is brought to the front
98 * \todo does not work after start
99 * \todo check whether ontop works (in creating dictionary)
101 static void center_window ( Fl_Window *w, Fl_Window *parent=nullptr, bool ontop=true)
103 if ( w->visible() )
104 return;
105 if ( !parent )
106 parent = Fl::first_window();
107 if ( !parent )
108 return;
109 // new position
110 int nx = (parent->w() - w->w())/2;
111 int ny = (parent->h() - w->h())/2;
112 if ( nx < 10 ) nx=10;
113 if ( ny < 10 ) ny=10;
114 w->position( parent->x_root()+nx, parent->y_root()+ny );
115 // should ensure, that w will be on top ...
116 if (ontop){
117 w->hide();
118 w->show();
124 /*!
125 * Dialog for the testing of romanization (both hiragana and katakana).
126 * Shows input and output field.
128 class DialogRomanizationTest : public Fl_Double_Window
130 private:
131 Fl_Input *input_ = nullptr;
132 Fl_Box *output_ = nullptr;
133 Fl_Choice *choice_ = nullptr;
134 Fl_Button *b_close_ = nullptr;
135 string buff_;
136 public:
137 DialogRomanizationTest( int w=300, int h=180 );
138 ~DialogRomanizationTest(){};
139 void cb_input ();
140 inline static void scb_input( Fl_Widget *w, void *p )
141 { ((DialogRomanizationTest*)p)->cb_input(); }
142 inline static void scb_close ( Fl_Widget *w, void *p )
143 { ((DialogRomanizationTest*)p)->hide(); }
147 /*! Works as container for all MainWindow related widgets
148 * and handles global shortcuts
149 * ALL CONFIGURATIONS OF ITS WIDGETS SHOULD BE DONE IN GUI::GUI()
151 class MainWindow : public Fl_Double_Window
153 private:
154 GUI *parent_ = nullptr;
155 public:
156 Fl_Menu_Button *b_menu_ = nullptr;
157 Fl_Button *b_toggle_view_ = nullptr; // switch between dictionary and kanjiview
159 Fl_Group *grp_dictionary_ = nullptr;
160 Fl_Group *grp_kanjidic_ = nullptr;
162 // grp_dictionary_
163 DicView *dic_view_ = nullptr;
164 Entry *dic_input_ = nullptr;
165 Fl_Check_Button *cb_verb_ = nullptr;
166 Fl_Check_Button *cb_adj_ = nullptr;
167 Fl_Check_Button *cb_noun_ = nullptr;
168 Fl_Check_Button *cb_expr_ = nullptr;
170 // grp_kanjidic_
171 Fl_Box *l_knj_results = nullptr;
172 Entry *e_skip = nullptr;
173 Entry *e_strokes = nullptr;
174 Entry *e_jlpt = nullptr;
175 Entry *e_grade = nullptr;
176 KanjiView *knj_view_ = nullptr;
177 Fl_Choice *knj_orderby_ = nullptr;
178 ComponentView *compo_view_ = nullptr;
179 Fl_Button *b_knj_clear_ = nullptr;
180 Fl_Button *b_knj_search_ = nullptr;
181 Fl_Check_Button *cb_knj_jis208 = nullptr;
182 // toggle sort components by strokes / by freq
183 Fl_Check_Button *cb_knj_components = nullptr;
186 MainWindow ( GUI *parent, int w, int h );
187 ~MainWindow() {};
189 int handle ( int event );
194 * Encapsulates MainWindow and all dialogs.
195 * Provides interface for class App.
196 * \sa App
198 class GUI
200 private:
201 aoi::App *parent_;
203 int font_base_size_ = 12;
204 string fontname_kanji_ = "";
205 string help_file_ = "";
207 std::map<string,string> buffer_;
209 MainWindow *main_window_ = nullptr;
211 DialogFontTest *dlg_fonts_ = nullptr;
212 DialogDownload *dlg_download_ = nullptr;
213 DialogProgress *dlg_progress_ = nullptr;
214 KanjiPopupWindow *popup_ = nullptr;
215 Fl_Help_Dialog *dlg_help_ = nullptr;
216 DialogEditWord *dlg_edit_word_ = nullptr;
217 ManageDBDialog *dlg_manage_db_ = nullptr;
219 //! Prevents closing MainWindow when ESC pressed.
220 inline static void scb_main_window_ ( Fl_Widget *w, void *f )
222 if ( Fl::event() == FL_SHORTCUT ){
223 switch ( Fl::event_key() ){
224 case FL_Escape: // dont close main window on ESC
225 case 'm':
226 return;
229 quit_fltk( w, (void*)w );
233 void change_cursor ( Fl_Cursor c = FL_CURSOR_DEFAULT );
236 public:
238 GUI ( aoi::App *parent );
239 ~GUI (){};
242 * Sets FONT_KANJI a FL_SYMBOL (needed in Fl_Help_Dialog).
243 * Initialize fonts in all relevant widgets and dialogs.
245 void init_fonts();
248 * Sets FL_BACKGROUND_COLOR, FL_BACKGROUND2_COLOR, FL_FOREGROUND_COLOR
249 * and FL_SELECTION_COLOR
251 void init_colors();
254 //! Shows MainWindow and returns Fl::run()
255 int run ( int argc, char **argv );
257 //! Reset checkboxes for filtering pos in dictionary (noun,verb, adj, exp)
258 void reset_filters ();
261 * Shows and sets modal dialog with progress.
263 inline void progress ( float percent, const string &message ){
264 center_window( dlg_progress_ );
265 dlg_progress_->progress( percent, message );
267 //! Hides modal progress dialog.
268 inline void progress_hide (){
269 dlg_progress_->init();
270 dlg_progress_->hide();
271 Fl::check();
274 inline void alert ( const char *msg ) { fl_alert("%s",msg); };
275 inline void alert ( const string &s ) { alert(s.c_str()); };
277 //! Shows download dialog for given url.
278 inline string download_dialog ( const string &url ){
279 string fname = utils::guess_fname_from_url(url);
280 dlg_download_->set_names ( url, fname );
281 center_window( dlg_download_ );
282 dlg_download_->run();
283 return fname;
286 //! Shows no. of found dictionary results in DicView header.
287 inline void set_dic_results ( const string &s )
288 { main_window_->dic_view_->headers( {"","",s} ); };
289 //! Shows no. of found kanji results in label.
290 inline void set_kanji_results ( const string &s ) {
291 buffer_["kanji_results"] = s;
292 // XXX: ugly hack, but l_knj_results is invisibile if
293 // label(buffer_["kanji_results"].c_str()) of any other
294 // widget is not called ...
295 main_window_->knj_view_->label( buffer_["kanji_results"].c_str() );
296 main_window_->knj_view_->label("");
297 main_window_->l_knj_results->label( buffer_["kanji_results"].c_str() );
300 //! Shows <i>Manage database</i> dialog.
301 inline ManageDBDialog *dlg_manage_db (){
302 center_window( dlg_manage_db_, main_window_);
303 return dlg_manage_db_;
306 /*!
307 * Copy userdata to clipboard and selection buffer (middle button on Linux).
309 static void scb_copy ( Fl_Widget *w, void *userdata ) {
310 const char *d = (const char*)userdata;
311 int len = strlen(d);
312 Fl::copy( d, len, 0);
313 Fl::copy( d, len, 1);
317 //! Change cursor to WAIT (hourglass).
318 inline void cursor_wait () { change_cursor(FL_CURSOR_WAIT); };
319 //! Change cursor to default (arrow).
320 inline void cursor_default () { change_cursor(); }
322 inline bool sort_components_by_strokes () const {
323 return main_window_->cb_knj_components->value();
326 //! Shows <i>Font</i> dialog.
327 int select_font () {
328 center_window( dlg_fonts_ );
329 return dlg_fonts_->run();
332 //! Shows <i>Romanization test</i> dialog.
333 void show_romanization_test ()
335 DialogRomanizationTest *d = new DialogRomanizationTest();
336 d->show();
339 //! Shows dialog <i>Settings</i>.
340 void show_settings ();
342 /*!
343 * Popus menu (context) menu in DicView.
344 * \param did JMdict id of the word.
345 * \param things List of kanji in the word.
346 * \param notes If false then item <i>Notes</i> will be grayed out.
347 * \param examples If false then item <i>Examples</i> will be grayed out.
349 void dicview_menu ( int did, const vector<string> &things, bool notes=false, bool examples=false );
351 // XXX
352 void edit_word ( const aoi::DicWord &w );
354 //! Popups KanjiPopupWindow in KanjiView.
355 void popup_kanji ( const Kanji &k );
357 // interface for App (controller)
358 inline void help_file ( const string &s ) { help_file_ = s; };
359 inline void fontname_kanji ( const string &s )
360 { fontname_kanji_=s; init_fonts(); };
361 inline void font_base_size ( int s )
362 { font_base_size_=s; init_fonts(); };
363 inline string skip () const { return main_window_->e_skip->value(); };
364 inline int sort_mode () const { return main_window_->knj_orderby_->value(); };
365 inline const char *strokes () const { return main_window_->e_strokes->value(); };
366 inline const char *jlpt () const { return main_window_->e_jlpt->value(); };
367 inline const char *grade () const { return main_window_->e_grade->value(); };
368 inline vector<string> components_include () const
369 { return main_window_->compo_view_->selected1(); };
370 inline vector<string> components_exclude () const
371 { return main_window_->compo_view_->selected2(); };
372 inline void highlight_components ( const string &comps )
373 { main_window_->compo_view_->set_highlight(comps); }
375 string ask_file (){
376 Fl_Native_File_Chooser fnfc;
377 fnfc.title("Pick a file");
378 fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
379 switch ( fnfc.show() ) {
380 case -1:
381 throw std::runtime_error( fnfc.errmsg() );
382 break;
383 case 1:
384 return "";
386 return fnfc.filename();
389 vector<string> listview_filters ();
391 inline int dicview_selected_rowid () const
392 { return main_window_->dic_view_->selected_row_id(); };
394 inline void set_components ( const vector<ComponentView::Cell> &v )
395 { main_window_->compo_view_->set_data(v); };
397 inline void set_listview ( const vector<string> &d, const vector<int> &r={} )
398 { main_window_->dic_view_->set_data(d,r); };
399 inline void register_tag_dicview ( const string &tag, const TextStyle &style )
400 { main_window_->dic_view_->register_tag(tag,style); };
402 inline void set_kanjiview ( const vector<KanjiView::Cell> &d )
403 { main_window_->knj_view_->set_data(d); };
405 inline const char *get_dic_input () const
406 { return main_window_->dic_input_->value(); };
408 // callbacks (real)
409 void cb_toggle_group ();
410 void cb_knj_clear ();
411 void cb_show_help (){
412 dlg_help_->load(help_file_.c_str());
413 dlg_help_->show();
415 void cb_jis208_toggle ();
417 // static callbacks - wrappers for real callbacks
418 inline static void scb_knj_clear ( Fl_Widget *w, void *f )
419 {((GUI *)f)->cb_knj_clear(); }
420 inline static void scb_toggle_group(Fl_Widget *w, void *f)
421 {((GUI *)f)->cb_toggle_group();};
422 inline static void scb_show_help(Fl_Widget *w, void *f)
423 {((GUI *)f)->cb_show_help();};
424 inline static void scb_jis208_toggle(Fl_Widget *w, void *f)
425 {((GUI *)f)->cb_jis208_toggle();};
426 inline static void scb_test_romanization ( Fl_Widget *w, void *p )
427 {((GUI*)p)->show_romanization_test(); }
428 inline static void scb_test_fonts ( Fl_Widget *w, void *p )
429 {((GUI*)p)->select_font(); }
430 inline static void scb_show_settings ( Fl_Widget *w, void *p )
431 {((GUI*)p)->show_settings(); }
435 } // namespace
437 #endif // _GUI_HXX