From f5f28ea5cf0b9ba2eb32f11b5e04f3d48f28647f Mon Sep 17 00:00:00 2001
From: cybermind <iddqd_mail@mail.ru>
Date: Sun, 3 Mar 2013 21:23:19 +0600
Subject: [PATCH] [+] Ability to call some ui functions from lua [+] Ability to
 scroll through idle workers list [-] Fixed ButtonButton handling in pie menu
 [-] Fixed UserButtons not clearing

---
 src/include/interface.h |  7 +++++++
 src/tolua/ui.pkg        |  6 ++++++
 src/ui/interface.cpp    | 17 ++++++++++++++---
 src/ui/mouse.cpp        |  3 ++-
 src/ui/ui.cpp           |  1 +
 5 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/src/include/interface.h b/src/include/interface.h
index cf5b91cfd..f8840e58d 100644
--- a/src/include/interface.h
+++ b/src/include/interface.h
@@ -329,6 +329,13 @@ extern void SetHoldClickDelay(int delay);
 extern void UiTogglePause();
 /// Toggle big map
 extern void UiToggleBigMap();
+/// Toggle terrain display on/off.
+extern void UiToggleTerrain();
+/// Find the next idle worker
+extern void UiFindIdleWorker();
+/// Track unit, the viewport follows the unit.
+extern void UiTrackUnit();
+
 /// Handle cheats
 extern int HandleCheats(const std::string &input);
 
diff --git a/src/tolua/ui.pkg b/src/tolua/ui.pkg
index cbbc06c00..2af30b73f 100644
--- a/src/tolua/ui.pkg
+++ b/src/tolua/ui.pkg
@@ -572,3 +572,9 @@ function MenuScreen()
 end
 $]
 
+void CenterOnMessage();
+void ToggleShowMessages();
+void UiFindIdleWorker();
+void CycleViewportMode(int step);
+void UiToggleTerrain();
+void UiTrackUnit();
\ No newline at end of file
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
index 4e023ae62..2a0bd2fa4 100644
--- a/src/ui/interface.cpp
+++ b/src/ui/interface.cpp
@@ -87,6 +87,7 @@ char BigMapMode;                     /// Show only the map
 enum _iface_state_ InterfaceState;   /// Current interface state
 bool GodMode;                        /// Invincibility cheat
 enum _key_state_ KeyState;           /// current key state
+CUnit *LastIdleWorker;               /// Last called idle worker
 
 /*----------------------------------------------------------------------------
 --  Functions
@@ -425,7 +426,7 @@ static void UiRecallMapPosition(unsigned position)
 /**
 **  Toggle terrain display on/off.
 */
-static void UiToggleTerrain()
+void UiToggleTerrain()
 {
 	UI.Minimap.WithTerrain ^= 1;
 	if (UI.Minimap.WithTerrain) {
@@ -438,14 +439,24 @@ static void UiToggleTerrain()
 /**
 **  Find the next idle worker, select it, and center on it
 */
-static void UiFindIdleWorker()
+void UiFindIdleWorker()
 {
 	if (ThisPlayer->FreeWorkers.empty()) {
 		return;
 	}
 	CUnit *unit = ThisPlayer->FreeWorkers[0];
+	if (LastIdleWorker) {
+		std::vector<CUnit *>::const_iterator it = std::find(ThisPlayer->FreeWorkers.begin(),
+			ThisPlayer->FreeWorkers.end(), LastIdleWorker);
+		if (it != ThisPlayer->FreeWorkers.end()) {
+			if (*it != ThisPlayer->FreeWorkers.back()) {
+				unit = *(++it);
+			}	
+		}
+	}
 
 	if (unit != NULL) {
+		LastIdleWorker = unit;
 		SelectSingleUnit(*unit);
 		UI.StatusLine.Clear();
 		ClearCosts();
@@ -469,7 +480,7 @@ static void UiToggleGrabMouse()
 /**
 **  Track unit, the viewport follows the unit.
 */
-static void UiTrackUnit()
+void UiTrackUnit()
 {
 	//Check if player has selected at least 1 unit
 	if (!Selected[0]) {
diff --git a/src/ui/mouse.cpp b/src/ui/mouse.cpp
index f50f65c42..a6ea7bf91 100644
--- a/src/ui/mouse.cpp
+++ b/src/ui/mouse.cpp
@@ -2135,8 +2135,9 @@ static void HandlePieMenuMouseSelection()
 
 	int pie = GetPieUnderCursor();
 	if (pie != -1) {
+		const ButtonCmd action = CurrentButtons[pie].Action;
 		UI.ButtonPanel.DoClicked(pie);
-		if (CurrentButtons[pie].Action == ButtonButton) {
+		if (action == ButtonButton) {
 			// there is a submenu => stay in piemenu mode
 			// and recenter the piemenu around the cursor
 			CursorStartScreenPos = CursorScreenPos;
diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp
index d5ec5d1b4..900f07127 100644
--- a/src/ui/ui.cpp
+++ b/src/ui/ui.cpp
@@ -336,6 +336,7 @@ void CleanUserInterface()
 	delete UI.UpgradingButton;
 	delete UI.ResearchingButton;
 	UI.TransportingButtons.clear();
+	UI.UserButtons.clear();
 
 	// Button Panel
 	CGraphic::Free(UI.ButtonPanel.G);