mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-01 01:09:04 +01:00
feat(editor): scripted mouse and keys of a self-test are delivered between frames like real input events, so a press seen by ImGui starts a drag as it does by hand; while a script drives the input the real mouse and keyboard are ignored
This commit is contained in:
@@ -80,6 +80,8 @@ void focus_callback(GLFWwindow *window, int focus)
|
|||||||
|
|
||||||
void cursor_enter_callback(GLFWwindow *window, int entered)
|
void cursor_enter_callback(GLFWwindow *window, int entered)
|
||||||
{
|
{
|
||||||
|
if (scripted_input::driving())
|
||||||
|
return;
|
||||||
ui_layer::cursor_enter_callback(entered);
|
ui_layer::cursor_enter_callback(entered);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,6 +98,8 @@ void window_resize_callback(GLFWwindow *, int w, int h)
|
|||||||
|
|
||||||
void cursor_pos_callback(GLFWwindow *window, double x, double y)
|
void cursor_pos_callback(GLFWwindow *window, double x, double y)
|
||||||
{
|
{
|
||||||
|
if (scripted_input::driving())
|
||||||
|
return;
|
||||||
ui_layer::cursor_pos_callback(x, y);
|
ui_layer::cursor_pos_callback(x, y);
|
||||||
Global.cursor_pos = glm::ivec2(x, y);
|
Global.cursor_pos = glm::ivec2(x, y);
|
||||||
Application.on_cursor_pos(x, y);
|
Application.on_cursor_pos(x, y);
|
||||||
@@ -103,22 +107,30 @@ void cursor_pos_callback(GLFWwindow *window, double x, double y)
|
|||||||
|
|
||||||
void mouse_button_callback(GLFWwindow *window, int button, int action, int mods)
|
void mouse_button_callback(GLFWwindow *window, int button, int action, int mods)
|
||||||
{
|
{
|
||||||
|
if (scripted_input::driving())
|
||||||
|
return;
|
||||||
Application.on_mouse_button(button, action, mods);
|
Application.on_mouse_button(button, action, mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset)
|
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset)
|
||||||
{
|
{
|
||||||
|
if (scripted_input::driving())
|
||||||
|
return;
|
||||||
Application.on_scroll(xoffset, yoffset);
|
Application.on_scroll(xoffset, yoffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||||
{
|
{
|
||||||
|
if (scripted_input::driving())
|
||||||
|
return;
|
||||||
|
|
||||||
Application.on_key(key, scancode, action, mods);
|
Application.on_key(key, scancode, action, mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
void char_callback(GLFWwindow *window, unsigned int c)
|
void char_callback(GLFWwindow *window, unsigned int c)
|
||||||
{
|
{
|
||||||
|
if (scripted_input::driving())
|
||||||
|
return;
|
||||||
Application.on_char(c);
|
Application.on_char(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6232,6 +6232,7 @@ void editor_mode::render_change_history(){
|
|||||||
|
|
||||||
void editor_mode::on_event_poll()
|
void editor_mode::on_event_poll()
|
||||||
{
|
{
|
||||||
|
m_selftest.input.deliver();
|
||||||
// game-engine style camera: WSAD/EQ only fly the camera while the right mouse button is held.
|
// game-engine style camera: WSAD/EQ only fly the camera while the right mouse button is held.
|
||||||
// when it's released the keyboard is free for gizmo shortcuts, and we flush a zero-movement
|
// when it's released the keyboard is free for gizmo shortcuts, and we flush a zero-movement
|
||||||
// command once so the camera doesn't keep coasting on the last velocity it was given.
|
// command once so the camera doesn't keep coasting on the last velocity it was given.
|
||||||
|
|||||||
@@ -46,24 +46,41 @@ int modifier_of(int const Key)
|
|||||||
return Key == GLFW_KEY_LEFT_CONTROL ? GLFW_MOD_CONTROL : Key == GLFW_KEY_LEFT_SHIFT ? GLFW_MOD_SHIFT : Key == GLFW_KEY_LEFT_ALT ? GLFW_MOD_ALT : 0;
|
return Key == GLFW_KEY_LEFT_CONTROL ? GLFW_MOD_CONTROL : Key == GLFW_KEY_LEFT_SHIFT ? GLFW_MOD_SHIFT : Key == GLFW_KEY_LEFT_ALT ? GLFW_MOD_ALT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
void modifiers(int const Mods)
|
||||||
|
|
||||||
void scripted_input::modifiers() const
|
|
||||||
{
|
{
|
||||||
auto &io{ImGui::GetIO()};
|
auto &io{ImGui::GetIO()};
|
||||||
io.AddKeyEvent(ImGuiMod_Ctrl, (m_mods & GLFW_MOD_CONTROL) != 0);
|
io.AddKeyEvent(ImGuiMod_Ctrl, (Mods & GLFW_MOD_CONTROL) != 0);
|
||||||
io.AddKeyEvent(ImGuiMod_Shift, (m_mods & GLFW_MOD_SHIFT) != 0);
|
io.AddKeyEvent(ImGuiMod_Shift, (Mods & GLFW_MOD_SHIFT) != 0);
|
||||||
io.AddKeyEvent(ImGuiMod_Alt, (m_mods & GLFW_MOD_ALT) != 0);
|
io.AddKeyEvent(ImGuiMod_Alt, (Mods & GLFW_MOD_ALT) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void scripted_input::queue(std::function<void()> Event)
|
||||||
|
{
|
||||||
|
s_driving = true;
|
||||||
|
m_events.emplace_back(std::move(Event));
|
||||||
|
}
|
||||||
|
|
||||||
|
void scripted_input::deliver()
|
||||||
|
{
|
||||||
|
auto const events{std::move(m_events)};
|
||||||
|
m_events.clear();
|
||||||
|
for (auto const &event : events)
|
||||||
|
event();
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripted_input::mouse_to(glm::dvec2 const &Screen)
|
void scripted_input::mouse_to(glm::dvec2 const &Screen)
|
||||||
{
|
{
|
||||||
if (false == m_mouse.has_value())
|
bool const entered{m_mouse.has_value()};
|
||||||
ui_layer::cursor_enter_callback(1);
|
|
||||||
m_mouse = Screen;
|
m_mouse = Screen;
|
||||||
ui_layer::cursor_pos_callback(Screen.x, Screen.y);
|
queue([Screen, entered]() {
|
||||||
Global.cursor_pos = glm::ivec2(Screen);
|
if (false == entered)
|
||||||
Application.on_cursor_pos(Screen.x, Screen.y);
|
ui_layer::cursor_enter_callback(1);
|
||||||
|
ui_layer::cursor_pos_callback(Screen.x, Screen.y);
|
||||||
|
Global.cursor_pos = glm::ivec2(Screen);
|
||||||
|
Application.on_cursor_pos(Screen.x, Screen.y);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool scripted_input::dispatch(std::string const &Command, std::istringstream &Words)
|
bool scripted_input::dispatch(std::string const &Command, std::istringstream &Words)
|
||||||
@@ -82,16 +99,21 @@ bool scripted_input::dispatch(std::string const &Command, std::istringstream &Wo
|
|||||||
std::string action;
|
std::string action;
|
||||||
Words >> which >> action;
|
Words >> which >> action;
|
||||||
auto const button{which == "right" ? GLFW_MOUSE_BUTTON_RIGHT : which == "middle" ? GLFW_MOUSE_BUTTON_MIDDLE : GLFW_MOUSE_BUTTON_LEFT};
|
auto const button{which == "right" ? GLFW_MOUSE_BUTTON_RIGHT : which == "middle" ? GLFW_MOUSE_BUTTON_MIDDLE : GLFW_MOUSE_BUTTON_LEFT};
|
||||||
Application.on_mouse_button(button, action == "release" ? GLFW_RELEASE : GLFW_PRESS, m_mods);
|
auto const state{action == "release" ? GLFW_RELEASE : GLFW_PRESS};
|
||||||
modifiers();
|
queue([button, state, mods = m_mods]() {
|
||||||
|
Application.on_mouse_button(button, state, mods);
|
||||||
|
modifiers(mods);
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Command == "wheel")
|
if (Command == "wheel")
|
||||||
{
|
{
|
||||||
double offset{0.0};
|
double offset{0.0};
|
||||||
Words >> offset;
|
Words >> offset;
|
||||||
Application.on_scroll(0.0, offset);
|
queue([offset, mods = m_mods]() {
|
||||||
modifiers();
|
Application.on_scroll(0.0, offset);
|
||||||
|
modifiers(mods);
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Command == "press" || Command == "release" || Command == "tap")
|
if (Command == "press" || Command == "release" || Command == "tap")
|
||||||
@@ -107,14 +129,18 @@ bool scripted_input::dispatch(std::string const &Command, std::istringstream &Wo
|
|||||||
if (Command != "release")
|
if (Command != "release")
|
||||||
{
|
{
|
||||||
m_mods |= modifier_of(key);
|
m_mods |= modifier_of(key);
|
||||||
Application.on_key(key, 0, GLFW_PRESS, m_mods);
|
queue([key, mods = m_mods]() {
|
||||||
modifiers();
|
Application.on_key(key, 0, GLFW_PRESS, mods);
|
||||||
|
modifiers(mods);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (Command != "press")
|
if (Command != "press")
|
||||||
{
|
{
|
||||||
m_mods &= ~modifier_of(key);
|
m_mods &= ~modifier_of(key);
|
||||||
Application.on_key(key, 0, GLFW_RELEASE, m_mods);
|
queue([key, mods = m_mods]() {
|
||||||
modifiers();
|
Application.on_key(key, 0, GLFW_RELEASE, mods);
|
||||||
|
modifiers(mods);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -129,7 +155,7 @@ bool scripted_input::dispatch(std::string const &Command, std::istringstream &Wo
|
|||||||
unsigned int code{extra == 0 ? lead : lead & (0x3Fu >> extra)};
|
unsigned int code{extra == 0 ? lead : lead & (0x3Fu >> extra)};
|
||||||
for (int k = 1; k <= extra && index + k < text.size(); ++k)
|
for (int k = 1; k <= extra && index + k < text.size(); ++k)
|
||||||
code = (code << 6) | (static_cast<unsigned char>(text[index + k]) & 0x3Fu);
|
code = (code << 6) | (static_cast<unsigned char>(text[index + k]) & 0x3Fu);
|
||||||
Application.on_char(code);
|
queue([code]() { Application.on_char(code); });
|
||||||
index += extra + 1;
|
index += extra + 1;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -20,16 +21,23 @@ class scripted_input
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool dispatch(std::string const &Command, std::istringstream &Words);
|
bool dispatch(std::string const &Command, std::istringstream &Words);
|
||||||
|
void deliver();
|
||||||
void mouse_to(glm::dvec2 const &Screen);
|
void mouse_to(glm::dvec2 const &Screen);
|
||||||
std::optional<glm::dvec2> const &mouse() const
|
std::optional<glm::dvec2> const &mouse() const
|
||||||
{
|
{
|
||||||
return m_mouse;
|
return m_mouse;
|
||||||
}
|
}
|
||||||
|
static bool driving()
|
||||||
|
{
|
||||||
|
return s_driving;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void modifiers() const;
|
void queue(std::function<void()> Event);
|
||||||
std::optional<glm::dvec2> m_mouse;
|
std::optional<glm::dvec2> m_mouse;
|
||||||
int m_mods{0};
|
int m_mods{0};
|
||||||
|
std::vector<std::function<void()>> m_events;
|
||||||
|
static inline bool s_driving{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
class input_script
|
class input_script
|
||||||
@@ -37,6 +45,10 @@ class input_script
|
|||||||
public:
|
public:
|
||||||
explicit input_script(char const *Variable) : m_variable{Variable} {}
|
explicit input_script(char const *Variable) : m_variable{Variable} {}
|
||||||
void step();
|
void step();
|
||||||
|
void deliver()
|
||||||
|
{
|
||||||
|
m_input.deliver();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char const *m_variable;
|
char const *m_variable;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public:
|
|||||||
void on_mouse_button( int const Button, int const Action, int const Mods ) override { /* not handled by the launcher */ }
|
void on_mouse_button( int const Button, int const Action, int const Mods ) override { /* not handled by the launcher */ }
|
||||||
void on_scroll( double const Xoffset, double const Yoffset ) override { /* not handled by the launcher */ }
|
void on_scroll( double const Xoffset, double const Yoffset ) override { /* not handled by the launcher */ }
|
||||||
void on_window_resize( int w, int h ) override;
|
void on_window_resize( int w, int h ) override;
|
||||||
void on_event_poll() override { /* not handled by the launcher */ }
|
void on_event_poll() override { m_script.deliver(); }
|
||||||
bool is_command_processor() const override { return false; }
|
bool is_command_processor() const override { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user