Commit 3cbbe729 authored by twanvl's avatar twanvl

Added ScriptableImage plus the beginnings of dependency stuff

parent 06c75f4e
...@@ -179,7 +179,7 @@ IMPLEMENT_REFLECTION(ChoiceStyle) { ...@@ -179,7 +179,7 @@ IMPLEMENT_REFLECTION(ChoiceStyle) {
REFLECT(alignment); REFLECT(alignment);
REFLECT(colors_card_list); REFLECT(colors_card_list);
// REFLECT(font); // REFLECT(font);
// REFLECT(choice_images); REFLECT(choice_images);
// if (tag.reading() && choice_colors.empty()) // if (tag.reading() && choice_colors.empty())
REFLECT(choice_colors); REFLECT(choice_colors);
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <data/field.hpp> #include <data/field.hpp>
#include <gfx/gfx.hpp> // for ImageCombine #include <gfx/gfx.hpp> // for ImageCombine
#include <script/scriptable.hpp> #include <script/scriptable.hpp>
#include <script/image.hpp>
// ----------------------------------------------------------------------------- : ChoiceField // ----------------------------------------------------------------------------- : ChoiceField
...@@ -115,7 +116,7 @@ class ChoiceStyle : public Style { ...@@ -115,7 +116,7 @@ class ChoiceStyle : public Style {
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
// FontInfo font; ///< Font for drawing text (when RENDER_TEXT) // FontInfo font; ///< Font for drawing text (when RENDER_TEXT)
// map<String,ScriptableImage> choice_images; ///< Images for the various choices (when RENDER_IMAGE) 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) 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? bool colors_card_list;///< Does this field determine colors of the rows in the card list?
String mask_filename; ///< Filename of an additional mask over the images String mask_filename; ///< Filename of an additional mask over the images
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <data/card.hpp> #include <data/card.hpp>
#include <data/field.hpp> #include <data/field.hpp>
#include <script/value.hpp> #include <script/value.hpp>
#include <script/script_manager.hpp>
// ----------------------------------------------------------------------------- : Set // ----------------------------------------------------------------------------- : Set
...@@ -26,8 +27,18 @@ Set::Set(const StyleSheetP& stylesheet) ...@@ -26,8 +27,18 @@ Set::Set(const StyleSheetP& stylesheet)
, game(stylesheet->game) , game(stylesheet->game)
{} {}
Set::~Set() {}
Context& Set::getContext() {
throw "TODO";
}
String Set::typeName() const { return _("set"); } String Set::typeName() const { return _("set"); }
void Set::validate() {
}
IMPLEMENT_REFLECTION(Set) { IMPLEMENT_REFLECTION(Set) {
tag.addAlias(300, _("style"), _("stylesheet")); // < 0.3.0 used style instead of stylesheet tag.addAlias(300, _("style"), _("stylesheet")); // < 0.3.0 used style instead of stylesheet
REFLECT(game); REFLECT(game);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <util/reflect.hpp> #include <util/reflect.hpp>
#include <util/action_stack.hpp> #include <util/action_stack.hpp>
#include <util/io/package.hpp> #include <util/io/package.hpp>
#include <boost/scoped_ptr.hpp>
DECLARE_POINTER_TYPE(Card); DECLARE_POINTER_TYPE(Card);
DECLARE_POINTER_TYPE(Set); DECLARE_POINTER_TYPE(Set);
...@@ -20,6 +21,8 @@ DECLARE_POINTER_TYPE(Game); ...@@ -20,6 +21,8 @@ DECLARE_POINTER_TYPE(Game);
DECLARE_POINTER_TYPE(StyleSheet); DECLARE_POINTER_TYPE(StyleSheet);
DECLARE_POINTER_TYPE(Field); DECLARE_POINTER_TYPE(Field);
DECLARE_POINTER_TYPE(Value); DECLARE_POINTER_TYPE(Value);
class ScriptManager;
class Context;
// ----------------------------------------------------------------------------- : Set // ----------------------------------------------------------------------------- : Set
...@@ -32,6 +35,7 @@ class Set : public Packaged { ...@@ -32,6 +35,7 @@ class Set : public Packaged {
Set(const GameP& game); Set(const GameP& game);
/// Create a set using the given stylesheet, and its game /// Create a set using the given stylesheet, and its game
Set(const StyleSheetP& stylesheet); Set(const StyleSheetP& stylesheet);
~Set();
/// The game this set uses /// The game this set uses
GameP game; GameP game;
...@@ -47,10 +51,18 @@ class Set : public Packaged { ...@@ -47,10 +51,18 @@ class Set : public Packaged {
/// Actions performed on this set and the cards in it /// Actions performed on this set and the cards in it
ActionStack actions; ActionStack actions;
/// A context for performing scripts
/** Should only be used from the main thread! */
Context& getContext();
protected: protected:
String typeName() const; virtual String typeName() const;
virtual void validate();
DECLARE_REFLECTION(); DECLARE_REFLECTION();
private:
/// Object for managing and executing scripts
scoped_ptr<ScriptManager> script_manager;
}; };
......
...@@ -37,6 +37,14 @@ void resample(const Image& imgIn, Image& imgOut); ...@@ -37,6 +37,14 @@ void resample(const Image& imgIn, Image& imgOut);
/// that rectangle is resampledinto the entire output image /// that rectangle is resampledinto the entire output image
void resample_and_clip(const Image& imgIn, Image& imgOut, wxRect rect); void resample_and_clip(const Image& imgIn, Image& imgOut, wxRect rect);
/// How to preserve the aspect ratio of an image when rescaling
enum PreserveAspect
{ ASPECT_STRETCH ///< don't preserve
, ASPECT_BORDER ///< put borders around the image to make it the right shape
, ASPECT_FIT ///< generate a smaller image if needed
};
// ----------------------------------------------------------------------------- : Image rotation // ----------------------------------------------------------------------------- : Image rotation
/// Rotates an image counter clockwise /// Rotates an image counter clockwise
...@@ -45,14 +53,12 @@ Image rotate_image(const Image& image, int angle); ...@@ -45,14 +53,12 @@ Image rotate_image(const Image& image, int angle);
// ----------------------------------------------------------------------------- : Blending // ----------------------------------------------------------------------------- : Blending
/// Blends two images together, using a horizontal gradient /// Blends two images together using some linear gradient
/** The result is stored in img1 /** The result is stored in img1
* To the left the color is that of img1, to the right of img2 * The two coordinates give the two points between which the images are blended
* Coordinates are given in the range [0..1);
*/ */
void hblend(Image& img1, const Image& img2); void linear_blend(Image& img1, const Image& img2, double x1,double y1, double x2,double y2);
/// Blends two images together, using a vertical gradient
void vblend(Image& img1, const Image& img2);
/// Blends two images together, using a third image as a mask /// Blends two images together, using a third image as a mask
/** The result is stored in img1 /** The result is stored in img1
...@@ -61,6 +67,9 @@ void vblend(Image& img1, const Image& img2); ...@@ -61,6 +67,9 @@ void vblend(Image& img1, const Image& img2);
*/ */
void mask_blend(Image& img1, const Image& img2, const Image& mask); void mask_blend(Image& img1, const Image& img2, const Image& mask);
/// Use the red channel of img2 as alpha channel for img1
void set_alpha(Image& img1, const Image& img2);
// ----------------------------------------------------------------------------- : Combining // ----------------------------------------------------------------------------- : Combining
/// Ways in which images can be combined, similair to what Photoshop supports /// Ways in which images can be combined, similair to what Photoshop supports
......
...@@ -999,6 +999,12 @@ ...@@ -999,6 +999,12 @@
<File <File
RelativePath=".\util\action_stack.hpp"> RelativePath=".\util\action_stack.hpp">
</File> </File>
<File
RelativePath=".\util\age.cpp">
</File>
<File
RelativePath=".\util\age.hpp">
</File>
<File <File
RelativePath=".\util\alignment.cpp"> RelativePath=".\util\alignment.cpp">
</File> </File>
...@@ -1113,6 +1119,36 @@ ...@@ -1113,6 +1119,36 @@
<File <File
RelativePath=".\script\dependency.cpp"> RelativePath=".\script\dependency.cpp">
</File> </File>
<File
RelativePath=".\script\image.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)3.obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)3.obj"/>
</FileConfiguration>
<FileConfiguration
Name="Debug Unicode|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)3.obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release Unicode|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)3.obj"/>
</FileConfiguration>
</File>
<File
RelativePath=".\script\image.hpp">
</File>
<File <File
RelativePath=".\script\parser.cpp"> RelativePath=".\script\parser.cpp">
</File> </File>
...@@ -1125,6 +1161,12 @@ ...@@ -1125,6 +1161,12 @@
<File <File
RelativePath=".\script\script.hpp"> RelativePath=".\script\script.hpp">
</File> </File>
<File
RelativePath=".\script\script_manager.cpp">
</File>
<File
RelativePath=".\script\script_manager.hpp">
</File>
<File <File
RelativePath=".\script\scriptable.cpp"> RelativePath=".\script\scriptable.cpp">
</File> </File>
......
...@@ -48,6 +48,7 @@ bool DataViewer::drawBorders() const { return false; } ...@@ -48,6 +48,7 @@ bool DataViewer::drawBorders() const { return false; }
bool DataViewer::drawEditing() const { return false; } bool DataViewer::drawEditing() const { return false; }
wxPen DataViewer::borderPen(bool) const { return wxPen(); } wxPen DataViewer::borderPen(bool) const { return wxPen(); }
ValueViewer* DataViewer::focusedViewer() const { return nullptr; } ValueViewer* DataViewer::focusedViewer() const { return nullptr; }
Context& DataViewer::getContext() const { return set->getContext(); }
// ----------------------------------------------------------------------------- : Setting data // ----------------------------------------------------------------------------- : Setting data
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
DECLARE_POINTER_TYPE(Style); DECLARE_POINTER_TYPE(Style);
DECLARE_POINTER_TYPE(ValueViewer); DECLARE_POINTER_TYPE(ValueViewer);
class Context;
// ----------------------------------------------------------------------------- : DataViewer // ----------------------------------------------------------------------------- : DataViewer
...@@ -47,6 +48,8 @@ class DataViewer : public SetView { ...@@ -47,6 +48,8 @@ class DataViewer : public SetView {
/// The viewer that is currently focused, may be null /// The viewer that is currently focused, may be null
/** null by default, can be overloaded */ /** null by default, can be overloaded */
virtual ValueViewer* focusedViewer() const; virtual ValueViewer* focusedViewer() const;
/// Get a script context to use for scripts in the viewers
Context& getContext() const;
// --------------------------------------------------- : Setting data // --------------------------------------------------- : Setting data
......
...@@ -7,5 +7,44 @@ ...@@ -7,5 +7,44 @@
// ----------------------------------------------------------------------------- : Includes // ----------------------------------------------------------------------------- : Includes
#include <render/value/choice.hpp> #include <render/value/choice.hpp>
#include <render/card/viewer.hpp>
// ----------------------------------------------------------------------------- : // ----------------------------------------------------------------------------- : ChoiceValueViewer
void ChoiceValueViewer::draw(RotatedDC& dc) {
drawFieldBorder(dc);
if (value().value().empty()) return;
double margin = 0;
if (style().render_style & RENDER_IMAGE) {
// draw image
map<String,ScriptableImage>::iterator it = style().choice_images.find(value().value());
if (it != style().choice_images.end()) {
ScriptableImage& img = it->second;
ScriptImageP i;
if (nativeLook()) {
i = img.update(viewer.getContext(), 16, 16, ASPECT_BORDER, false);
} else if(style().render_style & RENDER_TEXT) {
// also drawing text
i = img.update(viewer.getContext(), 0, 0);
} else {
i = img.update(viewer.getContext(),
dc.trS(style().width), dc.trS(style().height),
style().alignment == ALIGN_STRETCH ? ASPECT_STRETCH : ASPECT_FIT
);
}
if (i) {
dc.DrawImage(i->image,
align_in_rect(style().alignment, RealSize(i->image.GetWidth(), i->image.GetHeight()), style().getRect()),
i->combine == COMBINE_NORMAL ? style().combine : i->combine
);
margin = i->image.GetWidth() + 1;
}
}
}
if (style().render_style & RENDER_TEXT) {
// draw text
dc.DrawText(capitalize(value().value()),
align_in_rect(ALIGN_MIDDLE_LEFT, RealSize(0, dc.GetCharHeight()), style().getRect()) + RealSize(margin, 0)
);
}
}
\ No newline at end of file
...@@ -10,9 +10,18 @@ ...@@ -10,9 +10,18 @@
// ----------------------------------------------------------------------------- : Includes // ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp> #include <util/prec.hpp>
#include <render/value/viewer.hpp>
#include <data/field/choice.hpp>
// ----------------------------------------------------------------------------- : // ----------------------------------------------------------------------------- : ChoiceValueViewer
/// Viewer that displays a choice value
class ChoiceValueViewer : public ValueViewer {
public:
DECLARE_VALUE_VIEWER(Choice) : ValueViewer(parent,style) {}
virtual void draw(RotatedDC& dc);
};
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
#endif #endif
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
// ----------------------------------------------------------------------------- : ColorValueViewer // ----------------------------------------------------------------------------- : ColorValueViewer
/// Viewer that displays an color value /// Viewer that displays a color value
class ColorValueViewer : public ValueViewer { class ColorValueViewer : public ValueViewer {
public: public:
DECLARE_VALUE_VIEWER(Color) : ValueViewer(parent,style) {} DECLARE_VALUE_VIEWER(Color) : ValueViewer(parent,style) {}
......
...@@ -76,7 +76,7 @@ class ValueViewer { ...@@ -76,7 +76,7 @@ class ValueViewer {
#define DECLARE_VALUE_VIEWER(Type) \ #define DECLARE_VALUE_VIEWER(Type) \
private: \ private: \
inline const Type##Style& style() const { return static_cast<const Type##Style&>(*styleP); } \ inline Type##Style& style() const { return static_cast< Type##Style&>(*styleP); } \
inline const Type##Value& value() const { return static_cast<const Type##Value&>(*valueP); } \ inline const Type##Value& value() const { return static_cast<const Type##Value&>(*valueP); } \
inline const Type##Field& field() const { return style().field(); } \ inline const Type##Field& field() const { return style().field(); } \
public: \ public: \
......
//+----------------------------------------------------------------------------+
//| 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 <script/image.hpp>
#include <script/context.hpp>
#include <util/dynamic_arg.hpp>
#include <util/io/package.hpp>
// image generating functions have two modes
// if last_update_age > 0 they return whether the image is still up to date
// if last_update_age == 0 they generate the image
DECLARE_DYNAMIC_ARG (long, last_update_age);
IMPLEMENT_DYNAMIC_ARG(long, last_update_age, 0);
IMPLEMENT_DYNAMIC_ARG(Package*, load_images_from, nullptr);
// ----------------------------------------------------------------------------- : ScriptImage
ScriptType ScriptImage::type() const { return SCRIPT_IMAGE; }
String ScriptImage::typeName() const { return _("image"); }
// ----------------------------------------------------------------------------- : Utility
/// Convert a script value to an image
ScriptImageP to_script_image(const ScriptValueP& value) {
if (ScriptImageP img = dynamic_pointer_cast<ScriptImage>(value)) {
return img; // already an image
} else if (value->type() == SCRIPT_STRING) {
// open a file
String filename = *value;
Package* pkg = load_images_from();
if (!pkg) throw ScriptError(_("Can only load images in a context where an image is expected"));
InputStreamP file = pkg->openIn(filename);
ScriptImageP img = new_intrusive<ScriptImage>();
if (img->image.LoadFile(*file)) {
if (img->image.HasMask()) img->image.InitAlpha(); // we can't handle masks
return img;
} else {
throw ScriptError(_("Unable to load image '") + filename + _("' from '" + pkg->name() + _("'")));
}
} else {
throw ScriptError(_("Can not convert from '") + value->typeName() + _("' to image"));
}
}
/// Is the given image up to date?
bool script_image_up_to_date(const ScriptValueP& value) {
if (value->type() == SCRIPT_INT) {
return (int)*value; // boolean up-to-dateness from parameter
} else {
return true;
}
}
// ----------------------------------------------------------------------------- : ScriptableImage
ScriptImageP ScriptableImage::update(Context& ctx, UInt width, UInt height, PreserveAspect preserve_aspect, bool saturate) {
// up to date?
if (!cache || (UInt)cache->image.GetWidth() != width || (UInt)cache->image.GetHeight() == height) {
// cache must be updated
cache = generate(ctx, width, height, preserve_aspect, saturate);
last_update.update();
}
return cache;
}
// ----------------------------------------------------------------------------- : Reflection
// we need some custom io, because the behaviour is different for each of Reader/Writer/GetMember
template <> void Reader::handle(ScriptableImage& s) {
handle(s.script.unparsed);
if (starts_with(s.script.unparsed, _("script:"))) {
s.script.unparsed = s.script.unparsed.substr(7);
s.script.parse(*this);
} else {
// script is a constant function
s.script.script = new_intrusive<Script>();
s.script.script->addInstruction(I_PUSH_CONST, s.script.unparsed);
}
}
template <> void Writer::handle(const ScriptableImage& s) {
handle(s.script.unparsed);
}
template <> void GetDefaultMember::handle(const ScriptableImage& s) {
handle(s.script.unparsed);
}
// ----------------------------------------------------------------------------- : Functions
SCRIPT_FUNCTION(linear_blend) {
if (last_update_age() == 0) {
ScriptImageP image1 = to_script_image(ctx.getVariable(_("image1")));
ScriptImageP image2 = to_script_image(ctx.getVariable(_("image2")));
SCRIPT_PARAM(double, x1); SCRIPT_PARAM(double, y1);
SCRIPT_PARAM(double, x2); SCRIPT_PARAM(double, y2);
linear_blend(image1->image, image2->image, x1, y1, x2, y2);
return image1;
} else {
SCRIPT_RETURN(
script_image_up_to_date(ctx.getVariable(_("image1"))) &&
script_image_up_to_date(ctx.getVariable(_("image2")))
);
}
}
SCRIPT_FUNCTION(masked_blend) {
if (last_update_age() == 0) {
ScriptImageP light = to_script_image(ctx.getVariable(_("light")));
ScriptImageP dark = to_script_image(ctx.getVariable(_("dark")));
ScriptImageP mask = to_script_image(ctx.getVariable(_("mask")));
mask_blend(light->image, dark->image, mask->image);
return light;
} else {
SCRIPT_RETURN(
script_image_up_to_date(ctx.getVariable(_("light"))) &&
script_image_up_to_date(ctx.getVariable(_("dark" ))) &&
script_image_up_to_date(ctx.getVariable(_("mask" )))
);
}
}
SCRIPT_FUNCTION(set_mask) {
if (last_update_age() == 0) {
ScriptImageP image = to_script_image(ctx.getVariable(_("image")));
ScriptImageP mask = to_script_image(ctx.getVariable(_("mask")));
set_alpha(image->image, mask->image);
return image;
} else {
SCRIPT_RETURN(
script_image_up_to_date(ctx.getVariable(_("image"))) &&
script_image_up_to_date(ctx.getVariable(_("mask")))
);
}
}
//+----------------------------------------------------------------------------+
//| 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_SCRIPT_IMAGE
#define HEADER_SCRIPT_IMAGE
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <util/age.hpp>
#include <script/scriptable.hpp>
#include <gfx/gfx.hpp>
#include <util/dynamic_arg.hpp>
class Package;
DECLARE_INTRUSIVE_POINTER_TYPE(ScriptImage);
// ----------------------------------------------------------------------------- : ScriptableImage
DECLARE_DYNAMIC_ARG(Package*, load_images_from);
/// An image, returned by a script function
class ScriptImage : public ScriptValue {
public:
inline ScriptImage() : combine(COMBINE_NORMAL) {}
inline ScriptImage(const Image& image, ImageCombine combine = COMBINE_NORMAL)
: image(image), combine(combine)
{}
Image image; ///< The image
ImageCombine combine; ///< How to combine the image with the background
virtual ScriptType type() const;
virtual String typeName() const;
};
/// An image that can also be scripted
/** Differs from Scriptable<Image> in that:
* - A script is always used
* - Age is checked, chached images are used if possible
* - The image can be scaled
*/
class ScriptableImage {
public:
/// Is there an image set?
inline operator bool() const { return script; }
/// Generate an image, doesn't cache, and doesn't scale
ScriptImageP generate(Context& ctx) const;
/// Generate an image, scaling it and optionally saturating it
ScriptImageP generate(Context& ctx, UInt width, UInt height, PreserveAspect preserve_aspect = ASPECT_STRETCH, bool saturate = false) const;
/// Update and return the cached image
/** Only recomputes the image if it is out of date, or the size doesn't match.
* If width==height==0 then doesn't resample.
*/
ScriptImageP update(Context& ctx, UInt width = 0, UInt height = 0, PreserveAspect preserve_aspect = ASPECT_STRETCH, bool saturate = false);
/// Is the cached image up to date?
bool upToDate(Context& ctx, Age age) const;
private:
OptionalScript script; ///< The script, not really optional
ScriptImageP cache; ///< The cached image
Age last_update; ///< Age of last image update of the cached image
DECLARE_REFLECTION();
};
/// Missing for now
inline ScriptValueP toScript(const ScriptableImage&) { return script_nil; }
// ----------------------------------------------------------------------------- : EOF
#endif
//+----------------------------------------------------------------------------+
//| 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 <script/script_manager.hpp>
// ----------------------------------------------------------------------------- :
//+----------------------------------------------------------------------------+
//| 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_SCRIPT_SCRIPT_MANAGER
#define HEADER_SCRIPT_SCRIPT_MANAGER
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <script/context.hpp>
#include <data/set.hpp>
// ----------------------------------------------------------------------------- : Dependency
/// Types of dependencies
enum DependencyType
{ DEP_CARD_FIELD ///< dependency of a script in a "card" field
, DEP_CARDS_FIELD ///< dependency of a script in a "card" field for all cards
, DEP_SET_INFO_FIELD ///< dependency of a script in a "set" field
, DEP_STYLESHEET_FIELD ///< dependency of a script in a "style" property
, DEP_CARD_COPY_DEP ///< copy the dependencies from a card field
, DEP_SET_COPY_DEP ///< copy the dependencies from a set field
, DEP_CHOICE_IMAGE ///< dependency of a generated choice image, index2 gives the index of the choice image
};
/// A 'pointer' to some script that depends on another script
class Dependency {
public:
DependencyType type : 4; ///< Type of the dependent script
UInt index2 : 10; ///< A second index, used for some types
size_t index; ///< index into an IndexMap
};
// ----------------------------------------------------------------------------- : Dependencies of data type members
// ----------------------------------------------------------------------------- : ScriptManager
/// Manager of the script context for a set, keeps scripts up to date
/** Whenever there is an action all necessary scripts are executed.
* Executes both Value scripts and Style scriptables.
*
* The context contains a normal pointer to the set, not a shared_ptr, because the set
* itself owns this object.
*/
class ScriptManager : public ActionListener {
public:
ScriptManager(Set& set);
private:
Context context; ///< Context for evaluating scripts
void initScriptStuff();
void initDependencies();
void initDependencies(const StyleSheetP&);
void initContext(const StyleSheetP&);
// Update all styles for a particular card
void updateStyles(const CardP& card);
/// Updates scripts, starting at some value
/** if the value changes any dependend values are updated as well */
void updateValue(Value* value, const CardP& card);
/// Update all fields of all cards
/** Update all set info fields
* Doesn't update styles
*/
void updateAll();
// Update all values with a specific dependency
void updateAllDependend(const vector<Dependency>& dependendScripts);
protected:
/// Respond to actions by updating scripts
void onAction(const Action&, bool undone);
};
// ----------------------------------------------------------------------------- : EOF
#endif
...@@ -35,6 +35,7 @@ enum ScriptType ...@@ -35,6 +35,7 @@ enum ScriptType
, SCRIPT_DOUBLE , SCRIPT_DOUBLE
, SCRIPT_STRING , SCRIPT_STRING
, SCRIPT_COLOR , SCRIPT_COLOR
, SCRIPT_IMAGE
, SCRIPT_BUILDIN_FUN , SCRIPT_BUILDIN_FUN
, SCRIPT_SCRIPT_FUN , SCRIPT_SCRIPT_FUN
, SCRIPT_OBJECT , SCRIPT_OBJECT
......
//+----------------------------------------------------------------------------+
//| 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/age.hpp>
// ----------------------------------------------------------------------------- : Age
// what a waste of a source file...
volatile LONG Age::new_age;
//+----------------------------------------------------------------------------+
//| 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_AGE
#define HEADER_UTIL_AGE
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#ifdef _MSC_VER
extern "C" {
LONG __cdecl _InterlockedIncrement(LONG volatile *Addend);
LONG __cdecl _InterlockedDecrement(LONG volatile *Addend);
}
#pragma intrinsic (_InterlockedIncrement)
#define InterlockedIncrement _InterlockedIncrement
#pragma intrinsic (_InterlockedDecrement)
#define InterlockedDecrement _InterlockedDecrement
#endif
// ----------------------------------------------------------------------------- : Age
/// Represents the age of a value, higher values are newer
/** Age is counted using a global variable */
class Age {
public:
/// Construct a new age value,
Age() {
update();
}
/// Update the age to become the newest one
inline void update() {
age = InterlockedIncrement(&new_age);
}
/// Compare two ages, smaller means earlier
inline bool operator < (Age a) const { return age < a.age; }
private:
/// This age
LONG age;
/// Global age counter, value of the last age created
static volatile LONG new_age;
};
// ----------------------------------------------------------------------------- : Aged
// ----------------------------------------------------------------------------- : EOF
#endif
...@@ -33,6 +33,7 @@ enum Alignment ...@@ -33,6 +33,7 @@ enum Alignment
, ALIGN_STRETCH = 0x2000 , ALIGN_STRETCH = 0x2000
// common combinations // common combinations
, ALIGN_TOP_LEFT = ALIGN_TOP | ALIGN_LEFT , ALIGN_TOP_LEFT = ALIGN_TOP | ALIGN_LEFT
, ALIGN_MIDDLE_LEFT = ALIGN_MIDDLE | ALIGN_LEFT
, ALIGN_MIDDLE_CENTER = ALIGN_MIDDLE | ALIGN_CENTER , ALIGN_MIDDLE_CENTER = ALIGN_MIDDLE | ALIGN_CENTER
}; };
......
...@@ -146,8 +146,11 @@ void RotatedDC::SetFont(wxFont font, double size) { ...@@ -146,8 +146,11 @@ void RotatedDC::SetFont(wxFont font, double size) {
dc.SetFont(font); dc.SetFont(font);
} }
RealSize RotatedDC::GetTextExtent(const String& text) { RealSize RotatedDC::GetTextExtent(const String& text) const {
int w, h; int w, h;
dc.GetTextExtent(text, &w, &h); dc.GetTextExtent(text, &w, &h);
return RealSize(w,h) / zoom; return RealSize(w,h) / zoom;
} }
double RotatedDC::GetCharHeight() const {
return dc.GetCharHeight() / zoom;
}
...@@ -108,7 +108,7 @@ class RotatedDC : public Rotation { ...@@ -108,7 +108,7 @@ class RotatedDC : public Rotation {
RotatedDC(DC& dc, int angle, const RealRect& rect, double zoom, bool high_quality); RotatedDC(DC& dc, int angle, const RealRect& rect, double zoom, bool high_quality);
RotatedDC(DC& dc, const Rotation& rotation, bool high_quality); RotatedDC(DC& dc, const Rotation& rotation, bool high_quality);
// ----------------------------- : Drawing // --------------------------------------------------- : Drawing
void DrawText (const String& text, const RealPoint& pos); void DrawText (const String& text, const RealPoint& pos);
/// Draw abitmap, it must already be zoomed! /// Draw abitmap, it must already be zoomed!
...@@ -122,7 +122,7 @@ class RotatedDC : public Rotation { ...@@ -122,7 +122,7 @@ class RotatedDC : public Rotation {
// Fill the dc with the color of the current brush // Fill the dc with the color of the current brush
void Fill(); void Fill();
// ----------------------------- : Forwarded properties // --------------------------------------------------- : Forwarded properties
/// Sets the pen for the dc, does not scale the line width /// Sets the pen for the dc, does not scale the line width
void SetPen(const wxPen&); void SetPen(const wxPen&);
...@@ -134,7 +134,8 @@ class RotatedDC : public Rotation { ...@@ -134,7 +134,8 @@ class RotatedDC : public Rotation {
/** The font will get the given (internal) point size */ /** The font will get the given (internal) point size */
void SetFont(wxFont font, double size); void SetFont(wxFont font, double size);
RealSize GetTextExtent(const String& text); RealSize GetTextExtent(const String& text) const;
double GetCharHeight() const;
inline wxDC& getDC() { return dc; } inline wxDC& getDC() { return dc; }
......
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