Commit 3a3aacc2 authored by twanvl's avatar twanvl

added FieldP to values and styles, implemented reflection for IndexMap

parent e00fadbe
...@@ -355,8 +355,8 @@ void DuplicateSymbolPartsAction::getParts(set<SymbolPartP>& parts) { ...@@ -355,8 +355,8 @@ void DuplicateSymbolPartsAction::getParts(set<SymbolPartP>& parts) {
// ----------------------------------------------------------------------------- : Reorder symbol parts // ----------------------------------------------------------------------------- : Reorder symbol parts
ReorderSymbolPartsAction::ReorderSymbolPartsAction(Symbol& symbol, size_t partId1, size_t partId2) ReorderSymbolPartsAction::ReorderSymbolPartsAction(Symbol& symbol, size_t part_id1, size_t part_id2)
: symbol(symbol), partId1(partId1), partId2(partId2) : symbol(symbol), part_id1(part_id1), part_id2(part_id2)
{} {}
String ReorderSymbolPartsAction::getName(bool to_undo) const { String ReorderSymbolPartsAction::getName(bool to_undo) const {
...@@ -364,7 +364,7 @@ String ReorderSymbolPartsAction::getName(bool to_undo) const { ...@@ -364,7 +364,7 @@ String ReorderSymbolPartsAction::getName(bool to_undo) const {
} }
void ReorderSymbolPartsAction::perform(bool to_undo) { void ReorderSymbolPartsAction::perform(bool to_undo) {
assert(partId1 < symbol.parts.size()); assert(part_id1 < symbol.parts.size());
assert(partId2 < symbol.parts.size()); assert(part_id2 < symbol.parts.size());
swap(symbol.parts[partId1], symbol.parts[partId2]); swap(symbol.parts[part_id1], symbol.parts[part_id2]);
} }
...@@ -223,7 +223,7 @@ class DuplicateSymbolPartsAction : public SymbolPartListAction { ...@@ -223,7 +223,7 @@ class DuplicateSymbolPartsAction : public SymbolPartListAction {
/// Change the position of a part in a symbol, by swapping two parts. /// Change the position of a part in a symbol, by swapping two parts.
class ReorderSymbolPartsAction : public SymbolPartListAction { class ReorderSymbolPartsAction : public SymbolPartListAction {
public: public:
ReorderSymbolPartsAction(Symbol& symbol, size_t partId1, size_t partId2); ReorderSymbolPartsAction(Symbol& symbol, size_t part_id1, size_t part_id2);
virtual String getName(bool to_undo) const; virtual String getName(bool to_undo) const;
virtual void perform(bool to_undo); virtual void perform(bool to_undo);
...@@ -231,7 +231,7 @@ class ReorderSymbolPartsAction : public SymbolPartListAction { ...@@ -231,7 +231,7 @@ class ReorderSymbolPartsAction : public SymbolPartListAction {
private: private:
Symbol& symbol; ///< Symbol to swap the parts in Symbol& symbol; ///< Symbol to swap the parts in
public: public:
size_t partId1, partId2; ///< Indeces of parts to swap size_t part_id1, part_id2; ///< Indeces of parts to swap
}; };
......
...@@ -35,5 +35,6 @@ String Card::identification() const { ...@@ -35,5 +35,6 @@ String Card::identification() const {
IMPLEMENT_REFLECTION(Card) { IMPLEMENT_REFLECTION(Card) {
REFLECT(notes); REFLECT(notes);
REFLECT_NAMELESS(data);
} }
...@@ -31,20 +31,19 @@ class Card { ...@@ -31,20 +31,19 @@ class Card {
/// Creates a card using the given game /// Creates a card using the given game
Card(const Game& game); Card(const Game& game);
/// Get an identification of the card, an identification is something like a name, title, etc.
String identification() const;
/// The values on the fields of the card. /// The values on the fields of the card.
/** The indices should correspond to the cardFields in the Game */ /** The indices should correspond to the card_fields in the Game */
IndexMap<FieldP, ValueP> data; IndexMap<FieldP, ValueP> data;
/// Notes for this card /// Notes for this card
String notes; String notes;
/// Alternative style to use for this card /// Alternative style to use for this card
/** Optional; if not set use the card style from the set */ /** Optional; if not set use the card style from the set */
StyleSheetP stylesheet; StyleSheetP stylesheet;
/// Get the identification of this card, an identification is something like a name, title, etc.
/** May return "" */
String identification() const;
DECLARE_REFLECTION(); DECLARE_REFLECTION();
}; };
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <data/field.hpp> #include <data/field.hpp>
#include <data/field/text.hpp> #include <data/field/text.hpp>
#include <data/field/choice.hpp> #include <data/field/choice.hpp>
#include <data/field/multiple_choice.hpp>
#include <data/field/boolean.hpp> #include <data/field/boolean.hpp>
#include <data/field/image.hpp> #include <data/field/image.hpp>
#include <data/field/symbol.hpp> #include <data/field/symbol.hpp>
...@@ -56,21 +57,29 @@ shared_ptr<Field> read_new<Field>(Reader& reader) { ...@@ -56,21 +57,29 @@ shared_ptr<Field> read_new<Field>(Reader& reader) {
// there must be a type specified // there must be a type specified
String type; String type;
reader.handle(_("type"), type); reader.handle(_("type"), type);
if (type == _("text")) return new_shared<TextField>(); if (type == _("text")) return new_shared<TextField>();
else if (type == _("choice")) return new_shared<ChoiceField>(); else if (type == _("choice")) return new_shared<ChoiceField>();
else if (type == _("boolean")) return new_shared<BooleanField>(); else if (type == _("multiple choice")) return new_shared<MultipleChoiceField>();
else if (type == _("image")) return new_shared<ImageField>(); else if (type == _("boolean")) return new_shared<BooleanField>();
else if (type == _("symbol")) return new_shared<SymbolField>(); else if (type == _("image")) return new_shared<ImageField>();
else if (type == _("color")) return new_shared<ColorField>(); else if (type == _("symbol")) return new_shared<SymbolField>();
else if (type == _("color")) return new_shared<ColorField>();
else { else {
throw ParseError(_("Unsupported field type: '") + type + _("'")); throw ParseError(_("Unsupported field type: '") + type + _("'"));
} }
} }
// ----------------------------------------------------------------------------- : Style // ----------------------------------------------------------------------------- : Style
Style::Style(const FieldP& field)
: fieldP(field)
, z_index(0)
, left(0), width (1)
, top (0), height(1)
, visible(true)
{}
Style::~Style() {} Style::~Style() {}
IMPLEMENT_REFLECTION(Style) { IMPLEMENT_REFLECTION(Style) {
...@@ -82,9 +91,12 @@ IMPLEMENT_REFLECTION(Style) { ...@@ -82,9 +91,12 @@ IMPLEMENT_REFLECTION(Style) {
REFLECT(visible); REFLECT(visible);
} }
void initObject(const FieldP& field, StyleP& style) { void init_object(const FieldP& field, StyleP& style) {
style = field->newStyle(field); style = field->newStyle(field);
} }
template <> StyleP read_new<Style>(Reader&) {
throw InternalError(_("IndexMap contains nullptr StyleP the application should have crashed already"));
}
// ----------------------------------------------------------------------------- : Value // ----------------------------------------------------------------------------- : Value
...@@ -93,7 +105,10 @@ Value::~Value() {} ...@@ -93,7 +105,10 @@ Value::~Value() {}
IMPLEMENT_REFLECTION_NAMELESS(Value) { IMPLEMENT_REFLECTION_NAMELESS(Value) {
} }
void initObject(const FieldP& field, ValueP& value) { void init_object(const FieldP& field, ValueP& value) {
value = field->newValue(field); value = field->newValue(field);
} }
template <> ValueP read_new<Value>(Reader&) {
throw InternalError(_("IndexMap contains nullptr ValueP the application should have crashed already"));
}
...@@ -63,9 +63,11 @@ shared_ptr<Field> read_new<Field>(Reader& reader); ...@@ -63,9 +63,11 @@ shared_ptr<Field> read_new<Field>(Reader& reader);
/// Style information needed to display a Value in a Field. /// Style information needed to display a Value in a Field.
class Style { class Style {
public: public:
Style(const FieldP&);
virtual ~Style(); virtual ~Style();
int z_index; ///< Stacking of values of this field, higher = on top const FieldP fieldP; ///< Field this style is for, should have the right type!
int z_index; ///< Stacking of values of this field, higher = on top
Scriptable<double> left, top; ///< Position of this field Scriptable<double> left, top; ///< Position of this field
Scriptable<double> width, height; ///< Position of this field Scriptable<double> width, height; ///< Position of this field
Scriptable<bool> visible; ///< Is this field visible? Scriptable<bool> visible; ///< Is this field visible?
...@@ -74,14 +76,20 @@ class Style { ...@@ -74,14 +76,20 @@ class Style {
DECLARE_REFLECTION_VIRTUAL(); DECLARE_REFLECTION_VIRTUAL();
}; };
void initObject(const FieldP&, StyleP&); void init_object(const FieldP&, StyleP&);
inline const FieldP& get_key (const StyleP& s) { return s->fieldP; }
inline const String& get_key_name(const StyleP& s) { return s->fieldP->name; }
template <> StyleP read_new<Style>(Reader&);
// ----------------------------------------------------------------------------- : Value // ----------------------------------------------------------------------------- : Value
/// A specific value 'in' a Field. /// A specific value 'in' a Field.
class Value { class Value {
public: public:
inline Value(const FieldP& field) : fieldP(field) {}
virtual ~Value(); virtual ~Value();
const FieldP fieldP; ///< Field this value is for, should have the right type!
/// Convert this value to a string for use in tables /// Convert this value to a string for use in tables
virtual String toString() const = 0; virtual String toString() const = 0;
...@@ -90,7 +98,29 @@ class Value { ...@@ -90,7 +98,29 @@ class Value {
DECLARE_REFLECTION_VIRTUAL(); DECLARE_REFLECTION_VIRTUAL();
}; };
void initObject(const FieldP&, ValueP&); void init_object(const FieldP&, ValueP&);
inline const FieldP& get_key (const ValueP& v) { return v->fieldP; }
inline const String& get_key_name(const ValueP& v) { return v->fieldP->name; }
template <> ValueP read_new<Value>(Reader&);
// ----------------------------------------------------------------------------- : Utilities
// implement newStyle and newValue
#define FIELD_TYPE(Type) \
StyleP Type ## Field::newStyle(const FieldP& thisP) const { \
assert(thisP.get() == this); \
return new_shared1<Type ## Style>(static_pointer_cast<Type ## Field>(thisP)); \
} \
ValueP Type ## Field::newValue(const FieldP& thisP) const { \
assert(thisP.get() == this); \
return new_shared1<Type ## Value>(static_pointer_cast<Type ## Field>(thisP)); \
}
// implement field() which returns a field with the right (derived) type
#define HAS_FIELD(Type) \
inline Type ## Field& field() const { \
return *static_cast<Type ## Field*>(fieldP.get()); \
}
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
#endif #endif
...@@ -16,13 +16,7 @@ BooleanField::BooleanField() { ...@@ -16,13 +16,7 @@ BooleanField::BooleanField() {
choices->initIds(); choices->initIds();
} }
StyleP BooleanField::newStyle(const FieldP& thisP) const { FIELD_TYPE(Boolean)
return new_shared<BooleanStyle>();
}
ValueP BooleanField::newValue(const FieldP& thisP) const {
return new_shared<BooleanValue>();
}
String BooleanField::typeName() const { String BooleanField::typeName() const {
return _("boolean"); return _("boolean");
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
// ----------------------------------------------------------------------------- : BooleanField // ----------------------------------------------------------------------------- : BooleanField
DECLARE_POINTER_TYPE(BooleanField);
/// A field whos value is either true or false /// A field whos value is either true or false
class BooleanField : public ChoiceField { class BooleanField : public ChoiceField {
public: public:
...@@ -34,6 +36,9 @@ class BooleanField : public ChoiceField { ...@@ -34,6 +36,9 @@ class BooleanField : public ChoiceField {
/// The Style for a BooleanField /// The Style for a BooleanField
class BooleanStyle : public ChoiceStyle { class BooleanStyle : public ChoiceStyle {
public: public:
inline BooleanStyle(const ChoiceFieldP& field) : ChoiceStyle(field) {}
HAS_FIELD(Boolean)
// no extra data // no extra data
private: private:
...@@ -45,6 +50,9 @@ class BooleanStyle : public ChoiceStyle { ...@@ -45,6 +50,9 @@ class BooleanStyle : public ChoiceStyle {
/// The Value in a BooleanField /// The Value in a BooleanField
class BooleanValue : public ChoiceValue { class BooleanValue : public ChoiceValue {
public: public:
inline BooleanValue(const ChoiceFieldP& field) : ChoiceValue(field) {}
HAS_FIELD(Boolean)
// no extra data // no extra data
private: private:
......
...@@ -17,13 +17,7 @@ ChoiceField::ChoiceField() ...@@ -17,13 +17,7 @@ ChoiceField::ChoiceField()
, default_name(_("Default")) , default_name(_("Default"))
{} {}
StyleP ChoiceField::newStyle(const FieldP& thisP) const { FIELD_TYPE(Choice)
return new_shared<ChoiceStyle>();
}
ValueP ChoiceField::newValue(const FieldP& thisP) const {
return new_shared<ChoiceValue>();
}
String ChoiceField::typeName() const { String ChoiceField::typeName() const {
return _("choice"); return _("choice");
...@@ -153,8 +147,13 @@ template <> void GetMember::handle(const ChoiceField::Choice& c) { ...@@ -153,8 +147,13 @@ template <> void GetMember::handle(const ChoiceField::Choice& c) {
// ----------------------------------------------------------------------------- : ChoiceStyle // ----------------------------------------------------------------------------- : ChoiceStyle
ChoiceStyle::ChoiceStyle() ChoiceStyle::ChoiceStyle(const ChoiceFieldP& field)
: Style(field)
, popup_style(POPUP_DROPDOWN)
, render_style(RENDER_TEXT)
, combine(COMBINE_NORMAL)
, alignment(ALIGN_STRETCH)
, colors_card_list(false)
{} {}
IMPLEMENT_REFLECTION_ENUM(ChoicePopupStyle) { IMPLEMENT_REFLECTION_ENUM(ChoicePopupStyle) {
...@@ -191,7 +190,6 @@ String ChoiceValue::toString() const { ...@@ -191,7 +190,6 @@ String ChoiceValue::toString() const {
return value(); return value();
} }
IMPLEMENT_REFLECTION_NAMELESS(ChoiceValue) { IMPLEMENT_REFLECTION_NAMELESS(ChoiceValue) {
REFLECT_NAMELESS(value); REFLECT_NAMELESS(value);
} }
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
// ----------------------------------------------------------------------------- : ChoiceField // ----------------------------------------------------------------------------- : ChoiceField
DECLARE_POINTER_TYPE(ChoiceField);
/// A field that contains a list of choices /// A field that contains a list of choices
class ChoiceField : public Field { class ChoiceField : public Field {
public: public:
...@@ -108,7 +110,8 @@ enum ChoiceRenderStyle ...@@ -108,7 +110,8 @@ enum ChoiceRenderStyle
/// The Style for a ChoiceField /// The Style for a ChoiceField
class ChoiceStyle : public Style { class ChoiceStyle : public Style {
public: public:
ChoiceStyle(); ChoiceStyle(const ChoiceFieldP& field);
HAS_FIELD(Choice)
ChoicePopupStyle popup_style; ///< Style of popups/menus ChoicePopupStyle popup_style; ///< Style of popups/menus
ChoiceRenderStyle render_style; ///< Style of rendering ChoiceRenderStyle render_style; ///< Style of rendering
...@@ -129,6 +132,9 @@ class ChoiceStyle : public Style { ...@@ -129,6 +132,9 @@ class ChoiceStyle : public Style {
/// The Value in a ChoiceField /// The Value in a ChoiceField
class ChoiceValue : public Value { class ChoiceValue : public Value {
public: public:
inline ChoiceValue(const ChoiceFieldP& field) : Value(field) {}
HAS_FIELD(Choice)
Defaultable<String> value; /// The name of the selected choice Defaultable<String> value; /// The name of the selected choice
virtual String toString() const; virtual String toString() const;
......
...@@ -17,13 +17,7 @@ ColorField::ColorField() ...@@ -17,13 +17,7 @@ ColorField::ColorField()
, allow_custom(true) , allow_custom(true)
{} {}
StyleP ColorField::newStyle(const FieldP& thisP) const { FIELD_TYPE(Color)
return new_shared<ColorStyle>();
}
ValueP ColorField::newValue(const FieldP& thisP) const {
return new_shared<ColorValue>();
}
String ColorField::typeName() const { String ColorField::typeName() const {
return _("color"); return _("color");
...@@ -47,8 +41,9 @@ IMPLEMENT_REFLECTION(ColorField::Choice) { ...@@ -47,8 +41,9 @@ IMPLEMENT_REFLECTION(ColorField::Choice) {
// ----------------------------------------------------------------------------- : ColorStyle // ----------------------------------------------------------------------------- : ColorStyle
ColorStyle::ColorStyle() ColorStyle::ColorStyle(const ColorFieldP& field)
: radius(0) : Style(field)
, radius(0)
, left_width(100000), right_width (100000) , left_width(100000), right_width (100000)
, top_width (100000), bottom_width(100000) , top_width (100000), bottom_width(100000)
{} {}
...@@ -65,12 +60,12 @@ IMPLEMENT_REFLECTION(ColorStyle) { ...@@ -65,12 +60,12 @@ IMPLEMENT_REFLECTION(ColorStyle) {
// ----------------------------------------------------------------------------- : ColorValue // ----------------------------------------------------------------------------- : ColorValue
String ColorValue::toString() const { String ColorValue::toString() const {
/* if (value.isDefault()) return field->default_name; if (value.isDefault()) return field().default_name;
// is this a named color? // is this a named color?
FOR_EACH(c, field->choices) { FOR_EACH(c, field().choices) {
if (value == c->color) return c->name; if (value() == c->color) return c->name;
} }
*/ return _("<color>"); return _("<color>");
} }
IMPLEMENT_REFLECTION_NAMELESS(ColorValue) { IMPLEMENT_REFLECTION_NAMELESS(ColorValue) {
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
// ----------------------------------------------------------------------------- : ColorField // ----------------------------------------------------------------------------- : ColorField
DECLARE_POINTER_TYPE(ColorField);
/// A field for color values, it contains a list of choices for colors /// A field for color values, it contains a list of choices for colors
class ColorField : public Field { class ColorField : public Field {
public: public:
...@@ -52,14 +54,15 @@ class ColorField::Choice { ...@@ -52,14 +54,15 @@ class ColorField::Choice {
/// The Style for a ColorField /// The Style for a ColorField
class ColorStyle : public Style { class ColorStyle : public Style {
public: public:
ColorStyle(); ColorStyle(const ColorFieldP& field);
HAS_FIELD(Color)
int radius; ///< Radius of round corners int radius; ///< Radius of round corners
UInt left_width; ///< Width of the colored region on the left side UInt left_width; ///< Width of the colored region on the left side
UInt right_width; ///< Width of the colored region on the right side UInt right_width; ///< Width of the colored region on the right side
UInt top_width; ///< Width of the colored region on the top side UInt top_width; ///< Width of the colored region on the top side
UInt bottom_width; ///< Width of the colored region on the bottom side UInt bottom_width; ///< Width of the colored region on the bottom side
private: private:
DECLARE_REFLECTION(); DECLARE_REFLECTION();
}; };
...@@ -69,6 +72,9 @@ class ColorStyle : public Style { ...@@ -69,6 +72,9 @@ class ColorStyle : public Style {
/// The Value in a ColorField /// The Value in a ColorField
class ColorValue : public Value { class ColorValue : public Value {
public: public:
inline ColorValue(const ColorFieldP& field) : Value(field) {}
HAS_FIELD(Color)
Defaultable<Color> value; ///< The value Defaultable<Color> value; ///< The value
virtual String toString() const; virtual String toString() const;
......
...@@ -10,13 +10,7 @@ ...@@ -10,13 +10,7 @@
// ----------------------------------------------------------------------------- : ImageField // ----------------------------------------------------------------------------- : ImageField
StyleP ImageField::newStyle(const FieldP& thisP) const { FIELD_TYPE(Image)
return new_shared<ImageStyle>();
}
ValueP ImageField::newValue(const FieldP& thisP) const {
return new_shared<ImageValue>();
}
String ImageField::typeName() const { String ImageField::typeName() const {
return _("image"); return _("image");
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
// ----------------------------------------------------------------------------- : ImageField // ----------------------------------------------------------------------------- : ImageField
DECLARE_POINTER_TYPE(ImageField);
/// A field for image values /// A field for image values
class ImageField : public Field { class ImageField : public Field {
public: public:
...@@ -33,7 +35,10 @@ class ImageField : public Field { ...@@ -33,7 +35,10 @@ class ImageField : public Field {
/// The Style for a ImageField /// The Style for a ImageField
class ImageStyle : public Style { class ImageStyle : public Style {
public: public:
inline ImageStyle(const ImageFieldP& field) : Style(field) {}
Scriptable<String> mask_filename; ///< Filename for a mask image Scriptable<String> mask_filename; ///< Filename for a mask image
private: private:
DECLARE_REFLECTION(); DECLARE_REFLECTION();
}; };
...@@ -43,6 +48,8 @@ class ImageStyle : public Style { ...@@ -43,6 +48,8 @@ class ImageStyle : public Style {
/// The Value in a ImageField, i.e. an image /// The Value in a ImageField, i.e. an image
class ImageValue : public Value { class ImageValue : public Value {
public: public:
inline ImageValue(const ImageFieldP& field) : Value(field) {}
String filename; ///< Filename of the image (in the current package), or "" String filename; ///< Filename of the image (in the current package), or ""
virtual String toString() const; virtual String toString() const;
......
...@@ -15,13 +15,7 @@ MultipleChoiceField::MultipleChoiceField() ...@@ -15,13 +15,7 @@ MultipleChoiceField::MultipleChoiceField()
, maximum_selection(1000000) , maximum_selection(1000000)
{} {}
StyleP MultipleChoiceField::newStyle(const FieldP& thisP) const { FIELD_TYPE(MultipleChoice)
return new_shared<MultipleChoiceStyle>();
}
ValueP MultipleChoiceField::newValue(const FieldP& thisP) const {
return new_shared<MultipleChoiceValue>();
}
String MultipleChoiceField::typeName() const { String MultipleChoiceField::typeName() const {
return _("multiple choice"); return _("multiple choice");
...@@ -35,8 +29,9 @@ IMPLEMENT_REFLECTION(MultipleChoiceField) { ...@@ -35,8 +29,9 @@ IMPLEMENT_REFLECTION(MultipleChoiceField) {
// ----------------------------------------------------------------------------- : MultipleChoiceStyle // ----------------------------------------------------------------------------- : MultipleChoiceStyle
MultipleChoiceStyle::MultipleChoiceStyle() MultipleChoiceStyle::MultipleChoiceStyle(const MultipleChoiceFieldP& field)
: direction(HORIZONTAL) : ChoiceStyle(field)
, direction(HORIZONTAL)
, spacing(0) , spacing(0)
{} {}
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
// ----------------------------------------------------------------------------- : MultipleChoiceField // ----------------------------------------------------------------------------- : MultipleChoiceField
DECLARE_POINTER_TYPE(MultipleChoiceField);
/// A ChoiceField where multiple choices can be selected simultaniously /// A ChoiceField where multiple choices can be selected simultaniously
class MultipleChoiceField : public ChoiceField { class MultipleChoiceField : public ChoiceField {
public: public:
...@@ -38,7 +40,8 @@ enum Direction { ...@@ -38,7 +40,8 @@ enum Direction {
/// The Style for a MultipleChoiceField /// The Style for a MultipleChoiceField
class MultipleChoiceStyle : public ChoiceStyle { class MultipleChoiceStyle : public ChoiceStyle {
public: public:
MultipleChoiceStyle(); MultipleChoiceStyle(const MultipleChoiceFieldP& field);
HAS_FIELD(MultipleChoice)
Direction direction; ///< In what direction are choices layed out? Direction direction; ///< In what direction are choices layed out?
double spacing; ///< Spacing between choices (images) in pixels double spacing; ///< Spacing between choices (images) in pixels
...@@ -55,6 +58,9 @@ class MultipleChoiceStyle : public ChoiceStyle { ...@@ -55,6 +58,9 @@ class MultipleChoiceStyle : public ChoiceStyle {
*/ */
class MultipleChoiceValue : public ChoiceValue { class MultipleChoiceValue : public ChoiceValue {
public: public:
inline MultipleChoiceValue(const MultipleChoiceFieldP& field) : ChoiceValue(field) {}
HAS_FIELD(MultipleChoice)
// no extra data // no extra data
/// Splits the value, stores the selected choices in the out parameter /// Splits the value, stores the selected choices in the out parameter
......
...@@ -10,13 +10,7 @@ ...@@ -10,13 +10,7 @@
// ----------------------------------------------------------------------------- : SymbolField // ----------------------------------------------------------------------------- : SymbolField
StyleP SymbolField::newStyle(const FieldP& thisP) const { FIELD_TYPE(Symbol)
return new_shared<SymbolStyle>();
}
ValueP SymbolField::newValue(const FieldP& thisP) const {
return new_shared<SymbolValue>();
}
String SymbolField::typeName() const { String SymbolField::typeName() const {
return _("symbol"); return _("symbol");
......
...@@ -17,6 +17,8 @@ DECLARE_POINTER_TYPE(SymbolFilter); ...@@ -17,6 +17,8 @@ DECLARE_POINTER_TYPE(SymbolFilter);
// ----------------------------------------------------------------------------- : SymbolField // ----------------------------------------------------------------------------- : SymbolField
DECLARE_POINTER_TYPE(SymbolField);
/// A field for image values /// A field for image values
class SymbolField : public Field { class SymbolField : public Field {
public: public:
...@@ -35,6 +37,9 @@ class SymbolField : public Field { ...@@ -35,6 +37,9 @@ class SymbolField : public Field {
/// The Style for a SymbolField /// The Style for a SymbolField
class SymbolStyle : public Style { class SymbolStyle : public Style {
public: public:
inline SymbolStyle(const SymbolFieldP& field) : Style(field) {}
HAS_FIELD(Symbol)
class Variation; class Variation;
typedef shared_ptr<Variation> VariationP; typedef shared_ptr<Variation> VariationP;
vector<VariationP> variations; ///< Different variantions of the same symbol vector<VariationP> variations; ///< Different variantions of the same symbol
...@@ -58,6 +63,9 @@ class SymbolStyle::Variation { ...@@ -58,6 +63,9 @@ class SymbolStyle::Variation {
/// The Value in a SymbolField, i.e. a symbol /// The Value in a SymbolField, i.e. a symbol
class SymbolValue : public Value { class SymbolValue : public Value {
public: public:
inline SymbolValue(const SymbolFieldP& field) : Value(field) {}
HAS_FIELD(Symbol)
String filename; ///< Filename of the symbol (in the current package) String filename; ///< Filename of the symbol (in the current package)
virtual String toString() const; virtual String toString() const;
......
...@@ -16,15 +16,7 @@ TextField::TextField() ...@@ -16,15 +16,7 @@ TextField::TextField()
, default_name(_("Default")) , default_name(_("Default"))
{} {}
StyleP TextField::newStyle(const FieldP& thisP) const { FIELD_TYPE(Text)
assert(thisP.get() == this);
return new_shared<TextStyle>();
}
ValueP TextField::newValue(const FieldP& thisP) const {
assert(thisP.get() == this);
return new_shared<TextValue>();
}
String TextField::typeName() const { String TextField::typeName() const {
return _("text"); return _("text");
...@@ -42,8 +34,40 @@ IMPLEMENT_REFLECTION(TextField) { ...@@ -42,8 +34,40 @@ IMPLEMENT_REFLECTION(TextField) {
// ----------------------------------------------------------------------------- : TextStyle // ----------------------------------------------------------------------------- : TextStyle
TextStyle::TextStyle(const TextFieldP& field)
: Style(field)
, always_symbol(false), allow_formating(true)
, alignment(ALIGN_TOP_LEFT)
, angle(0)
, padding_left (0), padding_left_min (10000)
, padding_right (0), padding_right_min (10000)
, padding_top (0), padding_top_min (10000)
, padding_bottom(0), padding_bottom_min(10000)
, line_height_soft(1.0)
, line_height_hard(1.0)
, line_height_line(1.0)
{}
IMPLEMENT_REFLECTION(TextStyle) { IMPLEMENT_REFLECTION(TextStyle) {
REFLECT_BASE(Style); REFLECT_BASE(Style);
// REFLECT(font);
// REFLECT(symbol_font);
REFLECT(always_symbol);
REFLECT(allow_formating);
REFLECT(alignment);
REFLECT(angle);
REFLECT(padding_left);
REFLECT(padding_right);
REFLECT(padding_top);
REFLECT(padding_bottom);
REFLECT(padding_left_min);
REFLECT(padding_right_min);
REFLECT(padding_top_min);
REFLECT(padding_bottom_min);
REFLECT(line_height_soft);
REFLECT(line_height_hard);
REFLECT(line_height_line);
REFLECT_N("mask", mask_filename);
} }
// ----------------------------------------------------------------------------- : TextValue // ----------------------------------------------------------------------------- : TextValue
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
// ----------------------------------------------------------------------------- : TextField // ----------------------------------------------------------------------------- : TextField
DECLARE_POINTER_TYPE(TextField);
/// A field for values containing tagged text /// A field for values containing tagged text
class TextField : public Field { class TextField : public Field {
public: public:
...@@ -40,16 +42,19 @@ class TextField : public Field { ...@@ -40,16 +42,19 @@ class TextField : public Field {
/// The Style for a TextField /// The Style for a TextField
class TextStyle : public Style { class TextStyle : public Style {
public: public:
TextStyle(const TextFieldP&);
HAS_FIELD(Text)
// FontInfo font; ///< Font to use for the text // FontInfo font; ///< Font to use for the text
// SymbolFontInfo symbol_font; ///< Symbol font for symbols in the text // SymbolFontInfo symbol_font; ///< Symbol font for symbols in the text
bool always_symbol; ///< Should everything be drawn as symbols? bool always_symbol; ///< Should everything be drawn as symbols?
bool allow_formatting; ///< Is formating (bold/italic/..) allowed? bool allow_formating; ///< Is formating (bold/italic/..) allowed?
Alignment alignment; ///< Alignment inside the box Alignment alignment; ///< Alignment inside the box
int angle; ///< Angle of the text inside the box int angle; ///< Angle of the text inside the box
int padding_left, padding_left_min; ///< Padding double padding_left, padding_left_min; ///< Padding
int padding_right, padding_right_min; ///< Padding double padding_right, padding_right_min; ///< Padding
int padding_top, padding_top_min; ///< Padding double padding_top, padding_top_min; ///< Padding
int padding_bottom, padding_bottom_min; ///< Padding double padding_bottom, padding_bottom_min; ///< Padding
double line_height_soft; ///< Line height for soft linebreaks double line_height_soft; ///< Line height for soft linebreaks
double line_height_hard; ///< Line height for hard linebreaks double line_height_hard; ///< Line height for hard linebreaks
double line_height_line; ///< Line height for <line> tags double line_height_line; ///< Line height for <line> tags
...@@ -63,7 +68,10 @@ class TextStyle : public Style { ...@@ -63,7 +68,10 @@ class TextStyle : public Style {
/// The Value in a TextField /// The Value in a TextField
class TextValue : public Value { class TextValue : public Value {
public: public:
inline TextValue(const TextFieldP& field) : Value(field) {}
HAS_FIELD(Text)
Defaultable<String> value; ///< The text of this value Defaultable<String> value; ///< The text of this value
virtual String toString() const; virtual String toString() const;
......
...@@ -22,7 +22,7 @@ String Set::typeName() const { return _("set"); } ...@@ -22,7 +22,7 @@ String Set::typeName() const { return _("set"); }
IMPLEMENT_REFLECTION(Set) { IMPLEMENT_REFLECTION(Set) {
WITH_DYNAMIC_ARG(game_for_new_cards, game.get()) { WITH_DYNAMIC_ARG(game_for_new_cards, game.get()) {
REFLECT_N("card", cards); REFLECT(cards);
} }
} }
......
...@@ -17,17 +17,22 @@ ...@@ -17,17 +17,22 @@
DECLARE_POINTER_TYPE(Card); DECLARE_POINTER_TYPE(Card);
DECLARE_POINTER_TYPE(Set); DECLARE_POINTER_TYPE(Set);
DECLARE_POINTER_TYPE(Game); DECLARE_POINTER_TYPE(Game);
DECLARE_POINTER_TYPE(Stylesheet);
// ----------------------------------------------------------------------------- : Set // ----------------------------------------------------------------------------- : Set
/// A set of cards /// A set of cards
class Set : public Packaged { class Set : public Packaged {
public: public:
/// Create a set, the set should be open()ed later
Set();
/// Create a set using the given game /// Create a set using the given game
Set(const GameP& game); Set(const GameP& game);
/// The game this set uses /// The game this set uses
GameP game; GameP game;
/// The default stylesheet
StylesheetP stylesheet;
/// The cards in the set /// The cards in the set
vector<CardP> cards; vector<CardP> cards;
/// Actions performed on this set and the cards in it /// Actions performed on this set and the cards in it
...@@ -35,10 +40,7 @@ class Set : public Packaged { ...@@ -35,10 +40,7 @@ class Set : public Packaged {
protected: protected:
String typeName() const; String typeName() const;
// default constructor accessible to Reader
Set();
DECLARE_REFLECTION(); DECLARE_REFLECTION();
}; };
......
...@@ -41,10 +41,10 @@ void SymbolPartList::onChangeSymbol() { ...@@ -41,10 +41,10 @@ void SymbolPartList::onChangeSymbol() {
void SymbolPartList::onAction(const Action& action) { void SymbolPartList::onAction(const Action& action) {
TYPE_CASE(action, ReorderSymbolPartsAction) { TYPE_CASE(action, ReorderSymbolPartsAction) {
if (selected == (long) action.partId1) { if (selected == (long) action.part_id1) {
selectItem((long) action.partId2); selectItem((long) action.part_id2);
} else if (selected == (long) action.partId2) { } else if (selected == (long) action.part_id2) {
selectItem((long) action.partId1); selectItem((long) action.part_id1);
} }
} }
TYPE_CASE_(action, SymbolPartListAction) { TYPE_CASE_(action, SymbolPartListAction) {
......
...@@ -40,7 +40,10 @@ bool MSE::OnInit() { ...@@ -40,7 +40,10 @@ bool MSE::OnInit() {
initFileFormats(); initFileFormats();
settings.read(); settings.read();
//Window* wnd = new SymbolWindow(nullptr); //Window* wnd = new SymbolWindow(nullptr);
Window* wnd = new SetWindow(nullptr, new_shared1<Set>(Game::byName(_("magic")))); //GameP g = Game::byName(_("magic"))
SetP s = new_shared<Set>();
s->open(_("test.mse-set"));
Window* wnd = new SetWindow(nullptr, s);
wnd->Show(); wnd->Show();
return true; return true;
......
...@@ -611,6 +611,36 @@ ...@@ -611,6 +611,36 @@
<Filter <Filter
Name="action" Name="action"
Filter=""> Filter="">
<File
RelativePath=".\data\action\set.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
<FileConfiguration
Name="Debug Unicode|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release Unicode|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
</File>
<File
RelativePath=".\data\action\set.hpp">
</File>
<File <File
RelativePath=".\data\action\symbol.cpp"> RelativePath=".\data\action\symbol.cpp">
<FileConfiguration <FileConfiguration
...@@ -709,6 +739,12 @@ ...@@ -709,6 +739,12 @@
<File <File
RelativePath=".\data\field\image.hpp"> RelativePath=".\data\field\image.hpp">
</File> </File>
<File
RelativePath=".\data\field\multiple_choice.cpp">
</File>
<File
RelativePath=".\data\field\multiple_choice.hpp">
</File>
<File <File
RelativePath=".\data\field\symbol.cpp"> RelativePath=".\data\field\symbol.cpp">
<FileConfiguration <FileConfiguration
......
...@@ -172,7 +172,7 @@ class ScriptCollection : public ScriptValue { ...@@ -172,7 +172,7 @@ class ScriptCollection : public ScriptValue {
// ----------------------------------------------------------------------------- : Collections : maps // ----------------------------------------------------------------------------- : Collections : maps
/// Script value containing a map like collection /// Script value containing a map-like collection
template <typename Collection> template <typename Collection>
class ScriptMap : public ScriptValue { class ScriptMap : public ScriptValue {
public: public:
...@@ -223,6 +223,8 @@ template <typename T> ...@@ -223,6 +223,8 @@ template <typename T>
inline ScriptValueP toScript(const vector<T>* v) { return new_intrusive1<ScriptCollection<vector<T> > >(v); } inline ScriptValueP toScript(const vector<T>* v) { return new_intrusive1<ScriptCollection<vector<T> > >(v); }
template <typename K, typename V> template <typename K, typename V>
inline ScriptValueP toScript(const map<K,V>* v) { return new_intrusive1<ScriptMap<map<K,V> > >(v); } inline ScriptValueP toScript(const map<K,V>* v) { return new_intrusive1<ScriptMap<map<K,V> > >(v); }
template <typename K, typename V>
inline ScriptValueP toScript(const IndexMap<K,V>* v) { return new_intrusive1<ScriptMap<IndexMap<K,V> > >(v); }
template <typename T> template <typename T>
inline ScriptValueP toScript(const shared_ptr<T>& v) { return new_intrusive1<ScriptObject<T> >(v); } inline ScriptValueP toScript(const shared_ptr<T>& v) { return new_intrusive1<ScriptObject<T> >(v); }
......
...@@ -13,11 +13,19 @@ ...@@ -13,11 +13,19 @@
// ----------------------------------------------------------------------------- : IndexMap // ----------------------------------------------------------------------------- : IndexMap
/// A kind of map of K->V, with the following properties: /// A kind of map of Key->Value, with the following properties:
/** - K must have a unique member ->index of type UInt /** - K must have a unique member ->index of type UInt
* - There must exist a function initObject(K, V&) * - There must exist a function void init_object(Key, Value&)
* that stores a new V object for a given key in the reference * that stores a new V object for a given key in the reference
* - There must exist a function Key get_key(Value)
* that returns a key for a given value
* - For reflection there must exist a function String get_key_name(Value)
* that returns the key in string form
* - O(1) inserts and lookups * - O(1) inserts and lookups
*
* The 'map' is actually just a vector of values, each key has an index
* which is used for the vector.
* Values know their keys, so there is no need to store them separately.
*/ */
template <typename Key, typename Value> template <typename Key, typename Value>
class IndexMap : private vector<Value> { class IndexMap : private vector<Value> {
...@@ -25,20 +33,18 @@ class IndexMap : private vector<Value> { ...@@ -25,20 +33,18 @@ class IndexMap : private vector<Value> {
using vector<Value>::empty; using vector<Value>::empty;
using vector<Value>::size; using vector<Value>::size;
using vector<Value>::iterator; using vector<Value>::iterator;
using vector<Value>::const_iterator;
using vector<Value>::begin; using vector<Value>::begin;
using vector<Value>::end; using vector<Value>::end;
/// Initialize this map with default values given a list of keys, has no effect if !empty() /// Initialize this map with default values given a list of keys, has no effect if !empty()
/** Requires a function
* void initObject(Key, Value&)
*/
void init(const vector<Key>& keys) { void init(const vector<Key>& keys) {
if (!this->empty()) return; if (!this->empty()) return;
this->reserve(keys.size()); this->reserve(keys.size());
FOR_EACH_CONST(key, keys) { FOR_EACH_CONST(key, keys) {
assert(key); assert(key);
if (key->index >= this->size()) this->resize(key->index + 1); if (key->index >= this->size()) this->resize(key->index + 1);
initObject(key, (*this)[key->index]); init_object(key, (*this)[key->index]);
} }
} }
...@@ -48,20 +54,18 @@ class IndexMap : private vector<Value> { ...@@ -48,20 +54,18 @@ class IndexMap : private vector<Value> {
assert(this->size() > key->index); assert(this->size() > key->index);
return at(key->index); return at(key->index);
} }
/// Is a value contained in this index map? /// Is a value contained in this index map?
/// requires a function Key Value::getKey()
inline bool contains(const Value& value) const { inline bool contains(const Value& value) const {
assert(value); assert(value);
size_t index = value->getKey()->index; size_t index = get_key(value)->index;
return index < this.size() && (*this)[index] == value return index < this.size() && (*this)[index] == value
} }
/// Is a key in the domain of this index map? /// Is a key in the domain of this index map?
/// requires a function Key Value::getKey()
inline bool containsKey(const Key& key) const { inline bool containsKey(const Key& key) const {
assert(key); assert(key);
return key->index < this.size() && (*this)[key->index]->getKey() == key return key->index < this.size() && get_key((*this)[key->index]) == key
} }
private: private:
......
...@@ -46,6 +46,7 @@ class GetDefaultMember { ...@@ -46,6 +46,7 @@ class GetDefaultMember {
template <typename T> void handle(const Scriptable<T>&); template <typename T> void handle(const Scriptable<T>&);
template <typename T> void handle(const vector<T>& c) { value = toScript(&c); } template <typename T> void handle(const vector<T>& c) { value = toScript(&c); }
template <typename K, typename V> void handle(const map<K,V>& c) { value = toScript(&c); } template <typename K, typename V> void handle(const map<K,V>& c) { value = toScript(&c); }
template <typename K, typename V> void handle(const IndexMap<K,V>& c) { value = toScript(&c); }
template <typename T> void handle(const shared_ptr<T>& p) { value = toScript(p); } template <typename T> void handle(const shared_ptr<T>& p) { value = toScript(p); }
void handle(const ScriptValueP&); void handle(const ScriptValueP&);
void handle(const ScriptP&); void handle(const ScriptP&);
...@@ -78,6 +79,16 @@ class GetMember : private GetDefaultMember { ...@@ -78,6 +79,16 @@ class GetMember : private GetDefaultMember {
} }
/// Handle an object: investigate children /// Handle an object: investigate children
template <typename T> void handle(const T&); template <typename T> void handle(const T&);
/// Handle an index map: invistigate keys
template <typename K, typename V> void handle(const IndexMap<K,V>& m) {
if (gdm.result()) return;
for (typename IndexMap<K,V>::const_iterator it = m.begin() ; it != m.end() ; ++it) {
if (get_key_name(*it) == target_name) {
gdm.handle(*it);
return;
}
}
}
private: private:
const String& target_name; ///< The name we are looking for const String& target_name; ///< The name we are looking for
......
...@@ -65,7 +65,9 @@ class Reader { ...@@ -65,7 +65,9 @@ class Reader {
/// Reads a shared_ptr from the input stream /// Reads a shared_ptr from the input stream
template <typename T> void handle(shared_ptr<T>& pointer); template <typename T> void handle(shared_ptr<T>& pointer);
/// Reads a map from the input stream /// Reads a map from the input stream
template <typename K, typename V> void handle(map<K,V>& map); template <typename K, typename V> void handle(map<K,V>& m);
/// Reads an IndexMap from the input stream, reads only keys that already exist in the map
template <typename K, typename V> void handle(IndexMap<K,V>& m);
/// Reads a Defaultable from the input stream /// Reads a Defaultable from the input stream
template <typename T> void handle(Defaultable<T>&); template <typename T> void handle(Defaultable<T>&);
/// Reads a Scriptable from the input stream /// Reads a Scriptable from the input stream
...@@ -150,10 +152,19 @@ void Reader::handle(shared_ptr<T>& pointer) { ...@@ -150,10 +152,19 @@ void Reader::handle(shared_ptr<T>& pointer) {
} }
template <typename K, typename V> template <typename K, typename V>
void Reader::handle(map<K,V>& map) { void Reader::handle(map<K,V>& m) {
// TODO // TODO
} }
template <typename K, typename V>
void Reader::handle(IndexMap<K,V>& m) {
while (indent >= expected_indent) {
for (typename IndexMap<K,V>::iterator it = m.begin() ; it != m.end() ; ++it) {
handle(get_key_name(*it).c_str(), *it);
}
}
}
// ----------------------------------------------------------------------------- : Reflection // ----------------------------------------------------------------------------- : Reflection
/// Implement reflection as used by Reader /// Implement reflection as used by Reader
......
...@@ -52,6 +52,8 @@ class Writer { ...@@ -52,6 +52,8 @@ class Writer {
template <typename T> void handle(const shared_ptr<T>& pointer); template <typename T> void handle(const shared_ptr<T>& pointer);
/// Write a map to the output stream /// Write a map to the output stream
template <typename K, typename V> void handle(const map<K,V>& map); template <typename K, typename V> void handle(const map<K,V>& map);
/// Write an IndexMap to the output stream
template <typename K, typename V> void handle(const IndexMap<K,V>& map);
/// Write an object of type Defaultable<T> to the output stream /// Write an object of type Defaultable<T> to the output stream
template <typename T> void handle(const Defaultable<T>&); template <typename T> void handle(const Defaultable<T>&);
/// Write an object of type Scriptable<T> to the output stream /// Write an object of type Scriptable<T> to the output stream
...@@ -98,6 +100,7 @@ template <typename T> ...@@ -98,6 +100,7 @@ template <typename T>
void Writer::handle(const shared_ptr<T>& pointer) { void Writer::handle(const shared_ptr<T>& pointer) {
if (pointer) handle(*pointer); if (pointer) handle(*pointer);
} }
template <typename K, typename V> template <typename K, typename V>
void Writer::handle(const map<K,V>& m) { void Writer::handle(const map<K,V>& m) {
for (typename map<K,V>::const_iterator it = m.begin() ; it != m.end() ; ++it) { for (typename map<K,V>::const_iterator it = m.begin() ; it != m.end() ; ++it) {
...@@ -105,6 +108,14 @@ void Writer::handle(const map<K,V>& m) { ...@@ -105,6 +108,14 @@ void Writer::handle(const map<K,V>& m) {
} }
} }
template <typename K, typename V>
void Writer::handle(const IndexMap<K,V>& m) {
for (typename IndexMap<K,V>::const_iterator it = m.begin() ; it != m.end() ; ++it) {
handle(get_key_name(*it).c_str(), *it);
}
}
// ----------------------------------------------------------------------------- : Reflection // ----------------------------------------------------------------------------- : Reflection
/// Implement reflection as used by Writer /// Implement reflection as used by Writer
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment