From 7987ea9a9877a4e9f44492210784c7e8d7f94bb9 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Wed, 22 Aug 2012 18:18:19 +0400 Subject: [PATCH] Put some compatibility features into the base dfhack viewscreen. --- library/LuaApi.cpp | 9 +++++- library/include/modules/Screen.h | 9 ++++++ library/lua/gui.lua | 6 +++- library/lua/gui/dwarfmode.lua | 9 ++---- library/modules/Screen.cpp | 55 ++++++++++++++++++++++++++++++-- plugins/manipulator.cpp | 9 ++---- 6 files changed, 80 insertions(+), 17 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 7f18ce3e6..d25da8087 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1179,7 +1179,14 @@ int screen_show(lua_State *L) before = Lua::CheckDFObject(L, 2); df::viewscreen *screen = dfhack_lua_viewscreen::get_pointer(L, 1, true); - lua_pushboolean(L, Screen::show(screen, before)); + + bool ok = Screen::show(screen, before); + + // If it is a table, get_pointer created a new object. Don't leak it. + if (!ok && lua_istable(L, 1)) + delete screen; + + lua_pushboolean(L, ok); return 1; } diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h index 10b6afb21..ce3f32ed2 100644 --- a/library/include/modules/Screen.h +++ b/library/include/modules/Screen.h @@ -117,12 +117,21 @@ namespace DFHack } class DFHACK_EXPORT dfhack_viewscreen : public df::viewscreen { + df::coord2d last_size; + void check_resize(); + + protected: + bool text_input_mode; + public: dfhack_viewscreen(); virtual ~dfhack_viewscreen(); static bool is_instance(df::viewscreen *screen); + virtual void logic(); + virtual void render(); + virtual int8_t movies_okay() { return 1; } virtual bool key_conflict(df::interface_key key); diff --git a/library/lua/gui.lua b/library/lua/gui.lua index 20d7526ef..abe1047c9 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -203,6 +203,8 @@ end Screen = defclass(Screen, dfhack.screen) +Screen.text_input_mode = false + function Screen:isShown() return self._native ~= nil end @@ -219,7 +221,7 @@ function Screen:renderParent() end end -function Screen:inputToParent(...) +function Screen:sendInputToParent(...) if self._native and self._native.parent then simulateInput(self._native.parent, ...) end @@ -232,6 +234,8 @@ function Screen:show(below) self:onAboutToShow(below) if dscreen.show(self, below) then self:onShown() + else + error('Could not show screen') end end diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua index f38b975f7..2d19b2f03 100644 --- a/library/lua/gui/dwarfmode.lua +++ b/library/lua/gui/dwarfmode.lua @@ -127,17 +127,12 @@ local move_keys = { function DwarfOverlay:propagateMoveKeys(keys) for _,v in ipairs(move_keys) do if keys[v] then - self:inputToParent(v) - return + self:sendInputToParent(v) + return v end end end -function DwarfOverlay:onIdle() - -- Dwarfmode constantly needs repainting - dscreen.invalidate() -end - function DwarfOverlay:onAboutToShow(below) local screen = dfhack.gui.getCurViewscreen() if below then screen = below.parent end diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index cadd4c6d5..9b6839a40 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -258,7 +258,7 @@ bool Screen::isDismissed(df::viewscreen *screen) static std::set dfhack_screens; -dfhack_viewscreen::dfhack_viewscreen() +dfhack_viewscreen::dfhack_viewscreen() : text_input_mode(false) { dfhack_screens.insert(this); } @@ -273,9 +273,42 @@ bool dfhack_viewscreen::is_instance(df::viewscreen *screen) return dfhack_screens.count(screen) != 0; } +void dfhack_viewscreen::check_resize() +{ + auto size = Screen::getWindowSize(); + + if (size != last_size) + { + last_size = size; + resize(size.x, size.y); + } +} + +void dfhack_viewscreen::logic() +{ + check_resize(); + + // Various stuff works poorly unless always repainting + Screen::invalidate(); +} + +void dfhack_viewscreen::render() +{ + check_resize(); +} + bool dfhack_viewscreen::key_conflict(df::interface_key key) { - return key == interface_key::OPTIONS; + if (key == interface_key::OPTIONS) + return true; + + if (text_input_mode) + { + if (key == interface_key::HELP || key == interface_key::MOVIES) + return true; + } + + return false; } /* @@ -364,6 +397,10 @@ int dfhack_lua_viewscreen::do_destroy(lua_State *L) void dfhack_lua_viewscreen::update_focus(lua_State *L, int idx) { + lua_getfield(L, idx, "text_input_mode"); + text_input_mode = lua_toboolean(L, -1); + lua_pop(L, 1); + lua_getfield(L, idx, "focus_path"); auto str = lua_tostring(L, -1); if (!str) str = ""; @@ -496,23 +533,35 @@ dfhack_lua_viewscreen::~dfhack_lua_viewscreen() void dfhack_lua_viewscreen::render() { + if (Screen::isDismissed(this)) return; + + dfhack_viewscreen::render(); + safe_call_lua(do_render, 0, 0); } void dfhack_lua_viewscreen::logic() { + if (Screen::isDismissed(this)) return; + + dfhack_viewscreen::logic(); + lua_pushstring(Lua::Core::State, "onIdle"); safe_call_lua(do_notify, 1, 0); } void dfhack_lua_viewscreen::help() { + if (Screen::isDismissed(this)) return; + lua_pushstring(Lua::Core::State, "onHelp"); safe_call_lua(do_notify, 1, 0); } void dfhack_lua_viewscreen::resize(int w, int h) { + if (Screen::isDismissed(this)) return; + auto L = Lua::Core::State; lua_pushstring(L, "onResize"); lua_pushinteger(L, w); @@ -522,6 +571,8 @@ void dfhack_lua_viewscreen::resize(int w, int h) void dfhack_lua_viewscreen::feed(std::set *keys) { + if (Screen::isDismissed(this)) return; + lua_pushlightuserdata(Lua::Core::State, keys); safe_call_lua(do_input, 1, 0); } diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index deb45b9d9..4d8487edc 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -246,7 +246,7 @@ public: static viewscreen_unitlaborsst *create (char pushtype, df::viewscreen *scr = NULL); void feed(set *events); - void logic(); + void render(); void resize(int w, int h) { calcSize(); } @@ -444,16 +444,13 @@ void viewscreen_unitlaborsst::feed(set *events) // TODO: add sorting } -void viewscreen_unitlaborsst::logic() -{ - enabler->flag.bits.render = true; -} - void viewscreen_unitlaborsst::render() { if (Screen::isDismissed(this)) return; + dfhack_viewscreen::render(); + Screen::clear(); Screen::drawBorder(" Manage Labors ");