naev 0.12.5
dialogue.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
20#include <stdarg.h>
21#include <stdlib.h>
22
23#include "naev.h"
25
26#include "dialogue.h"
27
28#include "conf.h"
29#include "input.h"
30#include "log.h"
31#include "menu.h"
32#include "ndata.h"
33#include "opengl.h"
34#include "toolkit.h"
35
36static int dialogue_open;
37static int dlgid = 0;
38
39/*
40 * Custom widget scary stuff.
41 */
42typedef struct dialogue_update_s {
43 unsigned int wid;
44 int ( *update )( double, void * );
45 void *data;
48 int ( *event )( unsigned int, SDL_Event *, void * );
49 void *data;
50 int mx;
51 int my;
52 int w;
53 int h;
54 int last_w;
55 int last_h;
56};
57static int dialogue_custom_event( unsigned int wid, SDL_Event *event );
58
59/*
60 * Prototypes.
61 */
62/* extern */
63extern void main_loop( int nested ); /* from naev.c */
64/* generic */
65static void dialogue_close( unsigned int wid, const char *str );
66static void dialogue_cancel( unsigned int wid, const char *str );
67/* dialogues */
68static glFont *dialogue_getSize( const char *title, const char *msg, int *width,
69 int *height );
70static void dialogue_YesNoClose( unsigned int wid, const char *str );
71static void dialogue_inputClose( unsigned int wid, const char *str );
72static void dialogue_choiceClose( unsigned int wid, const char *str );
73static void dialogue_listClose( unsigned int wid, const char *str );
74static void dialogue_listCancel( unsigned int wid, const char *str );
75/* secondary loop hack */
76static int toolkit_loop( int *loop_done, dialogue_update_t *du );
77
81typedef struct InputDialogue_ {
82 unsigned int input_wid;
83 int x;
84 int y;
85 int w;
86 int h;
87 void ( *item_select_cb )( unsigned int wid, const char *wgtname, int x,
88 int y, int w,
89 int h );
91static void select_call_wrapper( unsigned int wid, const char *wgtname );
92
96int dialogue_isOpen( void )
97{
98 return !!dialogue_open;
99}
100
104static void dialogue_close( unsigned int wid, const char *str )
105{
106 (void)str;
107 int *loop_done;
108 loop_done = window_getData( wid );
109 window_destroy( wid );
110 *loop_done = 1;
111}
112
116static void dialogue_cancel( unsigned int wid, const char *str )
117{
118 (void)str;
119 int *loop_done;
120 loop_done = window_getData( wid );
121 window_destroy( wid );
122 *loop_done = -1;
123}
124
130void dialogue_alert( const char *fmt, ... )
131{
132 char msg[STRMAX_SHORT];
133 va_list ap;
134
135 if ( fmt == NULL )
136 return;
137 va_start( ap, fmt );
138 vsnprintf( msg, sizeof( msg ), fmt, ap );
139 va_end( ap );
140
141 dialogue_alertRaw( msg );
142}
143
149void dialogue_alertRaw( const char *msg )
150{
151 int w, h;
152 unsigned int msg_wid;
153 int done;
154 const char *caption = _( "Warning" );
155 glFont *font = dialogue_getSize( caption, msg, &w, &h );
156
157 /* create the window, can't reuse dialogue_msg since we need to have a
158 * different window name. */
159 msg_wid = window_create( "dlgAlert", caption, -1, -1, w, 110 + h );
160 window_setData( msg_wid, &done );
161 window_addText( msg_wid, 20, -40, w - 40, h, 0, "txtMsg", font, NULL, msg );
162 window_addButton( msg_wid, ( w - 50 ) / 2, 20, 50, 30, "btnOK", _( "OK" ),
164
165 toolkit_loop( &done, NULL );
166}
167
177static glFont *dialogue_getSize( const char *title, const char *msg, int *width,
178 int *height )
179{
180 glFont *font;
181 double w, h, d;
182 int i, titlelen, msglen;
183
184 /* Get title length. */
185 titlelen = gl_printWidthRaw( &gl_defFont, title );
186 msglen = gl_printWidthRaw( &gl_defFont, msg );
187
188 /* Try widths from 300 to 800 in 50 px increments.
189 * Each subsequent width gets an additional line, following this table:
190 *
191 * 300 px: 2 lines, 540 px total
192 * 350 px: 3 lines, 930 px total
193 * ...
194 * 800 px: 12 lines, 9600 px total
195 */
196 for ( i = 0; i < 11; i++ )
197 if ( msglen < ( 260 + i * 50 ) * ( 2 + i ) )
198 break;
199
200 w = 300 + i * 50;
201 w = MAX( w, titlelen + 40 ); /* Expand width if the title is long. */
202
203 /* Now we look at proportion. */
204 font = &gl_defFont;
205 h = gl_printHeightRaw( font, w - 40, msg );
206
207 d = ( (double)w / (double)h ) * ( 3. / 4. ); /* deformation factor. */
208 if ( FABS( d ) > 0.3 ) {
209 if ( h > w )
210 w = h;
211 h = gl_printHeightRaw( font, w - 40, msg );
212 }
213
214 /* Set values. */
215 ( *width ) = w;
216 ( *height ) = h;
217
218 return font;
219}
220
227void dialogue_msg( const char *caption, const char *fmt, ... )
228{
229 char msg[STRMAX];
230 va_list ap;
231
232 if ( fmt == NULL )
233 return;
234 va_start( ap, fmt );
235 vsnprintf( msg, sizeof( msg ), fmt, ap );
236 va_end( ap );
237
238 dialogue_msgRaw( caption, msg );
239}
240
248void dialogue_msgImg( const char *caption, const char *img, const char *fmt,
249 ... )
250{
251 char msg[STRMAX];
252 va_list ap;
253
254 if ( fmt == NULL )
255 return;
256 va_start( ap, fmt );
257 vsnprintf( msg, sizeof( msg ), fmt, ap );
258 va_end( ap );
259
260 dialogue_msgImgRaw( caption, msg, img, -1, -1 );
261}
262
269void dialogue_msgRaw( const char *caption, const char *msg )
270{
271 int w, h;
272 unsigned int msg_wid;
273 int done;
274 glFont *font = dialogue_getSize( caption, msg, &w, &h );
275
276 /* create the window */
277 msg_wid = window_create( "dlgMsg", caption, -1, -1, w, 110 + h );
278 window_setData( msg_wid, &done );
279 window_addText( msg_wid, 20, -40, w - 40, h, 0, "txtMsg", font, NULL, msg );
280 window_addButton( msg_wid, ( w - 50 ) / 2, 20, 50, 30, "btnOK", _( "OK" ),
282
283 toolkit_loop( &done, NULL );
284}
285
296void dialogue_msgImgRaw( const char *caption, const char *msg, const char *img,
297 int width, int height )
298{
299 int w, h, img_width, img_height;
300 glFont *font;
301 unsigned int msg_wid;
302 int done;
303 glTexture *gfx;
304 char buf[PATH_MAX];
305
306 /* Get the desired texture */
307 /* IMPORTANT : texture must not be freed here, it will be freed when the
308 * widget closes */
309 snprintf( buf, sizeof( buf ), "%s%s", GFX_PATH, img );
310 gfx = gl_newImage( buf, 0 );
311 if ( gfx == NULL )
312 return;
313
314 /* Find the popup's dimensions from text and image */
315 img_width = ( width < 0 ) ? gfx->w : width;
316 img_height = ( height < 0 ) ? gfx->h : height;
317 font = dialogue_getSize( caption, msg, &w, &h );
318 if ( h < img_width ) {
319 h = img_width;
320 }
321
322 /* Create the window */
323 msg_wid =
324 window_create( "dlgMsgImg", caption, -1, -1, img_width + w, 110 + h );
325 window_setData( msg_wid, &done );
326
327 /* Add the text box */
328 window_addText( msg_wid, img_width + 40, -40, w - 40, h, 0, "txtMsg", font,
329 NULL, msg );
330
331 /* Add a placeholder rectangle for the image */
332 window_addRect( msg_wid, 20, -40, img_width, img_height, "rctGFX", &cGrey10,
333 1 );
334
335 /* Actually add the texture in the rectangle */
336 window_addImage( msg_wid, 20, -40, img_width, img_height, "ImgGFX", gfx, 0 );
337
338 /* Add the OK button */
339 window_addButton( msg_wid, ( img_width + w - 50 ) / 2, 20, 50, 30, "btnOK",
340 _( "OK" ), dialogue_close );
341
342 toolkit_loop( &done, NULL );
343}
344
352int dialogue_YesNo( const char *caption, const char *fmt, ... )
353{
354 char msg[STRMAX];
355 va_list ap;
356
357 if ( fmt == NULL )
358 return -1;
359 va_start( ap, fmt );
360 vsnprintf( msg, sizeof( msg ), fmt, ap );
361 va_end( ap );
362
363 return dialogue_YesNoRaw( caption, msg );
364}
365
373int dialogue_YesNoRaw( const char *caption, const char *msg )
374{
375 unsigned int wid;
376 int w, h;
377 int done[2];
378 char buf[STRMAX_SHORT];
379 glFont *font = dialogue_getSize( caption, msg, &w, &h );
380
381 /* create window */
382 snprintf( buf, sizeof( buf ), "dlgYesNo%d", ++dlgid );
383 wid = window_create( buf, caption, -1, -1, w, h + 110 );
384 window_setData( wid, &done );
385 /* text */
386 window_addText( wid, 20, -40, w - 40, h, 0, "txtYesNo", font, NULL, msg );
387 /* buttons */
388 window_addButtonKey( wid, w / 2 - 100 - 10, 20, 100, 30, "btnYes",
389 _( "Yes" ), dialogue_YesNoClose, SDLK_y );
390 window_addButtonKey( wid, w / 2 + 10, 20, 100, 30, "btnNo", _( "No" ),
391 dialogue_YesNoClose, SDLK_n );
392
393 /* tricky secondary loop */
394 done[1] = -1; /* Default to negative. */
395 toolkit_loop( done, NULL );
396
397 /* Close the dialogue. */
398 dialogue_close( wid, NULL );
399
400 /* return the result */
401 return done[1];
402}
403
408static void dialogue_YesNoClose( unsigned int wid, const char *str )
409{
410 int *loop_done, result;
411
412 /* store the result */
413 if ( strcmp( str, "btnYes" ) == 0 )
414 result = 1;
415 else if ( strcmp( str, "btnNo" ) == 0 )
416 result = 0;
417 else {
418 WARN( _( "Unknown button clicked in YesNo dialogue!" ) );
419 result = 1;
420 }
421
422 /* set data. */
423 loop_done = window_getData( wid );
424 loop_done[0] = 1;
425 loop_done[1] = result;
426}
427
428static InputDialogue
441char *dialogue_input( const char *title, int min, int max, const char *fmt,
442 ... )
443{
444 char msg[STRMAX];
445 va_list ap;
446
447 if ( input_dialogue.input_wid )
448 return NULL;
449
450 if ( fmt == NULL )
451 return NULL;
452 va_start( ap, fmt );
453 vsnprintf( msg, sizeof( msg ), fmt, ap );
454 va_end( ap );
455
456 return dialogue_inputRaw( title, min, max, msg );
457}
458
470char *dialogue_inputRaw( const char *title, int min, int max, const char *msg )
471{
472 char *input;
473 int w, h, done;
474 glFont *font;
475
476 /* get text height */
477 font = dialogue_getSize( title, msg, &w, &h );
478 h = gl_printHeightRaw( font, w, msg );
479
480 /* create window */
481 input_dialogue.input_wid =
482 window_create( "dlgInput", title, -1, -1, w + 40, h + 140 );
483 window_setData( input_dialogue.input_wid, &done );
486 /* text */
487 window_addText( input_dialogue.input_wid, 20, -30, w, h, 0, "txtInput", font,
488 NULL, msg );
489 /* input */
490 window_addInput( input_dialogue.input_wid, 20, 20 + 30 + 10, w, 30,
491 "inpInput", max, 1, NULL );
492 /* Illegal characters on Linux FS: : */
493 /* Illegal characters on Windows FS: < > : " / \ | ? * */
494 window_setInputFilter( input_dialogue.input_wid, "inpInput",
495 "/:<>\"\\|?*" ); /* Remove illegal stuff. */
496 /* button */
497 window_addButton( input_dialogue.input_wid, -20, 20, 80, 30, "btnClose",
498 _( "Done" ), dialogue_inputClose );
499
500 /* tricky secondary loop */
501 done = 0;
502 input = NULL;
503 while ( ( done >= 0 ) &&
504 ( !input ||
505 ( (int)strlen( input ) < min ) ) ) { /* must be longer than min */
506
507 if ( input ) {
508 dialogue_alert( n_( "Input must be at least %d character long!",
509 "Input must be at least %d characters long!",
510 min ),
511 min );
512 free( input );
513 input = NULL;
514 }
515
516 if ( toolkit_loop( &done, NULL ) != 0 ) { /* error in loop -> quit */
517 return NULL;
518 }
519
520 /* save the input */
521 if ( done < 0 )
522 input = NULL;
523 else
524 input =
525 strdup( window_getInput( input_dialogue.input_wid, "inpInput" ) );
526 }
527
528 /* cleanup */
529 if ( input != NULL ) {
530 window_destroy( input_dialogue.input_wid );
531 }
532 input_dialogue.input_wid = 0;
533
534 /* return the result */
535 return input;
536}
537
542static void dialogue_inputClose( unsigned int wid, const char *str )
543{
544 (void)str;
545 int *loop_done;
546
547 /* break the loop */
548 loop_done = window_getData( wid );
549 *loop_done = 1;
550}
551
552static int dialogue_listSelected = -1;
553static void dialogue_listCancel( unsigned int wid, const char *str )
554{
555 dialogue_listSelected = -1;
556 dialogue_cancel( wid, str );
557}
558static void dialogue_listClose( unsigned int wid, const char *str )
559{
560 dialogue_listSelected = toolkit_getListPos( wid, "lstDialogue" );
561 dialogue_close( wid, str );
562}
571static void select_call_wrapper( unsigned int wid, const char *wgtname )
572{
573 if ( input_dialogue.item_select_cb )
574 input_dialogue.item_select_cb( wid, wgtname, input_dialogue.x,
576 input_dialogue.h );
577}
578
588int dialogue_list( const char *title, char **items, int nitems, const char *fmt,
589 ... )
590{
591 char msg[STRMAX_SHORT];
592 va_list ap;
593
594 if ( input_dialogue.input_wid )
595 return -1;
596
597 if ( fmt == NULL )
598 return -1;
599 va_start( ap, fmt );
600 vsnprintf( msg, sizeof( msg ), fmt, ap );
601 va_end( ap );
602
603 return dialogue_listPanelRaw( title, items, nitems, 0, 0, NULL, NULL, msg );
604}
605
614int dialogue_listRaw( const char *title, char **items, int nitems,
615 const char *msg )
616{
617 if ( input_dialogue.input_wid )
618 return -1;
619 return dialogue_listPanelRaw( title, items, nitems, 0, 0, NULL, NULL, msg );
620}
621
640 const char *title, char **items, int nitems, int extrawidth, int minheight,
641 void ( *add_widgets )( unsigned int wid, int x, int y, int w, int h ),
642 void ( *select_call )( unsigned int wid, const char *wgtname, int x, int y,
643 int w, int h ),
644 const char *fmt, ... )
645{
646 char msg[STRMAX_SHORT];
647 va_list ap;
648
649 if ( input_dialogue.input_wid )
650 return -1;
651
652 if ( fmt == NULL )
653 return -1;
654
655 /* get the message */
656 va_start( ap, fmt );
657 vsnprintf( msg, sizeof( msg ), fmt, ap );
658 va_end( ap );
659
660 return dialogue_listPanelRaw( title, items, nitems, extrawidth, minheight,
661 add_widgets, select_call, msg );
662}
663
682 const char *title, char **items, int nitems, int extrawidth, int minheight,
683 void ( *add_widgets )( unsigned int wid, int x, int y, int w, int h ),
684 void ( *select_call )( unsigned int wid, const char *wgtname, int x, int y,
685 int w, int h ),
686 const char *msg )
687{
688 int i;
689 int w, h, winw, winh;
690 glFont *font;
691 unsigned int wid;
692 int list_width, list_height;
693 int text_height, text_width;
694 int done;
695
696 if ( input_dialogue.input_wid )
697 return -1;
698
699 font = dialogue_getSize( title, msg, &text_width, &text_height );
700
701 /* Calculate size stuff. */
702 list_width = 0;
703 list_height = 0;
704 for ( i = 0; i < nitems; i++ ) {
705 list_width = MAX( list_width, gl_printWidthRaw( &gl_defFont, items[i] ) );
706 list_height += gl_defFont.h + 5;
707 }
708 list_height += 100;
709 if ( list_height > 500 )
710 h = ( list_height * 8 ) / 10;
711 else
712 h = MAX( 300, list_height );
713
714 h = MIN( ( (double)SCREEN_H * 2. ) / 3., h );
715 w = MAX( list_width + 60, 500 );
716
717 winw = w + extrawidth;
718 winh = MAX( h, minheight );
719
720 h = winh;
721
722 /* Create the window. */
723 wid = window_create( "dlgListPanel", title, -1, -1, winw, winh );
724 window_setData( wid, &done );
725 window_addText( wid, 20, -40, w - 40, text_height, 0, "txtMsg", font, NULL,
726 msg );
727 window_setAccept( wid, dialogue_listClose );
728 window_setCancel( wid, dialogue_listCancel );
729
730 if ( add_widgets )
731 add_widgets( wid, w, 0, winw, winh );
732
733 if ( select_call ) {
734 input_dialogue.x = w;
735 input_dialogue.y = 0;
736 input_dialogue.w = winw;
737 input_dialogue.h = winh;
738 input_dialogue.item_select_cb = select_call;
739 }
740
741 /* Create the list. */
742 window_addList( wid, 20, -40 - text_height - 20, w - 40,
743 h - ( 40 + text_height + 20 ) - ( 20 + 30 + 20 ),
744 "lstDialogue", items, nitems, 0, select_call_wrapper,
745 dialogue_listClose );
746
747 /* Create the buttons. */
748 window_addButton( wid, -20, 20, 120, 30, "btnOK", _( "OK" ),
749 dialogue_listClose );
750 window_addButton( wid, -20 - 120 - 20, 20, 120, 30, "btnCancel",
751 _( "Cancel" ), dialogue_listCancel );
752
753 toolkit_loop( &done, NULL );
754 /* cleanup */
755 input_dialogue.x = 0;
756 input_dialogue.y = 0;
757 input_dialogue.w = 0;
758 input_dialogue.h = 0;
759 input_dialogue.item_select_cb = NULL;
760
761 return dialogue_listSelected;
762}
763static unsigned int choice_wid = 0;
764static char *choice_result;
765static int choice_nopts;
773void dialogue_makeChoice( const char *caption, const char *msg, int opts )
774{
775 int w, h;
776 glFont *font;
777
778 choice_result = NULL;
779 choice_nopts = opts;
780 font = dialogue_getSize( caption, msg, &w, &h );
781
782 /* create window */
783 choice_wid = window_create( "dlgChoice", caption, -1, -1, w,
784 h + 100 + 40 * choice_nopts );
785 /* text */
786 window_addText( choice_wid, 20, -40, w - 40, h, 0, "txtChoice", font, NULL,
787 msg );
788}
789
796void dialogue_addChoice( const char *caption, const char *msg, const char *opt )
797{
798 int w, h;
799
800 if ( choice_nopts < 1 )
801 return;
802
803 dialogue_getSize( caption, msg, &w, &h );
804
805 /* buttons. Add one for each option in the menu. */
806 window_addButton( choice_wid, w / 2 - 125, choice_nopts * 40, 250, 30,
807 (char *)opt, (char *)opt, dialogue_choiceClose );
808 choice_nopts--;
809}
810
818{
819 int done;
820 char *res;
821
822 /* tricky secondary loop */
823 window_setData( choice_wid, &done );
824 toolkit_loop( &done, NULL );
825
826 /* Save value. */
827 res = choice_result;
828 choice_result = NULL;
829
830 return res;
831}
832
837static void dialogue_choiceClose( unsigned int wid, const char *str )
838{
839 int *loop_done;
840
841 /* Save result. */
842 choice_result = strdup( str );
843
844 /* Finish loop. */
845 loop_done = window_getData( wid );
846 *loop_done = 1;
847
848 /* destroy the window */
849 choice_wid = 0;
850 window_destroy( wid );
851}
852
853static int dialogue_custom_event( unsigned int wid, SDL_Event *event )
854{
855 int mx, my;
856 struct dialogue_custom_data_s *cd;
857 void *data = window_getData( wid );
858 cd = (struct dialogue_custom_data_s *)data;
859
860 /* We translate mouse coords here. */
861 if ( ( event->type == SDL_MOUSEBUTTONDOWN ) ||
862 ( event->type == SDL_MOUSEBUTTONUP ) ||
863 ( event->type == SDL_MOUSEMOTION ) ) {
864 gl_windowToScreenPos( &mx, &my, event->button.x, event->button.y );
865 mx += cd->mx;
866 my += cd->my;
867 /* Ignore out of bounds. We have to implement checking here. */
868 if ( ( mx < 0 ) || ( mx >= cd->w ) || ( my < 0 ) || ( my >= cd->h ) )
869 return 0;
870 event->button.x = mx;
871 event->button.y = my;
872 }
873
874 return ( *cd->event )( wid, event, cd->data );
875}
891 const char *wdwname, const char *caption, int width, int height,
892 int ( *update )( double dt, void *data ),
893 void ( *render )( double x, double y, double w, double h, void *data ),
894 int ( *event )( unsigned int wid, SDL_Event *event, void *data ), void *data,
895 int dynamic, void ( *freefunc )( void *data ) )
896{
897 struct dialogue_custom_data_s cd;
899 unsigned int wid;
900 int done, fullscreen;
901 int wx, wy, wgtx, wgty;
902
903 fullscreen = ( ( width < 0 ) && ( height < 0 ) );
904
905 /* create the window */
906 if ( fullscreen ) {
907 wid = window_create( wdwname, caption, -1, -1, -1, -1 );
908 window_setBorder( wid, 0 );
909 } else
910 wid = window_create( wdwname, caption, -1, -1, width + 40, height + 60 );
911 window_setData( wid, &done );
912
913 /* custom widget for all! */
914 if ( fullscreen ) {
915 width = gl_screen.nw;
916 height = gl_screen.nh;
917 wgtx = wgty = 0;
918 } else {
919 wgtx = wgty = 20;
920 }
921 window_addCust( wid, wgtx, wgty, width, height, "cstCustom", 0, render, NULL,
922 NULL, NULL, data );
923 if ( dynamic )
924 window_custSetDynamic( wid, "cstCustom", 1 );
925 if ( freefunc != NULL )
926 window_custFreeDataFunc( wid, "cstCustom", freefunc );
927 window_custSetClipping( wid, "cstCustom", 1 );
928
929 /* set up event stuff. */
930 window_posWindow( wid, &wx, &wy );
931 window_posWidget( wid, "cstCustom", &wgtx, &wgty );
932 cd.event = event;
933 cd.data = data;
934 cd.mx = -wx - wgtx;
935 cd.my = -wy - wgty;
936 cd.w = width;
937 cd.h = height;
938 window_setData( wid, &cd );
939 if ( event != NULL )
940 window_handleEvents( wid, &dialogue_custom_event );
941
942 /* dialogue stuff */
943 du.update = update;
944 du.data = data;
945 du.wid = wid;
946 toolkit_loop( &done, &du );
947}
948
956int dialogue_customFullscreen( unsigned int wid, int enable )
957{
958 struct dialogue_custom_data_s *cd;
959 int w, h;
960 if ( wid == 0 )
961 return -1;
962
963 cd = (struct dialogue_custom_data_s *)window_getData( wid );
964 window_dimWindow( wid, &w, &h );
965
966 if ( enable ) {
967 cd->last_w = cd->w + 40;
968 cd->last_h = cd->h + 60;
969 window_resize( wid, -1, -1 );
970 window_moveWidget( wid, "cstCustom", 0, 0 );
971 window_resizeWidget( wid, "cstCustom", cd->last_w, cd->last_h );
972 window_move( wid, -1, -1 );
973 window_setBorder( wid, 0 );
974 } else {
975 window_resize( wid, cd->last_w, cd->last_h );
976 window_moveWidget( wid, "cstCustom", 20, 20 );
977 window_move( wid, -1, -1 );
978 window_setBorder( wid, 1 );
979 }
980
981 return 0;
982}
983
992int dialogue_customResize( unsigned int wid, int width, int height )
993{
994 struct dialogue_custom_data_s *cd;
995 if ( wid == 0 )
996 return -1;
997 cd = (struct dialogue_custom_data_s *)window_getData( wid );
998 cd->last_w = width;
999 cd->last_h = height;
1000 window_resize( wid, width + 40, height + 60 );
1001 window_resizeWidget( wid, "cstCustom", width, height );
1002 return 0;
1003}
1004
1019static int toolkit_loop( int *loop_done, dialogue_update_t *du )
1020{
1021 Uint64 last_t = SDL_GetPerformanceCounter();
1022 const double fps_max =
1023 ( conf.fps_max > 0 ) ? 1. / (double)conf.fps_max : fps_min;
1024 int quit_game = 0;
1025
1026 /* Delay a toolkit iteration. */
1027 toolkit_delay();
1028
1029 /* Increment dialogues. */
1030 dialogue_open++;
1031 *loop_done = 0;
1032
1033 /* Flush events so SDL_LOOPDONE doesn't propagate. */
1034 SDL_FlushEvent( SDL_LOOPDONE );
1035
1036 while ( !( *loop_done ) && toolkit_isOpen() && !naev_isQuit() ) {
1037 SDL_Event event;
1038 Uint64 t;
1039 double dt;
1040
1041 /* Loop first so exit condition is checked before next iteration. */
1042 main_loop( 1 );
1043
1044 while ( !naev_isQuit() && SDL_PollEvent( &event ) ) { /* event loop */
1045 if ( event.type == SDL_QUIT ) {
1046 if ( menu_askQuit() ) {
1047 naev_quit(); /* Quit is handled here */
1048 *loop_done = 1; /* Exit loop and exit game. */
1049 quit_game = 1;
1050 break;
1051 }
1052 } else if ( event.type == SDL_LOOPDONE ) {
1053 *loop_done = 1;
1054 SDL_PushEvent(
1055 &event ); /* Replicate event until out of all loops. */
1056 break;
1057 } else if ( event.type == SDL_WINDOWEVENT &&
1058 event.window.event == SDL_WINDOWEVENT_RESIZED )
1059 naev_resize();
1060
1062 &event ); /* handles all the events and player keybinds */
1063 }
1064
1065 /* FPS Control. */
1066 t = SDL_GetPerformanceCounter();
1067 dt = (double)( t - last_t ) / (double)SDL_GetPerformanceFrequency();
1068 last_t = t;
1069 /* Sleep if necessary. */
1070 if ( dt < fps_max ) {
1071 double delay = fps_max - dt;
1072 SDL_Delay( (unsigned int)( delay * 1000. ) );
1073 }
1074
1075 /* Update stuff. */
1076 if ( du != NULL ) {
1077 /* Run update. */
1078 if ( ( *du->update )( dt, du->data ) ) {
1079 /* Hack to override data. */
1080 window_setData( du->wid, loop_done );
1081 dialogue_close( du->wid, NULL );
1082 }
1083 }
1084 }
1085
1086 /* Close dialogue. */
1087 dialogue_open--;
1088 if ( dialogue_open < 0 )
1089 WARN( _( "Dialogue counter not in sync!" ) );
1090
1091 return quit_game;
1092}
static char * choice_result
Definition dialogue.c:764
static int toolkit_loop(int *loop_done, dialogue_update_t *du)
Creates a secondary loop until loop_done is set to 1 or the toolkit closes.
Definition dialogue.c:1019
char * dialogue_runChoice(void)
Run the dialog and return the clicked string.
Definition dialogue.c:817
char * dialogue_inputRaw(const char *title, int min, int max, const char *msg)
Creates a dialogue that allows the player to write a message.
Definition dialogue.c:470
static int dlgid
Definition dialogue.c:37
void dialogue_alert(const char *fmt,...)
Displays an alert popup with only an ok button and a message.
Definition dialogue.c:130
static void dialogue_choiceClose(unsigned int wid, const char *str)
Closes a choice dialogue.
Definition dialogue.c:837
void dialogue_custom(const char *wdwname, const char *caption, int width, int height, int(*update)(double dt, void *data), void(*render)(double x, double y, double w, double h, void *data), int(*event)(unsigned int wid, SDL_Event *event, void *data), void *data, int dynamic, void(*freefunc)(void *data))
Opens a custom dialogue window.
Definition dialogue.c:890
int dialogue_customFullscreen(unsigned int wid, int enable)
Converts a custom dialogue to fullscreen.
Definition dialogue.c:956
int dialogue_listPanelRaw(const char *title, char **items, int nitems, int extrawidth, int minheight, void(*add_widgets)(unsigned int wid, int x, int y, int w, int h), void(*select_call)(unsigned int wid, const char *wgtname, int x, int y, int w, int h), const char *msg)
Creates a list dialogue with OK and Cancel buttons, with a fixed message, as well as a small extra ar...
Definition dialogue.c:681
char * dialogue_input(const char *title, int min, int max, const char *fmt,...)
Creates a dialogue that allows the player to write a message.
Definition dialogue.c:441
int dialogue_listRaw(const char *title, char **items, int nitems, const char *msg)
Creates a list dialogue with OK and Cancel button.
Definition dialogue.c:614
static void dialogue_close(unsigned int wid, const char *str)
Generic window close.
Definition dialogue.c:104
static void select_call_wrapper(unsigned int wid, const char *wgtname)
used to pass appropriate information to the method that handles updating the extra information area i...
Definition dialogue.c:571
int dialogue_YesNoRaw(const char *caption, const char *msg)
Runs a dialogue with both yes and no options.
Definition dialogue.c:373
int dialogue_listPanel(const char *title, char **items, int nitems, int extrawidth, int minheight, void(*add_widgets)(unsigned int wid, int x, int y, int w, int h), void(*select_call)(unsigned int wid, const char *wgtname, int x, int y, int w, int h), const char *fmt,...)
Creates a list dialogue with OK and Cancel buttons, with a fixed message, as well as a small extra ar...
Definition dialogue.c:639
int dialogue_customResize(unsigned int wid, int width, int height)
Resizes a custom dialogue.
Definition dialogue.c:992
void dialogue_msg(const char *caption, const char *fmt,...)
Opens a dialogue window with an ok button and a message.
Definition dialogue.c:227
int dialogue_list(const char *title, char **items, int nitems, const char *fmt,...)
Creates a list dialogue with OK and Cancel button with a fixed message.
Definition dialogue.c:588
void dialogue_addChoice(const char *caption, const char *msg, const char *opt)
Add a choice to the dialog.
Definition dialogue.c:796
static glFont * dialogue_getSize(const char *title, const char *msg, int *width, int *height)
Gets the size needed for the dialogue.
Definition dialogue.c:177
void dialogue_alertRaw(const char *msg)
Displays an alert popup with only an ok button and a message.
Definition dialogue.c:149
void dialogue_msgImgRaw(const char *caption, const char *msg, const char *img, int width, int height)
Opens a dialogue window with an ok button, a fixed message and an image.
Definition dialogue.c:296
void dialogue_makeChoice(const char *caption, const char *msg, int opts)
Create the choice dialog. Need to add choices with below method.
Definition dialogue.c:773
static void dialogue_inputClose(unsigned int wid, const char *str)
Closes an input dialogue.
Definition dialogue.c:542
static unsigned int choice_wid
Definition dialogue.c:763
static int dialogue_open
Definition dialogue.c:36
static int choice_nopts
Definition dialogue.c:765
void main_loop(int nested)
Split main loop from main() for secondary loop hack in toolkit.c.
Definition naev.c:795
void dialogue_msgRaw(const char *caption, const char *msg)
Opens a dialogue window with an ok button and a fixed message.
Definition dialogue.c:269
int dialogue_isOpen(void)
Checks to see if a dialogue is open.
Definition dialogue.c:96
static InputDialogue input_dialogue
Definition dialogue.c:429
static void dialogue_cancel(unsigned int wid, const char *str)
Generic window cancel.
Definition dialogue.c:116
int dialogue_YesNo(const char *caption, const char *fmt,...)
Runs a dialogue with both yes and no options.
Definition dialogue.c:352
void dialogue_msgImg(const char *caption, const char *img, const char *fmt,...)
Opens a dialogue window with an ok button, a message and an image.
Definition dialogue.c:248
static void dialogue_YesNoClose(unsigned int wid, const char *str)
Closes a yesno dialogue.
Definition dialogue.c:408
int gl_printHeightRaw(const glFont *ft_font, const int width, const char *text)
Gets the height of a non-formatted string.
Definition font.c:1050
int gl_printWidthRaw(const glFont *ft_font, const char *text)
Gets the width that it would take to print some text.
Definition font.c:984
glFont gl_defFont
Definition font.c:158
void input_handle(SDL_Event *event)
Handles global input.
Definition input.c:1833
Handles the important game menus.
int menu_askQuit(void)
Menu to ask if player really wants to quit.
Definition menu.c:701
void naev_quit(void)
Flags naev to quit.
Definition naev.c:145
void naev_resize(void)
Wrapper for gl_resize that handles non-GL reinitialization.
Definition naev.c:874
int naev_isQuit(void)
Get if Naev is trying to quit.
Definition naev.c:153
const double fps_min
Definition naev.c:116
Uint32 SDL_LOOPDONE
Definition naev.c:99
static Uint64 last_t
Definition naev.c:100
Header file with generic functions and naev-specifics.
#define MIN(x, y)
Definition naev.h:39
#define FABS(x)
Definition naev.h:34
#define MAX(x, y)
Definition naev.h:37
#define PATH_MAX
Definition naev.h:57
void gl_windowToScreenPos(int *sx, int *sy, int wx, int wy)
Translates the window position to screen position.
Definition opengl.c:762
glInfo gl_screen
Definition opengl.c:47
glTexture * gl_newImage(const char *path, const unsigned int flags)
Loads an image as a texture.
Definition opengl_tex.c:587
static const double d[]
Definition rng.c:263
Used to store information for input dialogues.
Definition dialogue.c:81
void(* item_select_cb)(unsigned int wid, const char *wgtname, int x, int y, int w, int h)
Definition dialogue.c:87
unsigned int input_wid
Definition dialogue.c:82
Represents a font in memory.
Definition font.h:17
Abstraction for rendering sprite sheets.
Definition opengl_tex.h:43
double w
Definition opengl_tex.h:47
double h
Definition opengl_tex.h:48
unsigned int window_create(const char *name, const char *displayname, const int x, const int y, const int w, const int h)
Creates a window.
Definition toolkit.c:688
void window_setAccept(unsigned int wid, void(*accept)(unsigned int, const char *))
Sets the default accept function of the window.
Definition toolkit.c:846
void window_dimWindow(unsigned int wid, int *w, int *h)
Gets the dimensions of a window.
Definition toolkit.c:370
int toolkit_isOpen(void)
Checks to see if the toolkit is open.
Definition toolkit.c:93
void window_move(unsigned int wid, int x, int y)
Moves a window to the specified coordinates.
Definition toolkit.c:176
void window_setCancel(unsigned int wid, void(*cancel)(unsigned int, const char *))
Sets the default cancel function of the window.
Definition toolkit.c:868
void window_moveWidget(unsigned int wid, const char *name, int x, int y)
Moves a widget.
Definition toolkit.c:463
void window_resize(unsigned int wid, int w, int h)
Resizes the window.
Definition toolkit.c:193
void toolkit_delay(void)
Delays the toolkit purge by an iteration, useful for dialogues.
Definition toolkit.c:105
void window_posWidget(unsigned int wid, const char *name, int *x, int *y)
Gets a widget's position.
Definition toolkit.c:441
void window_setBorder(unsigned int wid, int enable)
Sets or removes the border of a window.
Definition toolkit.c:942
void window_posWindow(unsigned int wid, int *x, int *y)
Gets the dimensions of a window.
Definition toolkit.c:392
void * window_getData(unsigned int wid)
Gets the custom data of a window.
Definition toolkit.c:923
void window_setData(unsigned int wid, void *data)
Sets custom data for a window.
Definition toolkit.c:906
void window_resizeWidget(unsigned int wid, const char *name, int w, int h)
Resizes a widget.
Definition toolkit.c:490
void window_destroy(unsigned int wid)
Kills the window.
Definition toolkit.c:1039
void window_handleEvents(unsigned int wid, int(*eventhandler)(unsigned int, SDL_Event *))
Sets the event handler for the window.
Definition toolkit.c:979