diff options
| -rw-r--r-- | LUA_API.rst | 24 | ||||
| -rw-r--r-- | Lua API.html | 22 | ||||
| -rw-r--r-- | library/Core.cpp | 2 | ||||
| -rw-r--r-- | library/LuaApi.cpp | 1 | ||||
| -rw-r--r-- | library/include/modules/Gui.h | 8 | ||||
| -rw-r--r-- | library/include/modules/Screen.h | 8 | ||||
| -rw-r--r-- | library/lua/gui.lua | 11 | ||||
| -rw-r--r-- | library/modules/Gui.cpp | 16 | ||||
| -rw-r--r-- | library/modules/Screen.cpp | 30 | ||||
| -rw-r--r-- | scripts/gui/mechanisms.lua | 7 |
10 files changed, 96 insertions, 33 deletions
diff --git a/LUA_API.rst b/LUA_API.rst index 76f6454f..49e20523 100644 --- a/LUA_API.rst +++ b/LUA_API.rst @@ -724,15 +724,20 @@ can be omitted. Gui module ---------- -* ``dfhack.gui.getCurViewscreen()`` +* ``dfhack.gui.getCurViewscreen([skip_dismissed])`` - Returns the viewscreen that is current in the core. + Returns the topmost viewscreen. If ``skip_dismissed`` is *true*, + ignores screens already marked to be removed. * ``dfhack.gui.getFocusString(viewscreen)`` Returns a string representation of the current focus position in the ui. The string has a "screen/foo/bar/baz..." format. +* ``dfhack.gui.getCurFocus([skip_dismissed])`` + + Returns the focus string of the current viewscreen. + * ``dfhack.gui.getSelectedWorkshopJob([silent])`` When a job is selected in *'q'* mode, returns the job, else @@ -1291,9 +1296,10 @@ Screens are managed with the following functions: Displays the given screen, possibly placing it below a different one. The screen must not be already shown. Returns *true* if success. -* ``dfhack.screen.dismiss(screen)`` +* ``dfhack.screen.dismiss(screen[,to_first])`` Marks the screen to be removed when the game enters its event loop. + If ``to_first`` is *true*, all screens up to the first one will be deleted. * ``dfhack.screen.isDismissed(screen)`` @@ -1312,10 +1318,22 @@ Supported callbacks and fields are: Initialized by ``show`` with a reference to the backing viewscreen object, and removed again when the object is deleted. +* ``function screen:onShow()`` + + Called by ``dfhack.screen.show`` if successful. + +* ``function screen:onDismiss()`` + + Called by ``dfhack.screen.dismiss`` if successful. + * ``function screen:onDestroy()`` Called from the destructor when the viewscreen is deleted. +* ``function screen:onResize(w, h)`` + + Called before ``onRender`` or ``onIdle`` when the window size has changed. + * ``function screen:onRender()`` Called when the viewscreen should paint itself. This is the only context diff --git a/Lua API.html b/Lua API.html index c4ab9c8c..15f1d89c 100644 --- a/Lua API.html +++ b/Lua API.html @@ -987,13 +987,17 @@ can be omitted.</p> <div class="section" id="gui-module"> <h3><a class="toc-backref" href="#id18">Gui module</a></h3> <ul> -<li><p class="first"><tt class="docutils literal">dfhack.gui.getCurViewscreen()</tt></p> -<p>Returns the viewscreen that is current in the core.</p> +<li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.gui.getCurViewscreen([skip_dismissed])</span></tt></p> +<p>Returns the topmost viewscreen. If <tt class="docutils literal">skip_dismissed</tt> is <em>true</em>, +ignores screens already marked to be removed.</p> </li> <li><p class="first"><tt class="docutils literal">dfhack.gui.getFocusString(viewscreen)</tt></p> <p>Returns a string representation of the current focus position in the ui. The string has a "screen/foo/bar/baz..." format.</p> </li> +<li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.gui.getCurFocus([skip_dismissed])</span></tt></p> +<p>Returns the focus string of the current viewscreen.</p> +</li> <li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.gui.getSelectedWorkshopJob([silent])</span></tt></p> <p>When a job is selected in <em>'q'</em> mode, returns the job, else prints error unless silent and returns <em>nil</em>.</p> @@ -1465,8 +1469,9 @@ interface screens added by dfhack should bear the "DFHack" signature.< <p>Displays the given screen, possibly placing it below a different one. The screen must not be already shown. Returns <em>true</em> if success.</p> </li> -<li><p class="first"><tt class="docutils literal">dfhack.screen.dismiss(screen)</tt></p> -<p>Marks the screen to be removed when the game enters its event loop.</p> +<li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.screen.dismiss(screen[,to_first])</span></tt></p> +<p>Marks the screen to be removed when the game enters its event loop. +If <tt class="docutils literal">to_first</tt> is <em>true</em>, all screens up to the first one will be deleted.</p> </li> <li><p class="first"><tt class="docutils literal">dfhack.screen.isDismissed(screen)</tt></p> <p>Checks if the screen is already marked for removal.</p> @@ -1482,9 +1487,18 @@ that delegates all processing to methods stored in that table.</p> <p>Initialized by <tt class="docutils literal">show</tt> with a reference to the backing viewscreen object, and removed again when the object is deleted.</p> </li> +<li><p class="first"><tt class="docutils literal">function screen:onShow()</tt></p> +<p>Called by <tt class="docutils literal">dfhack.screen.show</tt> if successful.</p> +</li> +<li><p class="first"><tt class="docutils literal">function screen:onDismiss()</tt></p> +<p>Called by <tt class="docutils literal">dfhack.screen.dismiss</tt> if successful.</p> +</li> <li><p class="first"><tt class="docutils literal">function screen:onDestroy()</tt></p> <p>Called from the destructor when the viewscreen is deleted.</p> </li> +<li><p class="first"><tt class="docutils literal">function screen:onResize(w, h)</tt></p> +<p>Called before <tt class="docutils literal">onRender</tt> or <tt class="docutils literal">onIdle</tt> when the window size has changed.</p> +</li> <li><p class="first"><tt class="docutils literal">function screen:onRender()</tt></p> <p>Called when the viewscreen should paint itself. This is the only context where the above painting functions work correctly.</p> diff --git a/library/Core.cpp b/library/Core.cpp index a61fef4e..6a0dea7c 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1260,7 +1260,7 @@ bool Core::ncurses_wgetch(int in, int & out) // FIXME: copypasta, push into a method! if(df::global::ui && df::global::gview) { - df::viewscreen * ws = Gui::GetCurrentScreen(); + df::viewscreen * ws = Gui::getCurViewscreen(); if (strict_virtual_cast<df::viewscreen_dwarfmodest>(ws) && df::global::ui->main.mode != ui_sidebar_mode::Hotkeys && df::global::ui->main.hotkeys[idx].cmd == df::ui_hotkey::T_cmd::None) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index d25da808..35cf1435 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -749,6 +749,7 @@ static const LuaWrapper::FunctionReg dfhack_module[] = { static const LuaWrapper::FunctionReg dfhack_gui_module[] = { WRAPM(Gui, getCurViewscreen), WRAPM(Gui, getFocusString), + WRAPM(Gui, getCurFocus), WRAPM(Gui, getSelectedWorkshopJob), WRAPM(Gui, getSelectedJob), WRAPM(Gui, getSelectedUnit), diff --git a/library/include/modules/Gui.h b/library/include/modules/Gui.h index e7155c43..273d84ce 100644 --- a/library/include/modules/Gui.h +++ b/library/include/modules/Gui.h @@ -55,8 +55,6 @@ namespace DFHack */ namespace Gui { - inline df::viewscreen *getCurViewscreen() { return Core::getTopViewscreen(); } - DFHACK_EXPORT std::string getFocusString(df::viewscreen *top); // Full-screen item details view @@ -113,7 +111,11 @@ namespace DFHack * Gui screens */ /// Get the current top-level view-screen - DFHACK_EXPORT df::viewscreen * GetCurrentScreen(); + DFHACK_EXPORT df::viewscreen *getCurViewscreen(bool skip_dismissed = false); + + inline std::string getCurFocus(bool skip_dismissed = false) { + return getFocusString(getCurViewscreen(skip_dismissed)); + } /// get the size of the window buffer DFHACK_EXPORT bool getWindowSize(int32_t & width, int32_t & height); diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h index ce3f32ed..492e1eec 100644 --- a/library/include/modules/Screen.h +++ b/library/include/modules/Screen.h @@ -112,7 +112,7 @@ namespace DFHack // Push and remove viewscreens DFHACK_EXPORT bool show(df::viewscreen *screen, df::viewscreen *before = NULL); - DFHACK_EXPORT void dismiss(df::viewscreen *screen); + DFHACK_EXPORT void dismiss(df::viewscreen *screen, bool to_first = false); DFHACK_EXPORT bool isDismissed(df::viewscreen *screen); } @@ -136,7 +136,10 @@ namespace DFHack virtual bool key_conflict(df::interface_key key); virtual bool is_lua_screen() { return false; } + virtual std::string getFocusString() = 0; + virtual void onShow() {}; + virtual void onDismiss() {}; }; class DFHACK_EXPORT dfhack_lua_viewscreen : public dfhack_viewscreen { @@ -166,5 +169,8 @@ namespace DFHack virtual void help(); virtual void resize(int w, int h); virtual void feed(std::set<df::interface_key> *keys); + + virtual void onShow(); + virtual void onDismiss(); }; } diff --git a/library/lua/gui.lua b/library/lua/gui.lua index f9a45548..62e393f0 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -232,9 +232,7 @@ function Screen:show(below) error("This screen is already on display") end self:onAboutToShow(below) - if dscreen.show(self, below) then - self:onShown() - else + if not dscreen.show(self, below) then error('Could not show screen') end end @@ -242,17 +240,16 @@ end function Screen:onAboutToShow() end -function Screen:onShown() +function Screen:onShow() end function Screen:dismiss() - if self._native and not dscreen.isDismissed(self) then + if self._native then dscreen.dismiss(self) - self:onDismissed() end end -function Screen:onDismissed() +function Screen:onDismiss() end ------------------------ diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index 9d3ee96e..91a17e99 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -983,17 +983,19 @@ void Gui::showPopupAnnouncement(std::string message, int color, bool bright) world->status.popups.push_back(popup); } -df::viewscreen * Gui::GetCurrentScreen() +df::viewscreen *Gui::getCurViewscreen(bool skip_dismissed) { df::viewscreen * ws = &gview->view; - while(ws) + while (ws && ws->child) + ws = ws->child; + + if (skip_dismissed) { - if(ws->child) - ws = ws->child; - else - return ws; + while (ws && Screen::isDismissed(ws) && ws->parent) + ws = ws->parent; } - return 0; + + return ws; } bool Gui::getViewCoords (int32_t &x, int32_t &y, int32_t &z) diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index 9b6839a4..c2377f2c 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -235,14 +235,26 @@ bool Screen::show(df::viewscreen *screen, df::viewscreen *before) if (screen->child) screen->child->parent = screen; + if (dfhack_viewscreen::is_instance(screen)) + static_cast<dfhack_viewscreen*>(screen)->onShow(); + return true; } -void Screen::dismiss(df::viewscreen *screen) +void Screen::dismiss(df::viewscreen *screen, bool to_first) { CHECK_NULL_POINTER(screen); - screen->breakdown_level = interface_breakdown_types::STOPSCREEN; + if (screen->breakdown_level != interface_breakdown_types::NONE) + return; + + if (to_first) + screen->breakdown_level = interface_breakdown_types::TOFIRST; + else + screen->breakdown_level = interface_breakdown_types::STOPSCREEN; + + if (dfhack_viewscreen::is_instance(screen)) + static_cast<dfhack_viewscreen*>(screen)->onDismiss(); } bool Screen::isDismissed(df::viewscreen *screen) @@ -261,6 +273,8 @@ static std::set<df::viewscreen*> dfhack_screens; dfhack_viewscreen::dfhack_viewscreen() : text_input_mode(false) { dfhack_screens.insert(this); + + last_size = Screen::getWindowSize(); } dfhack_viewscreen::~dfhack_viewscreen() @@ -576,3 +590,15 @@ void dfhack_lua_viewscreen::feed(std::set<df::interface_key> *keys) lua_pushlightuserdata(Lua::Core::State, keys); safe_call_lua(do_input, 1, 0); } + +void dfhack_lua_viewscreen::onShow() +{ + lua_pushstring(Lua::Core::State, "onShow"); + safe_call_lua(do_notify, 1, 0); +} + +void dfhack_lua_viewscreen::onDismiss() +{ + lua_pushstring(Lua::Core::State, "onDismiss"); + safe_call_lua(do_notify, 1, 0); +} diff --git a/scripts/gui/mechanisms.lua b/scripts/gui/mechanisms.lua index fe45d4ac..3b40ffbd 100644 --- a/scripts/gui/mechanisms.lua +++ b/scripts/gui/mechanisms.lua @@ -142,11 +142,8 @@ function MechanismList:onInput(keys) end end -if not df.viewscreen_dwarfmodest:is_instance(dfhack.gui.getCurViewscreen()) then - qerror("This script requires the main dwarfmode view") -end -if df.global.ui.main.mode ~= df.ui_sidebar_mode.QueryBuilding then - qerror("This script requires the 'q' interface mode") +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) |
