Add base for IW5 menu parsing

This commit is contained in:
Jan 2023-08-23 23:08:50 +02:00
parent 0d6e3e8298
commit 8a1fe03358
7 changed files with 175 additions and 58 deletions

View File

@ -848,6 +848,7 @@ namespace IW5
listBox->onDoubleClick = ConvertEventHandlerSet(commonListBox->m_on_double_click.get(), &parentMenu, &commonItem); listBox->onDoubleClick = ConvertEventHandlerSet(commonListBox->m_on_double_click.get(), &parentMenu, &commonItem);
ConvertColor(listBox->selectBorder, commonListBox->m_select_border); ConvertColor(listBox->selectBorder, commonListBox->m_select_border);
listBox->selectIcon = ConvertMaterial(commonListBox->m_select_icon, &parentMenu, &commonItem); listBox->selectIcon = ConvertMaterial(commonListBox->m_select_icon, &parentMenu, &commonItem);
listBox->elementHeightExp = ConvertOrApplyStatement(listBox->elementHeight, commonListBox->m_element_height_expression.get(), &parentMenu, &commonItem);
listBox->numColumns = static_cast<int>(std::min(std::extent_v<decltype(listBoxDef_s::columnInfo)>, commonListBox->m_columns.size())); listBox->numColumns = static_cast<int>(std::min(std::extent_v<decltype(listBoxDef_s::columnInfo)>, commonListBox->m_columns.size()));
for (auto i = 0; i < listBox->numColumns; i++) for (auto i = 0; i < listBox->numColumns; i++)
@ -971,6 +972,7 @@ namespace IW5
ConvertColor(item->glowColor, commonItem.m_glow_color); ConvertColor(item->glowColor, commonItem.m_glow_color);
item->window.background = ConvertMaterial(commonItem.m_background, &parentMenu, &commonItem); item->window.background = ConvertMaterial(commonItem.m_background, &parentMenu, &commonItem);
item->onFocus = ConvertEventHandlerSet(commonItem.m_on_focus.get(), &parentMenu, &commonItem); item->onFocus = ConvertEventHandlerSet(commonItem.m_on_focus.get(), &parentMenu, &commonItem);
item->hasFocus = ConvertEventHandlerSet(commonItem.m_has_focus.get(), &parentMenu, &commonItem);
item->leaveFocus = ConvertEventHandlerSet(commonItem.m_on_leave_focus.get(), &parentMenu, &commonItem); item->leaveFocus = ConvertEventHandlerSet(commonItem.m_on_leave_focus.get(), &parentMenu, &commonItem);
item->mouseEnter = ConvertEventHandlerSet(commonItem.m_on_mouse_enter.get(), &parentMenu, &commonItem); item->mouseEnter = ConvertEventHandlerSet(commonItem.m_on_mouse_enter.get(), &parentMenu, &commonItem);
item->mouseExit = ConvertEventHandlerSet(commonItem.m_on_mouse_exit.get(), &parentMenu, &commonItem); item->mouseExit = ConvertEventHandlerSet(commonItem.m_on_mouse_exit.get(), &parentMenu, &commonItem);
@ -983,6 +985,7 @@ namespace IW5
item->enableDvar = ConvertEnableDvar(commonItem, item->dvarFlags); item->enableDvar = ConvertEnableDvar(commonItem, item->dvarFlags);
item->onKey = ConvertKeyHandler(commonItem.m_key_handlers, &parentMenu, &commonItem); item->onKey = ConvertKeyHandler(commonItem.m_key_handlers, &parentMenu, &commonItem);
item->textExp = ConvertOrApplyStatement(item->text, commonItem.m_text_expression.get(), &parentMenu, &commonItem); item->textExp = ConvertOrApplyStatement(item->text, commonItem.m_text_expression.get(), &parentMenu, &commonItem);
item->textAlignYExp = ConvertOrApplyStatement(item->textaligny, commonItem.m_text_align_y_expression.get(), &parentMenu, &commonItem);
item->materialExp = ConvertOrApplyStatement(item->window.background, commonItem.m_material_expression.get(), &parentMenu, &commonItem); item->materialExp = ConvertOrApplyStatement(item->window.background, commonItem.m_material_expression.get(), &parentMenu, &commonItem);
item->disabledExp = ConvertExpression(commonItem.m_disabled_expression.get(), &parentMenu, &commonItem); item->disabledExp = ConvertExpression(commonItem.m_disabled_expression.get(), &parentMenu, &commonItem);
item->floatExpressions = ConvertFloatExpressions(&commonItem, item, &parentMenu, item->floatExpressionCount); item->floatExpressions = ConvertFloatExpressions(&commonItem, item, &parentMenu, item->floatExpressionCount);
@ -1103,6 +1106,7 @@ namespace IW5
menuData->onClose = ConvertEventHandlerSet(commonMenu.m_on_close.get(), &commonMenu); menuData->onClose = ConvertEventHandlerSet(commonMenu.m_on_close.get(), &commonMenu);
menuData->onCloseRequest = ConvertEventHandlerSet(commonMenu.m_on_request_close.get(), &commonMenu); menuData->onCloseRequest = ConvertEventHandlerSet(commonMenu.m_on_request_close.get(), &commonMenu);
menuData->onESC = ConvertEventHandlerSet(commonMenu.m_on_esc.get(), &commonMenu); menuData->onESC = ConvertEventHandlerSet(commonMenu.m_on_esc.get(), &commonMenu);
menuData->onFocusDueToClose = ConvertEventHandlerSet(commonMenu.m_on_focus_due_to_close.get(), &commonMenu);
menuData->onKey = ConvertKeyHandler(commonMenu.m_key_handlers, &commonMenu); menuData->onKey = ConvertKeyHandler(commonMenu.m_key_handlers, &commonMenu);
menu->items = ConvertMenuItems(commonMenu, menu->itemCount); menu->items = ConvertMenuItems(commonMenu, menu->itemCount);
menuData->expressionData = m_conversion_zone_state->m_supporting_data; menuData->expressionData = m_conversion_zone_state->m_supporting_data;

View File

@ -44,6 +44,7 @@ namespace menu
std::string m_select_icon; std::string m_select_icon;
std::unique_ptr<CommonEventHandlerSet> m_on_double_click; std::unique_ptr<CommonEventHandlerSet> m_on_double_click;
std::unique_ptr<ISimpleExpression> m_element_height_expression;
std::vector<Column> m_columns; std::vector<Column> m_columns;
}; };
@ -136,6 +137,7 @@ namespace menu
std::unique_ptr<ISimpleExpression> m_visible_expression; std::unique_ptr<ISimpleExpression> m_visible_expression;
std::unique_ptr<ISimpleExpression> m_disabled_expression; std::unique_ptr<ISimpleExpression> m_disabled_expression;
std::unique_ptr<ISimpleExpression> m_text_expression; std::unique_ptr<ISimpleExpression> m_text_expression;
std::unique_ptr<ISimpleExpression> m_text_align_y_expression;
std::unique_ptr<ISimpleExpression> m_material_expression; std::unique_ptr<ISimpleExpression> m_material_expression;
std::unique_ptr<ISimpleExpression> m_rect_x_exp; std::unique_ptr<ISimpleExpression> m_rect_x_exp;
std::unique_ptr<ISimpleExpression> m_rect_y_exp; std::unique_ptr<ISimpleExpression> m_rect_y_exp;
@ -145,6 +147,7 @@ namespace menu
ColorExpressions m_glowcolor_expressions; ColorExpressions m_glowcolor_expressions;
ColorExpressions m_backcolor_expressions; ColorExpressions m_backcolor_expressions;
std::unique_ptr<CommonEventHandlerSet> m_on_focus; std::unique_ptr<CommonEventHandlerSet> m_on_focus;
std::unique_ptr<CommonEventHandlerSet> m_has_focus;
std::unique_ptr<CommonEventHandlerSet> m_on_leave_focus; std::unique_ptr<CommonEventHandlerSet> m_on_leave_focus;
std::unique_ptr<CommonEventHandlerSet> m_on_mouse_enter; std::unique_ptr<CommonEventHandlerSet> m_on_mouse_enter;
std::unique_ptr<CommonEventHandlerSet> m_on_mouse_exit; std::unique_ptr<CommonEventHandlerSet> m_on_mouse_exit;

View File

@ -29,6 +29,7 @@ namespace menu
int m_owner_draw = 0; int m_owner_draw = 0;
int m_owner_draw_flags = 0; int m_owner_draw_flags = 0;
std::string m_sound_loop; std::string m_sound_loop;
std::unique_ptr<ISimpleExpression> m_sound_loop_exp;
double m_fade_clamp = 0; double m_fade_clamp = 0;
int m_fade_cycle = 0; int m_fade_cycle = 0;
double m_fade_amount = 0; double m_fade_amount = 0;
@ -46,6 +47,7 @@ namespace menu
std::unique_ptr<CommonEventHandlerSet> m_on_close; std::unique_ptr<CommonEventHandlerSet> m_on_close;
std::unique_ptr<CommonEventHandlerSet> m_on_request_close; std::unique_ptr<CommonEventHandlerSet> m_on_request_close;
std::unique_ptr<CommonEventHandlerSet> m_on_esc; std::unique_ptr<CommonEventHandlerSet> m_on_esc;
std::unique_ptr<CommonEventHandlerSet> m_on_focus_due_to_close;
std::multimap<int, std::unique_ptr<CommonEventHandlerSet>> m_key_handlers; std::multimap<int, std::unique_ptr<CommonEventHandlerSet>> m_key_handlers;
bool m_full_screen = false; bool m_full_screen = false;

View File

@ -45,6 +45,34 @@ class ItemScopeOperations
CommonItemFeatureType::EDIT_FIELD // ITEM_TYPE_PASSWORDFIELD CommonItemFeatureType::EDIT_FIELD // ITEM_TYPE_PASSWORDFIELD
}; };
inline static const CommonItemFeatureType IW5_FEATURE_TYPE_BY_TYPE[0x18]
{
CommonItemFeatureType::EDIT_FIELD, // ITEM_TYPE_TEXT
CommonItemFeatureType::NONE, // ITEM_TYPE_BUTTON
CommonItemFeatureType::NONE, // ITEM_TYPE_RADIOBUTTON
CommonItemFeatureType::NONE, // ITEM_TYPE_CHECKBOX
CommonItemFeatureType::EDIT_FIELD, // ITEM_TYPE_EDITFIELD
CommonItemFeatureType::NONE, // ITEM_TYPE_COMBO
CommonItemFeatureType::LISTBOX, // ITEM_TYPE_LISTBOX
CommonItemFeatureType::NONE, // ITEM_TYPE_MODEL
CommonItemFeatureType::NONE, // ITEM_TYPE_OWNERDRAW
CommonItemFeatureType::EDIT_FIELD, // ITEM_TYPE_NUMERICFIELD
CommonItemFeatureType::EDIT_FIELD, // ITEM_TYPE_SLIDER
CommonItemFeatureType::EDIT_FIELD, // ITEM_TYPE_YESNO
CommonItemFeatureType::MULTI_VALUE, // ITEM_TYPE_MULTI
CommonItemFeatureType::ENUM_DVAR, // ITEM_TYPE_DVARENUM
CommonItemFeatureType::EDIT_FIELD, // ITEM_TYPE_BIND
CommonItemFeatureType::NONE, // ITEM_TYPE_MENUMODEL
CommonItemFeatureType::EDIT_FIELD, // ITEM_TYPE_VALIDFILEFIELD
CommonItemFeatureType::EDIT_FIELD, // ITEM_TYPE_DECIMALFIELD
CommonItemFeatureType::EDIT_FIELD, // ITEM_TYPE_UPREDITFIELD
CommonItemFeatureType::NONE, // ITEM_TYPE_GAME_MESSAGE_WINDOW
CommonItemFeatureType::NEWS_TICKER, // ITEM_TYPE_NEWS_TICKER
CommonItemFeatureType::NONE, // ITEM_TYPE_TEXT_SCROLL
CommonItemFeatureType::EDIT_FIELD, // ITEM_TYPE_EMAILFIELD
CommonItemFeatureType::EDIT_FIELD // ITEM_TYPE_PASSWORDFIELD
};
public: public:
static void SetItemType(CommonItemDef& item, const FeatureLevel featureLevel, const TokenPos& pos, const int type) static void SetItemType(CommonItemDef& item, const FeatureLevel featureLevel, const TokenPos& pos, const int type)
{ {
@ -66,8 +94,10 @@ public:
case FeatureLevel::IW5: case FeatureLevel::IW5:
default: default:
assert(false); if (static_cast<unsigned>(type) >= std::extent_v<decltype(IW5_FEATURE_TYPE_BY_TYPE)>)
throw ParsingException(pos, "Unimplemented item types for feature level"); throw ParsingException(pos, "Invalid item type");
item.m_feature_type = IW5_FEATURE_TYPE_BY_TYPE[static_cast<unsigned>(type)];
break;
} }
switch (item.m_feature_type) switch (item.m_feature_type)
@ -431,26 +461,46 @@ namespace menu::item_scope_sequences
{ {
static constexpr auto CAPTURE_FIRST_TOKEN = 1; static constexpr auto CAPTURE_FIRST_TOKEN = 1;
static constexpr auto CAPTURE_COLUMN_COUNT = 2; static constexpr auto CAPTURE_COLUMN_COUNT = 2;
static constexpr auto CAPTURE_POS = 3; static constexpr auto CAPTURE_X_POS = 3;
static constexpr auto CAPTURE_WIDTH = 4; static constexpr auto CAPTURE_Y_POS = 4;
static constexpr auto CAPTURE_MAX_CHARS = 5; static constexpr auto CAPTURE_WIDTH = 5;
static constexpr auto CAPTURE_ALIGNMENT = 6; static constexpr auto CAPTURE_HEIGHT = 6;
static constexpr auto CAPTURE_MAX_CHARS = 7;
static constexpr auto CAPTURE_ALIGNMENT = 8;
public: public:
SequenceColumns() explicit SequenceColumns(const FeatureLevel featureLevel)
{ {
const MenuMatcherFactory create(this); const MenuMatcherFactory create(this);
AddMatchers({ if (featureLevel == FeatureLevel::IW5)
create.KeywordIgnoreCase("columns").Capture(CAPTURE_FIRST_TOKEN), {
create.Integer().Capture(CAPTURE_COLUMN_COUNT), AddMatchers({
create.Loop(create.And({ create.KeywordIgnoreCase("columns").Capture(CAPTURE_FIRST_TOKEN),
create.Integer().Capture(CAPTURE_POS), create.Integer().Capture(CAPTURE_COLUMN_COUNT),
create.Integer().Capture(CAPTURE_WIDTH), create.Loop(create.And({
create.Integer().Capture(CAPTURE_MAX_CHARS), create.Integer().Capture(CAPTURE_X_POS),
create.Integer().Capture(CAPTURE_ALIGNMENT), create.Integer().Capture(CAPTURE_Y_POS),
})), create.Integer().Capture(CAPTURE_WIDTH),
}); create.Integer().Capture(CAPTURE_HEIGHT),
create.Integer().Capture(CAPTURE_MAX_CHARS),
create.Integer().Capture(CAPTURE_ALIGNMENT),
})),
});
}
else
{
AddMatchers({
create.KeywordIgnoreCase("columns").Capture(CAPTURE_FIRST_TOKEN),
create.Integer().Capture(CAPTURE_COLUMN_COUNT),
create.Loop(create.And({
create.Integer().Capture(CAPTURE_X_POS),
create.Integer().Capture(CAPTURE_WIDTH),
create.Integer().Capture(CAPTURE_MAX_CHARS),
create.Integer().Capture(CAPTURE_ALIGNMENT),
})),
});
}
} }
protected: protected:
@ -461,14 +511,14 @@ namespace menu::item_scope_sequences
ItemScopeOperations::EnsureHasListboxFeatures(*state->m_current_item, result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos()); ItemScopeOperations::EnsureHasListboxFeatures(*state->m_current_item, result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos());
const auto& listBoxFeatures = state->m_current_item->m_list_box_features; const auto& listBoxFeatures = state->m_current_item->m_list_box_features;
while (result.HasNextCapture(CAPTURE_POS)) while (result.HasNextCapture(CAPTURE_X_POS))
{ {
CommonItemFeaturesListBox::Column column CommonItemFeaturesListBox::Column column
{ {
result.NextCapture(CAPTURE_POS).IntegerValue(), result.NextCapture(CAPTURE_X_POS).IntegerValue(),
0, state->m_feature_level == FeatureLevel::IW5 ? result.NextCapture(CAPTURE_Y_POS).IntegerValue() : 0,
result.NextCapture(CAPTURE_WIDTH).IntegerValue(), result.NextCapture(CAPTURE_WIDTH).IntegerValue(),
0, state->m_feature_level == FeatureLevel::IW5 ? result.NextCapture(CAPTURE_HEIGHT).IntegerValue() : 0,
result.NextCapture(CAPTURE_MAX_CHARS).IntegerValue(), result.NextCapture(CAPTURE_MAX_CHARS).IntegerValue(),
result.NextCapture(CAPTURE_ALIGNMENT).IntegerValue() result.NextCapture(CAPTURE_ALIGNMENT).IntegerValue()
}; };
@ -681,36 +731,28 @@ void ItemScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive
{ {
state->m_current_item->m_background = value; state->m_current_item->m_background = value;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("onFocus", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("onFocus", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_item->m_on_focus; return state->m_current_item->m_on_focus;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("leaveFocus", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("leaveFocus", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_item->m_on_leave_focus; return state->m_current_item->m_on_leave_focus;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("mouseEnter", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("mouseEnter", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_item->m_on_mouse_enter; return state->m_current_item->m_on_mouse_enter;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("mouseExit", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("mouseExit", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_item->m_on_mouse_exit; return state->m_current_item->m_on_mouse_exit;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("mouseEnterText", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("mouseEnterText", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_item->m_on_mouse_enter_text; return state->m_current_item->m_on_mouse_enter_text;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("mouseExitText", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("mouseExitText", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_item->m_on_mouse_exit_text; return state->m_current_item->m_on_mouse_exit_text;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("action", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("action", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_item->m_on_action; return state->m_current_item->m_on_action;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("accept", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("accept", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_item->m_on_accept; return state->m_current_item->m_on_accept;
})); }));
// special // special
@ -854,8 +896,19 @@ void ItemScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive
state->m_current_item->m_backcolor_expressions.m_rgb_exp = std::move(value); state->m_current_item->m_backcolor_expressions.m_rgb_exp = std::move(value);
})); }));
if (featureLevel == FeatureLevel::IW5)
{
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("hasFocus", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
return state->m_current_item->m_has_focus;
}));
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "textaligny"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
{
state->m_current_item->m_text_align_y_expression = std::move(value);
}));
}
// ============== ListBox ============== // ============== ListBox ==============
AddSequence(std::make_unique<SequenceColumns>()); AddSequence(std::make_unique<SequenceColumns>(featureLevel));
AddSequence(std::make_unique<GenericKeywordPropertySequence>("notselectable", [](const MenuFileParserState* state, const TokenPos& pos) AddSequence(std::make_unique<GenericKeywordPropertySequence>("notselectable", [](const MenuFileParserState* state, const TokenPos& pos)
{ {
ItemScopeOperations::EnsureHasListboxFeatures(*state->m_current_item, pos); ItemScopeOperations::EnsureHasListboxFeatures(*state->m_current_item, pos);
@ -891,8 +944,7 @@ void ItemScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive
ItemScopeOperations::EnsureHasListboxFeatures(*state->m_current_item, pos); ItemScopeOperations::EnsureHasListboxFeatures(*state->m_current_item, pos);
state->m_current_item->m_list_box_features->m_element_style = value; state->m_current_item->m_list_box_features->m_element_style = value;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("doubleclick", [](const MenuFileParserState* state, const TokenPos& pos) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("doubleclick", [](const MenuFileParserState* state, const TokenPos& pos) -> std::unique_ptr<CommonEventHandlerSet>& {
{
ItemScopeOperations::EnsureHasListboxFeatures(*state->m_current_item, pos); ItemScopeOperations::EnsureHasListboxFeatures(*state->m_current_item, pos);
return state->m_current_item->m_list_box_features->m_on_double_click; return state->m_current_item->m_list_box_features->m_on_double_click;
})); }));
@ -907,6 +959,15 @@ void ItemScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive
state->m_current_item->m_list_box_features->m_select_icon = value; state->m_current_item->m_list_box_features->m_select_icon = value;
})); }));
if (featureLevel == FeatureLevel::IW5)
{
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "elementheight"}, [](const MenuFileParserState* state, const TokenPos& pos, std::unique_ptr<ISimpleExpression> value)
{
ItemScopeOperations::EnsureHasListboxFeatures(*state->m_current_item, pos);
state->m_current_item->m_list_box_features->m_element_height_expression = std::move(value);
}));
}
// ============== Edit Field ============== // ============== Edit Field ==============
AddSequence(std::make_unique<SequenceDvarFloat>()); AddSequence(std::make_unique<SequenceDvarFloat>());
AddSequence(std::make_unique<GenericStringPropertySequence>("localvar", [](const MenuFileParserState* state, const TokenPos& pos, const std::string& value) AddSequence(std::make_unique<GenericStringPropertySequence>("localvar", [](const MenuFileParserState* state, const TokenPos& pos, const std::string& value)

View File

@ -258,20 +258,16 @@ void MenuScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive
{ {
state->m_current_menu->m_visible_expression = std::move(value); state->m_current_menu->m_visible_expression = std::move(value);
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("onOpen", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("onOpen", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_menu->m_on_open; return state->m_current_menu->m_on_open;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("onClose", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("onClose", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_menu->m_on_close; return state->m_current_menu->m_on_close;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("onRequestClose", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("onRequestClose", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_menu->m_on_request_close; return state->m_current_menu->m_on_request_close;
})); }));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("onESC", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("onESC", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
{
return state->m_current_menu->m_on_esc; return state->m_current_menu->m_on_esc;
})); }));
AddSequence(std::make_unique<GenericIntPropertySequence>("border", [](const MenuFileParserState* state, const TokenPos&, const int value) AddSequence(std::make_unique<GenericIntPropertySequence>("border", [](const MenuFileParserState* state, const TokenPos&, const int value)
@ -396,5 +392,19 @@ void MenuScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive
{ {
state->m_current_menu->m_text_only_focus = true; state->m_current_menu->m_text_only_focus = true;
})); }));
if (featureLevel == FeatureLevel::IW5)
{
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "soundLoop"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
{
state->m_current_menu->m_sound_loop_exp = std::move(value);
}));
AddSequence(std::make_unique<GenericMenuEventHandlerSetPropertySequence>("onFocusDueToClose", [](const MenuFileParserState* state, const TokenPos&) -> std::unique_ptr<CommonEventHandlerSet>& {
return state->m_current_menu->m_on_focus_due_to_close;
}));
}
AddSequence(std::make_unique<SequenceConsumeSemicolons>()); AddSequence(std::make_unique<SequenceConsumeSemicolons>());
} }

View File

@ -492,6 +492,31 @@ void MenuDumper::WriteFloatExpressionsProperty(const ItemFloatExpression* floatE
} }
} }
void MenuDumper::WriteMultiTokenStringProperty(const std::string& propertyKey, const char* value) const
{
if (!value)
return;
Indent();
WriteKey(propertyKey);
const auto tokenList = CreateScriptTokenList(value);
auto firstToken = true;
m_stream << "{ ";
for (const auto& token : tokenList)
{
if (firstToken)
firstToken = false;
else
m_stream << ";";
m_stream << "\"" << token << "\"";
}
if (!firstToken)
m_stream << " ";
m_stream << "}\n";
}
void MenuDumper::WriteColumnProperty(const std::string& propertyKey, const listBoxDef_s* listBox) const void MenuDumper::WriteColumnProperty(const std::string& propertyKey, const listBoxDef_s* listBox) const
{ {
if (listBox->numColumns <= 0) if (listBox->numColumns <= 0)
@ -533,7 +558,7 @@ void MenuDumper::WriteListBoxProperties(const itemDef_s* item)
WriteMenuEventHandlerSetProperty("doubleclick", listBox->onDoubleClick); WriteMenuEventHandlerSetProperty("doubleclick", listBox->onDoubleClick);
WriteColorProperty("selectBorder", listBox->selectBorder, COLOR_0000); WriteColorProperty("selectBorder", listBox->selectBorder, COLOR_0000);
WriteMaterialProperty("selectIcon", listBox->selectIcon); WriteMaterialProperty("selectIcon", listBox->selectIcon);
WriteStatementProperty("exp elementHeight", listBox->elementHeightExp, false); WriteStatementProperty("exp elementheight", listBox->elementHeightExp, false);
} }
void MenuDumper::WriteDvarFloatProperty(const std::string& propertyKey, const itemDef_s* item, const editFieldDef_s* editField) const void MenuDumper::WriteDvarFloatProperty(const std::string& propertyKey, const itemDef_s* item, const editFieldDef_s* editField) const
@ -659,9 +684,15 @@ void MenuDumper::WriteItemData(const itemDef_s* item)
WriteIntProperty("type", item->type, ITEM_TYPE_TEXT); WriteIntProperty("type", item->type, ITEM_TYPE_TEXT);
WriteIntProperty("border", item->window.border, 0); WriteIntProperty("border", item->window.border, 0);
WriteFloatProperty("borderSize", item->window.borderSize, 0.0f); WriteFloatProperty("borderSize", item->window.borderSize, 0.0f);
WriteStatementProperty("visible", item->visibleExp, true);
if (item->visibleExp)
WriteStatementProperty("visible", item->visibleExp, true);
else if (item->window.dynamicFlags[0] & WINDOW_FLAG_VISIBLE)
WriteIntProperty("visible", 1, 0);
WriteStatementProperty("disabled", item->disabledExp, true); WriteStatementProperty("disabled", item->disabledExp, true);
WriteIntProperty("ownerDraw", item->window.ownerDraw, 0); WriteIntProperty("ownerdraw", item->window.ownerDraw, 0);
WriteFlagsProperty("ownerdrawFlag", item->window.ownerDrawFlags);
WriteIntProperty("align", item->alignment, 0); WriteIntProperty("align", item->alignment, 0);
WriteIntProperty("textalign", item->textAlignMode, 0); WriteIntProperty("textalign", item->textAlignMode, 0);
WriteFloatProperty("textalignx", item->textalignx, 0.0f); WriteFloatProperty("textalignx", item->textalignx, 0.0f);
@ -687,19 +718,18 @@ void MenuDumper::WriteItemData(const itemDef_s* item)
WriteMenuEventHandlerSetProperty("accept", item->accept); WriteMenuEventHandlerSetProperty("accept", item->accept);
// WriteFloatProperty("special", item->special, 0.0f); // WriteFloatProperty("special", item->special, 0.0f);
WriteSoundAliasProperty("focusSound", item->focusSound); WriteSoundAliasProperty("focusSound", item->focusSound);
WriteFlagsProperty("ownerdrawFlag", item->window.ownerDrawFlags);
WriteStringProperty("dvarTest", item->dvarTest); WriteStringProperty("dvarTest", item->dvarTest);
if (item->dvarFlags & ITEM_DVAR_FLAG_ENABLE) if (item->dvarFlags & ITEM_DVAR_FLAG_ENABLE)
WriteStringProperty("enableDvar", item->enableDvar); WriteMultiTokenStringProperty("enableDvar", item->enableDvar);
else if (item->dvarFlags & ITEM_DVAR_FLAG_DISABLE) else if (item->dvarFlags & ITEM_DVAR_FLAG_DISABLE)
WriteStringProperty("disableDvar", item->enableDvar); WriteMultiTokenStringProperty("disableDvar", item->enableDvar);
else if (item->dvarFlags & ITEM_DVAR_FLAG_SHOW) else if (item->dvarFlags & ITEM_DVAR_FLAG_SHOW)
WriteStringProperty("showDvar", item->enableDvar); WriteMultiTokenStringProperty("showDvar", item->enableDvar);
else if (item->dvarFlags & ITEM_DVAR_FLAG_HIDE) else if (item->dvarFlags & ITEM_DVAR_FLAG_HIDE)
WriteStringProperty("hideDvar", item->enableDvar); WriteMultiTokenStringProperty("hideDvar", item->enableDvar);
else if (item->dvarFlags & ITEM_DVAR_FLAG_FOCUS) else if (item->dvarFlags & ITEM_DVAR_FLAG_FOCUS)
WriteStringProperty("focusDvar", item->enableDvar); WriteMultiTokenStringProperty("focusDvar", item->enableDvar);
WriteItemKeyHandlerProperty(item->onKey); WriteItemKeyHandlerProperty(item->onKey);
WriteStatementProperty("exp text", item->textExp, false); WriteStatementProperty("exp text", item->textExp, false);
@ -744,6 +774,7 @@ void MenuDumper::WriteMenuData(const menuDef_t* menu)
WriteColorProperty("forecolor", menu->window.foreColor, COLOR_1111); WriteColorProperty("forecolor", menu->window.foreColor, COLOR_1111);
WriteColorProperty("bordercolor", menu->window.borderColor, COLOR_0000); WriteColorProperty("bordercolor", menu->window.borderColor, COLOR_0000);
WriteColorProperty("focuscolor", menu->data->focusColor, COLOR_0000); WriteColorProperty("focuscolor", menu->data->focusColor, COLOR_0000);
WriteColorProperty("outlinecolor", menu->window.outlineColor, COLOR_0000);
WriteMaterialProperty("background", menu->window.background); WriteMaterialProperty("background", menu->window.background);
WriteIntProperty("ownerdraw", menu->window.ownerDraw, 0); WriteIntProperty("ownerdraw", menu->window.ownerDraw, 0);
WriteFlagsProperty("ownerdrawFlag", menu->window.ownerDrawFlags); WriteFlagsProperty("ownerdrawFlag", menu->window.ownerDrawFlags);
@ -761,7 +792,12 @@ void MenuDumper::WriteMenuData(const menuDef_t* menu)
WriteKeywordProperty("hiddenDuringUI", menu->window.staticFlags & WINDOW_FLAG_HIDDEN_DURING_UI); WriteKeywordProperty("hiddenDuringUI", menu->window.staticFlags & WINDOW_FLAG_HIDDEN_DURING_UI);
WriteStringProperty("allowedBinding", menu->data->allowedBinding); WriteStringProperty("allowedBinding", menu->data->allowedBinding);
WriteKeywordProperty("textOnlyFocus", menu->window.staticFlags & WINDOW_FLAG_TEXT_ONLY_FOCUS); WriteKeywordProperty("textOnlyFocus", menu->window.staticFlags & WINDOW_FLAG_TEXT_ONLY_FOCUS);
WriteStatementProperty("visible", menu->data->visibleExp, true);
if (menu->data->visibleExp)
WriteStatementProperty("visible", menu->data->visibleExp, true);
else if (menu->window.dynamicFlags[0] & WINDOW_FLAG_VISIBLE)
WriteIntProperty("visible", 1, 0);
WriteStatementProperty("exp rect X", menu->data->rectXExp, false); WriteStatementProperty("exp rect X", menu->data->rectXExp, false);
WriteStatementProperty("exp rect Y", menu->data->rectYExp, false); WriteStatementProperty("exp rect Y", menu->data->rectYExp, false);
WriteStatementProperty("exp rect W", menu->data->rectWExp, false); WriteStatementProperty("exp rect W", menu->data->rectWExp, false);

View File

@ -29,6 +29,7 @@ namespace IW5
void WriteSoundAliasProperty(const std::string& propertyKey, const snd_alias_list_t* soundAliasValue) const; void WriteSoundAliasProperty(const std::string& propertyKey, const snd_alias_list_t* soundAliasValue) const;
void WriteDecodeEffectProperty(const std::string& propertyKey, const itemDef_s* item) const; void WriteDecodeEffectProperty(const std::string& propertyKey, const itemDef_s* item) const;
void WriteItemKeyHandlerProperty(const ItemKeyHandler* itemKeyHandlerValue); void WriteItemKeyHandlerProperty(const ItemKeyHandler* itemKeyHandlerValue);
void WriteMultiTokenStringProperty(const std::string& propertyKey, const char* value) const;
void WriteFloatExpressionsProperty(const ItemFloatExpression* floatExpressions, int floatExpressionCount) const; void WriteFloatExpressionsProperty(const ItemFloatExpression* floatExpressions, int floatExpressionCount) const;
void WriteColumnProperty(const std::string& propertyKey, const listBoxDef_s* listBox) const; void WriteColumnProperty(const std::string& propertyKey, const listBoxDef_s* listBox) const;