Extensions: Add changed property handling
This commit is contained in:
parent
26e1a24060
commit
cc6bc1b8d9
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "PropertyContainer.h"
|
||||
#include "PropertyPythonObject.h"
|
||||
#include "ExtensionContainer.h"
|
||||
#include "Base/Interpreter.h"
|
||||
#include <CXX/Objects.hxx>
|
||||
|
||||
|
@ -253,6 +254,9 @@ protected:
|
|||
Base::Type::instantiationMethod method=0);
|
||||
//@}
|
||||
|
||||
virtual void extensionOnChanged(const Property* p) {(void)(p);};
|
||||
|
||||
friend class App::ExtensionContainer;
|
||||
|
||||
protected:
|
||||
void initExtension(Base::Type type);
|
||||
|
|
|
@ -265,17 +265,11 @@ const char* ExtensionContainer::getPropertyDocumentation(const char* name) const
|
|||
}
|
||||
|
||||
void ExtensionContainer::onChanged(const Property* prop) {
|
||||
/*
|
||||
//we need to make sure that the proxy we use is always the proxy of the extended class. This
|
||||
//is needed as only the extended class proxy (either c++ or python) is managed and ensured to
|
||||
//be the python implementation class
|
||||
//Note: this property only exist if the created object is FeaturePythonT<>, this won't work for
|
||||
//any default document object. But this doesnt matter much as there is a proxy object set anyway
|
||||
//if a extension gets registered from python. This is only for synchronisation.
|
||||
if(strcmp(prop->getName(), "Proxy")) {
|
||||
for(auto entry : _extensions)
|
||||
entry.second->extensionGetExtensionPyObject().setValue(static_cast<const PropertyPythonObject*>(prop)->getValue());
|
||||
}*/
|
||||
|
||||
//inform all extensions about changed property. This includes all properties from the
|
||||
//extended object (this) as well as all extension properties
|
||||
for(auto entry : _extensions)
|
||||
entry.second->extensionOnChanged(prop);
|
||||
|
||||
App::PropertyContainer::onChanged(prop);
|
||||
}
|
||||
|
|
|
@ -31,43 +31,43 @@
|
|||
#include <App/Application.h>
|
||||
|
||||
#include <App/FeaturePythonPyImp.h>
|
||||
#include "AttachableObjectPy.h"
|
||||
#include "AttachableObjecty.h"
|
||||
|
||||
|
||||
using namespace Part;
|
||||
using namespace Attacher;
|
||||
|
||||
PROPERTY_SOURCE(Part::AttachableObject, Part::Feature);
|
||||
EXTENSION_PROPERTY_SOURCE(Part::AttachExtension, Part::Feature);
|
||||
|
||||
AttachableObject::AttachableObject()
|
||||
AttachExtension::AttachExtension()
|
||||
: _attacher(0)
|
||||
{
|
||||
ADD_PROPERTY_TYPE(AttacherType, ("Attacher::AttachEngine3D"), "Attachment",(App::PropertyType)(App::Prop_None),"Class name of attach engine object driving the attachment.");
|
||||
EXTENSION_ADD_PROPERTY_TYPE(AttacherType, ("Attacher::AttachEngine3D"), "Attachment",(App::PropertyType)(App::Prop_None),"Class name of attach engine object driving the attachment.");
|
||||
this->AttacherType.setStatus(App::Property::Status::Hidden, true);
|
||||
|
||||
ADD_PROPERTY_TYPE(Support, (0,0), "Attachment",(App::PropertyType)(App::Prop_None),"Support of the 2D geometry");
|
||||
EXTENSION_ADD_PROPERTY_TYPE(Support, (0,0), "Attachment",(App::PropertyType)(App::Prop_None),"Support of the 2D geometry");
|
||||
|
||||
ADD_PROPERTY_TYPE(MapMode, (mmDeactivated), "Attachment", App::Prop_None, "Mode of attachment to other object");
|
||||
EXTENSION_ADD_PROPERTY_TYPE(MapMode, (mmDeactivated), "Attachment", App::Prop_None, "Mode of attachment to other object");
|
||||
MapMode.setEnums(AttachEngine::eMapModeStrings);
|
||||
//a rough test if mode string list in Attacher.cpp is in sync with eMapMode enum.
|
||||
assert(MapMode.getEnumVector().size() == mmDummy_NumberOfModes);
|
||||
|
||||
ADD_PROPERTY_TYPE(MapReversed, (false), "Attachment", App::Prop_None, "Reverse Z direction (flip sketch upside down)");
|
||||
EXTENSION_ADD_PROPERTY_TYPE(MapReversed, (false), "Attachment", App::Prop_None, "Reverse Z direction (flip sketch upside down)");
|
||||
|
||||
ADD_PROPERTY_TYPE(MapPathParameter, (0.0), "Attachment", App::Prop_None, "Sets point of curve to map the sketch to. 0..1 = start..end");
|
||||
EXTENSION_ADD_PROPERTY_TYPE(MapPathParameter, (0.0), "Attachment", App::Prop_None, "Sets point of curve to map the sketch to. 0..1 = start..end");
|
||||
|
||||
ADD_PROPERTY_TYPE(superPlacement, (Base::Placement()), "Attachment", App::Prop_None, "Extra placement to apply in addition to attachment (in local coordinates)");
|
||||
EXTENSION_ADD_PROPERTY_TYPE(superPlacement, (Base::Placement()), "Attachment", App::Prop_None, "Extra placement to apply in addition to attachment (in local coordinates)");
|
||||
|
||||
setAttacher(new AttachEngine3D);//default attacher
|
||||
}
|
||||
|
||||
AttachableObject::~AttachableObject()
|
||||
AttachExtension::~AttachExtension()
|
||||
{
|
||||
if(_attacher)
|
||||
delete _attacher;
|
||||
}
|
||||
|
||||
void AttachableObject::setAttacher(AttachEngine* attacher)
|
||||
void AttachExtension::setAttacher(AttachEngine* attacher)
|
||||
{
|
||||
if (_attacher)
|
||||
delete _attacher;
|
||||
|
@ -84,7 +84,7 @@ void AttachableObject::setAttacher(AttachEngine* attacher)
|
|||
}
|
||||
}
|
||||
|
||||
bool AttachableObject::changeAttacherType(const char* typeName)
|
||||
bool AttachExtension::changeAttacherType(const char* typeName)
|
||||
{
|
||||
//check if we need to actually change anything
|
||||
if (_attacher){
|
||||
|
@ -112,13 +112,13 @@ bool AttachableObject::changeAttacherType(const char* typeName)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool AttachableObject::positionBySupport()
|
||||
bool AttachExtension::positionBySupport()
|
||||
{
|
||||
if (!_attacher)
|
||||
throw Base::Exception("AttachableObject: can't positionBySupport, because no AttachEngine is set.");
|
||||
throw Base::Exception("AttachExtension: can't positionBySupport, because no AttachEngine is set.");
|
||||
updateAttacherVals();
|
||||
try{
|
||||
this->Placement.setValue(_attacher->calculateAttachedPlacement(this->Placement.getValue()));
|
||||
getPlacement().setValue(_attacher->calculateAttachedPlacement(getPlacement().getValue()));
|
||||
return true;
|
||||
} catch (ExceptionCancel) {
|
||||
//disabled, don't do anything
|
||||
|
@ -126,7 +126,7 @@ bool AttachableObject::positionBySupport()
|
|||
};
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *AttachableObject::execute()
|
||||
App::DocumentObjectExecReturn *AttachExtension::exttensionExecute()
|
||||
{
|
||||
if(this->isTouched_Mapping()) {
|
||||
try{
|
||||
|
@ -137,12 +137,12 @@ App::DocumentObjectExecReturn *AttachableObject::execute()
|
|||
return new App::DocumentObjectExecReturn(e.GetMessageString());
|
||||
}
|
||||
}
|
||||
return Part::Feature::execute();
|
||||
return App::DocumentObjectExtension::extensionExecute();
|
||||
}
|
||||
|
||||
void AttachableObject::onChanged(const App::Property* prop)
|
||||
void AttachExtension::extensionOnChanged(const App::Property* prop)
|
||||
{
|
||||
if(! this->isRestoring()){
|
||||
if(! getExtendedObject()->isRestoring()){
|
||||
if ((prop == &Support
|
||||
|| prop == &MapMode
|
||||
|| prop == &MapPathParameter
|
||||
|
@ -163,7 +163,7 @@ void AttachableObject::onChanged(const App::Property* prop)
|
|||
|
||||
eMapMode mmode = eMapMode(this->MapMode.getValue());
|
||||
this->superPlacement.setReadOnly(!bAttached);
|
||||
this->Placement.setReadOnly(bAttached && mmode != mmTranslate); //for mmTranslate, orientation should remain editable even when attached.
|
||||
getPlacement().setReadOnly(bAttached && mmode != mmTranslate); //for mmTranslate, orientation should remain editable even when attached.
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -172,10 +172,10 @@ void AttachableObject::onChanged(const App::Property* prop)
|
|||
this->changeAttacherType(this->AttacherType.getValue());
|
||||
}
|
||||
|
||||
Part::Feature::onChanged(prop);
|
||||
App::DocumentObjectExtension::extensionOnChanged(prop);
|
||||
}
|
||||
|
||||
void AttachableObject::updateAttacherVals()
|
||||
void AttachExtension::updateAttacherVals()
|
||||
{
|
||||
if (!_attacher)
|
||||
return;
|
||||
|
@ -187,22 +187,31 @@ void AttachableObject::updateAttacherVals()
|
|||
this->superPlacement.getValue());
|
||||
}
|
||||
|
||||
App::PropertyPlacement& AttachExtension::getPlacement() {
|
||||
|
||||
if(!getExtendedObject()->isDerivedFrom(App::GeoFeature::getClassTypeId()))
|
||||
throw Base::Exception("AttachExtension not added to GeooFeature!");
|
||||
|
||||
return static_cast<App::GeoFeature*>(getExtendedObject())->Placement;
|
||||
}
|
||||
|
||||
|
||||
namespace App {
|
||||
/// @cond DOXERR
|
||||
PROPERTY_SOURCE_TEMPLATE(Part::AttachableObjectPython, Part::AttachableObject)
|
||||
template<> const char* Part::AttachableObjectPython::getViewProviderName(void) const {
|
||||
EXTENSION_PROPERTY_SOURCE_TEMPLATE(Part::AttachExtensionPython, Part::AttachExtension)
|
||||
template<> const char* Part::AttachExtensionPython::getViewProviderName(void) const {
|
||||
return "PartGui::ViewProviderPython";
|
||||
}
|
||||
template<> PyObject* Part::AttachableObjectPython::getPyObject(void) {
|
||||
template<> PyObject* Part::AttachExtensionPython::getPyObject(void) {
|
||||
if (PythonObject.is(Py::_None())) {
|
||||
// ref counter is set to 1
|
||||
PythonObject = Py::Object(new FeaturePythonPyT<Part::AttachableObjectPy>(this),true);
|
||||
PythonObject = Py::Object(new FeaturePythonPyT<Part::AttachExtensionPy>(this),true);
|
||||
}
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
// explicit template instantiation
|
||||
template class PartExport FeaturePythonT<Part::AttachableObject>;
|
||||
template class PartExport FeaturePythonT<Part::AttachExtension>;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <App/PropertyStandard.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
#include <App/GeoFeature.h>
|
||||
#include <App/DocumentObjectExtension.h>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Base/Placement.h>
|
||||
#include <Base/Exception.h>
|
||||
|
@ -46,20 +47,16 @@ namespace Part
|
|||
{
|
||||
|
||||
/**
|
||||
* @brief The AttachableObject class is the thing to be inherited by an object
|
||||
* @brief The AttachableObject class is the thing to extend an object with
|
||||
* that should be attachable. It includes the required properties, and
|
||||
* shortcuts for accessing the attachment math class.
|
||||
*
|
||||
* Todos to make it work:
|
||||
* - call Attacher::execute() when executing derived object. Make sure to deal
|
||||
* with its return value, otherwise it will leak memory upon fails.
|
||||
*/
|
||||
class PartExport AttachableObject : public Part::Feature
|
||||
class PartExport AttachExtension : public App::DocumentObjectExtension
|
||||
{
|
||||
PROPERTY_HEADER(Part::AttachableObject);
|
||||
EXTENSION_PROPERTY_HEADER(Part::AttachableObject);
|
||||
public:
|
||||
AttachableObject();
|
||||
virtual ~AttachableObject();
|
||||
AttachExtension();
|
||||
virtual ~AttachExtension();
|
||||
|
||||
/**
|
||||
* @brief setAttacher sets the AttachEngine object. The class takes the
|
||||
|
@ -103,9 +100,11 @@ public:
|
|||
virtual bool isTouched_Mapping()
|
||||
{return true; /*support.isTouched isn't true when linked objects are changed... why?..*/};
|
||||
|
||||
App::DocumentObjectExecReturn *execute(void);
|
||||
App::DocumentObjectExecReturn *extensionExecute(void);
|
||||
protected:
|
||||
virtual void onChanged(const App::Property* /*prop*/);
|
||||
virtual void extensionOnChanged(const App::Property* /*prop*/);
|
||||
|
||||
App::PropertyPlacement& getPlacement();
|
||||
|
||||
public:
|
||||
void updateAttacherVals();
|
||||
|
@ -115,7 +114,7 @@ private:
|
|||
};
|
||||
|
||||
|
||||
typedef App::FeaturePythonT<AttachableObject> AttachableObjectPython;
|
||||
typedef App::ExtensionPythonT<AttachExtension> AttachExtensionPython;
|
||||
|
||||
} // namespace Part
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user