From b93e5b2ae3f921b7237c0f623f57384554a2a811 Mon Sep 17 00:00:00 2001 From: twanvl Date: Wed, 7 Feb 2007 16:17:15 +0000 Subject: [PATCH] Reverted resource references for combine_something, you can't use tool_image here, because on MSW that only works for .bmps' Added dependency stuff to invalidate Choice images; Fixed 'duplicate' in symbol editor git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@197 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/data/action/value.cpp | 10 ++++++++++ src/data/action/value.hpp | 16 ++++++++++++++++ src/data/field.cpp | 10 +++++----- src/data/field.hpp | 3 +++ src/data/field/choice.cpp | 20 ++++++++++++++------ src/data/field/choice.hpp | 2 ++ src/data/field/text.cpp | 4 ++-- src/gui/symbol/part_list.cpp | 12 ++++++------ src/gui/symbol/select_editor.cpp | 10 +++++----- src/gui/util.hpp | 2 ++ src/gui/value/choice.cpp | 13 ++++++++----- src/gui/welcome_window.cpp | 2 ++ src/render/card/viewer.cpp | 12 ++++++++++++ src/script/image.cpp | 4 +++- src/script/image.hpp | 4 ++++ src/script/script_manager.cpp | 9 ++++++++- src/util/age.cpp | 2 +- src/util/age.hpp | 5 +++++ src/util/window_id.hpp | 2 +- 19 files changed, 109 insertions(+), 33 deletions(-) diff --git a/src/data/action/value.cpp b/src/data/action/value.cpp index 237f172b..22fefcca 100644 --- a/src/data/action/value.cpp +++ b/src/data/action/value.cpp @@ -143,6 +143,7 @@ TextValueAction* typing_action(const TextValueP& value, size_t start, size_t end } } + // ----------------------------------------------------------------------------- : Event String ScriptValueEvent::getName(bool) const { @@ -152,3 +153,12 @@ String ScriptValueEvent::getName(bool) const { void ScriptValueEvent::perform(bool) { assert(false); // this action is just an event, it should not be performed } + + +String ScriptStyleEvent::getName(bool) const { + assert(false); // this action is just an event, getName shouldn't be called + throw InternalError(_("ScriptStyleEvent::getName")); +} +void ScriptStyleEvent::perform(bool) { + assert(false); // this action is just an event, it should not be performed +} diff --git a/src/data/action/value.hpp b/src/data/action/value.hpp index 1300ce1e..5e0e9843 100644 --- a/src/data/action/value.hpp +++ b/src/data/action/value.hpp @@ -19,7 +19,9 @@ #include class Card; +class StyleSheet; DECLARE_POINTER_TYPE(Value); +DECLARE_POINTER_TYPE(Style); DECLARE_POINTER_TYPE(TextValue); DECLARE_POINTER_TYPE(ChoiceValue); DECLARE_POINTER_TYPE(ColorValue); @@ -87,5 +89,19 @@ class ScriptValueEvent : public Action { const Value* value; ///< The modified value }; +/// Notification that a script caused a style to change +class ScriptStyleEvent : public Action { + public: + inline ScriptStyleEvent(const StyleSheet* stylesheet, const Style* style) + : stylesheet(stylesheet), style(style) + {} + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + const StyleSheet* stylesheet; ///< StyleSheet the style is for + const Style* style; ///< The modified style +}; + // ----------------------------------------------------------------------------- : EOF #endif diff --git a/src/data/field.cpp b/src/data/field.cpp index db747189..6521e86d 100644 --- a/src/data/field.cpp +++ b/src/data/field.cpp @@ -111,11 +111,11 @@ bool Style::update(Context& ctx) { } void Style::initDependencies(Context& ctx, const Dependency& dep) const { - left .initDependencies(ctx,dep); - top .initDependencies(ctx,dep); - width .initDependencies(ctx,dep); - height .initDependencies(ctx,dep); - visible.initDependencies(ctx,dep); +/// left .initDependencies(ctx,dep); +// top .initDependencies(ctx,dep); +// width .initDependencies(ctx,dep); +// height .initDependencies(ctx,dep); +// visible.initDependencies(ctx,dep); } // ----------------------------------------------------------------------------- : Value diff --git a/src/data/field.hpp b/src/data/field.hpp index 35522205..5f8ce0b9 100644 --- a/src/data/field.hpp +++ b/src/data/field.hpp @@ -102,7 +102,10 @@ class Style { /// Update scripted values of this style, return true if anything has changed virtual bool update(Context&); /// Add the given dependency to the dependent_scripts list for the variables this style depends on + /** Only use for things that need invalidate() */ virtual void initDependencies(Context&, const Dependency&) const; + /// Invalidate scripted images for this style + virtual void invalidate() {} private: DECLARE_REFLECTION_VIRTUAL(); diff --git a/src/data/field/choice.cpp b/src/data/field/choice.cpp index 16ad6181..61c184ef 100644 --- a/src/data/field/choice.cpp +++ b/src/data/field/choice.cpp @@ -167,19 +167,15 @@ ChoiceStyle::ChoiceStyle(const ChoiceFieldP& field) , combine(COMBINE_NORMAL) , alignment(ALIGN_STRETCH) , thumbnails(nullptr) + , thumbnail_age(1) // thumbnails were made before the beginning of time + , invalidated_images(false) {} ChoiceStyle::~ChoiceStyle() { delete thumbnails; } -// TODO -/* -void ChoiceStyle::invalidate() { - // rebuild choice images -} -*/ bool ChoiceStyle::update(Context& ctx) { // Don't update the choice images, leave that to invalidate() return Style::update(ctx); @@ -190,6 +186,18 @@ void ChoiceStyle::initDependencies(Context& ctx, const Dependency& dep) const { ci.second.initDependencies(ctx, dep); } } +void ChoiceStyle::invalidate() { + // rebuild choice images + // TODO: Don't use this; rely on upToDate() instead + FOR_EACH(ci, choice_images) { + // TODO : only invalidate images that actually have dependencies + ci.second.invalidate(); + } + if (thumbnails) { + thumbnails->RemoveAll(); + } + invalidated_images = true; +} void ChoiceStyle::loadMask(Package& pkg) { if (mask.Ok() || mask_filename.empty()) return; diff --git a/src/data/field/choice.hpp b/src/data/field/choice.hpp index f23759be..082f6f4e 100644 --- a/src/data/field/choice.hpp +++ b/src/data/field/choice.hpp @@ -129,12 +129,14 @@ class ChoiceStyle : public Style { Image mask; ///< The actual mask image wxImageList* thumbnails; ///< Thumbnails for the choices Age thumbnail_age; ///< Age the thumbnails were generated + bool invalidated_images; ///< Have the images been invalidated? /// Load the mask image, if it's not already done void loadMask(Package& pkg); virtual bool update(Context&); virtual void initDependencies(Context&, const Dependency&) const; + virtual void invalidate(); private: DECLARE_REFLECTION(); diff --git a/src/data/field/text.cpp b/src/data/field/text.cpp index d83d0d9a..e0b9e2f8 100644 --- a/src/data/field/text.cpp +++ b/src/data/field/text.cpp @@ -62,8 +62,8 @@ bool TextStyle::update(Context& ctx) { } void TextStyle::initDependencies(Context& ctx, const Dependency& dep) const { Style ::initDependencies(ctx, dep); - font .initDependencies(ctx, dep); - symbol_font.initDependencies(ctx, dep); +// font .initDependencies(ctx, dep); +// symbol_font.initDependencies(ctx, dep); } IMPLEMENT_REFLECTION(TextStyle) { diff --git a/src/gui/symbol/part_list.cpp b/src/gui/symbol/part_list.cpp index c1e47ea2..e19e602f 100644 --- a/src/gui/symbol/part_list.cpp +++ b/src/gui/symbol/part_list.cpp @@ -20,12 +20,12 @@ SymbolPartList::SymbolPartList(Window* parent, int id, SymbolP symbol) // Create image list wxImageList* images = new wxImageList(16,16); // NOTE: this is based on the order of the SymbolPartCombine enum! - images->Add(load_resource_tool_image(_("combine_or"))); - images->Add(load_resource_tool_image(_("combine_sub"))); - images->Add(load_resource_tool_image(_("combine_and"))); - images->Add(load_resource_tool_image(_("combine_xor"))); - images->Add(load_resource_tool_image(_("combine_over"))); - images->Add(load_resource_tool_image(_("combine_border"))); + images->Add(load_resource_image(_("combine_or"))); + images->Add(load_resource_image(_("combine_sub"))); + images->Add(load_resource_image(_("combine_and"))); + images->Add(load_resource_image(_("combine_xor"))); + images->Add(load_resource_image(_("combine_over"))); + images->Add(load_resource_image(_("combine_border"))); AssignImageList(images, wxIMAGE_LIST_SMALL); // create columns InsertColumn(0, _("Name")); diff --git a/src/gui/symbol/select_editor.cpp b/src/gui/symbol/select_editor.cpp index 29449494..da37578c 100644 --- a/src/gui/symbol/select_editor.cpp +++ b/src/gui/symbol/select_editor.cpp @@ -107,12 +107,12 @@ void SymbolSelectEditor::drawRotationCenter(DC& dc, const Vector2D& pos) { void SymbolSelectEditor::initUI(wxToolBar* tb, wxMenuBar* mb) { tb->AddSeparator(); - tb->AddTool(ID_PART_MERGE, _("Merge"), load_resource_tool_image(_("combine_or")), wxNullBitmap, wxITEM_CHECK, _("Merge with shapes below"), _("Merges this shape with those below it")); - tb->AddTool(ID_PART_SUBTRACT, _("Subtract"), load_resource_tool_image(_("combine_sub_dark")), wxNullBitmap, wxITEM_CHECK, _("Subtract from shapes below"), _("Subtracts this shape from shapes below it, leaves only the area in that shape that is not in this shape")); - tb->AddTool(ID_PART_INTERSECTION, _("Intersect"), load_resource_tool_image(_("combine_and_dark")), wxNullBitmap, wxITEM_CHECK, _("Intersect with shapes below"), _("Intersects this shape with shapes below it, leaves only the area in both shapes")); + tb->AddTool(ID_PART_MERGE, _("Merge"), load_resource_image(_("combine_or")), wxNullBitmap, wxITEM_CHECK, _("Merge with shapes below"), _("Merges this shape with those below it")); + tb->AddTool(ID_PART_SUBTRACT, _("Subtract"), load_resource_image(_("combine_sub_dark")), wxNullBitmap, wxITEM_CHECK, _("Subtract from shapes below"), _("Subtracts this shape from shapes below it, leaves only the area in that shape that is not in this shape")); + tb->AddTool(ID_PART_INTERSECTION, _("Intersect"), load_resource_image(_("combine_and_dark")), wxNullBitmap, wxITEM_CHECK, _("Intersect with shapes below"), _("Intersects this shape with shapes below it, leaves only the area in both shapes")); // note: difference doesn't work (yet) - tb->AddTool(ID_PART_OVERLAP, _("Overlap"), load_resource_tool_image(_("combine_over")), wxNullBitmap, wxITEM_CHECK, _("Place above other shapes"), _("Place this shape, and its border above shapes below it")); - tb->AddTool(ID_PART_BORDER, _("Border"), load_resource_tool_image(_("combine_border")), wxNullBitmap, wxITEM_CHECK, _("Draw as a border"), _("Draws this shape as a border")); + tb->AddTool(ID_PART_OVERLAP, _("Overlap"), load_resource_image(_("combine_over")), wxNullBitmap, wxITEM_CHECK, _("Place above other shapes"), _("Place this shape, and its border above shapes below it")); + tb->AddTool(ID_PART_BORDER, _("Border"), load_resource_image(_("combine_border")), wxNullBitmap, wxITEM_CHECK, _("Draw as a border"), _("Draws this shape as a border")); tb->Realize(); } void SymbolSelectEditor::destroyUI(wxToolBar* tb, wxMenuBar* mb) { diff --git a/src/gui/util.hpp b/src/gui/util.hpp index 8174c3e2..0261c2e4 100644 --- a/src/gui/util.hpp +++ b/src/gui/util.hpp @@ -46,6 +46,8 @@ wxCursor load_resource_cursor(const String& name); wxIcon load_resource_icon(const String& name); /// Load an image for use in a toolbar (filename: tool/...) from a resource +/** Note: should ONLY be used for ".bmp" images for now + */ wxBitmap load_resource_tool_image(const String& name); // ----------------------------------------------------------------------------- : Platform look diff --git a/src/gui/value/choice.cpp b/src/gui/value/choice.cpp index d4b8c053..9711428c 100644 --- a/src/gui/value/choice.cpp +++ b/src/gui/value/choice.cpp @@ -19,7 +19,7 @@ DECLARE_TYPEOF_COLLECTION(ChoiceField::ChoiceP); class ChoiceThumbnailRequest : public ThumbnailRequest { public: - ChoiceThumbnailRequest(ChoiceValueEditor* cve, int id); + ChoiceThumbnailRequest(ChoiceValueEditor* cve, int id, bool from_disk); virtual Image generate(); virtual void store(const Image&); private: @@ -27,11 +27,13 @@ class ChoiceThumbnailRequest : public ThumbnailRequest { int id; }; -ChoiceThumbnailRequest::ChoiceThumbnailRequest(ChoiceValueEditor* cve, int id) +ChoiceThumbnailRequest::ChoiceThumbnailRequest(ChoiceValueEditor* cve, int id, bool from_disk) : ThumbnailRequest( cve, cve->viewer.stylesheet->name() + _("/") + cve->field().name + _("/") << id, - cve->viewer.stylesheet->lastModified()) + from_disk ? cve->viewer.stylesheet->lastModified() + : wxDateTime::Now() + ) , stylesheet(cve->viewer.stylesheet) , id(id) {} @@ -195,10 +197,11 @@ void DropDownChoiceList::generateThumbnailImages() { for (int i = 0 ; i < end ; ++i) { String name = cannocial_name_form(group->choiceName(i)); ScriptableImage& img = cve.style().choice_images[name]; - if (i >= image_count || !img.upToDate(ctx, cve.style().thumbnail_age)) { + bool up_to_date = img.upToDate(ctx, cve.style().thumbnail_age); + if (i >= image_count || !up_to_date) { // TODO : handle the case where image i was previously skipped // request this thumbnail - thumbnail_thread.request( new_shared2(&cve, i) ); + thumbnail_thread.request( new_shared3(&cve, i, up_to_date && !cve.style().invalidated_images) ); } } cve.style().thumbnail_age.update(); diff --git a/src/gui/welcome_window.cpp b/src/gui/welcome_window.cpp index b00c3750..fa20b520 100644 --- a/src/gui/welcome_window.cpp +++ b/src/gui/welcome_window.cpp @@ -78,6 +78,7 @@ void WelcomeWindow::draw(DC& dc) { void WelcomeWindow::onOpenSet(wxCommandEvent&) { wxFileDialog dlg(this, _TITLE_("open set"), wxEmptyString, wxEmptyString, import_formats(), wxOPEN); if (dlg.ShowModal() == wxID_OK) { + wxBusyCursor wait; close(import_set(dlg.GetPath())); } } @@ -95,6 +96,7 @@ shared_ptr open_package(const String& filename) { } void WelcomeWindow::onOpenLast(wxCommandEvent&) { + wxBusyCursor wait; assert(!settings.recent_sets.empty()); close( open_package(settings.recent_sets.front()) ); } diff --git a/src/render/card/viewer.cpp b/src/render/card/viewer.cpp index f8cc0d28..9328174f 100644 --- a/src/render/card/viewer.cpp +++ b/src/render/card/viewer.cpp @@ -146,4 +146,16 @@ void DataViewer::onAction(const Action& action, bool undone) { } } } + TYPE_CASE(action, ScriptStyleEvent) { + if (action.stylesheet == stylesheet.get()) { + FOR_EACH(v, viewers) { + if (v->getStyle().get() == action.style) { + // refresh the viewer + v->onStyleChange(); + onChange(); + return; + } + } + } + } } diff --git a/src/script/image.cpp b/src/script/image.cpp index 1e2d5b42..abec54dd 100644 --- a/src/script/image.cpp +++ b/src/script/image.cpp @@ -264,7 +264,9 @@ SCRIPT_FUNCTION(symbol_variation) { throw ScriptError(_("Variation of symbol not found ('") + variation + _("')")); } else { // SCRIPT_RETURN(last_update_age() >= value->filename.last_update_age); - SCRIPT_RETURN(true); + SCRIPT_RETURN(last_update_age() > 1); // the symbol was created/loaded after program start, + // don't use cached images +// SCRIPT_RETURN(true); } } diff --git a/src/script/image.hpp b/src/script/image.hpp index 15693c77..4ef48993 100644 --- a/src/script/image.hpp +++ b/src/script/image.hpp @@ -71,6 +71,10 @@ class ScriptableImage { inline void initDependencies(Context& ctx, const Dependency& dep) const { script.initDependencies(ctx, dep); } + /// Invalidate the cached image + inline void invalidate() { + cache = ScriptImageP(); + } private: OptionalScript script; ///< The script, not really optional diff --git a/src/script/script_manager.cpp b/src/script/script_manager.cpp index 71779b65..17c88095 100644 --- a/src/script/script_manager.cpp +++ b/src/script/script_manager.cpp @@ -279,7 +279,14 @@ void SetScriptManager::alsoUpdate(deque& to_update, const vector(d.data); + StyleP style = stylesheet->card_style.at(d.index); + style->invalidate(); + // something changed, send event + ScriptStyleEvent change(stylesheet, style.get()); + set.actions.tellListeners(change, false); break; } case DEP_CARD_COPY_DEP: { // propagate dependencies from another field diff --git a/src/util/age.cpp b/src/util/age.cpp index bf614816..abfb5b90 100644 --- a/src/util/age.cpp +++ b/src/util/age.cpp @@ -12,6 +12,6 @@ // what a waste of a source file... -AtomicInt Age::new_age(0); +AtomicInt Age::new_age(2); IMPLEMENT_DYNAMIC_ARG(AtomicIntEquiv, last_update_age, 0); diff --git a/src/util/age.hpp b/src/util/age.hpp index 1e06c1b6..2209d6cc 100644 --- a/src/util/age.hpp +++ b/src/util/age.hpp @@ -23,6 +23,11 @@ class Age { Age() { update(); } + /// Create a special age + /** 0: dummy value, used for other purposes + * 1: before 'beginning of time', the age conceptually just before program start + * 2..: normal ages + */ Age(AtomicIntEquiv age) : age(age) {} /// Update the age to become the newest one diff --git a/src/util/window_id.hpp b/src/util/window_id.hpp index 8d435c3d..d44ce451 100644 --- a/src/util/window_id.hpp +++ b/src/util/window_id.hpp @@ -48,7 +48,6 @@ enum MenuID { , ID_EDIT_COPY = wxID_COPY , ID_EDIT_PASTE = wxID_PASTE , ID_EDIT_DELETE = 101 -, ID_EDIT_DUPLICATE = 102 , ID_EDIT_FIND = wxID_FIND , ID_EDIT_FIND_NEXT = 103 , ID_EDIT_REPLACE = wxID_REPLACE @@ -117,6 +116,7 @@ enum ChildMenuID { , ID_PART_OVERLAP = ID_PART + 4//PART_OVERLAP , ID_PART_BORDER = ID_PART + 5//PART_BORDER , ID_PART_MAX +, ID_EDIT_DUPLICATE // duplicating symbol parts // SymbolPointEditor toolbar/menu , ID_SEGMENT = 2101