Commit 84717dac authored by twanvl's avatar twanvl

implemented all field types

parent f1ea57b6
......@@ -53,10 +53,13 @@ shared_ptr<Field> read_new<Field>(Reader& reader) {
// there must be a type specified
String type;
reader.handle(_("type"), type);
if (type == _("text")) {
return new_shared<TextField>();
} else {
//return new_shared<TextField>();
if (type == _("text")) return new_shared<TextField>();
else if (type == _("choice")) return new_shared<ChoiceField>();
else if (type == _("boolean")) return new_shared<BooleanField>();
else if (type == _("image")) return new_shared<ImageField>();
else if (type == _("symbol")) return new_shared<SymbolField>();
else if (type == _("color")) return new_shared<ColorField>();
else {
throw ParseError(_("Unsupported field type: '") + type + _("'"));
}
}
......@@ -68,6 +71,12 @@ shared_ptr<Field> read_new<Field>(Reader& reader) {
Style::~Style() {}
IMPLEMENT_REFLECTION(Style) {
REFLECT(z_index);
REFLECT(left);
REFLECT(top);
REFLECT(width);
REFLECT(height);
REFLECT(visible);
}
void initObject(const FieldP& field, StyleP& style) {
......@@ -78,7 +87,7 @@ void initObject(const FieldP& field, StyleP& style) {
Value::~Value() {}
IMPLEMENT_REFLECTION(Value) {
IMPLEMENT_REFLECTION_NAMELESS(Value) {
}
void initObject(const FieldP& field, ValueP& value) {
......
......@@ -12,6 +12,7 @@
#include <util/prec.hpp>
#include <util/reflect.hpp>
#include <util/alignment.hpp>
#include <script/scriptable.hpp>
DECLARE_POINTER_TYPE(Field);
DECLARE_POINTER_TYPE(Style);
......@@ -46,8 +47,6 @@ class Field {
/// Creates a new Style corresponding to this Field
/** thisP is a smart pointer to this */
virtual StyleP newStyle(const FieldP& thisP) const = 0;
/// create a copy of this field
virtual FieldP clone() const = 0;
/// Type of this field
virtual String typeName() const = 0;
......@@ -66,6 +65,11 @@ class Style {
public:
virtual ~Style();
int z_index; ///< Stacking of values of this field, higher = on top
Scriptable<double> left, top; ///< Position of this field
Scriptable<double> width, height; ///< Position of this field
Scriptable<bool> visible; ///< Is this field visible?
private:
DECLARE_REFLECTION_VIRTUAL();
};
......@@ -78,10 +82,7 @@ void initObject(const FieldP&, StyleP&);
class Value {
public:
virtual ~Value();
/// Create a copy of this value
virtual ValueP clone() const = 0;
/// Convert this value to a string for use in tables
virtual String toString() const = 0;
......
......@@ -9,5 +9,40 @@
#include <data/field/boolean.hpp>
// ----------------------------------------------------------------------------- : BooleanField
BooleanField::BooleanField() {
// choices->choices.push_back(new_shared1<Choice>(_("yes")));
// choices->choices.push_back(new_shared1<Choice>(_("no")));
// choices->initIds();
}
StyleP BooleanField::newStyle(const FieldP& thisP) const {
return new_shared<BooleanStyle>();
}
ValueP BooleanField::newValue(const FieldP& thisP) const {
return new_shared<BooleanValue>();
}
String BooleanField::typeName() const {
return _("boolean");
}
IMPLEMENT_REFLECTION(BooleanField) {
REFLECT_BASE(Field); // NOTE: don't reflect as a ChoiceField
REFLECT(script);
REFLECT_N("default", default_script);
REFLECT(initial);
}
// ----------------------------------------------------------------------------- : BooleanStyle
IMPLEMENT_REFLECTION(BooleanStyle) {
REFLECT_BASE(ChoiceStyle);
}
// ----------------------------------------------------------------------------- : BooleanValue
IMPLEMENT_REFLECTION_NAMELESS(BooleanValue) {
REFLECT_BASE(ChoiceValue);
}
......@@ -21,6 +21,10 @@ class BooleanField : public ChoiceField {
// no extra data
virtual ValueP newValue(const FieldP& thisP) const;
virtual StyleP newStyle(const FieldP& thisP) const;
virtual String typeName() const;
private:
DECLARE_REFLECTION();
};
......
......@@ -8,6 +8,187 @@
#include <data/field/choice.hpp>
DECLARE_TYPEOF_COLLECTION(ChoiceField::ChoiceP);
// ----------------------------------------------------------------------------- : ChoiceField
ChoiceField::ChoiceField()
: choices((Choice*)new Choice)
, default_name(_("Default"))
{}
StyleP ChoiceField::newStyle(const FieldP& thisP) const {
return new_shared<ChoiceStyle>();
}
ValueP ChoiceField::newValue(const FieldP& thisP) const {
return new_shared<ChoiceValue>();
}
String ChoiceField::typeName() const {
return _("choice");
}
IMPLEMENT_REFLECTION(ChoiceField) {
REFLECT_BASE(Field);
REFLECT(choices);
REFLECT(script);
REFLECT_N("default", default_script);
REFLECT(initial);
REFLECT(default_name);
}
// ----------------------------------------------------------------------------- : ChoiceField::Choice
ChoiceField::Choice::Choice()
: first_id(0)
{}
bool ChoiceField::Choice::isGroup() const {
return !choices.empty();
}
bool ChoiceField::Choice::hasDefault() const {
return !isGroup() || !default_name.empty();
}
int ChoiceField::Choice::initIds() {
int id = first_id + (hasDefault() ? 1 : 0);
FOR_EACH(c, choices) {
c->first_id = id;
id = c->initIds();
}
return id;
}
int ChoiceField::Choice::choiceCount() const {
return lastId() - first_id;
}
int ChoiceField::Choice::lastId() const {
if (isGroup()) {
// last id of last choice
return choices.back()->lastId();
} else {
return first_id + 1;
}
}
int ChoiceField::Choice::choiceId(const String& search_name) const {
if (hasDefault() && search_name == name) {
return first_id;
} else if (name.empty()) { // no name for this group, forward to all children
FOR_EACH_CONST(c, choices) {
int sub_id = c->choiceId(search_name);
if (sub_id != -1) return sub_id;
}
} else if (isGroup() && starts_with(search_name, name + _(" "))) {
String sub_name = search_name.substr(name.size() + 1);
FOR_EACH_CONST(c, choices) {
int sub_id = c->choiceId(sub_name);
if (sub_id != -1) return sub_id;
}
}
return -1;
}
String ChoiceField::Choice::choiceName(int id) const {
if (hasDefault() && id == first_id) {
return name;
} else {
FOR_EACH_CONST_REVERSE(c, choices) { // take the last one that still contains id
if (id >= c->first_id) {
if (name.empty()) {
return c->choiceName(id);
} else {
return name + _(" ") + c->choiceName(id);
}
}
}
}
return _("");
}
String ChoiceField::Choice::choiceNameNice(int id) const {
if (!isGroup() && id == first_id) {
return name;
} else if (hasDefault() && id == first_id) {
return default_name;
} else {
FOR_EACH_CONST_REVERSE(c, choices) {
if (id == c->first_id) {
return c->name; // we don't want "<group> default"
} else if (id > c->first_id) {
return c->choiceNameNice(id);
}
}
}
return _("");
}
IMPLEMENT_REFLECTION_NO_GET_MEMBER(ChoiceField::Choice) {
if (isGroup() || (tag.reading() && tag.isComplex())) {
// complex values are groups
REFLECT(name);
REFLECT_N("group choice", default_name);
REFLECT(choices);
} else {
REFLECT_NAMELESS(name);
}
}
template <> void GetDefaultMember::handle(const ChoiceField::Choice& c) {
if (!c.isGroup()) handle(c.name);
}
template <> void GetMember::handle(const ChoiceField::Choice& c) {
handle(_("name"), c.name);
handle(_("group choice"), c.default_name);
handle(_("choices"), c.choices);
}
// ----------------------------------------------------------------------------- : ChoiceStyle
// ----------------------------------------------------------------------------- : ChoiceValue
\ No newline at end of file
ChoiceStyle::ChoiceStyle()
{}
IMPLEMENT_REFLECTION_ENUM(ChoicePopupStyle) {
VALUE_N("dropdown", POPUP_DROPDOWN);
VALUE_N("menu", POPUP_MENU);
VALUE_N("in place", POPUP_DROPDOWN_IN_PLACE);
}
IMPLEMENT_REFLECTION_ENUM(ChoiceRenderStyle) {
VALUE_N("text", RENDER_TEXT);
VALUE_N("image", RENDER_IMAGE);
VALUE_N("both", RENDER_BOTH);
VALUE_N("hidden", RENDER_HIDDEN);
VALUE_N("image hidden", RENDER_HIDDEN_IMAGE);
}
IMPLEMENT_REFLECTION(ChoiceStyle) {
REFLECT_BASE(Style);
REFLECT(popup_style);
REFLECT(render_style);
REFLECT_N("maks",mask_filename);
REFLECT(combine);
REFLECT(alignment);
REFLECT(colors_card_list);
// REFLECT(font);
// REFLECT(choice_images);
// if (tag.reading() && choice_colors.empty())
REFLECT(choice_colors);
}
// ----------------------------------------------------------------------------- : ChoiceValue
String ChoiceValue::toString() const {
return value();
}
IMPLEMENT_REFLECTION_NAMELESS(ChoiceValue) {
REFLECT_NAMELESS(value);
}
......@@ -13,14 +13,27 @@
#include <util/defaultable.hpp>
#include <data/field.hpp>
#include <gfx/gfx.hpp> // for ImageCombine
#include <script/scriptable.hpp>
// ----------------------------------------------------------------------------- : ChoiceField
/// A field that contains a list of choices
class ChoiceField : public Field {
public:
ChoiceField();
class Choice;
DECLARE_POINTER_TYPE(Choice);
typedef shared_ptr<Choice> ChoiceP;
ChoiceP choices; ///< A choice group of possible choices
OptionalScript script; ///< Script to apply to all values
OptionalScript default_script; ///< Script that generates the default value
String initial; ///< Initial choice of a new value, or ""
String default_name; ///< Name of "default" value
virtual ValueP newValue(const FieldP& thisP) const;
virtual StyleP newStyle(const FieldP& thisP) const;
virtual String typeName() const;
private:
DECLARE_REFLECTION();
......@@ -32,35 +45,44 @@ class ChoiceField::Choice {
String name; ///< Name/value of the item
String default_name; ///< A default item, if this is a group and default_name.empty() there is no default
vector<ChoiceP> choices; ///< Choices and sub groups in this group
UInt first_id; ///< First item-id in this group (can be the default item)
/// First item-id in this group (can be the default item)
/** Item-ids are consecutive integers, a group uses all ids [first_id..lastId()).
* The top level group has first_id 0.
*/
int first_id;
Choice();
/// Is this a group?
bool isGroup() const;
/// Can this Choice itself be chosen?
/** For a single choice this is always true, for a group only if it has a default choice */
bool hasDefault() const;
/// Initialize the first_id of children
/** Returns lastId() */
UInt initIds() const;
/** @pre first_id is set
* Returns lastId()
*/
int initIds();
/// Number of choices in this group (and subgroups), 1 if it is not a group
/** The default choice also counts */
UInt choiceCount() const;
int choiceCount() const;
/// item-id just beyond the end of this group
UInt lastId() const;
int lastId() const;
/// item-id of a choice, given the internal name
/** If the id is not in this group, returns -1 */
UInt choiceId(const String& name);
int choiceId(const String& name) const;
/// Internal name of a choice
/** The internal name is formed by concatenating the names of all parents, separated by spaces.
* Returns "" if id is not in this group
*/
String choiceName(UInt id);
String choiceName(int id) const;
/// Formated name of a choice.
/** Intended for use in menu structures, so it doesn't include the group name for children.
* Returns "" if id is not in this group.
*/
String choiceNameNice(UInt id);
String choiceNameNice(int id) const;
DECLARE_REFLECTION();
};
......@@ -85,13 +107,14 @@ enum ChoiceRenderStyle
/// The Style for a ChoiceField
class ChoiceStyle : public Style {
public:
ChoiceStyle();
ChoicePopupStyle popup_style; ///< Style of popups/menus
ChoiceRenderStyle render_style; ///< Style of rendering
// FontInfo font; ///< Font for drawing text (when RENDER_TEXT)
// map<String,ScriptableImage> choice_images; ///< Images for the various choices (when RENDER_IMAGE)
map<String,Color> choice_colors; ///< Colors for the various choices (when color_cardlist)
bool colors_card_list;///< Does this field determine colors of the rows in the card list?
ChoicePopupStyle popup_style; ///< Style of popups/menus
ChoiceRenderStyle render_style; ///< Style of rendering
String mask_filename; ///< Filename of an additional mask over the images
ImageCombine combine; ///< Combining mode for drawing the images
Alignment alignment; ///< Alignment of images
......@@ -106,6 +129,9 @@ class ChoiceStyle : public Style {
class ChoiceValue : public Value {
public:
Defaultable<String> value; /// The name of the selected choice
virtual String toString() const;
private:
DECLARE_REFLECTION();
};
......
......@@ -8,6 +8,71 @@
#include <data/field/color.hpp>
DECLARE_TYPEOF_COLLECTION(ColorField::ChoiceP);
// ----------------------------------------------------------------------------- : ColorField
ColorField::ColorField()
: default_name(_("Default"))
, allow_custom(true)
{}
StyleP ColorField::newStyle(const FieldP& thisP) const {
return new_shared<ColorStyle>();
}
ValueP ColorField::newValue(const FieldP& thisP) const {
return new_shared<ColorValue>();
}
String ColorField::typeName() const {
return _("color");
}
IMPLEMENT_REFLECTION(ColorField) {
REFLECT_BASE(Field);
REFLECT(script);
REFLECT_N("default", default_script);
REFLECT(default_name);
REFLECT(allow_custom);
REFLECT(choices);
}
// ----------------------------------------------------------------------------- : ColorField::Choice
IMPLEMENT_REFLECTION(ColorField::Choice) {
REFLECT(name);
REFLECT(color);
}
// ----------------------------------------------------------------------------- : ColorStyle
ColorStyle::ColorStyle()
: radius(0)
, left_width(100000), right_width (100000)
, top_width (100000), bottom_width(100000)
{}
IMPLEMENT_REFLECTION(ColorStyle) {
REFLECT_BASE(Style);
REFLECT(radius);
REFLECT(left_width);
REFLECT(right_width);
REFLECT(top_width);
REFLECT(bottom_width);
}
// ----------------------------------------------------------------------------- : ColorValue
String ColorValue::toString() const {
/* if (value.isDefault()) return field->default_name;
// is this a named color?
FOR_EACH(c, field->choices) {
if (value == c->color) return c->name;
}
*/ return _("<color>");
}
IMPLEMENT_REFLECTION_NAMELESS(ColorValue) {
REFLECT_NAMELESS(value);
}
......@@ -22,7 +22,7 @@ class ColorField : public Field {
ColorField();
class Choice;
DECLARE_POINTER_TYPE(Choice);
typedef shared_ptr<Choice> ChoiceP;
OptionalScript script; ///< Script to apply to all values
OptionalScript default_script; ///< Script that generates the default value
......@@ -30,6 +30,10 @@ class ColorField : public Field {
bool allow_custom; ///< Are colors not in the list of choices allowed?
String default_name; ///< Name of "default" value
virtual ValueP newValue(const FieldP& thisP) const;
virtual StyleP newStyle(const FieldP& thisP) const;
virtual String typeName() const;
private:
DECLARE_REFLECTION();
};
......@@ -67,6 +71,8 @@ class ColorValue : public Value {
public:
Defaultable<Color> value; ///< The value
virtual String toString() const;
private:
DECLARE_REFLECTION();
};
......
......@@ -9,5 +9,38 @@
#include <data/field/image.hpp>
// ----------------------------------------------------------------------------- : ImageField
StyleP ImageField::newStyle(const FieldP& thisP) const {
return new_shared<ImageStyle>();
}
ValueP ImageField::newValue(const FieldP& thisP) const {
return new_shared<ImageValue>();
}
String ImageField::typeName() const {
return _("image");
}
IMPLEMENT_REFLECTION(ImageField) {
REFLECT_BASE(Field);
}
// ----------------------------------------------------------------------------- : ImageStyle
// ----------------------------------------------------------------------------- : ImageValue
\ No newline at end of file
IMPLEMENT_REFLECTION(ImageStyle) {
REFLECT_BASE(Style);
REFLECT_N("mask", mask_filename);
}
// ----------------------------------------------------------------------------- : ImageValue
String ImageValue::toString() const {
return filename.empty() ? wxEmptyString : _("<image>");
}
IMPLEMENT_REFLECTION_NAMELESS(ImageValue) {
REFLECT_NAMELESS(filename);
}
......@@ -19,6 +19,11 @@
class ImageField : public Field {
public:
// no extra data
virtual ValueP newValue(const FieldP& thisP) const;
virtual StyleP newStyle(const FieldP& thisP) const;
virtual String typeName() const;
private:
DECLARE_REFLECTION();
};
......@@ -38,7 +43,10 @@ class ImageStyle : public Style {
/// The Value in a ImageField, i.e. an image
class ImageValue : public Value {
public:
String filename; ///< Filename of the image (in the current package)
String filename; ///< Filename of the image (in the current package), or ""
virtual String toString() const;
private:
DECLARE_REFLECTION();
};
......
......@@ -9,5 +9,47 @@
#include <data/field/symbol.hpp>
// ----------------------------------------------------------------------------- : SymbolField
StyleP SymbolField::newStyle(const FieldP& thisP) const {
return new_shared<SymbolStyle>();
}
ValueP SymbolField::newValue(const FieldP& thisP) const {
return new_shared<SymbolValue>();
}
String SymbolField::typeName() const {
return _("symbol");
}
IMPLEMENT_REFLECTION(SymbolField) {
REFLECT_BASE(Field);
}
// ----------------------------------------------------------------------------- : SymbolStyle
IMPLEMENT_REFLECTION(SymbolStyle) {
REFLECT_BASE(Style);
REFLECT(variations);
}
SymbolStyle::Variation::Variation()
: border_radius(0.05)
{}
IMPLEMENT_REFLECTION(SymbolStyle::Variation) {
REFLECT(name);
REFLECT(border_radius);
//REFLECT_NAMELESS(filter);
}
// ----------------------------------------------------------------------------- : SymbolValue
String SymbolValue::toString() const {
return filename.empty() ? wxEmptyString : _("<symbol>");
}
IMPLEMENT_REFLECTION_NAMELESS(SymbolValue) {
REFLECT_NAMELESS(filename);
}
......@@ -21,6 +21,11 @@ DECLARE_POINTER_TYPE(SymbolFilter);
class SymbolField : public Field {
public:
// no extra data
virtual ValueP newValue(const FieldP& thisP) const;
virtual StyleP newStyle(const FieldP& thisP) const;
virtual String typeName() const;
private:
DECLARE_REFLECTION();
};
......@@ -31,7 +36,7 @@ class SymbolField : public Field {
class SymbolStyle : public Style {
public:
class Variation;
DECLARE_POINTER_TYPE(Variation);
typedef shared_ptr<Variation> VariationP;
vector<VariationP> variations; ///< Different variantions of the same symbol
private:
......@@ -41,6 +46,7 @@ class SymbolStyle : public Style {
/// Styling for a symbol variation, defines color, border, etc.
class SymbolStyle::Variation {
public:
Variation();
String name; ///< Name of this variation
SymbolFilterP filter; ///< Filter to color the symbol
double border_radius; ///< Border radius for the symbol
......@@ -53,6 +59,9 @@ class SymbolStyle::Variation {
class SymbolValue : public Value {
public:
String filename; ///< Filename of the symbol (in the current package)
virtual String toString() const;
private:
DECLARE_REFLECTION();
};
......
......@@ -26,10 +26,6 @@ ValueP TextField::newValue(const FieldP& thisP) const {
return new_shared<TextValue>();
}
FieldP TextField::clone() const {
return new_shared1<TextField>(*this);
}
String TextField::typeName() const {
return _("text");
}
......@@ -46,24 +42,16 @@ IMPLEMENT_REFLECTION(TextField) {
// ----------------------------------------------------------------------------- : TextStyle
StyleP TextStyle::clone() const {
return new_shared1<TextStyle>(*this);
}
IMPLEMENT_REFLECTION(TextStyle) {
REFLECT_BASE(Style);
}
// ----------------------------------------------------------------------------- : TextValue
ValueP TextValue::clone() const {
return new_shared1<TextValue>(*this);
}
String TextValue::toString() const {
return value();
}
IMPLEMENT_REFLECTION(TextValue) {
REFLECT_BASE(Value);
IMPLEMENT_REFLECTION_NAMELESS(TextValue) {
REFLECT_NAMELESS(value);
}
......@@ -29,7 +29,6 @@ class TextField : public Field {
virtual ValueP newValue(const FieldP& thisP) const;
virtual StyleP newStyle(const FieldP& thisP) const;
virtual FieldP clone() const;
virtual String typeName() const;
private:
......@@ -55,10 +54,7 @@ class TextStyle : public Style {
double line_height_hard; ///< Line height for hard linebreaks
double line_height_line; ///< Line height for <line> tags
String mask_filename; ///< Filename of the mask
// ContourMaskP mask; ///< Mask to fit the text to (may be null)
virtual StyleP clone() const;
// ContourMaskP mask; ///< Mask to fit the text to (may be null)
private:
DECLARE_REFLECTION();
};
......@@ -70,7 +66,6 @@ class TextValue : public Value {
public:
Defaultable<String> value; ///< The text of this value
virtual ValueP clone() const;
virtual String toString() const;
private:
DECLARE_REFLECTION();
......
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