From 79f63662dd7c0cb4022e47fd053d589ec0a18769 Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Sat, 23 Mar 2013 19:48:52 +0000
Subject: [PATCH] [Add] Simple yes/no confirmation dialog.

---
 bin/conf       |  4 +--
 src/input.c    | 10 +++++++
 src/land.c     |  7 ++++-
 src/lephisto.c | 53 +++++++++++++++-------------------
 src/toolkit.c  | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/toolkit.h  |  1 +
 6 files changed, 119 insertions(+), 33 deletions(-)

diff --git a/bin/conf b/bin/conf
index 08fef31..7228683 100644
--- a/bin/conf
+++ b/bin/conf
@@ -1,6 +1,6 @@
 --WINDOW.
-width       = 800
-height      = 640
+width       = 1280
+height      = 1024
 fullscreen  = 0
 
 -- SCREEN.
diff --git a/src/input.c b/src/input.c
index 62976a3..11115d1 100644
--- a/src/input.c
+++ b/src/input.c
@@ -332,6 +332,16 @@ static void input_keyup(SDLKey key) {
 
 // Just seperates the event types.
 void input_handle(SDL_Event* event) {
+  // Pause the game if it is unfocused.
+  if(event->type == SDL_ACTIVEEVENT) {
+    if(event->active.state != SDL_APPMOUSEFOCUS) {
+      // We don't need mouse focus.
+      if((event->active.gain == 0) && !paused) pause();
+      else if((event->active.gain == 1) && pause) unpause();
+      return;
+    }
+  }
+
   if(toolkit)
     // Toolkit is handled seperately.
     if(toolkit_input(event))
diff --git a/src/land.c b/src/land.c
index 51ea672..03794aa 100644
--- a/src/land.c
+++ b/src/land.c
@@ -483,12 +483,17 @@ static void shipyard_info(char* str) {
 
 static void shipyard_buy(char* str) {
   (void)str;
-  char* shipname;
+  char* shipname, buf[16];
   Ship* ship;
 
   shipname = toolkit_getList(secondary_wid, "lstShipyard");
   ship = ship_get(shipname);
 
+  credits2str(buf, ship->price, 2);
+  if(toolkit_YesNo("Are you sure?",
+                   "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);
 }
diff --git a/src/lephisto.c b/src/lephisto.c
index ec603fe..e951c87 100644
--- a/src/lephisto.c
+++ b/src/lephisto.c
@@ -54,14 +54,14 @@ int indjoystick = -1;
 char* namjoystick = NULL;
 
 // Prototypes.
-
+void main_loop(void);
 static void display_fps(const double dt);
 static void window_caption(void);
 static void data_name(void);
 // Update.
 static void fps_control(void);
-static void update_space(void);
-static void render_space(void);
+static void update_all(void);
+static void render_all(void);
 
 #ifdef WIN32
 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,
@@ -175,33 +175,9 @@ int main(int argc, char** argv) {
     while(SDL_PollEvent(&event)) {
       if(event.type == SDL_QUIT) quit = 1; // Handle quit.
 
-      // Pause the game if it is unfocused.
-      if(event.type == SDL_ACTIVEEVENT) {
-        if(event.active.state != SDL_APPMOUSEFOCUS) {
-          // We don't need the mouse focus.
-          if((event.active.gain == 0) && !paused) pause();
-          else if((event.active.gain == 1) && paused) unpause();
-        }
-      }
-
       input_handle(&event); // handles all the events the player keybinds.
     }
-
-    sound_update(); // Do the sound stuff.
-
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    fps_control(); // Who doesn't love FPS control?
-    if(toolkit) toolkit_update(); // Simulate key repetition.
-
-    if(!menu_isOpen(MENU_MAIN)) {
-      if(!paused && !toolkit) update_space(); // Update the game.
-      render_space();
-    }
-
-    if(toolkit) toolkit_render();
-
-    SDL_GL_SwapBuffers();
+    main_loop();
   }
 
   // Unload data.
@@ -232,6 +208,23 @@ int main(int argc, char** argv) {
   exit(EXIT_SUCCESS);
 }
 
+// Slip main loop from main() for secondary loop hack in toolkit.c.
+void main_loop(void) {
+  sound_update(); // Do sound stuff.
+
+  glClear(GL_COLOR_BUFFER_BIT);
+
+  fps_control(); // Everyone loves fps control..
+  if(toolkit) toolkit_update(); // To simulate key repetition.
+  if(!menu_isOpen(MENU_MAIN)) {
+    if(!paused && !toolkit) update_all(); // Update game.
+    render_all();
+  }
+  if(toolkit) toolkit_render();
+
+  SDL_GL_SwapBuffers();
+}
+
 // Updates the game.
 static double fps_dt = 1.;
 static double dt = 0.;
@@ -251,7 +244,7 @@ static void fps_control(void) {
 }
 
 // Update the game.
-static void update_space(void) {
+static void update_all(void) {
   if(dt > 1./30.) {
     // Slow timers down and re-run calculations.
     pause_delay((unsigned int)dt*1000.);
@@ -279,7 +272,7 @@ static void update_space(void) {
 //        | Foreground particles.
 //        | Text and GUI.
 // ========================================================
-static void render_space(void) {
+static void render_all(void) {
   // BG.
   space_render(dt);
   planets_render();
diff --git a/src/toolkit.c b/src/toolkit.c
index 4aa30e2..b0a8144 100644
--- a/src/toolkit.c
+++ b/src/toolkit.c
@@ -2,6 +2,7 @@
 #include "log.h"
 #include "pause.h"
 #include "opengl.h"
+#include "input.h"
 #include "toolkit.h"
 
 #define INPUT_DELAY   500
@@ -112,6 +113,9 @@ static glColour* toolkit_colLight = &cGrey90;
 static glColour* toolkit_col   = &cGrey70;
 static glColour* toolkit_colDark = &cGrey30;
 
+// Extern.
+extern void main_loop(void); // lephisto.c
+// Static.
 static Widget* window_newWidget(Window* w);
 static void widget_cleanup(Widget* widget);
 static Window* window_wget(const unsigned int wid);
@@ -142,6 +146,10 @@ static void toolkit_drawRect(double x, double y, double w, double h,
                              glColour* c, glColour* lc);
 // Misc.
 static void toolkit_alertClose(char* str);
+static void toolkit_YesNoClose(char* str);
+// Secondary loop hack.
+static int loop_done;
+static void toolkit_loop(void);
 
 // Add a button that when pressed will trigger call, passing it's name as the
 // only parameter.
@@ -1343,6 +1351,54 @@ static void toolkit_alertClose(char* str) {
     window_destroy(window_get("Warning"));
 }
 
+// Runs a dialogue with a Yes No button, return 1 if yes.
+static int yesno_result;
+static unsigned int yesno_wid = 0;
+int toolkit_YesNo(char* caption, const char* fmt, ...) {
+  char msg[256];
+  va_list ap;
+
+  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);
+  }
+
+  // Create window.
+  yesno_wid = window_create(caption, -1, -1, 300, 140);
+  // Text.
+  window_addText(yesno_wid, 20, -30, 260, 70, 0, "txtAlert",
+                 &gl_smallFont, &cBlack, msg);
+  // Buttons.
+  window_addButton(yesno_wid, 300/2-50-10, 20, 50, 30, "btnYes", "Yes",
+                   toolkit_YesNoClose);
+
+  window_addButton(yesno_wid, 300/2+50+10, 20, 50, 30, "btnNo", "No",
+                   toolkit_YesNoClose);
+
+  // Tricky secondary loop.
+  toolkit_loop();
+
+  // Return the result.
+  return yesno_result;
+}
+
+static void toolkit_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;
+}
+
 // Init.
 int toolkit_init(void) {
   windows = malloc(sizeof(Window)*MIN_WINDOWS);
@@ -1361,3 +1417,24 @@ void toolkit_exit(void) {
   }
 }
 
+// Spawns a secondary loop that only works until the toolkit dies.
+// A lot like the main while loop in lephisto.c.
+static void toolkit_loop(void) {
+  SDL_Event event;
+
+  loop_done = 0;
+  while(!loop_done && toolkit) {
+    while(SDL_PollEvent(&event)) {
+      // Event loopz.
+      if(event.type == SDL_QUIT) {
+        // Pass quit event to main engine.
+        SDL_PushEvent(&event);
+        return;
+      }
+      // Handles all the events and player keybinds.
+      input_handle(&event);
+    }
+    main_loop();
+  }
+}
+
diff --git a/src/toolkit.h b/src/toolkit.h
index 39518f0..e1ba54f 100644
--- a/src/toolkit.h
+++ b/src/toolkit.h
@@ -45,6 +45,7 @@ void window_addInput(const unsigned int wid,
 
 // Popups and alerts.
 void toolkit_alert(const char* fmt, ...);
+int toolkit_YesNo(char* caption, const char* fmt, ...);
 
 // Modification.
 void window_setFptr(const unsigned int wid, void(*fptr)(char*));