some valgrind indiced changes
[aoi.git] / src / gui.cxx
blobb0861bc5c8781e1e2a0fd314b19865cdcb69159d
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 #include "gui.hxx"
18 #include <sstream>
19 #include "utils.hxx"
21 // RESIZING
22 // http://fltk.org/articles.php?L415+I0+T+M1000+P1
24 namespace aoi_ui {
26 const char *LABEL_DICTIONARY = "D";
27 const char *LABEL_KANJI = "K";
29 //////////////////////////////////////////////////////////////////////////
30 // DialogRomanizationTest
32 DialogRomanizationTest::DialogRomanizationTest( int w, int h )
33 : Fl_Double_Window(w,h){
34 choice_ = new Fl_Choice( 5, 5, w-10, 25 );
35 choice_->add("Hiragana");
36 choice_->add("Katakana");
37 choice_->value(0);
38 choice_->callback( scb_input, (void*)this );
39 input_ = new Fl_Input( 5, 35, w-10, 30 );
40 input_->callback( scb_input, (void*)this );
41 input_->when(FL_WHEN_CHANGED);
42 input_->take_focus();
43 output_ = new Fl_Input( 5, 75, w-10, h-105 );
44 output_->align( FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
45 output_->textfont( FONT_KANJI );
46 output_->textsize( 2*input_->labelsize() );
47 output_->box(FL_BORDER_BOX);
48 label("Romanization test");
49 b_close_ = new Fl_Button( w-65, h-25, 60, 20, "Close");
50 b_close_->callback( scb_close, (void*)this );
51 end();
52 set_modal();
56 void DialogRomanizationTest::cb_input (){
57 const char *s = input_->value();
58 if ( choice_->value() == 0 )
59 buff_ = App::get()->rmn()->romaji_to_hiragana(s).c_str();
60 else
61 buff_ = App::get()->rmn()->romaji_to_katakana(s).c_str();
62 output_->value( buff_.c_str() );
67 MainWindow::MainWindow ( GUI *parent, int w, int h ): Fl_Double_Window(w,h)
69 parent_ = parent;
71 // DICTIONARY
72 grp_dictionary_ = new Fl_Group(0,0,w,h);
74 Fl_Group *grp = new Fl_Group(60,5,200,30);
75 dic_input_ = new Entry( 60, 5, 200, 30, "Insert romaji/kanji" );
76 grp->resizable(0);
77 grp->end();
80 dic_view_ = new DicView( 5, 40, 700, 555 );
81 dic_view_->col_width(0,200);
82 dic_view_->col_width(1,200);
83 // width of the last column is determined dynamically
84 dic_view_->end();
85 cb_noun_ = new Fl_Check_Button(710, 40, 50, 20, "noun");
86 cb_verb_ = new Fl_Check_Button(710, 65, 50, 20, "verb");
87 cb_adj_ = new Fl_Check_Button(710, 90, 50, 20, "adj");
88 cb_expr_ = new Fl_Check_Button(710, 115, 50, 20, "expr");
90 grp_dictionary_->end();
92 // KANJIDIC
93 grp_kanjidic_ = new Fl_Group( 0, 0, WIN_WIDTH, WIN_HEIGHT );
95 Fl_Group *grp = new Fl_Group(60,5,WIN_WIDTH-60-60-2*5,30);
96 e_skip = new Entry( 60, 5, 120, 30, "SKIP" );
97 e_strokes = new Entry( 185, 5, 70, 30, "#" );
98 e_jlpt = new Entry( 260, 5, 40, 30, "JLPT");
99 e_grade = new Entry( 305, 5, 40, 30, "Grd.");
100 knj_orderby_ = new Fl_Choice( 350, 5, 150, 30 );
101 cb_knj_jis208 = new Fl_Check_Button( 505, 5, 100, 30, "JIS 208 only" );
102 b_knj_search_ = new Fl_Button( 615, 5, 60, 30, "Search");
103 b_knj_clear_ = new Fl_Button( 680, 5, 60, 30, "Clear");
104 l_knj_results = new Label( 555, 565, 240, 30 );
105 grp->resizable(0);
106 grp->end();
109 knj_view_ = new KanjiView( 5, 40, 545, 555 );
110 cb_knj_components = new Fl_Check_Button( 555, 40, 250, 25, "Sort by strokes");
111 compo_view_ = new ComponentView( 555, 70, 240, 300);
113 grp_kanjidic_->end();
114 grp_kanjidic_->hide();
116 // ALWAYS VISIBLE BUTTONS
118 int b_width = 10+fl_width( LABEL_DICTIONARY );
119 if ( b_width < 30 )
120 b_width = 30;
121 b_toggle_view_ = new Fl_Button( w-b_width-5, 5, b_width, 30, LABEL_DICTIONARY );
122 Fl_Group *g = new Fl_Group( 5, 5, 50, 30 );
123 b_menu_ = new Fl_Menu_Button( 5, 5, 50, 30, "M");
124 g->end();
125 g->resizable(0);
128 resizable( dic_view_ );
129 resizable( knj_view_ );
130 end();
134 int MainWindow::handle ( int event )
136 unsigned int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT);
137 if ( event == FL_KEYDOWN && mods==FL_CTRL ){
138 switch ( Fl::event_key() ){
139 // Ctrl-L
140 case 'l':
141 if ( grp_dictionary_->visible() )
142 dic_input_->take_focus();
143 else
144 e_skip->take_focus();
145 return 1;
146 // Ctrl-Q
147 case 'q':
148 parent_->cb_toggle_group();
149 return 1;
150 // Ctrl-S
151 case 's':
152 if ( grp_dictionary_->visible() )
153 dic_input_->callback()(dic_input_,(void*)App::get());
154 else
155 b_knj_search_->callback()(dic_input_,(void*)App::get());
156 return 1;
157 // Ctrl-M
158 case 'm':
159 b_menu_->popup();
160 return 1;
161 default:
162 break;
165 return Fl_Double_Window::handle(event);
170 GUI::GUI ( aoi::App *parent ):parent_(parent)
172 Fl::visual(FL_DOUBLE|FL_INDEX);
173 init_colors();
175 dlg_fonts_ = new DialogFontTest();
176 dlg_progress_ = new DialogProgress(300,50);
177 dlg_help_ = new Fl_Help_Dialog();
178 dlg_edit_word_ = new DialogEditWord();
179 dlg_manage_db_ = new ManageDBDialog();
180 dlg_download_ = new DialogDownload(400,125);
182 main_window_ = new MainWindow( this, WIN_WIDTH, WIN_HEIGHT );
183 main_window_->label( WIN_TITLE );
184 main_window_->callback(scb_main_window_);
186 // populate
187 // should be in same order as aoi::KANJI_SORT_MODE
188 main_window_->knj_orderby_->add("Freq (ASC)");
189 main_window_->knj_orderby_->add("Freq (DESC)");
190 main_window_->knj_orderby_->add("Strokes (ASC)");
191 main_window_->knj_orderby_->add("Strokes (DESC)");
192 main_window_->knj_orderby_->value(0);
194 main_window_->cb_knj_jis208->value( parent_->get_config<bool>("knj/jis208_only") );
196 // populate menu
197 main_window_->b_menu_->add("Manage database", 0, App::scb_manage_db, (void*)parent_ );
198 main_window_->b_menu_->add("Settings", 0, scb_show_settings, (void*)this);
199 main_window_->b_menu_->add("Tools/Test romanization", 0,
200 scb_test_romanization, (void*)this);
201 main_window_->b_menu_->add("Tools/Test fonts", 0,
202 scb_test_fonts, (void*)this);
203 main_window_->b_menu_->add("Help && About", 0, scb_show_help, (void*)this);
204 main_window_->b_menu_->add("Quit", 0, quit_fltk, (void*)main_window_ );
206 // callbacks
207 main_window_->dic_input_->callback( App::scb_dic_input, (void*)parent_ );
208 main_window_->dic_view_->cb_doubleclick( App::scb_dicview_doubleclick, (void*)parent_ );
209 main_window_->dic_view_->cb_rightclick( App::scb_dicview_rightclick, (void*)parent_ );
210 main_window_->cb_noun_->callback( App::scb_filter_listview, (void*)parent_ );
211 main_window_->cb_verb_->callback( App::scb_filter_listview, (void*)parent_ );
212 main_window_->cb_adj_->callback( App::scb_filter_listview, (void*)parent_ );
213 main_window_->cb_expr_->callback( App::scb_filter_listview, (void*)parent_ );
214 main_window_->e_skip->callback( App::scb_kanji_search, (void*)parent_);
215 main_window_->knj_orderby_->callback( App::scb_kanji_search, (void*)parent_);
216 main_window_->b_knj_search_->callback( App::scb_kanji_search, (void*)parent_);
217 main_window_->b_knj_clear_->callback( scb_knj_clear, (void*)this);
218 main_window_->knj_view_->cb_leftclick( App::scb_kanjiview_select, (void*)parent_ );
219 main_window_->knj_view_->cb_select( App::scb_kanjiview_select, (void*)parent_ );
220 main_window_->compo_view_->callback( App::scb_kanji_search, (void*)parent_ );
221 main_window_->b_toggle_view_->callback( scb_toggle_group, (void*)this );
222 main_window_->e_strokes->callback( App::scb_kanji_search, (void*)parent_);
223 main_window_->e_jlpt->callback( App::scb_kanji_search, (void*)parent_);
224 main_window_->e_grade->callback( App::scb_kanji_search, (void*)parent_);
225 main_window_->cb_knj_jis208->callback( scb_jis208_toggle, (void*)this);
226 main_window_->cb_knj_components->callback( App::scb_set_components , (void*)parent_ );
228 // other
229 main_window_->dic_input_->when(FL_WHEN_ENTER_KEY_ALWAYS);
230 main_window_->b_menu_->labeltype(FL_NORMAL_LABEL);
231 init_fonts();
233 main_window_->dic_input_->take_focus();
237 GUI::~GUI ()
239 delete dlg_download_;
240 delete dlg_manage_db_;
241 delete dlg_edit_word_;
242 delete dlg_help_;
243 delete dlg_progress_;
244 delete dlg_fonts_;
248 void GUI::init_colors ()
250 parent_->log("Initializing colors.");
252 Fl_Color col = parent_->get_color("foreground");
253 Fl::foreground(col>>24&0xFF, col>>16&0xFF, col>>8&0xFF);
255 col = parent_->get_color("background");
256 Fl::background(col>>24&0xFF, col>>16&0xFF, col>>8&0xFF);
258 col = parent_->get_color("background2");
259 Fl::background2(col>>24&0xFF, col>>16&0xFF, col>>8&0xFF);
261 col = parent_->get_color("selection");
262 Fl::free_color(FL_SELECTION_COLOR);
263 Fl::set_color(FL_SELECTION_COLOR, col>>24&0xFF, col>>16&0xFF, col>>8&0xFF);
265 // redraw widgets
266 if ( !main_window_ )
267 return;
269 for ( int i=0; i < main_window_->children(); i++ )
270 main_window_->child(i)->redraw();
271 Fl::check();
275 void GUI::init_fonts ()
277 Fl::set_font(FL_SYMBOL,fontname_kanji_.c_str()); // for Fl_Help_Dialog
278 Fl::set_font(FONT_KANJI, fontname_kanji_.c_str());
279 if ( dlg_help_ )
280 dlg_help_->textsize( font_base_size_ );
281 if ( main_window_->dic_view_ ){
282 main_window_->dic_view_->font_size( font_base_size_ );
283 main_window_->dic_view_->redraw();
285 if ( main_window_->knj_view_ ) {
286 main_window_->knj_view_->font_size( 3*font_base_size_ );
287 main_window_->knj_view_->redraw();
289 if ( main_window_->compo_view_ ) {
290 main_window_->compo_view_->font_cell( FONT_KANJI, font_base_size_*1.2 );
291 main_window_->compo_view_->font_label( FL_HELVETICA_BOLD, font_base_size_*1.2 );
293 if ( main_window_->dic_input_ ){
294 main_window_->dic_input_->textfont( FONT_KANJI );
295 main_window_->dic_input_->textsize( font_base_size_*1.2 );
300 int GUI::run ( int argc, char **argv )
302 main_window_->show(argc,argv);
303 return Fl::run();
307 void GUI::dicview_menu ( int did, const vector<string> &v, bool notes, bool examples )
309 Fl_Menu_Button menu(Fl::event_x(), Fl::event_y(), 80, 1);
310 menu.textfont(FONT_KANJI);
311 menu.textsize( 1.5*font_base_size_ );
312 for ( string s: v ){
313 menu.add( (s+"/Copy").c_str(), 0, scb_copy, (void*)s.c_str());
314 menu.add( (s+"/Show").c_str(), 0, scb_menu_show_kanji, (void*)this );
316 menu.add("Notes",0,0,0, notes ? 0:FL_MENU_INACTIVE);
317 menu.add("Examples",0, App::scb_examples,(void*)parent_,
318 examples ? 0:FL_MENU_INACTIVE);
319 menu.add("Show", 0, App::scb_edit_word, (void*)parent_);
320 menu.popup();
323 void GUI::edit_word ( const aoi::DicWord &w )
325 dlg_edit_word_->set(w);
326 dlg_edit_word_->show();
329 // callbacks
331 void GUI::cb_jis208_toggle ()
333 parent_->set_config("knj/jis208_only", std::to_string(main_window_->cb_knj_jis208->value()));
334 parent_->scb_kanji_search( nullptr, (void*)parent_);
337 void GUI::cb_toggle_group ()
339 if ( main_window_->grp_dictionary_->visible() ){
340 main_window_->grp_dictionary_->hide();
341 main_window_->grp_kanjidic_->show();
342 main_window_->b_toggle_view_->label(LABEL_KANJI);
344 else {
345 main_window_->grp_dictionary_->show();
346 main_window_->grp_kanjidic_->hide();
347 main_window_->b_toggle_view_->label(LABEL_DICTIONARY);
352 void GUI::popup_kanji ( const Kanji &k )
354 if ( popup_ )
355 delete popup_;
356 popup_ = new KanjiPopupWindow(100,100);
357 popup_->font_a(FL_HELVETICA_BOLD, font_base_size_ );
358 popup_->font_b(FL_HELVETICA, font_base_size_ );
359 popup_->set(k);
360 popup_->popup();
364 void GUI::popup_kanji ( const string &k )
366 popup_kanji(parent_->db_get_kanji(k));
370 void GUI::cb_knj_clear ()
372 main_window_->e_strokes->value("");
373 main_window_->e_skip->value("");
374 main_window_->e_jlpt->value("");
375 main_window_->e_grade->value("");
376 main_window_->compo_view_->set_data();
380 void GUI::reset_filters ()
382 main_window_->cb_noun_->value(0);
383 main_window_->cb_verb_->value(0);
384 main_window_->cb_adj_->value(0);
385 main_window_->cb_expr_->value(0);
389 vector<string> GUI::listview_filters ()
391 vector<string> out;
392 if ( main_window_->cb_noun_->value() )
393 out.push_back("noun");
394 if ( main_window_->cb_verb_->value() )
395 out.push_back("verb");
396 if ( main_window_->cb_adj_->value() )
397 out.push_back("adj");
398 if ( main_window_->cb_expr_->value() )
399 out.push_back("expr");
400 return out;
404 void GUI::show_settings ()
406 DialogSettings d;
407 d.set( parent_->get_config_map(), parent_->get_config_map_default() );
408 parent_->save_config( d.run() );
411 void GUI::change_cursor ( Fl_Cursor c )
413 if ( main_window_ && main_window_->visible() )
414 main_window_->cursor(c);
415 if ( dlg_manage_db_ && dlg_manage_db_->visible() )
416 dlg_manage_db_->cursor(c);
417 Fl::check();
419 } // namespace