Merge branch 'feature/guisorting'

# Conflicts:
#	modules/imgui/include/guipropertycomponent.h
#	modules/imgui/src/guipropertycomponent.cpp
This commit is contained in:
Alexander Bock
2017-12-07 01:15:52 -05:00
19 changed files with 315 additions and 20 deletions
+6 -2
View File
@@ -28,6 +28,8 @@
#include <modules/imgui/include/guicomponent.h>
#include <openspace/properties/property.h>
#include <openspace/properties/stringlistproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <ghoul/misc/boolean.h>
@@ -72,8 +74,10 @@ protected:
/// are regular, i.e., not containing wildcards, regex, or groups
/// This variable only has an impact on which \c setPropertyValue function is called
bool _hasOnlyRegularProperties = false;
UseTreeLayout _useTreeLayout;
bool _currentUseTreeLayout;
properties::BoolProperty _useTreeLayout;
properties::StringListProperty _treeOrdering;
bool _showHelpTooltip;
};
+4
View File
@@ -57,6 +57,10 @@ void renderStringProperty(properties::Property* prop, const std::string& ownerNa
IsRegularProperty isRegular = IsRegularProperty::Yes,
ShowToolTip showTooltip = ShowToolTip::Yes);
void renderStringListProperty(properties::Property* prop, const std::string& ownerName,
IsRegularProperty isRegular = IsRegularProperty::Yes,
ShowToolTip showTooltip = ShowToolTip::Yes);
void renderDoubleProperty(properties::Property* prop, const std::string& ownerName,
IsRegularProperty isRegular = IsRegularProperty::Yes,
ShowToolTip showTooltip = ShowToolTip::Yes);
-5
View File
@@ -626,11 +626,6 @@ void GUI::startFrame(float deltaTime, const glm::vec2& windowSize,
}
void GUI::endFrame() {
LINFOC("Enabled", _isEnabled);
LINFOC("Collapsed", _isCollapsed);
LINFOC("Hidden", _allHidden);
if (_program->isDirty()) {
_program->rebuildFromFile();
}
+64 -13
View File
@@ -37,6 +37,22 @@
namespace {
const ImVec2 size = ImVec2(350, 500);
static const openspace::properties::Property::PropertyInfo UseTreeInfo = {
"TreeLayout",
"Use Tree Layout",
"If this value is checked, this component will display the properties using a "
"tree layout, rather than using a flat map. This value should only be set on "
"property windows that display SceneGraphNodes, or the application might crash."
};
static const openspace::properties::Property::PropertyInfo OrderingInfo = {
"Ordering",
"Tree Ordering",
"This list determines the order of the first tree layer if it is used. Elements "
"present in this list will be shown first, with an alphabetical ordering for "
"elements not listed."
};
int nVisibleProperties(const std::vector<openspace::properties::Property*>& props,
openspace::properties::Property::Visibility visibility)
{
@@ -148,9 +164,12 @@ namespace openspace::gui {
GuiPropertyComponent::GuiPropertyComponent(std::string name, UseTreeLayout useTree)
: GuiComponent(std::move(name))
, _useTreeLayout(useTree)
, _currentUseTreeLayout(useTree)
{}
, _useTreeLayout(UseTreeInfo, useTree)
, _treeOrdering(OrderingInfo)
{
addProperty(_useTreeLayout);
addProperty(_treeOrdering);
}
void GuiPropertyComponent::setSource(SourceFunction function) {
_function = std::move(function);
@@ -241,13 +260,9 @@ void GuiPropertyComponent::render() {
_isEnabled = v;
_isCollapsed = ImGui::IsWindowCollapsed();
using namespace properties;
if (_function) {
if (_useTreeLayout) {
ImGui::Checkbox("Use Tree layout", &_currentUseTreeLayout);
}
std::vector<properties::PropertyOwner*> owners = _function();
std::sort(
@@ -258,7 +273,7 @@ void GuiPropertyComponent::render() {
}
);
if (_currentUseTreeLayout) {
if (_useTreeLayout) {
for (properties::PropertyOwner* owner : owners) {
ghoul_assert(
dynamic_cast<SceneGraphNode*>(owner),
@@ -268,12 +283,14 @@ void GuiPropertyComponent::render() {
}
// Sort:
// if guigrouping, sort by name and shortest first
// if guigrouping, sort by name and shortest first, but respect the user
// specified ordering
// then all w/o guigroup
const std::vector<std::string>& ordering = _treeOrdering;
std::stable_sort(
owners.begin(),
owners.end(),
[](properties::PropertyOwner* lhs, properties::PropertyOwner* rhs) {
[&ordering](PropertyOwner* lhs, PropertyOwner* rhs) {
std::string lhsGroup = static_cast<SceneGraphNode*>(lhs)->guiPath();
std::string rhsGroup = static_cast<SceneGraphNode*>(rhs)->guiPath();
@@ -283,7 +300,40 @@ void GuiPropertyComponent::render() {
if (rhsGroup.empty()) {
return true;
}
return lhsGroup < rhsGroup;
if (ordering.empty()) {
return lhsGroup < rhsGroup;
}
std::vector<std::string> lhsToken = ghoul::tokenizeString(
lhsGroup,
'/'
);
// The first token is always empty
auto lhsIt = std::find(ordering.begin(), ordering.end(), lhsToken[1]);
std::vector<std::string> rhsToken = ghoul::tokenizeString(
rhsGroup,
'/'
);
// The first token is always empty
auto rhsIt = std::find(ordering.begin(), ordering.end(), rhsToken[1]);
if (lhsIt != ordering.end() && rhsIt != ordering.end()) {
// If both top-level groups are in the ordering list, the order
// of the iterators gives us the order of the groups
return lhsIt < rhsIt;
}
else if (lhsIt != ordering.end() && rhsIt == ordering.end()) {
// If only one of them is in the list, we have a sorting
return true;
}
else if (lhsIt == ordering.end() && rhsIt != ordering.end()) {
return false;
}
else {
return lhsGroup < rhsGroup;
}
}
);
}
@@ -326,7 +376,7 @@ void GuiPropertyComponent::render() {
}
};
if (!_currentUseTreeLayout || noGuiGroups) {
if (!_useTreeLayout || noGuiGroups) {
std::for_each(owners.begin(), owners.end(), renderProp);
}
else { // _useTreeLayout && gui groups exist
@@ -395,6 +445,7 @@ void GuiPropertyComponent::renderProperty(properties::Property* prop,
{ "DMat3Property", &renderDMat3Property },
{ "DMat4Property", &renderDMat4Property },
{ "StringProperty", &renderStringProperty },
{ "StringListProperty", &renderStringListProperty },
{ "OptionProperty", &renderOptionProperty },
{ "TriggerProperty", &renderTriggerProperty },
{ "SelectionProperty", &renderSelectionProperty }
+52
View File
@@ -32,10 +32,12 @@
#include <openspace/properties/optionproperty.h>
#include <openspace/properties/selectionproperty.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/stringlistproperty.h>
#include <openspace/properties/vectorproperty.h>
#include <openspace/scripting/scriptengine.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/misc/misc.h>
namespace openspace {
@@ -244,6 +246,56 @@ void renderStringProperty(Property* prop, const std::string& ownerName,
ImGui::PopID();
}
void renderStringListProperty(Property* prop, const std::string& ownerName,
IsRegularProperty isRegular, ShowToolTip showTooltip)
{
ghoul_assert(prop, "prop must not be nullptr");
StringListProperty* p = static_cast<StringListProperty*>(prop);
std::string name = p->guiName();
ImGui::PushID((ownerName + "." + name).c_str());
std::string value;
p->getStringValue(value);
// const std::string value = p->value();
static const int bufferSize = 512;
static char buffer[bufferSize];
#ifdef _MSC_VER
strcpy_s(buffer, value.length() + 1, value.c_str());
#else
strcpy(buffer, value.c_str());
#endif
bool hasNewValue = ImGui::InputText(
name.c_str(),
buffer,
bufferSize,
ImGuiInputTextFlags_EnterReturnsTrue
);
if (showTooltip) {
renderTooltip(prop);
}
if (hasNewValue) {
std::vector<std::string> tokens = ghoul::tokenizeString(std::string(buffer), ',');
std::string script = "{";
for (std::string& token : tokens) {
if (!token.empty()) {
ghoul::trimWhitespace(token);
script += "[[" + token + "]],";
}
}
script += "}";
executeScript(
p->fullyQualifiedIdentifier(),
std::move(script),
isRegular
);
}
ImGui::PopID();
}
void renderDoubleProperty(properties::Property* prop, const std::string& ownerName,
IsRegularProperty isRegular, ShowToolTip showTooltip)
{