mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-08-01 12:50:36 +00:00
fix(menu): allow IW4 columns without alignment (#932)
* fix(menu): allow IW4 columns without alignment * feat: also make alignment optional for iw5 menus * chore: move menu sequences to anonymous namespace if possible --------- Co-authored-by: Jan Laupetin <[email protected]>
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
using namespace menu;
|
using namespace menu;
|
||||||
|
|
||||||
namespace menu
|
namespace
|
||||||
{
|
{
|
||||||
enum class ExpectedScriptToken
|
enum class ExpectedScriptToken
|
||||||
{
|
{
|
||||||
@@ -195,14 +195,9 @@ namespace menu
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace menu
|
|
||||||
|
|
||||||
namespace menu::event_handler_set_scope_sequences
|
|
||||||
{
|
|
||||||
class SequenceCloseBlock final : public MenuFileParser::sequence_t
|
class SequenceCloseBlock final : public MenuFileParser::sequence_t
|
||||||
{
|
{
|
||||||
static constexpr auto CAPTURE_TOKEN = 1;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SequenceCloseBlock()
|
SequenceCloseBlock()
|
||||||
{
|
{
|
||||||
@@ -922,9 +917,7 @@ namespace menu::event_handler_set_scope_sequences
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace menu::event_handler_set_scope_sequences
|
} // namespace
|
||||||
|
|
||||||
using namespace event_handler_set_scope_sequences;
|
|
||||||
|
|
||||||
EventHandlerSetScopeSequences::EventHandlerSetScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
EventHandlerSetScopeSequences::EventHandlerSetScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
||||||
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
using namespace menu;
|
using namespace menu;
|
||||||
|
|
||||||
namespace menu::function_scope_sequences
|
namespace
|
||||||
{
|
{
|
||||||
class SequenceCloseBlock final : public MenuFileParser::sequence_t
|
class SequenceCloseBlock final : public MenuFileParser::sequence_t
|
||||||
{
|
{
|
||||||
@@ -69,9 +69,7 @@ namespace menu::function_scope_sequences
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace menu::function_scope_sequences
|
} // namespace
|
||||||
|
|
||||||
using namespace function_scope_sequences;
|
|
||||||
|
|
||||||
FunctionScopeSequences::FunctionScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
FunctionScopeSequences::FunctionScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
||||||
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
||||||
@@ -79,7 +77,7 @@ FunctionScopeSequences::FunctionScopeSequences(std::vector<std::unique_ptr<MenuF
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive) const
|
void FunctionScopeSequences::AddSequences(const FeatureLevel featureLevel, const bool permissive) const
|
||||||
{
|
{
|
||||||
AddSequence(std::make_unique<SequenceCloseBlock>());
|
AddSequence(std::make_unique<SequenceCloseBlock>());
|
||||||
AddSequence(std::make_unique<GenericStringPropertySequence>("name",
|
AddSequence(std::make_unique<GenericStringPropertySequence>("name",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
using namespace menu;
|
using namespace menu;
|
||||||
|
|
||||||
namespace menu::global_scope_sequences
|
namespace
|
||||||
{
|
{
|
||||||
class SequenceCloseBlock final : public MenuFileParser::sequence_t
|
class SequenceCloseBlock final : public MenuFileParser::sequence_t
|
||||||
{
|
{
|
||||||
@@ -98,9 +98,7 @@ namespace menu::global_scope_sequences
|
|||||||
state->m_menus_to_load.emplace_back(menuNameToken.StringValue());
|
state->m_menus_to_load.emplace_back(menuNameToken.StringValue());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace menu::global_scope_sequences
|
} // namespace
|
||||||
|
|
||||||
using namespace global_scope_sequences;
|
|
||||||
|
|
||||||
GlobalScopeSequences::GlobalScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
GlobalScopeSequences::GlobalScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
||||||
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
||||||
@@ -108,7 +106,7 @@ GlobalScopeSequences::GlobalScopeSequences(std::vector<std::unique_ptr<MenuFileP
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive) const
|
void GlobalScopeSequences::AddSequences(const FeatureLevel featureLevel, const bool permissive) const
|
||||||
{
|
{
|
||||||
AddSequence(std::make_unique<SequenceCloseBlock>());
|
AddSequence(std::make_unique<SequenceCloseBlock>());
|
||||||
AddSequence(std::make_unique<SequenceFunctionDef>());
|
AddSequence(std::make_unique<SequenceFunctionDef>());
|
||||||
|
|||||||
@@ -12,148 +12,149 @@
|
|||||||
#include "Parsing/Menu/MenuFileCommonOperations.h"
|
#include "Parsing/Menu/MenuFileCommonOperations.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <format>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace menu;
|
using namespace menu;
|
||||||
|
|
||||||
constexpr auto ITEM_TYPE_OWNERDRAW = 8;
|
namespace
|
||||||
|
|
||||||
class ItemScopeOperations
|
|
||||||
{
|
{
|
||||||
inline static const CommonItemFeatureType IW4_FEATURE_TYPE_BY_TYPE[0x18]{
|
constexpr auto ITEM_TYPE_OWNERDRAW = 8;
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
inline static const CommonItemFeatureType IW5_FEATURE_TYPE_BY_TYPE[0x18]{
|
class ItemScopeOperations
|
||||||
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:
|
|
||||||
static void SetItemType(CommonItemDef& item, const FeatureLevel featureLevel, const TokenPos& pos, const int type)
|
|
||||||
{
|
{
|
||||||
if (type < 0)
|
inline static const CommonItemFeatureType IW4_FEATURE_TYPE_BY_TYPE[0x18]{
|
||||||
throw ParsingException(pos, "Invalid item type");
|
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
|
||||||
|
};
|
||||||
|
|
||||||
if (item.m_feature_type != CommonItemFeatureType::NONE)
|
inline static const CommonItemFeatureType IW5_FEATURE_TYPE_BY_TYPE[0x18]{
|
||||||
throw ParsingException(pos, "Item type has already been set");
|
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
|
||||||
|
};
|
||||||
|
|
||||||
item.m_type = type;
|
public:
|
||||||
|
static void SetItemType(CommonItemDef& item, const FeatureLevel featureLevel, const TokenPos& pos, const int type)
|
||||||
switch (featureLevel)
|
|
||||||
{
|
{
|
||||||
case FeatureLevel::IW4:
|
if (type < 0)
|
||||||
if (static_cast<unsigned>(type) >= std::extent_v<decltype(IW4_FEATURE_TYPE_BY_TYPE)>)
|
|
||||||
throw ParsingException(pos, "Invalid item type");
|
throw ParsingException(pos, "Invalid item type");
|
||||||
item.m_feature_type = IW4_FEATURE_TYPE_BY_TYPE[static_cast<unsigned>(type)];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FeatureLevel::IW5:
|
if (item.m_feature_type != CommonItemFeatureType::NONE)
|
||||||
default:
|
throw ParsingException(pos, "Item type has already been set");
|
||||||
if (static_cast<unsigned>(type) >= std::extent_v<decltype(IW5_FEATURE_TYPE_BY_TYPE)>)
|
|
||||||
throw ParsingException(pos, "Invalid item type");
|
item.m_type = type;
|
||||||
item.m_feature_type = IW5_FEATURE_TYPE_BY_TYPE[static_cast<unsigned>(type)];
|
|
||||||
break;
|
switch (featureLevel)
|
||||||
|
{
|
||||||
|
case FeatureLevel::IW4:
|
||||||
|
if (static_cast<unsigned>(type) >= std::extent_v<decltype(IW4_FEATURE_TYPE_BY_TYPE)>)
|
||||||
|
throw ParsingException(pos, "Invalid item type");
|
||||||
|
item.m_feature_type = IW4_FEATURE_TYPE_BY_TYPE[static_cast<unsigned>(type)];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FeatureLevel::IW5:
|
||||||
|
default:
|
||||||
|
if (static_cast<unsigned>(type) >= std::extent_v<decltype(IW5_FEATURE_TYPE_BY_TYPE)>)
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
case CommonItemFeatureType::LISTBOX:
|
||||||
|
item.m_list_box_features = std::make_unique<CommonItemFeaturesListBox>();
|
||||||
|
break;
|
||||||
|
case CommonItemFeatureType::EDIT_FIELD:
|
||||||
|
item.m_edit_field_features = std::make_unique<CommonItemFeaturesEditField>();
|
||||||
|
break;
|
||||||
|
case CommonItemFeatureType::MULTI_VALUE:
|
||||||
|
item.m_multi_value_features = std::make_unique<CommonItemFeaturesMultiValue>();
|
||||||
|
break;
|
||||||
|
case CommonItemFeatureType::NEWS_TICKER:
|
||||||
|
item.m_news_ticker_features = std::make_unique<CommonItemFeaturesNewsTicker>();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (item.m_feature_type)
|
static void EnsureHasListboxFeatures(const CommonItemDef& item, const TokenPos& pos)
|
||||||
{
|
{
|
||||||
case CommonItemFeatureType::LISTBOX:
|
if (item.m_feature_type != CommonItemFeatureType::LISTBOX || !item.m_list_box_features)
|
||||||
item.m_list_box_features = std::make_unique<CommonItemFeaturesListBox>();
|
throw ParsingException(pos, "Item must have be listbox to use this declaration");
|
||||||
break;
|
|
||||||
case CommonItemFeatureType::EDIT_FIELD:
|
|
||||||
item.m_edit_field_features = std::make_unique<CommonItemFeaturesEditField>();
|
|
||||||
break;
|
|
||||||
case CommonItemFeatureType::MULTI_VALUE:
|
|
||||||
item.m_multi_value_features = std::make_unique<CommonItemFeaturesMultiValue>();
|
|
||||||
break;
|
|
||||||
case CommonItemFeatureType::NEWS_TICKER:
|
|
||||||
item.m_news_ticker_features = std::make_unique<CommonItemFeaturesNewsTicker>();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void EnsureHasListboxFeatures(const CommonItemDef& item, const TokenPos& pos)
|
static void EnsureHasEditFieldFeatures(const CommonItemDef& item, const TokenPos& pos)
|
||||||
{
|
{
|
||||||
if (item.m_feature_type != CommonItemFeatureType::LISTBOX || !item.m_list_box_features)
|
if (item.m_feature_type != CommonItemFeatureType::EDIT_FIELD || !item.m_edit_field_features)
|
||||||
throw ParsingException(pos, "Item must have be listbox to use this declaration");
|
throw ParsingException(pos, "Item must have be edit field to use this declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EnsureHasEditFieldFeatures(const CommonItemDef& item, const TokenPos& pos)
|
static void EnsureHasMultiValueFeatures(const CommonItemDef& item, const TokenPos& pos)
|
||||||
{
|
{
|
||||||
if (item.m_feature_type != CommonItemFeatureType::EDIT_FIELD || !item.m_edit_field_features)
|
if (item.m_feature_type != CommonItemFeatureType::MULTI_VALUE || !item.m_multi_value_features)
|
||||||
throw ParsingException(pos, "Item must have be edit field to use this declaration");
|
throw ParsingException(pos, "Item must have be multi value to use this declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EnsureHasMultiValueFeatures(const CommonItemDef& item, const TokenPos& pos)
|
static void EnsureHasEnumDvarFeatures(const CommonItemDef& item, const TokenPos& pos)
|
||||||
{
|
{
|
||||||
if (item.m_feature_type != CommonItemFeatureType::MULTI_VALUE || !item.m_multi_value_features)
|
if (item.m_feature_type != CommonItemFeatureType::ENUM_DVAR)
|
||||||
throw ParsingException(pos, "Item must have be multi value to use this declaration");
|
throw ParsingException(pos, "Item must have be enum dvar to use this declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EnsureHasEnumDvarFeatures(const CommonItemDef& item, const TokenPos& pos)
|
static void EnsureHasNewsTickerFeatures(const CommonItemDef& item, const TokenPos& pos)
|
||||||
{
|
{
|
||||||
if (item.m_feature_type != CommonItemFeatureType::ENUM_DVAR)
|
if (item.m_feature_type != CommonItemFeatureType::NEWS_TICKER || !item.m_news_ticker_features)
|
||||||
throw ParsingException(pos, "Item must have be enum dvar to use this declaration");
|
throw ParsingException(pos, "Item must have be news ticker to use this declaration");
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void EnsureHasNewsTickerFeatures(const CommonItemDef& item, const TokenPos& pos)
|
|
||||||
{
|
|
||||||
if (item.m_feature_type != CommonItemFeatureType::NEWS_TICKER || !item.m_news_ticker_features)
|
|
||||||
throw ParsingException(pos, "Item must have be news ticker to use this declaration");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace menu::item_scope_sequences
|
|
||||||
{
|
|
||||||
class SequenceCloseBlock final : public MenuFileParser::sequence_t
|
class SequenceCloseBlock final : public MenuFileParser::sequence_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -449,94 +450,106 @@ namespace menu::item_scope_sequences
|
|||||||
|
|
||||||
class SequenceColumns final : public MenuFileParser::sequence_t
|
class SequenceColumns final : public MenuFileParser::sequence_t
|
||||||
{
|
{
|
||||||
static constexpr auto TAG_COLUMN = 1;
|
static constexpr auto TAG_VALUE = 1;
|
||||||
|
|
||||||
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 const char* SYNTAX_IW4 = "<xpos> <width> <maxChars> [alignment]";
|
||||||
|
static constexpr auto BASE_COLUMN_COUNT_IW4 = 3;
|
||||||
|
|
||||||
|
static constexpr const char* SYNTAX_IW5 = "<xpos> <ypos> <width> <height> <maxChars> [alignment]";
|
||||||
|
static constexpr auto BASE_COLUMN_COUNT_IW5 = 5;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SequenceColumns(const FeatureLevel featureLevel)
|
explicit SequenceColumns()
|
||||||
{
|
{
|
||||||
const MenuMatcherFactory create(this);
|
const MenuMatcherFactory create(this);
|
||||||
AddLabeledMatchers(MenuExpressionMatchers().Expression(this), MenuExpressionMatchers::LABEL_EXPRESSION);
|
AddLabeledMatchers(MenuExpressionMatchers().Expression(this), MenuExpressionMatchers::LABEL_EXPRESSION);
|
||||||
|
|
||||||
if (featureLevel == FeatureLevel::IW5)
|
AddMatchers({
|
||||||
{
|
create.KeywordIgnoreCase("columns").Capture(CAPTURE_FIRST_TOKEN),
|
||||||
AddMatchers({
|
create.Integer().Capture(CAPTURE_COLUMN_COUNT),
|
||||||
create.KeywordIgnoreCase("columns").Capture(CAPTURE_FIRST_TOKEN),
|
create.Loop(create.IntExpression().Tag(TAG_VALUE)),
|
||||||
create.Integer().Capture(CAPTURE_COLUMN_COUNT),
|
});
|
||||||
create.Loop(create.And({
|
|
||||||
create.True().Tag(TAG_COLUMN),
|
|
||||||
create.IntExpression(), // xpos
|
|
||||||
create.IntExpression(), // ypos
|
|
||||||
create.IntExpression(), // width
|
|
||||||
create.IntExpression(), // height
|
|
||||||
create.IntExpression(), // maxChars
|
|
||||||
create.IntExpression(), // alignment
|
|
||||||
})),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddMatchers({
|
|
||||||
create.KeywordIgnoreCase("columns").Capture(CAPTURE_FIRST_TOKEN),
|
|
||||||
create.Integer().Capture(CAPTURE_COLUMN_COUNT),
|
|
||||||
create.Loop(create.And({
|
|
||||||
create.True().Tag(TAG_COLUMN),
|
|
||||||
create.IntExpression(), // xpos
|
|
||||||
create.IntExpression(), // width
|
|
||||||
create.IntExpression(), // maxChars
|
|
||||||
create.IntExpression(), // alignment
|
|
||||||
})),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||||
{
|
{
|
||||||
assert(state->m_current_item);
|
assert(state->m_current_item);
|
||||||
|
|
||||||
ItemScopeOperations::EnsureHasListboxFeatures(*state->m_current_item, result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos());
|
|
||||||
|
|
||||||
assert(state->m_feature_level == FeatureLevel::IW4 || state->m_feature_level == FeatureLevel::IW5);
|
assert(state->m_feature_level == FeatureLevel::IW4 || state->m_feature_level == FeatureLevel::IW5);
|
||||||
|
|
||||||
const auto& listBoxFeatures = state->m_current_item->m_list_box_features;
|
const auto& firstToken = result.NextCapture(CAPTURE_FIRST_TOKEN);
|
||||||
while (result.PeekAndRemoveIfTag(TAG_COLUMN) == TAG_COLUMN)
|
ItemScopeOperations::EnsureHasListboxFeatures(*state->m_current_item, firstToken.GetPos());
|
||||||
|
|
||||||
|
const auto columnCount = static_cast<size_t>(result.NextCapture(CAPTURE_COLUMN_COUNT).IntegerValue());
|
||||||
|
std::vector<int> columnValues;
|
||||||
|
while (result.PeekAndRemoveIfTag(TAG_VALUE) == TAG_VALUE)
|
||||||
|
columnValues.emplace_back(MenuMatcherFactory::TokenIntExpressionValue(state, result));
|
||||||
|
|
||||||
|
size_t baseColumnCount;
|
||||||
|
const char* syntax;
|
||||||
|
bool hasHeightValues;
|
||||||
|
if (state->m_feature_level == FeatureLevel::IW4)
|
||||||
{
|
{
|
||||||
int xPos = 0;
|
baseColumnCount = BASE_COLUMN_COUNT_IW4;
|
||||||
int yPos = 0;
|
syntax = SYNTAX_IW4;
|
||||||
int width = 0;
|
hasHeightValues = false;
|
||||||
int height = 0;
|
}
|
||||||
int maxChars = 0;
|
else
|
||||||
int alignment = 0;
|
{
|
||||||
|
assert(state->m_feature_level == FeatureLevel::IW5);
|
||||||
|
baseColumnCount = BASE_COLUMN_COUNT_IW5;
|
||||||
|
syntax = SYNTAX_IW5;
|
||||||
|
hasHeightValues = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (state->m_feature_level == FeatureLevel::IW4)
|
bool hasAlignmentSpecified;
|
||||||
{
|
if (columnValues.size() == columnCount * (baseColumnCount + 1))
|
||||||
xPos = MenuMatcherFactory::TokenIntExpressionValue(state, result);
|
hasAlignmentSpecified = true;
|
||||||
width = MenuMatcherFactory::TokenIntExpressionValue(state, result);
|
else if (columnValues.size() == columnCount * baseColumnCount)
|
||||||
maxChars = MenuMatcherFactory::TokenIntExpressionValue(state, result);
|
hasAlignmentSpecified = false;
|
||||||
alignment = MenuMatcherFactory::TokenIntExpressionValue(state, result);
|
else
|
||||||
}
|
throw ParsingException(firstToken.GetPos(), std::format("Each row must have the following syntax: {}", syntax));
|
||||||
else if (state->m_feature_level == FeatureLevel::IW5)
|
|
||||||
{
|
|
||||||
xPos = MenuMatcherFactory::TokenIntExpressionValue(state, result);
|
|
||||||
yPos = MenuMatcherFactory::TokenIntExpressionValue(state, result);
|
|
||||||
width = MenuMatcherFactory::TokenIntExpressionValue(state, result);
|
|
||||||
height = MenuMatcherFactory::TokenIntExpressionValue(state, result);
|
|
||||||
maxChars = MenuMatcherFactory::TokenIntExpressionValue(state, result);
|
|
||||||
alignment = MenuMatcherFactory::TokenIntExpressionValue(state, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
CommonItemFeaturesListBox::Column column{
|
const auto& listBoxFeatures = state->m_current_item->m_list_box_features;
|
||||||
xPos,
|
|
||||||
yPos,
|
size_t valueIndex = 0u;
|
||||||
width,
|
for (auto columnIndex = 0u; columnIndex < columnCount; columnIndex++)
|
||||||
height,
|
{
|
||||||
maxChars,
|
const auto xPos = columnValues[valueIndex++];
|
||||||
alignment,
|
|
||||||
};
|
int yPos;
|
||||||
listBoxFeatures->m_columns.emplace_back(column);
|
if (hasHeightValues)
|
||||||
|
yPos = columnValues[valueIndex++];
|
||||||
|
else
|
||||||
|
yPos = 0;
|
||||||
|
|
||||||
|
const auto width = columnValues[valueIndex++];
|
||||||
|
|
||||||
|
int height;
|
||||||
|
if (hasHeightValues)
|
||||||
|
height = columnValues[valueIndex++];
|
||||||
|
else
|
||||||
|
height = 0;
|
||||||
|
|
||||||
|
const auto maxChars = columnValues[valueIndex++];
|
||||||
|
|
||||||
|
int alignment;
|
||||||
|
if (hasAlignmentSpecified)
|
||||||
|
alignment = columnValues[valueIndex++];
|
||||||
|
else
|
||||||
|
alignment = 0;
|
||||||
|
|
||||||
|
listBoxFeatures->m_columns.emplace_back(CommonItemFeaturesListBox::Column{
|
||||||
|
.m_x_pos = xPos,
|
||||||
|
.m_y_pos = yPos,
|
||||||
|
.m_width = width,
|
||||||
|
.m_height = height,
|
||||||
|
.m_max_chars = maxChars,
|
||||||
|
.m_alignment = alignment,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -573,7 +586,7 @@ namespace menu::item_scope_sequences
|
|||||||
auto newEventHandlerSet = std::make_unique<CommonEventHandlerSet>();
|
auto newEventHandlerSet = std::make_unique<CommonEventHandlerSet>();
|
||||||
state->m_current_event_handler_set = newEventHandlerSet.get();
|
state->m_current_event_handler_set = newEventHandlerSet.get();
|
||||||
state->m_current_nested_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)));
|
state->m_current_item->m_key_handlers.emplace(key, std::move(newEventHandlerSet));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -607,12 +620,10 @@ namespace menu::item_scope_sequences
|
|||||||
auto newEventHandlerSet = std::make_unique<CommonEventHandlerSet>();
|
auto newEventHandlerSet = std::make_unique<CommonEventHandlerSet>();
|
||||||
state->m_current_event_handler_set = newEventHandlerSet.get();
|
state->m_current_event_handler_set = newEventHandlerSet.get();
|
||||||
state->m_current_nested_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)));
|
state->m_current_item->m_key_handlers.emplace(keyValue, std::move(newEventHandlerSet));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace menu::item_scope_sequences
|
} // namespace
|
||||||
|
|
||||||
using namespace item_scope_sequences;
|
|
||||||
|
|
||||||
ItemScopeSequences::ItemScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
ItemScopeSequences::ItemScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
||||||
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
||||||
@@ -620,7 +631,7 @@ ItemScopeSequences::ItemScopeSequences(std::vector<std::unique_ptr<MenuFileParse
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive) const
|
void ItemScopeSequences::AddSequences(const FeatureLevel featureLevel, const bool permissive) const
|
||||||
{
|
{
|
||||||
AddSequence(std::make_unique<SequenceCloseBlock>());
|
AddSequence(std::make_unique<SequenceCloseBlock>());
|
||||||
AddSequence(std::make_unique<GenericStringPropertySequence>("name",
|
AddSequence(std::make_unique<GenericStringPropertySequence>("name",
|
||||||
@@ -746,32 +757,32 @@ void ItemScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive
|
|||||||
state->m_current_item->m_text_font = value;
|
state->m_current_item->m_text_font = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<GenericColorPropertySequence>("backcolor",
|
AddSequence(std::make_unique<GenericColorPropertySequence>("backcolor",
|
||||||
[](const MenuFileParserState* state, const TokenPos&, const CommonColor value)
|
[](const MenuFileParserState* state, const TokenPos&, const CommonColor& value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_back_color = value;
|
state->m_current_item->m_back_color = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<GenericColorPropertySequence>("forecolor",
|
AddSequence(std::make_unique<GenericColorPropertySequence>("forecolor",
|
||||||
[](const MenuFileParserState* state, const TokenPos&, const CommonColor value)
|
[](const MenuFileParserState* state, const TokenPos&, const CommonColor& value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_fore_color = value;
|
state->m_current_item->m_fore_color = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<GenericColorPropertySequence>("bordercolor",
|
AddSequence(std::make_unique<GenericColorPropertySequence>("bordercolor",
|
||||||
[](const MenuFileParserState* state, const TokenPos&, const CommonColor value)
|
[](const MenuFileParserState* state, const TokenPos&, const CommonColor& value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_border_color = value;
|
state->m_current_item->m_border_color = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<GenericColorPropertySequence>("outlinecolor",
|
AddSequence(std::make_unique<GenericColorPropertySequence>("outlinecolor",
|
||||||
[](const MenuFileParserState* state, const TokenPos&, const CommonColor value)
|
[](const MenuFileParserState* state, const TokenPos&, const CommonColor& value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_outline_color = value;
|
state->m_current_item->m_outline_color = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<GenericColorPropertySequence>("disablecolor",
|
AddSequence(std::make_unique<GenericColorPropertySequence>("disablecolor",
|
||||||
[](const MenuFileParserState* state, const TokenPos&, const CommonColor value)
|
[](const MenuFileParserState* state, const TokenPos&, const CommonColor& value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_disable_color = value;
|
state->m_current_item->m_disable_color = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<GenericColorPropertySequence>("glowcolor",
|
AddSequence(std::make_unique<GenericColorPropertySequence>("glowcolor",
|
||||||
[](const MenuFileParserState* state, const TokenPos&, const CommonColor value)
|
[](const MenuFileParserState* state, const TokenPos&, const CommonColor& value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_glow_color = value;
|
state->m_current_item->m_glow_color = value;
|
||||||
}));
|
}));
|
||||||
@@ -1060,7 +1071,7 @@ void ItemScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============== ListBox ==============
|
// ============== ListBox ==============
|
||||||
AddSequence(std::make_unique<SequenceColumns>(featureLevel));
|
AddSequence(std::make_unique<SequenceColumns>());
|
||||||
AddSequence(std::make_unique<GenericKeywordPropertySequence>("notselectable",
|
AddSequence(std::make_unique<GenericKeywordPropertySequence>("notselectable",
|
||||||
[](const MenuFileParserState* state, const TokenPos& pos)
|
[](const MenuFileParserState* state, const TokenPos& pos)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
using namespace menu;
|
using namespace menu;
|
||||||
|
|
||||||
namespace menu::menu_scope_sequences
|
namespace
|
||||||
{
|
{
|
||||||
class SequenceCloseBlock final : public MenuFileParser::sequence_t
|
class SequenceCloseBlock final : public MenuFileParser::sequence_t
|
||||||
{
|
{
|
||||||
@@ -72,8 +72,6 @@ namespace menu::menu_scope_sequences
|
|||||||
|
|
||||||
class SequenceItemDef final : public MenuFileParser::sequence_t
|
class SequenceItemDef final : public MenuFileParser::sequence_t
|
||||||
{
|
{
|
||||||
static constexpr auto CAPTURE_TOKEN = 1;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SequenceItemDef()
|
SequenceItemDef()
|
||||||
{
|
{
|
||||||
@@ -208,9 +206,7 @@ namespace menu::menu_scope_sequences
|
|||||||
state->m_current_menu->m_key_handlers.emplace(std::make_pair(keyValue, std::move(newEventHandlerSet)));
|
state->m_current_menu->m_key_handlers.emplace(std::make_pair(keyValue, std::move(newEventHandlerSet)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace menu::menu_scope_sequences
|
} // namespace
|
||||||
|
|
||||||
using namespace menu_scope_sequences;
|
|
||||||
|
|
||||||
MenuScopeSequences::MenuScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
MenuScopeSequences::MenuScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
||||||
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
||||||
@@ -218,7 +214,7 @@ MenuScopeSequences::MenuScopeSequences(std::vector<std::unique_ptr<MenuFileParse
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive) const
|
void MenuScopeSequences::AddSequences(const FeatureLevel featureLevel, const bool permissive) const
|
||||||
{
|
{
|
||||||
AddSequence(std::make_unique<SequenceCloseBlock>());
|
AddSequence(std::make_unique<SequenceCloseBlock>());
|
||||||
AddSequence(std::make_unique<SequenceItemDef>());
|
AddSequence(std::make_unique<SequenceItemDef>());
|
||||||
@@ -294,27 +290,27 @@ void MenuScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive
|
|||||||
state->m_current_menu->m_border_size = value;
|
state->m_current_menu->m_border_size = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<GenericColorPropertySequence>("backcolor",
|
AddSequence(std::make_unique<GenericColorPropertySequence>("backcolor",
|
||||||
[](const MenuFileParserState* state, const TokenPos&, const CommonColor value)
|
[](const MenuFileParserState* state, const TokenPos&, const CommonColor& value)
|
||||||
{
|
{
|
||||||
state->m_current_menu->m_back_color = value;
|
state->m_current_menu->m_back_color = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<GenericColorPropertySequence>("forecolor",
|
AddSequence(std::make_unique<GenericColorPropertySequence>("forecolor",
|
||||||
[](const MenuFileParserState* state, const TokenPos&, const CommonColor value)
|
[](const MenuFileParserState* state, const TokenPos&, const CommonColor& value)
|
||||||
{
|
{
|
||||||
state->m_current_menu->m_fore_color = value;
|
state->m_current_menu->m_fore_color = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<GenericColorPropertySequence>("bordercolor",
|
AddSequence(std::make_unique<GenericColorPropertySequence>("bordercolor",
|
||||||
[](const MenuFileParserState* state, const TokenPos&, const CommonColor value)
|
[](const MenuFileParserState* state, const TokenPos&, const CommonColor& value)
|
||||||
{
|
{
|
||||||
state->m_current_menu->m_border_color = value;
|
state->m_current_menu->m_border_color = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<GenericColorPropertySequence>("focuscolor",
|
AddSequence(std::make_unique<GenericColorPropertySequence>("focuscolor",
|
||||||
[](const MenuFileParserState* state, const TokenPos&, const CommonColor value)
|
[](const MenuFileParserState* state, const TokenPos&, const CommonColor& value)
|
||||||
{
|
{
|
||||||
state->m_current_menu->m_focus_color = value;
|
state->m_current_menu->m_focus_color = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<GenericColorPropertySequence>("outlinecolor",
|
AddSequence(std::make_unique<GenericColorPropertySequence>("outlinecolor",
|
||||||
[](const MenuFileParserState* state, const TokenPos&, const CommonColor value)
|
[](const MenuFileParserState* state, const TokenPos&, const CommonColor& value)
|
||||||
{
|
{
|
||||||
state->m_current_menu->m_outline_color = value;
|
state->m_current_menu->m_outline_color = value;
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
using namespace menu;
|
using namespace menu;
|
||||||
|
|
||||||
namespace menu::no_scope_sequences
|
namespace
|
||||||
{
|
{
|
||||||
class SequenceOpenGlobalScope final : public MenuFileParser::sequence_t
|
class SequenceOpenGlobalScope final : public MenuFileParser::sequence_t
|
||||||
{
|
{
|
||||||
@@ -25,9 +25,7 @@ namespace menu::no_scope_sequences
|
|||||||
state->m_in_global_scope = true;
|
state->m_in_global_scope = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace menu::no_scope_sequences
|
} // namespace
|
||||||
|
|
||||||
using namespace no_scope_sequences;
|
|
||||||
|
|
||||||
NoScopeSequences::NoScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
NoScopeSequences::NoScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences,
|
||||||
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
std::vector<MenuFileParser::sequence_t*>& scopeSequences)
|
||||||
@@ -35,7 +33,7 @@ NoScopeSequences::NoScopeSequences(std::vector<std::unique_ptr<MenuFileParser::s
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive) const
|
void NoScopeSequences::AddSequences(const FeatureLevel featureLevel, const bool permissive) const
|
||||||
{
|
{
|
||||||
AddSequence(std::make_unique<SequenceOpenGlobalScope>());
|
AddSequence(std::make_unique<SequenceOpenGlobalScope>());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -331,6 +331,59 @@ namespace test::game::iw4::menu::parsing::it
|
|||||||
REQUIRE(item->dvarFlags == ITEM_DVAR_FLAG_FOCUS);
|
REQUIRE(item->dvarFlags == ITEM_DVAR_FLAG_FOCUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("MenuParsingIW4IT: Can omit list box column alignment", "[parsing][converting][menu][it]")
|
||||||
|
{
|
||||||
|
MenuParsingItHelper helper;
|
||||||
|
|
||||||
|
helper.AddFile(R"testmenu(
|
||||||
|
{
|
||||||
|
menuDef
|
||||||
|
{
|
||||||
|
name "ListBoxColumns"
|
||||||
|
itemDef
|
||||||
|
{
|
||||||
|
type 6
|
||||||
|
// x, width, max chars
|
||||||
|
columns 1 22 190 64
|
||||||
|
}
|
||||||
|
itemDef
|
||||||
|
{
|
||||||
|
type 6
|
||||||
|
// x, width, max chars, alignment
|
||||||
|
columns 2 0 18 3 2 18 25 10 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)testmenu");
|
||||||
|
|
||||||
|
const auto result = helper.RunIntegrationTest();
|
||||||
|
REQUIRE(result.HasBeenSuccessful());
|
||||||
|
|
||||||
|
const auto* menu = helper.GetMenuAsset("ListBoxColumns");
|
||||||
|
REQUIRE(menu->itemCount == 2);
|
||||||
|
REQUIRE(menu->items != nullptr);
|
||||||
|
|
||||||
|
const auto* columnsWithoutAlignment = menu->items[0]->typeData.listBox;
|
||||||
|
REQUIRE(columnsWithoutAlignment != nullptr);
|
||||||
|
REQUIRE(columnsWithoutAlignment->numColumns == 1);
|
||||||
|
CHECK(columnsWithoutAlignment->columnInfo[0].pos == 22);
|
||||||
|
CHECK(columnsWithoutAlignment->columnInfo[0].width == 190);
|
||||||
|
CHECK(columnsWithoutAlignment->columnInfo[0].maxChars == 64);
|
||||||
|
CHECK(columnsWithoutAlignment->columnInfo[0].alignment == 0);
|
||||||
|
|
||||||
|
const auto* columnsWithAlignment = menu->items[1]->typeData.listBox;
|
||||||
|
REQUIRE(columnsWithAlignment != nullptr);
|
||||||
|
REQUIRE(columnsWithAlignment->numColumns == 2);
|
||||||
|
CHECK(columnsWithAlignment->columnInfo[0].pos == 0);
|
||||||
|
CHECK(columnsWithAlignment->columnInfo[0].width == 18);
|
||||||
|
CHECK(columnsWithAlignment->columnInfo[0].maxChars == 3);
|
||||||
|
CHECK(columnsWithAlignment->columnInfo[0].alignment == 2);
|
||||||
|
CHECK(columnsWithAlignment->columnInfo[1].pos == 18);
|
||||||
|
CHECK(columnsWithAlignment->columnInfo[1].width == 25);
|
||||||
|
CHECK(columnsWithAlignment->columnInfo[1].maxChars == 10);
|
||||||
|
CHECK(columnsWithAlignment->columnInfo[1].alignment == 1);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("MenuParsingIW4IT: Can specify event handler multiple times", "[parsing][converting][menu][it]")
|
TEST_CASE("MenuParsingIW4IT: Can specify event handler multiple times", "[parsing][converting][menu][it]")
|
||||||
{
|
{
|
||||||
MenuParsingItHelper helper;
|
MenuParsingItHelper helper;
|
||||||
|
|||||||
Reference in New Issue
Block a user