/**************************************************************************** * Copyright (c) 2017 Zheng Lei (realthunder) * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ****************************************************************************/ #ifndef GUI_VIEWPROVIDER_LINK_H #define GUI_VIEWPROVIDER_LINK_H #include #include "SoFCUnifiedSelection.h" #include "ViewProviderDocumentObject.h" #include "ViewProviderExtension.h" #include "ViewProviderFeaturePython.h" class SoBase; class SoDragger; class SoMaterialBinding; namespace Gui { class LinkInfo; using LinkInfoPtr = boost::intrusive_ptr; #if defined(_MSC_VER) // forward declaration to please VC 2013 void intrusive_ptr_add_ref(Gui::LinkInfo *px); void intrusive_ptr_release(Gui::LinkInfo *px); #endif class GuiExport ViewProviderLinkObserver: public ViewProviderExtension { EXTENSION_TYPESYSTEM_HEADER_WITH_OVERRIDE(); public: ViewProviderLinkObserver(); ~ViewProviderLinkObserver() override; void extensionReattach(App::DocumentObject *) override; void extensionBeforeDelete() override; void extensionOnChanged(const App::Property *) override; void extensionUpdateData(const App::Property*) override; void extensionFinishRestoring() override; bool extensionCanDragObject(App::DocumentObject*) const override { return false; } bool extensionCanDropObject(App::DocumentObject*) const override { return false; } void extensionModeSwitchChange() override; bool isLinkVisible() const; void setLinkVisible(bool); LinkInfoPtr linkInfo; }; class GuiExport LinkOwner { public: virtual void unlink(LinkInfoPtr) {} virtual void onLinkedIconChange(LinkInfoPtr) {} virtual void onLinkedUpdateData(LinkInfoPtr,const App::Property *) {} protected: virtual ~LinkOwner() = default; }; class GuiExport LinkView : public Base::BaseClass, public LinkOwner { TYPESYSTEM_HEADER_WITH_OVERRIDE(); public: LinkView(); ~LinkView() override; LinkView &operator=(const LinkView&) = delete; LinkView(const LinkView&) = delete; PyObject *getPyObject() override; void unlink(LinkInfoPtr) override; void onLinkedIconChange(LinkInfoPtr) override; void onLinkedUpdateData(LinkInfoPtr, const App::Property *) override; bool isLinked() const; SoFCSelectionRoot *getLinkRoot() const {return pcLinkRoot;} QIcon getLinkedIcon(QPixmap overlay) const; void updateLink(); void setLink(App::DocumentObject *obj, const std::vector &subs = std::vector()); void setLinkViewObject(ViewProviderDocumentObject *vpd, const std::vector &subs = std::vector()); std::vector getChildren() const; void setMaterial(int index, const App::Material *material); void setDrawStyle(int linePattern, double lineWidth=0, double pointSize=0); void setTransform(int index, const Base::Matrix4D &mat); void renderDoubleSide(bool); void setSize(int size); int getSize() const { return nodeArray.size(); } static void setTransform(SoTransform *pcTransform, const Base::Matrix4D &mat); enum SnapshotType { //three type of snapshot to override linked root node: //override transform and visibility SnapshotTransform = 0, //override visibility SnapshotVisible = 1, //override none (for child objects of a container) SnapshotChild = 2, SnapshotMax, //special type for sub object linking SnapshotContainer = -1, // sub object linking with transform override SnapshotContainerTransform = -2, }; void setNodeType(SnapshotType type, bool sublink=true); void setChildren(const std::vector &children, const boost::dynamic_bitset<> &vis, SnapshotType type=SnapshotVisible); bool linkGetDetailPath(const char *, SoFullPath *, SoDetail *&) const; bool linkGetElementPicked(const SoPickedPoint *, std::string &) const; void setElementVisible(int index, bool visible); bool isElementVisible(int index) const; ViewProviderDocumentObject *getOwner() const; void setOwner(ViewProviderDocumentObject *vpd); bool hasSubs() const; std::vector getSubNames() const; ViewProviderDocumentObject *getLinkedView() const; Base::BoundBox3d getBoundBox(ViewProviderDocumentObject *vpd=nullptr) const; void setInvalid(); protected: void replaceLinkedRoot(SoSeparator *); void resetRoot(); bool getGroupHierarchy(int index, SoFullPath *path) const; protected: LinkInfoPtr linkOwner; LinkInfoPtr linkInfo; CoinPtr pcLinkRoot; CoinPtr pcTransform; CoinPtr pcLinkedRoot; CoinPtr pcDrawStyle; // for override line width and point size CoinPtr pcShapeHints; // for override double side rendering for mirror SnapshotType nodeType; SnapshotType childType; bool autoSubLink; //auto delegate to linked sub object if there is only one sub object class SubInfo; friend class SubInfo; std::map > subInfo; class Element; std::vector > nodeArray; std::unordered_map nodeMap; Py::Object PythonObject; }; class GuiExport ViewProviderLink : public ViewProviderDocumentObject { PROPERTY_HEADER_WITH_OVERRIDE(Gui::ViewProviderLink); using inherited = ViewProviderDocumentObject; public: App::PropertyBool OverrideMaterial; App::PropertyMaterial ShapeMaterial; App::PropertyEnumeration DrawStyle; App::PropertyFloatConstraint LineWidth; App::PropertyFloatConstraint PointSize; App::PropertyMaterialList MaterialList; App::PropertyBoolList OverrideMaterialList; App::PropertyBool Selectable; App::PropertyColorList OverrideColorList; App::PropertyPersistentObject ChildViewProvider; ViewProviderLink(); ~ViewProviderLink() override; void attach(App::DocumentObject *pcObj) override; void reattach(App::DocumentObject *pcObj) override; bool isSelectable() const override; bool useNewSelectionModel() const override {return true;} void updateData(const App::Property*) override; void onChanged(const App::Property* prop) override; std::vector claimChildren() const override; bool getElementPicked(const SoPickedPoint *, std::string &) const override; bool getDetailPath(const char *, SoFullPath *, bool, SoDetail *&) const override; void finishRestoring() override; QIcon getIcon() const override; bool canDragObjects() const override; bool canDragObject(App::DocumentObject*) const override; void dragObject(App::DocumentObject*) override; bool canDropObjects() const override; bool canDragAndDropObject(App::DocumentObject*) const override; bool canDropObjectEx(App::DocumentObject *obj, App::DocumentObject *owner, const char *subname, const std::vector &subElements) const override; std::string dropObjectEx(App::DocumentObject*, App::DocumentObject*, const char *subname, const std::vector &subElements) override; bool onDelete(const std::vector &) override; bool canDelete(App::DocumentObject* obj) const override; std::vector getDisplayModes() const override; void setupContextMenu(QMenu*, QObject*, const char*) override; virtual QPixmap getOverlayPixmap() const; ViewProvider *startEditing(int ModNum) override; bool doubleClicked() override; PyObject *getPyObject() override; PyObject *getPyLinkView(); static void updateLinks(ViewProvider *vp); void updateDraggingPlacement(const Base::Placement &pla, bool force=false); Base::Placement currentDraggingPlacement() const; void enableCenterballDragger(bool enable); bool isUsingCenterballDragger() const { return useCenterballDragger; } std::map getElementColors(const char *subname=nullptr) const override; void setElementColors(const std::map &colors) override; void setOverrideMode(const std::string &mode) override; void onBeforeChange(const App::Property*) override; ViewProviderDocumentObject *getChildViewProvider() const { return childVp; } App::Property *getPropertyByName(const char* name) const override; void getPropertyMap(std::map &Map) const override; void getPropertyList(std::vector &List) const override; ViewProviderDocumentObject *getLinkedViewProvider( std::string *subname=nullptr, bool recursive=false) const override; bool allowOverride(const App::DocumentObject &) const override { return true; } void setTransformation(const Base::Matrix4D &rcMatrix) override; void setTransformation(const SbMatrix &rcMatrix) override; protected: bool setEdit(int ModNum) override; void setEditViewer(View3DInventorViewer*, int ModNum) override; void unsetEditViewer(View3DInventorViewer*) override; bool linkEdit(const App::LinkBaseExtension *ext=nullptr) const; void _setupContextMenu(App::LinkBaseExtension *ext, QMenu*, QObject*, const char*); enum LinkType { LinkTypeNone, LinkTypeNormal, LinkTypeSubs, }; bool hasElements(const App::LinkBaseExtension *ext = nullptr) const; bool isGroup(const App::LinkBaseExtension *ext=nullptr, bool plainGroup=false) const; const App::LinkBaseExtension *getLinkExtension() const; App::LinkBaseExtension *getLinkExtension(); void updateDataPrivate(App::LinkBaseExtension *ext, const App::Property*); void updateElementList(App::LinkBaseExtension *ext); bool setLinkType(App::LinkBaseExtension *ext); void onChangeIcon() const; std::vector claimChildrenPrivate() const; void applyMaterial(); void applyColors(); void checkIcon(const App::LinkBaseExtension *ext=nullptr); ViewProvider *getLinkedView(bool real,const App::LinkBaseExtension *ext=nullptr) const; bool initDraggingPlacement(); bool callDraggerProxy(const char *fname, bool update); private: static void dragStartCallback(void * data, SoDragger * d); static void dragFinishCallback(void * data, SoDragger * d); static void dragMotionCallback(void * data, SoDragger * d); protected: LinkView *linkView; LinkType linkType; bool hasSubName; bool hasSubElement; bool useCenterballDragger; struct DraggerContext{ Base::Matrix4D preTransform; Base::Placement initialPlacement; Base::Matrix4D mat; Base::BoundBox3d bbox; bool cmdPending; }; std::unique_ptr dragCtx; CoinPtr pcDragger; ViewProviderDocumentObject *childVp; LinkInfoPtr childVpLink; mutable qint64 overlayCacheKey; }; using ViewProviderLinkPython = ViewProviderFeaturePythonT; } //namespace Gui #endif // GUI_VIEWPROVIDER_LINK_H