From 296f82b02fcd0801d6614bb45da05c88ed7c88d2 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Fri, 24 Aug 2012 13:28:34 +0400 Subject: [PATCH] Try using the Objective-C 'alloc + init' idiom for lua screen objects. --- library/lua/dfhack.lua | 26 +++++++--------- library/lua/gui.lua | 57 ++++++++++++++++++++++++++++++++--- library/lua/gui/dwarfmode.lua | 17 +++++------ scripts/gui/hello-world.lua | 2 +- scripts/gui/mechanisms.lua | 18 +++++------ 5 files changed, 82 insertions(+), 38 deletions(-) diff --git a/library/lua/dfhack.lua b/library/lua/dfhack.lua index 5699e8a20..2cbd019a6 100644 --- a/library/lua/dfhack.lua +++ b/library/lua/dfhack.lua @@ -104,11 +104,21 @@ end -- Trivial classes +function rawset_default(target,source) + for k,v in pairs(source) do + if rawget(target,k) == nil then + rawset(target,k,v) + end + end +end + function defclass(class,parent) class = class or {} - rawset(class, '__index', rawget(class, '__index') or class) + rawset_default(class, { __index = class }) if parent then setmetatable(class, parent) + else + rawset_default(class, { init_fields = rawset_default }) end return class end @@ -153,14 +163,6 @@ function xyz2pos(x,y,z) end end -function rawset_default(target,source) - for k,v in pairs(source) do - if rawget(target,k) == nil then - rawset(target,k,v) - end - end -end - function safe_index(obj,idx,...) if obj == nil or idx == nil then return nil @@ -202,12 +204,6 @@ function dfhack.buildings.getSize(bld) return bld.x2+1-x, bld.y2+1-y, bld.centerx-x, bld.centery-y end -dfhack.screen.__index = dfhack.screen - -function dfhack.screen:__tostring() - return "" -end - -- Interactive local print_banner = true diff --git a/library/lua/gui.lua b/library/lua/gui.lua index 62e393f0b..ac032166f 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -4,6 +4,8 @@ local _ENV = mkmodule('gui') local dscreen = dfhack.screen +USE_GRAPHICS = dscreen.inGraphicsMode() + CLEAR_PEN = {ch=32,fg=0,bg=0} function simulateInput(screen,...) @@ -52,6 +54,9 @@ function inset(rect,dx1,dy1,dx2,dy2) rect.x2-(dx2 or dx1), rect.y2-(dy2 or dy1) ) end +function is_in_rect(rect,x,y) + return x and y and x >= rect.x1 and x <= rect.x2 and y >= rect.y1 and y <= rect.y2 +end local function to_pen(default, pen, bg, bold) if pen == nil then @@ -201,10 +206,17 @@ end -- Base screen object -- ------------------------ -Screen = defclass(Screen, dfhack.screen) +Screen = defclass(Screen) Screen.text_input_mode = false +function Screen:init() + self:updateLayout() + return self +end + +Screen.isDismissed = dscreen.isDismissed + function Screen:isShown() return self._native ~= nil end @@ -213,6 +225,18 @@ function Screen:isActive() return self:isShown() and not self:isDismissed() end +function Screen:invalidate() + dscreen.invalidate() +end + +function Screen:getWindowSize() + return dscreen.getWindowSize() +end + +function Screen:getMousePos() + return dscreen.getMousePos() +end + function Screen:renderParent() if self._native and self._native.parent then self._native.parent:render() @@ -241,6 +265,7 @@ function Screen:onAboutToShow() end function Screen:onShow() + self:updateLayout() end function Screen:dismiss() @@ -252,6 +277,13 @@ end function Screen:onDismiss() end +function Screen:onResize(w,h) + self:updateLayout() +end + +function Screen:updateLayout() +end + ------------------------ -- Framed screen object -- ------------------------ @@ -318,7 +350,8 @@ local function hint_coord(gap,hint) end end -function FramedScreen:updateFrameSize(sw,sh) +function FramedScreen:updateFrameSize() + local sw, sh = dscreen.getWindowSize() local iw, ih = sw-2, sh-2 local width = math.min(self.frame_width or iw, iw) local height = math.min(self.frame_height or ih, ih) @@ -328,8 +361,21 @@ function FramedScreen:updateFrameSize(sw,sh) self.frame_opaque = (gw == 0 and gh == 0) end -function FramedScreen:onResize(w,h) - self:updateFrameSize(w,h) +function FramedScreen:updateLayout() + self:updateFrameSize() +end + +function FramedScreen:getWindowSize() + local rect = self.frame_rect + return rect.width, rect.height +end + +function FramedScreen:getMousePos() + local rect = self.frame_rect + local x,y = dscreen.getMousePos() + if is_in_rect(rect,x,y) then + return x-rect.x1, y-rect.y1 + end end function FramedScreen:onRender() @@ -348,4 +394,7 @@ function FramedScreen:onRender() self:onRenderBody(Painter.new(rect)) end +function FramedScreen:onRenderBody(dc) +end + return _ENV diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua index dde5225a1..b5ffa7280 100644 --- a/library/lua/gui/dwarfmode.lua +++ b/library/lua/gui/dwarfmode.lua @@ -179,14 +179,6 @@ function DwarfOverlay:updateLayout() self.df_layout = getPanelLayout() end -function DwarfOverlay:onShown() - self:updateLayout() -end - -function DwarfOverlay:onResize(w,h) - self:updateLayout() -end - function DwarfOverlay:getViewport(old_vp) if old_vp then return old_vp:resize(self.df_layout) @@ -238,6 +230,14 @@ end MenuOverlay = defclass(MenuOverlay, DwarfOverlay) +function MenuOverlay:updateLayout() + DwarfOverlay.updateLayout(self) + self.frame_rect = self.df_layout.menu +end + +MenuOverlay.getWindowSize = gui.FramedScreen.getWindowSize +MenuOverlay.getMousePos = gui.FramedScreen.getMousePos + function MenuOverlay:onAboutToShow(below) DwarfOverlay.onAboutToShow(self,below) @@ -249,7 +249,6 @@ end function MenuOverlay:onRender() self:renderParent() - self:updateLayout() local menu = self.df_layout.menu if menu then diff --git a/scripts/gui/hello-world.lua b/scripts/gui/hello-world.lua index b67e50124..80986bbf6 100644 --- a/scripts/gui/hello-world.lua +++ b/scripts/gui/hello-world.lua @@ -17,6 +17,6 @@ local screen = mkinstance(gui.FramedScreen, { self:dismiss() end end -}) +}):init() screen:show() diff --git a/scripts/gui/mechanisms.lua b/scripts/gui/mechanisms.lua index 3b40ffbd7..d33d55a92 100644 --- a/scripts/gui/mechanisms.lua +++ b/scripts/gui/mechanisms.lua @@ -52,15 +52,16 @@ MechanismList = defclass(MechanismList, guidm.MenuOverlay) MechanismList.focus_path = 'mechanisms' -function MechanismList.new(building) - local self = { - links = {}, - selected = 1 +function MechanismList:init(building) + self:init_fields{ + links = {}, selected = 1 } - return mkinstance(MechanismList, self):init(building) + guidm.MenuOverlay.init(self) + self:fillList(building) + return self end -function MechanismList:init(building) +function MechanismList:fillList(building) local links = listMechanismLinks(building) links[1].viewport = self:getViewport() @@ -71,7 +72,6 @@ function MechanismList:init(building) self.links = links self.selected = 1 - return self end local colors = { @@ -133,7 +133,7 @@ function MechanismList:onInput(keys) end elseif keys.SELECT_ALL then if self.selected > 1 then - self:init(self.links[self.selected].obj) + self:fillList(self.links[self.selected].obj) end elseif keys.SELECT then self:dismiss() @@ -146,6 +146,6 @@ if dfhack.gui.getCurFocus() ~= 'dwarfmode/QueryBuilding/Some' then qerror("This script requires the main dwarfmode view in 'q' mode") end -local list = MechanismList.new(df.global.world.selected_building) +local list = mkinstance(MechanismList):init(df.global.world.selected_building) list:show() list:changeSelected(1)