mirror of
https://github.com/BanjoRecomp/BanjoRecomp
synced 2026-06-07 03:17:28 -04:00
clear and reset input bindings implemented
This commit is contained in:
@@ -172,6 +172,9 @@ namespace recomp {
|
||||
GameInput get_input_from_enum_name(const std::string_view name);
|
||||
InputField& get_input_binding(int profile_index, GameInput input, size_t binding_index);
|
||||
void set_input_binding(int profile_index, GameInput input, size_t binding_index, InputField value);
|
||||
void clear_input_binding(int profile_index, GameInput input);
|
||||
void reset_input_binding(int profile_index, InputDevice device, GameInput input);
|
||||
void reset_profile_bindings(int profile_index, recomp::InputDevice device);
|
||||
int add_input_profile(const std::string &key, const std::string &name, InputDevice device, bool custom);
|
||||
int get_input_profile_by_key(const std::string &key);
|
||||
const std::string &get_input_profile_key(int profile_index);
|
||||
|
||||
@@ -103,6 +103,62 @@ void recomp::set_input_binding(int profile_index, recomp::GameInput input, size_
|
||||
}
|
||||
}
|
||||
|
||||
void recomp::clear_input_binding(int profile_index, GameInput input) {
|
||||
for (size_t binding_index = 0; binding_index < recomp::bindings_per_input; binding_index++) {
|
||||
recomp::set_input_binding(profile_index, input, binding_index, recomp::InputField{});
|
||||
}
|
||||
}
|
||||
|
||||
void recomp::reset_input_binding(int profile_index, InputDevice device, GameInput input) {
|
||||
std::vector<recomp::InputField> new_mappings = recomp::get_default_mapping_for_input(
|
||||
device == recomp::InputDevice::Keyboard ?
|
||||
recomp::default_n64_keyboard_mappings :
|
||||
recomp::default_n64_controller_mappings,
|
||||
input
|
||||
);
|
||||
for (size_t binding_index = 0; binding_index < recomp::bindings_per_input; binding_index++) {
|
||||
if (binding_index >= new_mappings.size()) {
|
||||
recomp::set_input_binding(profile_index, input, binding_index, recomp::InputField{});
|
||||
} else {
|
||||
recomp::set_input_binding(profile_index, input, binding_index, new_mappings[binding_index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void recomp::reset_profile_bindings(int profile_index, recomp::InputDevice device) {
|
||||
const recomp::DefaultN64Mappings &defaults = (device == recomp::InputDevice::Keyboard)
|
||||
? recomp::default_n64_keyboard_mappings
|
||||
: recomp::default_n64_controller_mappings;
|
||||
|
||||
// multiplayer keyboard profiles just get cleared completely because of overlapping key bindings.
|
||||
bool is_multiplayer_kb = false;
|
||||
if (device == recomp::InputDevice::Keyboard) {
|
||||
for (size_t i = 0; i < recompinput::get_num_players(); i++) {
|
||||
if (recomp::get_mp_keyboard_profile_index(i) == profile_index) {
|
||||
is_multiplayer_kb = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < recomp::get_num_inputs(); i++) {
|
||||
recomp::GameInput input = static_cast<recomp::GameInput>(i);
|
||||
if (is_multiplayer_kb) {
|
||||
recomp::clear_input_binding(profile_index, input);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto &new_mappings = recomp::get_default_mapping_for_input(defaults, input);
|
||||
for (size_t binding_index = 0; binding_index < recomp::bindings_per_input; binding_index++) {
|
||||
if (binding_index >= new_mappings.size()) {
|
||||
recomp::set_input_binding(profile_index, input, binding_index, recomp::InputField{});
|
||||
} else {
|
||||
recomp::set_input_binding(profile_index, input, binding_index, new_mappings[binding_index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int recomp::add_input_profile(const std::string &key, const std::string &name, InputDevice device, bool custom) {
|
||||
auto it = input_profile_key_index_map.find(key);
|
||||
if (it != input_profile_key_index_map.end()) {
|
||||
|
||||
@@ -15,7 +15,8 @@ GameInputRow::GameInputRow(
|
||||
Element *parent,
|
||||
GameInputContext *input_ctx,
|
||||
std::function<void()> on_hover_callback,
|
||||
on_bind_click_callback on_bind_click
|
||||
on_bind_click_callback on_bind_click,
|
||||
on_clear_or_reset_callback on_clear_or_reset
|
||||
) : Element(parent, Events(EventType::Hover), "div", false) {
|
||||
this->input_id = input_ctx->input_id;
|
||||
this->on_hover_callback = on_hover_callback;
|
||||
@@ -74,13 +75,13 @@ GameInputRow::GameInputRow(
|
||||
|
||||
if (input_ctx->clearable) {
|
||||
auto clear_button = context.create_element<IconButton>(this, "icons/Trash.svg", ButtonStyle::Danger, IconButtonSize::Large);
|
||||
clear_button->add_pressed_callback([this]() {
|
||||
// TODO: Add clear callback
|
||||
clear_button->add_pressed_callback([this, on_clear_or_reset]() {
|
||||
on_clear_or_reset(this->input_id, false);
|
||||
});
|
||||
} else {
|
||||
auto reset_button = context.create_element<IconButton>(this, "icons/Reset.svg", ButtonStyle::Warning, IconButtonSize::Large);
|
||||
reset_button->add_pressed_callback([this]() {
|
||||
// TODO: Add reset callback
|
||||
reset_button->add_pressed_callback([this, on_clear_or_reset]() {
|
||||
on_clear_or_reset(this->input_id, true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -329,8 +330,11 @@ void ConfigPageControls::render_footer() {
|
||||
{
|
||||
auto footer_right = footer->get_right();
|
||||
footer_right->clear_children();
|
||||
context.create_element<Button>(footer_right, "Reset to defaults", ButtonStyle::Warning);
|
||||
// TODO: Add reset to defaults callback
|
||||
auto reset_to_defaults_button = context.create_element<Button>(footer_right, "Reset to defaults", ButtonStyle::Warning);
|
||||
reset_to_defaults_button->add_pressed_callback([this]() {
|
||||
recomp::reset_profile_bindings(this->selected_profile_index, this->get_player_input_device());
|
||||
this->update_control_mappings();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,6 +365,9 @@ void ConfigPageControls::render_control_mappings() {
|
||||
},
|
||||
[this](recompinput::GameInput game_input, int input_index) {
|
||||
this->on_bind_click(game_input, input_index);
|
||||
},
|
||||
[this](recompinput::GameInput game_input, bool reset) {
|
||||
this->on_clear_or_reset_game_input(game_input, reset);
|
||||
}
|
||||
);
|
||||
game_input_rows.push_back(row);
|
||||
@@ -399,20 +406,33 @@ void ConfigPageControls::update_control_mappings() {
|
||||
ConfigPageControls::~ConfigPageControls() {
|
||||
}
|
||||
|
||||
void ConfigPageControls::on_bind_click(recompinput::GameInput game_input, int input_index) {
|
||||
recompinput::InputDevice device;
|
||||
recompinput::InputDevice ConfigPageControls::get_player_input_device() {
|
||||
if (multiplayer_enabled) {
|
||||
device = recompinput::get_assigned_player_input_device(this->selected_player);
|
||||
} else {
|
||||
device = single_player_show_keyboard_mappings
|
||||
? recomp::InputDevice::Keyboard
|
||||
: recomp::InputDevice::Controller;
|
||||
return recompinput::get_assigned_player_input_device(this->selected_player);
|
||||
}
|
||||
|
||||
return single_player_show_keyboard_mappings
|
||||
? recomp::InputDevice::Keyboard
|
||||
: recomp::InputDevice::Controller;
|
||||
}
|
||||
|
||||
void ConfigPageControls::on_bind_click(recompinput::GameInput game_input, int input_index) {
|
||||
recompinput::InputDevice device = get_player_input_device();
|
||||
|
||||
recompinput::start_scanning_for_binding(this->selected_player, game_input, input_index, device);
|
||||
awaiting_binding = true;
|
||||
}
|
||||
|
||||
void ConfigPageControls::on_clear_or_reset_game_input(recompinput::GameInput game_input, bool reset) {
|
||||
if (!reset) {
|
||||
recomp::clear_input_binding(selected_profile_index, game_input);
|
||||
} else {
|
||||
recompinput::InputDevice device = get_player_input_device();
|
||||
recomp::reset_input_binding(selected_profile_index, device, game_input);
|
||||
}
|
||||
update_control_mappings();
|
||||
}
|
||||
|
||||
void ConfigPageControls::set_selected_player(int player) {
|
||||
selected_player = player;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ using on_bind_click_callback = std::function<void(recompinput::GameInput, int)>;
|
||||
// Player index, GameInput to be bound to, and the index of the binding that is being assigned
|
||||
using on_player_bind_callback = std::function<void(int, recompinput::GameInput, int)>;
|
||||
|
||||
using on_clear_or_reset_callback = std::function<void(recompinput::GameInput, bool)>;
|
||||
|
||||
// One single row of a game input mapping
|
||||
class GameInputRow : public Element {
|
||||
protected:
|
||||
@@ -53,7 +55,8 @@ public:
|
||||
Element *parent,
|
||||
GameInputContext *input_ctx,
|
||||
std::function<void()> on_hover_callback,
|
||||
on_bind_click_callback on_bind_click
|
||||
on_bind_click_callback on_bind_click,
|
||||
on_clear_or_reset_callback on_clear_or_reset
|
||||
);
|
||||
virtual ~GameInputRow();
|
||||
void update_bindings(BindingList &new_bindings);
|
||||
@@ -93,6 +96,10 @@ protected:
|
||||
private:
|
||||
void on_option_hover(uint8_t index);
|
||||
void on_bind_click(recompinput::GameInput game_input, int input_index);
|
||||
void on_clear_or_reset_game_input(
|
||||
recompinput::GameInput game_input,
|
||||
bool reset = false
|
||||
);
|
||||
|
||||
void on_select_player_profile(int player_index, int profile_index);
|
||||
void on_edit_player_profile(int player_index);
|
||||
@@ -103,6 +110,8 @@ private:
|
||||
void render_body_players();
|
||||
void render_body_mappings();
|
||||
void render_footer();
|
||||
|
||||
recompinput::InputDevice get_player_input_device();
|
||||
public:
|
||||
ConfigPageControls(
|
||||
Element *parent,
|
||||
|
||||
Reference in New Issue
Block a user