From a21deaaa31ae55045243a3459a0af16e1271fb1e Mon Sep 17 00:00:00 2001
From: Kalle Olavi Niemitalo <kon@iki.fi>
Date: Tue, 18 May 2010 00:44:28 +0300
Subject: [PATCH 1/3] Support implicit hot keys for check boxes

The new class CheckBoxWidget wraps gcn::CheckBox and looks for a hot
key in the caption given to the constructor, like ButtonWidget already
did for gcn::Button.  ImageCheckBox still does not automatically get a
hot key.

The Lua code now uses CheckBoxWidget but C++ code doesn't.
---
 engine/guichan/include/guichan/widgets/checkbox.h |    1 +
 engine/guichan/widgets/checkbox.cpp               |    5 +
 engine/include/widgets.h                          |    7 +
 engine/tolua/tolua.cpp                            |  187 ++++++++++++++++++---
 engine/tolua/ui.pkg                               |    6 +
 engine/ui/widgets.cpp                             |   22 +++
 scripts/guichan.lua                               |    2 +-
 7 files changed, 202 insertions(+), 28 deletions(-)

diff --git a/engine/guichan/include/guichan/widgets/checkbox.h b/engine/guichan/include/guichan/widgets/checkbox.h
index d31a3b7..f37068f 100644
--- a/engine/guichan/include/guichan/widgets/checkbox.h
+++ b/engine/guichan/include/guichan/widgets/checkbox.h
@@ -139,6 +139,7 @@ namespace gcn
 
         virtual void drawBorder(Graphics* graphics);
       
+        virtual void hotKeyPress();
 
         // Inherited from KeyListener
 
diff --git a/engine/guichan/widgets/checkbox.cpp b/engine/guichan/widgets/checkbox.cpp
index 024c952..02bf457 100644
--- a/engine/guichan/widgets/checkbox.cpp
+++ b/engine/guichan/widgets/checkbox.cpp
@@ -190,6 +190,11 @@ namespace gcn
         return false;
     }
   
+    void CheckBox::hotKeyPress()
+    {
+        toggle();
+    }
+
     void CheckBox::mouseClick(int x, int y, int button, int count)
     {
         if (button == MouseInput::LEFT)
diff --git a/engine/include/widgets.h b/engine/include/widgets.h
index 95b1855..7b2edc5 100644
--- a/engine/include/widgets.h
+++ b/engine/include/widgets.h
@@ -130,6 +130,13 @@ public:
 	bool mMouseDown;
 };
 
+class CheckBoxWidget : public gcn::CheckBox
+{
+public:
+	CheckBoxWidget();
+	CheckBoxWidget(const std::string &caption, bool marked = false);
+}; 
+
 class ImageCheckBox : public gcn::CheckBox
 {
 public:
diff --git a/engine/tolua/tolua.cpp b/engine/tolua/tolua.cpp
index e1f419d..758bf26 100644
--- a/engine/tolua/tolua.cpp
+++ b/engine/tolua/tolua.cpp
@@ -1,6 +1,6 @@
 /*
 ** Lua binding: stratagus
-** Generated automatically by tolua++-1.0.92 on Tue May  4 23:08:21 2010.
+** Generated automatically by tolua++-1.0.92 on Tue May 18 00:55:23 2010.
 */
 
 #ifndef __cplusplus
@@ -67,9 +67,9 @@ extern std::string CliMapName;
 /* function to release collected object via destructor */
 #ifdef __cplusplus
 
-static int tolua_collect_MenuScreen (lua_State* tolua_S)
+static int tolua_collect_CheckBoxWidget (lua_State* tolua_S)
 {
- MenuScreen* self = (MenuScreen*) tolua_tousertype(tolua_S,1,0);
+ CheckBoxWidget* self = (CheckBoxWidget*) tolua_tousertype(tolua_S,1,0);
 	Mtolua_delete(self);
 	return 0;
 }
@@ -137,9 +137,9 @@ static int tolua_collect_CheckBox (lua_State* tolua_S)
 	return 0;
 }
 
-static int tolua_collect_ImageWidget (lua_State* tolua_S)
+static int tolua_collect_ImageButton (lua_State* tolua_S)
 {
- ImageWidget* self = (ImageWidget*) tolua_tousertype(tolua_S,1,0);
+ ImageButton* self = (ImageButton*) tolua_tousertype(tolua_S,1,0);
 	Mtolua_delete(self);
 	return 0;
 }
@@ -242,6 +242,13 @@ static int tolua_collect_CParticleManager (lua_State* tolua_S)
 	return 0;
 }
 
+static int tolua_collect_MenuScreen (lua_State* tolua_S)
+{
+ MenuScreen* self = (MenuScreen*) tolua_tousertype(tolua_S,1,0);
+	Mtolua_delete(self);
+	return 0;
+}
+
 static int tolua_collect_ImageCheckBox (lua_State* tolua_S)
 {
  ImageCheckBox* self = (ImageCheckBox*) tolua_tousertype(tolua_S,1,0);
@@ -256,9 +263,9 @@ static int tolua_collect_ScrollingWidget (lua_State* tolua_S)
 	return 0;
 }
 
-static int tolua_collect_CNetworkHost (lua_State* tolua_S)
+static int tolua_collect_ImageWidget (lua_State* tolua_S)
 {
- CNetworkHost* self = (CNetworkHost*) tolua_tousertype(tolua_S,1,0);
+ ImageWidget* self = (ImageWidget*) tolua_tousertype(tolua_S,1,0);
 	Mtolua_delete(self);
 	return 0;
 }
@@ -291,9 +298,9 @@ static int tolua_collect_GraphicAnimation (lua_State* tolua_S)
 	return 0;
 }
 
-static int tolua_collect_Label (lua_State* tolua_S)
+static int tolua_collect_CNetworkHost (lua_State* tolua_S)
 {
- Label* self = (Label*) tolua_tousertype(tolua_S,1,0);
+ CNetworkHost* self = (CNetworkHost*) tolua_tousertype(tolua_S,1,0);
 	Mtolua_delete(self);
 	return 0;
 }
@@ -319,9 +326,9 @@ static int tolua_collect_StaticParticle (lua_State* tolua_S)
 	return 0;
 }
 
-static int tolua_collect_ImageButton (lua_State* tolua_S)
+static int tolua_collect_Label (lua_State* tolua_S)
 {
- ImageButton* self = (ImageButton*) tolua_tousertype(tolua_S,1,0);
+ Label* self = (Label*) tolua_tousertype(tolua_S,1,0);
 	Mtolua_delete(self);
 	return 0;
 }
@@ -339,7 +346,7 @@ static int tolua_collect_Slider (lua_State* tolua_S)
 static void tolua_reg_types (lua_State* tolua_S)
 {
  tolua_usertype(tolua_S,"CPlayerColorGraphic");
- tolua_usertype(tolua_S,"MenuScreen");
+ tolua_usertype(tolua_S,"LuaActionListener");
  tolua_usertype(tolua_S,"BasicContainer");
  tolua_usertype(tolua_S,"vector<CUIButton>");
  tolua_usertype(tolua_S,"CFontColor");
@@ -363,7 +370,7 @@ static void tolua_reg_types (lua_State* tolua_S)
  tolua_usertype(tolua_S,"DropDownWidget");
  tolua_usertype(tolua_S,"CPieMenu");
  tolua_usertype(tolua_S,"ScrollArea");
- tolua_usertype(tolua_S,"Button");
+ tolua_usertype(tolua_S,"Windows");
  tolua_usertype(tolua_S,"CInfoPanel");
  tolua_usertype(tolua_S,"Animation");
  tolua_usertype(tolua_S,"ScrollingWidget");
@@ -371,7 +378,7 @@ static void tolua_reg_types (lua_State* tolua_S)
  tolua_usertype(tolua_S,"StatBoxWidget");
  tolua_usertype(tolua_S,"CUITimer");
  tolua_usertype(tolua_S,"Widget");
- tolua_usertype(tolua_S,"Label");
+ tolua_usertype(tolua_S,"CheckBoxWidget");
  tolua_usertype(tolua_S,"Settings");
  tolua_usertype(tolua_S,"CResourceInfo");
  tolua_usertype(tolua_S,"vector<CFiller>");
@@ -379,39 +386,40 @@ static void tolua_reg_types (lua_State* tolua_S)
  tolua_usertype(tolua_S,"CMapInfo");
  tolua_usertype(tolua_S,"TextField");
  tolua_usertype(tolua_S,"CServerSetup");
- tolua_usertype(tolua_S,"CMapArea");
+ tolua_usertype(tolua_S,"MultiLineLabel");
  tolua_usertype(tolua_S,"ImageWidget");
  tolua_usertype(tolua_S,"SettingsPresets");
  tolua_usertype(tolua_S,"gcn::Graphics");
  tolua_usertype(tolua_S,"CStatusLine");
- tolua_usertype(tolua_S,"CMinimap");
+ tolua_usertype(tolua_S,"ListBox");
  tolua_usertype(tolua_S,"CPatchManager");
- tolua_usertype(tolua_S,"Window");
  tolua_usertype(tolua_S,"CParticleManager");
+ tolua_usertype(tolua_S,"Window");
+ tolua_usertype(tolua_S,"CPatchType");
  tolua_usertype(tolua_S,"CPreference");
  tolua_usertype(tolua_S,"CFiller");
- tolua_usertype(tolua_S,"CUserInterface");
+ tolua_usertype(tolua_S,"DropDown");
  tolua_usertype(tolua_S,"vector<string>");
- tolua_usertype(tolua_S,"Windows");
- tolua_usertype(tolua_S,"MultiLineLabel");
+ tolua_usertype(tolua_S,"CMapArea");
+ tolua_usertype(tolua_S,"Label");
  tolua_usertype(tolua_S,"CSmokeParticle");
- tolua_usertype(tolua_S,"CPatchType");
+ tolua_usertype(tolua_S,"MenuScreen");
  tolua_usertype(tolua_S,"Container");
  tolua_usertype(tolua_S,"ButtonWidget");
- tolua_usertype(tolua_S,"CFont");
+ tolua_usertype(tolua_S,"CNetworkHost");
  tolua_usertype(tolua_S,"CVideo");
  tolua_usertype(tolua_S,"ImageCheckBox");
- tolua_usertype(tolua_S,"LuaActionListener");
  tolua_usertype(tolua_S,"ImageRadioButton");
  tolua_usertype(tolua_S,"CEditor");
- tolua_usertype(tolua_S,"ListBox");
+ tolua_usertype(tolua_S,"CUserInterface");
+ tolua_usertype(tolua_S,"CFont");
  tolua_usertype(tolua_S,"CPosition");
  tolua_usertype(tolua_S,"GraphicAnimation");
- tolua_usertype(tolua_S,"CNetworkHost");
- tolua_usertype(tolua_S,"RadioButton");
  tolua_usertype(tolua_S,"CViewport");
+ tolua_usertype(tolua_S,"RadioButton");
+ tolua_usertype(tolua_S,"CMinimap");
  tolua_usertype(tolua_S,"StaticParticle");
- tolua_usertype(tolua_S,"DropDown");
+ tolua_usertype(tolua_S,"Button");
  tolua_usertype(tolua_S,"Slider");
 }
 
@@ -8051,6 +8059,118 @@ static int tolua_stratagus_CheckBox_adjustSize00(lua_State* tolua_S)
 }
 #endif //#ifndef TOLUA_DISABLE
 
+/* method: new of class  CheckBoxWidget */
+#ifndef TOLUA_DISABLE_tolua_stratagus_CheckBoxWidget_new00
+static int tolua_stratagus_CheckBoxWidget_new00(lua_State* tolua_S)
+{
+#ifndef TOLUA_RELEASE
+ tolua_Error tolua_err;
+ if (
+     !tolua_isusertable(tolua_S,1,"CheckBoxWidget",0,&tolua_err) ||
+     !tolua_isnoobj(tolua_S,2,&tolua_err)
+ )
+  goto tolua_lerror;
+ else
+#endif
+ {
+  {
+   CheckBoxWidget* tolua_ret = (CheckBoxWidget*)  Mtolua_new((CheckBoxWidget)());
+    tolua_pushusertype(tolua_S,(void*)tolua_ret,"CheckBoxWidget");
+  }
+ }
+ return 1;
+#ifndef TOLUA_RELEASE
+ tolua_lerror:
+ tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
+ return 0;
+#endif
+}
+#endif //#ifndef TOLUA_DISABLE
+
+/* method: new_local of class  CheckBoxWidget */
+#ifndef TOLUA_DISABLE_tolua_stratagus_CheckBoxWidget_new00_local
+static int tolua_stratagus_CheckBoxWidget_new00_local(lua_State* tolua_S)
+{
+#ifndef TOLUA_RELEASE
+ tolua_Error tolua_err;
+ if (
+     !tolua_isusertable(tolua_S,1,"CheckBoxWidget",0,&tolua_err) ||
+     !tolua_isnoobj(tolua_S,2,&tolua_err)
+ )
+  goto tolua_lerror;
+ else
+#endif
+ {
+  {
+   CheckBoxWidget* tolua_ret = (CheckBoxWidget*)  Mtolua_new((CheckBoxWidget)());
+    tolua_pushusertype(tolua_S,(void*)tolua_ret,"CheckBoxWidget");
+    tolua_register_gc(tolua_S,lua_gettop(tolua_S));
+  }
+ }
+ return 1;
+#ifndef TOLUA_RELEASE
+ tolua_lerror:
+ tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err);
+ return 0;
+#endif
+}
+#endif //#ifndef TOLUA_DISABLE
+
+/* method: new of class  CheckBoxWidget */
+#ifndef TOLUA_DISABLE_tolua_stratagus_CheckBoxWidget_new01
+static int tolua_stratagus_CheckBoxWidget_new01(lua_State* tolua_S)
+{
+ tolua_Error tolua_err;
+ if (
+     !tolua_isusertable(tolua_S,1,"CheckBoxWidget",0,&tolua_err) ||
+     !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
+     !tolua_isboolean(tolua_S,3,1,&tolua_err) ||
+     !tolua_isnoobj(tolua_S,4,&tolua_err)
+ )
+  goto tolua_lerror;
+ else
+ {
+  const std::string caption = ((const std::string)  tolua_tocppstring(tolua_S,2,0));
+  bool marked = ((bool)  tolua_toboolean(tolua_S,3,false));
+  {
+   CheckBoxWidget* tolua_ret = (CheckBoxWidget*)  Mtolua_new((CheckBoxWidget)(caption,marked));
+    tolua_pushusertype(tolua_S,(void*)tolua_ret,"CheckBoxWidget");
+  }
+ }
+ return 1;
+tolua_lerror:
+ return tolua_stratagus_CheckBoxWidget_new00(tolua_S);
+}
+#endif //#ifndef TOLUA_DISABLE
+
+/* method: new_local of class  CheckBoxWidget */
+#ifndef TOLUA_DISABLE_tolua_stratagus_CheckBoxWidget_new01_local
+static int tolua_stratagus_CheckBoxWidget_new01_local(lua_State* tolua_S)
+{
+ tolua_Error tolua_err;
+ if (
+     !tolua_isusertable(tolua_S,1,"CheckBoxWidget",0,&tolua_err) ||
+     !tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
+     !tolua_isboolean(tolua_S,3,1,&tolua_err) ||
+     !tolua_isnoobj(tolua_S,4,&tolua_err)
+ )
+  goto tolua_lerror;
+ else
+ {
+  const std::string caption = ((const std::string)  tolua_tocppstring(tolua_S,2,0));
+  bool marked = ((bool)  tolua_toboolean(tolua_S,3,false));
+  {
+   CheckBoxWidget* tolua_ret = (CheckBoxWidget*)  Mtolua_new((CheckBoxWidget)(caption,marked));
+    tolua_pushusertype(tolua_S,(void*)tolua_ret,"CheckBoxWidget");
+    tolua_register_gc(tolua_S,lua_gettop(tolua_S));
+  }
+ }
+ return 1;
+tolua_lerror:
+ return tolua_stratagus_CheckBoxWidget_new00_local(tolua_S);
+}
+#endif //#ifndef TOLUA_DISABLE
+
 /* method: new of class  ImageCheckBox */
 #ifndef TOLUA_DISABLE_tolua_stratagus_ImageCheckBox_new00
 static int tolua_stratagus_ImageCheckBox_new00(lua_State* tolua_S)
@@ -19917,6 +20037,19 @@ TOLUA_API int tolua_stratagus_open (lua_State* tolua_S)
    tolua_function(tolua_S,"adjustSize",tolua_stratagus_CheckBox_adjustSize00);
   tolua_endmodule(tolua_S);
   #ifdef __cplusplus
+  tolua_cclass(tolua_S,"CheckBoxWidget","CheckBoxWidget","CheckBox",tolua_collect_CheckBoxWidget);
+  #else
+  tolua_cclass(tolua_S,"CheckBoxWidget","CheckBoxWidget","CheckBox",NULL);
+  #endif
+  tolua_beginmodule(tolua_S,"CheckBoxWidget");
+   tolua_function(tolua_S,"new",tolua_stratagus_CheckBoxWidget_new00);
+   tolua_function(tolua_S,"new_local",tolua_stratagus_CheckBoxWidget_new00_local);
+   tolua_function(tolua_S,".call",tolua_stratagus_CheckBoxWidget_new00_local);
+   tolua_function(tolua_S,"new",tolua_stratagus_CheckBoxWidget_new01);
+   tolua_function(tolua_S,"new_local",tolua_stratagus_CheckBoxWidget_new01_local);
+   tolua_function(tolua_S,".call",tolua_stratagus_CheckBoxWidget_new01_local);
+  tolua_endmodule(tolua_S);
+  #ifdef __cplusplus
   tolua_cclass(tolua_S,"ImageCheckBox","ImageCheckBox","CheckBox",tolua_collect_ImageCheckBox);
   #else
   tolua_cclass(tolua_S,"ImageCheckBox","ImageCheckBox","CheckBox",NULL);
diff --git a/engine/tolua/ui.pkg b/engine/tolua/ui.pkg
index d478e17..14e8f5b 100644
--- a/engine/tolua/ui.pkg
+++ b/engine/tolua/ui.pkg
@@ -355,6 +355,12 @@ class CheckBox : public Widget
 	virtual void adjustSize();
 };
 
+class CheckBoxWidget : public CheckBox
+{
+	CheckBoxWidget();
+	CheckBoxWidget(const std::string caption, bool marked = false);
+};
+
 class ImageCheckBox : public CheckBox
 {
 	ImageCheckBox();
diff --git a/engine/ui/widgets.cpp b/engine/ui/widgets.cpp
index 893811e..db1e286 100644
--- a/engine/ui/widgets.cpp
+++ b/engine/ui/widgets.cpp
@@ -534,6 +534,28 @@ void ImageRadioButton::adjustSize()
 
 
 /*----------------------------------------------------------------------------
+--  CheckboxWidget
+----------------------------------------------------------------------------*/
+
+
+/**
+**  Checkbox widget constructor
+*/
+CheckBoxWidget::CheckBoxWidget() : gcn::CheckBox()
+{
+}
+
+/**
+**  Checkbox widget constructor
+*/
+CheckBoxWidget::CheckBoxWidget(const std::string &caption, bool marked) :
+	gcn::CheckBox(caption, marked)
+{
+	this->setHotKey(GetHotKey(caption));
+}
+
+
+/*----------------------------------------------------------------------------
 --  ImageCheckbox
 ----------------------------------------------------------------------------*/
 
diff --git a/scripts/guichan.lua b/scripts/guichan.lua
index 1c5dd34..a59cd6e 100644
--- a/scripts/guichan.lua
+++ b/scripts/guichan.lua
@@ -299,7 +299,7 @@ function AddMenuHelpers(menu)
   end
 
   function menu:addCheckBox(caption, x, y, callback)
-    local b = CheckBox(caption)
+    local b = CheckBoxWidget(caption)
     b:setBaseColor(clear)
     b:setForegroundColor(clear)
     b:setBackgroundColor(dark)
-- 
1.7.1

