mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-11 05:07:00 -04:00
Added Alignment, Defaultable and Scriptable types, needed some reflection tweaks for the last two.
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@17 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
//+----------------------------------------------------------------------------+
|
||||
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||
//+----------------------------------------------------------------------------+
|
||||
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/alignment.hpp>
|
||||
#include <util/reflect.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : Alignment
|
||||
|
||||
/// Convert a String to an Alignment
|
||||
Alignment fromString(const String& str) {
|
||||
int al = 0;
|
||||
return static_cast<Alignment>(al);
|
||||
}
|
||||
|
||||
/// Convert an Alignment to a String
|
||||
String toString(Alignment align) {
|
||||
String ret;
|
||||
// vertical
|
||||
if (align & ALIGN_TOP) ret += _(" top");
|
||||
if (align & ALIGN_MIDDLE) ret += _(" middle");
|
||||
if (align & ALIGN_BOTTOM) ret += _(" bottom");
|
||||
// horizontal
|
||||
if (align & ALIGN_LEFT) ret += _(" left");
|
||||
if (align & ALIGN_LEFT) ret += _(" center");
|
||||
if (align & ALIGN_LEFT) ret += _(" right");
|
||||
if (align & ALIGN_LEFT) ret += _(" justify");
|
||||
if (align & ALIGN_LEFT) ret += _(" justify-words");
|
||||
// modifier
|
||||
if (align & ALIGN_JUSTIFY_OVERFLOW) ret += _(" shrink-overflow");
|
||||
if (align & ALIGN_STRETCH) ret += _(" stretch");
|
||||
return ret.substr(1);
|
||||
}
|
||||
|
||||
// we need custom io, because there can be both a horizontal and a vertical component
|
||||
|
||||
template <> void Reader::handle(Alignment& align) {
|
||||
align = fromString(value);
|
||||
}
|
||||
template <> void Writer::handle(const Alignment& align) {
|
||||
handle(toString(align));
|
||||
}
|
||||
template <> void GetMember::store(const Alignment& align) {
|
||||
store(toString(align));
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
//+----------------------------------------------------------------------------+
|
||||
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||
//+----------------------------------------------------------------------------+
|
||||
|
||||
#ifndef HEADER_UTIL_ALIGNMENT
|
||||
#define HEADER_UTIL_ALIGNMENT
|
||||
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <util/real_point.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : Alignment
|
||||
|
||||
// Alignment in a textbox, specifies both horizontal and vertical alignment
|
||||
enum Alignment
|
||||
// horizontal
|
||||
{ ALIGN_LEFT = 0x01
|
||||
, ALIGN_CENTER = 0x02
|
||||
, ALIGN_RIGHT = 0x04
|
||||
, ALIGN_JUSTIFY = 0x08
|
||||
, ALIGN_JUSTIFY_WORDS = 0x10
|
||||
, ALIGN_HORIZONTAL = ALIGN_LEFT | ALIGN_CENTER | ALIGN_RIGHT | ALIGN_JUSTIFY | ALIGN_JUSTIFY_WORDS
|
||||
// vertical
|
||||
, ALIGN_TOP = 0x100
|
||||
, ALIGN_MIDDLE = 0x200
|
||||
, ALIGN_BOTTOM = 0x400
|
||||
, ALIGN_VERTICAL = ALIGN_TOP | ALIGN_MIDDLE | ALIGN_BOTTOM
|
||||
// modifiers
|
||||
, ALIGN_JUSTIFY_OVERFLOW = 0x1000
|
||||
, ALIGN_STRETCH = 0x2000
|
||||
// common combinations
|
||||
, ALIGN_TOP_LEFT = ALIGN_TOP | ALIGN_LEFT
|
||||
};
|
||||
|
||||
|
||||
/// How much should an object with obj_width be moved to be aligned in a box with box_width?
|
||||
double align_delta_x(Alignment align, double box_width, double obj_width);
|
||||
|
||||
/// How much should an object with obj_height be moved to be aligned in a box with box_height?
|
||||
double align_delta_t(Alignment align, double box_height, double obj_height);
|
||||
|
||||
/// Align a rectangle inside another rectangle
|
||||
/** returns the topleft coordinates of the inner rectangle after alignment
|
||||
*/
|
||||
RealPoint align_in_rect(Alignment align, const RealSize& to_align, const RealRect& outer);
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
#endif
|
||||
@@ -0,0 +1,68 @@
|
||||
//+----------------------------------------------------------------------------+
|
||||
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||
//+----------------------------------------------------------------------------+
|
||||
|
||||
#ifndef HEADER_UTIL_DEFAULTABLE
|
||||
#define HEADER_UTIL_DEFAULTABLE
|
||||
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <util/reflect.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : Defaultable
|
||||
|
||||
/// A value that can also be in a 'default' state.
|
||||
/** TODO: Defaultable is automatically also Aged
|
||||
*/
|
||||
template <typename T>
|
||||
class Defaultable {
|
||||
public:
|
||||
inline Defaultable() : is_default(true) {}
|
||||
inline Defaultable(const T& v) : value(v), is_default(false) {}
|
||||
|
||||
/// Assigning a value takes this object out of the default state
|
||||
inline void assign(const T& new_value) {
|
||||
value = new_value;
|
||||
is_default = false;
|
||||
}
|
||||
|
||||
/// Get access to the value
|
||||
inline const T& operator () () const { return value; }
|
||||
|
||||
/// Is this value in the default state?
|
||||
inline bool isDefault() const { return is_default; }
|
||||
|
||||
private:
|
||||
/// Is this value in the default state?
|
||||
bool is_default;
|
||||
/// The value
|
||||
T value;
|
||||
|
||||
friend class Reader;
|
||||
friend class Writer;
|
||||
};
|
||||
|
||||
|
||||
// we need some custom io, because the behaviour is different for each of Reader/Writer/GetMember
|
||||
|
||||
template <typename T>
|
||||
void Reader::handle(Defaultable<T>& def) {
|
||||
def.is_default = false;
|
||||
handle(def.value);
|
||||
}
|
||||
template <typename T>
|
||||
void Writer::handle(const Defaultable<T>& def) {
|
||||
if (!def.isDefault()) {
|
||||
handle(def());
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void GetMember::handle(const Defaultable<T>& def) {
|
||||
store(def());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
#endif
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <util/io/get_member.hpp>
|
||||
#include <util/vector2d.hpp>
|
||||
#include <script/value.hpp>
|
||||
#include <script/script.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : GetMember
|
||||
|
||||
@@ -16,12 +17,16 @@ GetMember::GetMember(const String& name)
|
||||
: targetName(name)
|
||||
{}
|
||||
|
||||
void GetMember::store(const String& v) { value = toScript(v); }
|
||||
void GetMember::store(const int v) { value = toScript(v); }
|
||||
void GetMember::store(const unsigned int v) { value = toScript((int)v); }
|
||||
void GetMember::store(const double v) { value = toScript(v); }
|
||||
void GetMember::store(const bool v) { value = toScript(v); }
|
||||
template <> void GetMember::store(const String& v) { value = toScript(v); }
|
||||
//template <> void GetMember::store(const Char* const& v) { value = toScript(v); }
|
||||
template <> void GetMember::store(const int& v) { value = toScript(v); }
|
||||
template <> void GetMember::store(const unsigned int& v) { value = toScript((int)v); }
|
||||
template <> void GetMember::store(const double& v) { value = toScript(v); }
|
||||
template <> void GetMember::store(const bool& v) { value = toScript(v); }
|
||||
|
||||
void GetMember::store(const Vector2D& v) {
|
||||
template <> void GetMember::store(const ScriptValueP& v) { value = v; }
|
||||
template <> void GetMember::store(const ScriptP& v) { value = v; }
|
||||
|
||||
template <> void GetMember::store(const Vector2D& v) {
|
||||
value = toScript(String::Format(_("(%.10lf,%.10lf)"), v.x, v.y));
|
||||
}
|
||||
|
||||
+10
-14
@@ -11,12 +11,11 @@
|
||||
|
||||
#include <util/prec.hpp>
|
||||
|
||||
class ScriptValue;
|
||||
typedef boost::intrusive_ptr<ScriptValue> ScriptValueP;
|
||||
DECLARE_INTRUSIVE_POINTER_TYPE(ScriptValue);
|
||||
inline void intrusive_ptr_add_ref(ScriptValue* p);
|
||||
inline void intrusive_ptr_release(ScriptValue* p);
|
||||
|
||||
class Vector2D;
|
||||
template <typename T> class Defaultable;
|
||||
|
||||
// ----------------------------------------------------------------------------- : GetMember
|
||||
|
||||
@@ -30,7 +29,7 @@ class GetMember {
|
||||
/// Tell the reflection code we are not reading
|
||||
inline bool reading() const { return false; }
|
||||
|
||||
/// The result, or scriptNil if the member was not found
|
||||
/// The result, or script_nil if the member was not found
|
||||
inline ScriptValueP result() { return value; }
|
||||
|
||||
// --------------------------------------------------- : Handling objects
|
||||
@@ -40,16 +39,13 @@ class GetMember {
|
||||
void handle(const Char* name, const T& object) {
|
||||
if (!value && name == targetName) store(object);
|
||||
}
|
||||
template <typename T>
|
||||
void handle(const T&);
|
||||
/// Handle an object: investigate children
|
||||
template <typename T> void handle(const T&);
|
||||
/// Handle a Defaultable: investigate children
|
||||
template <typename T> void handle(const Defaultable<T>& def);
|
||||
|
||||
/// Store something in the return value
|
||||
void store(const String& v);
|
||||
void store(const Vector2D& v);
|
||||
void store(const int v);
|
||||
void store(const unsigned int v);
|
||||
void store(const double v);
|
||||
void store(const bool v);
|
||||
template <typename T> void store(const T& v);
|
||||
/// Store a vector in the return value
|
||||
template <typename T> void store(const vector<T>& vector) {
|
||||
value = toScript(&vector);
|
||||
@@ -76,7 +72,7 @@ class GetMember {
|
||||
|
||||
/// Implement enum reflection as used by GetMember
|
||||
#define REFLECT_ENUM_GET_MEMBER(Enum) \
|
||||
template<> void GetMember::handle<Enum>(const Enum& enum_) {\
|
||||
template<> void GetMember::store<Enum>(const Enum& enum_) { \
|
||||
EnumGetMember gm(*this); \
|
||||
reflect_ ## Enum(const_cast<Enum&>(enum_), gm); \
|
||||
}
|
||||
@@ -91,7 +87,7 @@ class EnumGetMember {
|
||||
template <typename Enum>
|
||||
inline void handle(const Char* name, Enum value, Enum enum_) {
|
||||
if (enum_ == value) {
|
||||
getMember.store(name);
|
||||
getMember.store(String(name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ void Reader::moveNext() {
|
||||
void Reader::readLine() {
|
||||
// fix UTF8 in ascii builds; skip BOM
|
||||
line = decodeUTF8BOM(stream.ReadLine());
|
||||
line_number += 1;
|
||||
// read indentation
|
||||
indent = 0;
|
||||
while ((UInt)indent < line.size() && line.GetChar(indent) == _('\t')) {
|
||||
@@ -70,14 +71,13 @@ void Reader::readLine() {
|
||||
}
|
||||
// read key / value
|
||||
size_t pos = line.find_first_of(_(':'), indent);
|
||||
if (!pos || line.GetChar(indent) == _('#')) {
|
||||
// empty line or comment
|
||||
key.clear();
|
||||
return;
|
||||
}
|
||||
key = cannocial_name_form(trim(line.substr(indent, pos - indent)));
|
||||
value = pos == String::npos ? _("") : trim_left(line.substr(pos+1));
|
||||
// we read a line
|
||||
line_number += 1;
|
||||
// was it a comment?
|
||||
if (!key.empty() && key.GetChar(0) == _('#')) {
|
||||
key.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Handling basic types
|
||||
|
||||
+14
-1
@@ -12,6 +12,8 @@
|
||||
#include <util/prec.hpp>
|
||||
#include <wx/txtstrm.h>
|
||||
|
||||
template <typename T> class Defaultable;
|
||||
|
||||
// ----------------------------------------------------------------------------- : Reader
|
||||
|
||||
typedef wxInputStream InputStream;
|
||||
@@ -57,6 +59,8 @@ class Reader {
|
||||
template <typename T> void handle(shared_ptr<T>& pointer);
|
||||
/// Reads a map from the input stream
|
||||
//template <typename K, typename V> void handle(map<K,V>& map);
|
||||
/// Reads a Defaultable from the input stream
|
||||
template <typename T> void handle(Defaultable<T>& def);
|
||||
|
||||
private:
|
||||
// --------------------------------------------------- : Data
|
||||
@@ -130,7 +134,16 @@ void Reader::handle(shared_ptr<T>& pointer) {
|
||||
/// Implement reflection as used by Reader
|
||||
#define REFLECT_OBJECT_READER(Cls) \
|
||||
template<> void Reader::handle<Cls>(Cls& object) { \
|
||||
object.reflect(*this); \
|
||||
while (indent >= expected_indent) { \
|
||||
UInt l = line_number; \
|
||||
object.reflect(*this); \
|
||||
if (l == line_number) { \
|
||||
/* error */ \
|
||||
do { \
|
||||
moveNext(); \
|
||||
} while (indent > expected_indent); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Reflection for enumerations
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <util/prec.hpp>
|
||||
#include <wx/txtstrm.h>
|
||||
|
||||
template <typename T> class Defaultable;
|
||||
|
||||
// ----------------------------------------------------------------------------- : Writer
|
||||
|
||||
typedef wxOutputStream OutputStream;
|
||||
@@ -48,6 +50,8 @@ class Writer {
|
||||
template <typename T> void handle(const shared_ptr<T>& pointer);
|
||||
/// Write a map to the output stream
|
||||
//template <typename K, typename V> void handle(map<K,V>& map);
|
||||
/// Write an object of type Defaultable<T> to the output stream
|
||||
template <typename T> void handle(const Defaultable<T>& def);
|
||||
|
||||
private:
|
||||
// --------------------------------------------------- : Data
|
||||
|
||||
@@ -82,6 +82,8 @@
|
||||
#define REFLECT(var) tag.handle(_(#var), var)
|
||||
/// Reflect a variable under the given name
|
||||
#define REFLECT_N(name, var) tag.handle(_(name), var)
|
||||
/// Reflect a variable without a name, should be used only once per class
|
||||
#define REFLECT_NAMELESS(var) tag.handle(var)
|
||||
|
||||
/// Declare that the variables of a base class should also be reflected
|
||||
#define REFLECT_BASE(Base) Base::reflect_impl(tag)
|
||||
|
||||
@@ -68,6 +68,12 @@ inline shared_ptr<T> new_shared7(const A0& a0, const A1& a1, const A2& a2, const
|
||||
|
||||
#ifdef USE_INTRUSIVE_PTR
|
||||
|
||||
/// Declares the type TypeP as a intrusive_ptr<Type>
|
||||
#define DECLARE_INTRUSIVE_POINTER_TYPE(Type) \
|
||||
class Type; \
|
||||
typedef intrusive_ptr<Type> Type##P;
|
||||
|
||||
|
||||
/// Allocate a new intrusive-pointed object
|
||||
template <typename T>
|
||||
inline intrusive_ptr<T> new_intrusive() {
|
||||
@@ -85,6 +91,7 @@ inline shared_ptr<T> new_shared7(const A0& a0, const A1& a1, const A2& a2, const
|
||||
}
|
||||
|
||||
#else
|
||||
#define DECLARE_INTRUSIVE_POINTER_TYPE DECLARE_POINTER_TYPE
|
||||
#define intrusive_ptr smart_ptr
|
||||
#define new_intrusive new_smart
|
||||
#define new_intrusive1 new_smart1
|
||||
|
||||
Reference in New Issue
Block a user