mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 02:23:34 +00:00
Interface mockup 8
This commit is contained in:
@@ -1,139 +0,0 @@
|
||||
// This file was generated with the assistance of an AI coding tool.
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "PropertiesPanelWidget.h"
|
||||
|
||||
#include "../../components/KeyValueTable.h"
|
||||
#include "../../components/Section.h"
|
||||
#include "../../components/SvgIcon.h"
|
||||
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace {
|
||||
|
||||
QWidget* makePropertySetPanel(const ifcinterface::panels::properties::PropertySet& property_set, QWidget* parent = nullptr) {
|
||||
auto* group = new QGroupBox(property_set.title, parent);
|
||||
group->setObjectName("propertySetCard");
|
||||
auto* layout = new QVBoxLayout(group);
|
||||
layout->setContentsMargins(10, 10, 10, 10);
|
||||
layout->setSpacing(0);
|
||||
|
||||
QList<ifcinterface::components::KeyValueTableRow> rows;
|
||||
for (const auto& row : property_set.rows) {
|
||||
rows.append({row.key, row.value, "keyValueValueLabel", "", "", 0});
|
||||
}
|
||||
layout->addWidget(new ifcinterface::components::KeyValueTable(rows, group));
|
||||
return group;
|
||||
}
|
||||
|
||||
QWidget* makeAttributeList(const QList<ifcinterface::panels::properties::KeyValueRow>& rows, QWidget* parent = nullptr) {
|
||||
QList<ifcinterface::components::KeyValueTableRow> table_rows;
|
||||
for (const auto& row : rows) {
|
||||
table_rows.append({row.key, row.value, "keyValueValueLabel", "", "", 0});
|
||||
}
|
||||
return new ifcinterface::components::KeyValueTable(table_rows, parent);
|
||||
}
|
||||
|
||||
QWidget* makeRelationshipList(const QList<ifcinterface::panels::properties::RelationshipRow>& rows, QWidget* parent = nullptr) {
|
||||
QList<ifcinterface::components::KeyValueTableRow> table_rows;
|
||||
for (const auto& row_data : rows) {
|
||||
table_rows.append({row_data.key,
|
||||
row_data.value,
|
||||
"keyValueValueLabel",
|
||||
":/icons/cursor-pointer.svg",
|
||||
"keyValueTrailingIconLabel",
|
||||
72});
|
||||
}
|
||||
return new ifcinterface::components::KeyValueTable(table_rows, parent);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace ifcinterface::panels::properties {
|
||||
|
||||
PropertiesPanelWidget::PropertiesPanelWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
content_layout_ = new QVBoxLayout(this);
|
||||
content_layout_->setContentsMargins(0, 0, 0, 0);
|
||||
content_layout_->setSpacing(12);
|
||||
}
|
||||
|
||||
void PropertiesPanelWidget::render(const PropertiesPanelState& state) {
|
||||
while (auto* item = content_layout_->takeAt(0)) {
|
||||
if (auto* widget = item->widget()) widget->deleteLater();
|
||||
delete item;
|
||||
}
|
||||
|
||||
auto* entity_card = new QFrame(this);
|
||||
entity_card->setObjectName("entityClassCard");
|
||||
auto* entity_layout = new QHBoxLayout(entity_card);
|
||||
entity_layout->setContentsMargins(10, 8, 10, 8);
|
||||
entity_layout->setSpacing(10);
|
||||
auto* entity_icon = new QLabel(entity_card);
|
||||
entity_icon->setPixmap(components::icons::makePanelSvgPixmap(":/icons/cube-dots.svg", QSize(28, 28)));
|
||||
entity_icon->setAlignment(Qt::AlignCenter);
|
||||
auto* entity_text = new QWidget(entity_card);
|
||||
auto* entity_text_layout = new QVBoxLayout(entity_text);
|
||||
entity_text_layout->setContentsMargins(0, 0, 0, 0);
|
||||
entity_text_layout->setSpacing(2);
|
||||
auto* entity_class = new QLabel(state.entity.entity_class, entity_text);
|
||||
entity_class->setObjectName("entityClassLabel");
|
||||
auto* entity_type = new QLabel(state.entity.predefined_type, entity_text);
|
||||
entity_type->setProperty("textRole", "secondary");
|
||||
entity_text_layout->addWidget(entity_class);
|
||||
entity_text_layout->addWidget(entity_type);
|
||||
entity_layout->addWidget(entity_icon, 0, Qt::AlignVCenter);
|
||||
entity_layout->addWidget(entity_text, 1, Qt::AlignVCenter);
|
||||
|
||||
QList<QWidget*> property_set_widgets;
|
||||
for (const auto& property_set : state.property_sets) {
|
||||
property_set_widgets.append(makePropertySetPanel(property_set, this));
|
||||
}
|
||||
|
||||
QList<QWidget*> quantity_set_widgets;
|
||||
for (const auto& property_set : state.quantity_sets) {
|
||||
quantity_set_widgets.append(makePropertySetPanel(property_set, this));
|
||||
}
|
||||
|
||||
auto* entity_section = new components::Section("", components::SectionHeaderMode::Hidden, "", this);
|
||||
entity_section->addBodyWidget(entity_card);
|
||||
auto* attributes_section = new components::Section("Attributes", components::SectionHeaderMode::Visible, "", this);
|
||||
attributes_section->addBodyWidget(makeAttributeList(state.attributes, this));
|
||||
auto* relationships_section = new components::Section("Relationships", components::SectionHeaderMode::Visible, "", this);
|
||||
relationships_section->addBodyWidget(makeRelationshipList(state.relationships, this));
|
||||
auto* properties_section = new components::Section("Properties", components::SectionHeaderMode::Visible, "Filter properties or sets", this);
|
||||
for (auto* widget : property_set_widgets) properties_section->addBodyWidget(widget);
|
||||
auto* quantities_section = new components::Section("Quantities", components::SectionHeaderMode::Visible, "Filter quantities or sets", this);
|
||||
for (auto* widget : quantity_set_widgets) quantities_section->addBodyWidget(widget);
|
||||
|
||||
content_layout_->addWidget(entity_section);
|
||||
content_layout_->addWidget(attributes_section);
|
||||
content_layout_->addWidget(relationships_section);
|
||||
content_layout_->addWidget(properties_section);
|
||||
content_layout_->addWidget(quantities_section);
|
||||
content_layout_->addStretch(1);
|
||||
}
|
||||
|
||||
} // namespace ifcinterface::panels::properties
|
||||
+2
-2
@@ -18,9 +18,9 @@
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "PropertiesPanelView.h"
|
||||
#include "View.h"
|
||||
|
||||
#include "PropertiesPanelWidget.h"
|
||||
#include "Widget.h"
|
||||
|
||||
#include "../../ElementRegistry.h"
|
||||
#include "../../../ifcviewer/AppSettings.h"
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
#ifndef IFCINTERFACE_PANELS_PROPERTIESPANELVIEW_H
|
||||
#define IFCINTERFACE_PANELS_PROPERTIESPANELVIEW_H
|
||||
|
||||
#include "PropertiesPanelTypes.h"
|
||||
#include "Types.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
// This file was generated with the assistance of an AI coding tool.
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "Widget.h"
|
||||
|
||||
#include "../../components/KeyValueTable.h"
|
||||
#include "../../components/Section.h"
|
||||
#include "../../components/Style.h"
|
||||
#include "../../components/SvgIcon.h"
|
||||
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QToolButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace {
|
||||
|
||||
QWidget* makePropertySetPanel(const ifcinterface::panels::properties::PropertySet& property_set, QWidget* parent = nullptr) {
|
||||
auto* group = new QGroupBox(property_set.title, parent);
|
||||
group->setObjectName("propertySetBox");
|
||||
auto* layout = new QVBoxLayout(group);
|
||||
layout->setContentsMargins(10, 10, 10, 10);
|
||||
layout->setSpacing(0);
|
||||
|
||||
QList<ifcinterface::components::KeyValueTableRow> rows;
|
||||
for (const auto& row : property_set.rows) {
|
||||
rows.append({row.key, row.value, "keyValueValueLabel", "", "", 0});
|
||||
}
|
||||
layout->addWidget(new ifcinterface::components::KeyValueTable(rows, group));
|
||||
return group;
|
||||
}
|
||||
|
||||
QWidget* makeAttributeList(const QList<ifcinterface::panels::properties::KeyValueRow>& rows, QWidget* parent = nullptr) {
|
||||
QList<ifcinterface::components::KeyValueTableRow> table_rows;
|
||||
for (const auto& row : rows) {
|
||||
table_rows.append({row.key, row.value, "keyValueValueLabel", "", "", 0});
|
||||
}
|
||||
return new ifcinterface::components::KeyValueTable(table_rows, parent);
|
||||
}
|
||||
|
||||
QWidget* makeRelationshipList(const QList<ifcinterface::panels::properties::RelationshipRow>& rows, QWidget* parent = nullptr) {
|
||||
QList<ifcinterface::components::KeyValueTableRow> table_rows;
|
||||
for (const auto& row_data : rows) {
|
||||
table_rows.append({row_data.key,
|
||||
row_data.value,
|
||||
"keyValueValueLabel",
|
||||
":/icons/cursor-pointer.svg",
|
||||
"keyValueTrailingIconLabel",
|
||||
72});
|
||||
}
|
||||
return new ifcinterface::components::KeyValueTable(table_rows, parent);
|
||||
}
|
||||
|
||||
QWidget* makeFilterWrapper(QLineEdit** field_out, QWidget* parent = nullptr) {
|
||||
auto* wrapper = new QWidget(parent);
|
||||
wrapper->setObjectName("panelSectionFilterWrapper");
|
||||
auto* layout = new QVBoxLayout(wrapper);
|
||||
layout->setContentsMargins(ifcinterface::components::style::metrics::section_body_padding,
|
||||
0,
|
||||
ifcinterface::components::style::metrics::section_body_padding,
|
||||
0);
|
||||
layout->setSpacing(0);
|
||||
|
||||
auto* field = new QLineEdit(wrapper);
|
||||
field->setClearButtonEnabled(true);
|
||||
field->addAction(ifcinterface::components::icons::makeSvgIcon(":/icons/filter.svg"), QLineEdit::LeadingPosition);
|
||||
field->setVisible(false);
|
||||
layout->addWidget(field);
|
||||
|
||||
if (field_out) *field_out = field;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace ifcinterface::panels::properties {
|
||||
|
||||
PropertiesPanelWidget::PropertiesPanelWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
content_layout_ = new QVBoxLayout(this);
|
||||
content_layout_->setContentsMargins(0, 0, 0, 0);
|
||||
content_layout_->setSpacing(12);
|
||||
|
||||
auto* entity_box = new QFrame(this);
|
||||
entity_box->setObjectName("entityClassBox");
|
||||
auto* entity_layout = new QHBoxLayout(entity_box);
|
||||
entity_layout->setContentsMargins(10, 8, 10, 8);
|
||||
entity_layout->setSpacing(10);
|
||||
auto* entity_icon = new QLabel(entity_box);
|
||||
entity_icon->setPixmap(components::icons::makeSvgPixmap(":/icons/cube-dots.svg", QSize(28, 28)));
|
||||
entity_icon->setAlignment(Qt::AlignCenter);
|
||||
auto* entity_text = new QWidget(entity_box);
|
||||
auto* entity_text_layout = new QVBoxLayout(entity_text);
|
||||
entity_text_layout->setContentsMargins(0, 0, 0, 0);
|
||||
entity_text_layout->setSpacing(2);
|
||||
entity_class_label_ = new QLabel(entity_text);
|
||||
entity_class_label_->setObjectName("entityClassLabel");
|
||||
entity_type_label_ = new QLabel(entity_text);
|
||||
entity_type_label_->setProperty("textRole", "secondary");
|
||||
entity_text_layout->addWidget(entity_class_label_);
|
||||
entity_text_layout->addWidget(entity_type_label_);
|
||||
entity_layout->addWidget(entity_icon, 0, Qt::AlignVCenter);
|
||||
entity_layout->addWidget(entity_text, 1, Qt::AlignVCenter);
|
||||
|
||||
entity_section_ = new components::Section("", components::SectionHeaderMode::Hidden, this);
|
||||
entity_section_->addBodyWidget(entity_box);
|
||||
attributes_section_ = new components::Section("Attributes", components::SectionHeaderMode::Visible, this);
|
||||
relationships_section_ = new components::Section("Relationships", components::SectionHeaderMode::Visible, this);
|
||||
properties_section_ = new components::Section("Properties", components::SectionHeaderMode::Visible, this);
|
||||
quantities_section_ = new components::Section("Quantities", components::SectionHeaderMode::Visible, this);
|
||||
|
||||
properties_filter_toggle_ = new QToolButton(properties_section_);
|
||||
properties_filter_toggle_->setObjectName("panelSectionFilterToggle");
|
||||
properties_filter_toggle_->setCheckable(true);
|
||||
properties_filter_toggle_->setIcon(components::icons::makeSvgIcon(":/icons/filter.svg"));
|
||||
properties_filter_toggle_->setAutoRaise(true);
|
||||
properties_section_->addHeaderWidget(properties_filter_toggle_);
|
||||
|
||||
quantities_filter_toggle_ = new QToolButton(quantities_section_);
|
||||
quantities_filter_toggle_->setObjectName("panelSectionFilterToggle");
|
||||
quantities_filter_toggle_->setCheckable(true);
|
||||
quantities_filter_toggle_->setIcon(components::icons::makeSvgIcon(":/icons/filter.svg"));
|
||||
quantities_filter_toggle_->setAutoRaise(true);
|
||||
quantities_section_->addHeaderWidget(quantities_filter_toggle_);
|
||||
|
||||
properties_filter_wrapper_ = makeFilterWrapper(&properties_filter_field_, properties_section_);
|
||||
properties_filter_field_->setPlaceholderText("Filter properties or sets");
|
||||
quantities_filter_wrapper_ = makeFilterWrapper(&quantities_filter_field_, quantities_section_);
|
||||
quantities_filter_field_->setPlaceholderText("Filter quantities or sets");
|
||||
|
||||
connect(properties_filter_toggle_, &QToolButton::toggled, properties_filter_field_, [this](bool visible) {
|
||||
properties_filter_field_->setVisible(visible);
|
||||
properties_filter_wrapper_->setVisible(visible);
|
||||
if (visible) properties_filter_field_->setFocus();
|
||||
});
|
||||
connect(quantities_filter_toggle_, &QToolButton::toggled, quantities_filter_field_, [this](bool visible) {
|
||||
quantities_filter_field_->setVisible(visible);
|
||||
quantities_filter_wrapper_->setVisible(visible);
|
||||
if (visible) quantities_filter_field_->setFocus();
|
||||
});
|
||||
|
||||
properties_filter_wrapper_->setVisible(false);
|
||||
quantities_filter_wrapper_->setVisible(false);
|
||||
|
||||
content_layout_->addWidget(entity_section_);
|
||||
content_layout_->addWidget(attributes_section_);
|
||||
content_layout_->addWidget(relationships_section_);
|
||||
content_layout_->addWidget(properties_section_);
|
||||
content_layout_->addWidget(quantities_section_);
|
||||
content_layout_->addStretch(1);
|
||||
}
|
||||
|
||||
void PropertiesPanelWidget::render(const PropertiesPanelState& state) {
|
||||
const bool attributes_expanded = attributes_section_->isExpanded();
|
||||
const bool relationships_expanded = relationships_section_->isExpanded();
|
||||
const bool properties_expanded = properties_section_->isExpanded();
|
||||
const bool quantities_expanded = quantities_section_->isExpanded();
|
||||
const bool properties_filter_visible = properties_filter_toggle_->isChecked();
|
||||
const bool quantities_filter_visible = quantities_filter_toggle_->isChecked();
|
||||
const QString properties_filter_text = properties_filter_field_->text();
|
||||
const QString quantities_filter_text = quantities_filter_field_->text();
|
||||
|
||||
entity_class_label_->setText(state.entity.entity_class);
|
||||
entity_type_label_->setText(state.entity.predefined_type);
|
||||
|
||||
attributes_section_->clearBody();
|
||||
relationships_section_->clearBody();
|
||||
properties_section_->clearBody();
|
||||
quantities_section_->clearBody();
|
||||
|
||||
QList<QWidget*> property_set_widgets;
|
||||
for (const auto& property_set : state.property_sets) {
|
||||
property_set_widgets.append(makePropertySetPanel(property_set, this));
|
||||
}
|
||||
|
||||
QList<QWidget*> quantity_set_widgets;
|
||||
for (const auto& property_set : state.quantity_sets) {
|
||||
quantity_set_widgets.append(makePropertySetPanel(property_set, this));
|
||||
}
|
||||
|
||||
attributes_section_->addBodyWidget(makeAttributeList(state.attributes, this));
|
||||
relationships_section_->addBodyWidget(makeRelationshipList(state.relationships, this));
|
||||
properties_section_->addBodyWidget(properties_filter_wrapper_);
|
||||
for (auto* widget : property_set_widgets) properties_section_->addBodyWidget(widget);
|
||||
quantities_section_->addBodyWidget(quantities_filter_wrapper_);
|
||||
for (auto* widget : quantity_set_widgets) quantities_section_->addBodyWidget(widget);
|
||||
|
||||
attributes_section_->setExpanded(attributes_expanded);
|
||||
relationships_section_->setExpanded(relationships_expanded);
|
||||
properties_section_->setExpanded(properties_expanded);
|
||||
quantities_section_->setExpanded(quantities_expanded);
|
||||
properties_filter_field_->setText(properties_filter_text);
|
||||
quantities_filter_field_->setText(quantities_filter_text);
|
||||
properties_filter_toggle_->setChecked(properties_filter_visible);
|
||||
quantities_filter_toggle_->setChecked(quantities_filter_visible);
|
||||
}
|
||||
|
||||
} // namespace ifcinterface::panels::properties
|
||||
+18
-1
@@ -21,11 +21,15 @@
|
||||
#ifndef IFCINTERFACE_PANELS_PROPERTIESPANELWIDGET_H
|
||||
#define IFCINTERFACE_PANELS_PROPERTIESPANELWIDGET_H
|
||||
|
||||
#include "PropertiesPanelTypes.h"
|
||||
#include "Types.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QVBoxLayout;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QToolButton;
|
||||
namespace ifcinterface::components { class Section; }
|
||||
|
||||
namespace ifcinterface::panels::properties {
|
||||
|
||||
@@ -38,6 +42,19 @@ public:
|
||||
|
||||
private:
|
||||
QVBoxLayout* content_layout_ = nullptr;
|
||||
QLabel* entity_class_label_ = nullptr;
|
||||
QLabel* entity_type_label_ = nullptr;
|
||||
components::Section* entity_section_ = nullptr;
|
||||
components::Section* attributes_section_ = nullptr;
|
||||
components::Section* relationships_section_ = nullptr;
|
||||
components::Section* properties_section_ = nullptr;
|
||||
components::Section* quantities_section_ = nullptr;
|
||||
QWidget* properties_filter_wrapper_ = nullptr;
|
||||
QWidget* quantities_filter_wrapper_ = nullptr;
|
||||
QLineEdit* properties_filter_field_ = nullptr;
|
||||
QLineEdit* quantities_filter_field_ = nullptr;
|
||||
QToolButton* properties_filter_toggle_ = nullptr;
|
||||
QToolButton* quantities_filter_toggle_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace ifcinterface::panels::properties
|
||||
@@ -0,0 +1,222 @@
|
||||
// This file was generated with the assistance of an AI coding tool.
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "Dialog.h"
|
||||
|
||||
#include "../../../ifcviewer/AppSettings.h"
|
||||
#include "../../components/Section.h"
|
||||
#include "../../components/Style.h"
|
||||
#include "../../components/SvgIcon.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QFrame>
|
||||
#include <QFormLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QShowEvent>
|
||||
#include <QSpinBox>
|
||||
#include <QTabWidget>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace ifcinterface::panels::settings {
|
||||
|
||||
SettingsDialog::SettingsDialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
setObjectName("appDialog");
|
||||
setWindowTitle("Settings");
|
||||
setModal(true);
|
||||
resize(520, 420);
|
||||
setStyleSheet(components::style::buildAppStyleSheet());
|
||||
setupUi();
|
||||
}
|
||||
|
||||
void SettingsDialog::showEvent(QShowEvent* event) {
|
||||
syncFromSettings();
|
||||
QDialog::showEvent(event);
|
||||
}
|
||||
|
||||
void SettingsDialog::setupUi() {
|
||||
auto* root = new QVBoxLayout(this);
|
||||
root->setContentsMargins(12, 12, 12, 12);
|
||||
root->setSpacing(0);
|
||||
|
||||
auto* panel = new QFrame(this);
|
||||
panel->setObjectName("panel");
|
||||
auto* panel_layout = new QVBoxLayout(panel);
|
||||
panel_layout->setContentsMargins(0, components::style::metrics::section_body_padding, 0,
|
||||
components::style::metrics::section_body_padding);
|
||||
panel_layout->setSpacing(12);
|
||||
|
||||
auto* tabs = new QTabWidget(panel);
|
||||
|
||||
auto* graphics_tab = new QWidget(tabs);
|
||||
auto* graphics_layout = new QVBoxLayout(graphics_tab);
|
||||
graphics_layout->setContentsMargins(0, 0, 0, 0);
|
||||
graphics_layout->setSpacing(12);
|
||||
|
||||
auto* general_section = new components::Section("General", components::SectionHeaderMode::Visible, graphics_tab);
|
||||
auto* general_body = new QWidget(general_section);
|
||||
auto* general_form = new QFormLayout(general_body);
|
||||
general_form->setContentsMargins(0, 0, 0, 0);
|
||||
general_form->setHorizontalSpacing(16);
|
||||
general_form->setVerticalSpacing(10);
|
||||
|
||||
geometry_library_edit_ = new QLineEdit(general_body);
|
||||
geometry_library_edit_->setMinimumWidth(300);
|
||||
general_form->addRow("Geometry Library", geometry_library_edit_);
|
||||
|
||||
show_stats_check_ = new QCheckBox(general_body);
|
||||
general_form->addRow("Show Performance Stats", show_stats_check_);
|
||||
|
||||
backface_culling_check_ = new QCheckBox(general_body);
|
||||
backface_culling_check_->setToolTip(
|
||||
"Skip triangles facing away from the camera. Big FPS win on closed solids; "
|
||||
"disable if you see holes in open geometry.");
|
||||
general_form->addRow("Backface Culling", backface_culling_check_);
|
||||
|
||||
general_section->addBodyWidget(general_body);
|
||||
|
||||
auto* loading_section = new components::Section("Loading", components::SectionHeaderMode::Visible, graphics_tab);
|
||||
auto* loading_body = new QWidget(loading_section);
|
||||
auto* loading_form = new QFormLayout(loading_body);
|
||||
loading_form->setContentsMargins(0, 0, 0, 0);
|
||||
loading_form->setHorizontalSpacing(16);
|
||||
loading_form->setVerticalSpacing(10);
|
||||
|
||||
load_data_source_checkbox_ = new QCheckBox(loading_body);
|
||||
load_data_source_checkbox_->setToolTip(
|
||||
"Keep the .ifc/.rdb open after loading so element properties can be queried. "
|
||||
"Disable for geometry-only viewing.");
|
||||
loading_form->addRow("Load Property Data Source", load_data_source_checkbox_);
|
||||
|
||||
apply_coordinate_operation_check_ = new QCheckBox(loading_body);
|
||||
apply_coordinate_operation_check_->setToolTip(
|
||||
"Apply each model's IfcCoordinateOperation after load so it lands in "
|
||||
"georeferenced map coordinates.");
|
||||
loading_form->addRow("Apply Coordinate Operation", apply_coordinate_operation_check_);
|
||||
|
||||
void_limit_spin_ = new QSpinBox(loading_body);
|
||||
void_limit_spin_->setRange(0, 100000);
|
||||
loading_form->addRow("Void Limit", void_limit_spin_);
|
||||
|
||||
deflection_tolerance_spin_ = new QDoubleSpinBox(loading_body);
|
||||
deflection_tolerance_spin_->setRange(0.000001, 1000.0);
|
||||
deflection_tolerance_spin_->setDecimals(6);
|
||||
deflection_tolerance_spin_->setSingleStep(0.001);
|
||||
loading_form->addRow("Deflection Tolerance", deflection_tolerance_spin_);
|
||||
|
||||
angular_tolerance_spin_ = new QDoubleSpinBox(loading_body);
|
||||
angular_tolerance_spin_->setRange(0.000001, 3.141592);
|
||||
angular_tolerance_spin_->setDecimals(6);
|
||||
angular_tolerance_spin_->setSingleStep(0.05);
|
||||
loading_form->addRow("Angular Tolerance", angular_tolerance_spin_);
|
||||
|
||||
auto* description = new QLabel(
|
||||
"These settings are shared with the viewer backend and persist via QSettings.",
|
||||
loading_body);
|
||||
description->setProperty("textRole", "secondary");
|
||||
description->setWordWrap(true);
|
||||
loading_form->addRow(QString(), description);
|
||||
|
||||
loading_section->addBodyWidget(loading_body);
|
||||
graphics_layout->addWidget(general_section);
|
||||
graphics_layout->addWidget(loading_section);
|
||||
graphics_layout->addStretch(1);
|
||||
|
||||
auto make_placeholder_tab = [tabs](const QString& title, const QString& detail) {
|
||||
auto* tab = new QWidget(tabs);
|
||||
auto* layout = new QVBoxLayout(tab);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(12);
|
||||
|
||||
auto* section = new components::Section(title, components::SectionHeaderMode::Visible, tab);
|
||||
auto* body = new QWidget(section);
|
||||
auto* body_layout = new QVBoxLayout(body);
|
||||
body_layout->setContentsMargins(0, 0, 0, 0);
|
||||
body_layout->setSpacing(8);
|
||||
|
||||
auto* heading = new QLabel(title, body);
|
||||
auto* content = new QLabel(detail, body);
|
||||
content->setProperty("textRole", "secondary");
|
||||
content->setWordWrap(true);
|
||||
|
||||
body_layout->addWidget(heading);
|
||||
body_layout->addWidget(content);
|
||||
section->addBodyWidget(body);
|
||||
layout->addWidget(section);
|
||||
layout->addStretch(1);
|
||||
return tab;
|
||||
};
|
||||
|
||||
tabs->addTab(make_placeholder_tab("Navigation", "Navigation preferences and interaction modes will live here."),
|
||||
"Navigation");
|
||||
tabs->addTab(make_placeholder_tab("Keybindings", "Shortcut presets and command bindings will live here."),
|
||||
"Keybindings");
|
||||
tabs->addTab(graphics_tab, "Graphics");
|
||||
tabs->addTab(make_placeholder_tab("Theme", "Theme, density, and UI appearance settings will live here."),
|
||||
"Theme");
|
||||
tabs->addTab(make_placeholder_tab("About", "Version, credits, and environment information will live here."),
|
||||
"About");
|
||||
|
||||
auto* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, panel);
|
||||
if (auto* ok = buttons->button(QDialogButtonBox::Ok)) {
|
||||
ok->setText("OK");
|
||||
ok->setIcon(components::icons::makeSvgIcon(":/icons/check.svg"));
|
||||
}
|
||||
if (auto* cancel = buttons->button(QDialogButtonBox::Cancel)) {
|
||||
cancel->setText("Cancel");
|
||||
cancel->setIcon(components::icons::makeSvgIcon(":/icons/xmark-circle.svg"));
|
||||
}
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &SettingsDialog::onAccepted);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
panel_layout->addWidget(tabs);
|
||||
panel_layout->addWidget(buttons);
|
||||
root->addWidget(panel);
|
||||
}
|
||||
|
||||
void SettingsDialog::syncFromSettings() {
|
||||
geometry_library_edit_->setText(AppSettings::instance().geometryLibrary());
|
||||
show_stats_check_->setChecked(AppSettings::instance().showStats());
|
||||
backface_culling_check_->setChecked(AppSettings::instance().backfaceCulling());
|
||||
load_data_source_checkbox_->setChecked(AppSettings::instance().loadDataSource());
|
||||
apply_coordinate_operation_check_->setChecked(AppSettings::instance().applyCoordinateOperation());
|
||||
void_limit_spin_->setValue(AppSettings::instance().voidLimit());
|
||||
deflection_tolerance_spin_->setValue(AppSettings::instance().deflectionTolerance());
|
||||
angular_tolerance_spin_->setValue(AppSettings::instance().angularTolerance());
|
||||
}
|
||||
|
||||
void SettingsDialog::onAccepted() {
|
||||
AppSettings::instance().setGeometryLibrary(geometry_library_edit_->text());
|
||||
AppSettings::instance().setShowStats(show_stats_check_->isChecked());
|
||||
AppSettings::instance().setBackfaceCulling(backface_culling_check_->isChecked());
|
||||
AppSettings::instance().setLoadDataSource(load_data_source_checkbox_->isChecked());
|
||||
AppSettings::instance().setApplyCoordinateOperation(apply_coordinate_operation_check_->isChecked());
|
||||
AppSettings::instance().setVoidLimit(void_limit_spin_->value());
|
||||
AppSettings::instance().setDeflectionTolerance(deflection_tolerance_spin_->value());
|
||||
AppSettings::instance().setAngularTolerance(angular_tolerance_spin_->value());
|
||||
accept();
|
||||
}
|
||||
|
||||
} // namespace ifcinterface::panels::settings
|
||||
@@ -0,0 +1,59 @@
|
||||
// This file was generated with the assistance of an AI coding tool.
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCINTERFACE_PANELS_SETTINGSDIALOG_H
|
||||
#define IFCINTERFACE_PANELS_SETTINGSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QCheckBox;
|
||||
class QDoubleSpinBox;
|
||||
class QLineEdit;
|
||||
class QShowEvent;
|
||||
class QSpinBox;
|
||||
|
||||
namespace ifcinterface::panels::settings {
|
||||
|
||||
class SettingsDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SettingsDialog(QWidget* parent = nullptr);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent* event) override;
|
||||
|
||||
private:
|
||||
void setupUi();
|
||||
void syncFromSettings();
|
||||
void onAccepted();
|
||||
|
||||
QLineEdit* geometry_library_edit_ = nullptr;
|
||||
QCheckBox* show_stats_check_ = nullptr;
|
||||
QCheckBox* backface_culling_check_ = nullptr;
|
||||
QCheckBox* load_data_source_checkbox_ = nullptr;
|
||||
QCheckBox* apply_coordinate_operation_check_ = nullptr;
|
||||
QSpinBox* void_limit_spin_ = nullptr;
|
||||
QDoubleSpinBox* deflection_tolerance_spin_ = nullptr;
|
||||
QDoubleSpinBox* angular_tolerance_spin_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace ifcinterface::panels::settings
|
||||
|
||||
#endif
|
||||
+2
-2
@@ -18,9 +18,9 @@
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "SpatialHierarchyPanelView.h"
|
||||
#include "View.h"
|
||||
|
||||
#include "SpatialHierarchyPanelWidget.h"
|
||||
#include "Widget.h"
|
||||
|
||||
namespace ifcinterface::panels::spatial_hierarchy {
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
#ifndef IFCINTERFACE_PANELS_SPATIALHIERARCHYPANELVIEW_H
|
||||
#define IFCINTERFACE_PANELS_SPATIALHIERARCHYPANELVIEW_H
|
||||
|
||||
#include "SpatialHierarchyPanelTypes.h"
|
||||
#include "Types.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
+4
-4
@@ -18,7 +18,7 @@
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "SpatialHierarchyPanelWidget.h"
|
||||
#include "Widget.h"
|
||||
|
||||
#include "../../components/Section.h"
|
||||
#include "../../components/SvgIcon.h"
|
||||
@@ -37,7 +37,7 @@ SpatialHierarchyPanelWidget::SpatialHierarchyPanelWidget(QWidget* parent)
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(0);
|
||||
|
||||
auto* section = new components::Section("", components::SectionHeaderMode::Hidden, "", this);
|
||||
auto* section = new components::Section("", components::SectionHeaderMode::Hidden, this);
|
||||
|
||||
tree_ = new QTreeWidget(section);
|
||||
tree_->setColumnCount(2);
|
||||
@@ -71,8 +71,8 @@ void SpatialHierarchyPanelWidget::addNode(QTreeWidgetItem* parent, const TreeNod
|
||||
auto* item = new QTreeWidgetItem(parent, {node.name, ""});
|
||||
item->setData(1, Qt::UserRole, node.visible);
|
||||
item->setSizeHint(0, QSize(0, 24));
|
||||
item->setIcon(0, components::icons::makePanelSvgIcon(iconPath(node.kind)));
|
||||
item->setIcon(1, components::icons::makePanelSvgIcon(node.visible ? ":/icons/eye.svg" : ":/icons/eye-closed.svg"));
|
||||
item->setIcon(0, components::icons::makeSvgIcon(iconPath(node.kind)));
|
||||
item->setIcon(1, components::icons::makeSvgIcon(node.visible ? ":/icons/eye.svg" : ":/icons/eye-closed.svg"));
|
||||
for (const auto& child : node.children) {
|
||||
addNode(item, child);
|
||||
}
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
#ifndef IFCINTERFACE_PANELS_SPATIALHIERARCHYPANELWIDGET_H
|
||||
#define IFCINTERFACE_PANELS_SPATIALHIERARCHYPANELWIDGET_H
|
||||
|
||||
#include "SpatialHierarchyPanelTypes.h"
|
||||
#include "Types.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "TodoPanelWidget.h"
|
||||
#include "Widget.h"
|
||||
|
||||
#include "../../components/Section.h"
|
||||
|
||||
@@ -34,7 +34,7 @@ TodoPanelWidget::TodoPanelWidget(const QString& title, QWidget* parent)
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(0);
|
||||
|
||||
auto* section = new components::Section("", components::SectionHeaderMode::Hidden, "", this);
|
||||
auto* section = new components::Section("", components::SectionHeaderMode::Hidden, this);
|
||||
|
||||
auto* body = new QWidget(section);
|
||||
auto* body_layout = new QVBoxLayout(body);
|
||||
Reference in New Issue
Block a user