[Core] Add visibility toggling to ViewProvider
With this extension of the API, view providers can indicate whether document objects should be able to be toggled for visibility. There is both a C++ and Python interface, idiomatic for FreeCAD code.
This commit is contained in:
@@ -29,7 +29,7 @@
|
||||
|
||||
# imports the one and only
|
||||
import FreeCAD, FreeCADGui
|
||||
from enum import IntEnum
|
||||
from enum import IntEnum, Enum
|
||||
|
||||
# shortcuts
|
||||
Gui = FreeCADGui
|
||||
@@ -52,6 +52,11 @@ class SelectionStyle(IntEnum):
|
||||
NormalSelection = 0
|
||||
GreedySelection = 1
|
||||
|
||||
# The values must match with that of the Python enum class in ViewProvider.pyi
|
||||
class ToggleVisibilityMode(Enum):
|
||||
CanToggleVisibility = "CanToggleVisibility"
|
||||
NoToggleVisibility = "NoToggleVisibility"
|
||||
|
||||
Gui.Selection.SelectionStyle = SelectionStyle
|
||||
|
||||
# Important definitions
|
||||
|
||||
@@ -5534,7 +5534,9 @@ void DocumentObjectItem::testStatus(bool resetStatus, QIcon& icon1, QIcon& icon2
|
||||
QPainter pt;
|
||||
pt.begin(&px);
|
||||
pt.setPen(Qt::NoPen);
|
||||
pt.drawPixmap(0, 0, px_org.width(), px_org.height(), (currentStatus & Status::Visible) ? pxVisible : pxInvisible);
|
||||
if (object()->canToggleVisibility()) {
|
||||
pt.drawPixmap(0, 0, px_org.width(), px_org.height(), (currentStatus & Status::Visible) ? pxVisible : pxInvisible);
|
||||
}
|
||||
pt.drawPixmap(px_org.width() + spacing, 0, px_org.width(), px_org.height(), px_org);
|
||||
pt.end();
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ PROPERTY_SOURCE_ABSTRACT(Gui::ViewProvider, App::TransactionalObject)
|
||||
|
||||
ViewProvider::ViewProvider()
|
||||
: overrideMode("As Is")
|
||||
, toggleVisibilityMode(ToggleVisibilityMode::CanToggleVisibility)
|
||||
{
|
||||
setStatus(UpdateData, true);
|
||||
|
||||
|
||||
@@ -121,6 +121,11 @@ class GuiExport ViewProvider : public App::TransactionalObject
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Gui::ViewProvider);
|
||||
|
||||
public:
|
||||
enum class ToggleVisibilityMode : bool {
|
||||
CanToggleVisibility = true,
|
||||
NoToggleVisibility = false
|
||||
};
|
||||
|
||||
/// constructor.
|
||||
ViewProvider();
|
||||
|
||||
@@ -247,6 +252,22 @@ public:
|
||||
/// deliver the icon shown in the tree view
|
||||
virtual QIcon getIcon() const;
|
||||
|
||||
/**
|
||||
* @brief Whether the viewprovider should allow to toggle the visibility.
|
||||
*
|
||||
* Some document objects are not rendered and for those document objects,
|
||||
* it makes no sense to be able to toggle the visibility. Examples are
|
||||
* VarSet and Spreadsheet.
|
||||
*
|
||||
* Note that "rendered" should be seen broadly here. Objects such as
|
||||
* TechDraw pages, templates, views, and dimensions are not rendered by
|
||||
* Coin but are "rendered" on the TechDraw page and hence this function can
|
||||
* return true for those items.
|
||||
*/
|
||||
bool canToggleVisibility() const {
|
||||
return toggleVisibilityMode == ToggleVisibilityMode::CanToggleVisibility;
|
||||
}
|
||||
|
||||
/** @name Methods used by the Tree
|
||||
* If you want to take control over the
|
||||
* viewprovider specific overlay icons that will be drawn with color
|
||||
@@ -571,6 +592,8 @@ protected:
|
||||
/// Turn on mode switch
|
||||
virtual void setModeSwitch();
|
||||
|
||||
void setToggleVisibility(ToggleVisibilityMode mode) { toggleVisibilityMode = mode; }
|
||||
|
||||
protected:
|
||||
/// The root Separator of the ViewProvider
|
||||
SoSeparator *pcRoot;
|
||||
@@ -584,6 +607,10 @@ protected:
|
||||
ViewProviderPy* pyViewObject{nullptr};
|
||||
std::string overrideMode;
|
||||
std::bitset<32> StatusBits;
|
||||
/// whether visibility can toggled
|
||||
ToggleVisibilityMode toggleVisibilityMode;
|
||||
|
||||
friend class ViewProviderPy;
|
||||
|
||||
private:
|
||||
int _iActualMode{-1};
|
||||
|
||||
@@ -2,6 +2,7 @@ from Base.Metadata import constmethod
|
||||
from Base.BoundBox import BoundBox
|
||||
from App.ExtensionContainer import ExtensionContainer
|
||||
from typing import Any, Final, List, Optional
|
||||
import enum
|
||||
|
||||
|
||||
class ViewProvider(ExtensionContainer):
|
||||
@@ -12,6 +13,11 @@ class ViewProvider(ExtensionContainer):
|
||||
Licence: LGPL
|
||||
"""
|
||||
|
||||
class ToggleVisibilityMode(enum.Enum):
|
||||
CanToggleVisibility = "CanToggleVisibility"
|
||||
NoToggleVisibility = "NoToggleVisibility"
|
||||
|
||||
|
||||
def addProperty(
|
||||
self,
|
||||
type: str,
|
||||
@@ -367,3 +373,7 @@ class ViewProvider(ExtensionContainer):
|
||||
|
||||
DropPrefix: Final[str] = ""
|
||||
"""Subname referencing the sub-object for holding dropped object."""
|
||||
|
||||
ToggleVisibility: ToggleVisibilityMode = ToggleVisibilityMode.CanToggleVisibility
|
||||
"""Get/set whether the viewprovider can toggle the visibility of
|
||||
the object."""
|
||||
|
||||
@@ -706,3 +706,34 @@ Py::String ViewProviderPy::getDropPrefix() const
|
||||
{
|
||||
return {getViewProviderPtr()->getDropPrefix()};
|
||||
}
|
||||
|
||||
void ViewProviderPy::setToggleVisibility(Py::Object arg)
|
||||
{
|
||||
std::string val;
|
||||
|
||||
if (PyObject_HasAttrString(arg.ptr(), "value")) {
|
||||
// we are dealing with the enum
|
||||
val = Py::String(arg.getAttr("value"));
|
||||
}
|
||||
else {
|
||||
// we are dealing with a string
|
||||
val = Py::String(arg);
|
||||
}
|
||||
|
||||
if (val == "CanToggleVisibility") {
|
||||
getViewProviderPtr()->setToggleVisibility(ViewProvider::ToggleVisibilityMode::CanToggleVisibility);
|
||||
}
|
||||
else if (val == "NoToggleVisibility") {
|
||||
getViewProviderPtr()->setToggleVisibility(ViewProvider::ToggleVisibilityMode::NoToggleVisibility);
|
||||
}
|
||||
else {
|
||||
throw Py::ValueError("Invalid ToggleVisibility mode. Use 'CanToggleVisibility' or 'NoToggleVisibility'.");
|
||||
}
|
||||
}
|
||||
|
||||
Py::Object ViewProviderPy::getToggleVisibility() const
|
||||
{
|
||||
bool canToggleVisibility = getViewProviderPtr()->canToggleVisibility();
|
||||
|
||||
return Py::String(canToggleVisibility ? "CanToggleVisibility" : "NoToggleVisibility");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user