Files
MagicSetEditor2/src/data/field/multiple_choice.cpp
T
2026-04-19 19:06:52 +02:00

120 lines
3.5 KiB
C++

//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make card games |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <data/field/multiple_choice.hpp>
// ----------------------------------------------------------------------------- : MultipleChoiceField
MultipleChoiceField::MultipleChoiceField()
: minimum_selection(0)
, maximum_selection(1000000)
{}
IMPLEMENT_FIELD_TYPE(MultipleChoice, "multiple choice");
IMPLEMENT_REFLECTION(MultipleChoiceField) {
REFLECT_BASE(ChoiceField);
REFLECT(minimum_selection);
REFLECT(maximum_selection);
REFLECT(empty_choice);
}
// ----------------------------------------------------------------------------- : MultipleChoiceStyle
MultipleChoiceStyle::MultipleChoiceStyle(const MultipleChoiceFieldP& field)
: ChoiceStyle(field)
, direction(LEFT_TO_RIGHT)
, spacing(0)
{}
IMPLEMENT_REFLECTION(MultipleChoiceStyle) {
REFLECT_BASE(ChoiceStyle);
REFLECT(direction);
REFLECT(spacing);
}
int MultipleChoiceStyle::update(Context& ctx) {
int changes = ChoiceStyle::update(ctx);
changes |= direction.update(ctx) * CHANGE_OTHER;
changes |= spacing.update(ctx) * CHANGE_OTHER;
return changes;
}
// ----------------------------------------------------------------------------- : MultipleChoiceValue
IMPLEMENT_REFLECTION_NAMELESS(MultipleChoiceValue) {
REFLECT_BASE(ChoiceValue);
}
bool MultipleChoiceValue::isDefault() {
return value.isDefault();
}
bool MultipleChoiceValue::update(Context& ctx) {
String old_value = value();
ctx.setVariable(_("last_change"), to_script(last_change));
ChoiceValue::update(ctx);
normalForm();
return value() != old_value;
}
void MultipleChoiceValue::get(vector<String>& out) const {
// split the value
out.clear();
bool is_new = true;
FOR_EACH_CONST(c, value()) {
if (c == _(',')) {
is_new = true;
} else if (is_new) {
if (c != _(' ')) { // ignore whitespace after ,
is_new = false;
out.push_back(String(1, c));
}
} else {
assert(!out.empty());
out.back() += c;
}
}
}
void MultipleChoiceValue::normalForm() {
String& val = value.mutateDontChangeDefault();
// which choices are active?
vector<bool> seen(field().choices->lastId());
for (size_t pos = 0 ; pos < val.size() ; ) {
if (val.GetChar(pos) == _(' ')) {
++pos; // ingore whitespace
} else {
// does this choice match the one asked about?
size_t end = val.find_first_of(_(','), pos);
if (end == String::npos) end = val.size();
// find this choice
for (size_t i = 0 ; i < seen.size() ; ++i) {
if (is_substr(val, pos, field().choices->choiceName((int)i))) {
seen[i] = true;
break;
}
}
pos = end + 1;
}
}
// now put them back in the right order
val.clear();
for (size_t i = 0 ; i < seen.size() ; ++i) {
if (seen[i]) {
if (!val.empty()) val += _(", ");
val += field().choices->choiceName((int)i);
}
}
// empty choice name
if (val.empty()) {
val = field().empty_choice;
}
}