Add menu key handlers

This commit is contained in:
Jan 2021-11-20 22:01:01 +01:00
parent aae2b9f3d9
commit 03b3981312
4 changed files with 152 additions and 5 deletions

View File

@ -152,6 +152,7 @@ namespace menu
std::unique_ptr<CommonEventHandlerSet> m_on_mouse_exit_text;
std::unique_ptr<CommonEventHandlerSet> m_on_action;
std::unique_ptr<CommonEventHandlerSet> m_on_accept;
std::map<int, std::unique_ptr<CommonEventHandlerSet>> m_key_handlers;
std::unique_ptr<CommonItemFeaturesListBox> m_list_box_features;
std::unique_ptr<CommonItemFeaturesEditField> m_edit_field_features;

View File

@ -45,7 +45,7 @@ namespace menu
std::unique_ptr<CommonEventHandlerSet> m_on_close;
std::unique_ptr<CommonEventHandlerSet> m_on_request_close;
std::unique_ptr<CommonEventHandlerSet> m_on_esc;
std::map<int, std::unique_ptr<CommonEventHandlerSet>> m_key_handler;
std::map<int, std::unique_ptr<CommonEventHandlerSet>> m_key_handlers;
bool m_full_screen;
bool m_screen_space;

View File

@ -382,10 +382,11 @@ namespace menu::item_scope_sequences
class SequenceColumns final : public MenuFileParser::sequence_t
{
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
static constexpr auto CAPTURE_POS = 2;
static constexpr auto CAPTURE_WIDTH = 3;
static constexpr auto CAPTURE_MAX_CHARS = 4;
static constexpr auto CAPTURE_ALIGNMENT = 5;
static constexpr auto CAPTURE_COLUMN_COUNT = 2;
static constexpr auto CAPTURE_POS = 3;
static constexpr auto CAPTURE_WIDTH = 4;
static constexpr auto CAPTURE_MAX_CHARS = 5;
static constexpr auto CAPTURE_ALIGNMENT = 6;
public:
SequenceColumns()
@ -394,6 +395,7 @@ namespace menu::item_scope_sequences
AddMatchers({
create.KeywordIgnoreCase("columns").Capture(CAPTURE_FIRST_TOKEN),
create.Integer().Capture(CAPTURE_COLUMN_COUNT),
create.Loop(create.And({
create.Integer().Capture(CAPTURE_POS),
create.Integer().Capture(CAPTURE_WIDTH),
@ -426,6 +428,76 @@ namespace menu::item_scope_sequences
}
}
};
class SequenceExecKey final : public MenuFileParser::sequence_t
{
static constexpr auto CAPTURE_KEY = 1;
public:
SequenceExecKey()
{
const MenuMatcherFactory create(this);
AddMatchers({
create.KeywordIgnoreCase("execKey"),
create.String().Capture(CAPTURE_KEY),
create.Char('{')
});
}
protected:
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
assert(state->m_current_item);
const auto& keyToken = result.NextCapture(CAPTURE_KEY);
const auto& keyValue = keyToken.StringValue();
if (keyValue.empty() || keyValue.size() > 1)
throw ParsingException(keyToken.GetPos(), "Key handler string must have exactly one character");
const auto key = static_cast<int>(static_cast<unsigned char>(keyValue[0]));
auto newEventHandlerSet = std::make_unique<CommonEventHandlerSet>();
state->m_current_event_handler_set = newEventHandlerSet.get();
state->m_current_nested_event_handler_set = newEventHandlerSet.get();
state->m_current_item->m_key_handlers.emplace(std::make_pair(key, std::move(newEventHandlerSet)));
}
};
class SequenceExecKeyInt final : public MenuFileParser::sequence_t
{
static constexpr auto CAPTURE_KEY = 1;
public:
SequenceExecKeyInt()
{
const MenuMatcherFactory create(this);
AddMatchers({
create.KeywordIgnoreCase("execKeyInt"),
create.Integer().Capture(CAPTURE_KEY),
create.Char('{')
});
}
protected:
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
assert(state->m_current_item);
const auto& keyToken = result.NextCapture(CAPTURE_KEY);
const auto& keyValue = keyToken.IntegerValue();
if (keyValue < 0)
throw ParsingException(keyToken.GetPos(), "Key handler value must be positive");
auto newEventHandlerSet = std::make_unique<CommonEventHandlerSet>();
state->m_current_event_handler_set = newEventHandlerSet.get();
state->m_current_nested_event_handler_set = newEventHandlerSet.get();
state->m_current_item->m_key_handlers.emplace(std::make_pair(keyValue, std::move(newEventHandlerSet)));
}
};
}
using namespace item_scope_sequences;
@ -724,6 +796,8 @@ void ItemScopeSequences::AddSequences(FeatureLevel featureLevel)
{
state->m_current_item->m_on_accept = std::move(value);
}));
AddSequence(std::make_unique<SequenceExecKey>());
AddSequence(std::make_unique<SequenceExecKeyInt>());
// ============== ListBox ==============
AddSequence(std::make_unique<SequenceColumns>());

View File

@ -127,6 +127,76 @@ namespace menu::menu_scope_sequences
state->m_current_menu->m_rect = rect;
}
};
class SequenceExecKey final : public MenuFileParser::sequence_t
{
static constexpr auto CAPTURE_KEY = 1;
public:
SequenceExecKey()
{
const MenuMatcherFactory create(this);
AddMatchers({
create.KeywordIgnoreCase("execKey"),
create.String().Capture(CAPTURE_KEY),
create.Char('{')
});
}
protected:
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
assert(state->m_current_menu);
const auto& keyToken = result.NextCapture(CAPTURE_KEY);
const auto& keyValue = keyToken.StringValue();
if (keyValue.empty() || keyValue.size() > 1)
throw ParsingException(keyToken.GetPos(), "Key handler string must have exactly one character");
const auto key = static_cast<int>(static_cast<unsigned char>(keyValue[0]));
auto newEventHandlerSet = std::make_unique<CommonEventHandlerSet>();
state->m_current_event_handler_set = newEventHandlerSet.get();
state->m_current_nested_event_handler_set = newEventHandlerSet.get();
state->m_current_menu->m_key_handlers.emplace(std::make_pair(key, std::move(newEventHandlerSet)));
}
};
class SequenceExecKeyInt final : public MenuFileParser::sequence_t
{
static constexpr auto CAPTURE_KEY = 1;
public:
SequenceExecKeyInt()
{
const MenuMatcherFactory create(this);
AddMatchers({
create.KeywordIgnoreCase("execKeyInt"),
create.Integer().Capture(CAPTURE_KEY),
create.Char('{')
});
}
protected:
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
assert(state->m_current_menu);
const auto& keyToken = result.NextCapture(CAPTURE_KEY);
const auto& keyValue = keyToken.IntegerValue();
if (keyValue < 0)
throw ParsingException(keyToken.GetPos(), "Key handler value must be positive");
auto newEventHandlerSet = std::make_unique<CommonEventHandlerSet>();
state->m_current_event_handler_set = newEventHandlerSet.get();
state->m_current_nested_event_handler_set = newEventHandlerSet.get();
state->m_current_menu->m_key_handlers.emplace(std::make_pair(keyValue, std::move(newEventHandlerSet)));
}
};
}
using namespace menu_scope_sequences;
@ -289,4 +359,6 @@ void MenuScopeSequences::AddSequences(FeatureLevel featureLevel)
{
state->m_current_menu->m_on_esc = std::move(value);
}));
AddSequence(std::make_unique<SequenceExecKey>());
AddSequence(std::make_unique<SequenceExecKeyInt>());
}