mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
choice images work
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@63 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -108,7 +108,7 @@ void combine_image(Image& a, const Image& b, ImageCombine combine) {
|
||||
// Combine image data, by dispatching to combineImageDo
|
||||
switch(combine) {
|
||||
#define DISPATCH(comb) case comb: combine_image_do<comb>(a,b); return
|
||||
DISPATCH(COMBINE_NORMAL);
|
||||
case COMBINE_NORMAL: a = b; return; // no need to do a per pixel operation
|
||||
DISPATCH(COMBINE_ADD);
|
||||
DISPATCH(COMBINE_SUBTRACT);
|
||||
DISPATCH(COMBINE_STAMP);
|
||||
@@ -135,5 +135,18 @@ void combine_image(Image& a, const Image& b, ImageCombine combine) {
|
||||
}
|
||||
|
||||
void draw_combine_image(DC& dc, UInt x, UInt y, const Image& img, ImageCombine combine) {
|
||||
// todo
|
||||
}
|
||||
if (combine == COMBINE_NORMAL) {
|
||||
dc.DrawBitmap(img, x, y);
|
||||
} else {
|
||||
// Capture the current image in the target rectangle
|
||||
Bitmap sourceB(img.GetWidth(), img.GetHeight());
|
||||
wxMemoryDC sourceDC;
|
||||
sourceDC.SelectObject(sourceB);
|
||||
sourceDC.Blit(0, 0, img.GetWidth(), img.GetHeight(), &dc, x, y);
|
||||
sourceDC.SelectObject(wxNullBitmap);
|
||||
Image source = sourceB.ConvertToImage();
|
||||
// Combine and draw
|
||||
combine_image(source, img, combine);
|
||||
dc.DrawBitmap(source, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -178,7 +178,7 @@
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="rpcrt4.lib wsock32.lib comctl32.lib wxbase26ud.lib wxmsw26ud_core.lib wxjpegd.lib wxpngd.lib wxtiffd.lib wxzlibd.lib wxregexd.lib"
|
||||
AdditionalDependencies="rpcrt4.lib wsock32.lib comctl32.lib wxbase26ud.lib wxmsw26ud_core.lib wxjpegd.lib wxpngd.lib wxtiffd.lib wxzlibd.lib wxregexud.lib"
|
||||
OutputFile="$(OutDir)/mse.exe"
|
||||
LinkIncremental="2"
|
||||
IgnoreDefaultLibraryNames="libcd.lib,libcid.lib"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <render/value/choice.hpp>
|
||||
#include <render/card/viewer.hpp>
|
||||
#include <data/stylesheet.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : ChoiceValueViewer
|
||||
|
||||
@@ -22,12 +23,12 @@ void ChoiceValueViewer::draw(RotatedDC& dc) {
|
||||
ScriptableImage& img = it->second;
|
||||
ScriptImageP i;
|
||||
if (nativeLook()) {
|
||||
i = img.update(viewer.getContext(), 16, 16, ASPECT_BORDER, false);
|
||||
i = img.update(viewer.getContext(), *getSet().stylesheet, 16, 16, ASPECT_BORDER, false);
|
||||
} else if(style().render_style & RENDER_TEXT) {
|
||||
// also drawing text
|
||||
i = img.update(viewer.getContext(), 0, 0);
|
||||
i = img.update(viewer.getContext(), *getSet().stylesheet, 0, 0);
|
||||
} else {
|
||||
i = img.update(viewer.getContext(),
|
||||
i = img.update(viewer.getContext(), *getSet().stylesheet,
|
||||
dc.trS(style().width), dc.trS(style().height),
|
||||
style().alignment == ALIGN_STRETCH ? ASPECT_STRETCH : ASPECT_FIT
|
||||
);
|
||||
|
||||
@@ -24,7 +24,44 @@ class ScriptReplaceRule : public ScriptValue {
|
||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; }
|
||||
virtual String typeName() const { return _("replace_rule"); }
|
||||
virtual ScriptValueP eval(Context& ctx) const {
|
||||
throw "TODO";
|
||||
SCRIPT_PARAM(String, input);
|
||||
if (context.IsValid() || replacement_function) {
|
||||
// match first, then check context of match
|
||||
String ret;
|
||||
while (regex.Matches(input)) {
|
||||
// for each match ...
|
||||
size_t start, len;
|
||||
bool ok = regex.GetMatch(&start, &len, 0);
|
||||
assert(ok);
|
||||
ret += input.substr(0, start); // everything before the match position stays
|
||||
String inside = input.substr(start, len); // inside the match
|
||||
String next_input = input.substr(start + len); // next loop the input is after this match
|
||||
String after_replace = ret + _("<match>") + next_input; // after replacing, the resulting context would be
|
||||
if (!context.IsValid() || context.Matches(after_replace)) {
|
||||
// the context matches -> perform replacement
|
||||
if (replacement_function) {
|
||||
// set match results in context
|
||||
for (UInt m = 0 ; m < regex.GetMatchCount() ; ++m) {
|
||||
regex.GetMatch(&start, &len, m);
|
||||
String name = m == 0 ? _("input") : String(_("_")) << m;
|
||||
String value = input.substr(start, len);
|
||||
ctx.setVariable(name, toScript(value));
|
||||
}
|
||||
// call
|
||||
inside = (String)*replacement_function->eval(ctx);
|
||||
} else {
|
||||
regex.Replace(&inside, replacement, 1); // replace inside
|
||||
}
|
||||
}
|
||||
ret += inside;
|
||||
input = next_input;
|
||||
}
|
||||
SCRIPT_RETURN(ret);
|
||||
} else {
|
||||
// dumb replacing
|
||||
regex.Replace(&input, replacement);
|
||||
SCRIPT_RETURN(input);
|
||||
}
|
||||
}
|
||||
|
||||
wxRegEx regex; ///< Regex to match
|
||||
@@ -59,6 +96,38 @@ SCRIPT_FUNCTION(replace_rule) {
|
||||
|
||||
// ----------------------------------------------------------------------------- : Rules : regex filter
|
||||
|
||||
class ScriptFilterRule : public ScriptValue {
|
||||
public:
|
||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; }
|
||||
virtual String typeName() const { return _("replace_rule"); }
|
||||
virtual ScriptValueP eval(Context& ctx) const {
|
||||
SCRIPT_PARAM(String, input);
|
||||
String ret;
|
||||
while (regex.Matches(input)) {
|
||||
// match, append to result
|
||||
size_t start, len;
|
||||
bool ok = regex.GetMatch(&start, &len, 0);
|
||||
assert(ok);
|
||||
ret += input.substr(start, len); // the match
|
||||
input = input.substr(start + len); // everything after the match
|
||||
}
|
||||
SCRIPT_RETURN(ret);
|
||||
}
|
||||
|
||||
wxRegEx regex; ///< Regex to match
|
||||
};
|
||||
|
||||
// Create a regular expression rule for filtering strings
|
||||
SCRIPT_FUNCTION(filter_rule) {
|
||||
intrusive_ptr<ScriptFilterRule> ret(new ScriptFilterRule);
|
||||
// match
|
||||
SCRIPT_PARAM(String, match);
|
||||
if (!ret->regex.Compile(match, wxRE_ADVANCED)) {
|
||||
throw ScriptError(_("Error while compiling regular expression: '")+match+_("'"));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Rules : sort
|
||||
|
||||
/// Sort a string using a specification using the shortest cycle metric, see spec_sort
|
||||
@@ -247,6 +316,7 @@ SCRIPT_FUNCTION(number_of_items) {
|
||||
|
||||
void init_script_functions(Context& ctx) {
|
||||
ctx.setVariable(_("replace rule"), script_replace_rule);
|
||||
ctx.setVariable(_("filter rule"), script_filter_rule);
|
||||
ctx.setVariable(_("sort rule"), script_sort_rule);
|
||||
ctx.setVariable(_("to upper"), script_to_upper);
|
||||
ctx.setVariable(_("to lower"), script_to_lower);
|
||||
|
||||
@@ -59,8 +59,9 @@ bool script_image_up_to_date(const ScriptValueP& value) {
|
||||
|
||||
// ----------------------------------------------------------------------------- : ScriptableImage
|
||||
|
||||
ScriptImageP ScriptableImage::generate(Context& ctx) const {
|
||||
ScriptImageP ScriptableImage::generate(Context& ctx, Package& pkg) const {
|
||||
try {
|
||||
WITH_DYNAMIC_ARG(load_images_from, &pkg);
|
||||
ScriptImageP img = to_script_image(script.invoke(ctx));
|
||||
return img;
|
||||
} catch (Error e) {
|
||||
@@ -71,8 +72,8 @@ ScriptImageP ScriptableImage::generate(Context& ctx) const {
|
||||
}
|
||||
}
|
||||
|
||||
ScriptImageP ScriptableImage::generate(Context& ctx, UInt width, UInt height, PreserveAspect preserve_aspect, bool saturate) const {
|
||||
ScriptImageP image = generate(ctx);
|
||||
ScriptImageP ScriptableImage::generate(Context& ctx, Package& pkg, UInt width, UInt height, PreserveAspect preserve_aspect, bool saturate) const {
|
||||
ScriptImageP image = generate(ctx, pkg);
|
||||
if (!image->image.Ok()) {
|
||||
// return an image so we don't fail
|
||||
image->image = Image(1,1);
|
||||
@@ -109,11 +110,11 @@ ScriptImageP ScriptableImage::generate(Context& ctx, UInt width, UInt height, Pr
|
||||
return image;
|
||||
}
|
||||
|
||||
ScriptImageP ScriptableImage::update(Context& ctx, UInt width, UInt height, PreserveAspect preserve_aspect, bool saturate) {
|
||||
ScriptImageP ScriptableImage::update(Context& ctx, Package& pkg, UInt width, UInt height, PreserveAspect preserve_aspect, bool saturate) {
|
||||
// up to date?
|
||||
if (!cache || (UInt)cache->image.GetWidth() != width || (UInt)cache->image.GetHeight() != height || !upToDate(ctx, last_update)) {
|
||||
// cache must be updated
|
||||
cache = generate(ctx, width, height, preserve_aspect, saturate);
|
||||
cache = generate(ctx, pkg, width, height, preserve_aspect, saturate);
|
||||
last_update.update();
|
||||
}
|
||||
return cache;
|
||||
|
||||
@@ -50,15 +50,16 @@ class ScriptableImage {
|
||||
inline operator bool() const { return script; }
|
||||
|
||||
/// Generate an image, doesn't cache, and doesn't scale
|
||||
ScriptImageP generate(Context& ctx) const;
|
||||
/** Image files are loaded from the given package */
|
||||
ScriptImageP generate(Context& ctx, Package&) 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;
|
||||
ScriptImageP generate(Context& ctx, Package&, 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);
|
||||
ScriptImageP update(Context& ctx, Package&, 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;
|
||||
|
||||
@@ -20,7 +20,7 @@ ScriptValue::operator Color() const { throw ScriptError(_("Can't convert from "
|
||||
ScriptValueP ScriptValue::eval(Context&) const
|
||||
{ throw ScriptError(_("Can't convert from ")+typeName()+_(" to function" )); }
|
||||
ScriptValueP ScriptValue::getMember(const String& name) const
|
||||
{ throw (typeName() + _(" has no member '") + name + _("'")); }
|
||||
{ throw ScriptError(typeName() + _(" has no member '") + name + _("'")); }
|
||||
ScriptValueP ScriptValue::next() { throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator")); }
|
||||
ScriptValueP ScriptValue::makeIterator() const { throw ScriptError( _("Can't convert from ")+typeName()+_(" to collection")); }
|
||||
int ScriptValue::itemCount() const { throw ScriptError( _("Can't convert from ")+typeName()+_(" to collection")); }
|
||||
|
||||
Reference in New Issue
Block a user