Merge pull request #2813 from myk002/myk_zscreen_focus_fallthrough

allow focus string generation to fall through unfocused ZScreens
develop
Myk 2023-02-05 20:07:52 -08:00 committed by GitHub
commit 4ab3629abc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 9 deletions

@ -974,10 +974,11 @@ Screens
the specified type (e.g. ``df.viewscreen_titlest``), or ``nil`` if none match.
If ``depth`` is not specified or is less than 1, all viewscreens are checked.
* ``dfhack.gui.getDFViewscreen([skip_dismissed])``
* ``dfhack.gui.getDFViewscreen([skip_dismissed[, viewscreen]])``
Returns the topmost viewscreen not owned by DFHack. If ``skip_dismissed`` is
``true``, ignores screens already marked to be removed.
``true``, ignores screens already marked to be removed. If ``viewscreen`` is
specified, starts the scan at the given viewscreen.
General-purpose selections
~~~~~~~~~~~~~~~~~~~~~~~~~~

@ -189,7 +189,7 @@ namespace DFHack
DFHACK_EXPORT df::viewscreen *getViewscreenByIdentity(virtual_identity &id, int n = 1);
/// Get the top-most underlying DF viewscreen (not owned by DFHack)
DFHACK_EXPORT df::viewscreen *getDFViewscreen(bool skip_dismissed = false);
DFHACK_EXPORT df::viewscreen *getDFViewscreen(bool skip_dismissed = false, df::viewscreen *top = NULL);
/// Get the top-most viewscreen of the given type from the top `n` viewscreens (or all viewscreens if n < 1)
/// returns NULL if none match

@ -351,6 +351,7 @@ namespace DFHack
virtual bool is_lua_screen() { return false; }
virtual bool isFocused() { return true; }
virtual std::string getFocusString() = 0;
virtual void onShow() {};
virtual void onDismiss() {};
@ -365,6 +366,7 @@ namespace DFHack
class DFHACK_EXPORT dfhack_lua_viewscreen : public dfhack_viewscreen {
std::string focus;
bool defocused = false;
void update_focus(lua_State *L, int idx);
@ -384,6 +386,7 @@ namespace DFHack
static df::viewscreen *get_pointer(lua_State *L, int idx, bool make);
virtual bool is_lua_screen() { return true; }
virtual bool isFocused() { return !defocused; }
virtual std::string getFocusString() { return focus; }
virtual void render();

@ -484,6 +484,12 @@ bool Gui::matchFocusString(std::string focusString, bool prefixMatch) {
}) != currentFocusStrings.end();
}
static void push_dfhack_focus_string(dfhack_viewscreen *vs, std::vector<std::string> &focusStrings)
{
auto name = vs->getFocusString();
focusStrings.push_back(name.empty() ? "dfhack" : "dfhack/" + name);
}
std::vector<std::string> Gui::getFocusStrings(df::viewscreen* top)
{
std::vector<std::string> focusStrings;
@ -493,10 +499,21 @@ std::vector<std::string> Gui::getFocusStrings(df::viewscreen* top)
if (dfhack_viewscreen::is_instance(top))
{
auto name = static_cast<dfhack_viewscreen*>(top)->getFocusString();
focusStrings.push_back(name.empty() ? "dfhack" : "dfhack/" + name);
dfhack_viewscreen *vs = static_cast<dfhack_viewscreen*>(top);
if (vs->isFocused())
{
push_dfhack_focus_string(vs, focusStrings);
return focusStrings;
}
else if (virtual_identity *id = virtual_identity::get(top))
top = Gui::getDFViewscreen(top);
if (dfhack_viewscreen::is_instance(top))
{
push_dfhack_focus_string(static_cast<dfhack_viewscreen*>(top), focusStrings);
return focusStrings;
}
}
if (virtual_identity *id = virtual_identity::get(top))
{
std::string name = getNameChunk(id, 11, 2);
@ -504,7 +521,8 @@ std::vector<std::string> Gui::getFocusStrings(df::viewscreen* top)
if (handler)
handler(name, focusStrings, top);
}
else
if (!focusStrings.size())
{
Core &core = Core::getInstance();
std::string name = core.p->readClassName(*(void**)top);
@ -1865,8 +1883,9 @@ df::viewscreen *Gui::getViewscreenByIdentity (virtual_identity &id, int n)
return NULL;
}
df::viewscreen *Gui::getDFViewscreen(bool skip_dismissed) {
df::viewscreen *screen = Gui::getCurViewscreen(skip_dismissed);
df::viewscreen *Gui::getDFViewscreen(bool skip_dismissed, df::viewscreen *screen) {
if (!screen)
screen = Gui::getCurViewscreen(skip_dismissed);
while (screen && dfhack_viewscreen::is_instance(screen)) {
screen = screen->parent;
if (skip_dismissed)

@ -865,6 +865,9 @@ void dfhack_lua_viewscreen::update_focus(lua_State *L, int idx)
lua_getfield(L, idx, "allow_options");
allow_options = lua_toboolean(L, -1);
lua_pop(L, 1);
lua_getfield(L, idx, "defocused");
defocused = lua_toboolean(L, -1);
lua_pop(L, 1);
lua_getfield(L, idx, "focus_path");
auto str = lua_tostring(L, -1);
@ -1081,6 +1084,7 @@ using df::identity_traits;
#define CUR_STRUCT dfhack_viewscreen
static const struct_field_info dfhack_viewscreen_fields[] = {
{ METHOD(OBJ_METHOD, is_lua_screen), 0, 0 },
{ METHOD(OBJ_METHOD, isFocused), 0, 0 },
{ METHOD(OBJ_METHOD, getFocusString), 0, 0 },
{ METHOD(OBJ_METHOD, onShow), 0, 0 },
{ METHOD(OBJ_METHOD, onDismiss), 0, 0 },