#include "controller_presets.h" #include #include "cfg/button.h" namespace overlay::windows { // helpers - iterate all button groups static void count_buttons_in(const std::vector &btns, int &naive, int &device) { for (auto &btn : btns) { if (btn.primary.is_naive()) naive++; if (btn.primary.is_device()) device++; for (auto &alt : btn.alternatives) { if (alt.is_naive()) naive++; if (alt.is_device()) device++; } } } int ControllerTemplate::count_naive_buttons() const { int naive = 0, device = 0; count_buttons_in(buttons, naive, device); count_buttons_in(modifier_buttons, naive, device); count_buttons_in(keypad_buttons, naive, device); return naive; } int ControllerTemplate::count_device_buttons() const { int naive = 0, device = 0; count_buttons_in(buttons, naive, device); count_buttons_in(modifier_buttons, naive, device); count_buttons_in(keypad_buttons, naive, device); return device; } int ControllerTemplate::count_device_analogs() const { int count = 0; for (auto &a : analogs) { if (a.is_device()) count++; } return count; } int ControllerTemplate::count_device_lights() const { int count = 0; for (auto &l : lights) { if (l.primary.is_device()) count++; for (auto &alt : l.alternatives) { if (alt.is_device()) count++; } } return count; } static void collect_devices_from(const std::vector &btns, std::set &devices) { for (auto &btn : btns) { if (btn.primary.is_device()) devices.insert(btn.primary.device_identifier); for (auto &alt : btn.alternatives) { if (alt.is_device()) devices.insert(alt.device_identifier); } } } std::set ControllerTemplate::get_used_devices() const { std::set devices; collect_devices_from(buttons, devices); collect_devices_from(modifier_buttons, devices); collect_devices_from(keypad_buttons, devices); for (auto &a : analogs) { if (a.is_device()) devices.insert(a.device_identifier); } for (auto &l : lights) { if (l.primary.is_device()) devices.insert(l.primary.device_identifier); for (auto &alt : l.alternatives) { if (alt.is_device()) devices.insert(alt.device_identifier); } } return devices; } static void collect_sources_from(const std::vector &btns, std::set &sources_set, bool &has_naive) { for (auto &btn : btns) { if (btn.primary.is_naive()) has_naive = true; if (btn.primary.is_device()) sources_set.insert(btn.primary.device_identifier); for (auto &alt : btn.alternatives) { if (alt.is_naive()) has_naive = true; if (alt.is_device()) sources_set.insert(alt.device_identifier); } } } std::vector ControllerTemplate::get_binding_sources() const { std::set sources_set; bool has_naive = false; collect_sources_from(buttons, sources_set, has_naive); collect_sources_from(modifier_buttons, sources_set, has_naive); collect_sources_from(keypad_buttons, sources_set, has_naive); for (auto &a : analogs) { if (a.is_device()) { sources_set.insert(a.device_identifier); } } for (auto &l : lights) { if (l.primary.is_device()) sources_set.insert(l.primary.device_identifier); for (auto &alt : l.alternatives) { if (alt.is_device()) sources_set.insert(alt.device_identifier); } } std::vector result; if (has_naive) { result.emplace_back("Naive"); } for (auto &s : sources_set) { result.push_back(s); } // sort alphabetically std::sort(result.begin(), result.end()); return result; } void ControllerTemplate::rename_source(const std::string &old_id, const std::string &new_id) { auto rename_in_buttons = [&](std::vector &btns) { for (auto &btn : btns) { if (btn.primary.device_identifier == old_id) btn.primary.device_identifier = new_id; for (auto &alt : btn.alternatives) { if (alt.device_identifier == old_id) alt.device_identifier = new_id; } } }; rename_in_buttons(buttons); rename_in_buttons(modifier_buttons); rename_in_buttons(keypad_buttons); for (auto &a : analogs) { if (a.device_identifier == old_id) a.device_identifier = new_id; } for (auto &l : lights) { if (l.primary.device_identifier == old_id) l.primary.device_identifier = new_id; for (auto &alt : l.alternatives) { if (alt.device_identifier == old_id) alt.device_identifier = new_id; } } } std::string ControllerTemplate::get_source_summary(const std::string &source) const { bool is_naive = (source == "Naive"); std::string result; // collect button lines from a button vector auto collect_btn_lines = [&](const std::vector &btns, std::vector &lines) { for (auto &tb : btns) { auto check_entry = [&](const TemplateButtonEntry &e) { if (is_naive && e.is_naive()) { Button b(""); b.setVKey(e.vKey); lines.push_back(tb.name + " = " + (e.vKey == INVALID_VKEY ? "None" : b.getVKeyString())); } else if (!is_naive && e.is_device() && e.device_identifier == source) { std::string desc = std::to_string(e.vKey); if (e.analog_type != BAT_NONE) { desc += " (analog:" + std::to_string((int)e.analog_type) + ")"; } lines.push_back(tb.name + " = " + desc); } }; check_entry(tb.primary); for (auto &alt : tb.alternatives) { check_entry(alt); } } }; // buttons std::vector btn_lines; collect_btn_lines(buttons, btn_lines); if (!btn_lines.empty()) { result += "Buttons:\n"; for (auto &line : btn_lines) { result += " " + line + "\n"; } } // modifier buttons std::vector modifier_lines; collect_btn_lines(modifier_buttons, modifier_lines); if (!modifier_lines.empty()) { result += "Modifiers:\n"; for (auto &line : modifier_lines) { result += " " + line + "\n"; } } // keypad buttons std::vector kp_lines; collect_btn_lines(keypad_buttons, kp_lines); if (!kp_lines.empty()) { result += "Keypad:\n"; for (auto &line : kp_lines) { result += " " + line + "\n"; } } // analogs if (!is_naive) { std::vector analog_lines; for (auto &a : analogs) { if (a.is_device() && a.device_identifier == source) { analog_lines.push_back(a.name + " (idx:" + std::to_string(a.index) + ")"); } } if (!analog_lines.empty()) { result += "Analogs:\n"; for (auto &line : analog_lines) { result += " " + line + "\n"; } } } // lights if (!is_naive) { std::vector light_lines; for (auto &l : lights) { auto check_light = [&](const TemplateLightEntry &e) { if (e.is_device() && e.device_identifier == source) { light_lines.push_back(l.name + " (idx:" + std::to_string(e.index) + ")"); } }; check_light(l.primary); for (auto &alt : l.alternatives) { check_light(alt); } } if (!light_lines.empty()) { result += "Lights:\n"; for (auto &line : light_lines) { result += " " + line + "\n"; } } } if (result.empty()) { result = "(no bindings)"; } // trim trailing newline while (!result.empty() && result.back() == '\n') { result.pop_back(); } return result; } }