diff options
| author | Alexander Gavrilov | 2012-08-20 23:04:01 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-08-20 23:04:01 +0400 |
| commit | 601a3a7927d50500b3dbdd2d20c5d7740a5484a1 (patch) | |
| tree | 0acd09a61f5b5359d9a4197b8baef8043dda1f38 /library/lua | |
| parent | 38a07a4ca584e2cccc2c2814c35266ba33d692c8 (diff) | |
| download | dfhack-601a3a7927d50500b3dbdd2d20c5d7740a5484a1.tar.gz dfhack-601a3a7927d50500b3dbdd2d20c5d7740a5484a1.tar.bz2 dfhack-601a3a7927d50500b3dbdd2d20c5d7740a5484a1.tar.xz | |
Add a script that implements a linked mechanism browser.
Diffstat (limited to 'library/lua')
| -rw-r--r-- | library/lua/gui.lua | 65 | ||||
| -rw-r--r-- | library/lua/gui/dwarfmode.lua | 119 |
2 files changed, 181 insertions, 3 deletions
diff --git a/library/lua/gui.lua b/library/lua/gui.lua index 0e4e4cc6..5883a2ee 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -4,6 +4,42 @@ local _ENV = mkmodule('gui') local dscreen = dfhack.screen +CLEAR_PEN = {ch=32,fg=0,bg=0} + +function simulateInput(screen,...) + local keys = {} + local function push_key(arg) + local kv = arg + if type(arg) == 'string' then + kv = df.interface_key[arg] + if kv == nil then + error('Invalid keycode: '..arg) + end + end + if type(arg) == 'number' then + keys[#keys+1] = kv + end + end + for i = 1,select('#',...) do + local arg = select(i,...) + if arg ~= nil then + local t = type(arg) + if type(arg) == 'table' then + for k,v in pairs(arg) do + if v == true then + push_key(k) + else + push_key(v) + end + end + else + push_key(arg) + end + end + end + dscreen._doSimulateInput(screen, keys) +end + Screen = defclass(Screen, dfhack.screen) function Screen.new(attrs) @@ -26,6 +62,12 @@ function Screen:renderParent() end end +function Screen:inputToParent(...) + if self._native and self._native.parent then + simulateInput(self._native.parent, ...) + end +end + function paint_border(x1,y1,x2,y2,color,title) local pen = { ch = ' ', fg = COLOR_BLACK, bg = color } dscreen.fillRect(pen,x1,y1,x2,y1) @@ -40,20 +82,37 @@ function paint_border(x1,y1,x2,y2,color,title) end end -function Screen:renderFrame(color,title,width,height) +local function hint_coord(gap,hint) + if hint and hint > 0 then + return math.min(hint,gap) + elseif hint and hint < 0 then + return math.max(0,gap-hint) + else + return math.floor(gap/2) + end +end + +function mkdims_xy(x1,y1,x2,y2) + return { x1=x1, y1=y1, x2=x2, y2=y2, width=x2-x1+1, height=y2-y1+1 } +end +function mkdims_wh(x1,y1,w,h) + return { x1=x1, y1=y1, x2=x1+w-1, y2=y1+h-1, width=w, height=h } +end + +function Screen:renderFrame(color,title,width,height,xhint,yhint) local sw, sh = dscreen.getWindowSize() local iw, ih = sw-2, sh-2 width = math.min(width or iw, iw) height = math.min(height or ih, ih) local gw, gh = iw-width, ih-height - local x1, y1 = math.floor(gw/2), math.floor(gh/2) + local x1, y1 = hint_coord(gw,xhint), hint_coord(gh,yhint) local x2, y2 = x1+width+1, y1+height+1 if gw == 0 and gh == 0 then dscreen.clear() else self:renderParent() - dscreen.fillRect({ch=' ',fg=0,bg=0},x1,y1,x2,y2) + dscreen.fillRect(CLEAR_PEN,x1,y1,x2,y2) end paint_border(x1,y1,x2,y2,color,title) diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua new file mode 100644 index 00000000..2c62751e --- /dev/null +++ b/library/lua/gui/dwarfmode.lua @@ -0,0 +1,119 @@ +-- Support for messing with the dwarfmode screen + +local _ENV = mkmodule('gui.dwarfmode') + +local gui = require('gui') +local dscreen = dfhack.screen + +AREA_MAP_WIDTH = 23 +MENU_WIDTH = 30 + +function getPanelLayout() + local sw, sh = dscreen.getWindowSize() + local view_height = sh-2 + local view_rb = sw-1 + local area_x2 = sw-AREA_MAP_WIDTH-2 + local menu_x2 = sw-MENU_WIDTH-2 + local menu_x1 = area_x2-MENU_WIDTH-1 + local area_pos = df.global.ui_area_map_width + local menu_pos = df.global.ui_menu_width + local rv = {} + + if area_pos < 3 then + rv.area_map = gui.mkdims_xy(area_x2+1,1,view_rb-1,view_height) + view_rb = area_x2 + end + if menu_pos < area_pos or df.global.ui.main.mode ~= 0 then + if menu_pos >= area_pos then + rv.menu_forced = true + menu_pos = area_pos-1 + end + local menu_x = menu_x2 + if menu_pos < 2 then menu_x = menu_x1 end + rv.menu = gui.mkdims_xy(menu_x+1,1,view_rb-1,view_height) + view_rb = menu_x + end + rv.area_pos = area_pos + rv.menu_pos = menu_pos + rv.map = gui.mkdims_xy(1,1,view_rb-1,view_height) + return rv +end + +function getViewportPos() + return { + x = df.global.window_x, + y = df.global.window_y, + z = df.global.window_z + } +end + +function getCursorPos() + return copyall(df.global.cursor) +end + +function setCursorPos(cursor) + df.global.cursor = cursor +end + +function setViewportPos(layout,view) + local map = df.global.world.map + df.global.window_x = math.max(0, math.min(view.x, map.x_count-layout.map.width)) + df.global.window_y = math.max(0, math.min(view.y, map.y_count-layout.map.height)) + df.global.window_z = math.max(0, math.min(view.z, map.z_count-1)) + return getViewportPos() +end + +function centerViewportOn(layout,target) + local mapsz = layout.map + local view = xyz2pos( + target.x-math.floor(layout.map.width/2), + target.y-math.floor(layout.map.height/2), + target.z + ) + return setViewportPos(layout, view) +end + +function isInViewport(layout,view,target,gap) + gap = gap or 0 + return target.x-gap >= view.x and target.x+gap < view.x+layout.map.width + and target.y-gap >= view.y and target.y+gap < view.y+layout.map.height + and target.z == view.z +end + +DwarfOverlay = defclass(DwarfOverlay, gui.Screen) + +function DwarfOverlay:updateLayout() + self.df_layout = getPanelLayout() + self.df_viewport = getViewportPos() + self.df_cursor = getCursorPos() +end + +local move_keys = { + 'CURSOR_UP', 'CURSOR_DOWN', 'CURSOR_LEFT', 'CURSOR_RIGHT', + 'CURSOR_UPLEFT', 'CURSOR_UPRIGHT', 'CURSOR_DOWNLEFT', 'CURSOR_DOWNRIGHT', + 'CURSOR_UP_FAST', 'CURSOR_DOWN_FAST', 'CURSOR_LEFT_FAST', 'CURSOR_RIGHT_FAST', + 'CURSOR_UPLEFT_FAST', 'CURSOR_UPRIGHT_FAST', 'CURSOR_DOWNLEFT_FAST', 'CURSOR_DOWNRIGHT_FAST', + 'CURSOR_UP_Z', 'CURSOR_DOWN_Z', 'CURSOR_UP_Z_AUX', 'CURSOR_DOWN_Z_AUX' +} + +function DwarfOverlay:propagateMoveKeys(keys) + for _,v in ipairs(move_keys) do + if keys[v] then + self:inputToParent(v) + return + end + end +end + +function DwarfOverlay:onIdle() + dscreen.invalidate() +end + +function DwarfOverlay:clearMenu() + local menu = self.df_layout.menu + if not menu then return nil end + dscreen.fillRect(gui.CLEAR_PEN,menu.x1,menu.y1,menu.x2,menu.y2) + return menu.x1,menu.y1,menu.width,menu.height +end + +return _ENV |
