Skip to content
Snippets Groups Projects
Commit ae465d0d authored by dg's avatar dg
Browse files

Started creating better UI base classes, all in engine.ui.* They should be...

Started creating better UI base classes, all in engine.ui.* They should be easier to use, saner, faster and look better


git-svn-id: http://svn.net-core.org/repos/t-engine4@1349 51575b47-30f0-44d4-a5cc-537603b46e54
parent 523ec853
No related branches found
No related tags found
No related merge requests found
Showing
with 501 additions and 6 deletions
game/engines/default/data/gfx/ui/button-left-sel.png

408 B

game/engines/default/data/gfx/ui/button-left.png

396 B

game/engines/default/data/gfx/ui/button-middle-sel.png

238 B

game/engines/default/data/gfx/ui/button-middle.png

233 B

game/engines/default/data/gfx/ui/button-right-sel.png

427 B

game/engines/default/data/gfx/ui/button-right.png

434 B

game/engines/default/data/gfx/ui/selection-left-sel.png

375 B

game/engines/default/data/gfx/ui/selection-middle-sel.png

241 B

game/engines/default/data/gfx/ui/selection-right-sel.png

380 B

...@@ -196,16 +196,16 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup, ismouse) ...@@ -196,16 +196,16 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup, ismouse)
if self.binds[ks] and self.virtuals[self.binds[ks]] then if self.binds[ks] and self.virtuals[self.binds[ks]] then
if isup and not _M.binds_def[self.binds[ks]].updown then return end if isup and not _M.binds_def[self.binds[ks]].updown then return end
self.virtuals[self.binds[ks]](sym, ctrl, shift, alt, meta, unicode, isup) self.virtuals[self.binds[ks]](sym, ctrl, shift, alt, meta, unicode, isup)
return return true
elseif us and self.binds[us] and self.virtuals[self.binds[us]] then elseif us and self.binds[us] and self.virtuals[self.binds[us]] then
if isup and not _M.binds_def[self.binds[us]].updown then return end if isup and not _M.binds_def[self.binds[us]].updown then return end
self.virtuals[self.binds[us]](sym, ctrl, shift, alt, meta, unicode, isup) self.virtuals[self.binds[us]](sym, ctrl, shift, alt, meta, unicode, isup)
return return true
end end
if isup then return end if isup then return end
engine.KeyCommand.receiveKey(self, sym, ctrl, shift, alt, meta, unicode, isup) return engine.KeyCommand.receiveKey(self, sym, ctrl, shift, alt, meta, unicode, isup)
end end
--- Force a key to trigger --- Force a key to trigger
......
...@@ -57,8 +57,10 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup) ...@@ -57,8 +57,10 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup)
-- Convert locale -- Convert locale
sym = self.locale_convert[sym] or sym sym = self.locale_convert[sym] or sym
local handled = false
if not self.commands[sym] and not self.commands[self.__DEFAULT] then if not self.commands[sym] and not self.commands[self.__DEFAULT] then
if self.on_input and unicode then self.on_input(unicode) end if self.on_input and unicode then self.on_input(unicode) handled = true end
elseif self.commands[sym] and (ctrl or shift or alt or meta) and not self.commands[sym].anymod then elseif self.commands[sym] and (ctrl or shift or alt or meta) and not self.commands[sym].anymod then
local mods = {} local mods = {}
if alt then mods[#mods+1] = "alt" end if alt then mods[#mods+1] = "alt" end
...@@ -68,14 +70,18 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup) ...@@ -68,14 +70,18 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup)
mods = table.concat(mods,',') mods = table.concat(mods,',')
if self.commands[sym][mods] then if self.commands[sym][mods] then
self.commands[sym][mods](sym, ctrl, shift, alt, meta, unicode) self.commands[sym][mods](sym, ctrl, shift, alt, meta, unicode)
handled = true
end end
elseif self.commands[sym] and self.commands[sym].plain then elseif self.commands[sym] and self.commands[sym].plain then
self.commands[sym].plain(sym, ctrl, shift, alt, meta, unicode) self.commands[sym].plain(sym, ctrl, shift, alt, meta, unicode)
handled = true
elseif self.commands[self.__DEFAULT] and self.commands[self.__DEFAULT].plain then elseif self.commands[self.__DEFAULT] and self.commands[self.__DEFAULT].plain then
self.commands[self.__DEFAULT].plain(sym, ctrl, shift, alt, meta, unicode) self.commands[self.__DEFAULT].plain(sym, ctrl, shift, alt, meta, unicode)
handled = true
end end
if self.atLast then self.atLast(sym, ctrl, shift, alt, meta, unicode) end if self.atLast then self.atLast(sym, ctrl, shift, alt, meta, unicode) handled = true end
return handled
end end
--- Adds a key/command combinaison --- Adds a key/command combinaison
......
-- TE4 - T-Engine 4
-- Copyright (C) 2009, 2010 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
require "engine.class"
local KeyBind = require "engine.KeyBind"
local Mouse = require "engine.Mouse"
--- A generic UI element
module(..., package.seeall, class.make)
local gfx_prefix = "/data/gfx/"
local cache = {}
-- Default font
_M.font = core.display.newFont("/data/font/Vera.ttf", 12)
_M.font_h = _M.font:lineSkip()
function _M:init(t, no_gen)
self.mouse = Mouse.new()
self.key = KeyBind.new()
if t.font then
self.font = core.display.newFont(t.font[1], t.font[2])
self.font_h = self.font:lineSkip()
end
if not no_gen then self:generate() end
end
function _M:getImage(file)
if cache[file] then return unpack(cache[file]) end
local s = core.display.loadImage(gfx_prefix..file)
assert(s, "bad UI image: "..file)
s:alpha(true)
cache[file] = {s, s:getSize()}
return unpack(cache[file])
end
-- TE4 - T-Engine 4
-- Copyright (C) 2009, 2010 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
require "engine.class"
local Base = require "engine.ui.Base"
local Focusable = require "engine.ui.Focusable"
--- A generic UI button
module(..., package.seeall, class.inherit(Base, Focusable))
function _M:init(t)
self.text = assert(t.text, "no button text")
self.fct = assert(t.fct, "no button fct")
Base.init(self, t)
end
function _M:generate()
local ls, ls_w, ls_h = self:getImage("ui/button-left-sel.png")
local ms, ms_w, ms_h = self:getImage("ui/button-middle-sel.png")
local rs, rs_w, rs_h = self:getImage("ui/button-right-sel.png")
local l, l_w, l_h = self:getImage("ui/button-left.png")
local m, m_w, m_h = self:getImage("ui/button-middle.png")
local r, r_w, r_h = self:getImage("ui/button-right.png")
-- Draw UI
self.font:setStyle("bold")
local w, h = self.font:size(self.text:removeColorCodes())
local fw, fh = w + ls_w + rs_w, ls_h
local ss = core.display.newSurface(fw, fh)
local s = core.display.newSurface(fw, fh)
ss:merge(ls, 0, 0)
for i = ls_w, fw - rs_w do ss:merge(ms, i, 0) end
ss:merge(rs, fw - rs_w, 0)
ss:drawColorStringBlended(self.font, self.text, ls_w, (fh - h) / 2, 255, 255, 255)
s:merge(l, 0, 0)
for i = l_w, fw - r_w do s:merge(m, i, 0) end
s:merge(r, fw - r_w, 0)
s:drawColorStringBlended(self.font, self.text, ls_w, (fh - h) / 2, 255, 255, 255)
self.font:setStyle("normal")
-- Add UI controls
self.mouse:registerZone(0, 0, fw, fh, function(button, x, y, xrel, yrel, bx, by, event) if button == "left" and event == "button" then self.fct() end end)
self.key:addBind("ACCEPT", function() self.fct() end)
self.tex, self.tex_w, self.tex_h = s:glTexture()
self.stex = ss:glTexture()
self.w, self.h = fw, fh
end
function _M:display(x, y)
if self.focused then
self.stex:toScreenFull(x, y, self.w, self.h, self.tex_w, self.tex_h)
else
self.tex:toScreenFull(x, y, self.w, self.h, self.tex_w, self.tex_h)
end
end
-- TE4 - T-Engine 4
-- Copyright (C) 2009, 2010 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
require "engine.class"
local KeyBind = require "engine.KeyBind"
local Base = require "engine.ui.Base"
--- A generic UI button
module(..., package.seeall, class.inherit(Base))
function _M:init(title, w, h, x, y, alpha, font, showup)
self.title = assert(title, "no dialog title")
self.alpha = self.alpha or 200
if showup ~= nil then
self.__showup = showup
else
self.__showup = 2
end
self.uis = {}
self.focus_ui = nil
self.focus_ui_id = 0
Base.init(self, {}, true)
self:resize(w, h, x, y, alpha)
end
function _M:resize(w, h, x, y, alpha)
local gamew, gameh = core.display.size()
self.w, self.h = math.floor(w), math.floor(h)
self.display_x = math.floor(x or (gamew - self.w) / 2)
self.display_y = math.floor(y or (gameh - self.h) / 2)
self.iw, self.ih = w - 2 * 5, h - 8 - 16 - 3
self:generate()
end
function _M:generate()
local gamew, gameh = core.display.size()
local s = core.display.newSurface(self.w, self.h)
s:alpha(true)
s:erase(0, 0, 0, self.alpha)
local b7, b7_w, b7_h = self:getImage("border_7.png")
local b9, b9_w, b9_h = self:getImage("border_9.png")
local b1, b1_w, b1_h = self:getImage("border_1.png")
local b3, b3_w, b3_h = self:getImage("border_3.png")
local b8, b8_w, b8_h = self:getImage("border_8.png")
local b4, b4_w, b4_h = self:getImage("border_4.png")
s:merge(b7, 0, 0)
s:merge(b9, self.w - b9_w, 0)
s:merge(b1, 0, self.h - b1_h)
s:merge(b3, self.w - b9_w, self.h - b3_h)
for i = b7_w, self.w - b9_w do
s:merge(b8, i, 0)
s:merge(b8, i, 20)
s:merge(b8, i, self.h - 3)
end
for i = b7_h, self.h - b1_h do
s:merge(b4, 0, i)
s:merge(b4, self.w - 3, i)
end
self.font:setStyle("bold")
local tw, th = self.font:size(self.title:removeColorCodes())
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(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)
self.key:addBinds{
MOVE_UP = function() self:setFocus(util.boundWrap(self.focus_ui_id - 1, 1, #self.uis)) end,
MOVE_DOWN = function() self:setFocus(util.boundWrap(self.focus_ui_id + 1, 1, #self.uis)) end,
MOVE_LEFT = "MOVE_UP",
MOVE_RIGHT = "MOVE_DOWN",
}
self.tex, self.tex_w, self.tex_h = s:glTexture()
end
function _M:loadUI(t)
self.uis = {}
self.focus_ui = nil
self.focus_ui_id = 0
for i, ui in ipairs(t) do
self.uis[#self.uis+1] = ui
local ux, uy = 0, 0
if ui.top then uy = uy + ui.top
elseif ui.bottom then uy = uy + self.h - ui.bottom - ui.ui.h end
if ui.left then ux = ux + ui.left
elseif ui.right then ux = ux + self.w - ui.right - ui.ui.w end
ui.x = ux
ui.y = uy
ui.ui.mouse.delegate_offset_x = ux
ui.ui.mouse.delegate_offset_y = uy
if not self.focus_ui and ui.ui.can_focus then
self:setFocus(i)
else
ui.ui:setFocus(false)
end
end
end
function _M:setFocus(id)
if self.focus_ui then self.focus_ui.ui:setFocus(false) end
local ui = self.uis[id]
self.focus_ui = ui
self.focus_ui_id = id
ui.ui:setFocus(true)
end
function _M:mouseEvent(button, x, y, xrel, yrel, bx, by, event)
-- Look for focus
for i = 1, #self.uis do
local ui = self.uis[i]
if ui.ui.can_focus and bx >= ui.x and bx <= ui.x + ui.ui.w and by >= ui.y and by <= ui.y + ui.ui.h then
self:setFocus(i)
-- Pass the event
ui.ui.mouse:delegate(button, bx, by, xrel, yrel, bx, by, event)
break
end
end
end
function _M:keyEvent(...)
if not self.focus_ui or not self.focus_ui.ui.key:receiveKey(...) then
KeyBind.receiveKey(self.key, ...)
end
end
function _M:display() end
function _M:toScreen(x, y)
-- Draw with only the texture
--[[
if self.__showup then
local eff = self.__showup_effect or "pop"
if eff == "overpop" then
local zoom = self.__showup / 7
if self.__showup >= 9 then
zoom = (9 - (self.__showup - 9)) / 7 - 1
zoom = 1 + zoom * 0.5
end
self.texture:toScreenFull(x + (self.w - self.w * zoom) / 2, y + (self.h - self.h * zoom) / 2, self.w * zoom, self.h * zoom, self.texture_w * zoom, self.texture_h * zoom)
self.__showup = self.__showup + 1
if self.__showup >= 11 then self.__showup = nil end
else
local zoom = self.__showup / 7
self.texture:toScreenFull(x + (self.w - self.w * zoom) / 2, y + (self.h - self.h * zoom) / 2, self.w * zoom, self.h * zoom, self.texture_w * zoom, self.texture_h * zoom)
self.__showup = self.__showup + 1
if self.__showup >= 7 then self.__showup = nil end
end
else
]]
self.tex:toScreenFull(x, y, self.w, self.h, self.tex_w, self.tex_h)
for i = 1, #self.uis do
local ui = self.uis[i]
ui.ui:display(x + ui.x, y + ui.y)
end
-- end
end
-- TE4 - T-Engine 4
-- Copyright (C) 2009, 2010 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
require "engine.class"
--- Make a UI element clickable
module(..., package.seeall, class.make)
can_focus = true
function _M:setFocus(v)
self.focused = v
end
-- TE4 - T-Engine 4
-- Copyright (C) 2009, 2010 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
require "engine.class"
local Base = require "engine.ui.Base"
local Focusable = require "engine.ui.Focusable"
--- A generic UI button
module(..., package.seeall, class.inherit(Base, Focusable))
function _M:init(t)
self.text = assert(t.text, "no button text")
self.fct = assert(t.fct, "no button fct")
Base.init(self, t)
end
function _M:generate()
local ls, ls_w, ls_h = self:getImage("ui/button-left-sel.png")
local ms, ms_w, ms_h = self:getImage("ui/button-middle-sel.png")
local rs, rs_w, rs_h = self:getImage("ui/button-right-sel.png")
local l, l_w, l_h = self:getImage("ui/button-left.png")
local m, m_w, m_h = self:getImage("ui/button-middle.png")
local r, r_w, r_h = self:getImage("ui/button-right.png")
-- Draw UI
self.font:setStyle("bold")
local w, h = self.font:size(self.text:removeColorCodes())
local fw, fh = w + ls_w + rs_w, ls_h
local ss = core.display.newSurface(fw, fh)
local s = core.display.newSurface(fw, fh)
ss:merge(ls, 0, 0)
for i = ls_w, fw - rs_w do ss:merge(ms, i, 0) end
ss:merge(rs, fw - rs_w, 0)
ss:drawColorStringBlended(self.font, self.text, ls_w, (fh - h) / 2, 255, 255, 255)
s:merge(l, 0, 0)
for i = l_w, fw - r_w do s:merge(m, i, 0) end
s:merge(r, fw - r_w, 0)
s:drawColorStringBlended(self.font, self.text, ls_w, (fh - h) / 2, 255, 255, 255)
self.font:setStyle("normal")
-- Add UI controls
self.mouse:registerZone(0, 0, fw, fh, function(button, x, y, xrel, yrel, bx, by, event) if button == "left" and event == "button" then self.fct() end end)
self.key:addBind("ACCEPT", function() self.fct() end)
self.tex, self.tex_w, self.tex_h = s:glTexture()
self.stex = ss:glTexture()
self.w, self.h = fw, fh
end
function _M:display(x, y)
if self.focused then
self.stex:toScreenFull(x, y, self.w, self.h, self.tex_w, self.tex_h)
else
self.tex:toScreenFull(x, y, self.w, self.h, self.tex_w, self.tex_h)
end
end
...@@ -550,7 +550,8 @@ function util.showMainMenu(no_reboot) ...@@ -550,7 +550,8 @@ function util.showMainMenu(no_reboot)
if game and type(game) == "table" then game:joinThreads(30) end if game and type(game) == "table" then game:joinThreads(30) end
if no_reboot then if no_reboot then
local Menu = require("special.mainmenu.class.Game") -- local Menu = require("special.mainmenu.class.Game")
local Menu = require("special.mainmenu.class.TestUI")
game = Menu.new() game = Menu.new()
game:run() game:run()
else else
......
-- TE4 - T-Engine 4
-- Copyright (C) 2009, 2010 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
require "engine.class"
require "engine.Game"
require "engine.KeyBind"
require "engine.interface.GameMusic"
local Module = require "engine.Module"
local Savefile = require "engine.Savefile"
local Tooltip = require "engine.Tooltip"
local ButtonList = require "engine.ButtonList"
local DownloadDialog = require "engine.dialogs.DownloadDialog"
local Button = require "engine.ui.Button"
local Dialog = require "engine.ui.Dialog"
module(..., package.seeall, class.inherit(engine.Game, engine.interface.GameMusic))
function _M:init()
engine.Game.init(self, engine.KeyBind.new())
self.refuse_threads = true
local b1 = Button.new{text="Ok", fct=function() print"OK" end}
local b2 = Button.new{text="Cancel", fct=function() print"KO" end}
local d = Dialog.new("plop", 400, 300)
d:loadUI{
{left=10, bottom=10, ui=b1},
{right=10, bottom=10, ui=b2},
}
self:registerDialog(d)
end
function _M:run()
self:setCurrent()
end
function _M:tick()
return true
end
function _M:display()
engine.Game.display(self)
end
--- Skip to a module directly ?
function _M:commandLineArgs(args)
end
--- Ask if we realy want to close, if so, save the game first
function _M:onQuit()
os.exit()
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