mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-21 00:25:44 +00:00
Add menu key handlers
This commit is contained in:
parent
aae2b9f3d9
commit
03b3981312
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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>());
|
||||
|
@ -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>());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user