diff --git a/src/data/action/symbol_part.hpp b/src/data/action/symbol_part.hpp index 3e861938..5c8e4192 100644 --- a/src/data/action/symbol_part.hpp +++ b/src/data/action/symbol_part.hpp @@ -150,7 +150,7 @@ class ControlPointAddAction : public Action { // ----------------------------------------------------------------------------- : Remove control point /// Action that removes any number of points from a symbol part -/// TODO: If less then 3 points are left removes the entire part! +/// TODO: If less then 3 points are left removes the entire part? Action* controlPointRemoveAction(const SymbolPartP& part, const set& toDelete); diff --git a/src/gui/control/graph.cpp b/src/gui/control/graph.cpp index 0efdac41..243a15fd 100644 --- a/src/gui/control/graph.cpp +++ b/src/gui/control/graph.cpp @@ -203,7 +203,7 @@ void GraphControl::setData(const GraphDataPre& data) { void GraphControl::setData(const GraphDataP& data) { if (graph) { graph->setData(data); - current_item.clear(); // TODO : preserver selection + current_item.clear(); // TODO : preserve selection Refresh(false); } } diff --git a/src/gui/symbol/control.cpp b/src/gui/symbol/control.cpp index 78b52ef1..aaccb983 100644 --- a/src/gui/symbol/control.cpp +++ b/src/gui/symbol/control.cpp @@ -201,7 +201,7 @@ void SymbolControl::onSize(wxSizeEvent& ev) { Refresh(false); } void SymbolControl::onUpdateUI(wxUpdateUIEvent& ev) { - if (!editor) return; + if (!editor) return; switch (ev.GetId()) { case ID_MODE_SELECT: case ID_MODE_ROTATE: case ID_MODE_POINTS: case ID_MODE_SHAPES: //case ID_MODE_PAINT: ev.Check(editor->modeToolId() == ev.GetId()); diff --git a/src/gui/symbol/window.cpp b/src/gui/symbol/window.cpp index 5fdca286..dd7c513d 100644 --- a/src/gui/symbol/window.cpp +++ b/src/gui/symbol/window.cpp @@ -10,8 +10,12 @@ #include #include #include +#include +#include +#include #include #include +#include #include #include @@ -29,7 +33,7 @@ SymbolPartP defaultSymbolPart(double d) { } // A default symbol, a square -SymbolP defaultSymbol() { +SymbolP default_symbol() { SymbolP symbol = new_shared(); symbol->parts.push_back(defaultSymbolPart(0)); return symbol; @@ -38,12 +42,29 @@ SymbolP defaultSymbol() { // ----------------------------------------------------------------------------- : Constructor SymbolWindow::SymbolWindow(Window* parent) { - init(parent, defaultSymbol()); + init(parent, default_symbol()); } -SymbolWindow::SymbolWindow(Window* parent, String filename) { - // TODO - init(parent, defaultSymbol()); +SymbolWindow::SymbolWindow(Window* parent, const String& filename) { + // TODO : open file + init(parent, default_symbol()); +} + +SymbolWindow::SymbolWindow(Window* parent, const SymbolValueP& value, const SetP& set) + : value(value), set(set) +{ + // attempt to load symbol + SymbolP symbol; + if (!value->filename.empty()) { + try { + // load symbol + symbol = set->readFile(value->filename); + } catch (const Error& e) { + handle_error(e); + } + } + if (!symbol) symbol = default_symbol(); + init(parent, symbol); } void SymbolWindow::init(Window* parent, SymbolP symbol) { @@ -122,12 +143,17 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) { s->Add(v, 0, wxEXPAND); s->Add(control, 1, wxEXPAND); SetSizer(s); + + // we want update ui events + wxUpdateUIEvent::SetMode(wxUPDATE_UI_PROCESS_SPECIFIED); + SetExtraStyle(wxWS_EX_PROCESS_UI_UPDATES); + em->SetExtraStyle(wxWS_EX_PROCESS_UI_UPDATES); } // ----------------------------------------------------------------------------- : Event handling void SymbolWindow::onFileNew(wxCommandEvent& ev) { - SymbolP symbol = defaultSymbol(); + SymbolP symbol = default_symbol(); parts->setSymbol(symbol); control->setSymbol(symbol); } @@ -151,12 +177,25 @@ void SymbolWindow::onFileOpen(wxCommandEvent& ev) { } void SymbolWindow::onFileSave(wxCommandEvent& ev) { + // TODO + onFileSaveAs(ev); } void SymbolWindow::onFileSaveAs(wxCommandEvent& ev) { + String name = wxFileSelector(_("Save symbol"),_(""),_(""),_(""),_("Symbol files (*.mse-symbol)|*.mse-symbol"),wxSAVE, this); + if (!name.empty()) { + Writer writer(new_shared1(name)); + writer.handle(control->getSymbol()); + } } void SymbolWindow::onFileStore(wxCommandEvent& ev) { + if (value) { + FileName new_filename = set->newFileName(value->field().name,_(".mse-symbol")); // a new unique name in the package + Writer writer(set->openOut(new_filename)); + writer.handle(control->getSymbol()); + set->actions.add(value_action(value, new_filename)); + } } void SymbolWindow::onFileExit(wxCommandEvent& ev) { @@ -191,7 +230,7 @@ void SymbolWindow::onUpdateUI(wxUpdateUIEvent& ev) { switch(ev.GetId()) { // file menu case ID_FILE_STORE: { - // ev.Enable(value); + ev.Enable(value); break; // undo/redo } case ID_EDIT_UNDO: { diff --git a/src/gui/symbol/window.hpp b/src/gui/symbol/window.hpp index 94234b96..7f274d14 100644 --- a/src/gui/symbol/window.hpp +++ b/src/gui/symbol/window.hpp @@ -9,13 +9,14 @@ // ----------------------------------------------------------------------------- : Includes -#include "../../util/prec.hpp" +#include #include #include -//#include "control.hpp" class SymbolControl; class SymbolPartList; +DECLARE_POINTER_TYPE(SymbolValue); +DECLARE_POINTER_TYPE(Set); // ----------------------------------------------------------------------------- : SymbolWindow @@ -25,9 +26,9 @@ class SymbolWindow : public Frame { /// Construct a SymbolWindow SymbolWindow(Window* parent); /// Construct a SymbolWindow showing a symbol from a file - SymbolWindow(Window* parent, String filename); -// /// Construct a SymbolWindow showing a symbol from a set -// SymbolWindow(Window* parent); + SymbolWindow(Window* parent, const String& filename); +// /// Construct a SymbolWindow showing a symbol value in a set + SymbolWindow(Window* parent, const SymbolValueP& value, const SetP& set); private: // --------------------------------------------------- : Children @@ -39,8 +40,8 @@ class SymbolWindow : public Frame { SymbolPartList* parts; ///< A list of parts in the symbol // when editing a symbol field -// SymbolValueP value -// SetP set + SymbolValueP value; + SetP set; // --------------------------------------------------- : Event handling DECLARE_EVENT_TABLE(); diff --git a/src/gui/value/choice.cpp b/src/gui/value/choice.cpp index be8a2d02..a3662608 100644 --- a/src/gui/value/choice.cpp +++ b/src/gui/value/choice.cpp @@ -112,5 +112,5 @@ void ChoiceValueEditor::determineSize() { } void ChoiceValueEditor::change(const Defaultable& c) { - getSet().actions.add(value_action(static_pointer_cast(valueP), c)); + getSet().actions.add(value_action(valueP(), c)); } diff --git a/src/gui/value/color.cpp b/src/gui/value/color.cpp index f3321c43..3883137f 100644 --- a/src/gui/value/color.cpp +++ b/src/gui/value/color.cpp @@ -148,7 +148,7 @@ void ColorValueEditor::determineSize() { } void ColorValueEditor::change(const Defaultable& c) { - getSet().actions.add(value_action(static_pointer_cast(valueP), c)); + getSet().actions.add(value_action(valueP(), c)); } void ColorValueEditor::changeCustom() { Color c = wxGetColourFromUser(0, value().value()); diff --git a/src/gui/value/symbol.cpp b/src/gui/value/symbol.cpp index 17a8285a..00aeed0e 100644 --- a/src/gui/value/symbol.cpp +++ b/src/gui/value/symbol.cpp @@ -7,7 +7,18 @@ // ----------------------------------------------------------------------------- : Includes #include +#include -// ----------------------------------------------------------------------------- : +// ----------------------------------------------------------------------------- : SymbolValueEditor IMPLEMENT_VALUE_EDITOR(Symbol) {} + +void SymbolValueEditor::onLeftDClick(const RealPoint& pos, wxMouseEvent&) { + // TODO : use SetWindow as parent? Maybe not, the symbol editor will stay open when mainwindow closes + SymbolWindow* wnd = new SymbolWindow(nullptr, valueP(), viewer.getSet()); + wnd->Show(); +} + +void SymbolValueEditor::determineSize() { + style().height = 50; +} diff --git a/src/gui/value/symbol.hpp b/src/gui/value/symbol.hpp index 304bca44..566dacde 100644 --- a/src/gui/value/symbol.hpp +++ b/src/gui/value/symbol.hpp @@ -19,6 +19,9 @@ class SymbolValueEditor : public SymbolValueViewer, public ValueEditor { public: DECLARE_VALUE_EDITOR(Symbol); + + virtual void onLeftDClick(const RealPoint& pos, wxMouseEvent&); + virtual void determineSize(); }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/gui/value/text.hpp b/src/gui/value/text.hpp index aa9f34f8..d4510acb 100644 --- a/src/gui/value/text.hpp +++ b/src/gui/value/text.hpp @@ -20,6 +20,7 @@ class TextValueEditor : public TextValueViewer, public ValueEditor { public: DECLARE_VALUE_EDITOR(Text); +// virtual void determineSize(); }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/render/card/viewer.cpp b/src/render/card/viewer.cpp index e66905e2..2965c2e0 100644 --- a/src/render/card/viewer.cpp +++ b/src/render/card/viewer.cpp @@ -95,9 +95,8 @@ void DataViewer::setStyles(IndexMap& styles) { (s->width || s->width .isScripted()) && (s->height || s->height .isScripted()))) { // no need to make a viewer for things that are always invisible - viewers.push_back(makeViewer(s)); - // REMOVEME //TODO //%%% - if (!viewers.back()) viewers.pop_back(); + ValueViewerP viewer = makeViewer(s); + if (viewer) viewers.push_back(viewer); } } // sort viewers by z-index of style diff --git a/src/render/symbol/filter.cpp b/src/render/symbol/filter.cpp index 026d80d9..5cf92c85 100644 --- a/src/render/symbol/filter.cpp +++ b/src/render/symbol/filter.cpp @@ -28,7 +28,7 @@ void filter_symbol(Image& symbol, const SymbolFilter& filter) { AColor result = filter.color((double)x / width, (double)y / height, point); // Store color data[0] = result.Red(); - data[2] = result.Green(); + data[1] = result.Green(); data[2] = result.Blue(); alpha[0] = result.alpha; // next diff --git a/src/render/symbol/viewer.cpp b/src/render/symbol/viewer.cpp index 9c78919b..ec383cd0 100644 --- a/src/render/symbol/viewer.cpp +++ b/src/render/symbol/viewer.cpp @@ -18,7 +18,8 @@ Image render_symbol(const SymbolP& symbol, double border_radius, int size) { Bitmap bmp(size, size); wxMemoryDC dc; dc.SelectObject(bmp); - clearDC_black(dc); + clearDC(dc, Color(0,128,0)); + viewer.rotation.setZoom(size); viewer.draw(dc); dc.SelectObject(wxNullBitmap); return bmp.ConvertToImage(); @@ -28,7 +29,7 @@ Image render_symbol(const SymbolP& symbol, double border_radius, int size) { SymbolViewer::SymbolViewer(const SymbolP& symbol, double border_radius) : border_radius(border_radius) - , rotation(0, RealRect(0,0,500,500)) + , rotation(0, RealRect(0,0,500,500), 500) { setSymbol(symbol); } diff --git a/src/render/value/viewer.hpp b/src/render/value/viewer.hpp index bff557fa..0e038f76 100644 --- a/src/render/value/viewer.hpp +++ b/src/render/value/viewer.hpp @@ -79,12 +79,15 @@ class ValueViewer { // ----------------------------------------------------------------------------- : Utility -#define DECLARE_VALUE_VIEWER(Type) \ - protected: \ - inline Type##Style& style() const { return static_cast< Type##Style&>(*styleP); } \ - inline const Type##Value& value() const { return static_cast(*valueP); } \ - inline const Type##Field& field() const { return style().field(); } \ - public: \ +#define DECLARE_VALUE_VIEWER(Type) \ + protected: \ + inline Type##Style& style() const { return static_cast< Type##Style&>(*ValueViewer::styleP); } \ + inline const Type##Value& value() const { return static_cast(*ValueViewer::valueP); } \ + inline const Type##Field& field() const { return style().field(); } \ + inline Type##StyleP styleP() const { return static_pointer_cast(ValueViewer::styleP); } \ + inline Type##ValueP valueP() const { return static_pointer_cast(ValueViewer::valueP); } \ + inline Type##FieldP fieldP() const { return static_pointer_cast(style().fieldP); } \ + public: \ Type##ValueViewer(DataViewer& parent, const Type ## StyleP& style) diff --git a/src/script/script_manager.cpp b/src/script/script_manager.cpp index 8a23abc0..40f65c9f 100644 --- a/src/script/script_manager.cpp +++ b/src/script/script_manager.cpp @@ -217,18 +217,21 @@ void ScriptManager::alsoUpdate(deque& to_update, const vectordata.at(ds.index); toUpdate.push_back(ToUpdate(&*value)); diff --git a/src/util/action_stack.cpp b/src/util/action_stack.cpp index c0fd2ec6..484f67d2 100644 --- a/src/util/action_stack.cpp +++ b/src/util/action_stack.cpp @@ -43,6 +43,7 @@ void ActionStack::add(Action* action, bool allow_merge) { void ActionStack::undo() { assert(canUndo()); + if (!canUndo()) return; Action* action = undo_actions.back(); action->perform(true); tellListeners(*action, true); @@ -52,6 +53,7 @@ void ActionStack::undo() { } void ActionStack::redo() { assert(canRedo()); + if (!canRedo()) return; Action* action = redo_actions.back(); action->perform(false); tellListeners(*action, false); diff --git a/src/util/io/package.cpp b/src/util/io/package.cpp index fc6c37e9..5fe7c5e7 100644 --- a/src/util/io/package.cpp +++ b/src/util/io/package.cpp @@ -203,7 +203,7 @@ String Package::nameOut(const String& file) { } } -String Package::newFileName(const String& prefix, const String& suffix) { +FileName Package::newFileName(const String& prefix, const String& suffix) { assert(wxThread::IsMain()); // Writing should only be done from the main thread String name; UInt infix = 0; diff --git a/src/util/io/package.hpp b/src/util/io/package.hpp index deff9a08..54e02b04 100644 --- a/src/util/io/package.hpp +++ b/src/util/io/package.hpp @@ -98,7 +98,7 @@ class Package { /// Creates a new, unique, filename with the specified prefix and suffix /// for example newFileName("image/",".jpg") -> "image/1.jpg" /// Returns the name of a temporary file that can be written to. - String newFileName(const String& prefix, const String& suffix); + FileName newFileName(const String& prefix, const String& suffix); /// Signal that a file is still used by this package. /// Must be called for files not opened using openOut/nameOut diff --git a/src/util/prec.hpp b/src/util/prec.hpp index 0bcd5f71..e04549ad 100644 --- a/src/util/prec.hpp +++ b/src/util/prec.hpp @@ -66,7 +66,11 @@ typedef unsigned int UInt; #define nullptr 0 /// A string standing for a filename, has different behaviour when reading/writing -class FileName : public String {}; +class FileName : public String { + public: + FileName() {} + FileName(const String& s) : String(s) {} +}; // ----------------------------------------------------------------------------- : EOF #endif