[Add] Input dialogues can now be cancelled and return NULL.

This commit is contained in:
Allanis 2013-09-15 21:39:51 +01:00
parent 7f10a1e69e
commit b31fda7ce8
7 changed files with 111 additions and 29 deletions

View File

@ -247,8 +247,9 @@ static void outfits_open(void) {
snprintf(buf, 128, "%s - Outfits", land_planet->name);
secondary_wid = window_create(buf, -1, -1,
OUTFITS_WIDTH, OUTFITS_HEIGHT);
/* Will allow buying from keyboard. */
window_setFptr(secondary_wid, outfits_buy);
window_setAccept(secondary_wid, outfits_buy);
/* Buttons. */
window_addButton(secondary_wid, -20, 20,
@ -674,8 +675,11 @@ static void shipyard_buy(char* str) {
"Do you really want to spend %s on a new ship?", buf)==0)
return;
player_newShip(ship, player->solid->pos.x, player->solid->pos.y,
0., 0., player->solid->dir);
if(player_newShip(ship, player->solid->pos.x, player->solid->pos.y,
0., 0., player->solid->dir) != 0) {
/* Player actually oborted naming process. */
return;
}
player->credits -= ship->price; /* Auch! Paying is hard! */

View File

@ -161,6 +161,8 @@ void menu_small(void) {
wid = window_create("Menu", -1, -1, MENU_WIDTH, MENU_HEIGHT);
window_setCancel(wid, menu_small_close);
window_addButton(wid, 20, 20 + BUTTON_HEIGHT*2 + 20*2,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnResume", "Resume", menu_small_close);
@ -176,9 +178,8 @@ void menu_small(void) {
}
static void menu_small_close(char* str) {
if(strcmp(str, "btnResume")==0)
window_destroy(window_get("Menu"));
(void)str;
window_destroy(window_get("Menu"));
menu_Close(MENU_SMALL);
}

View File

@ -216,6 +216,12 @@ void player_new(void) {
player_name = dialogue_input("Player Name", 3, 20,
"Please tell me your name:");
/* Player cancelled dialogue. */
if(player_name == NULL) {
menu_main();
return;
}
if(lfile_fileExists("saves/%s.ls", player_name)) {
r = dialogue_YesNo("Overwrite",
"You already have a pilot named %s. Overwrite?", player_name);
@ -311,8 +317,12 @@ static void player_newMake(void) {
player_message("Welcome to "APPNAME"!");
player_message("v%d.%d.%d", VMAJOR, VMINOR, VREV);
/* Create the player and start the game. */
player_newShip(ship, x, y, 0., 0., RNG(0, 359)/180.*M_PI);
/* Try to create the pilot, if fails re-ask for player name. */
if(player_newShip(ship, x, y, 0., 0., RNG(0, 369)/180.*M_PI) != 0) {
player_new();
return;
}
space_init(sysname);
free(sysname);
@ -321,14 +331,15 @@ static void player_newMake(void) {
}
/**
* @fn void player_newShip(Ship* ship, double px, double py,
* @fn int player_newShip(Ship* ship, double px, double py,
* double vx, double vy, double dir)
*
* @brief Create a new ship for player.
* @return 0 indicates success, -1 means dialogue was cancelled.
*
* @sa player_newShipMake
*/
void player_newShip(Ship* ship, double px, double py,
int player_newShip(Ship* ship, double px, double py,
double vx, double vy, double dir) {
char* ship_name;
@ -341,11 +352,18 @@ void player_newShip(Ship* ship, double px, double py,
player_vy = vy;
player_dir = dir;
ship_name = dialogue_input("Player Name", 3, 20,
ship_name = dialogue_input("Ship Name", 3, 20,
"Please name your shiny new %s", ship->name);
/* Dialogue cancelled. */
if(ship_name == NULL)
return -1;
player_newShipMake(ship_name);
free(ship_name);
return 0;
}
/**
@ -357,7 +375,7 @@ static void player_newShipMake(char* name) {
Vec2 vp, vv;
/* Store the current ship if it exists. */
if(player) {
if(player != NULL) {
player_stack = realloc(player_stack, sizeof(Pilot*)*(player_nstack+1));
player_stack[player_nstack] = pilot_copy(player);
player_lstack = realloc(player_lstack, sizeof(char*)*(player_nstack+1));

View File

@ -31,7 +31,7 @@ typedef enum RadarShape_ { RADAR_RECT, RADAR_CIRCLE } RadarShape;
/* Creation/Cleanup. */
void player_new(void);
void player_newShip(Ship* ship, double px, double py,
int player_newShip(Ship* ship, double px, double py,
double vx, double vy, double dir);
void player_cleanup(void);
int gui_load(const char* name);

View File

@ -144,7 +144,7 @@ void load_game_menu(void) {
"btnDelete", "Del", load_menu_delete);
/* Default action. */
window_setFptr(wid, load_menu_load);
window_setAccept(wid, load_menu_load);
}
static void load_menu_close(char* str) {

View File

@ -1,3 +1,9 @@
/**
* @file toolkit.c
*
* @brief Handle window and widgets.
*/
#include <stdarg.h>
#include "lephisto.h"
@ -92,9 +98,10 @@ typedef struct Window_ {
int hidden; /* Is it hidden? */
int focus; /* Which window is focused. */
/* Pointer to a function to run if user hits 'enter' and no button is focused */
/* nor any other input thiny that catches 'enter'. */
void(*def_fptr)(char*);
void(*accept_fptr)(char*); /**< Triggered by hitting 'enter' with no widget
that catches the keypress. */
void(*cancel_fptr)(char*); /**< Triggered by hitting 'escape' with no
widget that catches the keypress. */
double x,y; /* Position. */
double w,h; /* Dimensions. */
@ -158,6 +165,7 @@ 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);
@ -491,9 +499,10 @@ unsigned int window_create(char* name, const int x, const int y,
wdw->id = wid;
wdw->name = strdup(name);
wdw->hidden = 0;
wdw->focus = -1;
wdw->def_fptr = NULL;
wdw->hidden = 0;
wdw->focus = -1;
wdw->accept_fptr = NULL;
wdw->cancel_fptr = NULL;
wdw->w = (double)w;
wdw->h = (double)h;
@ -530,12 +539,40 @@ unsigned int window_create(char* name, const int x, const int y,
return wid;
}
/* Sets the window's default function. */
void window_setFptr(const unsigned int wid, void(*fptr)(char*)) {
/**
* @fn void window_setAccept(const unsigned int wid, void(*accept)(char*))
*
* @brief Set the default accept function of the window.
*
* This function is called whenever 'enter' is pressed and the current widget
* does not catch it. NULL disables the accept function.
* @param wid ID of the window to set the accept function.
* @param accept Function to trigger when window is "accepted". Parameter
* passed is window name.
*/
void window_setAccept(const unsigned int wid, void(*accept)(char*)) {
Window* wdw;
wdw = window_wget(wid);
if(wdw != NULL) wdw->def_fptr = fptr;
if(wdw != NULL) wdw->accept_fptr = accept;
}
/**
* @fn void window_setCancel(const unsigned int wid, void(*cancel)(char*))
*
* @brief Set the default cancel function of the window.
*
* This function is called whenever 'escape' is hit and the current widget
* does not catch it. NULL disables the cancel function.
* @param wid ID of the window to set cancel function.
* @param cancel Function to trigger when window is "cancelled".
* Parameter passed is the window name.
*/
void window_setCancel(const unsigned int wid, void(*cancel)(char*)) {
Window* wdw;
wdw = window_wget(wid);
if(wdw != NULL) wdw->cancel_fptr = cancel;
}
/* Destroy a widget. */
@ -1288,6 +1325,13 @@ static int toolkit_keyEvent(SDL_Event* event) {
if(event->type == SDL_KEYDOWN)
toolkit_triggerFocus();
return 1;
case SDLK_ESCAPE:
if(event->type == SDL_KEYDOWN)
if(wdw->cancel_fptr != NULL) {
(*wdw->cancel_fptr)(wdw->name);
return 1;
}
return 0;
case SDLK_UP:
if(event->type == SDL_KEYDOWN) {
toolkit_regKey(SDLK_UP);
@ -1391,7 +1435,7 @@ static void toolkit_triggerFocus(void) {
wgt->name, wdw->name);
break;
default:
if(wdw->def_fptr)(*wdw->def_fptr)(wgt->name);
if(wdw->accept_fptr)(*wdw->accept_fptr)(wgt->name);
break;
}
}
@ -1598,6 +1642,7 @@ static void dialogue_YesNoClose(char* str) {
/* 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;
@ -1613,12 +1658,16 @@ char* dialogue_input(char* title, int min, int max, const char* fmt, ...) {
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_setFptr(input_wid, dialogue_inputClose);
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);
@ -1632,7 +1681,8 @@ char* dialogue_input(char* title, int min, int max, const char* fmt, ...) {
/* Tricky secondary loop. */
input = NULL;
while(!input || ((int)strlen(input) < min)) {
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);
@ -1640,11 +1690,14 @@ char* dialogue_input(char* title, int min, int max, const char* fmt, ...) {
input = NULL;
}
if(toolkit_loop()) /* Error in loop -> quit. */
if(toolkit_loop() != 0) /* Error in loop -> quit. */
return NULL;
/* Save the input. */
input = strdup(window_getInput(input_wid, "inpInput"));
if(input_cancelled != 0)
input = NULL;
else
input = strdup(window_getInput(input_wid, "inpInput"));
}
/* Cleanup. */
@ -1661,6 +1714,11 @@ static void dialogue_inputClose(char* str) {
loop_done = 1;
}
static void dialogue_inputCancel(char* str) {
input_cancelled = 1;
dialogue_inputClose(str);
}
/* Init. */
int toolkit_init(void) {
windows = malloc(sizeof(Window)*MIN_WINDOWS);

View File

@ -53,7 +53,8 @@ int dialogue_YesNo(char* caption, const char* fmt, ...);
char* dialogue_input(char* title, int min, int max, const char* fmt, ...);
/* Modification. */
void window_setFptr(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*));
/* Text. */
void window_modifyText(const unsigned int wid, char* name, char* newstring);
/* Button. */