input: allow dynamic change of mouse configs

This commit is contained in:
Megamouse 2024-06-26 18:57:41 +02:00
parent a9d53e98de
commit e790842007
10 changed files with 81 additions and 39 deletions

View file

@ -314,9 +314,9 @@ std::unordered_map<Id, Note> create_id_to_note_mapping()
Note id_to_note(Id id)
{
static auto mapping = create_id_to_note_mapping();
auto it = mapping.find(id);
return it != std::end(mapping) ? it->second : Note::Invalid;
static const auto mapping = create_id_to_note_mapping();
const auto it = mapping.find(id);
return it != mapping.cend() ? it->second : Note::Invalid;
}
namespace combo

View file

@ -27,7 +27,7 @@ bool mouse_config::load()
return false;
}
void mouse_config::save() const
void mouse_config::save()
{
fs::pending_file file(cfg_name);
@ -36,6 +36,8 @@ void mouse_config::save() const
file.file.write(to_string());
file.commit();
}
reload_requested = true;
}
cfg::string& mouse_config::get_button(int code)

View file

@ -9,18 +9,20 @@ struct mouse_config final : cfg::node
const std::string cfg_name;
cfg::string mouse_button_1{this, "Button 1", "Mouse Left"};
cfg::string mouse_button_2{this, "Button 2", "Mouse Right"};
cfg::string mouse_button_3{this, "Button 3", "Mouse Middle"};
cfg::string mouse_button_4{this, "Button 4", ""};
cfg::string mouse_button_5{this, "Button 5", ""};
cfg::string mouse_button_6{this, "Button 6", ""};
cfg::string mouse_button_7{this, "Button 7", ""};
cfg::string mouse_button_8{this, "Button 8", ""};
cfg::string mouse_button_1{ this, "Button 1", "Mouse Left", true };
cfg::string mouse_button_2{ this, "Button 2", "Mouse Right", true };
cfg::string mouse_button_3{ this, "Button 3", "Mouse Middle", true };
cfg::string mouse_button_4{ this, "Button 4", "", true };
cfg::string mouse_button_5{ this, "Button 5", "", true };
cfg::string mouse_button_6{ this, "Button 6", "", true };
cfg::string mouse_button_7{ this, "Button 7", "", true };
cfg::string mouse_button_8{ this, "Button 8", "", true };
atomic_t<bool> reload_requested = true;
bool exist() const;
bool load();
void save() const;
void save();
cfg::string& get_button(int code);
};

View file

@ -23,14 +23,7 @@ void basic_mouse_handler::Init(const u32 max_connect)
g_cfg_mouse.from_default();
g_cfg_mouse.load();
m_buttons[CELL_MOUSE_BUTTON_1] = get_mouse_button(g_cfg_mouse.mouse_button_1);
m_buttons[CELL_MOUSE_BUTTON_2] = get_mouse_button(g_cfg_mouse.mouse_button_2);
m_buttons[CELL_MOUSE_BUTTON_3] = get_mouse_button(g_cfg_mouse.mouse_button_3);
m_buttons[CELL_MOUSE_BUTTON_4] = get_mouse_button(g_cfg_mouse.mouse_button_4);
m_buttons[CELL_MOUSE_BUTTON_5] = get_mouse_button(g_cfg_mouse.mouse_button_5);
m_buttons[CELL_MOUSE_BUTTON_6] = get_mouse_button(g_cfg_mouse.mouse_button_6);
m_buttons[CELL_MOUSE_BUTTON_7] = get_mouse_button(g_cfg_mouse.mouse_button_7);
m_buttons[CELL_MOUSE_BUTTON_8] = get_mouse_button(g_cfg_mouse.mouse_button_8);
reload_config();
m_mice.clear();
m_mice.emplace_back(Mouse());
@ -52,6 +45,18 @@ void basic_mouse_handler::Init(const u32 max_connect)
type = mouse_handler::basic;
}
void basic_mouse_handler::reload_config()
{
m_buttons[CELL_MOUSE_BUTTON_1] = get_mouse_button(g_cfg_mouse.mouse_button_1);
m_buttons[CELL_MOUSE_BUTTON_2] = get_mouse_button(g_cfg_mouse.mouse_button_2);
m_buttons[CELL_MOUSE_BUTTON_3] = get_mouse_button(g_cfg_mouse.mouse_button_3);
m_buttons[CELL_MOUSE_BUTTON_4] = get_mouse_button(g_cfg_mouse.mouse_button_4);
m_buttons[CELL_MOUSE_BUTTON_5] = get_mouse_button(g_cfg_mouse.mouse_button_5);
m_buttons[CELL_MOUSE_BUTTON_6] = get_mouse_button(g_cfg_mouse.mouse_button_6);
m_buttons[CELL_MOUSE_BUTTON_7] = get_mouse_button(g_cfg_mouse.mouse_button_7);
m_buttons[CELL_MOUSE_BUTTON_8] = get_mouse_button(g_cfg_mouse.mouse_button_8);
}
/* Sets the target window for the event handler, and also installs an event filter on the target. */
void basic_mouse_handler::SetTargetWindow(QWindow* target)
{
@ -80,6 +85,11 @@ bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev)
// !m_target->isVisible() is a hack since currently a guiless application will STILL inititialize a gsrender (providing a valid target)
if (!m_target || !m_target->isVisible() || target == m_target)
{
if (g_cfg_mouse.reload_requested.exchange(false))
{
reload_config();
}
switch (ev->type())
{
case QEvent::MouseButtonPress:

View file

@ -27,9 +27,10 @@ public:
bool eventFilter(QObject* obj, QEvent* ev) override;
private:
QWindow* m_target = nullptr;
void reload_config();
bool get_mouse_lock_state() const;
static int get_mouse_button(const cfg::string& button);
QWindow* m_target = nullptr;
std::map<u8, int> m_buttons;
};

View file

@ -102,4 +102,6 @@ void raw_mice_config::save()
{
cfg_log.error("Failed to save %s config to '%s' (error=%s)", cfg_id, cfg_name, fs::g_tls_error);
}
reload_requested = true;
}

View file

@ -18,14 +18,14 @@ public:
cfg::_float<10, 1000> mouse_acceleration{ this, "Mouse Acceleration", 100.0f, true };
cfg::string mouse_button_1{this, "Button 1", "Button 1"};
cfg::string mouse_button_2{this, "Button 2", "Button 2"};
cfg::string mouse_button_3{this, "Button 3", "Button 3"};
cfg::string mouse_button_4{this, "Button 4", "Button 4"};
cfg::string mouse_button_5{this, "Button 5", "Button 5"};
cfg::string mouse_button_6{this, "Button 6", ""};
cfg::string mouse_button_7{this, "Button 7", ""};
cfg::string mouse_button_8{this, "Button 8", ""};
cfg::string mouse_button_1{ this, "Button 1", "Button 1", true };
cfg::string mouse_button_2{ this, "Button 2", "Button 2", true };
cfg::string mouse_button_3{ this, "Button 3", "Button 3", true };
cfg::string mouse_button_4{ this, "Button 4", "Button 4", true };
cfg::string mouse_button_5{ this, "Button 5", "Button 5", true };
cfg::string mouse_button_6{ this, "Button 6", "", true };
cfg::string mouse_button_7{ this, "Button 7", "", true };
cfg::string mouse_button_8{ this, "Button 8", "", true };
cfg::string& get_button_by_index(int index);
cfg::string& get_button(int code);
@ -38,6 +38,7 @@ struct raw_mice_config : cfg::node
shared_mutex m_mutex;
static constexpr std::string_view cfg_id = "raw_mouse";
std::array<std::shared_ptr<raw_mouse_config>, 4> players;
atomic_t<bool> reload_requested = false;
bool load();
void save();

View file

@ -35,6 +35,15 @@ u32 g_registered_handlers = 0;
raw_mouse::raw_mouse(u32 index, const std::string& device_name, void* handle, raw_mouse_handler* handler)
: m_index(index), m_device_name(device_name), m_handle(handle), m_handler(handler)
{
reload_config();
}
raw_mouse::~raw_mouse()
{
}
void raw_mouse::reload_config()
{
if (m_index < ::size32(g_cfg_raw_mouse.players))
{
@ -54,10 +63,6 @@ raw_mouse::raw_mouse(u32 index, const std::string& device_name, void* handle, ra
}
}
raw_mouse::~raw_mouse()
{
}
std::pair<int, int> raw_mouse::get_mouse_button(const cfg::string& button)
{
const std::string value = button.to_string();
@ -119,6 +124,11 @@ void raw_mouse::update_values(const RAWMOUSE& state)
// Update window handle and size
update_window_handle();
if (std::exchange(reload_requested, false))
{
reload_config();
}
const auto get_button_pressed = [this](u8 button, int button_flags)
{
const auto& [down, up] = ::at32(m_buttons, button);
@ -142,6 +152,9 @@ void raw_mouse::update_values(const RAWMOUSE& state)
get_button_pressed(CELL_MOUSE_BUTTON_3, state.usButtonFlags);
get_button_pressed(CELL_MOUSE_BUTTON_4, state.usButtonFlags);
get_button_pressed(CELL_MOUSE_BUTTON_5, state.usButtonFlags);
get_button_pressed(CELL_MOUSE_BUTTON_6, state.usButtonFlags);
get_button_pressed(CELL_MOUSE_BUTTON_7, state.usButtonFlags);
get_button_pressed(CELL_MOUSE_BUTTON_8, state.usButtonFlags);
// Get mouse wheel
if ((state.usButtonFlags & RI_MOUSE_WHEEL))
@ -556,6 +569,14 @@ void raw_mouse_handler::handle_native_event(const MSG& msg)
{
std::lock_guard lock(m_raw_mutex);
if (g_cfg_raw_mouse.reload_requested.exchange(false))
{
for (auto& [handle, mouse] : m_raw_mice)
{
mouse.request_reload();
}
}
if (auto it = m_raw_mice.find(raw_input.header.hDevice); it != m_raw_mice.end())
{
it->second.update_values(raw_input.data.mouse);

View file

@ -43,8 +43,10 @@ public:
const std::string& device_name() const { return m_device_name; }
u32 index() const { return m_index; }
void set_index(u32 index) { m_index = index; }
void request_reload() { reload_requested = true; }
private:
void reload_config();
static std::pair<int, int> get_mouse_button(const cfg::string& button);
u32 m_index = 0;
@ -60,6 +62,7 @@ private:
float m_mouse_acceleration = 1.0f;
raw_mouse_handler* m_handler{};
std::map<u8, std::pair<int, int>> m_buttons;
bool reload_requested = false;
};
class raw_mouse_handler final : public MouseHandlerBase

View file

@ -748,9 +748,9 @@ skylander_dialog* skylander_dialog::get_dlg(QWidget* parent)
void skylander_dialog::clear_skylander(u8 slot)
{
if (auto slot_infos = sky_slots[slot])
if (const auto& slot_infos = sky_slots[slot])
{
auto [cur_slot, id, var] = slot_infos.value();
const auto& [cur_slot, id, var] = slot_infos.value();
g_skyportal.remove_skylander(cur_slot);
sky_slots[slot] = {};
update_edits();
@ -811,10 +811,10 @@ void skylander_dialog::update_edits()
for (auto i = 0; i < UI_SKY_NUM; i++)
{
QString display_string;
if (auto sd = sky_slots[i])
if (const auto& sd = sky_slots[i])
{
auto [portal_slot, sky_id, sky_var] = sd.value();
auto found_sky = list_skylanders.find(std::make_pair(sky_id, sky_var));
const auto& [portal_slot, sky_id, sky_var] = sd.value();
const auto found_sky = list_skylanders.find(std::make_pair(sky_id, sky_var));
if (found_sky != list_skylanders.end())
{
display_string = QString::fromStdString(found_sky->second);