From 4f8b6f3691d583d7ad2a22847e3853335aac943c Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Sun, 19 Aug 2012 11:38:32 +0000
Subject: [PATCH] Sane keyboard navigtion in the levelup screen

git-svn-id: http://svn.net-core.org/repos/t-engine4@5514 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engines/default/engine/ui/Button.lua     |  3 +-
 game/engines/default/engine/ui/Textzone.lua   |  2 +-
 .../default/engine/ui/TextzoneList.lua        |  8 +-
 game/modules/tome/dialogs/LevelupDialog.lua   | 19 ++--
 .../tome/dialogs/elements/TalentTrees.lua     | 91 +++++++++++++------
 5 files changed, 80 insertions(+), 43 deletions(-)

diff --git a/game/engines/default/engine/ui/Button.lua b/game/engines/default/engine/ui/Button.lua
index e3998c9bcb..372e6b3cde 100644
--- a/game/engines/default/engine/ui/Button.lua
+++ b/game/engines/default/engine/ui/Button.lua
@@ -33,7 +33,8 @@ function _M:init(t)
 	self.text = assert(t.text, "no button text")
 	self.fct = assert(t.fct, "no button fct")
 	self.force_w = t.width
-
+	if t.can_focus ~= nil then self.can_focus = t.can_focus end
+	
 	Base.init(self, t)
 end
 
diff --git a/game/engines/default/engine/ui/Textzone.lua b/game/engines/default/engine/ui/Textzone.lua
index ac8911c6c5..2c030141f3 100644
--- a/game/engines/default/engine/ui/Textzone.lua
+++ b/game/engines/default/engine/ui/Textzone.lua
@@ -40,7 +40,7 @@ function _M:init(t)
 	self.dest_area = t.dest_area and t.dest_area or { h = self.h }
 	
 	self.color = t.color or {r=255, g=255, b=255}
-	self.can_focus = false
+	if t.can_focus ~= nil then self.can_focus = t.can_focus end
 	self.scroll_inertia = 0
 
 	Base.init(self, t)
diff --git a/game/engines/default/engine/ui/TextzoneList.lua b/game/engines/default/engine/ui/TextzoneList.lua
index 146ad22346..1f79aacc80 100644
--- a/game/engines/default/engine/ui/TextzoneList.lua
+++ b/game/engines/default/engine/ui/TextzoneList.lua
@@ -33,13 +33,14 @@ function _M:init(t)
 	self.w = assert(t.width, "no list width")
 	self.h = assert(t.height, "no list height")
 	self.scrollbar = t.scrollbar
+	self.focus_check = t.focus_check
 	self.variable_height = t.variable_height
 	
 	self.dest_area = t.dest_area and t.dest_area or { h = self.h }
 	self.max_h = 0
 	self.scroll_inertia = 0
 	
-	if self.scrollbar then self.can_focus = true end
+	if t.can_focus ~= nil then self.can_focus = t.can_focus end
 
 	Base.init(self, t)
 
@@ -145,6 +146,11 @@ function _M:switchItem(item, create_if_needed, force)
 		self.scrollbar.max = self.max_h - self.h
 		self.scrollbar.pos = 0
 	end
+	if self.focus_check and self.max_h > self.h then
+		self.can_focus = true
+	else
+		self.can_focus = false
+	end
 	self.list = d.list
 	self.max_display = d.max_display
 	self.cur_item = item
diff --git a/game/modules/tome/dialogs/LevelupDialog.lua b/game/modules/tome/dialogs/LevelupDialog.lua
index 06b6ea6168..a0f56cb7b3 100644
--- a/game/modules/tome/dialogs/LevelupDialog.lua
+++ b/game/modules/tome/dialogs/LevelupDialog.lua
@@ -615,19 +615,14 @@ function _M:createDisplay()
 		no_tooltip = self.no_tooltip,
 	}
 
-	self.c_points = Textzone.new{
-		width=200, height=1, auto_height=true,
-		text=_points_left:format(self.actor.unused_stats, self.actor.unused_talents_types, self.actor.unused_talents, self.actor.unused_generics)
-	}
-
 	local vsep1 = Separator.new{dir="horizontal", size=self.ih - 20}
 	local vsep2 = Separator.new{dir="horizontal", size=self.ih - 20}
 	local hsep = Separator.new{dir="vertical", size=180}
 
-	self.b_stat = Button.new{text="Stats: "..self.actor.unused_stats, fct=function() end}
-	self.b_class = Button.new{text="Class points: "..self.actor.unused_talents, fct=function() end}
-	self.b_generic = Button.new{text="Generic points: "..self.actor.unused_generics, fct=function() end}
-	self.b_types = Button.new{text="Category points: "..self.actor.unused_talents_types, fct=function() end}
+	self.b_stat = Button.new{can_focus = false, text="Stats: "..self.actor.unused_stats, fct=function() end}
+	self.b_class = Button.new{can_focus = false, text="Class points: "..self.actor.unused_talents, fct=function() end}
+	self.b_generic = Button.new{can_focus = false, text="Generic points: "..self.actor.unused_generics, fct=function() end}
+	self.b_types = Button.new{can_focus = false, text="Category points: "..self.actor.unused_talents_types, fct=function() end}
 
 	local ret = {
 		{left=-10, top=0, ui=self.b_stat},
@@ -636,19 +631,19 @@ function _M:createDisplay()
 		{left=self.c_stat, top=40, ui=vsep1},
 
 		{left=vsep1, top=0, ui=self.b_class},
-		{left=vsep1, top=self.b_class, ui=self.c_ctree},
+		{left=vsep1, top=self.b_class.h + 10, ui=self.c_ctree},
 
 		{left=self.c_ctree, top=40, ui=vsep2},
 
 		{left=580, top=0, ui=self.b_generic},
-		{left=vsep2, top=self.b_generic, ui=self.c_gtree},
+		{left=vsep2, top=self.b_generic.h + 10, ui=self.c_gtree},
 
 		{left=330, top=0, ui=self.b_types},
 	}
 
 	if self.no_tooltip then
 		local vsep3 = Separator.new{dir="horizontal", size=self.ih - 20}
-        self.c_desc = TextzoneList.new{ width=self.iw - 200 - 530 - 40, height = self.ih, dest_area = { h = self.ih } }
+        self.c_desc = TextzoneList.new{ focus_check = true, scrollbar = true, width=self.iw - 200 - 530 - 40, height = self.ih, dest_area = { h = self.ih } }
 		ret[#ret+1] = {right=0, top=0, ui=self.c_desc}
 		ret[#ret+1] = {right=self.c_desc.w, top=0, ui=vsep3}
 	end
diff --git a/game/modules/tome/dialogs/elements/TalentTrees.lua b/game/modules/tome/dialogs/elements/TalentTrees.lua
index aa69df5452..4c0f5a494d 100644
--- a/game/modules/tome/dialogs/elements/TalentTrees.lua
+++ b/game/modules/tome/dialogs/elements/TalentTrees.lua
@@ -79,14 +79,14 @@ function _M:generate()
 	for i = 1, #self.tree do
 		local tree = self.tree[i]
 		local key = tree.text_status
-		local current_h = key and key.h or 0
-		if tree.shown then current_h = current_h + self.frame_size + (key and key.h or 0) + 16 end
+		local current_h = (key and key.h or 0) + 2
+		if tree.shown then current_h = current_h + self.frame_size + self.fh + 14 end
 		self.max_h = self.max_h + current_h
 		tree.h = current_h
 	end
 	
 	-- generate the scrollbar
-	if self.scrollbar then self.scrollbar.max = self.max_h - self.h + 2 end
+	if self.scrollbar then self.scrollbar.max = self.max_h - self.h end
 
 	-- Add UI controls
 	self.mouse:registerZone(0, 0, self.w, self.h, function(button, x, y, xrel, yrel, bx, by, event)
@@ -165,41 +165,44 @@ function _M:updateTooltip()
 end
 
 function _M:moveSel(i, j)
-	local match = nil
-
 	if i == 0 then
 		local t = self.tree[self.sel_i]
 		if t.nodes then
 			self.sel_j = util.bound(self.sel_j + j, 1, #t.nodes)
-			match = t.nodes[self.sel_j]
 		end
-	elseif i == 1 then
-		local t = self.tree[self.sel_i]
-		if t.shown and self.sel_j == 0 and t.nodes and #t.nodes > 0 then
-			self.sel_j = 1
-			match = t.nodes[1]
-		else
-			self.sel_i = util.bound(self.sel_i + i, 1, #self.tree)
-			self.sel_j = 0
-			local t = self.tree[self.sel_i]
-			match = t
-		end
-	elseif i == -1 then
-		local t = self.tree[self.sel_i]
-		if t.shown and self.sel_j > 0 and t.nodes and #t.nodes > 0 then
-			self.sel_j = 0
-			match = t
-		else
-			self.sel_i = util.bound(self.sel_i + i, 1, #self.tree)
+	elseif i == 1 then -- down
+		repeat
 			local t = self.tree[self.sel_i]
-			if t.shown and t.nodes and #t.nodes > 0 then
+			if t.shown and self.sel_j == 0 and t.nodes and #t.nodes > 0 then
 				self.sel_j = 1
-				match = t.nodes[1]
+				break
 			else
+				self.sel_i = util.bound(self.sel_i + 1, 1, #self.tree)
 				self.sel_j = 0
-				match = t
+				if self.tree[self.sel_i].text_status then
+					break
+				end
 			end
-		end
+		until self.sel_i > #self.tree
+	elseif i == -1 then -- up
+		repeat
+			local t = self.tree[self.sel_i]
+			if t.shown and self.sel_j > 0 and t.nodes and #t.nodes > 0 then
+				self.sel_j = 0
+			else
+				self.sel_i = util.bound(self.sel_i - 1, 1, #self.tree)
+				local t = self.tree[self.sel_i]
+				if t.shown and t.nodes and #t.nodes > 0 then
+					self.sel_j = 1
+					break
+				else
+					self.sel_j = 0
+				end
+			end
+			if self.tree[self.sel_i].text_status then
+				break
+			end
+		until self.sel_i < 1
 	end
 
 	if self.scrollbar and self.last_input_was_keyboard then
@@ -259,6 +262,33 @@ function _M:redrawAllItems()
 	end
 end
 
+function _M:on_focus_change(status)
+	self.last_input_was_keyboard = true
+	if status then
+		self.prev_item = nil
+		self.focus_decay = focus_decay_max * 32
+		if not self.last_mz then
+			for i = 1, #self.tree do
+				local tree = self.tree[i]
+				if tree.text_status then
+					self.sel_i = i
+					self.sel_j = 0
+					self:moveSel(0, 0)
+					break
+				end
+				if tree.shown then
+					for j = 1, #tree.nodes do
+						self.sel_i = i
+						self.sel_j = j
+						self:moveSel(0, 0)
+						break
+					end
+				end
+			end
+		end
+	end
+end
+
 function _M:on_select(item, force)
 	if self.prev_item == item and not force then return end
 	local str, fx, fy = self.tooltip(item)
@@ -277,6 +307,11 @@ function _M:display(x, y, nb_keyframes, screen_x, screen_y, offset_x, offset_y,
 	self.last_display_x = screen_x
 	self.last_display_y = screen_y
 
+	if self.focus_decay then
+		core.display.drawQuad(x, y, self.w, self.h, 255, 255, 255, self.focus_decay * self.one_by_focus_decay)
+		self.focus_decay = self.focus_decay - nb_keyframes * 64
+		if self.focus_decay <= 0 then self.focus_decay = nil end
+	end
 	local tmp_inertia = 0 -- used to correct selection frame position
 
 	-- apply inertia to scrollbar
-- 
GitLab