OPT added to MAkefile; KanjiView::Cell constructor: fg,bg changed to int (Fl_Color...
[aoi.git] / src / gui.cxx
blob7e03e0fa011dd7bcdca40242cfccc61b1be7923a
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"
22 namespace aoi_ui {
24 const char *LABEL_DICTIONARY = "D";
25 const char *LABEL_KANJI = "K";
27 //////////////////////////////////////////////////////////////////////////
28 // DialogRomanizationTest
30 DialogRomanizationTest::DialogRomanizationTest( int w, int h )
31 : Fl_Double_Window(w,h){
32 choice_ = new Fl_Choice( 5, 5, w-10, 25 );
33 choice_->add("Hiragana");
34 choice_->add("Katakana");
35 choice_->value(0);
36 choice_->callback( scb_input, (void*)this );
37 input_ = new Fl_Input( 5, 35, w-10, 30 );
38 input_->callback( scb_input, (void*)this );
39 input_->when(FL_WHEN_CHANGED);
40 input_->take_focus();
41 output_ = new Fl_Input( 5, 75, w-10, h-105 );
42 output_->align( FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
43 output_->textfont( FONT_KANJI );
44 output_->textsize( 2*input_->labelsize() );
45 output_->box(FL_BORDER_BOX);
46 label("Romanization test");
47 b_close_ = new Fl_Button( w-65, h-25, 60, 20, "Close");
48 b_close_->callback( scb_close, (void*)this );
49 end();
50 set_modal();
54 void DialogRomanizationTest::cb_input (){
55 const char *s = input_->value();
56 if ( choice_->value() == 0 )
57 buff_ = App::get()->rmn()->romaji_to_hiragana(s).c_str();
58 else
59 buff_ = App::get()->rmn()->romaji_to_katakana(s).c_str();
60 output_->value( buff_.c_str() );
64 MainWindow::MainWindow ( GUI *parent, int w, int h ): Fl_Double_Window(w,h)
66 parent_ = parent;
68 // DICTIONARY
69 grp_dictionary_ = new Fl_Group(0,0,w,h);
71 Fl_Group *grp = new Fl_Group(60,5,200,30);
72 dic_input_ = new Entry( 60, 5, 200, 30, "Insert romaji/kanji" );
73 grp->resizable(0);
74 grp->end();
77 dic_view_ = new DicView( 5, 40, 700, 555 );
78 dic_view_->col_width(0,200);
79 dic_view_->col_width(1,200);
80 // width of the last column is determined dynamically
81 dic_view_->end();
82 cb_noun_ = new Fl_Check_Button(710, 40, 50, 20, "noun");
83 cb_verb_ = new Fl_Check_Button(710, 65, 50, 20, "verb");
84 cb_adj_ = new Fl_Check_Button(710, 90, 50, 20, "adj");
85 cb_expr_ = new Fl_Check_Button(710, 115, 50, 20, "expr");
87 grp_dictionary_->end();
89 // KANJIDIC
90 grp_kanjidic_ = new Fl_Group( 0, 0, WIN_WIDTH, WIN_HEIGHT );
92 Fl_Group *grp = new Fl_Group(60,5,WIN_WIDTH-60-60-2*5,30);
93 e_skip = new Entry( 60, 5, 120, 30, "SKIP" );
94 e_strokes = new Entry( 185, 5, 70, 30, "#" );
95 e_jlpt = new Entry( 260, 5, 40, 30, "JLPT");
96 e_grade = new Entry( 305, 5, 40, 30, "Grd.");
97 knj_orderby_ = new Fl_Choice( 350, 5, 150, 30 );
98 cb_knj_jis208 = new Fl_Check_Button( 505, 5, 100, 30, "JIS 208 only" );
99 b_knj_search_ = new Fl_Button( 615, 5, 60, 30, "Search");
100 b_knj_clear_ = new Fl_Button( 680, 5, 60, 30, "Clear");
101 l_knj_results = new Label( 555, 565, 240, 30 );
102 grp->resizable(0);
103 grp->end();
106 knj_view_ = new KanjiView( 5, 40, 545, 555 );
107 cb_knj_components = new Fl_Check_Button( 555, 40, 250, 25, "Sort by strokes");
108 compo_view_ = new ComponentView( 555, 70, 240, 300);
110 grp_kanjidic_->end();
111 grp_kanjidic_->hide();
113 // ALWAYS VISIBLE BUTTONS
115 int b_width = 10+fl_width( LABEL_DICTIONARY );
116 if ( b_width < 30 )
117 b_width = 30;
118 b_toggle_view_ = new Fl_Button( w-b_width-5, 5, b_width, 30, LABEL_DICTIONARY );
119 Fl_Group *g = new Fl_Group( 5, 5, 50, 30 );
120 b_menu_ = new Fl_Menu_Button( 5, 5, 50, 30, "M");
121 g->end();
122 g->resizable(0);
125 resizable( dic_view_ );
126 resizable( knj_view_ );
127 end();
131 int MainWindow::handle ( int event )
133 unsigned int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT);
134 if ( event == FL_KEYDOWN && mods==FL_CTRL ){
135 switch ( Fl::event_key() ){
136 // Ctrl-L
137 case 'l':
138 if ( grp_dictionary_->visible() )
139 dic_input_->take_focus();
140 else
141 e_skip->take_focus();
142 return 1;
143 // Ctrl-Q
144 case 'q':
145 parent_->cb_toggle_group();
146 return 1;
147 // Ctrl-S
148 case 's':
149 if ( grp_dictionary_->visible() )
150 dic_input_->callback()(dic_input_,(void*)App::get());
151 else
152 b_knj_search_->callback()(dic_input_,(void*)App::get());
153 return 1;
154 // Ctrl-M
155 case 'm':
156 b_menu_->popup();
157 return 1;
158 default:
159 break;
162 return Fl_Double_Window::handle(event);
166 GUI::GUI ( aoi::App *parent ):parent_(parent)
168 Fl::visual(FL_DOUBLE|FL_INDEX);
169 init_colors();
171 dlg_fonts_ = new DialogFontTest();
172 dlg_progress_ = new DialogProgress(300,50);
173 dlg_help_ = new Fl_Help_Dialog();
174 dlg_edit_word_ = new DialogEditWord();
175 dlg_manage_db_ = new ManageDBDialog();
176 dlg_download_ = new DialogDownload(400,125);
178 main_window_ = new MainWindow( this, WIN_WIDTH, WIN_HEIGHT );
179 main_window_->label( WIN_TITLE );
180 main_window_->callback(scb_main_window_);
182 // populate
183 // should be in same order as aoi::KANJI_SORT_MODE
184 main_window_->knj_orderby_->add("Freq (ASC)");
185 main_window_->knj_orderby_->add("Freq (DESC)");
186 main_window_->knj_orderby_->add("Strokes (ASC)");
187 main_window_->knj_orderby_->add("Strokes (DESC)");
188 main_window_->knj_orderby_->value(0);
190 main_window_->cb_knj_jis208->value( parent_->get_config<bool>("knj/jis208_only") );
192 // populate menu
193 main_window_->b_menu_->add("Manage database", 0, App::scb_manage_db, (void*)parent_ );
194 main_window_->b_menu_->add("Settings", 0, scb_show_settings, (void*)this);
195 main_window_->b_menu_->add("Tools/Test romanization", 0,
196 scb_test_romanization, (void*)this);
197 main_window_->b_menu_->add("Tools/Test fonts", 0,
198 scb_test_fonts, (void*)this);
199 main_window_->b_menu_->add("Help && About", 0, scb_show_help, (void*)this);
200 main_window_->b_menu_->add("Quit", 0, quit_fltk, (void*)main_window_ );
202 // callbacks
203 main_window_->dic_input_->callback( App::scb_dic_input, (void*)parent_ );
204 main_window_->dic_view_->cb_doubleclick( App::scb_dicview_doubleclick, (void*)parent_ );
205 main_window_->dic_view_->cb_rightclick( App::scb_dicview_rightclick, (void*)parent_ );
206 main_window_->cb_noun_->callback( App::scb_filter_listview, (void*)parent_ );
207 main_window_->cb_verb_->callback( App::scb_filter_listview, (void*)parent_ );
208 main_window_->cb_adj_->callback( App::scb_filter_listview, (void*)parent_ );
209 main_window_->cb_expr_->callback( App::scb_filter_listview, (void*)parent_ );
210 main_window_->e_skip->callback( App::scb_kanji_search, (void*)parent_);
211 main_window_->knj_orderby_->callback( App::scb_kanji_search, (void*)parent_);
212 main_window_->b_knj_search_->callback( App::scb_kanji_search, (void*)parent_);
213 main_window_->b_knj_clear_->callback( scb_knj_clear, (void*)this);
214 main_window_->knj_view_->cb_leftclick( App::scb_kanjiview_select, (void*)parent_ );
215 main_window_->knj_view_->cb_select( App::scb_kanjiview_select, (void*)parent_ );
216 main_window_->compo_view_->callback( App::scb_kanji_search, (void*)parent_ );
217 main_window_->b_toggle_view_->callback( scb_toggle_group, (void*)this );
218 main_window_->e_strokes->callback( App::scb_kanji_search, (void*)parent_);
219 main_window_->e_jlpt->callback( App::scb_kanji_search, (void*)parent_);
220 main_window_->e_grade->callback( App::scb_kanji_search, (void*)parent_);
221 main_window_->cb_knj_jis208->callback( scb_jis208_toggle, (void*)this);
222 main_window_->cb_knj_components->callback( App::scb_set_components , (void*)parent_ );
224 // other
225 main_window_->dic_input_->when(FL_WHEN_ENTER_KEY_ALWAYS);
226 main_window_->b_menu_->labeltype(FL_NORMAL_LABEL);
227 init_fonts();
229 main_window_->dic_input_->take_focus();
233 GUI::~GUI ()
235 delete dlg_download_;
236 delete dlg_manage_db_;
237 delete dlg_edit_word_;
238 delete dlg_help_;
239 delete dlg_progress_;
240 delete dlg_fonts_;
244 void GUI::init_colors ()
246 parent_->log("Initializing colors.");
248 Fl_Color col = parent_->get_color("foreground");
249 Fl::foreground(col>>24&0xFF, col>>16&0xFF, col>>8&0xFF);
251 col = parent_->get_color("background");
252 Fl::background(col>>24&0xFF, col>>16&0xFF, col>>8&0xFF);
254 col = parent_->get_color("background2");
255 Fl::background2(col>>24&0xFF, col>>16&0xFF, col>>8&0xFF);
257 col = parent_->get_color("selection");
258 Fl::free_color(FL_SELECTION_COLOR);
259 Fl::set_color(FL_SELECTION_COLOR, col>>24&0xFF, col>>16&0xFF, col>>8&0xFF);
261 // redraw widgets
262 if ( !main_window_ )
263 return;
265 for ( int i=0; i < main_window_->children(); i++ )
266 main_window_->child(i)->redraw();
267 Fl::check();
271 void GUI::init_fonts ()
273 Fl::set_font(FL_SYMBOL,fontname_kanji_.c_str()); // used in Fl_Help_Dialog
274 Fl::set_font(FONT_KANJI, fontname_kanji_.c_str());
275 if ( dlg_help_ )
276 dlg_help_->textsize( font_base_size_ );
277 if ( main_window_->dic_view_ ){
278 main_window_->dic_view_->font_size( font_base_size_ );
279 main_window_->dic_view_->redraw();
281 if ( main_window_->knj_view_ ) {
282 main_window_->knj_view_->font_size( 3*font_base_size_ );
283 main_window_->knj_view_->redraw();
285 if ( main_window_->compo_view_ ) {
286 main_window_->compo_view_->font_cell( FONT_KANJI, font_base_size_*1.2 );
287 main_window_->compo_view_->font_label( FL_HELVETICA_BOLD, font_base_size_*1.2 );
289 if ( main_window_->dic_input_ ){
290 main_window_->dic_input_->textfont( FONT_KANJI );
291 main_window_->dic_input_->textsize( font_base_size_*1.2 );
296 int GUI::run ( int argc, char **argv )
298 main_window_->show(argc,argv);
299 return Fl::run();
303 void GUI::dicview_menu ( int did, const vector<string> &v, bool notes, bool examples )
305 Fl_Menu_Button menu(Fl::event_x(), Fl::event_y(), 80, 1);
306 menu.textfont(FONT_KANJI);
307 menu.textsize( 1.5*font_base_size_ );
308 for ( string s: v ){
309 menu.add( (s+"/Copy").c_str(), 0, scb_copy, (void*)s.c_str());
310 menu.add( (s+"/Show").c_str(), 0, scb_menu_show_kanji, (void*)this );
312 menu.add("Notes",0,0,0, notes ? 0:FL_MENU_INACTIVE);
313 menu.add("Examples",0, App::scb_examples,(void*)parent_,
314 examples ? 0:FL_MENU_INACTIVE);
315 menu.add("Show", 0, App::scb_edit_word, (void*)parent_);
316 menu.popup();
320 void GUI::edit_word ( const aoi::DicWord &w )
322 dlg_edit_word_->set(w);
323 dlg_edit_word_->show();
327 void GUI::cb_jis208_toggle ()
329 parent_->set_config("knj/jis208_only",
330 std::to_string(main_window_->cb_knj_jis208->value()));
331 parent_->scb_kanji_search( nullptr, (void*)parent_);
335 void GUI::cb_toggle_group ()
337 if ( main_window_->grp_dictionary_->visible() ){
338 main_window_->grp_dictionary_->hide();
339 main_window_->grp_kanjidic_->show();
340 main_window_->b_toggle_view_->label(LABEL_KANJI);
342 else {
343 main_window_->grp_dictionary_->show();
344 main_window_->grp_kanjidic_->hide();
345 main_window_->b_toggle_view_->label(LABEL_DICTIONARY);
350 void GUI::popup_kanji ( const Kanji &k )
352 if ( popup_ )
353 delete popup_;
354 popup_ = new KanjiPopupWindow(100,100);
355 popup_->font_a(FL_HELVETICA_BOLD, font_base_size_ );
356 popup_->font_b(FL_HELVETICA, font_base_size_ );
357 popup_->set(k);
358 popup_->popup();
362 void GUI::popup_kanji ( const string &k )
364 popup_kanji(parent_->db_get_kanji(k));
368 void GUI::cb_knj_clear ()
370 main_window_->e_strokes->value("");
371 main_window_->e_skip->value("");
372 main_window_->e_jlpt->value("");
373 main_window_->e_grade->value("");
374 main_window_->compo_view_->set_data();
378 void GUI::reset_filters ()
380 main_window_->cb_noun_->value(0);
381 main_window_->cb_verb_->value(0);
382 main_window_->cb_adj_->value(0);
383 main_window_->cb_expr_->value(0);
387 vector<string> GUI::listview_filters ()
389 vector<string> out;
390 if ( main_window_->cb_noun_->value() )
391 out.push_back("noun");
392 if ( main_window_->cb_verb_->value() )
393 out.push_back("verb");
394 if ( main_window_->cb_adj_->value() )
395 out.push_back("adj");
396 if ( main_window_->cb_expr_->value() )
397 out.push_back("expr");
398 return out;
402 void GUI::show_settings ()
404 DialogSettings d;
405 d.set( parent_->get_config_map(), parent_->get_config_map_default() );
406 parent_->save_config( d.run() );
409 void GUI::change_cursor ( Fl_Cursor c )
411 if ( main_window_ && main_window_->visible() )
412 main_window_->cursor(c);
413 if ( dlg_manage_db_ && dlg_manage_db_->visible() )
414 dlg_manage_db_->cursor(c);
415 Fl::check();
417 } // namespace