From f27577abd719607207ca660198a8c0c37e7ec426 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Wed, 27 Jan 2010 13:19:03 +0000
Subject: [PATCH] moving hotkeys to an interface

git-svn-id: http://svn.net-core.org/repos/t-engine4@283 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/data/keybinds/hotkeys.lua                | 13 +++++++
 game/engine/KeyBind.lua                       | 34 +++++++++++++++++++
 game/engine/dialogs/KeyBinder.lua             | 30 ++--------------
 game/engine/dialogs/ShowInventory.lua         |  4 +--
 game/engine/dialogs/UseTalents.lua            | 14 ++++++--
 game/modules/tome/class/Game.lua              | 12 ++++---
 ...{TalentsDisplay.lua => HotkeysDisplay.lua} |  7 ++--
 game/modules/tome/class/Player.lua            | 26 +++-----------
 8 files changed, 79 insertions(+), 61 deletions(-)
 rename game/modules/tome/class/{TalentsDisplay.lua => HotkeysDisplay.lua} (92%)

diff --git a/game/data/keybinds/hotkeys.lua b/game/data/keybinds/hotkeys.lua
index 501be6b73c..72ca009309 100644
--- a/game/data/keybinds/hotkeys.lua
+++ b/game/data/keybinds/hotkeys.lua
@@ -219,3 +219,16 @@ defineAction{
 	group = "hotkeys",
 	name = "Third Hotkey 12",
 }
+
+defineAction{
+	default = { "sym:280:false:false:false:false" },
+	type = "HOTKEY_PREV_PAGE",
+	group = "hotkeys",
+	name = "Previous Hotkey Page",
+}
+defineAction{
+	default = { "sym:281:false:false:false:false" },
+	type = "HOTKEY_NEXT_PAGE",
+	group = "hotkeys",
+	name = "Next Hotkey Page",
+}
diff --git a/game/engine/KeyBind.lua b/game/engine/KeyBind.lua
index 2b203439a8..fa526ded8f 100644
--- a/game/engine/KeyBind.lua
+++ b/game/engine/KeyBind.lua
@@ -107,10 +107,44 @@ function _M:bindKeys()
 	end
 end
 
+function _M:findBoundKeys(virtual)
+	local bs = {}
+	for ks, virt in pairs(self.binds) do
+		if virt == virtual then bs[#bs+1] = ks end
+	end
+	return unpack(bs)
+end
+
 function _M:makeKeyString(sym, ctrl, shift, alt, meta, unicode)
 	return ("sym:%s:%s:%s:%s:%s"):format(tostring(sym), tostring(ctrl), tostring(shift), tostring(alt), tostring(meta)), unicode and "uni:"..unicode
 end
 
+function _M:formatKeyString(ks)
+	if not ks then return "--" end
+
+	if ks:find("^uni:") then
+		return ks:sub(5)
+	else
+		local i, j, sym, ctrl, shift, alt, meta = ks:find("^sym:([0-9]+):([a-z]+):([a-z]+):([a-z]+):([a-z]+)$")
+		if not i then return "--" end
+
+		ctrl = ctrl == "true" and true or false
+		shift = shift == "true" and true or false
+		alt = alt == "true" and true or false
+		meta = meta == "true" and true or false
+		sym = tonumber(sym) or sym
+		sym = _M.sym_to_name[sym] or sym
+		sym = sym:gsub("^_", "")
+
+		if ctrl then sym = "[ctrl]+"..sym end
+		if shift then sym = "[shift]+"..sym end
+		if alt then sym = "[alt]+"..sym end
+		if meta then sym = "[meta]+"..sym end
+
+		return sym
+	end
+end
+
 function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode)
 	local ks, us = self:makeKeyString(sym, ctrl, shift, alt, meta, unicode)
 --	print("[BIND]", sym, ctrl, shift, alt, meta, unicode, " :=: ", ks, us, " ?=? ", self.binds[ks], us and self.binds[us])
diff --git a/game/engine/dialogs/KeyBinder.lua b/game/engine/dialogs/KeyBinder.lua
index 5dc4016763..852fae82e6 100644
--- a/game/engine/dialogs/KeyBinder.lua
+++ b/game/engine/dialogs/KeyBinder.lua
@@ -78,32 +78,6 @@ function _M:use()
 	game:registerDialog(d)
 end
 
-function _M:formatKeyString(ks)
-	if not ks then return "--" end
-
-	if ks:find("^uni:") then
-		return ks:sub(5)
-	else
-		local i, j, sym, ctrl, shift, alt, meta = ks:find("^sym:([0-9]+):([a-z]+):([a-z]+):([a-z]+):([a-z]+)$")
-		if not i then return "--" end
-
-		ctrl = ctrl == "true" and true or false
-		shift = shift == "true" and true or false
-		alt = alt == "true" and true or false
-		meta = meta == "true" and true or false
-		sym = tonumber(sym) or sym
-		sym = KeyBind.sym_to_name[sym] or sym
-		sym = sym:gsub("^_", "")
-
-		if ctrl then sym = "[ctrl]+"..sym end
-		if shift then sym = "[shift]+"..sym end
-		if alt then sym = "[alt]+"..sym end
-		if meta then sym = "[meta]+"..sym end
-
-		return sym
-	end
-end
-
 function _M:generateList(key_source)
 	local l = {}
 
@@ -131,8 +105,8 @@ function _M:generateList(key_source)
 			type = k.type,
 			bind1 = binds[1],
 			bind2 = binds[2],
-			b1 = function(v) return self:formatKeyString(v.bind1) end,
-			b2 = function(v) return self:formatKeyString(v.bind2) end,
+			b1 = function(v) return KeyBind:formatKeyString(v.bind1) end,
+			b2 = function(v) return KeyBind:formatKeyString(v.bind2) end,
 		}
 		i = i + 1
 	end
diff --git a/game/engine/dialogs/ShowInventory.lua b/game/engine/dialogs/ShowInventory.lua
index d743092897..a07e6cd454 100644
--- a/game/engine/dialogs/ShowInventory.lua
+++ b/game/engine/dialogs/ShowInventory.lua
@@ -77,7 +77,7 @@ function _M:init(title, inven, filter, action, actor)
 end
 
 function _M:defineHotkey(id)
-	if not self.actor then return end
+	if not self.actor or not self.actor.hotkey then return end
 
 	self.actor.hotkey[id] = {"inventory", self.list[self.sel].object:getName()}
 	self:simplePopup("Hotkey "..id.." assigned", self.list[self.sel].object:getName():capitalize().." assigned to hotkey "..id)
@@ -111,7 +111,7 @@ function _M:drawDialog(s)
 	self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
 
 	local help
-	if self.actor then
+	if self.actor and self.actor.hotkey then
 		help = [[Keyboard: #00FF00#up key/down key#FFFFFF# to select an object; #00FF00#enter#FFFFFF# to use. #00FF00#1-0#FFFFFF# to assign a hotkey.
 Mouse: #00FF00#Left click#FFFFFF# to use.
 ]]
diff --git a/game/engine/dialogs/UseTalents.lua b/game/engine/dialogs/UseTalents.lua
index 4af3f18b20..b15f0a3516 100644
--- a/game/engine/dialogs/UseTalents.lua
+++ b/game/engine/dialogs/UseTalents.lua
@@ -75,6 +75,8 @@ function _M:init(actor)
 end
 
 function _M:defineHotkey(id)
+	if not self.actor.hotkey then return end
+
 	self.actor.hotkey[id] = {"talent", self.list[self.sel].talent}
 	self:simplePopup("Hotkey "..id.." assigned", self.actor:getTalentFromId(self.list[self.sel].talent).name:capitalize().." assigned to hotkey "..id)
 	self.actor.changed = true
@@ -110,10 +112,18 @@ function _M:drawDialog(s)
 	-- Description part
 	self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
 
-	local talentshelp = ([[Keyboard: #00FF00#up key/down key#FFFFFF# to select a stat; #00FF00#enter#FFFFFF# to use.
+	local help
+	if not self.actor.hotkey then
+		help = [[Keyboard: #00FF00#up key/down key#FFFFFF# to select a stat; #00FF00#enter#FFFFFF# to use.
+Mouse: #00FF00#Left click#FFFFFF# to use.
+]]
+	else
+		help = [[Keyboard: #00FF00#up key/down key#FFFFFF# to select a stat; #00FF00#enter#FFFFFF# to use.
 #00FF00#1-0#FFFFFF# to assign a hotkey.
 Mouse: #00FF00#Left click#FFFFFF# to use.
-]]):splitLines(self.iw / 2 - 10, self.font)
+]]
+	end
+	local talentshelp = help:splitLines(self.iw / 2 - 10, self.font)
 
 	local lines = {}
 	local t = self.actor:getTalentFromId(self.list[self.sel].talent)
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 45430f666b..68f08ec56f 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -19,7 +19,7 @@ local Player = require "mod.class.Player"
 local NPC = require "mod.class.NPC"
 
 local PlayerDisplay = require "mod.class.PlayerDisplay"
-local TalentsDisplay = require "mod.class.TalentsDisplay"
+local HotkeysDisplay = require "mod.class.HotkeysDisplay"
 
 local LogDisplay = require "engine.LogDisplay"
 local LogFlasher = require "engine.LogFlasher"
@@ -47,7 +47,7 @@ function _M:run()
 	self.flash = LogFlasher.new(0, 0, self.w, 20, nil, nil, nil, {255,255,255}, {0,0,0})
 	self.logdisplay = LogDisplay.new(0, self.h * 0.8, self.w * 0.5, self.h * 0.2, nil, nil, nil, {255,255,255}, {30,30,30})
 	self.player_display = PlayerDisplay.new(0, 20, 200, self.h * 0.8 - 20, {30,30,0})
-	self.talents_display = TalentsDisplay.new(self.w * 0.5, self.h * 0.8, self.w * 0.5, self.h * 0.2, {30,30,0})
+	self.hotkeys_display = HotkeysDisplay.new(nil, self.w * 0.5, self.h * 0.8, self.w * 0.5, self.h * 0.2, {30,30,0})
 	self.calendar = Calendar.new("/data/calendar_rivendell.lua", "Today is the %s %s of the %s year of the Fourth Age of Middle-earth.\nThe time is %02d:%02d.", 122)
 	self.tooltip = Tooltip.new(nil, nil, {255,255,255}, {30,30,30})
 	self.flyers = FlyingText.new()
@@ -66,6 +66,8 @@ function _M:run()
 	-- Starting from here we create a new game
 	if not self.player then self:newGame() end
 
+	self.hotkeys_display.actor = self.player
+
 	self.target = Target.new(Map, self.player)
 	self.target.target.entity = self.player
 	self.old_tmx, self.old_tmy = 0, 0
@@ -108,7 +110,7 @@ function _M:onResolutionChange()
 	self.flash:resize(0, 0, self.w, 20)
 	self.logdisplay:resize(0, self.h * 0.8, self.w * 0.5, self.h * 0.2)
 	self.player_display:resize(0, 20, 200, self.h * 0.8 - 20)
-	self.talents_display:resize(self.w * 0.5, self.h * 0.8, self.w * 0.5, self.h * 0.2)
+	self.hotkeys_display:resize(self.w * 0.5, self.h * 0.8, self.w * 0.5, self.h * 0.2)
 end
 
 function _M:setupDisplayMode()
@@ -199,7 +201,7 @@ function _M:display()
 	self.flash:display():toScreen(self.flash.display_x, self.flash.display_y)
 	self.logdisplay:display():toScreen(self.logdisplay.display_x, self.logdisplay.display_y)
 	self.player_display:display():toScreen(self.player_display.display_x, self.player_display.display_y)
-	self.talents_display:display():toScreen(self.talents_display.display_x, self.talents_display.display_y)
+	self.hotkeys_display:display():toScreen(self.hotkeys_display.display_x, self.hotkeys_display.display_y)
 
 	-- Now the map, if any
 	if self.level and self.level.map then
@@ -402,6 +404,8 @@ function _M:setupCommands()
 		HOTKEY_THIRD_10 = function() self.player:activateHotkey(34) end,
 		HOTKEY_THIRD_11 = function() self.player:activateHotkey(35) end,
 		HOTKEY_THIRD_12 = function() self.player:activateHotkey(36) end,
+		HOTKEY_PREV_PAGE = function() self.player:prevHotkeyPage() end,
+		HOTKEY_NEXT_PAGE = function() self.player:nextHotkeyPage() end,
 
 		-- Actions
 		CHANGE_LEVEL = function()
diff --git a/game/modules/tome/class/TalentsDisplay.lua b/game/modules/tome/class/HotkeysDisplay.lua
similarity index 92%
rename from game/modules/tome/class/TalentsDisplay.lua
rename to game/modules/tome/class/HotkeysDisplay.lua
index 67d02724ad..c5841d9c03 100644
--- a/game/modules/tome/class/TalentsDisplay.lua
+++ b/game/modules/tome/class/HotkeysDisplay.lua
@@ -15,7 +15,7 @@ function _M:resize(x, y, w, h)
 	self.display_x, self.display_y = x, y
 	self.w, self.h = w, h
 	self.surface = core.display.newSurface(w, h)
-	self.actor.changed = true
+	if self.actor then self.actor.changed = true end
 
 	local cw, ch = self.font:size(" ")
 	self.font_w = cw
@@ -24,11 +24,10 @@ end
 
 local page_to_hotkey = {"", "SECOND_", "THIRD_"}
 
--- Displays the talents, keybinds & cooldowns
--- This could use some optimisation, to not redraw everything every time
+-- Displays the hotkeys, keybinds & cooldowns
 function _M:display()
 	local a = self.actor
-	if not a.changed then return self.surface end
+	if not a or not a.changed then return self.surface end
 	a.changed = false
 
 	local hks = {}
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index 2e9a4cabc4..7cb76f7b85 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -2,6 +2,7 @@ require "engine.class"
 require "mod.class.Actor"
 require "engine.interface.PlayerRest"
 require "engine.interface.PlayerRun"
+require "engine.interface.PlayerHotkeys"
 local Savefile = require "engine.Savefile"
 local Map = require "engine.Map"
 local Dialog = require "engine.Dialog"
@@ -9,11 +10,12 @@ local ActorTalents = require "engine.interface.ActorTalents"
 
 --- Defines the player for ToME
 -- It is a normal actor, with some redefined methods to handle user interaction.<br/>
--- It is also able to run and rest.
+-- It is also able to run and rest and use hotkeys
 module(..., package.seeall, class.inherit(
 	mod.class.Actor,
 	engine.interface.PlayerRest,
-	engine.interface.PlayerRun
+	engine.interface.PlayerRun,
+	engine.interface.PlayerHotkeys
 ))
 
 function _M:init(t, no_default)
@@ -31,6 +33,7 @@ function _M:init(t, no_default)
 		TOOL = 1,
 	}
 	mod.class.Actor.init(self, t, no_default)
+	engine.interface.PlayerHotkeys.init(self, t)
 	self.player = true
 	self.type = "humanoid"
 	self.subtype = "player"
@@ -54,7 +57,6 @@ function _M:init(t, no_default)
 	self.lite = 0
 
 	self.descriptor = {}
-	self.hotkey = {}
 end
 
 function _M:move(x, y, force)
@@ -193,24 +195,6 @@ function _M:runCheck()
 	return engine.interface.PlayerRun.runCheck(self)
 end
 
---- Uses an hotkeyed talent
-function _M:activateHotkey(id)
-	if self.hotkey[id] then
-		if self.hotkey[id][1] == "talent" then
-			self:useTalent(self.hotkey[id][2])
-		elseif self.hotkey[id][1] == "inventory" then
-			local o, item = self:findInInventory(self:getInven("INVEN"), self.hotkey[id][2])
-			if not o then
-				Dialog:simplePopup("Item not found", "You do not have any "..self.hotkey[id][2]..".")
-			else
-				self:playerUseItem(o, item)
-			end
-		end
-	else
-		Dialog:simplePopup("Hotkey not defined", "You may define a hotkey by pressing 'm' and following the inscructions there.")
-	end
-end
-
 function _M:playerPickup()
 	-- If 2 or more objects, display a pickup dialog, otehrwise just picks up
 	if game.level.map:getObject(self.x, self.y, 2) then
-- 
GitLab