diff --git a/src/data/action/value.cpp b/src/data/action/value.cpp index f0bec4b6..363a00d7 100644 --- a/src/data/action/value.cpp +++ b/src/data/action/value.cpp @@ -23,18 +23,23 @@ // ----------------------------------------------------------------------------- : ValueAction +ValueAction::ValueAction(const ValueP& value) + : valueP(value), card(nullptr), old_time_modified(wxDateTime::Now()) +{} +ValueAction::~ValueAction() {} // here because we need the destructor of Card + String ValueAction::getName(bool to_undo) const { return _ACTION_1_("change", valueP->fieldP->name); } void ValueAction::perform(bool to_undo) { if (card) { - swap(const_cast(card)->time_modified, old_time_modified); + swap(card->time_modified, old_time_modified); } } -void ValueAction::isOnCard(Card* card) { - this->card = card; +void ValueAction::setCard(CardP const& card) { + const_cast(this->card) = card; } // ----------------------------------------------------------------------------- : Simple @@ -253,13 +258,13 @@ void ScriptStyleEvent::perform(bool) { // ----------------------------------------------------------------------------- : Action performer -ValueActionPerformer::ValueActionPerformer(const ValueP& value, Card* card, const SetP& set) +ValueActionPerformer::ValueActionPerformer(const ValueP& value, CardP const& card, const SetP& set) : value(value), card(card), set(set) {} ValueActionPerformer::~ValueActionPerformer() {} void ValueActionPerformer::addAction(unique_ptr&& action) { - action->isOnCard(card); + action->setCard(card); set->actions.addAction(move(action)); } diff --git a/src/data/action/value.hpp b/src/data/action/value.hpp index ede4a70f..5a448d39 100644 --- a/src/data/action/value.hpp +++ b/src/data/action/value.hpp @@ -17,9 +17,9 @@ #include #include -class Card; class StyleSheet; class LocalFileName; +DECLARE_POINTER_TYPE(Card); DECLARE_POINTER_TYPE(Set); DECLARE_POINTER_TYPE(Value); DECLARE_POINTER_TYPE(Style); @@ -36,18 +36,17 @@ DECLARE_POINTER_TYPE(PackageChoiceValue); /// An Action the changes a Value class ValueAction : public Action { public: - inline ValueAction(const ValueP& value) - : valueP(value), card(nullptr), old_time_modified(wxDateTime::Now()) - {} + ValueAction(const ValueP& value); + ~ValueAction(); String getName(bool to_undo) const override; void perform(bool to_undo) override; /// We know that the value is on the given card, add that information - void isOnCard(Card* card); + void setCard(CardP const& card); const ValueP valueP; ///< The modified value - const Card* card; ///< The card the value is on, or null if it is not a card value + const CardP card; ///< The card the value is on, or null if it is not a card value private: wxDateTime old_time_modified; }; @@ -166,7 +165,7 @@ public: /** Used to reduce coupling */ class ValueActionPerformer { public: - ValueActionPerformer(const ValueP& value, Card* card, const SetP& set); + ValueActionPerformer(const ValueP& value, CardP const& card, const SetP& set); ~ValueActionPerformer(); /// Perform an action. The performer takes ownerwhip of the action. void addAction(unique_ptr&& action); @@ -174,7 +173,7 @@ public: const ValueP value; ///< The value Package& getLocalPackage(); private: - Card* card; ///< Card the value is on (if any) - SetP set; ///< Set for the actions + CardP card; ///< Card the value is on (if any) + SetP set; ///< Set for the actions }; diff --git a/src/data/format/image.cpp b/src/data/format/image.cpp index 57f4edc4..3b36ad78 100644 --- a/src/data/format/image.cpp +++ b/src/data/format/image.cpp @@ -32,13 +32,15 @@ public: Rotation getRotation() const override; private: bool use_zoom_settings; + double zoom = 1.0; + double angle = 0.0; }; Rotation UnzoomedDataViewer::getRotation() const { if (use_zoom_settings) { return DataViewer::getRotation(); } else { if (!stylesheet) stylesheet = set->stylesheet; - return Rotation(0, stylesheet->getCardRect(), 1.0, 1.0, ROTATION_ATTACH_TOP_LEFT); + return Rotation(angle, stylesheet->getCardRect(), zoom, 1.0, ROTATION_ATTACH_TOP_LEFT); } } diff --git a/src/gui/drop_down_list.cpp b/src/gui/drop_down_list.cpp index 883fa62d..e48f9a05 100644 --- a/src/gui/drop_down_list.cpp +++ b/src/gui/drop_down_list.cpp @@ -115,10 +115,10 @@ void DropDownList::show(bool in_place, wxPoint pos, RealRect* rect) { int parent_height = 0; if (!in_place && viewer) { // Position the drop down list below the editor control (based on the style) - Rotation rot = viewer->viewer.getRotation(); + Rotation rot = viewer->parent.getRotation(); Rotater rr(rot, viewer->getRotation()); RealRect r = rot.trRectToBB(rect ? *rect : rot.getInternalRect()); - if (viewer->viewer.nativeLook()) { + if (viewer->nativeLook()) { pos = RealPoint(r.x - 3, r.y - 3); size.width = max(size.width, r.width + 6); parent_height = (int)r.height + 6; @@ -282,8 +282,8 @@ int DropDownList::itemPosition(size_t item) const { void DropDownList::redrawArrowOnParent() { if (viewer) { ValueEditor* e = viewer->getEditor(); - if (e && viewer->viewer.nativeLook()) { - CardEditor& editor = static_cast(viewer->viewer); + if (e && viewer->parent.nativeLook()) { + CardEditor& editor = static_cast(viewer->parent); shared_ptr dcP = editor.overdrawDC(); RotatedDC& dc = *dcP; Rotater r(dc, viewer->getRotation()); diff --git a/src/gui/value/choice.cpp b/src/gui/value/choice.cpp index f709b395..db1be54d 100644 --- a/src/gui/value/choice.cpp +++ b/src/gui/value/choice.cpp @@ -78,7 +78,7 @@ DropDownChoiceListBase::DropDownChoiceListBase void DropDownChoiceListBase::onShow() { // update 'enabled' - Context& ctx = cve.viewer.getContext(); + Context& ctx = cve.getContext(); FOR_EACH(c, group->choices) { c->enabled.update(ctx); } @@ -145,7 +145,7 @@ void DropDownChoiceListBase::drawIcon(DC& dc, int x, int y, size_t item, bool se void DropDownChoiceListBase::generateThumbnailImages() { if (!isRoot()) return; // init choice images - Context& ctx = cve.viewer.getContext(); + Context& ctx = cve.getContext(); if (style().choice_images.empty() && style().image.isScripted()) { int n = field().choices->lastId(); for (int i = 0 ; i < n; ++i) { @@ -230,7 +230,7 @@ size_t DropDownChoiceList::selection() const { } else { // run default script to find out what the default choice would be try { - String default_choice = field().default_script.invoke( cve.viewer.getContext() )->toString(); + String default_choice = field().default_script.invoke(cve.getContext())->toString(); default_id = group->choiceId(default_choice); } catch (ScriptError const& e) { handle_error(ScriptError(e.what() + _("\n in default script for '") + field().name + _("'"))); diff --git a/src/gui/value/color.cpp b/src/gui/value/color.cpp index 5835deab..e6468871 100644 --- a/src/gui/value/color.cpp +++ b/src/gui/value/color.cpp @@ -108,7 +108,7 @@ size_t DropDownColorList::selection() const { } else if (hasDefault()) { // evaluate script to find default color try { - default_color = field().default_script.invoke(cve.viewer.getContext())->toColor(); + default_color = field().default_script.invoke(cve.getContext())->toColor(); } catch (ScriptError const& e) { handle_error(ScriptError(e.what() + _("\n in default script for '") + field().name + _("'"))); } diff --git a/src/gui/value/editor.cpp b/src/gui/value/editor.cpp index 92f8212b..2c895671 100644 --- a/src/gui/value/editor.cpp +++ b/src/gui/value/editor.cpp @@ -14,7 +14,7 @@ void ValueEditor::addAction(unique_ptr a) { if (a) { - a->isOnCard(editor().getCard().get()); + a->setCard(editor().getCard()); editor().addAction(move(a)); } } diff --git a/src/gui/value/editor.hpp b/src/gui/value/editor.hpp index 0b57bc1e..0f0dddd0 100644 --- a/src/gui/value/editor.hpp +++ b/src/gui/value/editor.hpp @@ -142,7 +142,7 @@ protected: private: \ /** Retrieve the parent editor object */ \ inline DataEditor& editor() const override { \ - return static_cast(viewer); \ + return static_cast(parent); \ } \ public: diff --git a/src/gui/value/image.cpp b/src/gui/value/image.cpp index bd010782..c529c244 100644 --- a/src/gui/value/image.cpp +++ b/src/gui/value/image.cpp @@ -37,7 +37,7 @@ bool ImageValueEditor::onLeftDClick(const RealPoint&, wxMouseEvent&) { void ImageValueEditor::sliceImage(const Image& image) { if (!image.Ok()) return; // mask - GeneratedImage::Options options((int)style().width, (int)style().height, &viewer.getStylePackage(), &viewer.getLocalPackage()); + GeneratedImage::Options options((int)style().width, (int)style().height, &parent.getStylePackage(), &parent.getLocalPackage()); AlphaMask mask; style().mask.getNoCache(options,mask); // slice diff --git a/src/gui/value/symbol.cpp b/src/gui/value/symbol.cpp index a84d8637..8280347d 100644 --- a/src/gui/value/symbol.cpp +++ b/src/gui/value/symbol.cpp @@ -65,7 +65,7 @@ bool SymbolValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent&) { int button = findButton(pos); if (button != button_down) { button_down = button; - viewer.redraw(*this); + parent.redraw(*this); } return true; } @@ -74,7 +74,7 @@ bool SymbolValueEditor::onMotion(const RealPoint& pos, wxMouseEvent& ev) { int button = findButton(pos); if (button != button_down) { button_down = button; - viewer.redraw(*this); + parent.redraw(*this); } } return true; @@ -85,13 +85,13 @@ bool SymbolValueEditor::onLeftUp(const RealPoint& pos, wxMouseEvent&) { if (button_down == 0) { // edit button_down = -2; - viewer.redraw(*this); + parent.redraw(*this); editSymbol(); return true; } else if (button_down == 1) { // gallery button_down = -2; - viewer.redraw(*this); + parent.redraw(*this); // TODO return true; } else { @@ -117,5 +117,5 @@ void SymbolValueEditor::editSymbol() { } ValueActionPerformer* SymbolValueEditor::getActionPerformer() { - return new ValueActionPerformer(valueP(), editor().getCard().get(), editor().getSetForActions()); + return new ValueActionPerformer(valueP(), editor().getCard(), editor().getSetForActions()); } diff --git a/src/gui/value/text.cpp b/src/gui/value/text.cpp index 12f09b77..72a92c5a 100644 --- a/src/gui/value/text.cpp +++ b/src/gui/value/text.cpp @@ -181,7 +181,7 @@ void DropDownWordList::setWords(const WordListWordP& words2) { void DropDownWordList::addWordsFromScript(const WordListWordP& w) { assert(w->script); // run script - Context& ctx = tve.viewer.getContext(); + Context& ctx = tve.getContext(); String str = w->script.invoke(ctx)->toString(); // collect items vector strings; @@ -317,7 +317,7 @@ IMPLEMENT_VALUE_EDITOR(Text) , scrollbar(nullptr), scroll_with_cursor(false) , hovered_words(nullptr) { - if (viewer.nativeLook() && field().multi_line) { + if (nativeLook() && field().multi_line) { scrollbar = new TextValueEditorScrollBar(*this); style->padding_right = max(style->padding_right(), (double)scrollbar->GetSize().x); } @@ -616,7 +616,7 @@ bool TextValueEditor::onCommand(int id) { wxMenu* TextValueEditor::getMenu(int type) const { if (type == ID_INSERT_SYMBOL && (style().always_symbol || style().allow_formating) && style().symbol_font.valid()) { - return style().symbol_font.font->insertSymbolMenu(viewer.getContext()); + return style().symbol_font.font->insertSymbolMenu(getContext()); } else { return nullptr; } @@ -709,7 +709,7 @@ wxCursor TextValueEditor::cursor(const RealPoint& pos) const { hovered_words = p.get(); const_cast(this)->redrawWordListIndicators(); } - Radians angle = viewer.getRotation().getAngle() + deg_to_rad(style().angle); + Radians angle = parent.getRotation().getAngle() + deg_to_rad(style().angle); if (is_sideways(angle)) { // 90 or 270 degrees if (!rotated_ibeam.Ok()) { rotated_ibeam = wxCursor(load_resource_cursor(_("rot_text"))); @@ -866,7 +866,7 @@ void TextValueEditor::showCaret() { return; } // Rotation - Rotation rot(viewer.getRotation()); + Rotation rot(parent.getRotation()); Rotater rot2(rot, getRotation()); // The caret wxCaret* caret = editor().GetCaret(); @@ -877,7 +877,7 @@ void TextValueEditor::showCaret() { // it is not 0 for empty text, because TextRenderer handles that case if (cursor.height == 0) { if (style().always_symbol && style().symbol_font.valid()) { - style().symbol_font.font->update(viewer.getContext()); + style().symbol_font.font->update(getContext()); RealSize s = style().symbol_font.font->defaultSymbolSize(rot.trS(style().symbol_font.size)); cursor.height = s.height; } else { @@ -1033,7 +1033,7 @@ void TextValueEditor::replaceSelection(const String& replacement, const String& void TextValueEditor::tryAutoReplace() { size_t end = selection_start_i; - GameSettings& gs = settings.gameSettingsFor(viewer.getGame()); + GameSettings& gs = settings.gameSettingsFor(parent.getGame()); if (!gs.use_auto_replace) return; FOR_EACH(ar, gs.auto_replaces) { if (ar->enabled && ar->match.size() <= end) { @@ -1217,7 +1217,7 @@ bool TextValueEditor::matchSubstr(const String& s, size_t pos, FindInfo& find) { fixSelection(TYPE_INDEX); was_selection = old_sel_start == selection_start && old_sel_end == selection_end; } - if (find.handle(viewer.getCard(), valueP(), pos, was_selection)) { + if (find.handle(parent.getCard(), valueP(), pos, was_selection)) { return true; } else { // TODO: string might have changed when doing replace all @@ -1253,7 +1253,7 @@ void TextValueEditor::determineSize(bool force_fit) { style().angle = 0; // force no rotation in nativeLook if (scrollbar) { // muliline, determine scrollbar size - Rotation rot = viewer.getRotation(); + Rotation rot = parent.getRotation(); Rotater r(rot, getRotation()); if (!force_fit) style().height = 100; int sbw = wxSystemSettings::GetMetric(wxSYS_VSCROLL_X); @@ -1329,7 +1329,7 @@ void TextValueEditor::prepareDrawScrollbar(RotatedDC& dc) { style().width.mutate() -= scrollbar_width; // prepare text, and remember scroll position double scroll_pos = v.getExactScrollPosition(); - v.prepare(dc, value().value(), style(), viewer.getContext()); + v.prepare(dc, value().value(), style(), getContext()); v.setExactScrollPosition(scroll_pos); // scroll to the same place, but always show the caret ensureCaretVisible(); @@ -1358,7 +1358,7 @@ void TextValueEditor::findWordLists() { String name = str.substr(pos + 11, type_end - pos - 11); WordListP word_list; // find word list type - FOR_EACH(wl, viewer.getGame().word_lists) { + FOR_EACH(wl, parent.getGame().word_lists) { if (wl->name == name) { word_list = wl; break; @@ -1399,7 +1399,7 @@ void TextValueEditor::redrawWordListIndicators(bool toggling_dropdown) { void TextValueEditor::drawWordListIndicators(RotatedDC& dc, bool redrawing) { if (word_lists.empty()) return; - DrawWhat what = viewer.drawWhat(this); + DrawWhat what = drawWhat(); bool current = what & DRAW_ACTIVE; // Draw lines around fields FOR_EACH(wl, word_lists) { diff --git a/src/render/card/viewer.hpp b/src/render/card/viewer.hpp index aa79f8fd..9ef2c0f9 100644 --- a/src/render/card/viewer.hpp +++ b/src/render/card/viewer.hpp @@ -97,8 +97,8 @@ protected: /// Notification that the size of the viewer may have changed virtual void onChangeSize() {} - vector viewers; ///< The viewers for the different values in the data - CardP card; ///< The card that is currently displayed, if any - mutable StyleSheetP stylesheet; ///< Stylesheet being used + vector viewers; ///< The viewers for the different values in the data + CardP card; ///< The card that is currently displayed, if any + mutable StyleSheetP stylesheet; ///< Stylesheet being used }; diff --git a/src/render/value/choice.cpp b/src/render/value/choice.cpp index e139607f..998d3229 100644 --- a/src/render/value/choice.cpp +++ b/src/render/value/choice.cpp @@ -36,7 +36,7 @@ bool prepare_choice_viewer(RotatedDC& dc, ValueViewer& viewer, ChoiceStyle& styl if (style.render_style & RENDER_IMAGE) { style.initImage(); CachedScriptableImage& img = style.image; - Context& ctx = viewer.viewer.getContext(); + Context& ctx = viewer.getContext(); ctx.setVariable(SCRIPT_VAR_input, to_script(value)); // generate to determine the size if (img.update(ctx) && img.isReady()) { @@ -67,7 +67,7 @@ void draw_choice_viewer(RotatedDC& dc, ValueViewer& viewer, ChoiceStyle& style, CachedScriptableImage& img = style.image; if (style.content_dependent) { // re run script - Context& ctx = viewer.viewer.getContext(); + Context& ctx = viewer.getContext(); ctx.setVariable(SCRIPT_VAR_input, to_script(value)); img.update(ctx); } diff --git a/src/render/value/image.cpp b/src/render/value/image.cpp index ed62ebd5..c6262b8c 100644 --- a/src/render/value/image.cpp +++ b/src/render/value/image.cpp @@ -16,7 +16,7 @@ IMPLEMENT_VALUE_VIEWER(Image); void ImageValueViewer::draw(RotatedDC& dc) { - DrawWhat what = viewer.drawWhat(this); + DrawWhat what = drawWhat(); // reset? int w = max(0,(int)dc.trX(style().width)), h = max(0,(int)dc.trY(style().height)); Radians a = dc.getAngle(); diff --git a/src/render/value/text.cpp b/src/render/value/text.cpp index a2bbe048..e084e6e9 100644 --- a/src/render/value/text.cpp +++ b/src/render/value/text.cpp @@ -16,16 +16,16 @@ IMPLEMENT_VALUE_VIEWER(Text); bool TextValueViewer::prepare(RotatedDC& dc) { getMask(dc); // ensure alpha/contour mask is loaded - return v.prepare(dc, value().value(), style(), viewer.getContext()); + return v.prepare(dc, value().value(), style(), getContext()); } void TextValueViewer::draw(RotatedDC& dc) { drawFieldBorder(dc); if (!v.prepared()) { - v.prepare(dc, value().value(), style(), viewer.getContext()); + v.prepare(dc, value().value(), style(), getContext()); dc.setStretch(getStretch()); } - DrawWhat what = viewer.drawWhat(this); + DrawWhat what = drawWhat(); v.draw(dc, style(), (DrawWhat)(what & DRAW_ACTIVE)); setFieldBorderPen(dc); v.draw(dc, style(), (DrawWhat)(what & ~DRAW_ACTIVE)); diff --git a/src/render/value/viewer.cpp b/src/render/value/viewer.cpp index 5cecedd7..5b4cd11f 100644 --- a/src/render/value/viewer.cpp +++ b/src/render/value/viewer.cpp @@ -13,11 +13,11 @@ // ----------------------------------------------------------------------------- : ValueViewer ValueViewer::ValueViewer(DataViewer& parent, const StyleP& style) - : StyleListener(style), viewer(parent) + : StyleListener(style), parent(parent) {} -Package& ValueViewer::getStylePackage() const { return viewer.getStylePackage(); } -Package& ValueViewer::getLocalPackage() const { return viewer.getLocalPackage(); } +Package& ValueViewer::getStylePackage() const { return parent.getStylePackage(); } +Package& ValueViewer::getLocalPackage() const { return parent.getLocalPackage(); } void ValueViewer::setValue(const ValueP& value) { assert(value->fieldP == styleP->fieldP); // matching field @@ -53,7 +53,7 @@ Rotation ValueViewer::getRotation() const { bool ValueViewer::setFieldBorderPen(RotatedDC& dc) { if (!getField()->editable) return false; - DrawWhat what = viewer.drawWhat(this); + DrawWhat what = drawWhat(); if (!(what & DRAW_BORDERS)) return false; if (what & DRAW_ACTIVE) { dc.SetPen(wxPen(Color(0, 128, 255), 1, wxPENSTYLE_SOLID)); @@ -91,20 +91,26 @@ const AlphaMask& ValueViewer::getMask(const Rotation& rot) const { return getMask((int)rot.trX(styleP->width), (int)rot.trY(styleP->height)); } +Context& ValueViewer::getContext() const { + return parent.getContext(); +} void ValueViewer::redraw() { - viewer.redraw(*this); + parent.redraw(*this); } bool ValueViewer::nativeLook() const { - return viewer.nativeLook(); + return parent.nativeLook(); +} +DrawWhat ValueViewer::drawWhat() const { + return parent.drawWhat(this); } bool ValueViewer::isCurrent() const { - return viewer.viewerIsCurrent(this); + return parent.viewerIsCurrent(this); } void ValueViewer::onStyleChange(int changes) { if (!(changes & CHANGE_ALREADY_PREPARED)) { - viewer.redraw(*this); + parent.redraw(*this); } } diff --git a/src/render/value/viewer.hpp b/src/render/value/viewer.hpp index aed0b14c..a464d236 100644 --- a/src/render/value/viewer.hpp +++ b/src/render/value/viewer.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include class Set; @@ -69,10 +70,11 @@ public: /// Convert this viewer to an editor, if possible virtual ValueEditor* getEditor() { return nullptr; } - - DataViewer& viewer; ///< Our parent object + +public: + DataViewer& parent; ///< Our parent object protected: - ValueP valueP; ///< The value we are currently viewing + ValueP valueP; ///< The value we are currently viewing /// Set the pen for drawing the border, returns true if a border needs to be drawn bool setFieldBorderPen(RotatedDC& dc); @@ -85,10 +87,15 @@ protected: /// Load the AlphaMask for this field, scaled but not rotated const AlphaMask& getMask(int w = 0, int h = 0) const; const AlphaMask& getMask(const Rotation& rot) const; - + public: + // Context to use for script functions + Context& getContext() const; + /// Should this viewer render using a platform native look? bool nativeLook() const; + /// What elements to draw + DrawWhat drawWhat() const; /// Is this the currently selected viewer? /** Usually only the editor allows selection of viewers */ bool isCurrent() const; diff --git a/src/script/script_manager.cpp b/src/script/script_manager.cpp index e6a88927..ec1c481c 100644 --- a/src/script/script_manager.cpp +++ b/src/script/script_manager.cpp @@ -142,7 +142,7 @@ void SetScriptManager::initDependencies(Context& ctx, StyleSheet& stylesheet) { void SetScriptManager::onAction(const Action& action, bool undone) { TYPE_CASE(action, ValueAction) { if (action.card) { - updateValue(*action.valueP, const_cast(action.card)->intrusive_from_this()); + updateValue(*action.valueP, action.card); return; } else { // is it a keyword's fake value?