From c30dbec39ef948d3946fd7f35f414718023c8e0f Mon Sep 17 00:00:00 2001 From: twanvl Date: Thu, 23 Nov 2006 16:28:09 +0000 Subject: [PATCH] finished symbol rendering git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@90 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/render/symbol/filter.cpp | 7 ++++++ src/render/symbol/filter.hpp | 4 +++ src/render/symbol/viewer.cpp | 13 ++++++++++ src/render/symbol/viewer.hpp | 9 ++++--- src/render/value/symbol.cpp | 44 ++++++++++++++++++++++++++++++++- src/render/value/symbol.hpp | 4 +++ src/util/io/package.hpp | 24 ++++++++++++------ src/util/io/package_manager.cpp | 2 +- 8 files changed, 93 insertions(+), 14 deletions(-) diff --git a/src/render/symbol/filter.cpp b/src/render/symbol/filter.cpp index 9b54fd4e..026d80d9 100644 --- a/src/render/symbol/filter.cpp +++ b/src/render/symbol/filter.cpp @@ -7,6 +7,7 @@ // ----------------------------------------------------------------------------- : Includes #include +#include #include #include @@ -37,6 +38,12 @@ void filter_symbol(Image& symbol, const SymbolFilter& filter) { } } +Image render_symbol(const SymbolP& symbol, const SymbolFilter& filter, double border_radius, int size) { + Image i = render_symbol(symbol, border_radius, size); + filter_symbol(i, filter); + return i; +} + // ----------------------------------------------------------------------------- : SymbolFilter IMPLEMENT_REFLECTION(SymbolFilter) { diff --git a/src/render/symbol/filter.hpp b/src/render/symbol/filter.hpp index 26b47398..7c731aed 100644 --- a/src/render/symbol/filter.hpp +++ b/src/render/symbol/filter.hpp @@ -12,6 +12,7 @@ #include #include +DECLARE_POINTER_TYPE(Symbol); class SymbolFilter; // ----------------------------------------------------------------------------- : Color @@ -32,6 +33,9 @@ class AColor : public Color { */ void filter_symbol(Image& symbol, const SymbolFilter& filter); +/// Render a Symbol to an Image and filter it +Image render_symbol(const SymbolP& symbol, const SymbolFilter& filter, double border_radius = 0.05, int size = 100); + /// Is a point inside a symbol? enum SymbolSet { SYMBOL_INSIDE diff --git a/src/render/symbol/viewer.cpp b/src/render/symbol/viewer.cpp index 2e841f79..9c78919b 100644 --- a/src/render/symbol/viewer.cpp +++ b/src/render/symbol/viewer.cpp @@ -11,6 +11,19 @@ DECLARE_TYPEOF_COLLECTION(SymbolPartP); +// ----------------------------------------------------------------------------- : Simple rendering + +Image render_symbol(const SymbolP& symbol, double border_radius, int size) { + SymbolViewer viewer(symbol, border_radius); + Bitmap bmp(size, size); + wxMemoryDC dc; + dc.SelectObject(bmp); + clearDC_black(dc); + viewer.draw(dc); + dc.SelectObject(wxNullBitmap); + return bmp.ConvertToImage(); +} + // ----------------------------------------------------------------------------- : Constructor SymbolViewer::SymbolViewer(const SymbolP& symbol, double border_radius) diff --git a/src/render/symbol/viewer.hpp b/src/render/symbol/viewer.hpp index e5c796dd..d748190b 100644 --- a/src/render/symbol/viewer.hpp +++ b/src/render/symbol/viewer.hpp @@ -40,13 +40,14 @@ class SymbolViewer : public SymbolView { Rotation rotation; ///< Object that handles rotation, scaling and translation // --------------------------------------------------- : Drawing - - public: + /// Draw the symbol to a dc void draw(DC& dc); - + void highlightPart(DC& dc, const SymbolPart& part, HighlightStyle style); - + + void onAction(const Action&, bool) {} + private: /// Combines a symbol part with what is currently drawn, the border and interior are drawn separatly /** directB/directI are true if the border/interior is the screen dc, false if it diff --git a/src/render/value/symbol.cpp b/src/render/value/symbol.cpp index 16eba402..49b9a5b2 100644 --- a/src/render/value/symbol.cpp +++ b/src/render/value/symbol.cpp @@ -7,9 +7,51 @@ // ----------------------------------------------------------------------------- : Includes #include +#include +#include +#include +#include // draw_checker +#include + +DECLARE_TYPEOF_COLLECTION(SymbolStyle::VariationP); // ----------------------------------------------------------------------------- : SymbolValueViewer void SymbolValueViewer::draw(RotatedDC& dc) { - // TODO + drawFieldBorder(dc); + // draw checker background + draw_checker(dc, style().getRect()); + double wh = min(style().width, style().height); + // try to load symbol + if (symbols.empty() && !value().filename.empty()) { + try { + // load symbol + SymbolP symbol = getSet().readFile(value().filename); + // render and filter variations + FOR_EACH(variation, style().variations) { + Image img = render_symbol(symbol, *variation->filter, variation->border_radius); + Image resampled(wh, wh, false); + resample(img, resampled); + symbols.push_back(Bitmap(resampled)); + } + } catch (const Error& e) { + handle_error(e); + } + } + // draw image, if any + for (size_t i = 0 ; i < symbols.size() ; ++i) { + // todo : labels? + dc.DrawBitmap(symbols[i], style().getPos() + RealSize(i * (wh + 2), 0)); + } + // draw helper text if there are no symbols + if (symbols.empty()) { + dc.SetFont(wxFont(10,wxSWISS,wxNORMAL,wxNORMAL)); + dc.SetTextForeground(*wxBLACK); + RealSize text_size = dc.GetTextExtent(_("double click to edit symbol")); + dc.DrawText(_("double click to edit symbol"), align_in_rect(ALIGN_MIDDLE_CENTER, text_size, style().getRect())); + } +} + +void SymbolValueViewer::onValueChange() { + symbols.clear(); } diff --git a/src/render/value/symbol.hpp b/src/render/value/symbol.hpp index 3d708222..7d93a27c 100644 --- a/src/render/value/symbol.hpp +++ b/src/render/value/symbol.hpp @@ -21,6 +21,10 @@ class SymbolValueViewer : public ValueViewer { DECLARE_VALUE_VIEWER(Symbol) : ValueViewer(parent,style) {} virtual void draw(RotatedDC& dc); + void onValueChange(); + + private: + vector symbols; ///< Cached images }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/util/io/package.hpp b/src/util/io/package.hpp index b5a8570e..deff9a08 100644 --- a/src/util/io/package.hpp +++ b/src/util/io/package.hpp @@ -112,22 +112,30 @@ class Package { /// Open a file given an absolute filename static InputStreamP openAbsoluteFile(const String& name); -/* // --------------------------------------------------- : Managing the inside of the package : IO files + // --------------------------------------------------- : Managing the inside of the package : Reader/writer template - void readFile (String n, T& obj) { - In i(openFileIn(n), filename + _("/") + n); + void readFile(const String& file, T& obj) { + Reader reader(openIn(file), absoluteFilename() + _("/") + file); try { - i(obj); - } catch (ParseError e) { - throw FileParseError(e.what(), filename+_("/")+n); // more detailed message + reader.handle(obj); + } catch (const ParseError& err) { + throw FileParseError(err.what(), absoluteFilename() + _("/") + file); // more detailed message } } + template + T readFile(const String& file) { + T obj; + readFile(file, obj); + return obj; + } template - void writeFile(const String& file, T obj) { + void writeFile(const String& file, const T& obj) { + Writer writer(openOut(file)); + writer.handle(obj); } - */ + // --------------------------------------------------- : Private stuff private: diff --git a/src/util/io/package_manager.cpp b/src/util/io/package_manager.cpp index e310aac5..94830dab 100644 --- a/src/util/io/package_manager.cpp +++ b/src/util/io/package_manager.cpp @@ -98,4 +98,4 @@ InputStreamP PackageManager::openFileFromPackage(const String& name) { void PackageManager::destroy() { loaded_packages.clear(); -} \ No newline at end of file +}