mousequery plugin with TWBT modifications

develop
Vitaly Pronkin 2018-05-25 01:07:12 +12:00
parent c2964e72e8
commit 0217916568
4 changed files with 232 additions and 127 deletions

@ -127,6 +127,12 @@ DFhackCExport int SDL_PushEvent(SDL::Event* event)
return _SDL_PushEvent(event);
}
static unsigned char* (*_SDL_GetKeyState)(int *numkeys) = 0;
DFhackCExport unsigned char* SDL_GetKeyState(int *numkeys)
{
return _SDL_GetKeyState(numkeys);
}
struct WINDOW;
DFhackCExport int DFH_wgetch(WINDOW *win)
{
@ -291,6 +297,7 @@ DFhackCExport int DFH_SDL_Init(uint32_t flags)
bind(SDL_Quit);
bind(SDL_PollEvent);
bind(SDL_PushEvent);
bind(SDL_GetKeyState);
bind(SDL_UpperBlit);
bind(SDL_CreateRGBSurface);

@ -58,6 +58,7 @@ DFhackCExport int SDL_NumJoysticks(void);
DFhackCExport void SDL_Quit(void);
DFhackCExport int SDL_PollEvent(SDL::Event* event);
DFhackCExport int SDL_PushEvent(SDL::Event* event);
DFhackCExport unsigned char* SDL_GetKeyState(int *numkeys);
DFhackCExport int SDL_Init(uint32_t flags);
DFhackCExport int wgetch(WINDOW * win);

@ -136,7 +136,11 @@ if (BUILD_SUPPORTED)
DFHACK_PLUGIN(manipulator manipulator.cpp)
DFHACK_PLUGIN(misery misery.cpp)
DFHACK_PLUGIN(mode mode.cpp)
IF(UNIX AND NOT APPLE)
DFHACK_PLUGIN(mousequery mousequery.cpp LINK_LIBRARIES SDL)
ELSE()
DFHACK_PLUGIN(mousequery mousequery.cpp)
ENDIF()
DFHACK_PLUGIN(orders orders.cpp LINK_LIBRARIES jsoncpp)
DFHACK_PLUGIN(pathable pathable.cpp LINK_LIBRARIES lua)
DFHACK_PLUGIN(petcapRemover petcapRemover.cpp)

@ -21,6 +21,10 @@
#include "TileTypes.h"
#include "DataFuncs.h"
// For SDL_GetKeyState
#include "Hooks.h"
#include "SDL_keyboard.h"
DFHACK_PLUGIN("mousequery");
REQUIRE_GLOBAL(enabler);
REQUIRE_GLOBAL(gps);
@ -48,6 +52,9 @@ static bool mouse_moved = false;
static uint32_t scroll_delay = 100;
static bool awaiting_lbut_up, awaiting_rbut_up;
static enum { None, Left, Right } drag_mode;
static df::coord get_mouse_pos(int32_t &mx, int32_t &my)
{
df::coord pos;
@ -293,16 +300,15 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest
return false;
}
bool handleMouse(const set<df::interface_key> *input)
bool handleLeft(df::coord &mpos, int32_t mx, int32_t my)
{
int32_t mx, my;
auto mpos = get_mouse_pos(mx, my);
if (mpos.x == -30000)
return false;
static unsigned char *keystate = 0;
if (!keystate)
keystate = SDL_GetKeyState(NULL);
if (!(keystate[SDL::Key::K_LSHIFT] || keystate[SDL::Key::K_RSHIFT]))
mpos.z += Gui::getDepthAt(mx, my);
auto dims = Gui::getDwarfmodeViewDims();
if (enabler->mouse_lbut)
{
bool cursor_still_here = (last_clicked_x == mpos.x && last_clicked_y == mpos.y && last_clicked_z == mpos.z);
last_clicked_x = mpos.x;
last_clicked_y = mpos.y;
@ -370,6 +376,7 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest
// Can't check limits earlier as we must be sure we are in query or default mode
// (so we can clear the button down flag)
auto dims = Gui::getDwarfmodeViewDims();
int right_bound = (dims.menu_x1 > 0) ? dims.menu_x1 - 2 : gps->dimx - 2;
if (mx < 1 || mx > right_bound || my < 1 || my > gps->dimy - 2)
return false;
@ -411,7 +418,8 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest
return true;
}
else if (rbutton_enabled && enabler->mouse_rbut)
bool handleRight(df::coord &mpos, int32_t mx, int32_t my)
{
if (isInDesignationMenu() && !box_designation_enabled)
return false;
@ -429,6 +437,7 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest
}
else
{
auto dims = Gui::getDwarfmodeViewDims();
int scroll_trigger_x = dims.menu_x1 / 3;
int scroll_trigger_y = gps->dimy / 3;
if (mx < scroll_trigger_x)
@ -443,6 +452,38 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest
if (my > gps->dimy - scroll_trigger_y)
sendKey(interface_key::CURSOR_DOWN_FAST);
}
return false;
}
bool handleMouse(const set<df::interface_key> *input)
{
int32_t mx, my;
auto mpos = get_mouse_pos(mx, my);
if (mpos.x == -30000)
return false;
if (enabler->mouse_lbut)
{
if (drag_mode == Left)
{
awaiting_lbut_up = true;
enabler->mouse_lbut = false;
last_move_pos = mpos;
}
else
return handleLeft(mpos, mx, my);
}
else if (enabler->mouse_rbut)
{
if (drag_mode == Right)
{
awaiting_rbut_up = true;
enabler->mouse_rbut = false;
last_move_pos = mpos;
}
else if (rbutton_enabled)
return handleRight(mpos, mx, my);
}
else if (input->count(interface_key::CUSTOM_ALT_M) && isInDesignationMenu())
{
@ -554,10 +595,39 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest
return;
}
if (awaiting_lbut_up && !enabler->mouse_lbut_down)
{
awaiting_lbut_up = false;
handleLeft(mpos, mx, my);
}
if (awaiting_rbut_up && !enabler->mouse_rbut_down)
{
awaiting_rbut_up = false;
if (rbutton_enabled)
handleRight(mpos, mx, my);
}
if (mpos_valid)
{
if (mpos.x != last_move_pos.x || mpos.y != last_move_pos.y || mpos.z != last_move_pos.z)
{
awaiting_lbut_up = false;
awaiting_rbut_up = false;
if ((enabler->mouse_lbut_down && drag_mode == Left) || (enabler->mouse_rbut_down && drag_mode == Right))
{
int newx = (*df::global::window_x) - (mpos.x - last_move_pos.x);
int newy = (*df::global::window_y) - (mpos.y - last_move_pos.y);
newx = std::max(0, std::min(newx, world->map.x_count - dims.map_x2+1));
newy = std::max(0, std::min(newy, world->map.y_count - dims.map_y2+1));
(*df::global::window_x) = newx;
(*df::global::window_y) = newy;
return;
}
mouse_moved = true;
last_move_pos = mpos;
}
@ -677,6 +747,10 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest
return;
}
// Don't change levels
if (mpos.z != *df::global::window_z)
return;
last_t = enabler->clock;
moveCursor(mpos, false);
}
@ -699,6 +773,14 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest
set_to_limit(look_list, 8);
int disp_y = gps->dimy - look_list - 2;
if (mpos.z != *df::global::window_z)
{
int y = gps->dimy - 2;
char buf[6];
sprintf(buf, "@%d", mpos.z - *df::global::window_z);
OutputString(COLOR_GREY, disp_x, y, buf, true, left_margin);
}
int c = 0;
for (auto it = ulist.begin(); it != ulist.end() && c < 8; it++, c++)
{
@ -783,6 +865,15 @@ static command_result mousequery_cmd(color_ostream &out, vector <string> & param
{
live_view = (state == "enable");
}
else if (cmd == "drag")
{
if (state == "left")
drag_mode = Left;
else if (state == "right")
drag_mode = Right;
else if (state == "disable")
drag_mode = None;
}
else if (cmd[0] == 'd')
{
auto l = atoi(state.c_str());
@ -828,12 +919,14 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <Plug
PluginCommand(
"mousequery", "Add mouse functionality to Dwarf Fortress",
mousequery_cmd, false,
"mousequery [plugin|rbutton|track|edge|live] [enabled|disabled]\n"
"mousequery [plugin|rbutton|track|edge|live] [enable|disable]\n"
" plugin: enable/disable the entire plugin\n"
" rbutton: enable/disable right mouse button\n"
" track: enable/disable moving cursor in build and designation mode\n"
" edge: enable/disable active edge scrolling (when on, will also enable tracking)\n"
" live: enable/disable query view when unpaused\n\n"
"mousequery drag [left|right|disable]\n"
" Enable/disable map dragging with the specified mouse button\n\n"
"mousequery delay <amount>\n"
" Set delay when edge scrolling in tracking mode. Omit amount to display current setting.\n"
));