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)
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
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
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)
return
return true
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
--- Force a key to trigger
......
......@@ -57,8 +57,10 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup)
-- Convert locale
sym = self.locale_convert[sym] or sym
local handled = false
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
local mods = {}
if alt then mods[#mods+1] = "alt" end
......@@ -68,14 +70,18 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup)
mods = table.concat(mods,',')
if self.commands[sym][mods] then
self.commands[sym][mods](sym, ctrl, shift, alt, meta, unicode)
handled = true
end
elseif self.commands[sym] and self.commands[sym].plain then
self.commands[sym].plain(sym, ctrl, shift, alt, meta, unicode)
handled = true
elseif self.commands[self.__DEFAULT] and self.commands[self.__DEFAULT].plain then
self.commands[self.__DEFAULT].plain(sym, ctrl, shift, alt, meta, unicode)
handled = true
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
--- 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)
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.Game")
local Menu = require("special.mainmenu.class.TestUI")
game = Menu.new()
game:run()
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