summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-08-19 17:53:25 +0400
committerAlexander Gavrilov2012-08-19 17:53:25 +0400
commitcacb082416667ec4309d85e934068ded041d21b8 (patch)
treef34c045461dfea3c4a5054d90b4042050bf9857f /library
parent30f71ff5106d271d04bfa26b976441cfa9b2abf6 (diff)
downloaddfhack-cacb082416667ec4309d85e934068ded041d21b8.tar.gz
dfhack-cacb082416667ec4309d85e934068ded041d21b8.tar.bz2
dfhack-cacb082416667ec4309d85e934068ded041d21b8.tar.xz
Add a stupid example of a lua-controlled viewscreen.
Diffstat (limited to 'library')
-rw-r--r--library/LuaApi.cpp10
-rw-r--r--library/lua/dfhack.lua17
-rw-r--r--library/lua/gui.lua63
-rw-r--r--library/modules/Screen.cpp3
4 files changed, 92 insertions, 1 deletions
diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp
index d296a2e5..0f3ed935 100644
--- a/library/LuaApi.cpp
+++ b/library/LuaApi.cpp
@@ -196,7 +196,15 @@ static bool get_int_field(lua_State *L, T *pf, int idx, const char *name, int de
static void decode_pen(lua_State *L, Pen &pen, int idx)
{
- get_int_field(L, &pen.ch, idx, "ch", 0);
+ idx = lua_absindex(L, idx);
+
+ lua_getfield(L, idx, "ch");
+ if (lua_isstring(L, -1))
+ pen.ch = lua_tostring(L, -1)[0];
+ else
+ get_int_field(L, &pen.ch, idx, "ch", 0);
+ lua_pop(L, 1);
+
get_int_field(L, &pen.fg, idx, "fg", 7);
get_int_field(L, &pen.bg, idx, "bg", 0);
diff --git a/library/lua/dfhack.lua b/library/lua/dfhack.lua
index 8c8a75aa..5ebc9809 100644
--- a/library/lua/dfhack.lua
+++ b/library/lua/dfhack.lua
@@ -102,6 +102,23 @@ function reload(module)
dofile(path)
end
+-- Trivial classes
+
+function defclass(class,parent)
+ class = class or {}
+ rawset(class, '__index', rawget(class, '__index') or class)
+ if parent then
+ setmetatable(class, parent)
+ end
+ return class
+end
+
+function mkinstance(class,table)
+ table = table or {}
+ setmetatable(table, class)
+ return table
+end
+
-- Misc functions
function printall(table)
diff --git a/library/lua/gui.lua b/library/lua/gui.lua
new file mode 100644
index 00000000..0e4e4cc6
--- /dev/null
+++ b/library/lua/gui.lua
@@ -0,0 +1,63 @@
+-- Viewscreen implementation utility collection.
+
+local _ENV = mkmodule('gui')
+
+local dscreen = dfhack.screen
+
+Screen = defclass(Screen, dfhack.screen)
+
+function Screen.new(attrs)
+ return mkinstance(Screen, attrs)
+end
+
+function Screen:isShown()
+ return self._native ~= nil
+end
+
+function Screen:isActive()
+ return self:isShown() and not self:isDismissed()
+end
+
+function Screen:renderParent()
+ if self._native and self._native.parent then
+ self._native.parent:render()
+ else
+ dscreen.clear()
+ 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)
+ dscreen.fillRect(pen,x1,y2,x2,y2)
+ dscreen.fillRect(pen,x1,y1+1,x1,y2-1)
+ dscreen.fillRect(pen,x2,y1+1,x2,y2-1)
+
+ if title then
+ local x = math.floor((x2-x1-3-#title)/2 + x1)
+ pen.bg = bit32.bxor(pen.bg, 8)
+ dscreen.paintString(pen, x, y1, ' '..title..' ')
+ end
+end
+
+function Screen:renderFrame(color,title,width,height)
+ 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 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)
+ end
+
+ paint_border(x1,y1,x2,y2,color,title)
+ return x1+1,y1+1,width,height,x2-1,y2-1
+end
+
+return _ENV
diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp
index ac45bb86..ba0313e2 100644
--- a/library/modules/Screen.cpp
+++ b/library/modules/Screen.cpp
@@ -318,6 +318,9 @@ int dfhack_lua_viewscreen::do_destroy(lua_State *L)
lua_setfield(L, -2, "_native");
lua_getfield(L, -1, "onDestroy");
+ if (lua_isnil(L, -1))
+ return 0;
+
lua_pushvalue(L, -2);
lua_call(L, 1, 0);
return 0;