mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 05:00:53 +00:00
Interface mockup 5
This commit is contained in:
@@ -25,14 +25,20 @@ find_package(Qt${QT_VERSION} COMPONENTS Core Gui Widgets Svg REQUIRED PATHS ${QT
|
|||||||
|
|
||||||
set(INTERFACE_FILES
|
set(INTERFACE_FILES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/ElementRegistry.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/ElementRegistry.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/MainWindow.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/MainWindow.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/MainWindow.h
|
${CMAKE_CURRENT_SOURCE_DIR}/MainWindow.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/components/SvgIcon.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/components/SvgIcon.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/components/SvgIcon.h
|
${CMAKE_CURRENT_SOURCE_DIR}/components/SvgIcon.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/components/Style.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/components/Style.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/components/KeyValueTable.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/components/KeyValueTable.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/components/Section.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/components/Section.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/components/Section.h
|
${CMAKE_CURRENT_SOURCE_DIR}/components/Section.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/components/PanelChrome.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/components/Panel.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/components/PanelChrome.h
|
${CMAKE_CURRENT_SOURCE_DIR}/components/Panel.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/ModelsPanelTypes.h
|
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/ModelsPanelTypes.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/ModelsPanelWidget.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/ModelsPanelWidget.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/ModelsPanelWidget.h
|
${CMAKE_CURRENT_SOURCE_DIR}/panels/models/ModelsPanelWidget.h
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// 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 "ElementRegistry.h"
|
||||||
|
|
||||||
|
#include "../ifcviewer/GeometryStreamer.h"
|
||||||
|
#include "../ifcviewer/SceneLoader.h"
|
||||||
|
#include "../ifcviewer/SidecarCache.h"
|
||||||
|
|
||||||
|
namespace ifcinterface {
|
||||||
|
|
||||||
|
ElementRegistry::ElementRegistry(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElementRegistry::bindLoader(SceneLoader* loader) {
|
||||||
|
connect(loader, &SceneLoader::sidecarElementsReady,
|
||||||
|
this, &ElementRegistry::onSidecarElementsReady);
|
||||||
|
connect(loader, &SceneLoader::streamedElementsReady,
|
||||||
|
this, &ElementRegistry::onStreamedElementsReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<BasicElementInfo> ElementRegistry::find(uint32_t object_id) const {
|
||||||
|
auto it = elements_.find(object_id);
|
||||||
|
if (it == elements_.end()) return std::nullopt;
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElementRegistry::onSidecarElementsReady(uint32_t /*mid*/,
|
||||||
|
std::vector<PackedElementInfo> elements,
|
||||||
|
std::string string_table) {
|
||||||
|
auto str = [&](uint32_t offset, uint32_t length) -> QString {
|
||||||
|
if (length == 0 || offset + length > string_table.size()) return {};
|
||||||
|
return QString::fromStdString(string_table.substr(offset, length));
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& pe : elements) {
|
||||||
|
BasicElementInfo info;
|
||||||
|
info.object_id = pe.object_id;
|
||||||
|
info.model_id = pe.model_id;
|
||||||
|
info.ifc_id = pe.ifc_id;
|
||||||
|
info.parent_id = pe.parent_id;
|
||||||
|
info.guid = str(pe.guid_offset, pe.guid_length);
|
||||||
|
info.name = str(pe.name_offset, pe.name_length);
|
||||||
|
info.type = str(pe.type_offset, pe.type_length);
|
||||||
|
elements_[info.object_id] = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElementRegistry::onStreamedElementsReady(uint32_t /*mid*/, std::vector<ElementInfo> elements) {
|
||||||
|
for (const auto& e : elements) {
|
||||||
|
BasicElementInfo info;
|
||||||
|
info.object_id = e.object_id;
|
||||||
|
info.model_id = e.model_id;
|
||||||
|
info.ifc_id = e.ifc_id;
|
||||||
|
info.parent_id = e.parent_id;
|
||||||
|
info.guid = QString::fromStdString(e.guid);
|
||||||
|
info.name = QString::fromStdString(e.name);
|
||||||
|
info.type = QString::fromStdString(e.type);
|
||||||
|
elements_[info.object_id] = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ifcinterface
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
// 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_ELEMENTREGISTRY_H
|
||||||
|
#define IFCINTERFACE_ELEMENTREGISTRY_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <optional>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class SceneLoader;
|
||||||
|
struct PackedElementInfo;
|
||||||
|
struct ElementInfo;
|
||||||
|
|
||||||
|
namespace ifcinterface {
|
||||||
|
|
||||||
|
struct BasicElementInfo {
|
||||||
|
uint32_t object_id = 0;
|
||||||
|
uint32_t model_id = 0;
|
||||||
|
int ifc_id = 0;
|
||||||
|
int parent_id = 0;
|
||||||
|
QString guid;
|
||||||
|
QString name;
|
||||||
|
QString type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ElementRegistry : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ElementRegistry(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
void bindLoader(SceneLoader* loader);
|
||||||
|
std::optional<BasicElementInfo> find(uint32_t object_id) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onSidecarElementsReady(uint32_t mid,
|
||||||
|
std::vector<PackedElementInfo> elements,
|
||||||
|
std::string string_table);
|
||||||
|
void onStreamedElementsReady(uint32_t mid, std::vector<ElementInfo> elements);
|
||||||
|
|
||||||
|
std::unordered_map<uint32_t, BasicElementInfo> elements_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ifcinterface
|
||||||
|
|
||||||
|
#endif
|
||||||
+69
-342
@@ -23,7 +23,9 @@
|
|||||||
#include "../ifcviewer/AppSettings.h"
|
#include "../ifcviewer/AppSettings.h"
|
||||||
#include "../ifcviewer/SceneLoader.h"
|
#include "../ifcviewer/SceneLoader.h"
|
||||||
#include "../ifcviewer/ViewportWindow.h"
|
#include "../ifcviewer/ViewportWindow.h"
|
||||||
#include "components/PanelChrome.h"
|
#include "ElementRegistry.h"
|
||||||
|
#include "components/Panel.h"
|
||||||
|
#include "components/Style.h"
|
||||||
#include "components/SvgIcon.h"
|
#include "components/SvgIcon.h"
|
||||||
#include "panels/todo/TodoPanelWidget.h"
|
#include "panels/todo/TodoPanelWidget.h"
|
||||||
#include "panels/models/ModelsPanelView.h"
|
#include "panels/models/ModelsPanelView.h"
|
||||||
@@ -52,9 +54,10 @@ namespace ifcinterface::shell {
|
|||||||
MainWindow::MainWindow(QWidget* parent)
|
MainWindow::MainWindow(QWidget* parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
{
|
{
|
||||||
|
element_registry_ = new ifcinterface::ElementRegistry(this);
|
||||||
setupChrome();
|
setupChrome();
|
||||||
setupViewport();
|
setupViewport();
|
||||||
setupDocks();
|
setupPanels();
|
||||||
setupStatus();
|
setupStatus();
|
||||||
setupLoader();
|
setupLoader();
|
||||||
setupRibbon();
|
setupRibbon();
|
||||||
@@ -66,280 +69,7 @@ void MainWindow::setupChrome() {
|
|||||||
setDockOptions(QMainWindow::AllowNestedDocks |
|
setDockOptions(QMainWindow::AllowNestedDocks |
|
||||||
QMainWindow::AllowTabbedDocks |
|
QMainWindow::AllowTabbedDocks |
|
||||||
QMainWindow::GroupedDragging);
|
QMainWindow::GroupedDragging);
|
||||||
|
setStyleSheet(components::style::buildAppStyleSheet());
|
||||||
setStyleSheet(R"(
|
|
||||||
QMainWindow {
|
|
||||||
background: #26292f;
|
|
||||||
}
|
|
||||||
QWidget {
|
|
||||||
color: #d0d5dd;
|
|
||||||
background: #26292f;
|
|
||||||
selection-background-color: #39b54a;
|
|
||||||
selection-color: #14161a;
|
|
||||||
}
|
|
||||||
QFrame#ribbonShell {
|
|
||||||
background: #2d3138;
|
|
||||||
border-bottom: 1px solid #1b1d22;
|
|
||||||
}
|
|
||||||
QTabBar::tab {
|
|
||||||
background: transparent;
|
|
||||||
color: #8d97a7;
|
|
||||||
padding: 8px 14px;
|
|
||||||
margin-right: 2px;
|
|
||||||
border-bottom: 2px solid transparent;
|
|
||||||
}
|
|
||||||
QTabBar::tab:selected {
|
|
||||||
color: #f2f5fa;
|
|
||||||
border-bottom: 2px solid #39b54a;
|
|
||||||
}
|
|
||||||
QTabBar::tab:hover {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
QFrame#ribbonBand {
|
|
||||||
background: #31353d;
|
|
||||||
border-top: 1px solid #3b4048;
|
|
||||||
}
|
|
||||||
QFrame#ribbonPage {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QFrame#ribbonGroup {
|
|
||||||
background: transparent;
|
|
||||||
border-right: 1px solid #434852;
|
|
||||||
}
|
|
||||||
QLabel#ribbonGroupLabel {
|
|
||||||
color: #7f8796;
|
|
||||||
font-size: 9px;
|
|
||||||
font-weight: 600;
|
|
||||||
letter-spacing: 0.08em;
|
|
||||||
}
|
|
||||||
QToolButton#ribbonButton {
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
padding: 6px 4px 4px 4px;
|
|
||||||
font-size: 11px;
|
|
||||||
color: #d6dce6;
|
|
||||||
}
|
|
||||||
QToolButton#ribbonButton:hover {
|
|
||||||
background: #3a3f48;
|
|
||||||
}
|
|
||||||
QToolButton#ribbonButton:pressed {
|
|
||||||
background: #24282f;
|
|
||||||
}
|
|
||||||
QFrame#viewportShell {
|
|
||||||
background: #202329;
|
|
||||||
border-top: 1px solid #1d2025;
|
|
||||||
}
|
|
||||||
QFrame#viewportFrame {
|
|
||||||
background: #1a1d22;
|
|
||||||
border: 1px solid #333942;
|
|
||||||
}
|
|
||||||
QDockWidget {
|
|
||||||
color: #d0d5dd;
|
|
||||||
}
|
|
||||||
QLabel#dockTitleText {
|
|
||||||
color: #dfe4ec;
|
|
||||||
font-size: 10px;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0.08em;
|
|
||||||
}
|
|
||||||
QToolButton#dockTitleButton {
|
|
||||||
color: #8e97a5;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QToolButton#dockTitleButton:hover {
|
|
||||||
color: #ffffff;
|
|
||||||
background: #353a42;
|
|
||||||
}
|
|
||||||
QFrame#panelFrame {
|
|
||||||
background: #2b2f36;
|
|
||||||
border: 1px solid #3e444e;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
QWidget#panelBody {
|
|
||||||
background: #2b2f36;
|
|
||||||
}
|
|
||||||
QTreeWidget, QListWidget, QTableWidget, QAbstractScrollArea {
|
|
||||||
background: #2b2f36;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
gridline-color: #333842;
|
|
||||||
}
|
|
||||||
QTreeWidget::viewport, QListWidget::viewport, QTableWidget::viewport {
|
|
||||||
background: #2b2f36;
|
|
||||||
}
|
|
||||||
QHeaderView::section {
|
|
||||||
background: #31353d;
|
|
||||||
color: #b5becc;
|
|
||||||
border: none;
|
|
||||||
border-bottom: 1px solid #434a55;
|
|
||||||
padding: 7px 8px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
QTableCornerButton::section {
|
|
||||||
background: #31353d;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
QScrollArea {
|
|
||||||
background: #2b2f36;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
QScrollArea > QWidget > QWidget {
|
|
||||||
background: #2b2f36;
|
|
||||||
}
|
|
||||||
QLineEdit {
|
|
||||||
background: #31353d;
|
|
||||||
border: 1px solid #434a55;
|
|
||||||
border-radius: 3px;
|
|
||||||
padding: 6px 8px;
|
|
||||||
color: #d9dfeb;
|
|
||||||
}
|
|
||||||
QLineEdit:focus {
|
|
||||||
border: 1px solid #5b6472;
|
|
||||||
}
|
|
||||||
QFrame#entityClassCard {
|
|
||||||
background: #26292f;
|
|
||||||
border: 1px solid #404650;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
QLabel#entityClassLabel {
|
|
||||||
color: #eef2f8;
|
|
||||||
font-weight: 700;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QLabel#entityTypeLabel {
|
|
||||||
color: #9aa4b3;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QWidget#attributeList {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QTreeView::item, QListView::item, QTableView::item {
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
QScrollBar:vertical {
|
|
||||||
background: transparent;
|
|
||||||
width: 10px;
|
|
||||||
margin: 2px 2px 2px 0;
|
|
||||||
}
|
|
||||||
QScrollBar:horizontal {
|
|
||||||
background: transparent;
|
|
||||||
height: 10px;
|
|
||||||
margin: 0 2px 2px 2px;
|
|
||||||
}
|
|
||||||
QScrollBar::handle:vertical, QScrollBar::handle:horizontal {
|
|
||||||
background: #525a67;
|
|
||||||
border-radius: 3px;
|
|
||||||
min-height: 24px;
|
|
||||||
min-width: 24px;
|
|
||||||
}
|
|
||||||
QScrollBar::handle:vertical:hover, QScrollBar::handle:horizontal:hover {
|
|
||||||
background: #697385;
|
|
||||||
}
|
|
||||||
QScrollBar::add-line, QScrollBar::sub-line,
|
|
||||||
QScrollBar::add-page, QScrollBar::sub-page {
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
QStatusBar {
|
|
||||||
background: #24272c;
|
|
||||||
border-top: 1px solid #1a1c20;
|
|
||||||
}
|
|
||||||
QStatusBar QLabel {
|
|
||||||
color: #97a1af;
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
padding: 2px 8px;
|
|
||||||
}
|
|
||||||
QGroupBox {
|
|
||||||
background: transparent;
|
|
||||||
border: 1px solid #404650;
|
|
||||||
border-radius: 3px;
|
|
||||||
margin-top: 10px;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
QGroupBox#propertySetCard {
|
|
||||||
background: #26292f;
|
|
||||||
border: 1px solid #404650;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
QGroupBox#propertySetCard::title {
|
|
||||||
subcontrol-origin: margin;
|
|
||||||
left: 10px;
|
|
||||||
padding: 0 4px;
|
|
||||||
color: #d5dbe5;
|
|
||||||
}
|
|
||||||
QGroupBox#propertySetCard > QWidget {
|
|
||||||
background: #26292f;
|
|
||||||
}
|
|
||||||
QWidget#panelSection {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QWidget#panelSectionFilterWrapper {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QWidget#relationshipRow {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QLabel#relationshipIconLabel {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QWidget#inspectorPanel {
|
|
||||||
background: #2b2f36;
|
|
||||||
}
|
|
||||||
QFrame#panelSectionHeader {
|
|
||||||
background: #26292f;
|
|
||||||
}
|
|
||||||
QToolButton#panelSectionHeaderButton {
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
color: #e1e7f0;
|
|
||||||
font-weight: 700;
|
|
||||||
text-align: left;
|
|
||||||
padding: 2px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
QToolButton#panelSectionHeaderButton:hover {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
QToolButton#panelSectionHeaderButton::menu-indicator {
|
|
||||||
image: none;
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
QToolButton#panelSectionFilterToggle {
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
QToolButton#panelSectionFilterToggle:hover {
|
|
||||||
background: #353a42;
|
|
||||||
}
|
|
||||||
QWidget#panelSectionBody {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QLabel#propertyKeyLabel {
|
|
||||||
color: #9aa4b3;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QLabel#propertyValueLabel {
|
|
||||||
color: #dce2eb;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QLabel#relationshipValueLabel {
|
|
||||||
color: #dce2eb;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QLabel#todoPanelTitle {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #e1e6ee;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
QLabel#todoPanelBody {
|
|
||||||
color: #8f98a6;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QToolButton* MainWindow::makeRibbonAction(const QString& text, const QString& icon_path) {
|
QToolButton* MainWindow::makeRibbonAction(const QString& text, const QString& icon_path) {
|
||||||
@@ -376,17 +106,13 @@ QWidget* MainWindow::makeRibbonGroup(const QString& title, const QList<QToolButt
|
|||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* MainWindow::makeComingSoonPanel(const QString& title) {
|
|
||||||
return new panels::todo::TodoPanelWidget(title, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::setStatusMessage(const QString& mode, const QString& detail) {
|
void MainWindow::setStatusMessage(const QString& mode, const QString& detail) {
|
||||||
status_mode_label_->setText(mode);
|
status_mode_label_->setText(mode);
|
||||||
status_selection_label_->setText(detail);
|
status_selection_label_->setText(detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
QToolButton* MainWindow::makePanelToggle(const QString& text, QDockWidget* dock) {
|
QToolButton* MainWindow::makePanelToggle(const QString& text, QDockWidget* dock) {
|
||||||
auto* button = makeRibbonAction(text, ":/icons/dm_toggle_openings.png");
|
auto* button = makeRibbonAction(text, ":/icons/sidebar-expand.svg");
|
||||||
button->setCheckable(true);
|
button->setCheckable(true);
|
||||||
button->setChecked(dock->isVisible());
|
button->setChecked(dock->isVisible());
|
||||||
connect(button, &QToolButton::toggled, dock, [dock](bool checked) {
|
connect(button, &QToolButton::toggled, dock, [dock](bool checked) {
|
||||||
@@ -565,19 +291,20 @@ QWidget* MainWindow::buildPanelsRibbonPage() {
|
|||||||
row->setSpacing(0);
|
row->setSpacing(0);
|
||||||
|
|
||||||
row->addWidget(makeRibbonGroup("DATA", {
|
row->addWidget(makeRibbonGroup("DATA", {
|
||||||
makePanelToggle("Models", models_dock_),
|
makePanelToggle("Models", models_panel_),
|
||||||
makePanelToggle("Spatial", spatial_dock_),
|
makePanelToggle("Spatial", spatial_panel_),
|
||||||
makePanelToggle("Layers", layers_dock_),
|
makePanelToggle("Layers", layers_panel_),
|
||||||
makePanelToggle("Properties", properties_dock_)
|
makePanelToggle("Properties", properties_panel_)
|
||||||
}));
|
}));
|
||||||
row->addWidget(makeRibbonGroup("QUERY", {
|
row->addWidget(makeRibbonGroup("QUERY", {
|
||||||
makePanelToggle("Views", stored_views_dock_),
|
makePanelToggle("Views", stored_views_panel_),
|
||||||
makePanelToggle("Search", search_dock_),
|
makePanelToggle("Search", search_panel_),
|
||||||
makePanelToggle("Sheets", spreadsheet_dock_)
|
makePanelToggle("Sheets", spreadsheet_panel_),
|
||||||
|
makePanelToggle("Audit", audit_panel_)
|
||||||
}));
|
}));
|
||||||
row->addWidget(makeRibbonGroup("COLLABORATE", {
|
row->addWidget(makeRibbonGroup("COLLABORATE", {
|
||||||
makePanelToggle("Clash", clash_dock_),
|
makePanelToggle("Clash", clash_panel_),
|
||||||
makePanelToggle("Issues", issues_dock_)
|
makePanelToggle("Issues", issues_panel_)
|
||||||
}));
|
}));
|
||||||
row->addStretch(1);
|
row->addStretch(1);
|
||||||
return page;
|
return page;
|
||||||
@@ -644,68 +371,67 @@ void MainWindow::setupViewport() {
|
|||||||
setCentralWidget(shell);
|
setCentralWidget(shell);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupDocks() {
|
void MainWindow::setupPanels() {
|
||||||
auto* models_panel = new panels::models::ModelsPanelWidget(this);
|
auto* models_widget = new panels::models::ModelsPanelWidget(this);
|
||||||
auto* spatial_panel = new panels::spatial_hierarchy::SpatialHierarchyPanelWidget(this);
|
auto* spatial_widget = new panels::spatial_hierarchy::SpatialHierarchyPanelWidget(this);
|
||||||
auto* properties_panel = new panels::properties::PropertiesPanelWidget(this);
|
auto* properties_widget = new panels::properties::PropertiesPanelWidget(this);
|
||||||
|
|
||||||
models_panel_view_ = new panels::models::ModelsPanelView(models_panel, this);
|
models_view_ = new panels::models::ModelsPanelView(models_widget, this);
|
||||||
spatial_panel_view_ = new panels::spatial_hierarchy::SpatialHierarchyPanelView(spatial_panel, this);
|
spatial_view_ = new panels::spatial_hierarchy::SpatialHierarchyPanelView(spatial_widget, this);
|
||||||
properties_panel_view_ = new panels::properties::PropertiesPanelView(properties_panel, this);
|
properties_view_ = new panels::properties::PropertiesPanelView(
|
||||||
|
properties_widget, viewport_, element_registry_, this);
|
||||||
|
|
||||||
connect(models_panel_view_, &panels::models::ModelsPanelView::statusMessageRequested,
|
connect(models_view_, &panels::models::ModelsPanelView::statusMessageRequested,
|
||||||
this, &MainWindow::setStatusMessage);
|
this, &MainWindow::setStatusMessage);
|
||||||
connect(spatial_panel_view_, &panels::spatial_hierarchy::SpatialHierarchyPanelView::statusMessageRequested,
|
connect(spatial_view_, &panels::spatial_hierarchy::SpatialHierarchyPanelView::statusMessageRequested,
|
||||||
this, &MainWindow::setStatusMessage);
|
this, &MainWindow::setStatusMessage);
|
||||||
|
|
||||||
models_dock_ = components::panel::makeDock(
|
models_panel_ = new components::Panel("Models", models_widget, this, true);
|
||||||
"Models", components::panel::wrapPanel(models_panel), this, true);
|
spatial_panel_ = new components::Panel("Spatial Hierarchy", spatial_widget, this);
|
||||||
spatial_dock_ = components::panel::makeDock(
|
properties_panel_ = new components::Panel("Properties", properties_widget, this);
|
||||||
"Spatial Hierarchy", components::panel::wrapPanel(spatial_panel), this);
|
layers_panel_ = new components::Panel("Layers", new panels::todo::TodoPanelWidget("Layers", this), this);
|
||||||
properties_dock_ = components::panel::makeDock(
|
stored_views_panel_ = new components::Panel(
|
||||||
"Properties", components::panel::wrapPanel(properties_panel), this);
|
"Stored Views", new panels::todo::TodoPanelWidget("Stored Views", this), this);
|
||||||
layers_dock_ = components::panel::makeDock(
|
search_panel_ = new components::Panel(
|
||||||
"Layers", components::panel::wrapPanel(makeComingSoonPanel("Layers")), this);
|
"Search and Query", new panels::todo::TodoPanelWidget("Search and Query", this), this);
|
||||||
stored_views_dock_ = components::panel::makeDock(
|
spreadsheet_panel_ = new components::Panel(
|
||||||
"Stored Views", components::panel::wrapPanel(makeComingSoonPanel("Stored Views")), this);
|
"Spreadsheet", new panels::todo::TodoPanelWidget("Spreadsheet", this), this);
|
||||||
search_dock_ = components::panel::makeDock(
|
audit_panel_ = new components::Panel("Audit", new panels::todo::TodoPanelWidget("Audit", this), this);
|
||||||
"Search and Query", components::panel::wrapPanel(makeComingSoonPanel("Search and Query")), this);
|
clash_panel_ = new components::Panel("Clash", new panels::todo::TodoPanelWidget("Clash", this), this);
|
||||||
spreadsheet_dock_ = components::panel::makeDock(
|
issues_panel_ = new components::Panel("Issues", new panels::todo::TodoPanelWidget("Issues", this), this);
|
||||||
"Spreadsheet", components::panel::wrapPanel(makeComingSoonPanel("Spreadsheet")), this);
|
|
||||||
clash_dock_ = components::panel::makeDock(
|
|
||||||
"Clash", components::panel::wrapPanel(makeComingSoonPanel("Clash")), this);
|
|
||||||
issues_dock_ = components::panel::makeDock(
|
|
||||||
"Issues", components::panel::wrapPanel(makeComingSoonPanel("Issues")), this);
|
|
||||||
|
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, models_dock_);
|
addDockWidget(Qt::LeftDockWidgetArea, models_panel_);
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, spatial_dock_);
|
addDockWidget(Qt::LeftDockWidgetArea, spatial_panel_);
|
||||||
splitDockWidget(models_dock_, spatial_dock_, Qt::Vertical);
|
splitDockWidget(models_panel_, spatial_panel_, Qt::Vertical);
|
||||||
|
|
||||||
addDockWidget(Qt::RightDockWidgetArea, properties_dock_);
|
addDockWidget(Qt::RightDockWidgetArea, properties_panel_);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, layers_dock_);
|
addDockWidget(Qt::RightDockWidgetArea, layers_panel_);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, stored_views_dock_);
|
addDockWidget(Qt::RightDockWidgetArea, stored_views_panel_);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, search_dock_);
|
addDockWidget(Qt::RightDockWidgetArea, search_panel_);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, spreadsheet_dock_);
|
addDockWidget(Qt::RightDockWidgetArea, spreadsheet_panel_);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, clash_dock_);
|
addDockWidget(Qt::RightDockWidgetArea, audit_panel_);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, issues_dock_);
|
addDockWidget(Qt::RightDockWidgetArea, clash_panel_);
|
||||||
|
addDockWidget(Qt::RightDockWidgetArea, issues_panel_);
|
||||||
|
|
||||||
tabifyDockWidget(properties_dock_, layers_dock_);
|
tabifyDockWidget(properties_panel_, layers_panel_);
|
||||||
tabifyDockWidget(layers_dock_, stored_views_dock_);
|
tabifyDockWidget(layers_panel_, stored_views_panel_);
|
||||||
tabifyDockWidget(stored_views_dock_, search_dock_);
|
tabifyDockWidget(stored_views_panel_, search_panel_);
|
||||||
tabifyDockWidget(search_dock_, spreadsheet_dock_);
|
tabifyDockWidget(search_panel_, spreadsheet_panel_);
|
||||||
tabifyDockWidget(spreadsheet_dock_, clash_dock_);
|
tabifyDockWidget(spreadsheet_panel_, audit_panel_);
|
||||||
tabifyDockWidget(clash_dock_, issues_dock_);
|
tabifyDockWidget(audit_panel_, clash_panel_);
|
||||||
properties_dock_->raise();
|
tabifyDockWidget(clash_panel_, issues_panel_);
|
||||||
|
properties_panel_->raise();
|
||||||
|
|
||||||
layers_dock_->hide();
|
layers_panel_->hide();
|
||||||
stored_views_dock_->hide();
|
stored_views_panel_->hide();
|
||||||
search_dock_->hide();
|
search_panel_->hide();
|
||||||
spreadsheet_dock_->hide();
|
spreadsheet_panel_->hide();
|
||||||
clash_dock_->hide();
|
audit_panel_->hide();
|
||||||
issues_dock_->hide();
|
clash_panel_->hide();
|
||||||
|
issues_panel_->hide();
|
||||||
|
|
||||||
resizeDocks({models_dock_, properties_dock_}, {290, 330}, Qt::Horizontal);
|
resizeDocks({models_panel_, properties_panel_}, {290, 330}, Qt::Horizontal);
|
||||||
resizeDocks({models_dock_, spatial_dock_}, {280, 240}, Qt::Vertical);
|
resizeDocks({models_panel_, spatial_panel_}, {280, 240}, Qt::Vertical);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupStatus() {
|
void MainWindow::setupStatus() {
|
||||||
@@ -728,6 +454,7 @@ void MainWindow::setupStatus() {
|
|||||||
void MainWindow::setupLoader() {
|
void MainWindow::setupLoader() {
|
||||||
AppSettings::instance().setLoadDataSource(false);
|
AppSettings::instance().setLoadDataSource(false);
|
||||||
loader_ = new SceneLoader(viewport_, this);
|
loader_ = new SceneLoader(viewport_, this);
|
||||||
|
element_registry_->bindLoader(loader_);
|
||||||
connect(loader_, &SceneLoader::loadStarted, this, &MainWindow::onLoadStarted);
|
connect(loader_, &SceneLoader::loadStarted, this, &MainWindow::onLoadStarted);
|
||||||
connect(loader_, &SceneLoader::loadedFromSidecar, this, &MainWindow::onLoadedFromSidecar);
|
connect(loader_, &SceneLoader::loadedFromSidecar, this, &MainWindow::onLoadedFromSidecar);
|
||||||
connect(loader_, &SceneLoader::loadedFromStream, this, &MainWindow::onLoadedFromStream);
|
connect(loader_, &SceneLoader::loadedFromStream, this, &MainWindow::onLoadedFromStream);
|
||||||
|
|||||||
+16
-14
@@ -31,6 +31,7 @@ class QTabBar;
|
|||||||
class QToolButton;
|
class QToolButton;
|
||||||
class ViewportWindow;
|
class ViewportWindow;
|
||||||
class SceneLoader;
|
class SceneLoader;
|
||||||
|
namespace ifcinterface { class ElementRegistry; }
|
||||||
namespace ifcinterface::panels::models { class ModelsPanelView; }
|
namespace ifcinterface::panels::models { class ModelsPanelView; }
|
||||||
namespace ifcinterface::panels::spatial_hierarchy { class SpatialHierarchyPanelView; }
|
namespace ifcinterface::panels::spatial_hierarchy { class SpatialHierarchyPanelView; }
|
||||||
namespace ifcinterface::panels::properties { class PropertiesPanelView; }
|
namespace ifcinterface::panels::properties { class PropertiesPanelView; }
|
||||||
@@ -46,7 +47,7 @@ private:
|
|||||||
void setupChrome();
|
void setupChrome();
|
||||||
void setupRibbon();
|
void setupRibbon();
|
||||||
void setupViewport();
|
void setupViewport();
|
||||||
void setupDocks();
|
void setupPanels();
|
||||||
void setupStatus();
|
void setupStatus();
|
||||||
void setupLoader();
|
void setupLoader();
|
||||||
QWidget* buildHomeRibbonPage();
|
QWidget* buildHomeRibbonPage();
|
||||||
@@ -55,7 +56,6 @@ private:
|
|||||||
QWidget* buildPanelsRibbonPage();
|
QWidget* buildPanelsRibbonPage();
|
||||||
QToolButton* makeRibbonAction(const QString& text, const QString& icon_path);
|
QToolButton* makeRibbonAction(const QString& text, const QString& icon_path);
|
||||||
QWidget* makeRibbonGroup(const QString& title, const QList<QToolButton*>& buttons);
|
QWidget* makeRibbonGroup(const QString& title, const QList<QToolButton*>& buttons);
|
||||||
QWidget* makeComingSoonPanel(const QString& title);
|
|
||||||
QToolButton* makePanelToggle(const QString& text, QDockWidget* dock);
|
QToolButton* makePanelToggle(const QString& text, QDockWidget* dock);
|
||||||
void setStatusMessage(const QString& mode, const QString& detail);
|
void setStatusMessage(const QString& mode, const QString& detail);
|
||||||
void addFiles(const QStringList& paths);
|
void addFiles(const QStringList& paths);
|
||||||
@@ -78,19 +78,21 @@ private:
|
|||||||
QStackedWidget* ribbon_pages_ = nullptr;
|
QStackedWidget* ribbon_pages_ = nullptr;
|
||||||
ViewportWindow* viewport_ = nullptr;
|
ViewportWindow* viewport_ = nullptr;
|
||||||
SceneLoader* loader_ = nullptr;
|
SceneLoader* loader_ = nullptr;
|
||||||
|
ifcinterface::ElementRegistry* element_registry_ = nullptr;
|
||||||
QWidget* viewport_container_ = nullptr;
|
QWidget* viewport_container_ = nullptr;
|
||||||
QDockWidget* models_dock_ = nullptr;
|
QDockWidget* models_panel_ = nullptr;
|
||||||
QDockWidget* spatial_dock_ = nullptr;
|
QDockWidget* spatial_panel_ = nullptr;
|
||||||
QDockWidget* layers_dock_ = nullptr;
|
QDockWidget* layers_panel_ = nullptr;
|
||||||
QDockWidget* properties_dock_ = nullptr;
|
QDockWidget* properties_panel_ = nullptr;
|
||||||
QDockWidget* stored_views_dock_ = nullptr;
|
QDockWidget* stored_views_panel_ = nullptr;
|
||||||
QDockWidget* search_dock_ = nullptr;
|
QDockWidget* search_panel_ = nullptr;
|
||||||
QDockWidget* spreadsheet_dock_ = nullptr;
|
QDockWidget* spreadsheet_panel_ = nullptr;
|
||||||
QDockWidget* clash_dock_ = nullptr;
|
QDockWidget* audit_panel_ = nullptr;
|
||||||
QDockWidget* issues_dock_ = nullptr;
|
QDockWidget* clash_panel_ = nullptr;
|
||||||
ifcinterface::panels::models::ModelsPanelView* models_panel_view_ = nullptr;
|
QDockWidget* issues_panel_ = nullptr;
|
||||||
ifcinterface::panels::spatial_hierarchy::SpatialHierarchyPanelView* spatial_panel_view_ = nullptr;
|
ifcinterface::panels::models::ModelsPanelView* models_view_ = nullptr;
|
||||||
ifcinterface::panels::properties::PropertiesPanelView* properties_panel_view_ = nullptr;
|
ifcinterface::panels::spatial_hierarchy::SpatialHierarchyPanelView* spatial_view_ = nullptr;
|
||||||
|
ifcinterface::panels::properties::PropertiesPanelView* properties_view_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ifcinterface::shell
|
} // namespace ifcinterface::shell
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// 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 "KeyValueTable.h"
|
||||||
|
|
||||||
|
#include "SvgIcon.h"
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
namespace ifcinterface::components {
|
||||||
|
|
||||||
|
KeyValueTable::KeyValueTable(const QList<KeyValueTableRow>& rows, QWidget* parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
setObjectName("attributeList");
|
||||||
|
|
||||||
|
auto* layout = new QVBoxLayout(this);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->setSpacing(6);
|
||||||
|
|
||||||
|
for (const auto& row_data : rows) {
|
||||||
|
auto* row = new QWidget(this);
|
||||||
|
if (!row_data.trailing_icon_path.isEmpty()) {
|
||||||
|
row->setObjectName("relationshipRow");
|
||||||
|
} else {
|
||||||
|
row->setObjectName("keyValueRow");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* row_layout = new QHBoxLayout(row);
|
||||||
|
row_layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
row_layout->setSpacing(12);
|
||||||
|
|
||||||
|
auto* key = new QLabel(row_data.key, row);
|
||||||
|
key->setObjectName("propertyKeyLabel");
|
||||||
|
if (row_data.key_minimum_width > 0) {
|
||||||
|
key->setMinimumWidth(row_data.key_minimum_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* value = new QLabel(row_data.value, row);
|
||||||
|
value->setObjectName(row_data.value_object_name.isEmpty()
|
||||||
|
? "propertyValueLabel"
|
||||||
|
: row_data.value_object_name);
|
||||||
|
value->setWordWrap(true);
|
||||||
|
value->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
row_layout->addWidget(key);
|
||||||
|
row_layout->addWidget(value, 1);
|
||||||
|
|
||||||
|
if (!row_data.trailing_icon_path.isEmpty()) {
|
||||||
|
auto* icon = new QLabel(row);
|
||||||
|
icon->setObjectName(row_data.trailing_icon_object_name.isEmpty()
|
||||||
|
? "relationshipIconLabel"
|
||||||
|
: row_data.trailing_icon_object_name);
|
||||||
|
icon->setPixmap(icons::makePanelSvgPixmap(row_data.trailing_icon_path, QSize(14, 14)));
|
||||||
|
icon->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||||
|
row_layout->addWidget(icon, 0, Qt::AlignRight | Qt::AlignVCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
layout->addWidget(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ifcinterface::components
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
// 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_COMPONENTS_KEYVALUETABLE_H
|
||||||
|
#define IFCINTERFACE_COMPONENTS_KEYVALUETABLE_H
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QString>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace ifcinterface::components {
|
||||||
|
|
||||||
|
struct KeyValueTableRow {
|
||||||
|
QString key;
|
||||||
|
QString value;
|
||||||
|
QString value_object_name = "propertyValueLabel";
|
||||||
|
QString trailing_icon_path;
|
||||||
|
QString trailing_icon_object_name;
|
||||||
|
int key_minimum_width = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class KeyValueTable : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit KeyValueTable(const QList<KeyValueTableRow>& rows, QWidget* parent = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ifcinterface::components
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -18,8 +18,9 @@
|
|||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#include "PanelChrome.h"
|
#include "Panel.h"
|
||||||
|
|
||||||
|
#include "Style.h"
|
||||||
#include "SvgIcon.h"
|
#include "SvgIcon.h"
|
||||||
|
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
@@ -30,7 +31,7 @@
|
|||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
namespace ifcinterface::components::panel {
|
namespace ifcinterface::components {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -69,32 +70,31 @@ public:
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
QDockWidget* makeDock(const QString& title, QWidget* content, QWidget* parent, bool has_settings) {
|
Panel::Panel(const QString& title, QWidget* content, QWidget* parent, bool has_settings)
|
||||||
auto* dock = new QDockWidget(title, parent);
|
: QDockWidget(title, parent)
|
||||||
dock->setObjectName(title);
|
{
|
||||||
dock->setFeatures(QDockWidget::DockWidgetMovable |
|
|
||||||
QDockWidget::DockWidgetFloatable |
|
|
||||||
QDockWidget::DockWidgetClosable);
|
|
||||||
dock->setTitleBarWidget(new DockTitleBar(title, has_settings, dock));
|
|
||||||
dock->setWidget(content);
|
|
||||||
return dock;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFrame* wrapPanel(QWidget* inner) {
|
|
||||||
auto* outer = new QFrame();
|
auto* outer = new QFrame();
|
||||||
auto* outer_layout = new QVBoxLayout(outer);
|
auto* outer_layout = new QVBoxLayout(outer);
|
||||||
outer_layout->setContentsMargins(6, 6, 6, 6);
|
outer_layout->setContentsMargins(style::metrics::padding,
|
||||||
|
style::metrics::padding,
|
||||||
|
style::metrics::padding,
|
||||||
|
style::metrics::padding);
|
||||||
outer_layout->setSpacing(0);
|
outer_layout->setSpacing(0);
|
||||||
|
|
||||||
auto* frame = new QFrame(outer);
|
auto* frame = new QFrame(outer);
|
||||||
frame->setObjectName("panelFrame");
|
frame->setObjectName("panel");
|
||||||
auto* layout = new QVBoxLayout(frame);
|
auto* frame_layout = new QVBoxLayout(frame);
|
||||||
layout->setContentsMargins(0, 8, 0, 8);
|
frame_layout->setContentsMargins(0, style::metrics::padding, 0, style::metrics::padding);
|
||||||
layout->setSpacing(0);
|
frame_layout->setSpacing(0);
|
||||||
layout->addWidget(inner);
|
frame_layout->addWidget(content);
|
||||||
|
|
||||||
outer_layout->addWidget(frame);
|
outer_layout->addWidget(frame);
|
||||||
return outer;
|
|
||||||
|
setObjectName(title);
|
||||||
|
setFeatures(QDockWidget::DockWidgetMovable |
|
||||||
|
QDockWidget::DockWidgetFloatable |
|
||||||
|
QDockWidget::DockWidgetClosable);
|
||||||
|
setTitleBarWidget(new DockTitleBar(title, has_settings, this));
|
||||||
|
setWidget(outer);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ifcinterface::components::panel
|
} // namespace ifcinterface::components
|
||||||
@@ -21,17 +21,19 @@
|
|||||||
#ifndef IFCINTERFACE_COMPONENTS_PANEL_PANELCHROME_H
|
#ifndef IFCINTERFACE_COMPONENTS_PANEL_PANELCHROME_H
|
||||||
#define IFCINTERFACE_COMPONENTS_PANEL_PANELCHROME_H
|
#define IFCINTERFACE_COMPONENTS_PANEL_PANELCHROME_H
|
||||||
|
|
||||||
#include <QString>
|
#include <QDockWidget>
|
||||||
|
|
||||||
class QDockWidget;
|
|
||||||
class QFrame;
|
|
||||||
class QWidget;
|
class QWidget;
|
||||||
|
|
||||||
namespace ifcinterface::components::panel {
|
namespace ifcinterface::components {
|
||||||
|
|
||||||
QDockWidget* makeDock(const QString& title, QWidget* content, QWidget* parent, bool has_settings = false);
|
class Panel : public QDockWidget {
|
||||||
QFrame* wrapPanel(QWidget* inner);
|
Q_OBJECT
|
||||||
|
|
||||||
} // namespace ifcinterface::components::panel
|
public:
|
||||||
|
explicit Panel(const QString& title, QWidget* content, QWidget* parent = nullptr, bool has_settings = false);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ifcinterface::components
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "Section.h"
|
#include "Section.h"
|
||||||
|
|
||||||
|
#include "Style.h"
|
||||||
#include "SvgIcon.h"
|
#include "SvgIcon.h"
|
||||||
|
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
@@ -49,14 +50,14 @@ Section::Section(const QString& title, SectionHeaderMode header_mode,
|
|||||||
setObjectName("panelSection");
|
setObjectName("panelSection");
|
||||||
auto* layout = new QVBoxLayout(this);
|
auto* layout = new QVBoxLayout(this);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
layout->setSpacing(6);
|
layout->setSpacing(style::metrics::section_spacing);
|
||||||
|
|
||||||
if (header_mode == SectionHeaderMode::Visible) {
|
if (header_mode == SectionHeaderMode::Visible) {
|
||||||
auto* header = new QFrame(this);
|
auto* header = new QFrame(this);
|
||||||
header->setObjectName("panelSectionHeader");
|
header->setObjectName("panelSectionHeader");
|
||||||
auto* header_layout = new QHBoxLayout(header);
|
auto* header_layout = new QHBoxLayout(header);
|
||||||
header_layout->setContentsMargins(0, 0, 0, 0);
|
header_layout->setContentsMargins(0, 0, 0, 0);
|
||||||
header_layout->setSpacing(6);
|
header_layout->setSpacing(style::metrics::section_spacing);
|
||||||
|
|
||||||
auto* toggle = new QToolButton(header);
|
auto* toggle = new QToolButton(header);
|
||||||
toggle->setObjectName("panelSectionHeaderButton");
|
toggle->setObjectName("panelSectionHeaderButton");
|
||||||
@@ -89,7 +90,8 @@ Section::Section(const QString& title, SectionHeaderMode header_mode,
|
|||||||
auto* filter_wrapper = new QWidget(this);
|
auto* filter_wrapper = new QWidget(this);
|
||||||
filter_wrapper->setObjectName("panelSectionFilterWrapper");
|
filter_wrapper->setObjectName("panelSectionFilterWrapper");
|
||||||
auto* filter_wrapper_layout = new QVBoxLayout(filter_wrapper);
|
auto* filter_wrapper_layout = new QVBoxLayout(filter_wrapper);
|
||||||
filter_wrapper_layout->setContentsMargins(10, 0, 10, 0);
|
filter_wrapper_layout->setContentsMargins(style::metrics::filter_body_padding_x, 0,
|
||||||
|
style::metrics::filter_body_padding_x, 0);
|
||||||
filter_wrapper_layout->setSpacing(0);
|
filter_wrapper_layout->setSpacing(0);
|
||||||
filter_wrapper_layout->addWidget(filter_field_);
|
filter_wrapper_layout->addWidget(filter_field_);
|
||||||
layout->addWidget(filter_wrapper);
|
layout->addWidget(filter_wrapper);
|
||||||
@@ -108,7 +110,8 @@ Section::Section(const QString& title, SectionHeaderMode header_mode,
|
|||||||
auto* filter_wrapper = new QWidget(this);
|
auto* filter_wrapper = new QWidget(this);
|
||||||
filter_wrapper->setObjectName("panelSectionFilterWrapper");
|
filter_wrapper->setObjectName("panelSectionFilterWrapper");
|
||||||
auto* filter_wrapper_layout = new QVBoxLayout(filter_wrapper);
|
auto* filter_wrapper_layout = new QVBoxLayout(filter_wrapper);
|
||||||
filter_wrapper_layout->setContentsMargins(8, 0, 8, 0);
|
filter_wrapper_layout->setContentsMargins(style::metrics::hidden_filter_body_padding_x, 0,
|
||||||
|
style::metrics::hidden_filter_body_padding_x, 0);
|
||||||
filter_wrapper_layout->setSpacing(0);
|
filter_wrapper_layout->setSpacing(0);
|
||||||
filter_wrapper_layout->addWidget(filter_field_);
|
filter_wrapper_layout->addWidget(filter_field_);
|
||||||
layout->addWidget(filter_wrapper);
|
layout->addWidget(filter_wrapper);
|
||||||
@@ -118,11 +121,14 @@ Section::Section(const QString& title, SectionHeaderMode header_mode,
|
|||||||
body_->setObjectName("panelSectionBody");
|
body_->setObjectName("panelSectionBody");
|
||||||
body_layout_ = new QVBoxLayout(body_);
|
body_layout_ = new QVBoxLayout(body_);
|
||||||
if (header_mode == SectionHeaderMode::Visible) {
|
if (header_mode == SectionHeaderMode::Visible) {
|
||||||
body_layout_->setContentsMargins(10, 6, 10, 0);
|
body_layout_->setContentsMargins(style::metrics::section_body_padding_x,
|
||||||
|
style::metrics::section_body_padding_top,
|
||||||
|
style::metrics::section_body_padding_x, 0);
|
||||||
} else {
|
} else {
|
||||||
body_layout_->setContentsMargins(8, 0, 8, 0);
|
body_layout_->setContentsMargins(style::metrics::hidden_section_body_padding_x, 0,
|
||||||
|
style::metrics::hidden_section_body_padding_x, 0);
|
||||||
}
|
}
|
||||||
body_layout_->setSpacing(6);
|
body_layout_->setSpacing(style::metrics::section_spacing);
|
||||||
layout->addWidget(body_);
|
layout->addWidget(body_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,303 @@
|
|||||||
|
// 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 "Style.h"
|
||||||
|
|
||||||
|
namespace ifcinterface::components::style {
|
||||||
|
|
||||||
|
QString buildAppStyleSheet() {
|
||||||
|
return QString(R"(
|
||||||
|
QMainWindow {
|
||||||
|
background: #26292f;
|
||||||
|
}
|
||||||
|
QWidget {
|
||||||
|
color: #d0d5dd;
|
||||||
|
background: #26292f;
|
||||||
|
selection-background-color: #39b54a;
|
||||||
|
selection-color: #14161a;
|
||||||
|
}
|
||||||
|
QFrame#ribbonShell {
|
||||||
|
background: #2d3138;
|
||||||
|
border-bottom: 1px solid #1b1d22;
|
||||||
|
}
|
||||||
|
QTabBar::tab {
|
||||||
|
background: transparent;
|
||||||
|
color: #8d97a7;
|
||||||
|
padding: 8px 14px;
|
||||||
|
margin-right: 2px;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
}
|
||||||
|
QTabBar::tab:selected {
|
||||||
|
color: #f2f5fa;
|
||||||
|
border-bottom: 2px solid #39b54a;
|
||||||
|
}
|
||||||
|
QTabBar::tab:hover {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
QFrame#ribbonBand {
|
||||||
|
background: #31353d;
|
||||||
|
border-top: 1px solid #3b4048;
|
||||||
|
}
|
||||||
|
QFrame#ribbonPage {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QFrame#ribbonGroup {
|
||||||
|
background: transparent;
|
||||||
|
border-right: 1px solid #434852;
|
||||||
|
}
|
||||||
|
QLabel#ribbonGroupLabel {
|
||||||
|
color: #7f8796;
|
||||||
|
font-size: 9px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
}
|
||||||
|
QToolButton#ribbonButton {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 6px 4px 4px 4px;
|
||||||
|
font-size: 11px;
|
||||||
|
color: #d6dce6;
|
||||||
|
}
|
||||||
|
QToolButton#ribbonButton:hover {
|
||||||
|
background: #3a3f48;
|
||||||
|
}
|
||||||
|
QToolButton#ribbonButton:pressed {
|
||||||
|
background: #24282f;
|
||||||
|
}
|
||||||
|
QFrame#viewportShell {
|
||||||
|
background: #202329;
|
||||||
|
border-top: 1px solid #1d2025;
|
||||||
|
}
|
||||||
|
QFrame#viewportFrame {
|
||||||
|
background: #1a1d22;
|
||||||
|
border: 1px solid #333942;
|
||||||
|
}
|
||||||
|
QDockWidget {
|
||||||
|
color: #d0d5dd;
|
||||||
|
}
|
||||||
|
QLabel#dockTitleText {
|
||||||
|
color: #dfe4ec;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
}
|
||||||
|
QToolButton#dockTitleButton {
|
||||||
|
color: #8e97a5;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QToolButton#dockTitleButton:hover {
|
||||||
|
color: #ffffff;
|
||||||
|
background: #353a42;
|
||||||
|
}
|
||||||
|
QFrame#panel {
|
||||||
|
background: #2b2f36;
|
||||||
|
border: 1px solid #3e444e;
|
||||||
|
border-radius: %1px;
|
||||||
|
}
|
||||||
|
QTreeWidget, QListWidget, QTableWidget, QAbstractScrollArea {
|
||||||
|
background: #2b2f36;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
gridline-color: #333842;
|
||||||
|
}
|
||||||
|
QTreeWidget::viewport, QListWidget::viewport, QTableWidget::viewport {
|
||||||
|
background: #2b2f36;
|
||||||
|
}
|
||||||
|
QHeaderView::section {
|
||||||
|
background: #31353d;
|
||||||
|
color: #b5becc;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid #434a55;
|
||||||
|
padding: 7px 8px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
QTableCornerButton::section {
|
||||||
|
background: #31353d;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
QScrollArea {
|
||||||
|
background: #2b2f36;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
QScrollArea > QWidget > QWidget {
|
||||||
|
background: #2b2f36;
|
||||||
|
}
|
||||||
|
QLineEdit {
|
||||||
|
background: #31353d;
|
||||||
|
border: 1px solid #434a55;
|
||||||
|
border-radius: %1px;
|
||||||
|
padding: %2px %3px;
|
||||||
|
color: #d9dfeb;
|
||||||
|
}
|
||||||
|
QLineEdit:focus {
|
||||||
|
border: 1px solid #5b6472;
|
||||||
|
}
|
||||||
|
QFrame#entityClassCard {
|
||||||
|
background: #26292f;
|
||||||
|
border: 1px solid #404650;
|
||||||
|
border-radius: %1px;
|
||||||
|
}
|
||||||
|
QLabel#entityClassLabel {
|
||||||
|
color: #eef2f8;
|
||||||
|
font-weight: 700;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QLabel#entityTypeLabel {
|
||||||
|
color: #9aa4b3;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QWidget#attributeList {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QTreeView::item, QListView::item, QTableView::item {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
QScrollBar:vertical {
|
||||||
|
background: transparent;
|
||||||
|
width: 10px;
|
||||||
|
margin: 2px 2px 2px 0;
|
||||||
|
}
|
||||||
|
QScrollBar:horizontal {
|
||||||
|
background: transparent;
|
||||||
|
height: 10px;
|
||||||
|
margin: 0 2px 2px 2px;
|
||||||
|
}
|
||||||
|
QScrollBar::handle:vertical, QScrollBar::handle:horizontal {
|
||||||
|
background: #525a67;
|
||||||
|
border-radius: %1px;
|
||||||
|
min-height: 24px;
|
||||||
|
min-width: 24px;
|
||||||
|
}
|
||||||
|
QScrollBar::handle:vertical:hover, QScrollBar::handle:horizontal:hover {
|
||||||
|
background: #697385;
|
||||||
|
}
|
||||||
|
QScrollBar::add-line, QScrollBar::sub-line,
|
||||||
|
QScrollBar::add-page, QScrollBar::sub-page {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
QStatusBar {
|
||||||
|
background: #24272c;
|
||||||
|
border-top: 1px solid #1a1c20;
|
||||||
|
}
|
||||||
|
QStatusBar QLabel {
|
||||||
|
color: #97a1af;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 2px 8px;
|
||||||
|
}
|
||||||
|
QGroupBox {
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid #404650;
|
||||||
|
border-radius: %1px;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
QGroupBox#propertySetCard {
|
||||||
|
background: #26292f;
|
||||||
|
border: 1px solid #404650;
|
||||||
|
border-radius: %1px;
|
||||||
|
}
|
||||||
|
QGroupBox#propertySetCard::title {
|
||||||
|
subcontrol-origin: margin;
|
||||||
|
left: %4px;
|
||||||
|
padding: 0 4px;
|
||||||
|
color: #d5dbe5;
|
||||||
|
}
|
||||||
|
QGroupBox#propertySetCard > QWidget {
|
||||||
|
background: #26292f;
|
||||||
|
}
|
||||||
|
QWidget#panelSection {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QWidget#panelSectionFilterWrapper {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QWidget#relationshipRow {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QLabel#relationshipIconLabel {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QWidget#inspectorPanel {
|
||||||
|
background: #2b2f36;
|
||||||
|
}
|
||||||
|
QFrame#panelSectionHeader {
|
||||||
|
background: #26292f;
|
||||||
|
}
|
||||||
|
QToolButton#panelSectionHeaderButton {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #e1e7f0;
|
||||||
|
font-weight: 700;
|
||||||
|
text-align: left;
|
||||||
|
padding: %5px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
QToolButton#panelSectionHeaderButton:hover {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
QToolButton#panelSectionHeaderButton::menu-indicator {
|
||||||
|
image: none;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
QToolButton#panelSectionFilterToggle {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: %5px;
|
||||||
|
}
|
||||||
|
QToolButton#panelSectionFilterToggle:hover {
|
||||||
|
background: #353a42;
|
||||||
|
}
|
||||||
|
QWidget#panelSectionBody {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QLabel#propertyKeyLabel {
|
||||||
|
color: #9aa4b3;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QLabel#propertyValueLabel {
|
||||||
|
color: #dce2eb;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QLabel#relationshipValueLabel {
|
||||||
|
color: #dce2eb;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QLabel#todoPanelTitle {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #e1e6ee;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
QLabel#todoPanelBody {
|
||||||
|
color: #8f98a6;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
)")
|
||||||
|
.arg(metrics::panel_radius)
|
||||||
|
.arg(metrics::control_padding_y)
|
||||||
|
.arg(metrics::control_padding_x)
|
||||||
|
.arg(metrics::card_padding)
|
||||||
|
.arg(metrics::section_header_padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ifcinterface::components::style
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
// 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_COMPONENTS_STYLE_H
|
||||||
|
#define IFCINTERFACE_COMPONENTS_STYLE_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace ifcinterface::components::style::metrics {
|
||||||
|
|
||||||
|
inline constexpr int padding = 6;
|
||||||
|
inline constexpr int section_spacing = 6;
|
||||||
|
inline constexpr int section_body_padding_x = 10;
|
||||||
|
inline constexpr int section_body_padding_top = 6;
|
||||||
|
inline constexpr int hidden_section_body_padding_x = 8;
|
||||||
|
inline constexpr int section_header_padding = 2;
|
||||||
|
inline constexpr int filter_body_padding_x = 10;
|
||||||
|
inline constexpr int hidden_filter_body_padding_x = 8;
|
||||||
|
inline constexpr int card_padding = 10;
|
||||||
|
inline constexpr int control_padding_y = 6;
|
||||||
|
inline constexpr int control_padding_x = 8;
|
||||||
|
inline constexpr int panel_radius = 3;
|
||||||
|
|
||||||
|
} // namespace ifcinterface::components::style::metrics
|
||||||
|
|
||||||
|
namespace ifcinterface::components::style {
|
||||||
|
|
||||||
|
QString buildAppStyleSheet();
|
||||||
|
|
||||||
|
} // namespace ifcinterface::components::style
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<svg width="24" stroke-width="1.5" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M19 21L5 21C3.89543 21 3 20.1046 3 19L3 5C3 3.89543 3.89543 3 5 3L19 3C20.1046 3 21 3.89543 21 5L21 19C21 20.1046 20.1046 21 19 21Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M9.5 21V3" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M5.5 10L7.25 12L5.5 14" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 533 B |
@@ -4,21 +4,6 @@
|
|||||||
<file alias="DMSans-VariableFont_opsz,wght.ttf">../ifctester/webapp/public/fonts/dmsans/DMSans-VariableFont_opsz,wght.ttf</file>
|
<file alias="DMSans-VariableFont_opsz,wght.ttf">../ifctester/webapp/public/fonts/dmsans/DMSans-VariableFont_opsz,wght.ttf</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/icons">
|
<qresource prefix="/icons">
|
||||||
<file alias="IFC.png">../bonsai/bonsai/bim/data/icons/IFC.png</file>
|
|
||||||
<file alias="dm_add.png">../bonsai/bonsai/bim/data/icons/dm_add.png</file>
|
|
||||||
<file alias="dm_add_type.png">../bonsai/bonsai/bim/data/icons/dm_add_type.png</file>
|
|
||||||
<file alias="dm_assign.png">../bonsai/bonsai/bim/data/icons/dm_assign.png</file>
|
|
||||||
<file alias="dm_centerline.png">../bonsai/bonsai/bim/data/icons/dm_centerline.png</file>
|
|
||||||
<file alias="dm_connect_mep_elements.png">../bonsai/bonsai/bim/data/icons/dm_connect_mep_elements.png</file>
|
|
||||||
<file alias="dm_decomposition.png">../bonsai/bonsai/bim/data/icons/dm_decomposition.png</file>
|
|
||||||
<file alias="dm_edit_profile.png">../bonsai/bonsai/bim/data/icons/dm_edit_profile.png</file>
|
|
||||||
<file alias="dm_ifc.png">../bonsai/bonsai/bim/data/icons/dm_ifc.png</file>
|
|
||||||
<file alias="dm_perform_quantity_take-off.png">../bonsai/bonsai/bim/data/icons/dm_perform_quantity_take-off.png</file>
|
|
||||||
<file alias="dm_rectangle.png">../bonsai/bonsai/bim/data/icons/dm_rectangle.png</file>
|
|
||||||
<file alias="dm_refresh.png">../bonsai/bonsai/bim/data/icons/dm_refresh.png</file>
|
|
||||||
<file alias="dm_rotate_90.png">../bonsai/bonsai/bim/data/icons/dm_rotate_90.png</file>
|
|
||||||
<file alias="dm_split.png">../bonsai/bonsai/bim/data/icons/dm_split.png</file>
|
|
||||||
<file alias="dm_toggle_openings.png">../bonsai/bonsai/bim/data/icons/dm_toggle_openings.png</file>
|
|
||||||
<file alias="plus-square.svg">icons/plus-square.svg</file>
|
<file alias="plus-square.svg">icons/plus-square.svg</file>
|
||||||
<file alias="download-square.svg">icons/download-square.svg</file>
|
<file alias="download-square.svg">icons/download-square.svg</file>
|
||||||
<file alias="cloud-square.svg">icons/cloud-square.svg</file>
|
<file alias="cloud-square.svg">icons/cloud-square.svg</file>
|
||||||
@@ -55,5 +40,6 @@
|
|||||||
<file alias="filter.svg">icons/filter.svg</file>
|
<file alias="filter.svg">icons/filter.svg</file>
|
||||||
<file alias="cube-dots.svg">icons/cube-dots.svg</file>
|
<file alias="cube-dots.svg">icons/cube-dots.svg</file>
|
||||||
<file alias="cursor-pointer.svg">icons/cursor-pointer.svg</file>
|
<file alias="cursor-pointer.svg">icons/cursor-pointer.svg</file>
|
||||||
|
<file alias="sidebar-expand.svg">icons/sidebar-expand.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@@ -22,22 +22,36 @@
|
|||||||
|
|
||||||
#include "PropertiesPanelWidget.h"
|
#include "PropertiesPanelWidget.h"
|
||||||
|
|
||||||
|
#include "../../ElementRegistry.h"
|
||||||
|
#include "../../../ifcviewer/ViewportWindow.h"
|
||||||
|
|
||||||
namespace ifcinterface::panels::properties {
|
namespace ifcinterface::panels::properties {
|
||||||
|
|
||||||
PropertiesPanelView::PropertiesPanelView(PropertiesPanelWidget* widget, QObject* parent)
|
PropertiesPanelView::PropertiesPanelView(PropertiesPanelWidget* widget,
|
||||||
: QObject(parent), widget_(widget)
|
ViewportWindow* viewport,
|
||||||
|
ifcinterface::ElementRegistry* registry,
|
||||||
|
QObject* parent)
|
||||||
|
: QObject(parent), widget_(widget), registry_(registry)
|
||||||
{
|
{
|
||||||
state_.entity = {"IfcWall", "SOLIDWALL"};
|
connect(viewport, &ViewportWindow::objectPicked, this, [this](uint32_t object_id) {
|
||||||
state_.attributes = {
|
refresh(object_id);
|
||||||
|
});
|
||||||
|
refresh(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertiesPanelView::refresh(uint32_t object_id) {
|
||||||
|
PropertiesPanelState state;
|
||||||
|
state.entity = {"IfcWall", "SOLIDWALL"};
|
||||||
|
state.attributes = {
|
||||||
{"GlobalId", "2Q$n5SLPP9Q8B7wQKjKfUQ"},
|
{"GlobalId", "2Q$n5SLPP9Q8B7wQKjKfUQ"},
|
||||||
{"Name", "Core-EXT-204"},
|
{"Name", "Core-EXT-204"},
|
||||||
{"Description", "External load-bearing wall"},
|
{"Description", "External load-bearing wall"},
|
||||||
};
|
};
|
||||||
state_.relationships = {
|
state.relationships = {
|
||||||
{"Type", "Basic Wall: Exterior - 200mm"},
|
{"Type", "Basic Wall: Exterior - 200mm"},
|
||||||
{"Container", "Level 02"},
|
{"Container", "Level 02"},
|
||||||
};
|
};
|
||||||
state_.property_sets = {
|
state.property_sets = {
|
||||||
{"Pset_WallCommon",
|
{"Pset_WallCommon",
|
||||||
{{"Reference", "Core-EXT-204"},
|
{{"Reference", "Core-EXT-204"},
|
||||||
{"Status", "Reviewed"},
|
{"Status", "Reviewed"},
|
||||||
@@ -53,7 +67,7 @@ PropertiesPanelView::PropertiesPanelView(PropertiesPanelWidget* widget, QObject*
|
|||||||
{"Last Review", "2026-04-30"},
|
{"Last Review", "2026-04-30"},
|
||||||
{"Assigned To", "Design Coordination"}}},
|
{"Assigned To", "Design Coordination"}}},
|
||||||
};
|
};
|
||||||
state_.quantity_sets = {
|
state.quantity_sets = {
|
||||||
{"BaseQuantities",
|
{"BaseQuantities",
|
||||||
{{"Length", "6.20 m"},
|
{{"Length", "6.20 m"},
|
||||||
{"Height", "3.45 m"},
|
{"Height", "3.45 m"},
|
||||||
@@ -65,7 +79,25 @@ PropertiesPanelView::PropertiesPanelView(PropertiesPanelWidget* widget, QObject*
|
|||||||
{"Paint Coverage", "42.78 m2"}}},
|
{"Paint Coverage", "42.78 m2"}}},
|
||||||
};
|
};
|
||||||
|
|
||||||
widget_->setState(state_);
|
if (registry_) {
|
||||||
|
auto info = registry_->find(object_id);
|
||||||
|
if (info && !info->type.isEmpty()) {
|
||||||
|
state.entity.entity_class = info->type;
|
||||||
|
if (!state.property_sets.isEmpty() && !state.property_sets[1].rows.isEmpty()) {
|
||||||
|
state.property_sets[1].rows[0].value = info->type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (info && !info->name.isEmpty()) {
|
||||||
|
state.attributes[1].value = info->name;
|
||||||
|
if (state.property_sets.size() > 1 && state.property_sets[1].rows.size() > 1) {
|
||||||
|
state.property_sets[1].rows[1].value = info->name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (info && !info->guid.isEmpty()) {
|
||||||
|
state.attributes[0].value = info->guid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
widget_->render(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ifcinterface::panels::properties
|
} // namespace ifcinterface::panels::properties
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace ifcinterface { class ElementRegistry; }
|
||||||
|
class ViewportWindow;
|
||||||
namespace ifcinterface::panels::properties {
|
namespace ifcinterface::panels::properties {
|
||||||
|
|
||||||
class PropertiesPanelWidget;
|
class PropertiesPanelWidget;
|
||||||
@@ -32,11 +34,16 @@ class PropertiesPanelWidget;
|
|||||||
class PropertiesPanelView : public QObject {
|
class PropertiesPanelView : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit PropertiesPanelView(PropertiesPanelWidget* widget, QObject* parent = nullptr);
|
explicit PropertiesPanelView(PropertiesPanelWidget* widget,
|
||||||
|
ViewportWindow* viewport,
|
||||||
|
ifcinterface::ElementRegistry* registry,
|
||||||
|
QObject* parent = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void refresh(uint32_t object_id);
|
||||||
|
|
||||||
PropertiesPanelWidget* widget_ = nullptr;
|
PropertiesPanelWidget* widget_ = nullptr;
|
||||||
PropertiesPanelState state_;
|
ifcinterface::ElementRegistry* registry_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ifcinterface::panels::properties
|
} // namespace ifcinterface::panels::properties
|
||||||
|
|||||||
@@ -20,10 +20,10 @@
|
|||||||
|
|
||||||
#include "PropertiesPanelWidget.h"
|
#include "PropertiesPanelWidget.h"
|
||||||
|
|
||||||
|
#include "../../components/KeyValueTable.h"
|
||||||
#include "../../components/Section.h"
|
#include "../../components/Section.h"
|
||||||
#include "../../components/SvgIcon.h"
|
#include "../../components/SvgIcon.h"
|
||||||
|
|
||||||
#include <QFormLayout>
|
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
@@ -36,79 +36,37 @@ namespace {
|
|||||||
QWidget* makePropertySetPanel(const ifcinterface::panels::properties::PropertySet& property_set, QWidget* parent = nullptr) {
|
QWidget* makePropertySetPanel(const ifcinterface::panels::properties::PropertySet& property_set, QWidget* parent = nullptr) {
|
||||||
auto* group = new QGroupBox(property_set.title, parent);
|
auto* group = new QGroupBox(property_set.title, parent);
|
||||||
group->setObjectName("propertySetCard");
|
group->setObjectName("propertySetCard");
|
||||||
auto* form = new QFormLayout(group);
|
auto* layout = new QVBoxLayout(group);
|
||||||
form->setContentsMargins(10, 10, 10, 10);
|
layout->setContentsMargins(10, 10, 10, 10);
|
||||||
form->setHorizontalSpacing(16);
|
layout->setSpacing(0);
|
||||||
form->setVerticalSpacing(6);
|
|
||||||
form->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
|
||||||
|
|
||||||
|
QList<ifcinterface::components::KeyValueTableRow> rows;
|
||||||
for (const auto& row : property_set.rows) {
|
for (const auto& row : property_set.rows) {
|
||||||
auto* key = new QLabel(row.key, group);
|
rows.append({row.key, row.value, "propertyValueLabel", "", "", 0});
|
||||||
key->setObjectName("propertyKeyLabel");
|
|
||||||
auto* value = new QLabel(row.value, group);
|
|
||||||
value->setObjectName("propertyValueLabel");
|
|
||||||
value->setWordWrap(true);
|
|
||||||
form->addRow(key, value);
|
|
||||||
}
|
}
|
||||||
|
layout->addWidget(new ifcinterface::components::KeyValueTable(rows, group));
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* makeAttributeList(const QList<ifcinterface::panels::properties::KeyValueRow>& rows, QWidget* parent = nullptr) {
|
QWidget* makeAttributeList(const QList<ifcinterface::panels::properties::KeyValueRow>& rows, QWidget* parent = nullptr) {
|
||||||
auto* panel = new QWidget(parent);
|
QList<ifcinterface::components::KeyValueTableRow> table_rows;
|
||||||
panel->setObjectName("attributeList");
|
|
||||||
auto* form = new QFormLayout(panel);
|
|
||||||
form->setContentsMargins(0, 0, 0, 0);
|
|
||||||
form->setHorizontalSpacing(16);
|
|
||||||
form->setVerticalSpacing(6);
|
|
||||||
form->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
|
||||||
|
|
||||||
for (const auto& row : rows) {
|
for (const auto& row : rows) {
|
||||||
auto* key = new QLabel(row.key, panel);
|
table_rows.append({row.key, row.value, "propertyValueLabel", "", "", 0});
|
||||||
key->setObjectName("propertyKeyLabel");
|
|
||||||
auto* value = new QLabel(row.value, panel);
|
|
||||||
value->setObjectName("propertyValueLabel");
|
|
||||||
value->setWordWrap(true);
|
|
||||||
form->addRow(key, value);
|
|
||||||
}
|
}
|
||||||
|
return new ifcinterface::components::KeyValueTable(table_rows, parent);
|
||||||
return panel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* makeRelationshipList(const QList<ifcinterface::panels::properties::RelationshipRow>& rows, QWidget* parent = nullptr) {
|
QWidget* makeRelationshipList(const QList<ifcinterface::panels::properties::RelationshipRow>& rows, QWidget* parent = nullptr) {
|
||||||
auto* panel = new QWidget(parent);
|
QList<ifcinterface::components::KeyValueTableRow> table_rows;
|
||||||
panel->setObjectName("attributeList");
|
|
||||||
auto* layout = new QVBoxLayout(panel);
|
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
layout->setSpacing(6);
|
|
||||||
|
|
||||||
for (const auto& row_data : rows) {
|
for (const auto& row_data : rows) {
|
||||||
auto* row = new QWidget(panel);
|
table_rows.append({row_data.key,
|
||||||
row->setObjectName("relationshipRow");
|
row_data.value,
|
||||||
auto* row_layout = new QHBoxLayout(row);
|
"relationshipValueLabel",
|
||||||
row_layout->setContentsMargins(0, 0, 0, 0);
|
":/icons/cursor-pointer.svg",
|
||||||
row_layout->setSpacing(12);
|
"relationshipIconLabel",
|
||||||
|
72});
|
||||||
auto* key = new QLabel(row_data.key, row);
|
|
||||||
key->setObjectName("propertyKeyLabel");
|
|
||||||
key->setMinimumWidth(72);
|
|
||||||
|
|
||||||
auto* target = new QLabel(row_data.value, row);
|
|
||||||
target->setObjectName("relationshipValueLabel");
|
|
||||||
target->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
|
||||||
|
|
||||||
auto* icon = new QLabel(row);
|
|
||||||
icon->setObjectName("relationshipIconLabel");
|
|
||||||
icon->setPixmap(ifcinterface::components::icons::makePanelSvgPixmap(":/icons/cursor-pointer.svg", QSize(14, 14)));
|
|
||||||
icon->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
|
||||||
|
|
||||||
row_layout->addWidget(key);
|
|
||||||
row_layout->addWidget(target, 1);
|
|
||||||
row_layout->addWidget(icon, 0, Qt::AlignRight | Qt::AlignVCenter);
|
|
||||||
layout->addWidget(row);
|
|
||||||
}
|
}
|
||||||
|
return new ifcinterface::components::KeyValueTable(table_rows, parent);
|
||||||
return panel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -121,22 +79,28 @@ PropertiesPanelWidget::PropertiesPanelWidget(QWidget* parent)
|
|||||||
auto* root = new QVBoxLayout(this);
|
auto* root = new QVBoxLayout(this);
|
||||||
root->setContentsMargins(0, 0, 0, 0);
|
root->setContentsMargins(0, 0, 0, 0);
|
||||||
root->setSpacing(0);
|
root->setSpacing(0);
|
||||||
|
|
||||||
|
scroll_ = new QScrollArea(this);
|
||||||
|
scroll_->setWidgetResizable(true);
|
||||||
|
scroll_->setFrameShape(QFrame::NoFrame);
|
||||||
|
|
||||||
|
content_ = new QWidget(scroll_);
|
||||||
|
content_->setObjectName("inspectorPanel");
|
||||||
|
content_layout_ = new QVBoxLayout(content_);
|
||||||
|
content_layout_->setContentsMargins(0, 0, 0, 0);
|
||||||
|
content_layout_->setSpacing(12);
|
||||||
|
|
||||||
|
scroll_->setWidget(content_);
|
||||||
|
root->addWidget(scroll_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertiesPanelWidget::setState(const PropertiesPanelState& state) {
|
void PropertiesPanelWidget::render(const PropertiesPanelState& state) {
|
||||||
auto* root = qobject_cast<QVBoxLayout*>(layout());
|
while (auto* item = content_layout_->takeAt(0)) {
|
||||||
while (auto* item = root->takeAt(0)) {
|
|
||||||
if (auto* widget = item->widget()) widget->deleteLater();
|
if (auto* widget = item->widget()) widget->deleteLater();
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* content = new QWidget(this);
|
auto* entity_card = new QFrame(content_);
|
||||||
content->setObjectName("inspectorPanel");
|
|
||||||
auto* content_layout = new QVBoxLayout(content);
|
|
||||||
content_layout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
content_layout->setSpacing(12);
|
|
||||||
|
|
||||||
auto* entity_card = new QFrame(content);
|
|
||||||
entity_card->setObjectName("entityClassCard");
|
entity_card->setObjectName("entityClassCard");
|
||||||
auto* entity_layout = new QHBoxLayout(entity_card);
|
auto* entity_layout = new QHBoxLayout(entity_card);
|
||||||
entity_layout->setContentsMargins(10, 8, 10, 8);
|
entity_layout->setContentsMargins(10, 8, 10, 8);
|
||||||
@@ -159,37 +123,31 @@ void PropertiesPanelWidget::setState(const PropertiesPanelState& state) {
|
|||||||
|
|
||||||
QList<QWidget*> property_set_widgets;
|
QList<QWidget*> property_set_widgets;
|
||||||
for (const auto& property_set : state.property_sets) {
|
for (const auto& property_set : state.property_sets) {
|
||||||
property_set_widgets.append(makePropertySetPanel(property_set, content));
|
property_set_widgets.append(makePropertySetPanel(property_set, content_));
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QWidget*> quantity_set_widgets;
|
QList<QWidget*> quantity_set_widgets;
|
||||||
for (const auto& property_set : state.quantity_sets) {
|
for (const auto& property_set : state.quantity_sets) {
|
||||||
quantity_set_widgets.append(makePropertySetPanel(property_set, content));
|
quantity_set_widgets.append(makePropertySetPanel(property_set, content_));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* entity_section = new components::Section("", components::SectionHeaderMode::Hidden, "", content);
|
auto* entity_section = new components::Section("", components::SectionHeaderMode::Hidden, "", content_);
|
||||||
entity_section->addBodyWidget(entity_card);
|
entity_section->addBodyWidget(entity_card);
|
||||||
auto* attributes_section = new components::Section("Attributes", components::SectionHeaderMode::Visible, "", content);
|
auto* attributes_section = new components::Section("Attributes", components::SectionHeaderMode::Visible, "", content_);
|
||||||
attributes_section->addBodyWidget(makeAttributeList(state.attributes, content));
|
attributes_section->addBodyWidget(makeAttributeList(state.attributes, content_));
|
||||||
auto* relationships_section = new components::Section("Relationships", components::SectionHeaderMode::Visible, "", content);
|
auto* relationships_section = new components::Section("Relationships", components::SectionHeaderMode::Visible, "", content_);
|
||||||
relationships_section->addBodyWidget(makeRelationshipList(state.relationships, content));
|
relationships_section->addBodyWidget(makeRelationshipList(state.relationships, content_));
|
||||||
auto* properties_section = new components::Section("Properties", components::SectionHeaderMode::Visible, "Filter properties or sets", content);
|
auto* properties_section = new components::Section("Properties", components::SectionHeaderMode::Visible, "Filter properties or sets", content_);
|
||||||
for (auto* widget : property_set_widgets) properties_section->addBodyWidget(widget);
|
for (auto* widget : property_set_widgets) properties_section->addBodyWidget(widget);
|
||||||
auto* quantities_section = new components::Section("Quantities", components::SectionHeaderMode::Visible, "Filter quantities or sets", content);
|
auto* quantities_section = new components::Section("Quantities", components::SectionHeaderMode::Visible, "Filter quantities or sets", content_);
|
||||||
for (auto* widget : quantity_set_widgets) quantities_section->addBodyWidget(widget);
|
for (auto* widget : quantity_set_widgets) quantities_section->addBodyWidget(widget);
|
||||||
|
|
||||||
content_layout->addWidget(entity_section);
|
content_layout_->addWidget(entity_section);
|
||||||
content_layout->addWidget(attributes_section);
|
content_layout_->addWidget(attributes_section);
|
||||||
content_layout->addWidget(relationships_section);
|
content_layout_->addWidget(relationships_section);
|
||||||
content_layout->addWidget(properties_section);
|
content_layout_->addWidget(properties_section);
|
||||||
content_layout->addWidget(quantities_section);
|
content_layout_->addWidget(quantities_section);
|
||||||
content_layout->addStretch(1);
|
content_layout_->addStretch(1);
|
||||||
|
|
||||||
auto* scroll = new QScrollArea(this);
|
|
||||||
scroll->setWidgetResizable(true);
|
|
||||||
scroll->setFrameShape(QFrame::NoFrame);
|
|
||||||
scroll->setWidget(content);
|
|
||||||
root->addWidget(scroll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ifcinterface::panels::properties
|
} // namespace ifcinterface::panels::properties
|
||||||
|
|||||||
@@ -25,6 +25,9 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QScrollArea;
|
||||||
|
class QVBoxLayout;
|
||||||
|
|
||||||
namespace ifcinterface::panels::properties {
|
namespace ifcinterface::panels::properties {
|
||||||
|
|
||||||
class PropertiesPanelWidget : public QWidget {
|
class PropertiesPanelWidget : public QWidget {
|
||||||
@@ -32,7 +35,12 @@ class PropertiesPanelWidget : public QWidget {
|
|||||||
public:
|
public:
|
||||||
explicit PropertiesPanelWidget(QWidget* parent = nullptr);
|
explicit PropertiesPanelWidget(QWidget* parent = nullptr);
|
||||||
|
|
||||||
void setState(const PropertiesPanelState& state);
|
void render(const PropertiesPanelState& state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScrollArea* scroll_ = nullptr;
|
||||||
|
QWidget* content_ = nullptr;
|
||||||
|
QVBoxLayout* content_layout_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ifcinterface::panels::properties
|
} // namespace ifcinterface::panels::properties
|
||||||
|
|||||||
Reference in New Issue
Block a user