From 820c477d7b112bccc6f50ccb719ef7d88ed9bf66 Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Wed, 6 Mar 2013 20:37:58 +0000
Subject: [PATCH] [Add] Clicky focus for lists as well as keyboard input.

---
 src/land.c    |  2 +-
 src/toolkit.c | 21 +++++++++++++++++++--
 src/toolkit.h |  3 ++-
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/land.c b/src/land.c
index 64e2298..9da3b92 100644
--- a/src/land.c
+++ b/src/land.c
@@ -58,7 +58,7 @@ static void commodity_exchange(void) {
         "Close", commodity_exchange_close);
 	
 	window_addList(secondary_wid, 20, -40, COMMODITY_WIDTH-30, COMMODITY_HEIGHT-80-BUTTON_HEIGHT,
-				"lstGoods", goods, ngoods, 0);
+				"lstGoods", goods, ngoods, 0, NULL);
 }
 
 static void commodity_exchange_close(char* str) {
diff --git a/src/toolkit.c b/src/toolkit.c
index 89fae18..6a15bda 100644
--- a/src/toolkit.c
+++ b/src/toolkit.c
@@ -33,7 +33,7 @@ typedef struct Widget_ {
   union {
     // Widget button.
     struct {
-      void(*fptr) (char*); // Callback.
+      void(*fptr) (char*); // Active callback.
       char* display; // Stored text.
     } btn;
     // Widget text.
@@ -53,6 +53,7 @@ typedef struct Widget_ {
       int noptions;   // total number of options.
       int selected;   // Currently selected option.
 			int pos;				// Current topmost option (in view).
+			void (*fptr) (char*); // Modify callback.
     } lst;
   } dat;
 } Widget;
@@ -87,10 +88,12 @@ static Widget* window_getwgt(const unsigned int wid, char* name);
 // Input.
 static void toolkit_mouseEvent(SDL_Event* event);
 static int toolkit_keyEvent(SDL_Event* event);
+// Focus.
 static void toolkit_nextFocus(void);
 static void toolkit_triggerFocus(void);
 static Widget* toolkit_getFocus(void);
 static void toolkit_listScroll(Widget* wgt, int direction);
+static void toolkit_listFocus(Widget* lst, double bx, double by);
 // Render.
 static void window_render(Window* w);
 static void toolkit_renderButton(Widget* btn, double bx, double by);
@@ -171,7 +174,8 @@ void window_addImage(const unsigned int wid, const int x, const int y,
 }
 
 void window_addList(const unsigned int wid, const int x, const int y,
-      const int w, const int h, char* name, char** items, int nitems, int defitem) {
+      const int w, const int h, char* name, char** items, int nitems, int defitem,
+			void(*call) (char*)) {
 
   Window *wdw = window_wget(wid);
   Widget* wgt = window_newWidget(wdw);
@@ -183,6 +187,7 @@ void window_addList(const unsigned int wid, const int x, const int y,
   wgt->dat.lst.noptions = nitems;
   wgt->dat.lst.selected = defitem; // -1 would be none.
 	wgt->dat.lst.pos = 0;
+	wgt->dat.lst.fptr = call;
   wgt->w = (double) w;
   wgt->h = (double) h - ((h % (gl_defFont.h+2)) + 2);
   if(x < 0) wgt->x = wdw->w - wgt->w + x;
@@ -787,6 +792,10 @@ static void toolkit_mouseEvent(SDL_Event* event) {
         case SDL_MOUSEBUTTONDOWN:
           wgt->status = WIDGET_STATUS_MOUSEDOWN;
           w->focus = i;
+
+					if(wgt->type == WIDGET_LIST)
+						toolkit_listFocus(wgt, x-wgt->x, y-wgt->y);
+
 					break;
         case SDL_MOUSEBUTTONUP:
           if(wgt->status == WIDGET_STATUS_MOUSEDOWN) {
@@ -926,12 +935,20 @@ static void toolkit_listScroll(Widget* wgt, int direction) {
 			wgt->dat.lst.selected -= direction;
 			wgt->dat.lst.selected = MAX(0, wgt->dat.lst.selected);
 			wgt->dat.lst.selected = MIN(wgt->dat.lst.selected, wgt->dat.lst.noptions-1);
+			if(wgt->dat.lst.fptr) (*wgt->dat.lst.fptr)(wgt->name);
 			break;
 		default:
 			break;
 	}
 }
 
+// List mouse even focus.
+static void toolkit_listFocus(Widget* lst, double bx, double by) {
+	(void)bx;
+	lst->dat.lst.selected = (lst->h - by) / (gl_defFont.h+2.);
+	toolkit_listScroll(lst, 0); // Check boundaries and trigger callback.
+}
+
 // Return the focused widget.
 static Widget* toolkit_getFocus(void) {
 	Window* wdw;
diff --git a/src/toolkit.h b/src/toolkit.h
index cde25b9..dfc06b9 100644
--- a/src/toolkit.h
+++ b/src/toolkit.h
@@ -22,7 +22,8 @@ void window_addImage(const unsigned int wid, const int x, const int y,
 void window_addList(const unsigned int wid,
 			const int x, const int y, // Position.
 			const int w, const int h, // Size.
-			char* name, char** items, int nitems, int defitem);
+			char* name, char** items, int nitems, int defitem,
+			void(*call)(char*));
 
 // Modification
 void window_modifyText(const unsigned int wid, char* name, char* newstring);