348 lines
12 KiB
C++
348 lines
12 KiB
C++
/****************************************************************************
|
|
* Copyright (c) 2017 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
|
|
* *
|
|
* 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 <App/Link.h>
|
|
|
|
#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<LinkInfo>;
|
|
|
|
#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<std::string> &subs = std::vector<std::string>());
|
|
|
|
void setLinkViewObject(ViewProviderDocumentObject *vpd,
|
|
const std::vector<std::string> &subs = std::vector<std::string>());
|
|
|
|
std::vector<ViewProviderDocumentObject*> 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<App::DocumentObject*> &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<std::string> 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<SoFCSelectionRoot> pcLinkRoot;
|
|
CoinPtr<SoTransform> pcTransform;
|
|
CoinPtr<SoSeparator> pcLinkedRoot;
|
|
CoinPtr<SoDrawStyle> pcDrawStyle; // for override line width and point size
|
|
CoinPtr<SoShapeHints> 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<std::string, std::unique_ptr<SubInfo> > subInfo;
|
|
|
|
class Element;
|
|
std::vector<std::unique_ptr<Element> > nodeArray;
|
|
std::unordered_map<SoNode*,int> 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<App::DocumentObject*> 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<std::string> &subElements) const override;
|
|
std::string dropObjectEx(App::DocumentObject*, App::DocumentObject*,
|
|
const char *subname, const std::vector<std::string> &subElements) override;
|
|
|
|
bool onDelete(const std::vector<std::string> &) override;
|
|
bool canDelete(App::DocumentObject* obj) const override;
|
|
|
|
std::vector<std::string> 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<std::string, App::Color> getElementColors(const char *subname=nullptr) const override;
|
|
void setElementColors(const std::map<std::string, App::Color> &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<std::string,App::Property*> &Map) const override;
|
|
void getPropertyList(std::vector<App::Property*> &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<App::DocumentObject*> 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<DraggerContext> dragCtx;
|
|
CoinPtr<SoDragger> pcDragger;
|
|
ViewProviderDocumentObject *childVp;
|
|
LinkInfoPtr childVpLink;
|
|
mutable qint64 overlayCacheKey;
|
|
};
|
|
|
|
using ViewProviderLinkPython = ViewProviderFeaturePythonT<ViewProviderLink>;
|
|
|
|
} //namespace Gui
|
|
|
|
|
|
#endif // GUI_VIEWPROVIDER_LINK_H
|