[Change] Seperated dialogues from toolkit.

This commit is contained in:
Allanis 2013-10-05 18:38:40 +01:00
parent 8e4b78621e
commit b748f0f18e
9 changed files with 295 additions and 266 deletions

280
src/dialogue.c Normal file
View File

@ -0,0 +1,280 @@
/**
* @file dialogue.c.
*
* @brief Handles dialogue stuff.
*/
#include <stdarg.h>
#include "lephisto.h"
#include "log.h"
#include "toolkit.h"
#include "pause.h"
#include "opengl.h"
#include "input.h"
#include "dialogue.h"
/* Extern. */
extern void main_loop(void); /* From lephisto.c */
/* Dialogues. */
static glFont* dialogue_getSize(char* msg, int* w, int* h);
static void dialogue_alertClose(char* str);
static void dialogue_msgClose(char* str);
static void dialogue_YesNoClose(char* str);
static void dialogue_inputClose(char* str);
static void dialogue_inputCancel(char* str);
/* Secondary loop hack. */
static int loop_done;
static int toolkit_loop(void);
/**
* @fn void dialogue_alert(const char* fmt, ...)
*
* @brief Display an alert popup with only an ok button and a message.
* @param fmt Printf stype message to display.
*/
void dialogue_alert(const char* fmt, ...) {
char msg[512];
va_list ap;
unsigned int wdw;
int h;
if(window_exists("Warning")) return;
if(fmt == NULL) return;
else { /* Get the message. */
va_start(ap, fmt);
vsprintf(msg, fmt, ap);
va_end(ap);
}
h = gl_printHeight(&gl_smallFont, 260, msg);
wdw = window_create("Warning", -1, -1, 300, 90+h);
window_addText(wdw, 20, -30, 260, h, 0, "txtAlert",
&gl_smallFont, &cBlack, msg);
window_addButton(wdw, 135, 20, 50, 30, "btnOK", "OK",
dialogue_alertClose);
}
/**
* @fn static void dialogue_alertClose(char* str)
*
* @brief Closes the alert dialogue.
* @param str Unused.
*/
static void dialogue_alertClose(char* str) {
(void)str;
if(window_exists("Warning"))
window_destroy(window_get("Warning"));
}
/**
* @fn static glFont* dialogue_getSize(char* msg, int* w, int* h)
*
* @brief Get the size needed for the dialogue.
* @param msg Message of the dialogue.
* @param[out] w Get the width needed.
* @param[out] h Get the height needed.
*/
static glFont* dialogue_getSize(char* msg, int* w, int* h) {
glFont* font;
font = &gl_smallFont; /* Try to use small font. */
(*h) = gl_printHeight(font, (*w)-40, msg);
if(strlen(msg) > 100) { /* Make font bigger for large texts. */
font = &gl_defFont;
(*h) = gl_printHeight(font, (*w)-40, msg);
if((*h) > 200) (*w) += MIN((*h)-200, 600); /* Too big, so we make it wider. */
(*h) = gl_printHeight(font, (*w)-40, msg);
}
return font;
}
/* Displays an alert popup with only an ok button and a message. */
static unsigned int msg_wid = 0;
void dialogue_msg(char* caption, const char* fmt, ...) {
char msg[4096];
va_list ap;
int w, h;
glFont* font;
if(msg_wid) return;
if(fmt == NULL) return;
else {
va_start(ap, fmt);
vsprintf(msg, fmt, ap);
va_end(ap);
}
w = 300; /* Default width. */
font = dialogue_getSize(msg, &w, &h);
/* Create the window. */
msg_wid = window_create(caption, -1, -1, w, 110 + h);
window_addText(msg_wid, 20, -40, w-40, h, 0, "txtMsg",
font, &cBlack, msg);
window_addButton(msg_wid, (w-50)/2, 20, 50, 30, "btnOK", "OK",
dialogue_msgClose);
toolkit_loop();
}
static void dialogue_msgClose(char* str) {
(void)str;
window_destroy(msg_wid);
msg_wid = 0;
loop_done = 1;
}
/* Run a dialogue with a Yes and No button, return 1 if yes, 0 for no. */
static int yesno_result;
static unsigned int yesno_wid = 0;
int dialogue_YesNo(char* caption, const char* fmt, ...) {
char msg[4096];
va_list ap;
int w, h;
glFont* font;
if(yesno_wid) return -1;
if(fmt == NULL) return -1;
else { /* Get the message. */
va_start(ap, fmt);
vsprintf(msg, fmt, ap);
va_end(ap);
}
w = 300;
font = dialogue_getSize(msg, &w, &h);
/* Create the window. */
yesno_wid = window_create(caption, -1, -1, w, h+110);
/* Text. */
window_addText(yesno_wid, 20, -40, w-40, h, 0, "txtYesNo",
font, &cBlack, msg);
/* Buttons. */
window_addButton(yesno_wid, w/2-50-10, 20, 50, 30, "btnYes", "Yes",
dialogue_YesNoClose);
window_addButton(yesno_wid, w/2+10, 20, 50, 30, "btnNo", "No",
dialogue_YesNoClose);
/* Tricky secondary loop. */
toolkit_loop();
/* Return the result. */
return yesno_result;
}
static void dialogue_YesNoClose(char* str) {
/* Store the result. */
if(strcmp(str, "btnYes")==0) yesno_result = 1;
else if(strcmp(str, "btnNo")==0) yesno_result = 0;
/* Destroy the window. */
window_destroy(yesno_wid);
yesno_wid = 0;
loop_done = 1;
}
/* Toolkit input boxes, returns the input. */
static unsigned int input_wid = 0;
static int input_cancelled = 0;
char* dialogue_input(char* title, int min, int max, const char* fmt, ...) {
char msg[512], *input;
va_list ap;
int h;
if(input_wid) return NULL;
if(fmt == NULL) return NULL;
else { /* Get the message. */
va_start(ap, fmt);
vsprintf(msg, fmt, ap);
va_end(ap);
}
/* Start out not cancelled. */
input_cancelled = 0;
/* Get text height. */
h = gl_printHeight(&gl_smallFont, 200, msg);
/* Create Window. */
input_wid = window_create(title, -1, -1, 240, h+140);
window_setAccept(input_wid, dialogue_inputClose);
window_setCancel(input_wid, dialogue_inputCancel);
/* Input. */
window_addText(input_wid, 30, -30, 200, h, 0, "txtInput",
&gl_smallFont, &cDConsole, msg);
window_addButton(input_wid, -20, 20, 80, 30,
"btnClose", "Done", dialogue_inputClose);
/* Tricky secondary. */
input = NULL;
while(!input_cancelled && (!input ||
((int) strlen(input) < min))) { /* Must be longer than min. */
if(input) {
dialogue_alert("Input must be at least %d characters long!", min);
free(input);
input = NULL;
}
if(toolkit_loop() != 0) /* Error in loop -> quit. */
return NULL;
if(input_cancelled != 0)
input = NULL;
else
input = strdup(window_getInput(input_wid, "inpInput"));
}
/* Cleanup plox. */
window_destroy(input_wid);
input_wid = 0;
return input;
}
static void dialogue_inputClose(char* str) {
(void)str;
/* Break the loop. */
loop_done = 1;
}
static void dialogue_inputCancel(char* str) {
input_cancelled = 1;
dialogue_inputClose(str);
}
/*
* Spawns a secondary loop that only works until the toolkit dies,
* alot like the main while loop in lephisto.c
*/
static int toolkit_loop(void) {
SDL_Event event, quit = { .type = SDL_QUIT };
loop_done = 0;
while(!loop_done && toolkit) {
while(SDL_PollEvent(&event)) { /* Event loop. */
if(event.type == SDL_QUIT) { /* Pass quit event to main engine. */
loop_done = 1;
SDL_PushEvent(&quit);
return -1;
}
input_handle(&event); /* Handles all the events and player keybinds. */
}
main_loop();
}
return 0;
}

10
src/dialogue.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
/*
* Popups and alerts.
*/
void dialogue_alert(const char* ftm, ...); /* Does not pause execution. */
void dialogue_msg(char* caption, const char* fmt, ...);
int dialogue_YesNo(char* caption, const char* fmt, ...); /* Yes = 1, No = 0. */
char* dialogue_input(char* title, int min, int max, const char* fmt, ...);

View File

@ -6,6 +6,7 @@
#include "lephisto.h" #include "lephisto.h"
#include "log.h" #include "log.h"
#include "toolkit.h" #include "toolkit.h"
#include "dialogue.h"
#include "player.h" #include "player.h"
#include "rng.h" #include "rng.h"
#include "music.h" #include "music.h"

View File

@ -4,7 +4,7 @@
#include "lephisto.h" #include "lephisto.h"
#include "rng.h" #include "rng.h"
#include "ltime.h" #include "ltime.h"
#include "toolkit.h" #include "dialogue.h"
#include "space.h" #include "space.h"
#include "land.h" #include "land.h"
#include "map.h" #include "map.h"

View File

@ -2,6 +2,7 @@
#include <SDL.h> #include <SDL.h>
#include "toolkit.h" #include "toolkit.h"
#include "dialogue.h"
#include "log.h" #include "log.h"
#include "lephisto.h" #include "lephisto.h"
#include "pilot.h" #include "pilot.h"

View File

@ -21,6 +21,7 @@
#include "pause.h" #include "pause.h"
#include "menu.h" #include "menu.h"
#include "toolkit.h" #include "toolkit.h"
#include "dialogue.h"
#include "mission.h" #include "mission.h"
#include "misn_lua.h" #include "misn_lua.h"
#include "ltime.h" #include "ltime.h"

View File

@ -7,6 +7,7 @@
#include "xml.h" #include "xml.h"
#include "player.h" #include "player.h"
#include "toolkit.h" #include "toolkit.h"
#include "dialogue.h"
#include "menu.h" #include "menu.h"
#include "lfile.h" #include "lfile.h"
#include "hook.h" #include "hook.h"

View File

@ -124,9 +124,6 @@ static glColour* toolkit_colLight = &cGrey90;
static glColour* toolkit_col = &cGrey70; static glColour* toolkit_col = &cGrey70;
static glColour* toolkit_colDark = &cGrey30; static glColour* toolkit_colDark = &cGrey30;
/* Extern. */
extern void main_loop(void); /* lephisto.c */
/* Static. */
/* Widgets. */ /* Widgets. */
static Widget* window_newWidget(Window* w); static Widget* window_newWidget(Window* w);
static void widget_cleanup(Widget* widget); static void widget_cleanup(Widget* widget);
@ -159,16 +156,6 @@ static void toolkit_clip(double x, double y, double w, double h);
static void toolkit_unclip(void); static void toolkit_unclip(void);
static void toolkit_drawRect(double x, double y, double w, double h, static void toolkit_drawRect(double x, double y, double w, double h,
glColour* c, glColour* lc); glColour* c, glColour* lc);
/* Dialogues.. */
static glFont* dialogue_getSize(char* msg, int* w, int* h);
static void dialogue_alertClose(char* str);
static void dialogue_msgClose(char* str);
static void dialogue_YesNoClose(char* str);
static void dialogue_inputClose(char* str);
static void dialogue_inputCancel(char* str);
/* Secondary loop hack. */
static int loop_done;
static int toolkit_loop(void);
/* Set the internal widget position. */ /* Set the internal widget position. */
static void toolkit_setPos(Window* wdw, Widget* wgt, int x, int y) { static void toolkit_setPos(Window* wdw, Widget* wgt, int x, int y) {
@ -1499,226 +1486,6 @@ static Widget* toolkit_getFocus(void) {
return &wdw->widgets[wdw->focus]; return &wdw->widgets[wdw->focus];
} }
void dialogue_alert(const char* fmt, ...) {
char msg[512];
va_list ap;
unsigned int wdw;
int h;
if(window_exists("Warning")) return;
if(fmt == NULL) return;
else {
/* Get the message. */
va_start(ap, fmt);
vsprintf(msg, fmt, ap);
va_end(ap);
}
h = gl_printHeight(&gl_smallFont, 260, msg);
/* Create window. */
wdw = window_create("Warning", -1, -1, 300, 90+h);
window_addText(wdw, 20, -30, 260, h, 0, "txtAlert",
&gl_smallFont, &cBlack, msg);
window_addButton(wdw, 135, 20, 50, 30, "btnOK", "OK",
dialogue_alertClose);
}
static void dialogue_alertClose(char* str) {
(void)str;
if(window_exists("Warning"))
window_destroy(window_get("Warning"));
}
static glFont* dialogue_getSize(char* msg, int* w, int* h) {
glFont* font;
font = &gl_smallFont; /* Try to use smallfont. */
(*h) = gl_printHeight(font, (*w)-40, msg);
if(strlen(msg) > 100) {
/* Make font bigger for large text area's. */
font = &gl_defFont;
(*h) = gl_printHeight(font, (*w)-40, msg);
if((*h) > 200) (*w) += MIN((*h)-200, 600); /* Too big, so we make it wider. */
(*h) = gl_printHeight(font, (*w)-40, msg);
}
return font;
}
/* Display an alert popup with only an OK button and a message. */
static unsigned int msg_wid = 0;
void dialogue_msg(char* caption, const char* fmt, ...) {
char msg[4096];
va_list ap;
int w, h;
glFont* font;
if(msg_wid) return;
if(fmt == NULL) return;
else {
/* Get the message. */
va_start(ap, fmt);
vsprintf(msg, fmt, ap);
va_end(ap);
}
w = 300; /* Default width. */
font = dialogue_getSize(msg, &w, &h);
/* Create the window. */
msg_wid = window_create(caption, -1, -1, w, 110+h);
window_addText(msg_wid, 20, -40, w-40, h, 0, "txtMsg",
font, &cBlack, msg);
window_addButton(msg_wid, (w-50)/2, 20, 50, 30, "btnOK", "OK",
dialogue_msgClose);
toolkit_loop();
}
static void dialogue_msgClose(char* str) {
(void)str;
window_destroy(msg_wid);
msg_wid = 0;
loop_done = 1;
}
/* Runs a dialogue with a Yes No button, return 1 if yes. */
static int yesno_result;
static unsigned int yesno_wid = 0;
int dialogue_YesNo(char* caption, const char* fmt, ...) {
char msg[4096];
va_list ap;
int w, h;
glFont* font;
if(yesno_wid) return -1;
if(fmt == NULL) return -1;
else {
/* Get the message. */
va_start(ap, fmt);
vsprintf(msg, fmt, ap);
va_end(ap);
}
w = 300;
font = dialogue_getSize(msg, &w, &h);
/* Create window. */
yesno_wid = window_create(caption, -1, -1, w, h+110);
/* Text. */
window_addText(yesno_wid, 20, -40, w-40, h, 0, "txtYesNo",
font, &cBlack, msg);
/* Buttons. */
window_addButton(yesno_wid, w/2-50-10, 20, 50, 30, "btnYes", "Yes",
dialogue_YesNoClose);
window_addButton(yesno_wid, w/2+50+10, 20, 50, 30, "btnNo", "No",
dialogue_YesNoClose);
/* Tricky secondary loop. */
toolkit_loop();
/* Return the result. */
return yesno_result;
}
static void dialogue_YesNoClose(char* str) {
/* Store the result. */
if(strcmp(str, "btnYes")==0) yesno_result = 1;
else if(strcmp(str, "btnNo")==0) yesno_result = 0;
/* Destroy the window. */
window_destroy(yesno_wid);
yesno_wid = 0;
loop_done = 1;
}
/* Toolkit input boxes, return input. */
static unsigned int input_wid = 0;
static int input_cancelled = 0;
char* dialogue_input(char* title, int min, int max, const char* fmt, ...) {
char msg[512], *input;
va_list ap;
int h;
if(input_wid) return NULL;
if(fmt == NULL) return NULL;
else {
/* Get the message. */
va_start(ap, fmt);
vsprintf(msg, fmt, ap);
va_end(ap);
}
/* Start out not cancelled. */
input_cancelled = 0;
/* Get text height. */
h = gl_printHeight(&gl_smallFont, 200, msg);
/* Create the window. */
input_wid = window_create(title, -1, -1, 240, h+140);
window_setAccept(input_wid, dialogue_inputClose);
window_setCancel(input_wid, dialogue_inputCancel);
/* Text. */
window_addText(input_wid, 30, -30, 200, h, 0, "txtInput",
&gl_smallFont, &cDConsole, msg);
/* Input. */
window_addInput(input_wid, 20, -50-h, 200, 20, "inpInput", max, 1);
/*Button. */
window_addButton(input_wid, -20, 20, 80, 30,
"btnClose", "Done", dialogue_inputClose);
/* Tricky secondary loop. */
input = NULL;
while(!input_cancelled && (!input ||
((int)strlen(input) < min))) { /* Must be longer then min. */
/* Must be longer than min. */
if(input) {
dialogue_alert("Input must be at least %d characters long!", min);
free(input);
input = NULL;
}
if(toolkit_loop() != 0) /* Error in loop -> quit. */
return NULL;
/* Save the input. */
if(input_cancelled != 0)
input = NULL;
else
input = strdup(window_getInput(input_wid, "inpInput"));
}
/* Cleanup. */
window_destroy(input_wid);
input_wid = 0;
return input;
}
static void dialogue_inputClose(char* str) {
(void)str;
/* Break the loop. */
loop_done = 1;
}
static void dialogue_inputCancel(char* str) {
input_cancelled = 1;
dialogue_inputClose(str);
}
/* Init. */ /* Init. */
int toolkit_init(void) { int toolkit_init(void) {
windows = malloc(sizeof(Window)*MIN_WINDOWS); windows = malloc(sizeof(Window)*MIN_WINDOWS);
@ -1735,26 +1502,3 @@ void toolkit_exit(void) {
free(windows); free(windows);
} }
/* Spawns a secondary loop that only works until the toolkit dies. */
/* A lot like the main while loop in lephisto.c. */
static int toolkit_loop(void) {
SDL_Event event, quit = { .type = SDL_QUIT };
loop_done = 0;
while(!loop_done && toolkit) {
while(SDL_PollEvent(&event)) {
/* Event loopz. */
if(event.type == SDL_QUIT) {
/* Pass quit event to main engine. */
loop_done = 1;
SDL_PushEvent(&quit);
return 1;
}
/* Handles all the events and player keybinds. */
input_handle(&event);
}
main_loop();
}
return 0;
}

View File

@ -43,15 +43,6 @@ void window_addInput(const unsigned int wid,
const int w, const int h, const int w, const int h,
char* name, const int max, const int oneline); char* name, const int max, const int oneline);
/* Popups and alerts. */
/* Does not pause execution. */
void dialogue_alert(const char* fmt, ...);
void dialogue_msg(char* caption, const char* fmt, ...);
/* Yes = 1, No = 0. */
int dialogue_YesNo(char* caption, const char* fmt, ...);
char* dialogue_input(char* title, int min, int max, const char* fmt, ...);
/* Modification. */ /* Modification. */
void window_setAccept(const unsigned int wid, void(*fptr)(char*)); void window_setAccept(const unsigned int wid, void(*fptr)(char*));
void window_setCancel(const unsigned int wid, void(*cancel)(char*)); void window_setCancel(const unsigned int wid, void(*cancel)(char*));