diff --git a/toonz/sources/include/tools/assistant.h b/toonz/sources/include/tools/assistant.h index bd1d8f1..e2edc22 100644 --- a/toonz/sources/include/tools/assistant.h +++ b/toonz/sources/include/tools/assistant.h @@ -10,6 +10,7 @@ #include <tsmartpointer.h> #include <tgeometry.h> #include <tmetaimage.h> +#include <tproperty.h> // std includes #include <vector> @@ -32,6 +33,9 @@ // Forward declarations +class TProperty; +class TPropertyGroup; + class TToolViewer; class TAssistant; class TAssistantPoint; @@ -90,12 +94,16 @@ public: class DVAPI TAssistant : public TMetaObjectHandler { protected: + const TStringId m_idEnabled; const TStringId m_idPoints; const TStringId m_idX; const TStringId m_idY; + const TStringId m_idMagnetism; TAssistantPointList m_points; + mutable TPropertyGroup m_properties; + public: TAssistant(TMetaObject &object); @@ -110,16 +118,33 @@ public: void movePoint(int index, const TPointD &position); void setPointSelection(int index, bool selected) const; + bool getEnabled() const + { return data()[m_idEnabled].getBool(); } + void setEnabled(bool x) + { if (getEnabled() != x) data()[m_idEnabled].setBool(x); } + + double getMagnetism() const + { return data()[m_idMagnetism].getDouble(); } + void setMagnetism(double x) + { if (getMagnetism() != x) data()[m_idMagnetism].setDouble(x); } + inline void selectPoint(int index) const { setPointSelection(index, true); } inline void deselectPoint(int index) const { setPointSelection(index, false); } inline void selectAll() const - { for(int i = 0; i < pointsCount(); ++i) setPointSelection(i, false); } + { for(int i = 0; i < pointsCount(); ++i) setPointSelection(i, true); } inline void deselectAll() const { for(int i = 0; i < pointsCount(); ++i) setPointSelection(i, false); } + TPropertyGroup& getProperties() const + { return m_properties; } + void propertyChanged(const TStringId &name) + { LockEvents lock(*this); onPropertyChanged(name); } + protected: + //! usually called when meta-object created + void onSetDefaults() override; //! called when part of variant data changed void onDataChanged(const TVariant &value) override; //! load object data from variant @@ -130,10 +155,18 @@ protected: virtual void onMovePoint(int index, const TPointD &position); //! save object data to variant virtual void onFixData(); + //! load all properties from variant + virtual void updateProperties(); + //! load single property from variant + virtual void updateProperty(const TStringId &name, const TVariant &value); + //! put value from property to variant + virtual void onPropertyChanged(const TStringId &name); void drawSegment(const TPointD &p0, const TPointD &p1, double pixelSize) const; void drawPoint(const TAssistantPoint &point, double pixelSize) const; + void addProperty(TProperty *p, const std::string &title); + public: virtual void getGuidelines(const TPointD &position, const TAffine &toTool, TGuidelineList &outGuidelines) const; virtual void draw(TToolViewer *viewer) const; diff --git a/toonz/sources/include/tvariant.h b/toonz/sources/include/tvariant.h index 5c12682..6da8977 100644 --- a/toonz/sources/include/tvariant.h +++ b/toonz/sources/include/tvariant.h @@ -60,7 +60,7 @@ public: { return !isIndex(); } inline int index() const { return m_index; } - inline int field() const + inline TStringId field() const { return m_field; } inline bool operator== (const TVariantPathEntry &other) const diff --git a/toonz/sources/tnztools/assistant.cpp b/toonz/sources/tnztools/assistant.cpp index 69e5ac8..e2f299c 100644 --- a/toonz/sources/tnztools/assistant.cpp +++ b/toonz/sources/tnztools/assistant.cpp @@ -2,6 +2,7 @@ #include <tools/assistant.h> #include <tgl.h> +#include <tproperty.h> #include <limits> @@ -122,10 +123,33 @@ TAssistantPoint::TAssistantPoint( TAssistant::TAssistant(TMetaObject &object): TMetaObjectHandler(object), + m_idEnabled("enabled"), m_idPoints("points"), m_idX("x"), - m_idY("y") -{ } + m_idY("y"), + m_idMagnetism("magnetism") +{ + addProperty( new TBoolProperty(m_idEnabled.str(), getEnabled()), + "Enabled" ); + addProperty( new TDoubleProperty(m_idMagnetism.str(), 0.0, 1.0, getMagnetism()), + "Magnetism" ); +} + +//--------------------------------------------------------------------------------------------------- + +void +TAssistant::addProperty(TProperty *p, const std::string &title) { + p->setQStringName( QString::fromStdString(title) ); + m_properties.add(p); +} + +//--------------------------------------------------------------------------------------------------- + +void +TAssistant::onSetDefaults() { + setEnabled(true); + setMagnetism(1.0); +} //--------------------------------------------------------------------------------------------------- @@ -171,6 +195,9 @@ TAssistant::onDataChanged(const TVariant &value) { pointData[m_idX].getDouble(), pointData[m_idY].getDouble() ); movePoint(entry.index(), position); + } else + if (data().getChildPathEntry(value, entry) && entry.isField()) { + updateProperty(entry.field(), data()[entry.field()]); } } @@ -186,6 +213,7 @@ TAssistant::onAllDataChanged() { pointData[m_idY].getDouble() ); } fixPoints(); + updateProperties(); } //--------------------------------------------------------------------------------------------------- @@ -210,6 +238,64 @@ TAssistant::onFixData() { pointData[m_idX].setDouble( m_points[i].position.x ); pointData[m_idY].setDouble( m_points[i].position.y ); } + setMagnetism( std::max(0.0, std::min(1.0, getMagnetism())) ); +} + +//--------------------------------------------------------------------------------------------------- + +void +TAssistant::updateProperties() { + const TVariantMap &map = data().getMap(); + for(TVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) + if (i->first != m_idPoints) + updateProperty(i->first, i->second); +} + +//--------------------------------------------------------------------------------------------------- + +void +TAssistant::updateProperty(const TStringId &name, const TVariant &value) { + TProperty *property = m_properties.getProperty(name); + if (!property) + return; + + if (TBoolProperty *boolProperty = dynamic_cast<TBoolProperty*>(property)) { + boolProperty->setValue( value.getBool() ); + } else + if (TDoubleProperty *doubleProperty = dynamic_cast<TDoubleProperty*>(property)) { + doubleProperty->setValue( value.getDouble() ); + } else + if (TStringProperty *stringProperty = dynamic_cast<TStringProperty*>(property)) { + stringProperty->setValue( to_wstring(value.getString()) ); + } else + if (TEnumProperty *enumProperty = dynamic_cast<TEnumProperty*>(property)) { + enumProperty->setValue( to_wstring(value.getString()) ); + } +} + +//--------------------------------------------------------------------------------------------------- + +void +TAssistant::onPropertyChanged(const TStringId &name) { + TProperty *property = m_properties.getProperty(name); + if (!property) + return; + + if (name == m_idPoints) + return; + + if (TBoolProperty *boolProperty = dynamic_cast<TBoolProperty*>(property)) { + data()[name].setBool( boolProperty->getValue() ); + } else + if (TDoubleProperty *doubleProperty = dynamic_cast<TDoubleProperty*>(property)) { + data()[name].setDouble( doubleProperty->getValue() ); + } else + if (TStringProperty *stringProperty = dynamic_cast<TStringProperty*>(property)) { + data()[name].setString( to_string(stringProperty->getValue()) ); + } else + if (TEnumProperty *enumProperty = dynamic_cast<TEnumProperty*>(property)) { + data()[name].setString( to_string(enumProperty->getValue()) ); + } } //--------------------------------------------------------------------------------------------------- diff --git a/toonz/sources/tnztools/editassistantstool.cpp b/toonz/sources/tnztools/editassistantstool.cpp index 0f17d54..baa9f06 100644 --- a/toonz/sources/tnztools/editassistantstool.cpp +++ b/toonz/sources/tnztools/editassistantstool.cpp @@ -5,6 +5,7 @@ #include <tools/toolhandle.h> #include <tools/cursors.h> #include <tools/assistant.h> +#include <tools/inputmanager.h> // TnzLib includes #include <toonz/tapplication.h> @@ -42,13 +43,13 @@ public: const TFrameId &frameId, bool isCreated, bool isRemoved, - TMetaObjectR metaObject, + TMetaObjectP metaObject, TVariant oldData ): ToolUtils::TToolUndo(level, frameId), m_isCreated(isCreated), m_isRemoved(isRemoved), - m_metaObject(metaObject.getPointer()), + m_metaObject(metaObject), m_oldData(oldData), m_newData(m_metaObject->data()), m_size(m_oldData.getMemSize() + m_newData.getMemSize()) @@ -65,18 +66,18 @@ public: { // wrap writer TMetaImage::Writer writer(*metaImage); bool found = false; - for(TMetaObjectRefList::iterator i = writer->begin(); i != writer->end(); ++i) - if (*i == m_metaObject) { + for(TMetaObjectList::iterator i = writer->begin(); i != writer->end(); ++i) + if ((*i) == m_metaObject) { if (remove) writer->erase(i); found = true; break; } if (!remove) { if (!found) - writer->push_back(TMetaObjectR(m_metaObject.getPointer())); + writer->push_back(m_metaObject); m_metaObject->data() = data; - if (TMetaObjectHandler *handler = m_metaObject->getHandler<TMetaObjectHandler>()) - handler->fixData(); + if (m_metaObject->handler()) + m_metaObject->handler()->fixData(); } } notifyImageChanged(); @@ -98,222 +99,373 @@ public: class EditAssistantsTool final : public TTool { Q_DECLARE_TR_FUNCTIONS(EditAssistantsTool) public: - typedef std::map<std::wstring, TStringId> TypeMap; + typedef std::map<TStringId, std::string> TypeMap; + + enum Mode { + ModeImage, + ModeAssistant, + ModePoint + }; protected: - TPropertyGroup m_prop; + TPropertyGroup m_allProperties; + TPropertyGroup m_toolProperties; TEnumProperty m_assistantType; - TypeMap m_localnameToType; + TypeMap m_typeToName; TStringId m_newAssisnantType; bool m_dragging; + TMetaObjectH m_currentAssistant; bool m_currentAssistantCreated; + bool m_currentAssistantChanged; int m_currentAssistantIndex; + TVariant m_currentAssistantBackup; int m_currentPointIndex; TPointD m_currentPointOffset; - TVariant m_currentAssistantBackup; TPointD m_currentPosition; TGuidelineList m_currentGuidelines; + TMetaImage::Reader *m_reader; + TMetaImage *m_readImage; + TMetaObjectPC m_readObject; + const TAssistant *m_readAssistant; + + TMetaImage::Writer *m_writer; + TMetaImage *m_writeImage; + TMetaObjectP m_writeObject; + TAssistant *m_writeAssistant; + public: EditAssistantsTool(): TTool("T_EditAssistants"), m_assistantType("AssistantType"), m_dragging(), m_currentAssistantCreated(), + m_currentAssistantChanged(), m_currentAssistantIndex(-1), - m_currentPointIndex(-1) + m_currentPointIndex(-1), + m_reader(), + m_readImage(), + m_readAssistant(), + m_writer(), + m_writeImage(), + m_writeAssistant() { bind(MetaImage); - m_prop.bind(m_assistantType); + addAssistantType("", "--"); + addAssistantType("assistantVanishingPoint", "Vanishing Point"); + m_toolProperties.bind(m_assistantType); updateTranslation(); } - + + ~EditAssistantsTool() + { close(); } + ToolType getToolType() const override { return TTool::LevelWriteTool; } int getCursorId() const override { return ToolCursor::StrokeSelectCursor; } - TPropertyGroup* getProperties(int targetType) override - { return &m_prop; } void onImageChanged() override { getViewer()->GLInvalidateAll(); } - void addAssistantType(const std::string &name, const std::string &typeName) { - const std::wstring localName = tr(name.c_str()).toStdWString(); - if (m_localnameToType.count(localName)) return; - m_localnameToType[localName] = TStringId(typeName); - m_assistantType.addValue(localName); + TPropertyGroup* getProperties(int) override { + m_allProperties.clear(); + for(int i = 0; i < m_toolProperties.getPropertyCount(); ++i) + m_allProperties.bind( *m_toolProperties.getProperty(i) ); + if (Closer closer = read(ModeAssistant)) { + TPropertyGroup &assistantProperties = m_readAssistant->getProperties(); + for(int i = 0; i < assistantProperties.getPropertyCount(); ++i) + m_allProperties.bind( *assistantProperties.getProperty(i) ); + } + updateTranslation(); + return &m_allProperties; + } + + void addAssistantType(const std::string &typeName, const std::string &name) { + if (m_typeToName.insert( TypeMap::value_type(TStringId(typeName), name) ).second) + m_assistantType.addValueWithUIName( + to_wstring(typeName), + QString::fromStdString(name) ); } void updateTranslation() override { - m_assistantType.setQStringName(tr("Assistant Type")); - m_assistantType.deleteAllValues(); - m_localnameToType.clear(); - addAssistantType("--", ""); - addAssistantType("Vanishing Point", "assistantVanishingPoint"); - m_assistantType.setIndex(0); + for(TypeMap::const_iterator i = m_typeToName.begin(); i != m_typeToName.end(); ++i) + m_assistantType.setItemUIName( + to_wstring(i->first.str()), + tr(i->second.c_str()) ); + for(int i = 0; i < m_allProperties.getPropertyCount(); ++i) { + TProperty *p = m_allProperties.getProperty(i); + //p->setQStringName( tr( p->getUINameOrig().c_str() ) ); + } } - bool onPropertyChanged(std::string propertyName) override { - TypeMap::const_iterator i = m_localnameToType.find(m_assistantType.getValue()); - m_newAssisnantType = i == m_localnameToType.end() ? TStringId() : i->second; + bool onPropertyChanged(std::string name/*, bool addToUndo*/) override { + if (TProperty *property = m_toolProperties.getProperty(name)) { + if (name == m_assistantType.getName()) + m_newAssisnantType = TStringId::find( to_string(m_assistantType.getValue()) ); + } else { + if (Closer closer = write(ModeAssistant, true)) + m_writeAssistant->propertyChanged(TStringId::find(name)); + //if (addToUndo) apply(); + getViewer()->GLInvalidateAll(); + } return true; } - void resetCurrentPoint() { +protected: + void close() { + m_readAssistant = 0; + m_readObject.reset(); + m_readImage = 0; + if (m_reader) delete(m_reader); + m_reader = 0; + + m_writeAssistant = 0; + m_writeObject.reset(); + m_writeImage = 0; + if (m_writer) delete(m_writer); + m_writer = 0; + } + + bool openRead(Mode mode) { + close(); + + if ( (mode >= ModeAssistant && !m_currentAssistant) + || (mode >= ModeAssistant && m_currentAssistantIndex < 0) + || (mode >= ModePoint && m_currentPointIndex < 0) ) return false; + + m_readImage = dynamic_cast<TMetaImage*>(getImage(true)); + if (m_readImage) { + m_reader = new TMetaImage::Reader(*m_readImage); + if (mode == ModeImage) return true; + + if ( m_currentAssistantIndex < (int)(*m_reader)->size() + && (**m_reader)[m_currentAssistantIndex] == m_currentAssistant ) + { + m_readObject = (**m_reader)[m_currentAssistantIndex]; + m_readAssistant = m_readObject->getHandler<TAssistant>(); + if (mode == ModeAssistant) return true; + + if (m_currentPointIndex < m_readAssistant->pointsCount()) { + if (mode == ModePoint) return true; + } + } + } + + close(); + return false; + } + + void touch() { + if (m_writeAssistant && !m_currentAssistantChanged) { + m_currentAssistantBackup = m_writeAssistant->data(); + m_currentAssistantChanged = true; + } + } + + bool openWrite(Mode mode, bool touch = false) { + close(); + + if ( (mode >= ModeAssistant && !m_currentAssistant) + || (mode >= ModeAssistant && m_currentAssistantIndex < 0) + || (mode >= ModePoint && m_currentPointIndex < 0) ) return false; + + m_writeImage = dynamic_cast<TMetaImage*>(getImage(true)); + if (m_writeImage) { + m_writer = new TMetaImage::Writer(*m_writeImage); + if (mode == ModeImage) return true; + + if ( m_currentAssistantIndex < (int)(*m_writer)->size() + && (**m_writer)[m_currentAssistantIndex] == m_currentAssistant ) + { + m_writeObject = (**m_writer)[m_currentAssistantIndex]; + m_writeAssistant = m_writeObject->getHandler<TAssistant>(); + if ( (mode == ModeAssistant) + || (mode == ModePoint && m_currentPointIndex < m_writeAssistant->pointsCount()) ) + { + if (touch) this->touch(); + return true; + } + } + } + + close(); + return false; + } + + + //! helper functions for construction like this: + //! if (Closer closer = read(ModeAssistant)) { do-something... } + struct Closer { + struct Args { + EditAssistantsTool *owner; + Args(EditAssistantsTool &owner): owner(&owner) { } + operator bool() const //!< declare bool-convertor here to prevent convertion path: Args->Closer->bool + { return owner && (owner->m_reader || owner->m_writer); } + void close() + { if (owner) owner->close(); } + }; + Closer(const Args &args): args(args) { } + ~Closer() { args.close(); } + operator bool() const { return args; } + private: + Args args; + }; + + Closer::Args read(Mode mode) + { openRead(mode); return Closer::Args(*this); } + Closer::Args write(Mode mode, bool touch = false) + { openWrite(mode, touch); return Closer::Args(*this); } + +public: + void updateOptionsBox() + { /* getApplication()->getCurrentTool()->notifyToolOptionsBoxChanged(); */ } + + void resetCurrentPoint(bool updateOptionsBox = true) { + close(); + m_currentAssistant.reset(); m_currentAssistantCreated = false; + m_currentAssistantChanged = false; m_currentAssistantIndex = -1; m_currentPointIndex = -1; m_currentPointOffset = TPointD(); m_currentAssistantBackup.reset(); + if (updateOptionsBox) this->updateOptionsBox(); } - const TAssistant* findCurrentPoint(const TPointD &position) { - resetCurrentPoint(); - TMetaImage *mi = dynamic_cast<TMetaImage*>(getImage(false)); - if (!mi) return NULL; - - double pixelSize2 = tglGetPixelSize2(); - TMetaImage::Reader reader(*mi); - const TAssistant *currentAssisntant = NULL; - for(TMetaObjectRefList::const_iterator i = reader->begin(); i != reader->end(); ++i) { - if (!*i) continue; - const TAssistant *assistant = (*i)->getHandler<TAssistant>(); - if (!assistant) continue; - assistant->deselectAll(); - for(int j = 0; j < assistant->pointsCount() && m_currentAssistantIndex < 0; ++j) { - const TAssistantPoint &p = assistant->points()[j]; - TPointD offset = p.position - position; - if (norm2(offset) <= p.radius*p.radius*pixelSize2) { - m_currentAssistantIndex = i - reader->begin(); - m_currentPointIndex = j; - m_currentPointOffset = offset; - currentAssisntant = assistant; - assistant->selectPoint(j); - break; + bool findCurrentPoint(const TPointD &position, double pixelSize = 1, bool updateOptionsBox = true) { + resetCurrentPoint(false); + if (Closer closer = read(ModeImage)) { + for(TMetaObjectListCW::iterator i = (*m_reader)->begin(); i != (*m_reader)->end(); ++i) { + if (!*i) continue; + + const TAssistant *assistant = (*i)->getHandler<TAssistant>(); + if (!assistant) continue; + + assistant->deselectAll(); + for(int j = 0; j < assistant->pointsCount() && m_currentAssistantIndex < 0; ++j) { + const TAssistantPoint &p = assistant->points()[j]; + TPointD offset = p.position - position; + if (norm(offset) <= p.radius*pixelSize) { + m_currentAssistant.set(*i); + m_currentAssistantIndex = i - (*m_reader)->begin(); + m_currentPointIndex = j; + m_currentPointOffset = offset; + assistant->selectAll(); + } } } } - return currentAssisntant; + + if (updateOptionsBox) this->updateOptionsBox(); + return m_currentAssistantIndex >= 0; } - void mouseMove(const TPointD &position, const TMouseEvent&) override { - if (m_dragging) return; - findCurrentPoint(position); - m_currentPosition = position; - getViewer()->GLInvalidateAll(); + bool apply() { + bool success = false; + if (m_currentAssistantChanged || m_currentAssistantCreated) { + if (Closer closer = write(ModePoint)) { + m_writeAssistant->fixData(); + TUndoManager::manager()->add(new EditAssistantsUndo( + getApplication()->getCurrentLevel()->getLevel()->getSimpleLevel(), + getCurrentFid(), + m_currentAssistantCreated, + false, + m_writeObject, + m_currentAssistantBackup )); + m_currentAssistantCreated = false; + m_currentAssistantChanged = false; + success = true; + } + } + + if (success) { + notifyImageChanged(); + getApplication()->getCurrentTool()->notifyToolChanged(); + getViewer()->GLInvalidateAll(); + } + + return success; } void leftButtonDown(const TPointD &position, const TMouseEvent&) override { + apply(); m_dragging = true; if (m_newAssisnantType) { // create assistant resetCurrentPoint(); - if (TMetaImage *mi = dynamic_cast<TMetaImage*>(getImage(true))) { - TMetaImage::Writer writer(*mi); - TMetaObjectR obj(new TMetaObject(m_newAssisnantType)); - if (TAssistant *assistant = obj->getHandler<TAssistant>()) { + if (Closer closer = write(ModeImage)) { + TMetaObjectP object(new TMetaObject(m_newAssisnantType)); + if (TAssistant *assistant = object->getHandler<TAssistant>()) { if (assistant->pointsCount()) { + assistant->setDefaults(); assistant->movePoint(0, position); m_currentAssistantCreated = true; - m_currentAssistantIndex = (int)writer->size(); + m_currentAssistantChanged = true; + m_currentAssistantIndex = (int)(*m_writer)->size(); + m_currentAssistant = object; m_currentPointIndex = 0; m_currentPointOffset = TPointD(); + m_currentAssistantBackup = assistant->data(); } - writer->push_back(obj); + (*m_writer)->push_back(object); } } m_newAssisnantType.reset(); - } else - if (const TAssistant *assistant = findCurrentPoint(position)) { - m_currentAssistantBackup = assistant->data(); + } else { + findCurrentPoint(position); } + m_currentPosition = position; getViewer()->GLInvalidateAll(); } void leftButtonDrag(const TPointD &position, const TMouseEvent&) override { - if (m_currentAssistantIndex >= 0) - if (m_currentPointIndex >= 0) - if (TMetaImage *mi = dynamic_cast<TMetaImage*>(getImage(true))) - { - TMetaImage::Writer writer(*mi); - if (m_currentAssistantIndex < (int)writer->size()) - if (TMetaObjectR obj = (*writer)[m_currentAssistantIndex]) - if (TAssistant *assistant = obj->getHandler<TAssistant>()) - if (m_currentPointIndex < assistant->pointsCount()) - { - assistant->movePoint( - m_currentPointIndex, - position + m_currentPointOffset); - } - } + if (Closer closer = write(ModePoint, true)) + m_writeAssistant->movePoint( + m_currentPointIndex, + position + m_currentPointOffset); m_currentPosition = position; getViewer()->GLInvalidateAll(); } void leftButtonUp(const TPointD &position, const TMouseEvent&) override { - if (m_currentAssistantIndex >= 0) - if (m_currentPointIndex >= 0) - if (TMetaImage *mi = dynamic_cast<TMetaImage*>(getImage(true))) - { - TMetaImage::Writer writer(*mi); - if (m_currentAssistantIndex < (int)writer->size()) - if (TMetaObjectR obj = (*writer)[m_currentAssistantIndex]) - if (TAssistant *assistant = obj->getHandler<TAssistant>()) - if (m_currentPointIndex < assistant->pointsCount()) - { - assistant->movePoint( - m_currentPointIndex, - position + m_currentPointOffset); - assistant->fixData(); - TUndoManager::manager()->add(new EditAssistantsUndo( - getApplication()->getCurrentLevel()->getLevel()->getSimpleLevel(), - getCurrentFid(), - m_currentAssistantCreated, - false, - obj, - m_currentAssistantBackup )); - m_currentAssistantCreated = false; - } - } - notifyImageChanged(); + if (Closer closer = write(ModePoint, true)) + m_writeAssistant->movePoint( + m_currentPointIndex, + position + m_currentPointOffset); + + apply(); m_assistantType.setIndex(0); getApplication()->getCurrentTool()->notifyToolChanged(); + emit getApplication()->getCurrentTool()->toolChanged(); m_currentPosition = position; getViewer()->GLInvalidateAll(); m_dragging = false; } - bool keyEvent( - bool press, - TInputState::Key key, - QKeyEvent *event, - const TInputManager &manager ) - { - if (key == TKey(Qt::Key_Delete)) { - if (!m_dragging) - if (m_currentAssistantIndex >= 0) - if (TMetaImage *mi = dynamic_cast<TMetaImage*>(getImage(true))) - { - { // wrap writer - TMetaImage::Writer writer(*mi); - if (m_currentAssistantIndex < (int)writer->size()) - if (TMetaObjectR obj = (*writer)[m_currentAssistantIndex]) - if (TAssistant *assistant = obj->getHandler<TAssistant>()) - { - writer->erase(writer->begin() + m_currentAssistantIndex); - TUndoManager::manager()->add(new EditAssistantsUndo( - getApplication()->getCurrentLevel()->getLevel()->getSimpleLevel(), - getCurrentFid(), - false, - true, - obj, - obj->data() )); - } + bool keyDown(QKeyEvent *keyEvent) override { + if (keyEvent->key() == Qt::Key_Delete) { + if (!m_dragging) { + apply(); + bool success = false; + if (Closer closer = write(ModeAssistant, true)) { + (*m_writer)->erase((*m_writer)->begin() + m_currentAssistantIndex); + TUndoManager::manager()->add(new EditAssistantsUndo( + getApplication()->getCurrentLevel()->getLevel()->getSimpleLevel(), + getCurrentFid(), + false, + true, + m_writeObject, + m_writeObject->data() )); + success = true; } + + if (success) { + notifyImageChanged(); + } + resetCurrentPoint(); - notifyImageChanged(); getApplication()->getCurrentTool()->notifyToolChanged(); getViewer()->GLInvalidateAll(); } @@ -326,10 +478,8 @@ public: m_currentGuidelines.clear(); // draw assistants - TMetaImage *mi = dynamic_cast<TMetaImage*>(getImage(false)); - if (!mi) return; - TMetaImage::Reader reader(*mi); - for(TMetaObjectRefList::const_iterator i = reader->begin(); i != reader->end(); ++i) + if (Closer closer = read(ModeImage)) + for(TMetaObjectListCW::iterator i = (*m_reader)->begin(); i != (*m_reader)->end(); ++i) if (*i) if (const TAssistant *assistant = (*i)->getHandler<TAssistant>()) {