From ae465d0d1d09720aab17de4769bbd349073f1fcf Mon Sep 17 00:00:00 2001 From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54> Date: Fri, 1 Oct 2010 15:32:13 +0000 Subject: [PATCH] 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 --- .../default/data/gfx/ui/button-left-sel.png | Bin 0 -> 408 bytes .../default/data/gfx/ui/button-left.png | Bin 0 -> 396 bytes .../default/data/gfx/ui/button-middle-sel.png | Bin 0 -> 238 bytes .../default/data/gfx/ui/button-middle.png | Bin 0 -> 233 bytes .../default/data/gfx/ui/button-right-sel.png | Bin 0 -> 427 bytes .../default/data/gfx/ui/button-right.png | Bin 0 -> 434 bytes .../data/gfx/ui/selection-left-sel.png | Bin 0 -> 375 bytes .../data/gfx/ui/selection-middle-sel.png | Bin 0 -> 241 bytes .../data/gfx/ui/selection-right-sel.png | Bin 0 -> 380 bytes game/engines/default/engine/KeyBind.lua | 6 +- game/engines/default/engine/KeyCommand.lua | 10 +- game/engines/default/engine/ui/Base.lua | 53 +++++ game/engines/default/engine/ui/Button.lua | 75 +++++++ game/engines/default/engine/ui/Dialog.lua | 185 ++++++++++++++++++ game/engines/default/engine/ui/Focusable.lua | 29 +++ game/engines/default/engine/ui/List.lua | 75 +++++++ game/engines/default/engine/utils.lua | 3 +- .../default/special/mainmenu/class/TestUI.lua | 71 +++++++ 18 files changed, 501 insertions(+), 6 deletions(-) create mode 100644 game/engines/default/data/gfx/ui/button-left-sel.png create mode 100644 game/engines/default/data/gfx/ui/button-left.png create mode 100644 game/engines/default/data/gfx/ui/button-middle-sel.png create mode 100644 game/engines/default/data/gfx/ui/button-middle.png create mode 100644 game/engines/default/data/gfx/ui/button-right-sel.png create mode 100644 game/engines/default/data/gfx/ui/button-right.png create mode 100644 game/engines/default/data/gfx/ui/selection-left-sel.png create mode 100644 game/engines/default/data/gfx/ui/selection-middle-sel.png create mode 100644 game/engines/default/data/gfx/ui/selection-right-sel.png create mode 100644 game/engines/default/engine/ui/Base.lua create mode 100644 game/engines/default/engine/ui/Button.lua create mode 100644 game/engines/default/engine/ui/Dialog.lua create mode 100644 game/engines/default/engine/ui/Focusable.lua create mode 100644 game/engines/default/engine/ui/List.lua create mode 100644 game/engines/default/special/mainmenu/class/TestUI.lua diff --git a/game/engines/default/data/gfx/ui/button-left-sel.png b/game/engines/default/data/gfx/ui/button-left-sel.png new file mode 100644 index 0000000000000000000000000000000000000000..647e3e36c00305138552219ee38885bc5ec880b3 GIT binary patch literal 408 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Ol*0U~b-^ehHajKx9jP7LeL$-D%~CV9KNFqkvE zWw^Tc;4Vj?2xoyuWHAE+w=f7ZGR&GI0Tg5}@$_|Nzs1GKZOr~!{cAi>NV3E=qQp5r zH#aq}gu%HeHL)Z$MWH;iBtya7(>EZzkxv|`=(DGbV~EE2(n+>{%#J**_WqlcVqIE- zE?ijZkhD~xwM|L<0h^|h)T}w}ZES_Ix9&7bt>rNOJ=u_Tv-EqVI}ug$kH3$UIvBF; z=9&iC4O3Nm8pR)Ml$Bb3uk-o#>oIrqCw}=O``}aJ*_yphm%C*Td`Ua_M(_EH(|kFM z%YHV!@NSdyd1gE-fT=5@fJbx@7t;z>JB77fa~!^?x@})Q>0?2tk3;E%RcHUJ=Ls{t z)qA;o)vnBq&+cAbRQvhW<^#Uxf;4O!cl}U$T)wM5Av9Q=J!Tr?g9dZ%*@w-0zgs+* yndq7-^8I&z;JkQ7@6$1_{12>V{dE8PPsV#L@!kHc6+406XYh3Ob6Mw<&;$T+Y@l!e literal 0 HcmV?d00001 diff --git a/game/engines/default/data/gfx/ui/button-left.png b/game/engines/default/data/gfx/ui/button-left.png new file mode 100644 index 0000000000000000000000000000000000000000..872652d716dce2232c9fd4842ee9070eedcd0068 GIT binary patch literal 396 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Ol*0U~b-^ehHajKx9jP7LeL$-D%~CV9KNFqkvE zWw^Tc;4Vj?2xoyuWHAE+cP9ulnx8zq7AVMG;_2(kev6Bd+eCRrYP%;;NV3E=qQp5r zH#aq}gu%HeHL)Z$MWH;iBtya7(>EZzkxv|`=((qhV~EE2(n;2S%!UGO`wM*<r)Vjh zXr92jYKp?e!=6e~v*xt7u|2h#qa=EVVT<)QKGwL?H(N7x&OZOIc-qOZpTGS30kIn% zQ56qFD_-gSEP3|y=%XpCW+{69<J%Coe#g#v%uW9De3lFAO;2CZma~;{#{BsLCYR19 z*w`(**uW6R#LFn`c*bD~Lo08PmPv!bnF|7wt#{@HY0Pz5vVOxEKI0>o!q!}Wwf*Hn zr6tQHw*30F&hk^;jEg2-Gv_(pmMWDkILFw=TqbK`oYZsV#-j%De={!D{r_1QdN%Ap lE@zC@{KoA<C+hD%XV-`bdGJw2C<o|e22WQ%mvv4FO#qlkm>d8A literal 0 HcmV?d00001 diff --git a/game/engines/default/data/gfx/ui/button-middle-sel.png b/game/engines/default/data/gfx/ui/button-middle-sel.png new file mode 100644 index 0000000000000000000000000000000000000000..8b32a9d0b3e0b784c34e1c1360cddb4befeeb94a GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{G!3HF)&rH7s5-1LGcVbv~PUa<$!<OXj?!sWs z@Rs4~-h;awfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHieMBe${Ex*sdGfI^Zbt`Q~9 z`MJ5Nc_j?aMX8A;sVNHOnI#zt?w-B@;f;LaKt-OOE{-7_*HgP4xf%=vjvQ*p|72LZ z{rrbLyO&<B3UK)_$=T^fR5Vk9eZOkBd!LIjm!)-)npB|ua}ATt^O92*O6Ko%c0cWQ bfL*+k+j3#I#JA5tLm50>{an^LB{Ts5=;TO7 literal 0 HcmV?d00001 diff --git a/game/engines/default/data/gfx/ui/button-middle.png b/game/engines/default/data/gfx/ui/button-middle.png new file mode 100644 index 0000000000000000000000000000000000000000..4bcd9226f3682b41641558cc15d5f751dc78fd3b GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{G!3HF)&rH7s5-1LGcVbv~PUa<$!<OXj?!sWs z@Rs4~-h;awfg+p*9+AZi4BVX{%xHe{^je@Gdx@v7EBh@jMs8CM-9!E!Kq1Kz*N775 z{M_8syb=cIqSVBa)D(sC%#sWRcTeAd@J2pypduGf7sn8e>#;o>c^eD_j;xXHWE7BO z-1uLq{yP_|r*rbnUdii*tP7so1ztLlmm+=h=1hg<fmzX(8l0<Mr4|O%HtR6d?`iin VdHBLhK>%nTgQu&X%Q~loCIG16MbrQQ literal 0 HcmV?d00001 diff --git a/game/engines/default/data/gfx/ui/button-right-sel.png b/game/engines/default/data/gfx/ui/button-right-sel.png new file mode 100644 index 0000000000000000000000000000000000000000..c504f1063aa2791b584275a46bae07dc7d0a2a05 GIT binary patch literal 427 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Ol*0U~b-^ehHajKx9jP7LeL$-D%~CV9KNFqkvE zWw^Tc;4Vj?2xoyuWHAE+w=f7ZGR&GI0Tg5}@$_|Nzs1GKZ7h+d|6>(UNV3E=qQp5r zH#aq}gu%HeHL)Z$MWH;iBtya7(>EZzkxv|G6`QAvV~EE2+&){s!wv$i`!||T`J)lj zz%*e(K_iPylk$#5p3N41vrNQ}-eag*(d;tOSU|<4HDFJ6db#GCqkShQFRQ#?Z9KW} zlg*OIvMFgdcgO2Y+cGI|9=nz3fhE_f=E~fEE)z4ywSfB!!;?>sbp;-LemeE(<6@o| z)pc7ek|pEQ-^`uwQZU`(GDE)3@0*z{=BH+IWxRXeQ?6_gl9wvbxngqBGN&kO5BVu< z5BE<o7L#1UI7MH#eyTx6&g7`=t7kb$tm!&-Ed1COzXR3x>&@>8%(`%Fx06CZ{eK=Q zrHbf>tF3;;XYDl-a5A1dPh@Yit?y*rw7_gz`6i|r3@ffxFf7}8?emNutV{uQF5bR3 RfWgYZ;OXk;vd$@?2>@i6pl|>H literal 0 HcmV?d00001 diff --git a/game/engines/default/data/gfx/ui/button-right.png b/game/engines/default/data/gfx/ui/button-right.png new file mode 100644 index 0000000000000000000000000000000000000000..6a7c2386566c5bf75d208ae6d98da69e50d011eb GIT binary patch literal 434 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Ol*0U~b-^ehHajKx9jP7LeL$-D%~CV9KNFqkvE zWw^Tc;4Vj?2xoyuWHAE+cP9ulnx8zq7AVMG;_2(kev6Bd+r;eaj^sr^A;}Wgh!W@g z+}zZ>5(ej@)Wnk16ovB4k_-iRPv3y>Mm}+%RlJ@qjv*T7b0==}Vs;d9J->!oEK^xx zveIv6G0inDlWwiw;F<hzeaD1jYCi<8?XFFb-WWK+<l-^AH|K8Gif!I(eZ*$Qvw7wB z_Zp~o|Ma>1Qp0!o;=5(PKl@sz8P3=IyQVR9n)swUG4Vz-=dc#A+c3{qew^L6q5r&W z{`>gEhgyPyS}SKRd)}kp#&}14ozR@m`8MwktSt>n7BMi8n8RkU<<XJVY#qODp1QiP zyn(TTJwfTJHB0gzS>ebv9WBloPd2SPo6*eI`0Z?!LhgoRR@Yo5d(8qXLYo7xNbGvG z_ptn}_ox3apCjzDt8M=_9oA4+(|;auxtC33W`-8I#H3elv}DOn;7o{q$QqGaxsg-4 ZUXi2br*w3I9WeA5JYD@<);T3K0RZHysA>QJ literal 0 HcmV?d00001 diff --git a/game/engines/default/data/gfx/ui/selection-left-sel.png b/game/engines/default/data/gfx/ui/selection-left-sel.png new file mode 100644 index 0000000000000000000000000000000000000000..c867bbee34663d54ab788ee0ac82a1fb9f1bfffa GIT binary patch literal 375 zcmeAS@N?(olHy`uVBq!ia0vp^EI=&8!3HF2>gs<0DaPU;cPEB*=VV?2Ic!PZ?k)`G z3~w2(?mf865h%i0;1OBOz`)%J!i?r8Pp<_EvX^-Jy0YKmV&pbtT3MY8GFP(1HKN2h zKQ}iuuY|$5C^fMpHASI3vm`^o-P1Q9ypc~FsOXZXi(`nyW!FAKzrzk9F89~$zs?n* z;n(issWQJoIbiuY*-Otv<}h<{NvUu}ah=jAf57n|_W0|i8<;QemF!JBvgX_4(&t=n zc@zHr`xB)5+Sl#I+uN7V>903)?qIl4;q}|lWrEsav8%qbf;n|sIVzPHr|q(M&%t8W z_Jdt=gW{Lx+8l|=;*S4yy%l}j#5^KqX-}Ha(!25a+=G@q7m{5aGu=3Me7RdY)iU_> z#VK;-zh27KoVs!@;%8Tqg`9o&w!ORaW_^A2XcE%`YZ<xs+izDrto_YxE#=m*%U13- P(02@;u6{1-oD!M<7ygZq literal 0 HcmV?d00001 diff --git a/game/engines/default/data/gfx/ui/selection-middle-sel.png b/game/engines/default/data/gfx/ui/selection-middle-sel.png new file mode 100644 index 0000000000000000000000000000000000000000..8b02bfc150883847094dd51aaf451f9509741fbf GIT binary patch literal 241 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{J!3HE}g>Tsd5-1LGcVbv~PUa<$!<OXj?!sWs z@Rs4~-h;awfg+p*9+AZi4BVX{%xHe{^je@Gdx@v7EBh@jMs6d%?guryfI^Zbt`Q~9 z`MJ5Nc_j?aMX8A;sVNHOnI#zt?w-B@;f;LaKt(>DE{-7_*KLn&<ZUqEaXol^xkI3m zmq7A{|4cduWi~Fh2v8`zT6pjJ;>5l~bMo)X^!_?8)%8l_OhANlgmW=}h}yzh&le|H eb9XK<RgKHor1GrvjN%EPxeT7JelF{r5}E)r;7#WM literal 0 HcmV?d00001 diff --git a/game/engines/default/data/gfx/ui/selection-right-sel.png b/game/engines/default/data/gfx/ui/selection-right-sel.png new file mode 100644 index 0000000000000000000000000000000000000000..180b43056a6d146f5f12825caf842574169bb433 GIT binary patch literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^EI=&8!3HF2>gs<0DaPU;cPEB*=VV?2Ic!PZ?k)`G z3~w2(?mf865h%i0;1OBOz`)%J!i?r8Pp<_EvX^-Jy0YKmV&pb3slRo+3n(O6;u=xn zoS&PUnpeW$T$GwvlA5AWo>`Ki;O^-g5Z=fq4pemA)5S4F;<9P4qZhNIfNOkd_#)1k z4LeE}igT<}@y=J?abf9p4~6Fi4_RF<aCaP<<G`WR!_9l{%bAkt-RG`+`uqKLahzSf z&b|405_yqRx2^Gt-eYISaN_9m*}RE+|L(dPVcww7@b#l#uyB!1)BGO)E%{ML7)~ac zu{A6xT#?drY(GO^4x^Ow3GPYTO|DfpC@^_t7%IG#U%kzili65kfpGJT9zDs0ug}Qt z6l9%uIAzKGyVqp<kDb|@o+VIMmK|R4^gzqzmv5Fv<z8D?@b7ntS^VAj*m$Nt%$An1 V1|N<Gegt}v!PC{xWt~$(696d(kr)5~ literal 0 HcmV?d00001 diff --git a/game/engines/default/engine/KeyBind.lua b/game/engines/default/engine/KeyBind.lua index ec0b336bee..4bed9be636 100644 --- a/game/engines/default/engine/KeyBind.lua +++ b/game/engines/default/engine/KeyBind.lua @@ -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 diff --git a/game/engines/default/engine/KeyCommand.lua b/game/engines/default/engine/KeyCommand.lua index 46847b219c..654c81e2f0 100644 --- a/game/engines/default/engine/KeyCommand.lua +++ b/game/engines/default/engine/KeyCommand.lua @@ -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 diff --git a/game/engines/default/engine/ui/Base.lua b/game/engines/default/engine/ui/Base.lua new file mode 100644 index 0000000000..584ee68258 --- /dev/null +++ b/game/engines/default/engine/ui/Base.lua @@ -0,0 +1,53 @@ +-- 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 diff --git a/game/engines/default/engine/ui/Button.lua b/game/engines/default/engine/ui/Button.lua new file mode 100644 index 0000000000..7436ec7753 --- /dev/null +++ b/game/engines/default/engine/ui/Button.lua @@ -0,0 +1,75 @@ +-- 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 diff --git a/game/engines/default/engine/ui/Dialog.lua b/game/engines/default/engine/ui/Dialog.lua new file mode 100644 index 0000000000..2abed07472 --- /dev/null +++ b/game/engines/default/engine/ui/Dialog.lua @@ -0,0 +1,185 @@ +-- 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 diff --git a/game/engines/default/engine/ui/Focusable.lua b/game/engines/default/engine/ui/Focusable.lua new file mode 100644 index 0000000000..03818bfe03 --- /dev/null +++ b/game/engines/default/engine/ui/Focusable.lua @@ -0,0 +1,29 @@ +-- 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 diff --git a/game/engines/default/engine/ui/List.lua b/game/engines/default/engine/ui/List.lua new file mode 100644 index 0000000000..7436ec7753 --- /dev/null +++ b/game/engines/default/engine/ui/List.lua @@ -0,0 +1,75 @@ +-- 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 diff --git a/game/engines/default/engine/utils.lua b/game/engines/default/engine/utils.lua index ffb139ace3..8b50025658 100644 --- a/game/engines/default/engine/utils.lua +++ b/game/engines/default/engine/utils.lua @@ -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 diff --git a/game/engines/default/special/mainmenu/class/TestUI.lua b/game/engines/default/special/mainmenu/class/TestUI.lua new file mode 100644 index 0000000000..6185cb8c7b --- /dev/null +++ b/game/engines/default/special/mainmenu/class/TestUI.lua @@ -0,0 +1,71 @@ +-- 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 + -- GitLab