diff --git a/game/engines/default/engine/Dialog.lua b/game/engines/default/engine/Dialog.lua index dd01da797580d00b163a0e0d50c8e7740451fa2a..df972116ba618ff4d004a862c3d05370a554d70c 100644 --- a/game/engines/default/engine/Dialog.lua +++ b/game/engines/default/engine/Dialog.lua @@ -314,16 +314,6 @@ function _M:mouseZones(t, no_new) end function _M:unload() ---[[ - if self.old_key then - game.key = self.old_key - game.key:setCurrent() - end - if self.old_mouse then - game.mouse = self.old_mouse - game.mouse:setCurrent() - end -]] end function _M:drawWBorder(s, x, y, w) diff --git a/game/engines/default/engine/dialogs/ShowEquipInven.lua b/game/engines/default/engine/dialogs/ShowEquipInven.lua index f7f0502db55f7f15201bdeeef48055f2f85a300e..6842d826f1577b4832a5f32f7be2081fb9caccda 100644 --- a/game/engines/default/engine/dialogs/ShowEquipInven.lua +++ b/game/engines/default/engine/dialogs/ShowEquipInven.lua @@ -18,32 +18,51 @@ -- darkgod@te4.org require "engine.class" -require "engine.Dialog" +local Dialog = require "engine.ui.Dialog" +local ListColumns = require "engine.ui.ListColumns" +local Textzone = require "engine.ui.Textzone" -module(..., package.seeall, class.inherit(engine.Dialog)) +module(..., package.seeall, class.inherit(Dialog)) function _M:init(title, actor, filter, action) self.action = action self.filter = filter self.actor = actor - engine.Dialog.init(self, title or "Inventory", game.w * 0.8, game.h * 0.8, nil, nil, nil, core.display.newFont("/data/font/VeraMono.ttf", 12)) + Dialog.init(self, title or "Inventory", game.w * 0.8, game.h * 0.8) self:generateList() - self.list = self.inven_list - self.sel = 1 - self.scroll = 1 --- self.max = math.floor((self.ih * 0.8 - 5) / self.font_h) - 1 + self.c_inven = ListColumns.new{width=math.floor(self.iw / 2 - 10), height=self.ih - self.max_h - 10, sortable=true, scrollbar=true, columns={ + {name="", width=7, display_prop="id", sort="id"}, + {name="", width=4, display_prop="char", sort="char"}, + {name="Inventory", width=61, display_prop="name", sort="name"}, + {name="Category", width=20, display_prop="cat", sort="cat"}, + {name="Enc.", width=8, display_prop="encumberance", sort="encumberance"}, + }, list=self.inven_list, fct=function(item, sel) self:use(item) end} + + self.c_equip = ListColumns.new{width=math.floor(self.iw / 2 - 10), height=self.ih - self.max_h - 10, scrollbar=true, columns={ + {name="", width=4, display_prop="char", sort="char"}, + {name="Equipment", width=68, display_prop="name"}, + {name="Category", width=20, display_prop="cat"}, + {name="Enc.", width=8, display_prop="encumberance"}, + }, list=self.equip_list, fct=function(item) self:use(item) end} + + self:loadUI{ + {left=0, top=0, ui=self.c_equip}, + {right=0, top=0, ui=self.c_inven}, + } + - self:keyCommands({ + self.key:addCommands{ __TEXTINPUT = function(c) if self.list.chars[c] then self.sel = self.list.chars[c] self:use() end end, - },{ + } + self.key:addBinds{ HOTKEY_1 = function() self:defineHotkey(1) end, HOTKEY_2 = function() self:defineHotkey(2) end, HOTKEY_3 = function() self:defineHotkey(3) end, @@ -80,47 +99,32 @@ function _M:init(title, actor, filter, action) HOTKEY_THIRD_10 = function() self:defineHotkey(34) end, HOTKEY_THIRD_11 = function() self:defineHotkey(35) end, HOTKEY_THIRD_12 = function() self:defineHotkey(36) end, - - MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, - MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, - MOVE_LEFT = function() self.list = self.equip_list self.sel = util.bound(self.sel, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, - MOVE_RIGHT = function() self.list = self.inven_list self.sel = util.bound(self.sel, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, - ACCEPT = function() self:use() end, - EXIT = function() game:unregisterDialog(self) end, - }) - self:mouseZones{ - { x=0, y=0, w=game.w, h=game.h, mode={button=true}, norestrict=true, fct=function(button) if button == "left" then game:unregisterDialog(self) end end}, - { x=2, y=5, w=self.iw, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty, event) - if tx < self.iw / 2 then - self.list = self.equip_list - else - self.list = self.inven_list - end - if button ~= "wheelup" and button ~= "wheeldown" then - self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list) + ACCEPT = function() + if self.focus_ui and self.focus_ui.ui == self.c_inven then self:use(self.c_inven.list[self.c_inven.sel]) + elseif self.focus_ui and self.focus_ui.ui == self.c_equip then self:use(self.c_equip.list[self.c_equip.sel]) end - self.changed = true - - if button == "left" and event == "button" then self:use() - elseif button == "right" and event == "button" then - elseif button == "wheelup" and event == "button" then self.key:triggerVirtual("MOVE_UP") - elseif button == "wheeldown" and event == "button" then self.key:triggerVirtual("MOVE_DOWN") - end - end }, + end, + EXIT = function() game:unregisterDialog(self) end, } end function _M:defineHotkey(id) if not self.actor or not self.actor.hotkey then return end - self.actor.hotkey[id] = {"inventory", self.list[self.sel].object:getName{no_count=true}} - self:simplePopup("Hotkey "..id.." assigned", self.list[self.sel].object:getName{no_count=true}:capitalize().." assigned to hotkey "..id) + local item = nil + if self.focus_ui and self.focus_ui.ui == self.c_inven then item = self.c_inven.list[self.c_inven.sel] + elseif self.focus_ui and self.focus_ui.ui == self.c_equip then item = self.c_equip.list[self.c_equip.sel] + end + if not item or not item.object then return end + + self.actor.hotkey[id] = {"inventory", item.object:getName{no_count=true}} + self:simplePopup("Hotkey "..id.." assigned", item.object:getName{no_count=true}:capitalize().." assigned to hotkey "..id) self.actor.changed = true end -function _M:use() - if self.list[self.sel] and self.list[self.sel].item then - if self.action(self.list[self.sel].object, self.list[self.sel].inven, self.list[self.sel].item) then +function _M:use(item) + if item then + if self.action(item.object, item.inven, item.item) then game:unregisterDialog(self) end end @@ -128,19 +132,20 @@ end function _M:generateList() -- Makes up the list - local list = {} + self.equip_list = {} + local list = self.equip_list local chars = {} local i = 0 self.max_h = 0 for inven_id = 1, #self.actor.inven_def do if self.actor.inven[inven_id] and self.actor.inven_def[inven_id].is_worn then - list[#list+1] = { name=self.actor.inven_def[inven_id].name, color={0x90, 0x90, 0x90}, inven=inven_id } + list[#list+1] = { id=#list+1, char="", name=self.actor.inven_def[inven_id].name, color={0x90, 0x90, 0x90}, inven=inven_id, cat="", encumberance="" } self.max_h = math.max(self.max_h, #self.actor.inven_def[inven_id].description:splitLines(self.iw - 10, self.font)) for item, o in ipairs(self.actor.inven[inven_id]) do if not self.filter or self.filter(o) then local char = string.char(string.byte('a') + i) - list[#list+1] = { name=char..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=inven_id, item=item } + list[#list+1] = { id=#list+1, char=char, name=o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=inven_id, item=item, cat=o.type.."/"..o.subtype, encumberance=o.encumber } self.max_h = math.max(self.max_h, #o:getDesc():splitLines(self.iw - 10, self.font)) chars[char] = #list i = i + 1 @@ -152,26 +157,20 @@ function _M:generateList() self.equip_list = list -- Makes up the list - local list = {} + self.inven_list = {} + local list = self.inven_list local chars = {} local i = 0 for item, o in ipairs(self.actor:getInven("INVEN")) do if not self.filter or self.filter(o) then local char = string.char(string.byte('a') + i) - list[#list+1] = { name=char..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=self.actor.INVEN_INVEN, item=item } + list[#list+1] = { id=#list+1, char=char, name=o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=self.actor.INVEN_INVEN, item=item, cat=o.type.."/"..o.subtype, encumberance=o.encumber } self.max_h = math.max(self.max_h, #o:getDesc():splitLines(self.iw - 10, self.font)) chars[char] = #list i = i + 1 end end list.chars = chars - self.inven_list = list - self.changed = true - - self.list = self.inven_list - self.sel = 1 - self.scroll = 1 - self.max = math.floor((self.ih - 5) / self.font_h) - self.max_h end function _M:on_recover_focus() diff --git a/game/engines/default/engine/ui/Dialog.lua b/game/engines/default/engine/ui/Dialog.lua index 5682f154f774be600912eb925aee0db20e84a560..a19b84ebcd23a48a98174825f3e5b3f77ab7e7b6 100644 --- a/game/engines/default/engine/ui/Dialog.lua +++ b/game/engines/default/engine/ui/Dialog.lua @@ -24,9 +24,80 @@ local Base = require "engine.ui.Base" --- A generic UI button module(..., package.seeall, class.inherit(Base)) +--- Requests a simple, press any key, dialog +function _M:simplePopup(title, text, fct, no_leave) + local w, h = self.font:size(text) + local tw, th = self.font:size(title) + local d = new(title, math.max(w, tw) + 20, h + 75) + d:loadUI{{left = 3, top = 3, ui=require("engine.ui.Textzone").new{width=w+10, height=h+5, text=text}}} + if not no_leave then + d.key:addBind("EXIT", function() game:unregisterDialog(d) if fct then fct() end end) + local close = require("engine.ui.Button").new{text="Close", fct=function() d.key:triggerVirtual("EXIT") end} + d:loadUI{no_reset=true, {hcenter = -close.w / 2, bottom = 3, ui=close}} + d:setFocus(close) + end + game:registerDialog(d) + return d +end + +--- Requests a simple, press any key, dialog +function _M:simpleLongPopup(title, text, w, fct, no_leave) + local list = text:splitLines(w - 10, self.font) + local d = new(title, w + 20, #list * self.font_h + 75) + d:loadUI{{left = 3, top = 3, ui=require("engine.ui.Textzone").new{width=w+10, height=self.font_h * #list, text=text}}} + if not no_leave then + d.key:addBind("EXIT", function() game:unregisterDialog(d) if fct then fct() end end) + local close = require("engine.ui.Button").new{text="Close", fct=function() d.key:triggerVirtual("EXIT") end} + d:loadUI{no_reset=true, {hcenter = -close.w / 2, bottom = 3, ui=close}} + d:setFocus(close) + end + game:registerDialog(d) + return d +end + +--- Requests a simple yes-no dialog +function _M:yesnoPopup(title, text, fct, yes_text, no_text) + local w, h = self.font:size(text) + local tw, th = self.font:size(title) + local d = new(title, math.max(w, tw) + 35, h + 75) + + d.key:addBind("EXIT", function() game:unregisterDialog(d) fct(false) end) + local ok = require("engine.ui.Button").new{text=yes_text or "Yes", fct=function() game:unregisterDialog(d) fct(true) end} + local cancel = require("engine.ui.Button").new{text=no_text or "No", fct=function() game:unregisterDialog(d) fct(false) end} + d:loadUI{ + {left = 3, top = 3, ui=require("engine.ui.Textzone").new{width=w+20, height=h+5, text=text}}, + {left = 3, bottom = 3, ui=ok}, + {right = 3, bottom = 3, ui=cancel}, + } + d:setFocus(ok) + + game:registerDialog(d) + return d +end + +--- Requests a long yes-no dialog +function _M:yesnoLongPopup(title, text, w, fct, yes_text, no_text) + local list = text:splitLines(w - 10, font) + local d = new(title, w + 20, #list * self.font_h + 75) + + d.key:addBind("EXIT", function() game:unregisterDialog(d) fct(false) end) + local ok = require("engine.ui.Button").new{text=yes_text or "Yes", fct=function() game:unregisterDialog(d) fct(true) end} + local cancel = require("engine.ui.Button").new{text=no_text or "No", fct=function() game:unregisterDialog(d) fct(false) end} + d:loadUI{ + {left = 3, top = 3, ui=require("engine.ui.Textzone").new{width=w+20, height=self.font_h * #list, text=text}}} + {left = 3, bottom = 3, ui=ok}, + {right = 3, bottom = 3, ui=cancel}, + } + d:setFocus(ok) + + game:registerDialog(d) + return d +end + + function _M:init(title, w, h, x, y, alpha, font, showup) self.title = assert(title, "no dialog title") - self.alpha = self.alpha or 200 + self.alpha = self.alpha or 255 if showup ~= nil then self.__showup = showup else @@ -85,7 +156,7 @@ function _M:generate() s:drawColorStringBlended(self.font, self.title, (self.w - tw) / 2, 4, 255,255,255) self.font:setStyle("normal") - self.mouse:registerZone(0, 0, gamew, gameh, function() self.key:triggerVirtual("EXIT") end) + self.mouse:registerZone(0, 0, gamew, gameh, function(button, x, y, xrel, yrel, bx, by, event) if button == "left" and event == "button" then self.key:triggerVirtual("EXIT") end end) self.mouse:registerZone(self.display_x, self.display_y, self.w, self.h, function(...) self:mouseEvent(...) end) self.key.receiveKey = function(_, ...) self:keyEvent(...) end self.key:addCommand("_TAB", function(...) self.key:triggerVirtual("MOVE_DOWN") end) @@ -100,17 +171,24 @@ function _M:generate() end function _M:loadUI(t) - self.uis = {} - self.focus_ui = nil - self.focus_ui_id = 0 + if not t.no_reset then + self.uis = {} + self.focus_ui = nil + self.focus_ui_id = 0 + end for i, ui in ipairs(t) do self.uis[#self.uis+1] = ui local ux, uy = self.ix, self.iy + if ui.top then uy = uy + ui.top - elseif ui.bottom then uy = uy + self.ih - ui.bottom - ui.ui.h end + elseif ui.bottom then uy = uy + self.ih - ui.bottom - ui.ui.h + elseif ui.vcenter then uy = uy + math.floor(self.ih / 2) + ui.vcenter end + if ui.left then ux = ux + ui.left - elseif ui.right then ux = ux + self.iw - ui.right - ui.ui.w end + elseif ui.right then ux = ux + self.iw - ui.right - ui.ui.w + elseif ui.hcenter then ux = ux + math.floor(self.iw / 2) + ui.hcenter end + ui.x = ux ui.y = uy ui.ui.mouse.delegate_offset_x = ux @@ -118,8 +196,8 @@ function _M:loadUI(t) if not self.focus_ui and ui.ui.can_focus then self:setFocus(i) - else - ui.ui:setFocus(false) + elseif ui.ui.can_focus then + ui.ui:setFocus(false) end end end @@ -127,6 +205,13 @@ end function _M:setFocus(id) if self.focus_ui then self.focus_ui.ui:setFocus(false) end + if type(id) == "table" then + for i = 1, #self.uis do + if self.uis[i].ui == id then id = i break end + end + if type(id) == "table" then return end + end + local ui = self.uis[id] self.focus_ui = ui self.focus_ui_id = id @@ -155,6 +240,9 @@ end function _M:display() end +function _M:unload() +end + function _M:toScreen(x, y) -- Draw with only the texture --[[ diff --git a/game/engines/default/engine/ui/List.lua b/game/engines/default/engine/ui/List.lua index d6fac8287b4c5bc773007ab5a2a21ef262edf738..c7d833af4aa03a774ef3376bb970cda5f79ed168 100644 --- a/game/engines/default/engine/ui/List.lua +++ b/game/engines/default/engine/ui/List.lua @@ -126,7 +126,7 @@ function _M:onUse() local item = self.list[self.sel] if not item then return end if item.fct then item:fct() - else self.fct(item) end + else self.fct(item, self.sel) end end function _M:display(x, y) diff --git a/game/engines/default/engine/ui/ListColumns.lua b/game/engines/default/engine/ui/ListColumns.lua index fd145b771b00ebaa38f90513080e0da989650de1..87708f437dc0d4b8382c2534027a64ac66dce93b 100644 --- a/game/engines/default/engine/ui/ListColumns.lua +++ b/game/engines/default/engine/ui/ListColumns.lua @@ -175,7 +175,7 @@ function _M:onUse() local item = self.list[self.sel] if not item then return end if item.fct then item:fct() - else self.fct(item) end + else self.fct(item, self.sel) end end function _M:selectColumn(i, force) @@ -190,10 +190,12 @@ function _M:selectColumn(i, force) self.sort_reverse = not self.sort_reverse end - local fct = col.sort - if type(fct) == "string" then fct = function(a, b) return a[col.sort] < b[col.sort] end end - if self.sort_reverse then local old=fct fct = function(a, b) return old(b, a) end end - table.sort(self.list, fct) + if self.sortable and not force then + local fct = col.sort + if type(fct) == "string" then fct = function(a, b) return a[col.sort] < b[col.sort] end end + if self.sort_reverse then local old=fct fct = function(a, b) return old(b, a) end end + table.sort(self.list, fct) + end end function _M:display(x, y) diff --git a/game/engines/default/engine/utils.lua b/game/engines/default/engine/utils.lua index 8b500256581c3cf386796484d2ad8b783374b90c..173d137543dc0e044c92abf9f9208cc52f32e23a 100644 --- a/game/engines/default/engine/utils.lua +++ b/game/engines/default/engine/utils.lua @@ -550,8 +550,8 @@ function util.showMainMenu(no_reboot) if game and type(game) == "table" then game:joinThreads(30) end if no_reboot then --- local Menu = require("special.mainmenu.class.Game") - local Menu = require("special.mainmenu.class.TestUI") + local Menu = require("special.mainmenu.class.Game") +-- local Menu = require("special.mainmenu.class.TestUI") game = Menu.new() game:run() else diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 3180e5030e353d73d1c4ef08f673e521c749ddbd..47147a12d1adf79a85df1e37113c3cc5679c885f 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -55,7 +55,7 @@ local FlyingText = require "engine.FlyingText" local Tooltip = require "engine.Tooltip" local Calendar = require "engine.Calendar" -local Dialog = require "engine.Dialog" +local Dialog = require "engine.ui.Dialog" local MapMenu = require "mod.dialogs.MapMenu" module(..., package.seeall, class.inherit(engine.GameTurnBased, engine.interface.GameMusic, engine.interface.GameSound, engine.interface.GameTargeting)) @@ -830,9 +830,9 @@ function _M:onQuit() self.player:restStop("quitting") if not self.quit_dialog and not self.player.dead then - self.quit_dialog = Dialog:yesnoPopup(" Save and exit? ", "Save and exit?", function(ok) + self.quit_dialog = Dialog:yesnoPopup("Save and exit?", "Save and exit?", function(ok) if ok then - local d = engine.Dialog:simplePopup("Quitting...", "Quitting...") + local d = engine.Dialog:simplePopup("Quitting...", "Quitting...", nil, true) d.__show_popup = false core.display.forceRedraw() diff --git a/game/modules/tome/class/interface/PlayerLore.lua b/game/modules/tome/class/interface/PlayerLore.lua index da5590083622837493b62c70b2329c8c14bd13c1..ea43793388a1046ed58be291301a906021e5e9ad 100644 --- a/game/modules/tome/class/interface/PlayerLore.lua +++ b/game/modules/tome/class/interface/PlayerLore.lua @@ -18,7 +18,7 @@ -- darkgod@te4.org require "engine.class" -local Dialog = require "engine.Dialog" +local Dialog = require "engine.ui.Dialog" module(..., package.seeall, class.make)