mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-07-21 22:32:59 +12:00
Qt: Allow rebinding keyboard controls (#779)
Some checks failed
Android Build / x64 (release) (push) Has been cancelled
Android Build / arm64 (release) (push) Has been cancelled
HTTP Server Build / build (push) Has been cancelled
Hydra Core Build / Windows (push) Has been cancelled
Hydra Core Build / MacOS (push) Has been cancelled
Hydra Core Build / Linux (push) Has been cancelled
Hydra Core Build / Android-x64 (push) Has been cancelled
Hydra Core Build / ARM-Libretro (push) Has been cancelled
Linux AppImage Build / build (push) Has been cancelled
Linux Build / build (push) Has been cancelled
MacOS Build / MacOS-arm64 (push) Has been cancelled
MacOS Build / MacOS-x86_64 (push) Has been cancelled
Qt Build / Windows (push) Has been cancelled
Qt Build / MacOS-arm64 (push) Has been cancelled
Qt Build / MacOS-x86_64 (push) Has been cancelled
Qt Build / Linux (push) Has been cancelled
Windows Build / build (push) Has been cancelled
iOS Simulator Build / build (push) Has been cancelled
MacOS Build / MacOS-Universal (push) Has been cancelled
Qt Build / MacOS-Universal (push) Has been cancelled
Some checks failed
Android Build / x64 (release) (push) Has been cancelled
Android Build / arm64 (release) (push) Has been cancelled
HTTP Server Build / build (push) Has been cancelled
Hydra Core Build / Windows (push) Has been cancelled
Hydra Core Build / MacOS (push) Has been cancelled
Hydra Core Build / Linux (push) Has been cancelled
Hydra Core Build / Android-x64 (push) Has been cancelled
Hydra Core Build / ARM-Libretro (push) Has been cancelled
Linux AppImage Build / build (push) Has been cancelled
Linux Build / build (push) Has been cancelled
MacOS Build / MacOS-arm64 (push) Has been cancelled
MacOS Build / MacOS-x86_64 (push) Has been cancelled
Qt Build / Windows (push) Has been cancelled
Qt Build / MacOS-arm64 (push) Has been cancelled
Qt Build / MacOS-x86_64 (push) Has been cancelled
Qt Build / Linux (push) Has been cancelled
Windows Build / build (push) Has been cancelled
iOS Simulator Build / build (push) Has been cancelled
MacOS Build / MacOS-Universal (push) Has been cancelled
Qt Build / MacOS-Universal (push) Has been cancelled
* Initial input UI draft Co-Authored-By: Paris Oplopoios <parisoplop@gmail.com> * More keybinding work Co-Authored-By: Paris Oplopoios <parisoplop@gmail.com> * Nit Co-Authored-By: Paris Oplopoios <parisoplop@gmail.com> * More nits Co-Authored-By: Paris Oplopoios <parisoplop@gmail.com> --------- Co-authored-by: Paris Oplopoios <parisoplop@gmail.com>
This commit is contained in:
parent
3cae1bd256
commit
81f37e1699
14 changed files with 385 additions and 14 deletions
|
@ -1,5 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <toml.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "helpers.hpp"
|
||||
|
@ -15,8 +20,108 @@ struct InputMappings {
|
|||
}
|
||||
|
||||
void setMapping(Scancode scancode, u32 key) { container[scancode] = key; }
|
||||
|
||||
template <typename ScancodeToString>
|
||||
void serialize(const std::filesystem::path& path, const std::string& frontend, ScancodeToString scancodeToString) const {
|
||||
toml::basic_value<toml::preserve_comments, std::map> data;
|
||||
|
||||
std::error_code error;
|
||||
if (std::filesystem::exists(path, error)) {
|
||||
try {
|
||||
data = toml::parse<toml::preserve_comments, std::map>(path);
|
||||
} catch (const std::exception& ex) {
|
||||
Helpers::warn("Exception trying to parse mappings file. Exception: %s\n", ex.what());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (error) {
|
||||
Helpers::warn("Filesystem error accessing %s (error: %s)\n", path.string().c_str(), error.message().c_str());
|
||||
}
|
||||
printf("Saving new mappings file %s\n", path.string().c_str());
|
||||
}
|
||||
|
||||
data["Metadata"]["Name"] = name.empty() ? "Unnamed Mappings" : name;
|
||||
data["Metadata"]["Device"] = device.empty() ? "Unknown Device" : device;
|
||||
data["Metadata"]["Frontend"] = frontend;
|
||||
|
||||
data["Mappings"] = toml::table{};
|
||||
|
||||
for (const auto& [scancode, key] : container) {
|
||||
const std::string& keyName = HID::Keys::keyToName(key);
|
||||
if (!data["Mappings"].contains(keyName)) {
|
||||
data["Mappings"][keyName] = toml::array{};
|
||||
}
|
||||
data["Mappings"][keyName].push_back(scancodeToString(scancode));
|
||||
}
|
||||
|
||||
std::ofstream file(path, std::ios::out);
|
||||
file << data;
|
||||
}
|
||||
|
||||
template <typename ScancodeFromString>
|
||||
static std::optional<InputMappings> deserialize(
|
||||
const std::filesystem::path& path, const std::string& wantFrontend, ScancodeFromString stringToScancode
|
||||
) {
|
||||
toml::basic_value<toml::preserve_comments, std::map> data;
|
||||
std::error_code error;
|
||||
|
||||
if (!std::filesystem::exists(path, error)) {
|
||||
if (error) {
|
||||
Helpers::warn("Filesystem error accessing %s (error: %s)\n", path.string().c_str(), error.message().c_str());
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
InputMappings mappings;
|
||||
|
||||
try {
|
||||
data = toml::parse<toml::preserve_comments, std::map>(path);
|
||||
|
||||
const auto metadata = toml::find(data, "Metadata");
|
||||
mappings.name = toml::find_or<std::string>(metadata, "Name", "Unnamed Mappings");
|
||||
mappings.device = toml::find_or<std::string>(metadata, "Device", "Unknown Device");
|
||||
|
||||
std::string haveFrontend = toml::find_or<std::string>(metadata, "Frontend", "Unknown Frontend");
|
||||
|
||||
bool equal = std::equal(haveFrontend.begin(), haveFrontend.end(), wantFrontend.begin(), wantFrontend.end(), [](char a, char b) {
|
||||
return std::tolower(a) == std::tolower(b);
|
||||
});
|
||||
|
||||
if (!equal) {
|
||||
Helpers::warn(
|
||||
"Mappings file %s was created for frontend %s, but we are using frontend %s\n", path.string().c_str(), haveFrontend.c_str(),
|
||||
wantFrontend.c_str()
|
||||
);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
} catch (const std::exception& ex) {
|
||||
Helpers::warn("Exception trying to parse config file. Exception: %s\n", ex.what());
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto& mappingsTable = toml::find_or<toml::table>(data, "Mappings", toml::table{});
|
||||
for (const auto& [keyName, scancodes] : mappingsTable) {
|
||||
for (const auto& scancodeVal : scancodes.as_array()) {
|
||||
std::string scancodeStr = scancodeVal.as_string();
|
||||
mappings.setMapping(stringToScancode(scancodeStr), HID::Keys::nameToKey(keyName));
|
||||
}
|
||||
}
|
||||
|
||||
return mappings;
|
||||
}
|
||||
|
||||
static InputMappings defaultKeyboardMappings();
|
||||
|
||||
auto begin() { return container.begin(); }
|
||||
auto end() { return container.end(); }
|
||||
|
||||
auto begin() const { return container.begin(); }
|
||||
auto end() const { return container.end(); }
|
||||
|
||||
private:
|
||||
Container container;
|
||||
std::string name;
|
||||
std::string device;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue