redefinir tecles

This commit is contained in:
2026-04-05 00:41:04 +02:00
parent a328681365
commit f8b60cb641
11 changed files with 167 additions and 24 deletions

View File

@@ -41,7 +41,8 @@ namespace Menu {
enum class ItemKind { Toggle,
Cycle,
IntRange,
Submenu };
Submenu,
KeyBind };
struct Item {
const char* label;
@@ -49,6 +50,7 @@ namespace Menu {
std::function<std::string()> getValue; // opcional
std::function<void(int dir)> change; // per Toggle/Cycle/IntRange
std::function<void()> enter; // per Submenu
SDL_Scancode* scancode{nullptr}; // per KeyBind
};
struct Page {
@@ -62,6 +64,7 @@ namespace Menu {
static std::unique_ptr<Text> font_;
static float open_anim_{0.0F}; // 0 = tancat, 1 = obert
static Uint32 last_ticks_{0};
static SDL_Scancode* capturing_{nullptr}; // != null → esperant tecla per assignar
// --- Helpers ---
@@ -72,11 +75,13 @@ namespace Menu {
static Page buildVideo();
static Page buildAudio();
static Page buildControls();
static Page buildRoot() {
Page p{"OPCIONS", {}, 0};
p.items.push_back({"VIDEO", ItemKind::Submenu, nullptr, nullptr, [] { stack_.push_back(buildVideo()); }});
p.items.push_back({"AUDIO", ItemKind::Submenu, nullptr, nullptr, [] { stack_.push_back(buildAudio()); }});
p.items.push_back({"VIDEO", ItemKind::Submenu, nullptr, nullptr, [] { stack_.push_back(buildVideo()); }, nullptr});
p.items.push_back({"AUDIO", ItemKind::Submenu, nullptr, nullptr, [] { stack_.push_back(buildAudio()); }, nullptr});
p.items.push_back({"CONTROLS", ItemKind::Submenu, nullptr, nullptr, [] { stack_.push_back(buildControls()); }, nullptr});
return p;
}
@@ -137,6 +142,16 @@ namespace Menu {
Options::applyAudio();
}
static Page buildControls() {
Page p{"CONTROLS", {}, 0};
p.items.push_back({"MOU AMUNT", ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.up});
p.items.push_back({"MOU AVALL", ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.down});
p.items.push_back({"MOU ESQUERRA", ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.left});
p.items.push_back({"MOU DRETA", ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.right});
p.items.push_back({"TECLA MENU", ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_gui.menu_toggle});
return p;
}
static Page buildAudio() {
Page p{"AUDIO", {}, 0};
@@ -242,6 +257,22 @@ namespace Menu {
void close() {
stack_.clear();
open_anim_ = 0.0F;
capturing_ = nullptr;
}
auto isCapturing() -> bool {
return capturing_ != nullptr;
}
void captureKey(SDL_Scancode sc) {
if (!capturing_) return;
if (sc == SDL_SCANCODE_ESCAPE) {
// Cancel·la
capturing_ = nullptr;
return;
}
*capturing_ = sc;
capturing_ = nullptr;
}
void handleKey(SDL_Scancode sc) {
@@ -279,6 +310,8 @@ namespace Menu {
case SDL_SCANCODE_KP_ENTER:
if (page.items[page.cursor].kind == ItemKind::Submenu) {
if (page.items[page.cursor].enter) page.items[page.cursor].enter();
} else if (page.items[page.cursor].kind == ItemKind::KeyBind) {
capturing_ = page.items[page.cursor].scancode;
} else if (page.items[page.cursor].change) {
page.items[page.cursor].change(+1);
}
@@ -363,6 +396,13 @@ namespace Menu {
int aw = font_->width(arrow);
Uint32 ac = selected ? CURSOR_COLOR : VALUE_COLOR;
font_->draw(pixel_data, box_x + BOX_W - ITEM_PAD_X - aw, y, arrow, ac);
} else if (item.kind == ItemKind::KeyBind) {
bool this_capturing = (capturing_ == item.scancode);
const char* text = this_capturing ? "<PREM TECLA>" : (item.scancode ? SDL_GetScancodeName(*item.scancode) : "");
if (!text || !*text) text = "---";
int tw = font_->width(text);
Uint32 tc = this_capturing ? 0xFF00FFFF : (selected ? CURSOR_COLOR : VALUE_COLOR);
font_->draw(pixel_data, box_x + BOX_W - ITEM_PAD_X - tw, y, text, tc);
} else if (item.getValue) {
std::string value = item.getValue();
int value_w = font_->width(value.c_str());