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_DIALOGS_HXX
18 #define _GUI_DIALOGS_HXX
21 #include <curl/curl.h>
22 #include <FL/Fl_Double_Window.H>
23 #include <FL/Fl_Text_Display.H>
24 #include <FL/Fl_Text_Buffer.H>
25 #include <FL/Fl_Menu_Window.H>
26 #include <FL/Fl_Menu_Button.H>
27 #include <FL/Fl_Progress.H>
28 #include <FL/Fl_Choice.H>
29 #include <FL/Fl_Box.H>
30 #include <FL/Fl_Button.H>
31 #include <FL/Fl_Hold_Browser.H>
33 #include <FL/fl_ask.H>
36 #include "gui_widgets.hxx"
37 #include "datatypes.hxx"
39 #include "romanization.hxx"
42 using aoi_config::Config
;
47 class DialogFontTest
: public Fl_Double_Window
50 Fl_Hold_Browser
*browser_
= nullptr;
51 Fl_Box
*l_fonts_
= nullptr;
52 Fl_Box
*l_ascii_
= nullptr;
53 Fl_Box
*l_jis208_
= nullptr;
54 Fl_Box
*l_jis212_
= nullptr;
55 Fl_Box
*l_jis213_
= nullptr;
56 Fl_Box
*l_kana_
= nullptr;
57 Fl_Box
*b_ascii_
= nullptr;
58 Fl_Box
*b_jis208_
= nullptr;
59 Fl_Box
*b_jis212_
= nullptr;
60 Fl_Box
*b_jis213_
= nullptr;
61 Fl_Box
*b_kana_
= nullptr;
62 Fl_Button
*bt_ok_
= nullptr;
63 Fl_Button
*bt_cancel_
= nullptr;
64 Fl_Input
*input_
= nullptr;
66 Fl_Font selected_font_
= -1;
69 DialogFontTest( int w
=600, int h
=400 ) : Fl_Double_Window(w
,h
)
71 browser_
= new Fl_Hold_Browser( 5, 5, 230, 365 );
72 browser_
->callback(static_callback
, (void*)this);
73 l_fonts_
= new Fl_Box( 5, 370, 250, 30 );
74 l_fonts_
->align( FL_ALIGN_INSIDE
|FL_ALIGN_LEFT
);
76 l_ascii_
= new Fl_Box( 240, 5, 110, 40, "ASCII" );
77 l_ascii_
->align( FL_ALIGN_INSIDE
|FL_ALIGN_LEFT
);
78 l_ascii_
->labelfont(FL_BOLD
);
79 b_ascii_
= new Fl_Box( 355, 5, 240, 40, "Hello world" );
80 b_ascii_
->align( FL_ALIGN_INSIDE
|FL_ALIGN_LEFT
);
81 b_ascii_
->labelsize(36);
83 l_kana_
= new Fl_Box( 240, 50, 110, 40, "Kana" );
84 l_kana_
->align( FL_ALIGN_INSIDE
|FL_ALIGN_LEFT
);
85 l_kana_
->labelfont(FL_BOLD
);
86 b_kana_
= new Fl_Box( 355, 50, 240, 40, "ひらーカタ." );
87 b_kana_
->align( FL_ALIGN_INSIDE
|FL_ALIGN_LEFT
);
88 b_kana_
->labelsize(36);
90 l_jis208_
= new Fl_Box( 240, 95, 110, 40, "JIS X 208" );
91 l_jis208_
->align( FL_ALIGN_INSIDE
|FL_ALIGN_LEFT
);
92 l_jis208_
->labelfont(FL_BOLD
);
93 b_jis208_
= new Fl_Box( 355, 95, 240, 40, "龠堯槇遙凜熙");
94 b_jis208_
->align( FL_ALIGN_INSIDE
|FL_ALIGN_LEFT
);
95 b_jis208_
->labelsize(36);
97 l_jis212_
= new Fl_Box( 240, 140, 110, 40, "JIS X 212" );
98 l_jis212_
->align( FL_ALIGN_INSIDE
|FL_ALIGN_LEFT
);
99 l_jis212_
->labelfont(FL_BOLD
);
100 b_jis212_
= new Fl_Box( 355, 140, 240, 40, "龑龒龔龖龗龞");
101 b_jis212_
->align( FL_ALIGN_INSIDE
|FL_ALIGN_LEFT
);
102 b_jis212_
->labelsize(36);
105 l_jis213_
= new Fl_Box( 240, 185, 110, 40, "JIS X 213" );
106 l_jis213_
->align( FL_ALIGN_INSIDE
|FL_ALIGN_LEFT
);
107 l_jis213_
->labelfont(FL_BOLD
);
108 b_jis213_
= new Fl_Box( 355, 185, 240, 40, "臭艹艹著贈辶");
109 b_jis213_
->align( FL_ALIGN_INSIDE
|FL_ALIGN_LEFT
);
110 b_jis213_
->labelsize(36);
112 input_
= new Fl_Input( 240, 270, 350, 40, "Custom text" );
113 input_
->align( FL_ALIGN_TOP_LEFT
);
114 input_
->labelfont( FL_HELVETICA
|FL_BOLD
);
116 bt_ok_
= new Fl_Button( w
-70, h
-35, 65, 30, "OK");
117 bt_ok_
->callback( static_ok
, (void*)this );
118 bt_cancel_
= new Fl_Button( w
-140, h
-35, 65, 30, "Cancel");
119 bt_cancel_
->callback( static_cancel
, (void*)this );
122 Fl_Font n_fonts
= Fl::set_fonts("*");
124 Fl_Font n_fonts
= Fl::set_fonts("-*-*-*-*-*-*-*-*-*-*-*-*-iso10646-1");
127 s_fonts_
= std::to_string(n_fonts
) + string(" fonts found");
128 l_fonts_
->label(s_fonts_
.c_str());
130 for ( int i
=0; i
<n_fonts
; ++i
){
131 const char *name
= Fl::get_font_name(i
);
132 browser_
->add( name
, (void*)i
);
136 browser_
->hide( FL_SYMBOL
+1 ); // protected for Help_View
137 // browser_->hide( FONT_KANJI+1 ); // reserved for program
143 void cb ( Fl_Font f
){
144 b_ascii_
->labelfont(f
);
145 b_kana_
->labelfont(f
);
146 b_jis208_
->labelfont(f
);
147 b_jis212_
->labelfont(f
);
148 b_jis213_
->labelfont(f
);
154 selected_font_
= browser_
->value()-1;
169 return selected_font();
172 inline Fl_Font
selected_font() const { return selected_font_
; };
173 inline static void static_callback ( Fl_Widget
*w
, void *p
)
174 { ((DialogFontTest
*)p
)->cb( ((Fl_Hold_Browser
*)w
)->value()-1 ); };
175 inline static void static_ok ( Fl_Widget
*w
, void *p
)
176 { ((DialogFontTest
*)p
)->cb_ok(); }
177 inline static void static_cancel ( Fl_Widget
*w
, void *p
)
178 { ((DialogFontTest
*)p
)->cb_cancel(); };
183 class DialogDownload
: public Fl_Double_Window
186 Fl_Progress
*progress_
= nullptr;
187 Fl_Button
*b_abort_
= nullptr;
188 Fl_Button
*b_url_
= nullptr;
189 Fl_Button
*b_fname_
= nullptr;
190 Fl_Button
*b_dload_
= nullptr;
191 Fl_Box
*l_url_
= nullptr;
192 Fl_Box
*l_fname_
= nullptr;
195 static bool abort_download_
;
196 bool downloading_
= false;
199 DialogDownload( int w
=400, int h
=125 );
202 static size_t mycurl_write_func(void *ptr
, size_t size
, size_t nmemb
, FILE *stream
)
204 size_t written
= fwrite(ptr
, size
, nmemb
, (FILE *)stream
);
207 static size_t mycurl_read_func(void *ptr
, size_t size
, size_t nmemb
, FILE *stream
)
208 { return fread(ptr
, size
, nmemb
, stream
); }
210 static int mycurl_progress_func(void *progress_widget
,
211 double dltotal
, double dlnow
,
212 double ultotal
, double ulnow
)
214 float perc
= 100.*dlnow
/dltotal
;
216 sprintf(buff
, "%.1f%% of %.1f MB", perc
, dltotal
/1024/1024);
217 ((Fl_Progress
*)progress_widget
)->label( buff
);
218 ((Fl_Progress
*)progress_widget
)->value(perc
);
220 // non-zero cancels download
221 return abort_download_
;
232 void download_url( const char *url
, const char *fname
);
233 void set_names ( const string
&url
, const string
&fname
="" );
236 void cb_url_callback ();
237 void cb_fname_callback ();
239 inline static void scb_url_callback ( Fl_Widget
*w
, void *p
){
240 ((DialogDownload
*)p
)->cb_url_callback(); }
241 inline static void scb_fname_callback ( Fl_Widget
*w
, void *p
){
242 ((DialogDownload
*)p
)->cb_fname_callback(); }
243 inline static void scb_abort ( Fl_Widget
*w
, void *p
){
244 ((DialogDownload
*)p
)->abort(); }
245 inline static void scb_download ( Fl_Widget
*w
, void *p
){
246 ((DialogDownload
*)p
)->cb_download(); }
247 inline static void scb_close_window ( Fl_Widget
*w
, void *f
){
248 // dont close main window on ESC
249 if ( Fl::event() == FL_SHORTCUT
&& Fl::event_key() == FL_Escape
)
251 // dont close when download in progress
252 if ( ((DialogDownload
*)f
)->downloading_
) {
253 fl_message("You must abort download before closing window." );
256 ((DialogDownload
*)w
)->hide();
261 class EditWordDialog
: public Fl_Double_Window
266 EditWordDialog ( int x
, int y
, int w
, int h
, const char *l
="Edit word" );
271 class ManageDBDialog
: public Fl_Double_Window
274 class Item
: public Fl_Group
277 Fl_Box
*l_name_
= nullptr;
278 Fl_Box
*l_ver_
= nullptr;
279 Fl_Menu_Button
*menu_
= nullptr;
280 Fl_Box
*l_desc_
= nullptr;
285 Item ( int x
, int y
, int w
, int h
, const char *l
=0 );
287 void set ( const string
&title
, const string
&version
,
288 const string
&description
, Fl_Color col
,
289 Fl_Callback
*f_file
, Fl_Callback
*f_download
, void *cb_data
);
290 inline string
title () const { return title_
; }
291 inline void version ( string s
, Fl_Color c
)
292 { version_
= s
; l_ver_
->label(version_
.c_str()); l_ver_
->labelcolor(c
); }
296 Fl_Button
*b_close_
= nullptr;
299 ManageDBDialog ( int w
=300, int h
=200, const char *l
="Manage Database" );
302 void add_item ( const string
&name
, const string
&version
,
303 const string
&description
, Fl_Color col
=FL_BLACK
,
304 Fl_Callback
*f_file
=nullptr, Fl_Callback
*f_download
=nullptr,
305 void *cb_data
=nullptr );
306 inline Item
*item ( const string
&name
)
308 for ( int i
=0; i
<children(); i
++ ){
309 Item
*pi
= dynamic_cast<Item
*>(child(i
));
310 if ( pi
&& pi
->title() == name
)
315 inline static void scb_close ( Fl_Widget
*w
, void *p
)
316 { ((ManageDBDialog
*)p
)->hide(); };
320 class KanjiPopupWindow
: public Fl_Menu_Window
326 KanjiPopupWindow ( int w
, int h
);
327 ~KanjiPopupWindow (){};
329 inline void font_a ( Fl_Font f
, int s
) { box_
->font_a( f
, s
); }
330 inline void font_b ( Fl_Font f
, int s
) { box_
->font_b( f
, s
); }
331 inline void set ( const Kanji
&k
) { box_
->set_data(k
); }
333 int handle ( int event
);
335 inline void popup() {
336 // XXX: after clear_border() take_focus() does not work
338 // position at cursor
339 position(Fl::event_x_root(), Fl::event_y_root());
340 size( box_
->w(), box_
->h());
347 class DialogTextDisplay
: public Fl_Double_Window
350 Fl_Text_Buffer
*buffer_
= nullptr;
351 Fl_Text_Display
*display_
= nullptr;
352 Fl_Button
*b_close_
= nullptr;
353 Fl_Button
*b_copy_
= nullptr;
355 DialogTextDisplay( int w
=300, int h
=200 ) : Fl_Double_Window(w
,h
){
356 printf("DialogTextDisplay\n");
357 b_close_
= new Fl_Button( w
-75, h
-30, 70, 30, "Close" );
358 b_copy_
= new Fl_Button( 5, h
-30, 70, 30, "Copy");
359 display_
= new Fl_Text_Display( 5, 5, w
-10, h
-35 );
360 buffer_
= new Fl_Text_Buffer();
361 b_close_
->callback( scb_close
, (void*)this );
362 b_copy_
->callback( scb_copy
, (void*)this);
363 display_
->buffer( buffer_
);
367 void set_text ( const string
&s
, Fl_Font f
=FL_HELVETICA
){
368 display_
->textfont(f
);
369 buffer_
->text(s
.c_str());
374 inline static void scb_close ( Fl_Widget
*w
, void *p
){
375 ((DialogTextDisplay
*)p
)->cb_close(); };
376 inline static void scb_copy ( Fl_Widget
*w
, void *p
) {
377 const char *d
= ((DialogTextDisplay
*)p
)->buffer_
->text();
379 Fl::copy( d
, len
, 0);
380 Fl::copy( d
, len
, 1);
386 class DialogAlert
: public Fl_Double_Window
389 string message_
= "";
390 string description_
= "";
392 Fl_Button
*b_ok_
= nullptr;
393 Fl_Button
*b_desc_
= nullptr; // popup description
394 Fl_Font font_desc_
= FONT_KANJI
;
395 Fl_Box
*box_
= nullptr;
398 DialogAlert( int w
=300, int h
=200) : Fl_Double_Window(w
,h
){
399 int bw
= 70; // button width
400 int bh
= 25; // button height
401 box_
= new Fl_Box( 5, 5, w
-10, h
-bh
-15);
402 b_ok_
= new Fl_Button( w
-5-bw
, h
-5-bh
, bw
, bh
, "OK" );
403 b_ok_
->callback( scb_close
, (void*)this );
404 b_desc_
= new Fl_Button( 5, h
-5-bh
, 100, bh
, "Description");
405 b_desc_
->callback( scb_show_description
, (void*)this );
406 b_desc_
->deactivate();
412 void set_text ( const string
&msg
, const string
&desc
){
414 b_desc_
->deactivate();
418 box_
->label(message_
.c_str());
426 void cb_show_description (){
429 d
.set_text(description_
.c_str(), font_desc_
);
433 inline static void scb_show_description ( Fl_Widget
*w
, void *p
){
434 ((DialogAlert
*)p
)->cb_show_description(); }
436 inline static void scb_close ( Fl_Widget
*w
, void *p
){
437 ((DialogAlert
*)p
)->cb_close(); };
441 class DialogProgress
: public Fl_Double_Window
444 string message_
= "";
445 Fl_Progress
*progress_
= nullptr;
448 DialogProgress( int w
, int h
):Fl_Double_Window(w
,h
){
449 box( FL_BORDER_BOX
);
450 progress_
= new Fl_Progress( 10, 10, w
-20, 30 );
451 progress_
->minimum(0);
452 progress_
->maximum(1);
459 void init () { message_
= ""; }
461 void progress ( float percent
, const string
&message
="" ){
463 progress_
->label(message_
.c_str());
464 progress_
->value( percent
/100. );
470 class DialogSettings
: public Fl_Double_Window
473 Fl_Hold_Browser
*browser_
= nullptr;
474 Fl_Button
*b_ok_
= nullptr;
475 Fl_Button
*b_defaults_
= nullptr;
476 std::map
<string
,Config::Value
> data_
;
477 std::map
<string
,Config::Value
> defaults_
;
480 DialogSettings( int w
=400, int h
=500 );
482 int handle ( int event
);
483 std::map
<string
,Config::Value
> run ();
484 void set ( const std::map
<string
,Config::Value
> &m
, const std::map
<string
,Config::Value
> &defaults
={} );
485 inline void restore_defaults () {
489 void cb ( int line
);
490 inline static void static_callback ( Fl_Widget
*w
, void *p
)
491 { ((DialogSettings
*)p
)->cb( ((Fl_Hold_Browser
*)w
)->value()); };
492 inline static void static_ok ( Fl_Widget
*w
, void *p
)
493 { ((DialogSettings
*)p
)->hide(); }
494 inline static void scb_restore_defaults ( Fl_Widget
*w
, void *p
)
495 { ((DialogSettings
*)p
)->restore_defaults(); };
498 } // namespace aoi_ui
499 #endif // _GUI_DIALOGS_HXX