[Add] Input dialogues can now be cancelled and return NULL.
This commit is contained in:
parent
7f10a1e69e
commit
b31fda7ce8
10
src/land.c
10
src/land.c
@ -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! */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
30
src/player.c
30
src/player.c
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user