mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-13 05:57:00 -04:00
Added ScriptableImage plus the beginnings of dependency stuff
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@58 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -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 @@
|
|||||||
#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 {
|
|||||||
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 @@
|
|||||||
#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)
|
|||||||
, 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
-1
@@ -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);
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
/// 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+15
-6
@@ -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);
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : 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);
|
|||||||
*/
|
*/
|
||||||
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 @@
|
|||||||
<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 @@
|
|||||||
<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 @@
|
|||||||
<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; }
|
|||||||
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 @@
|
|||||||
|
|
||||||
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 {
|
|||||||
/// 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 @@
|
|||||||
// ----------------------------------------------------------------------------- : 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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 @@
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : 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 {
|
|||||||
|
|
||||||
#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: \
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| 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")))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| 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
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| 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>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- :
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| 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
|
|||||||
, 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
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| 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;
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| 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
|
|||||||
, 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) {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
// 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 {
|
|||||||
/** 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; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user