Skip to content
Snippets Groups Projects
Commit bf1b0969 authored by DarkGod's avatar DarkGod
Browse files

Long chat dialogs will scroll

parent 44e6f98b
No related branches found
No related tags found
No related merge requests found
......@@ -43,7 +43,7 @@ function _M:init(chat, id)
self:generateList()
self.c_desc = Textzone.new{width=self.iw - 10 - xoff, height=1, auto_height=true, text=self.text.."\n"}
self.c_list = VariableList.new{width=self.iw - 10 - xoff, list=self.list, fct=function(item) self:use(item) end, select=function(item) self:select(item) end}
self.c_list = VariableList.new{width=self.iw - 10 - xoff, max_height=game.h * 0.70 - self.c_desc.h, list=self.list, fct=function(item) self:use(item) end, select=function(item) self:select(item) end}
local uis = {
{left=0, top=0, ui=self.c_desc},
......
......@@ -20,6 +20,7 @@
require "engine.class"
local Base = require "engine.ui.Base"
local Focusable = require "engine.ui.Focusable"
local Slider = require "engine.ui.Slider"
--- A generic UI list
module(..., package.seeall, class.inherit(Base, Focusable))
......@@ -27,8 +28,11 @@ module(..., package.seeall, class.inherit(Base, Focusable))
function _M:init(t)
self.list = assert(t.list, "no list list")
self.w = assert(t.width, "no list width")
self.max_h = t.max_height
self.fct = t.fct
self.select = t.select
self.scrollbar = t.scrollbar
self.min_items_shown = t.min_items_shown or 3
self.display_prop = t.display_prop or "name"
Base.init(self, t)
......@@ -39,6 +43,7 @@ function _M:generate()
self.key:reset()
self.sel = 1
self.scroll = 1
self.max = #self.list
local fw, fh = self.w, self.font_h
......@@ -49,7 +54,8 @@ function _M:generate()
self.frame_usel = self:makeFrame("ui/selector", fw, fh)
-- Draw the list items
self.h = 0
local sh = 0
local minh = 0
for i, item in ipairs(self.list) do
local color = item.color or {255,255,255}
local text = item[self.display_prop]:splitLines(fw - self.frame_sel.b4.w - self.frame_sel.b6.w, self.font)
......@@ -62,18 +68,38 @@ function _M:generate()
color_r, color_g, color_b = s:drawColorStringBlended(self.font, text[z], self.frame_sel.b4.w, self.frame_sel.b8.w / 3 + self.font_h * (z-1), color_r, color_g, color_b, true)
end
item.start_h = sh
item.fh = fh
item._tex = {s:glTexture()}
self.mouse:registerZone(0, self.h, self.w, fh, function(button, x, y, xrel, yrel, bx, by, event)
if self.sel and self.list[self.sel] then self.list[self.sel].focus_decay = self.focus_decay_max end
self.sel = i
self:onSelect()
if button == "left" and event == "button" then self:onUse() end
end)
self.h = self.h + fh
sh = sh + fh
if i <= self.min_items_shown then minh = sh end
end
self.h = math.max(minh, math.min(self.max_h or 1000000, sh))
if sh > self.h then self.scrollbar = true end
self.scroll_inertia = 0
self.scroll = 0
if self.scrollbar then self.scrollbar = Slider.new{size=self.h, max=sh} end
self.mouse:registerZone(0, 0, self.w, self.h, function(button, x, y, xrel, yrel, bx, by, event)
self.last_input_was_keyboard = false
if event == "button" and button == "wheelup" then if self.scrollbar then self.scroll_inertia = math.min(self.scroll_inertia, 0) - 5 end
elseif event == "button" and button == "wheeldown" then if self.scrollbar then self.scroll_inertia = math.max(self.scroll_inertia, 0) + 5 end
end
for i = 1, #self.list do
local item = self.list[i]
if by + self.scroll >= item.start_h and by + self.scroll < item.start_h + item.fh then
if self.sel and self.list[self.sel] then self.list[self.sel].focus_decay = self.focus_decay_max end
self.sel = i
self:onSelect()
if button == "left" and event == "button" then self:onUse() end
break
end
end
end)
-- Add UI controls
self.key:addBinds{
......@@ -101,10 +127,41 @@ function _M:onSelect()
local item = self.list[self.sel]
if not item then return end
if self.scrollbar then
local pos = 0
for i = 1, #self.list do
local itm = self.list[i]
pos = pos + itm.fh
-- we've reached selected row
if self.sel == i then
-- check if it was visible if not go scroll over there
if pos - itm.fh < self.scrollbar.pos then self.scrollbar.pos = util.minBound(pos - itm.fh, 0, self.scrollbar.max)
elseif pos > self.scrollbar.pos + self.h then self.scrollbar.pos = util.minBound(pos - self.h, 0, self.scrollbar.max)
end
break
end
end
end
if rawget(self, "select") then self.select(item, self.sel) end
end
function _M:display(x, y, nb_keyframes)
function _M:display(x, y, nb_keyframes, screen_x, screen_y)
local by = y
core.display.glScissor(true, screen_x, screen_y, self.w, self.h)
if self.scrollbar then
local tmp_pos = self.scrollbar.pos
self.scrollbar.pos = util.minBound(self.scrollbar.pos + self.scroll_inertia, 0, self.scrollbar.max)
if self.scroll_inertia > 0 then self.scroll_inertia = math.max(self.scroll_inertia - 1, 0)
elseif self.scroll_inertia < 0 then self.scroll_inertia = math.min(self.scroll_inertia + 1, 0)
end
if self.scrollbar.pos == 0 or self.scrollbar.pos == self.scrollbar.max then self.scroll_inertia = 0 end
y = y + (self.scrollbar and -self.scrollbar.pos or 0)
self.scroll = self.scrollbar.pos
end
for i = 1, self.max do
local item = self.list[i]
if not item then break end
......@@ -129,4 +186,12 @@ function _M:display(x, y, nb_keyframes)
item._tex[1]:toScreenFull(x + self.frame_sel.b4.w, y, self.fw, item.fh, item._tex[2], item._tex[3])
y = y + item.fh
end
core.display.glScissor(false)
if self.focused and self.scrollbar then
self.scrollbar:display(x + self.w - self.scrollbar.w, by)
self.last_scroll = self.scrollbar.pos
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment