Try using the Objective-C 'alloc + init' idiom for lua screen objects.

develop
Alexander Gavrilov 2012-08-24 13:28:34 +04:00
parent e825dc5ddb
commit 296f82b02f
5 changed files with 82 additions and 38 deletions

@ -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 "<lua viewscreen: "..tostring(self._native)..">"
end
-- Interactive
local print_banner = true

@ -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

@ -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

@ -17,6 +17,6 @@ local screen = mkinstance(gui.FramedScreen, {
self:dismiss()
end
end
})
}):init()
screen:show()

@ -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)