naev 0.11.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"
26#include "dialogue.h"
27
28#include "input.h"
29#include "log.h"
30#include "conf.h"
31#include "menu.h"
32#include "ndata.h"
33#include "nstring.h"
34#include "opengl.h"
35#include "pause.h"
36#include "toolkit.h"
37
38static int dialogue_open;
39static int dlgid = 0;
41/*
42 * Custom widget scary stuff.
43 */
44typedef struct dialogue_update_s {
45 unsigned int wid;
46 int (*update)(double, void*);
47 void *data;
50 int (*event)(unsigned int, SDL_Event*, void*);
51 void *data;
52 int mx;
53 int my;
54 int w;
55 int h;
56 int last_w;
57 int last_h;
58};
59static int dialogue_custom_event( unsigned int wid, SDL_Event *event );
60
61/*
62 * Prototypes.
63 */
64/* extern */
65extern void main_loop( int nested ); /* from naev.c */
66/* generic */
67static void dialogue_close( unsigned int wid, const char *str );
68static void dialogue_cancel( unsigned int wid, const char *str );
69/* dialogues */
70static glFont* dialogue_getSize( const char* title,
71 const char* msg, int* width, int* height );
72static void dialogue_YesNoClose( unsigned int wid, const char *str );
73static void dialogue_inputClose( unsigned int wid, const char *str );
74static void dialogue_choiceClose( unsigned int wid, const char *str );
75static void dialogue_listClose( unsigned int wid, const char *str );
76static void dialogue_listCancel( unsigned int wid, const char *str );
77/* secondary loop hack */
78static int toolkit_loop( int *loop_done, dialogue_update_t *du );
79
83typedef struct InputDialogue_ {
84 unsigned int input_wid;
85 int x;
86 int y;
87 int w;
88 int h;
89 void (*item_select_cb) (unsigned int wid, const char* wgtname,
90 int x, int y, int w, int h
91 );
93static void select_call_wrapper(unsigned int wid, const char* wgtname);
94
99{
100 return !!dialogue_open;
101}
102
106static void dialogue_close( unsigned int wid, const char *str )
107{
108 (void) str;
109 int *loop_done;
110 loop_done = window_getData( wid );
111 window_destroy( wid );
112 *loop_done = 1;
113}
114
118static void dialogue_cancel( unsigned int wid, const char *str )
119{
120 (void) str;
121 int *loop_done;
122 loop_done = window_getData( wid );
123 window_destroy( wid );
124 *loop_done = -1;
125}
126
132void dialogue_alert( const char *fmt, ... )
133{
134 char msg[STRMAX_SHORT];
135 va_list ap;
136
137 if (fmt == NULL)
138 return;
139 va_start(ap, fmt);
140 vsnprintf(msg, sizeof(msg), fmt, ap);
141 va_end(ap);
142
143 dialogue_alertRaw( msg );
144}
145
151void dialogue_alertRaw( const char *msg )
152{
153 int w,h;
154 unsigned int msg_wid;
155 int done;
156 const char *caption = _("Warning");
157 glFont *font = dialogue_getSize( caption, msg, &w, &h );
158
159 /* create the window, can't reuse dialogue_msg since we need to have a
160 * different window name. */
161 msg_wid = window_create( "dlgAlert", caption, -1, -1, w, 110 + h );
162 window_setData( msg_wid, &done );
163 window_addText( msg_wid, 20, -40, w-40, h, 0, "txtMsg",
164 font, NULL, msg );
165 window_addButton( msg_wid, (w-50)/2, 20, 50, 30, "btnOK", _("OK"),
167
168 toolkit_loop( &done, NULL );
169}
170
180static glFont* dialogue_getSize( const char* title,
181 const char* msg, int* width, int* height )
182{
183 glFont* font;
184 double w, h, d;
185 int i, titlelen, msglen;
186
187 /* Get title length. */
188 titlelen = gl_printWidthRaw( &gl_defFont, title );
189 msglen = gl_printWidthRaw( &gl_defFont, msg );
190
191 /* Try widths from 300 to 800 in 50 px increments.
192 * Each subsequent width gets an additional line, following this table:
193 *
194 * 300 px: 2 lines, 540 px total
195 * 350 px: 3 lines, 930 px total
196 * ...
197 * 800 px: 12 lines, 9600 px total
198 */
199 for (i=0; i<11; i++)
200 if (msglen < (260 + i * 50) * (2 + i))
201 break;
202
203 w = 300 + i * 50;
204 w = MAX(w, titlelen+40); /* Expand width if the title is long. */
205
206 /* Now we look at proportion. */
207 font = &gl_defFont;
208 h = gl_printHeightRaw( font, w-40, msg );
209
210 d = ((double)w/(double)h)*(3./4.); /* deformation factor. */
211 if (FABS(d) > 0.3) {
212 if (h > w)
213 w = h;
214 h = gl_printHeightRaw( font, w-40, msg );
215 }
216
217 /* Set values. */
218 (*width) = w;
219 (*height) = h;
220
221 return font;
222}
223
230void dialogue_msg( const char* caption, const char *fmt, ... )
231{
232 char msg[STRMAX];
233 va_list ap;
234
235 if (fmt == NULL)
236 return;
237 va_start(ap, fmt);
238 vsnprintf(msg, sizeof(msg), fmt, ap);
239 va_end(ap);
240
241 dialogue_msgRaw( caption, msg );
242}
243
251void dialogue_msgImg( const char* caption, const char *img, const char *fmt, ... )
252{
253 char msg[STRMAX];
254 va_list ap;
255
256 if (fmt == NULL)
257 return;
258 va_start(ap, fmt);
259 vsnprintf(msg, sizeof(msg), fmt, ap);
260 va_end(ap);
261
262 dialogue_msgImgRaw( caption, msg, img, -1, -1 );
263}
264
271void dialogue_msgRaw( const char* caption, const char *msg )
272{
273 int w,h;
274 unsigned int msg_wid;
275 int done;
276 glFont *font = dialogue_getSize( caption, msg, &w, &h );
277
278 /* create the window */
279 msg_wid = window_create( "dlgMsg", caption, -1, -1, w, 110 + h );
280 window_setData( msg_wid, &done );
281 window_addText( msg_wid, 20, -40, w-40, h, 0, "txtMsg",
282 font, NULL, msg );
283 window_addButton( msg_wid, (w-50)/2, 20, 50, 30, "btnOK", _("OK"),
285
286 toolkit_loop( &done, NULL );
287}
288
298void dialogue_msgImgRaw( const char* caption, const char *msg, const char *img, int width, int height )
299{
300 int w, h, img_width, img_height;
301 glFont* font;
302 unsigned int msg_wid;
303 int done;
304 glTexture *gfx;
305 char buf[PATH_MAX];
306
307 /* Get the desired texture */
308 /* IMPORTANT : texture must not be freed here, it will be freed when the 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 = window_create( "dlgMsgImg", caption, -1, -1, img_width + w, 110 + h );
324 window_setData( msg_wid, &done );
325
326 /* Add the text box */
327 window_addText( msg_wid, img_width+40, -40, w-40, h, 0, "txtMsg",
328 font, NULL, msg );
329
330 /* Add a placeholder rectangle for the image */
331 window_addRect( msg_wid, 20, -40, img_width, img_height,
332 "rctGFX", &cGrey10, 1 );
333
334 /* Actually add the texture in the rectangle */
335 window_addImage( msg_wid, 20, -40, img_width, img_height,
336 "ImgGFX", gfx, 0 );
337
338 /* Add the OK button */
339 window_addButton( msg_wid, (img_width+w -50)/2, 20, 50, 30, "btnOK", _("OK"),
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",
387 font, NULL, msg );
388 /* buttons */
389 window_addButtonKey( wid, w/2-100-10, 20, 100, 30, "btnYes", _("Yes"),
390 dialogue_YesNoClose, SDLK_y );
391 window_addButtonKey( wid, w/2+10, 20, 100, 30, "btnNo", _("No"),
392 dialogue_YesNoClose, SDLK_n );
393
394 /* tricky secondary loop */
395 done[1] = -1; /* Default to negative. */
396 toolkit_loop( done, NULL );
397
398 /* Close the dialogue. */
399 dialogue_close( wid, NULL );
400
401 /* return the result */
402 return done[1];
403}
409static void dialogue_YesNoClose( unsigned int wid, const char *str )
410{
411 int *loop_done, result;
412
413 /* store the result */
414 if (strcmp(str,"btnYes")==0)
415 result = 1;
416 else if (strcmp(str,"btnNo")==0)
417 result = 0;
418 else {
419 WARN(_("Unknown button clicked in YesNo dialogue!"));
420 result = 1;
421 }
422
423 /* set data. */
424 loop_done = window_getData( wid );
425 loop_done[0] = 1;
426 loop_done[1] = result;
427}
428
441char* dialogue_input( const char* title, int min, int max, const char *fmt, ... )
442{
443 char msg[STRMAX];
444 va_list ap;
445
447 return NULL;
448
449 if (fmt == NULL)
450 return NULL;
451 va_start(ap, fmt);
452 vsnprintf(msg, sizeof(msg), fmt, ap);
453 va_end(ap);
454
455 return dialogue_inputRaw( title, min, max, msg );
456}
457
469char* dialogue_inputRaw( const char* title, int min, int max, const char *msg )
470{
471 char *input;
472 int w, h, done;
473 glFont* font;
474
475 /* get text height */
476 font = dialogue_getSize( title, msg, &w, &h );
477 h = gl_printHeightRaw( font, w, msg );
478
479 /* create window */
480 input_dialogue.input_wid = window_create( "dlgInput", title, -1, -1, w+40, h+140 );
484 /* text */
485 window_addText( input_dialogue.input_wid, 20, -30, w, h, 0, "txtInput",
486 font, NULL, msg );
487 /* input */
488 window_addInput( input_dialogue.input_wid, 20, 20+30+10, w, 30,"inpInput", max, 1, NULL );
489 /* Illegal characters on Linux FS: : */
490 /* Illegal characters on Windows FS: < > : " / \ | ? * */
491 window_setInputFilter( input_dialogue.input_wid, "inpInput", "/:<>\"\\|?*" ); /* Remove illegal stuff. */
492 /* button */
493 window_addButton( input_dialogue.input_wid, -20, 20, 80, 30,
494 "btnClose", _("Done"), dialogue_inputClose );
495
496 /* tricky secondary loop */
497 done = 0;
498 input = NULL;
499 while ((done >= 0) && (!input ||
500 ((int)strlen(input) < min))) { /* must be longer than min */
501
502 if (input) {
503 dialogue_alert( n_(
504 "Input must be at least %d character long!",
505 "Input must be at least %d characters long!", min),
506 min );
507 free(input);
508 input = NULL;
509 }
510
511 if (toolkit_loop( &done, NULL ) != 0) { /* error in loop -> quit */
512 return NULL;
513 }
514
515 /* save the input */
516 if (done < 0)
517 input = NULL;
518 else
519 input = strdup(window_getInput(input_dialogue.input_wid, "inpInput"));
520 }
521
522 /* cleanup */
523 if (input != NULL) {
525 }
527
528 /* return the result */
529 return input;
530}
536static void dialogue_inputClose( unsigned int wid, const char *str )
537{
538 (void) str;
539 int *loop_done;
540
541 /* break the loop */
542 loop_done = window_getData( wid );
543 *loop_done = 1;
544}
545
546static int dialogue_listSelected = -1;
547static void dialogue_listCancel( unsigned int wid, const char *str )
548{
549 dialogue_listSelected = -1;
550 dialogue_cancel( wid, str );
551}
552static void dialogue_listClose( unsigned int wid, const char *str )
553{
554 dialogue_listSelected = toolkit_getListPos( wid, "lstDialogue" );
555 dialogue_close( wid, str );
556}
565static void select_call_wrapper(unsigned int wid, const char* wgtname)
566{
571}
580int dialogue_list( const char* title, char **items, int nitems, const char *fmt, ... )
581{
582 char msg[STRMAX_SHORT];
583 va_list ap;
584
585 if (input_dialogue.input_wid) return -1;
586
587 if (fmt == NULL)
588 return -1;
589 va_start(ap, fmt);
590 vsnprintf(msg, sizeof(msg), fmt, ap);
591 va_end(ap);
592
593 return dialogue_listPanelRaw( title, items, nitems, 0, 0, NULL, NULL, msg );
594}
603int dialogue_listRaw( const char* title, char **items, int nitems, const char *msg )
604{
605 if (input_dialogue.input_wid) return -1;
606 return dialogue_listPanelRaw( title, items, nitems, 0, 0, NULL, NULL, msg );
607}
624int dialogue_listPanel( const char* title, char **items, int nitems, int extrawidth,
625 int minheight, void (*add_widgets) (unsigned int wid, int x, int y, int w, int h),
626 void (*select_call) (unsigned int wid, const char* wgtname, int x, int y, int w, int h),
627 const char *fmt, ... )
628{
629 char msg[STRMAX_SHORT];
630 va_list ap;
631
633 return -1;
634
635 if (fmt == NULL)
636 return -1;
637
638 /* get the message */
639 va_start(ap, fmt);
640 vsnprintf(msg, sizeof(msg), fmt, ap);
641 va_end(ap);
642
643 return dialogue_listPanelRaw( title, items, nitems, extrawidth, minheight,
644 add_widgets, select_call, msg );
645}
662int dialogue_listPanelRaw( const char* title, char **items, int nitems, int extrawidth,
663 int minheight, void (*add_widgets) (unsigned int wid, int x, int y, int w, int h),
664 void (*select_call) (unsigned int wid, const char* wgtname, int x, int y, int w, int h),
665 const char *msg )
666{
667 int i;
668 int w, h, winw, winh;
669 glFont* font;
670 unsigned int wid;
671 int list_width, list_height;
672 int text_height, text_width;
673 int done;
674
675 if (input_dialogue.input_wid) return -1;
676
677 font = dialogue_getSize( title, msg, &text_width, &text_height );
678
679 /* Calculate size stuff. */
680 list_width = 0;
681 list_height = 0;
682 for (i=0; i<nitems; i++) {
683 list_width = MAX( list_width, gl_printWidthRaw( &gl_defFont, items[i] ) );
684 list_height += gl_defFont.h + 5;
685 }
686 list_height += 100;
687 if (list_height > 500)
688 h = (list_height*8)/10;
689 else
690 h = MAX( 300, list_height );
691
692 h = MIN( ((double)SCREEN_H*2.)/3., h );
693 w = MAX( list_width + 60, 500 );
694
695 winw = w + extrawidth;
696 winh = MAX( h, minheight );
697
698 h = winh;
699
700 /* Create the window. */
701 wid = window_create( "dlgListPanel", title, -1, -1, winw, winh );
702 window_setData( wid, &done );
703 window_addText( wid, 20, -40, w-40, text_height, 0, "txtMsg",
704 font, NULL, msg );
705 window_setAccept( wid, dialogue_listClose );
706 window_setCancel( wid, dialogue_listCancel );
707
708 if (add_widgets)
709 add_widgets(wid, w, 0, winw, winh);
710
711 if (select_call) {
712 input_dialogue.x = w;
713 input_dialogue.y = 0;
714 input_dialogue.w = winw;
715 input_dialogue.h = winh;
716 input_dialogue.item_select_cb = select_call;
717 }
718
719 /* Create the list. */
720 window_addList( wid, 20, -40-text_height-20,
721 w-40, h - (40+text_height+20) - (20+30+20),
722 "lstDialogue", items, nitems, 0, select_call_wrapper,
723 dialogue_listClose );
724
725 /* Create the buttons. */
726 window_addButton( wid, -20, 20, 120, 30,
727 "btnOK", _("OK"), dialogue_listClose );
728 window_addButton( wid, -20-120-20, 20, 120, 30,
729 "btnCancel", _("Cancel"), dialogue_listCancel );
730
731 toolkit_loop( &done, NULL );
732 /* cleanup */
733 input_dialogue.x = 0;
734 input_dialogue.y = 0;
735 input_dialogue.w = 0;
736 input_dialogue.h = 0;
738
739 return dialogue_listSelected;
740}
741static unsigned int choice_wid = 0;
742static char *choice_result;
743static int choice_nopts;
751void dialogue_makeChoice( const char *caption, const char *msg, int opts )
752{
753 int w,h;
754 glFont* font;
755
756 choice_result = NULL;
757 choice_nopts = opts;
758 font = dialogue_getSize( caption, msg, &w, &h );
759
760 /* create window */
761 choice_wid = window_create( "dlgChoice", caption, -1, -1, w, h+100+40*choice_nopts );
762 /* text */
763 window_addText( choice_wid, 20, -40, w-40, h, 0, "txtChoice",
764 font, NULL, msg );
765}
773void dialogue_addChoice( const char *caption, const char *msg, const char *opt)
774{
775 int w,h;
776
777 if (choice_nopts < 1)
778 return;
779
780 dialogue_getSize( caption, msg, &w, &h );
781
782 /* buttons. Add one for each option in the menu. */
783 window_addButton( choice_wid, w/2-125, choice_nopts*40, 250, 30, (char *) opt,
784 (char *) opt, dialogue_choiceClose );
785 choice_nopts --;
786
787}
796{
797 int done;
798 char *res;
799
800 /* tricky secondary loop */
801 window_setData( choice_wid, &done );
802 toolkit_loop( &done, NULL );
803
804 /* Save value. */
805 res = choice_result;
806 choice_result = NULL;
807
808 return res;
809}
815static void dialogue_choiceClose( unsigned int wid, const char *str )
816{
817 int *loop_done;
818
819 /* Save result. */
820 choice_result = strdup(str);
821
822 /* Finish loop. */
823 loop_done = window_getData( wid );
824 *loop_done = 1;
825
826 /* destroy the window */
827 choice_wid = 0;
828 window_destroy( wid );
829}
830
831static int dialogue_custom_event( unsigned int wid, SDL_Event *event )
832{
833 int mx, my;
834 struct dialogue_custom_data_s *cd;
835 void *data = window_getData( wid );
836 cd = (struct dialogue_custom_data_s*) data;
837
838 /* We translate mouse coords here. */
839 if ((event->type==SDL_MOUSEBUTTONDOWN) ||
840 (event->type==SDL_MOUSEBUTTONUP) ||
841 (event->type==SDL_MOUSEMOTION)) {
842 gl_windowToScreenPos( &mx, &my, event->button.x, event->button.y );
843 mx += cd->mx;
844 my += cd->my;
845 /* Ignore out of bounds. We have to implement checking here. */
846 if ((mx < 0) || (mx >= cd->w) || (my < 0) || (my >= cd->h))
847 return 0;
848 event->button.x = mx;
849 event->button.y = my;
850 }
851
852 return (*cd->event)( wid, event, cd->data );
853}
867void dialogue_custom( const char* caption, int width, int height,
868 int (*update) (double dt, void* data),
869 void (*render) (double x, double y, double w, double h, void* data),
870 int (*event) (unsigned int wid, SDL_Event* event, void* data),
871 void* data, int autofree, int dynamic )
872{
873 struct dialogue_custom_data_s cd;
875 unsigned int wid;
876 int done, fullscreen;
877 int wx, wy, wgtx, wgty;
878
879 fullscreen = ((width < 0) && (height < 0));
880
881 /* create the window */
882 if (fullscreen) {
883 wid = window_create( "dlgMsg", caption, -1, -1, -1, -1 );
884 window_setBorder( wid, 0 );
885 }
886 else
887 wid = window_create( "dlgMsg", caption, -1, -1, width+40, height+60 );
888 window_setData( wid, &done );
889
890 /* custom widget for all! */
891 if (fullscreen) {
892 width = gl_screen.nw;
893 height = gl_screen.nh;
894 wgtx = wgty = 0;
895 }
896 else {
897 wgtx = wgty = 20;
898 }
899 window_addCust( wid, wgtx, wgty, width, height, "cstCustom", 0, render, NULL, NULL, NULL, data );
900 if (dynamic)
901 window_custSetDynamic( wid, "cstCustom", 1 );
902 if (autofree)
903 window_custAutoFreeData( wid, "cstCustom" );
904 window_custSetClipping( wid, "cstCustom", 1 );
905
906 /* set up event stuff. */
907 window_posWindow( wid, &wx, &wy );
908 window_posWidget( wid, "cstCustom", &wgtx, &wgty );
909 cd.event = event;
910 cd.data = data;
911 cd.mx = -wx-wgtx;
912 cd.my = -wy-wgty;
913 cd.w = width;
914 cd.h = height;
915 window_setData( wid, &cd );
916 if (event != NULL)
917 window_handleEvents( wid, &dialogue_custom_event );
918
919 /* dialogue stuff */
920 du.update = update;
921 du.data = data;
922 du.wid = wid;
923 toolkit_loop( &done, &du );
924}
925
933{
934 struct dialogue_custom_data_s *cd;
935 unsigned int wid = window_get( "dlgMsg" );
936 int w, h;
937 if (wid == 0)
938 return -1;
939
940 cd = (struct dialogue_custom_data_s*) window_getData( wid );
941 window_dimWindow( wid, &w, &h );
942
943 if (enable) {
944 cd->last_w = cd->w+40;
945 cd->last_h = cd->h+60;
946 window_resize( wid, -1, -1 );
947 window_moveWidget( wid, "cstCustom", 0, 0 );
948 window_resizeWidget( wid, "cstCustom", cd->last_w, cd->last_h );
949 window_move( wid, -1, -1 );
950 window_setBorder( wid, 0 );
951 }
952 else {
953 window_resize( wid, cd->last_w, cd->last_h );
954 window_moveWidget( wid, "cstCustom", 20, 20 );
955 window_move( wid, -1, -1 );
956 window_setBorder( wid, 1 );
957 }
958
959 return 0;
960}
961
969int dialogue_customResize( int width, int height )
970{
971 struct dialogue_custom_data_s *cd;
972 unsigned int wid = window_get( "dlgMsg" );
973 if (wid == 0)
974 return -1;
975 cd = (struct dialogue_custom_data_s*) window_getData( wid );
976 cd->last_w = width;
977 cd->last_h = height;
978 window_resize( wid, width+40, height+60 );
979 window_resizeWidget( wid, "cstCustom", width, height );
980 return 0;
981}
982
996static int toolkit_loop( int *loop_done, dialogue_update_t *du )
997{
998 Uint64 time_ms = SDL_GetTicks64();
999 const double fps_max = (conf.fps_max > 0) ? 1./(double)conf.fps_max : fps_min;
1000 int quit_game = 0;
1001
1002 /* Delay a toolkit iteration. */
1003 toolkit_delay();
1004
1005 /* Increment dialogues. */
1006 dialogue_open++;
1007 *loop_done = 0;
1008
1009 /* Flush events so SDL_LOOPDONE doesn't propagate. */
1010 SDL_FlushEvent( SDL_LOOPDONE );
1011
1012 while (!(*loop_done) && toolkit_isOpen() && !naev_isQuit()) {
1013 SDL_Event event;
1014 Uint64 t;
1015 double dt;
1016
1017 /* Loop first so exit condition is checked before next iteration. */
1018 main_loop( 1 );
1019
1020 while (!naev_isQuit() && SDL_PollEvent(&event)) { /* event loop */
1021 if (event.type == SDL_QUIT) {
1022 if (menu_askQuit()) {
1023 naev_quit(); /* Quit is handled here */
1024 *loop_done = 1; /* Exit loop and exit game. */
1025 quit_game = 1;
1026 break;
1027 }
1028 }
1029 else if (event.type == SDL_LOOPDONE) {
1030 *loop_done = 1;
1031 SDL_PushEvent( &event ); /* Replicate event until out of all loops. */
1032 break;
1033 }
1034 else if (event.type == SDL_WINDOWEVENT &&
1035 event.window.event == SDL_WINDOWEVENT_RESIZED)
1036 naev_resize();
1037
1038 input_handle(&event); /* handles all the events and player keybinds */
1039 }
1040
1041 /* FPS Control. */
1042 /* Get elapsed. */
1043 t = SDL_GetTicks64();
1044 dt = (double)(t - time_ms) / 1000.;
1045 time_ms = t;
1046 /* Sleep if necessary. */
1047 if (dt < fps_max) {
1048 double delay = fps_max - dt;
1049 SDL_Delay( (unsigned int)(delay * 1000.) );
1050 }
1051
1052 /* Update stuff. */
1053 if (du != NULL) {
1054 /* Run update. */
1055 if ((*du->update)(dt, du->data)) {
1056 /* Hack to override data. */
1057 window_setData( du->wid, loop_done );
1058 dialogue_close( du->wid, NULL );
1059 }
1060 }
1061 }
1062
1063 /* Close dialogue. */
1064 dialogue_open--;
1065 if (dialogue_open < 0)
1066 WARN(_("Dialogue counter not in sync!"));
1067
1068 return quit_game;
1069}
static char * choice_result
Definition dialogue.c:742
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:996
char * dialogue_runChoice(void)
Run the dialog and return the clicked string.
Definition dialogue.c:795
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:469
static int dlgid
Definition dialogue.c:39
void dialogue_alert(const char *fmt,...)
Displays an alert popup with only an ok button and a message.
Definition dialogue.c:132
static void dialogue_choiceClose(unsigned int wid, const char *str)
Closes a choice dialogue.
Definition dialogue.c:815
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:662
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
void dialogue_custom(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 autofree, int dynamic)
Opens a custom dialogue window.
Definition dialogue.c:867
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:603
static void dialogue_close(unsigned int wid, const char *str)
Generic window close.
Definition dialogue.c:106
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:565
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:624
void dialogue_msg(const char *caption, const char *fmt,...)
Opens a dialogue window with an ok button and a message.
Definition dialogue.c:230
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:580
void dialogue_addChoice(const char *caption, const char *msg, const char *opt)
Add a choice to the dialog.
Definition dialogue.c:773
static glFont * dialogue_getSize(const char *title, const char *msg, int *width, int *height)
Gets the size needed for the dialogue.
Definition dialogue.c:180
void dialogue_alertRaw(const char *msg)
Displays an alert popup with only an ok button and a message.
Definition dialogue.c:151
int dialogue_customResize(int width, int height)
Resizes a custom dialogue.
Definition dialogue.c:969
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:298
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:751
static void dialogue_inputClose(unsigned int wid, const char *str)
Closes an input dialogue.
Definition dialogue.c:536
static unsigned int choice_wid
Definition dialogue.c:741
static int dialogue_open
Definition dialogue.c:38
static int choice_nopts
Definition dialogue.c:743
void main_loop(int nested)
Split main loop from main() for secondary loop hack in toolkit.c.
Definition naev.c:744
void dialogue_msgRaw(const char *caption, const char *msg)
Opens a dialogue window with an ok button and a fixed message.
Definition dialogue.c:271
int dialogue_isOpen(void)
Checks to see if a dialogue is open.
Definition dialogue.c:98
static InputDialogue input_dialogue
Definition dialogue.c:429
static void dialogue_cancel(unsigned int wid, const char *str)
Generic window cancel.
Definition dialogue.c:118
int dialogue_YesNo(const char *caption, const char *fmt,...)
Runs a dialogue with both yes and no options.
Definition dialogue.c:352
int dialogue_customFullscreen(int enable)
Converts a custom dialogue to fullscreen.
Definition dialogue.c:932
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:251
static void dialogue_YesNoClose(unsigned int wid, const char *str)
Closes a yesno dialogue.
Definition dialogue.c:409
int gl_printHeightRaw(const glFont *ft_font, const int width, const char *text)
Gets the height of a non-formatted string.
Definition font.c:1027
int gl_printWidthRaw(const glFont *ft_font, const char *text)
Gets the width that it would take to print some text.
Definition font.c:961
glFont gl_defFont
Definition font.c:153
void input_handle(SDL_Event *event)
Handles global input.
Definition input.c:1485
Handles the important game menus.
void naev_quit(void)
Flags naev to quit.
Definition naev.c:150
void naev_resize(void)
Wrapper for gl_resize that handles non-GL reinitialization.
Definition naev.c:790
int naev_isQuit(void)
Get if Naev is trying to quit.
Definition naev.c:158
const double fps_min
Definition naev.c:118
Uint32 SDL_LOOPDONE
Definition naev.c:101
static Uint64 time_ms
Definition naev.c:102
Header file with generic functions and naev-specifics.
#define MIN(x, y)
Definition naev.h:40
#define FABS(x)
Definition naev.h:37
#define MAX(x, y)
Definition naev.h:39
#define PATH_MAX
Definition naev.h:50
void gl_windowToScreenPos(int *sx, int *sy, int wx, int wy)
Translates the window position to screen position.
Definition opengl.c:616
glInfo gl_screen
Definition opengl.c:51
glTexture * gl_newImage(const char *path, const unsigned int flags)
Loads an image as a texture.
Definition opengl_tex.c:675
static const double d[]
Definition rng.c:273
Used to store information for input dialogues.
Definition dialogue.c:83
void(* item_select_cb)(unsigned int wid, const char *wgtname, int x, int y, int w, int h)
Definition dialogue.c:89
unsigned int input_wid
Definition dialogue.c:84
int fps_max
Definition conf.h:113
Represents a font in memory.
Definition font.h:16
int h
Definition font.h:18
int nw
Definition opengl.h:47
int nh
Definition opengl.h:48
Abstraction for rendering sprite sheets.
Definition opengl_tex.h:36
double w
Definition opengl_tex.h:40
double h
Definition opengl_tex.h:41
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:691
void window_setAccept(unsigned int wid, void(*accept)(unsigned int, const char *))
Sets the default accept function of the window.
Definition toolkit.c:847
void window_dimWindow(unsigned int wid, int *w, int *h)
Gets the dimensions of a window.
Definition toolkit.c:371
int toolkit_isOpen(void)
Checks to see if the toolkit is open.
Definition toolkit.c:94
void window_move(unsigned int wid, int x, int y)
Moves a window to the specified coordinates.
Definition toolkit.c:179
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:465
void window_resize(unsigned int wid, int w, int h)
Resizes the window.
Definition toolkit.c:196
void toolkit_delay(void)
Delays the toolkit purge by an iteration, useful for dialogues.
Definition toolkit.c:106
void window_posWidget(unsigned int wid, const char *name, int *x, int *y)
Gets a widget's position.
Definition toolkit.c:442
unsigned int window_get(const char *wdwname)
Gets the ID of a window.
Definition toolkit.c:666
void window_setBorder(unsigned int wid, int enable)
Sets or removes the border of a window.
Definition toolkit.c:941
void window_posWindow(unsigned int wid, int *x, int *y)
Gets the dimensions of a window.
Definition toolkit.c:393
void * window_getData(unsigned int wid)
Gets the custom data of a window.
Definition toolkit.c:922
void window_setData(unsigned int wid, void *data)
Sets custom data for a window.
Definition toolkit.c:905
void window_resizeWidget(unsigned int wid, const char *name, int w, int h)
Resizes a widget.
Definition toolkit.c:493
void window_destroy(unsigned int wid)
Kills the window.
Definition toolkit.c:1037
void window_handleEvents(unsigned int wid, int(*eventhandler)(unsigned int, SDL_Event *))
Sets the event handler for the window.
Definition toolkit.c:977