From ad7de34d3f1247e87ad46c2e373099c948ce7145 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 16 Sep 2022 12:15:01 -0700 Subject: [PATCH] add clickable overlay to title screen --- plugins/CMakeLists.txt | 1 + plugins/overlay.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 plugins/overlay.cpp diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 49e704b75..dc341b39d 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -144,6 +144,7 @@ if(BUILD_SUPPORTED) dfhack_plugin(mousequery mousequery.cpp) dfhack_plugin(nestboxes nestboxes.cpp) dfhack_plugin(orders orders.cpp LINK_LIBRARIES jsoncpp_static) + dfhack_plugin(overlay overlay.cpp) dfhack_plugin(pathable pathable.cpp LINK_LIBRARIES lua) dfhack_plugin(petcapRemover petcapRemover.cpp) dfhack_plugin(plants plants.cpp) diff --git a/plugins/overlay.cpp b/plugins/overlay.cpp new file mode 100644 index 000000000..42241aec6 --- /dev/null +++ b/plugins/overlay.cpp @@ -0,0 +1,80 @@ +#include "df/viewscreen_titlest.h" + +#include "modules/Gui.h" + +#include "PluginManager.h" +#include "VTableInterpose.h" +#include "uicommon.h" + +using namespace DFHack; + +DFHACK_PLUGIN("overlay"); +DFHACK_PLUGIN_IS_ENABLED(is_enabled); +REQUIRE_GLOBAL(enabler); +REQUIRE_GLOBAL(gps); + +static const std::string button_text = "[ DFHack Launcher ]"; +static bool clicked = false; + +static bool handle_click() { + int32_t x, y; + if (!enabler->tracking_on || !enabler->mouse_lbut || clicked || + !Gui::getMousePos(x, y)) + return false; + if (y == gps->dimy - 1 && x >= 1 && (size_t)x <= button_text.size()) { + clicked = true; + Core::getInstance().setHotkeyCmd("gui/launcher"); + return true; + } + return false; +} + +static void draw_widgets() { + int x = 1; + int y = gps->dimy - 1; + OutputString(COLOR_GREEN, x, y, button_text); +} + +struct title_hook : df::viewscreen_titlest { + typedef df::viewscreen_titlest interpose_base; + + DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) { + if (!handle_click()) + INTERPOSE_NEXT(feed)(input); + } + DEFINE_VMETHOD_INTERPOSE(void, render, ()) { + INTERPOSE_NEXT(render)(); + draw_widgets(); + } +}; +IMPLEMENT_VMETHOD_INTERPOSE(title_hook, feed); +IMPLEMENT_VMETHOD_INTERPOSE(title_hook, render); + +DFhackCExport command_result plugin_onstatechange(color_ostream &, + state_change_event evt) { + if (evt == SC_VIEWSCREEN_CHANGED) { + clicked = false; + } + return CR_OK; +} + +DFhackCExport command_result plugin_enable(color_ostream &, bool enable) { + if (is_enabled == enable) + return CR_OK; + if (enable != is_enabled) { + if (!INTERPOSE_HOOK(title_hook, feed).apply(enable) || + !INTERPOSE_HOOK(title_hook, render).apply(enable)) + return CR_FAILURE; + + is_enabled = enable; + } + return CR_OK; +} + +DFhackCExport command_result plugin_init(color_ostream &out, std::vector &) { + return plugin_enable(out, true); +} + +DFhackCExport command_result plugin_shutdown(color_ostream &out) { + return plugin_enable(out, false); +}