[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:
Pieter Hijma
2025-04-05 13:47:00 +02:00
parent 62b0e6eb4f
commit 0d5481e448
6 changed files with 78 additions and 2 deletions

View File

@@ -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

View File

@@ -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();

View File

@@ -93,6 +93,7 @@ PROPERTY_SOURCE_ABSTRACT(Gui::ViewProvider, App::TransactionalObject)
ViewProvider::ViewProvider()
: overrideMode("As Is")
, toggleVisibilityMode(ToggleVisibilityMode::CanToggleVisibility)
{
setStatus(UpdateData, true);

View File

@@ -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};

View File

@@ -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."""

View File

@@ -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");
}