Merge pull request #2094 from OpenSpace/feature/properties-visibility

Add settings in OpenSpaceEngine that sets visibility in gui
This commit is contained in:
sylvass
2022-06-29 09:07:46 -04:00
committed by GitHub
17 changed files with 109 additions and 71 deletions

View File

@@ -25,6 +25,9 @@
#ifndef __OPENSPACE_CORE___OPENSPACEENGINE___H__
#define __OPENSPACE_CORE___OPENSPACEENGINE___H__
#include <openspace/properties/optionproperty.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/property.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/scene/profile.h>
@@ -63,7 +66,7 @@ struct CommandlineArguments {
std::string configurationOverride;
};
class OpenSpaceEngine {
class OpenSpaceEngine : public properties::PropertyOwner {
public:
// A mode that specifies which part of the system is currently in control.
// The mode can be used to limit certain features, like setting time, navigation
@@ -101,6 +104,8 @@ public:
std::vector<std::byte> encode();
void decode(std::vector<std::byte> data);
properties::Property::Visibility visibility() const;
bool showHiddenSceneGraphNodes() const;
void toggleShutdownMode();
Mode currentMode() const;
@@ -136,6 +141,8 @@ private:
void resetPropertyChangeFlagsOfSubowners(openspace::properties::PropertyOwner* po);
properties::BoolProperty _printEvents;
properties::OptionProperty _visibility;
properties::BoolProperty _showHiddenSceneGraphNodes;
std::unique_ptr<Scene> _scene;
std::unique_ptr<AssetManager> _assetManager;

View File

@@ -62,13 +62,15 @@ class Property {
public:
/**
* The visibility classes for Property%s. The classes are strictly ordered as
* All > Developer > User > Hidden
* Hidden > Developer > AdvancedUser > User > NoviceUser > Always
*/
enum class Visibility {
Hidden = 3, ///< Never visible
Developer = 2, ///< Visible in Developer mode
User = 1, ///< Visible in User mode
All = 0, ///< Visible for all types, no matter what
Hidden = 5, ///< Never visible
Developer = 4, ///< Visible in Developer mode
AdvancedUser = 3, ///< Visible in Advanced User mode
User = 2, ///< Visible in User mode
NoviceUser = 1, ///< Visible in Novice User mode
Always = 0, ///< Visible for all types, no matter what
};
/**
@@ -99,7 +101,7 @@ public:
/// The user facing description of this Property
const char* description;
/// Determines the visibility of this Property in the user interface
Visibility visibility = Visibility::All;
Visibility visibility = Visibility::Always;
};
/// An OnChangeHandle is returned by the onChange method to uniquely identify an
@@ -119,7 +121,7 @@ public:
* necessary information for this Property. #PropertyInfo::identifier needs to be
* unique for each PropertyOwner. The #PropertyInfo::guiName will be stored in the
* metaData to be accessed by the GUI elements using the #PropertyInfo::guiName key.
* The default visibility settings is Visibility::All, whereas the default read-only
* The default visibility settings is Visibility::Always, whereas the default read-only
* state is \c false.
*
* \param info The PropertyInfo structure that contains all the required static

View File

@@ -168,11 +168,6 @@ DashboardItemAngle::DashboardItemAngle(const ghoul::Dictionary& dictionary)
{ Type::Focus, "Focus" },
{ Type::Camera, "Camera" }
});
_source.type.onChange([this]() {
_source.nodeName.setVisibility(
properties::Property::Visibility(_source.type == Type::Node)
);
});
if (p.sourceType.has_value()) {
_source.type = codegen::map<Type>(*p.sourceType);
}
@@ -201,11 +196,6 @@ DashboardItemAngle::DashboardItemAngle(const ghoul::Dictionary& dictionary)
{ Type::Focus, "Focus" },
{ Type::Camera, "Camera" }
});
_reference.type.onChange([this]() {
_reference.nodeName.setVisibility(
properties::Property::Visibility(_reference.type == Type::Node)
);
});
_reference.type = codegen::map<Type>(p.referenceType);
addProperty(_reference.type);
@@ -228,11 +218,6 @@ DashboardItemAngle::DashboardItemAngle(const ghoul::Dictionary& dictionary)
{ Type::Focus, "Focus" },
{ Type::Camera, "Camera" }
});
_destination.type.onChange([this]() {
_destination.nodeName.setVisibility(
properties::Property::Visibility(_source.type == Type::Node)
);
});
if (p.destinationType.has_value()) {
_destination.type = codegen::map<Type>(*p.destinationType);
}

View File

@@ -490,18 +490,6 @@ void ImGUIModule::renderFrame(float deltaTime, const glm::vec2& windowSize,
comp->setEnabled(enabled);
}
// Render and Update property visibility
// Fragile! Keep this in sync with properties::Property::Visibility
using V = properties::Property::Visibility;
int t = static_cast<std::underlying_type_t<V>>(_currentVisibility);
// Array is sorted by importance
std::array<const char*, 4> items = { "User", "Developer", "Hidden", "All" };
ImGui::Combo("PropertyVisibility", &t, items.data(), static_cast<int>(items.size()));
_currentVisibility = static_cast<V>(t);
_property.setVisibility(_currentVisibility);
#ifdef SHOW_IMGUI_HELPERS
ImGui::Checkbox("ImGUI Internals", &_showInternals);
if (_showInternals) {

View File

@@ -124,9 +124,6 @@ private:
UniformCache(tex, ortho) _uniformCache;
std::unique_ptr<ghoul::opengl::Texture> _fontTexture;
properties::Property::Visibility _currentVisibility =
properties::Property::Visibility::Developer;
std::vector<ImGuiContext*> _contexts;
std::vector<TouchInput> _validTouchStates;

View File

@@ -52,22 +52,17 @@ public:
void setPropertyOwnerFunction(
std::function<std::vector<properties::PropertyOwner*>()> func);
void setVisibility(properties::Property::Visibility visibility);
void render() override;
protected:
void renderPropertyOwner(properties::PropertyOwner* owner);
void renderProperty(properties::Property* prop, properties::PropertyOwner* owner);
properties::Property::Visibility _visibility = properties::Property::Visibility::User;
std::vector<properties::PropertyOwner*> _propertyOwners;
std::function<std::vector<properties::PropertyOwner*>()> _propertyOwnerFunction;
properties::BoolProperty _useTreeLayout;
properties::StringListProperty _treeOrdering;
properties::BoolProperty _ignoreHiddenHint;
};
} // namespace openspace::gui

View File

@@ -42,7 +42,6 @@ namespace openspace::gui {
GuiParallelComponent::GuiParallelComponent()
: GuiPropertyComponent("Parallel", "Parallel Connection")
{
setVisibility(properties::Property::Visibility::All);
}
void GuiParallelComponent::renderDisconnected() {

View File

@@ -26,6 +26,8 @@
#include <modules/imgui/include/imgui_include.h>
#include <modules/imgui/include/renderproperties.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/scene/scenegraphnode.h>
#include <ghoul/misc/misc.h>
#include <algorithm>
@@ -59,15 +61,17 @@ namespace {
"the hidden hints are followed."
};
int nVisibleProperties(const std::vector<openspace::properties::Property*>& props,
openspace::properties::Property::Visibility visibility)
int nVisibleProperties(const std::vector<openspace::properties::Property*>& props)
{
using Visibility = openspace::properties::Property::Visibility;
Visibility visibilityFilter = openspace::global::openSpaceEngine->visibility();
return static_cast<int>(std::count_if(
props.begin(),
props.end(),
[visibility](openspace::properties::Property* p) {
[visibilityFilter](openspace::properties::Property* p) {
using V = openspace::properties::Property::Visibility;
return static_cast<std::underlying_type_t<V>>(visibility) >=
return static_cast<std::underlying_type_t<V>>(visibilityFilter) >=
static_cast<std::underlying_type_t<V>>(p->visibility());
}
));
@@ -187,11 +191,9 @@ GuiPropertyComponent::GuiPropertyComponent(std::string identifier, std::string g
: GuiComponent(std::move(identifier), std::move(guiName))
, _useTreeLayout(UseTreeInfo, useTree)
, _treeOrdering(OrderingInfo)
, _ignoreHiddenHint(IgnoreHiddenInfo)
{
addProperty(_useTreeLayout);
addProperty(_treeOrdering);
addProperty(_ignoreHiddenHint);
}
void GuiPropertyComponent::setPropertyOwners(
@@ -206,10 +208,6 @@ void GuiPropertyComponent::setPropertyOwnerFunction(
_propertyOwnerFunction = std::move(func);
}
void GuiPropertyComponent::setVisibility(properties::Property::Visibility visibility) {
_visibility = visibility;
}
void GuiPropertyComponent::renderPropertyOwner(properties::PropertyOwner* owner) {
using namespace properties;
@@ -217,12 +215,12 @@ void GuiPropertyComponent::renderPropertyOwner(properties::PropertyOwner* owner)
return;
}
const int nThisProperty = nVisibleProperties(owner->properties(), _visibility);
const int nThisProperty = nVisibleProperties(owner->properties());
ImGui::PushID(owner->identifier().c_str());
const std::vector<PropertyOwner*>& subOwners = owner->propertySubOwners();
for (PropertyOwner* subOwner : subOwners) {
const std::vector<Property*>& properties = subOwner->propertiesRecursive();
int count = nVisibleProperties(properties, _visibility);
int count = nVisibleProperties(properties);
if (count == 0) {
continue;
}
@@ -286,6 +284,7 @@ void GuiPropertyComponent::render() {
ImGui::SetNextWindowBgAlpha(0.75f);
ImGui::Begin(guiName().c_str(), &v);
_isEnabled = v;
bool showHiddenNode = openspace::global::openSpaceEngine->showHiddenSceneGraphNodes();
_isCollapsed = ImGui::IsWindowCollapsed();
using namespace properties;
@@ -373,12 +372,14 @@ void GuiPropertyComponent::render() {
dynamic_cast<SceneGraphNode*>(*owners.begin())->guiPath().empty());
auto renderProp = [&](properties::PropertyOwner* pOwner) {
const int count = nVisibleProperties(pOwner->propertiesRecursive(), _visibility);
const int count = nVisibleProperties(pOwner->propertiesRecursive());
if (count == 0) {
return;
}
auto header = [&]() -> bool {
if (owners.size() > 1) {
// Create a header in case we have multiple owners
@@ -402,7 +403,7 @@ void GuiPropertyComponent::render() {
};
if (!_useTreeLayout || noGuiGroups) {
if (!_ignoreHiddenHint) {
if (!showHiddenNode) {
// Remove all of the nodes that we want hidden first
owners.erase(
std::remove_if(
@@ -424,7 +425,7 @@ void GuiPropertyComponent::render() {
for (properties::PropertyOwner* pOwner : owners) {
// We checked above that pOwner is a SceneGraphNode
SceneGraphNode* nOwner = static_cast<SceneGraphNode*>(pOwner);
if (!_ignoreHiddenHint && nOwner->hasGuiHintHidden()) {
if (!showHiddenNode && nOwner->hasGuiHintHidden()) {
continue;
}
const std::string gui = nOwner->guiPath();
@@ -491,7 +492,9 @@ void GuiPropertyComponent::renderProperty(properties::Property* prop,
// Check if the visibility of the property is high enough to be displayed
using V = properties::Property::Visibility;
const auto v = static_cast<std::underlying_type_t<V>>(_visibility);
using Visibility = openspace::properties::Property::Visibility;
Visibility visibilityFilter = openspace::global::openSpaceEngine->visibility();
const auto v = static_cast<std::underlying_type_t<V>>(visibilityFilter);
const auto propV = static_cast<std::underlying_type_t<V>>(prop->visibility());
if (v >= propV) {
auto it = FunctionMapping.find(prop->className());

View File

@@ -63,7 +63,7 @@ void DataPlane::initializeGL() {
// else if autofilter is turned off, register backgroundValues
}
else {
_backgroundValues.setVisibility(properties::Property::Visibility::All);
_backgroundValues.setVisibility(properties::Property::Visibility::Always);
}
});
}

View File

@@ -74,7 +74,7 @@ void DataSphere::initializeGL() {
// else if autofilter is turned off, register backgroundValues
}
else {
_backgroundValues.setVisibility(properties::Property::Visibility::All);
_backgroundValues.setVisibility(properties::Property::Visibility::Always);
//_backgroundValues.setVisible(true);
}
});

View File

@@ -134,7 +134,7 @@ void IswaDataGroup::registerProperties() {
// else if autofilter is turned off, register backgroundValues
}
else {
_backgroundValues.setVisibility(properties::Property::Visibility::All);
_backgroundValues.setVisibility(properties::Property::Visibility::Always);
//_backgroundValues.setVisible(true);
}
ghoul::Dictionary d;

View File

@@ -151,7 +151,7 @@ void KameleonPlane::initializeGL() {
// else if autofilter is turned off, register backgroundValues
}
else {
_backgroundValues.setVisibility(properties::Property::Visibility::All);
_backgroundValues.setVisibility(properties::Property::Visibility::Always);
//_backgroundValues.setVisible(true);
}
});

View File

@@ -0,0 +1,4 @@
if os.getenv("OPENSPACE_DEVELOPER")
then
openspace.setPropertyValueSingle('OpenSpaceEngine.PropertyVisibility', 4)
end

View File

@@ -399,6 +399,7 @@ void initialize() {
rootPropertyOwner->addPropertySubOwner(global::dashboard);
rootPropertyOwner->addPropertySubOwner(global::userPropertyOwner);
rootPropertyOwner->addPropertySubOwner(global::openSpaceEngine);
syncEngine->addSyncable(global::scriptEngine);
}

View File

@@ -118,12 +118,25 @@ namespace {
}
}
openspace::properties::Property::PropertyInfo PrintEventsInfo = {
constexpr openspace::properties::Property::PropertyInfo PrintEventsInfo = {
"PrintEvents",
"Print Events",
"If this is enabled, all events that are propagated through the system are "
"printed to the log."
};
constexpr openspace::properties::Property::PropertyInfo VisibilityInfo = {
"PropertyVisibility",
"Property Visibility",
"Hides or displays different settings in the GUI depending on how advanced they "
"are."
};
constexpr openspace::properties::Property::PropertyInfo ShowHiddenSceneInfo = {
"ShowHiddenSceneGraphNodes",
"Show Hidden Scene Graph Nodes",
"If checked, hidden scene graph nodes are visible in the UI"
};
} // namespace
namespace openspace {
@@ -131,7 +144,10 @@ namespace openspace {
class Scene;
OpenSpaceEngine::OpenSpaceEngine()
: _printEvents(PrintEventsInfo, false)
: properties::PropertyOwner({ "OpenSpaceEngine" })
, _printEvents(PrintEventsInfo, false)
, _visibility(VisibilityInfo)
, _showHiddenSceneGraphNodes(ShowHiddenSceneInfo, false)
{
FactoryManager::initialize();
FactoryManager::ref().addFactory<Renderable>("Renderable");
@@ -146,6 +162,19 @@ OpenSpaceEngine::OpenSpaceEngine()
SpiceManager::initialize();
TransformationManager::initialize();
addProperty(_printEvents);
addProperty(_visibility);
addProperty(_showHiddenSceneGraphNodes);
using Visibility = openspace::properties::Property::Visibility;
_visibility.addOptions({
{ static_cast<int>(Visibility::NoviceUser), "Novice User" },
{ static_cast<int>(Visibility::User), "User" },
{ static_cast<int>(Visibility::AdvancedUser), "Advanced User" },
{ static_cast<int>(Visibility::Developer), "Developer" },
{ static_cast<int>(Visibility::Hidden), "Everything" },
});
}
OpenSpaceEngine::~OpenSpaceEngine() {} // NOLINT
@@ -1192,6 +1221,8 @@ void OpenSpaceEngine::preSynchronization() {
if (_isRenderingFirstFrame) {
setCameraFromProfile(*global::profile);
setAdditionalScriptsFromProfile(*global::profile);
global::scriptEngine->runScriptFile(absPath("${SCRIPTS}/developer_settings.lua"));
}
// Handle callback(s) for change in engine mode
@@ -1582,6 +1613,14 @@ void OpenSpaceEngine::decode(std::vector<std::byte> data) {
global::syncEngine->decodeSyncables(std::move(data));
}
properties::Property::Visibility openspace::OpenSpaceEngine::visibility() const {
return static_cast<properties::Property::Visibility>(_visibility.value());
}
bool openspace::OpenSpaceEngine::showHiddenSceneGraphNodes() const {
return _showHiddenSceneGraphNodes;
}
void OpenSpaceEngine::toggleShutdownMode() {
if (_shutdown.inShutdown) {
// If we are already in shutdown mode, we want to disable it

View File

@@ -72,6 +72,8 @@ void OptionProperty::addOption(int value, std::string desc) {
}
}
_options.push_back(std::move(option));
// Set default value to option added first
NumericalProperty::setValue(_options[0].value);
}
void OptionProperty::addOptions(std::vector<std::pair<int, std::string>> options) {
@@ -100,7 +102,7 @@ void OptionProperty::setValue(int value) {
// @TODO(abock): This should be setValue(value) instead or otherwise the
// stored indices and option values start to drift if the
// operator T of the OptionProperty is used
NumericalProperty::setValue(static_cast<int>(i));
NumericalProperty::setValue(static_cast<int>(value));
return;
}
}
@@ -110,12 +112,26 @@ void OptionProperty::setValue(int value) {
}
bool OptionProperty::hasOption() const {
return value() >= 0 && value() < static_cast<int>(_options.size());
auto it = std::find_if(
_options.begin(),
_options.end(),
[setValue = value()](const Option& option) {
return option.value == setValue;
}
);
return it !=_options.end();
}
const OptionProperty::Option& OptionProperty::option() const {
return _options[value()];
auto it = std::find_if(
_options.begin(),
_options.end(),
[setValue = value()](const Option& option) {
return option.value == setValue;
}
);
return *it;
}
std::string OptionProperty::getDescriptionByValue(int value) {

View File

@@ -339,9 +339,11 @@ std::string Property::generateBaseJsonDescription() const {
std::string Property::generateMetaDataJsonDescription() const {
static const std::map<Visibility, std::string> VisibilityConverter = {
{ Visibility::All, "All" },
{ Visibility::Developer, "Developer" },
{ Visibility::Always, "Always" },
{ Visibility::NoviceUser, "NoviceUser" },
{ Visibility::User, "User" },
{ Visibility::AdvancedUser, "AdvancedUser" },
{ Visibility::Developer, "Developer" },
{ Visibility::Hidden, "Hidden" }
};
Visibility visibility = static_cast<Visibility>(