Rename IfcViewerFull to Bonsai Viewer

Directory src/ifcviewer-full -> src/bonsaiviewer, CMake target
IfcViewerFull -> BonsaiViewer, namespace ifcviewerfull -> bonsaiviewer,
QApplication / window titles / connector path now use the new brand.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-05-20 09:38:10 +10:00
parent fcae3d90af
commit 59e5b2b1b8
125 changed files with 308 additions and 308 deletions
+77
View File
@@ -0,0 +1,77 @@
// 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 "Buttons.h"
#include "SvgIcon.h"
#include <QFrame>
#include <QHBoxLayout>
#include <QLabel>
#include <QToolButton>
#include <QVBoxLayout>
namespace bonsaiviewer::components::buttons {
QToolButton* makeButton(const QString& text,
const QString& icon_path,
QWidget* parent) {
auto* button = new QToolButton(parent);
button->setObjectName("ribbonButton");
button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
button->setIcon(components::icons::makeAccentSvgIcon(icon_path));
button->setIconSize(QSize(20, 20));
button->setText(text);
button->setMinimumSize(QSize(90, 68));
button->setAutoRaise(false);
return button;
}
QWidget* makeButtonGroup(const QString& title,
const QList<QToolButton*>& buttons,
QWidget* parent,
bool trailing_separator,
int vertical_spacing) {
auto* group = new QFrame(parent);
group->setObjectName("ribbonGroup");
group->setProperty("separator", trailing_separator);
auto* group_layout = new QVBoxLayout(group);
group_layout->setContentsMargins(8, 6, 8, 4);
group_layout->setSpacing(vertical_spacing);
auto* button_row = new QHBoxLayout();
button_row->setContentsMargins(0, 0, 0, 0);
button_row->setSpacing(4);
for (auto* button : buttons) {
button_row->addWidget(button);
}
auto* label = new QLabel(title, group);
label->setObjectName("ribbonGroupLabel");
label->setProperty("textRole", "secondary");
label->setAlignment(Qt::AlignCenter);
group_layout->addLayout(button_row);
group_layout->addWidget(label);
return group;
}
} // namespace bonsaiviewer::components::buttons
+43
View File
@@ -0,0 +1,43 @@
// 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_BUTTONS_H
#define IFCINTERFACE_COMPONENTS_BUTTONS_H
#include <QList>
class QToolButton;
class QWidget;
namespace bonsaiviewer::components::buttons {
QToolButton* makeButton(const QString& text,
const QString& icon_path,
QWidget* parent);
QWidget* makeButtonGroup(const QString& title,
const QList<QToolButton*>& buttons,
QWidget* parent,
bool trailing_separator = true,
int vertical_spacing = 4);
} // namespace bonsaiviewer::components::buttons
#endif
+143
View File
@@ -0,0 +1,143 @@
// 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 "Style.h"
#include "Tabs.h"
#include <QDialog>
#include <QFrame>
#include <QScrollArea>
#include <QVBoxLayout>
namespace bonsaiviewer::components {
Dialog::Dialog(QWidget* parent, bool scrollable)
: QDialog(parent)
{
auto* outer_layout = new QVBoxLayout(this);
outer_layout->setContentsMargins(style::metrics::padding,
style::metrics::padding,
style::metrics::padding,
style::metrics::padding);
outer_layout->setSpacing(0);
auto* frame = new QFrame(this);
frame->setObjectName("panel");
auto* frame_layout = new QVBoxLayout(frame);
frame_layout->setContentsMargins(0,
style::metrics::section_body_padding,
0,
style::metrics::section_body_padding);
frame_layout->setSpacing(0);
auto* scroll = new QScrollArea(frame);
scroll->setWidgetResizable(true);
scroll->setFrameShape(QFrame::NoFrame);
auto* scroll_body = new QWidget(scroll);
scroll_body->setObjectName("panelScrollBody");
body_layout_ = new QVBoxLayout(scroll_body);
body_layout_->setContentsMargins(0, 0, 0, 0);
body_layout_->setSpacing(style::metrics::section_body_padding);
body_layout_->setAlignment(Qt::AlignTop);
scroll->setWidget(scroll_body);
frame_layout->addWidget(scroll, scrollable ? 1 : 0);
auto* footer = new QWidget(frame);
footer_layout_ = new QVBoxLayout(footer);
footer_layout_->setContentsMargins(style::metrics::section_body_padding,
style::metrics::section_body_padding,
style::metrics::section_body_padding,
0);
footer_layout_->setSpacing(style::metrics::section_body_padding);
footer_layout_->setAlignment(Qt::AlignTop);
frame_layout->addWidget(footer);
outer_layout->addWidget(frame);
}
void Dialog::addBodyWidget(QWidget* widget) {
body_layout_->addWidget(widget);
}
void Dialog::addFooterWidget(QWidget* widget) {
footer_layout_->addWidget(widget);
}
TabbedDialog::TabbedDialog(QWidget* parent)
: QDialog(parent)
{
auto* outer_layout = new QVBoxLayout(this);
outer_layout->setContentsMargins(style::metrics::padding,
style::metrics::padding,
style::metrics::padding,
style::metrics::padding);
outer_layout->setSpacing(0);
auto* frame = new QFrame(this);
frame->setObjectName("panel");
auto* frame_layout = new QVBoxLayout(frame);
frame_layout->setContentsMargins(0,
style::metrics::section_body_padding,
0,
style::metrics::section_body_padding);
frame_layout->setSpacing(0);
tabs_ = new TabWidget(frame);
frame_layout->addWidget(tabs_, 1);
auto* footer = new QWidget(frame);
footer_layout_ = new QVBoxLayout(footer);
footer_layout_->setContentsMargins(style::metrics::section_body_padding,
style::metrics::section_body_padding,
style::metrics::section_body_padding,
0);
footer_layout_->setSpacing(style::metrics::section_body_padding);
footer_layout_->setAlignment(Qt::AlignTop);
frame_layout->addWidget(footer);
outer_layout->addWidget(frame);
}
void TabbedDialog::addTab(const QString& title, QWidget* widget) {
auto* scroll = new QScrollArea(tabs_);
scroll->setWidgetResizable(true);
scroll->setFrameShape(QFrame::NoFrame);
auto* scroll_body = new QWidget(scroll);
scroll_body->setObjectName("panelScrollBody");
auto* layout = new QVBoxLayout(scroll_body);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(style::metrics::section_body_padding);
layout->setAlignment(Qt::AlignTop);
layout->addWidget(widget);
scroll->setWidget(scroll_body);
tabs_->addTab(scroll, title);
}
void TabbedDialog::addFooterWidget(QWidget* widget) {
footer_layout_->addWidget(widget);
}
} // namespace bonsaiviewer::components
+63
View File
@@ -0,0 +1,63 @@
// 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_DIALOG_H
#define IFCINTERFACE_COMPONENTS_DIALOG_H
#include <QDialog>
class QVBoxLayout;
class QWidget;
class QTabWidget;
namespace bonsaiviewer::components {
class Dialog : public QDialog {
Q_OBJECT
public:
explicit Dialog(QWidget* parent = nullptr,
bool scrollable = false);
void addBodyWidget(QWidget* widget);
void addFooterWidget(QWidget* widget);
private:
QVBoxLayout* body_layout_ = nullptr;
QVBoxLayout* footer_layout_ = nullptr;
};
class TabbedDialog : public QDialog {
Q_OBJECT
public:
explicit TabbedDialog(QWidget* parent = nullptr);
void addTab(const QString& title, QWidget* widget);
void addFooterWidget(QWidget* widget);
private:
QTabWidget* tabs_ = nullptr;
QVBoxLayout* footer_layout_ = nullptr;
};
} // namespace bonsaiviewer::components
#endif
@@ -0,0 +1,72 @@
// 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 <QGridLayout>
#include <QLabel>
namespace bonsaiviewer::components {
KeyValueTable::KeyValueTable(const QList<KeyValueTableRow>& rows, QWidget* parent)
: QWidget(parent)
{
setObjectName("keyValueTable");
auto* layout = new QGridLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setHorizontalSpacing(12);
layout->setVerticalSpacing(6);
layout->setColumnStretch(1, 1);
int row_index = 0;
for (const auto& row_data : rows) {
auto* key = new QLabel(row_data.key, this);
key->setProperty("textRole", "secondary");
if (row_data.key_minimum_width > 0) {
key->setMinimumWidth(row_data.key_minimum_width);
}
auto* value = new QLabel(row_data.value, this);
value->setObjectName(row_data.value_object_name.isEmpty()
? "keyValueValueLabel"
: row_data.value_object_name);
value->setWordWrap(true);
value->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
layout->addWidget(key, row_index, 0, Qt::AlignLeft | Qt::AlignTop);
layout->addWidget(value, row_index, 1);
if (!row_data.trailing_icon_path.isEmpty()) {
auto* icon = new QLabel(this);
icon->setObjectName(row_data.trailing_icon_object_name.isEmpty()
? "keyValueTrailingIconLabel"
: row_data.trailing_icon_object_name);
icon->setPixmap(icons::makeSvgPixmap(row_data.trailing_icon_path, QSize(14, 14)));
icon->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
layout->addWidget(icon, row_index, 2, Qt::AlignRight | Qt::AlignTop);
}
++row_index;
}
}
} // namespace bonsaiviewer::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 bonsaiviewer::components {
struct KeyValueTableRow {
QString key;
QString value;
QString value_object_name = "keyValueValueLabel";
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 bonsaiviewer::components
#endif
+140
View File
@@ -0,0 +1,140 @@
// 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 "Panel.h"
#include "Style.h"
#include "SvgIcon.h"
#include <QDockWidget>
#include <QFrame>
#include <QHBoxLayout>
#include <QLabel>
#include <QMenu>
#include <QScrollArea>
#include <QToolButton>
#include <QVBoxLayout>
namespace bonsaiviewer::components {
namespace {
class DockTitleBar : public QWidget {
public:
explicit DockTitleBar(const QString& title,
bool has_settings = false,
std::function<void()> on_settings = {},
QWidget* parent = nullptr)
: QWidget(parent)
{
auto* layout = new QHBoxLayout(this);
layout->setContentsMargins(10, 6, 6, 6);
layout->setSpacing(6);
auto* text = new QLabel(title.toUpper(), this);
text->setObjectName("panelTitleText");
layout->addWidget(text);
layout->addStretch(1);
if (has_settings) {
auto* settings = new QToolButton(this);
settings->setIcon(icons::makeSvgIcon(":/icons/settings.svg"));
settings->setAutoRaise(true);
settings->setCursor(Qt::ArrowCursor);
settings->setFixedSize(18, 18);
settings->setObjectName("panelTitleButton");
settings->setToolTip(QString("%1 settings").arg(title));
connect(settings, &QToolButton::clicked, this, [on_settings = std::move(on_settings)]() {
if (on_settings) on_settings();
});
layout->addWidget(settings);
}
}
};
} // namespace
Panel::Panel(const QString& title, QWidget* content, QWidget* parent, bool has_settings, bool scrollable)
: QDockWidget(title, parent)
{
auto* outer = new QFrame();
auto* outer_layout = new QVBoxLayout(outer);
outer_layout->setContentsMargins(style::metrics::padding,
style::metrics::padding,
style::metrics::padding,
style::metrics::padding);
outer_layout->setSpacing(0);
auto* frame = new QFrame(outer);
frame->setObjectName("panel");
auto* frame_layout = new QVBoxLayout(frame);
frame_layout->setContentsMargins(0, style::metrics::section_body_padding, 0, style::metrics::section_body_padding);
frame_layout->setSpacing(0);
if (scrollable) {
auto* scroll = new QScrollArea(frame);
scroll->setWidgetResizable(true);
scroll->setFrameShape(QFrame::NoFrame);
auto* scroll_body = new QWidget(scroll);
scroll_body->setObjectName("panelScrollBody");
body_layout_ = new QVBoxLayout(scroll_body);
body_layout_->setContentsMargins(0, 0, 0, 0);
body_layout_->setSpacing(style::metrics::section_body_padding);
body_layout_->setAlignment(Qt::AlignTop);
scroll->setWidget(scroll_body);
frame_layout->addWidget(scroll);
} else {
auto* body = new QWidget(frame);
body_layout_ = new QVBoxLayout(body);
body_layout_->setContentsMargins(0, 0, 0, 0);
body_layout_->setSpacing(style::metrics::section_body_padding);
body_layout_->setAlignment(Qt::AlignTop);
frame_layout->addWidget(body);
}
if (content) {
addBodyWidget(content);
}
outer_layout->addWidget(frame);
setObjectName(title);
setFeatures(QDockWidget::DockWidgetMovable |
QDockWidget::DockWidgetFloatable |
QDockWidget::DockWidgetClosable);
setTitleBarWidget(new DockTitleBar(title, has_settings, [this]() {
emit settingsRequested();
}, this));
setWidget(outer);
}
void Panel::addBodyWidget(QWidget* widget) {
body_layout_->addWidget(widget);
}
void Panel::clearBodyWidgets() {
while (auto* item = body_layout_->takeAt(0)) {
if (auto* widget = item->widget()) widget->deleteLater();
delete item;
}
}
} // namespace bonsaiviewer::components
+53
View File
@@ -0,0 +1,53 @@
// 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_PANEL_PANELCHROME_H
#define IFCINTERFACE_COMPONENTS_PANEL_PANELCHROME_H
#include <QDockWidget>
class QWidget;
class QVBoxLayout;
namespace bonsaiviewer::components {
class Panel : public QDockWidget {
Q_OBJECT
public:
explicit Panel(const QString& title,
QWidget* content = nullptr,
QWidget* parent = nullptr,
bool has_settings = false,
bool scrollable = false);
void addBodyWidget(QWidget* widget);
void clearBodyWidgets();
signals:
void settingsRequested();
private:
QVBoxLayout* body_layout_ = nullptr;
};
} // namespace bonsaiviewer::components
#endif
+118
View File
@@ -0,0 +1,118 @@
// 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 "Section.h"
#include "Style.h"
#include <QFrame>
#include <QHBoxLayout>
#include <QSizePolicy>
#include <QToolButton>
#include <QVBoxLayout>
namespace bonsaiviewer::components {
Section::Section(const QString& title, SectionHeaderMode header_mode, QWidget* parent)
: QWidget(parent)
{
setObjectName("panelSection");
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
auto* layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(style::metrics::padding);
if (header_mode == SectionHeaderMode::Visible) {
auto* header = new QFrame(this);
header->setObjectName("panelSectionHeader");
header_layout_ = new QHBoxLayout(header);
header_layout_->setContentsMargins(0, 0, 0, 0);
header_layout_->setSpacing(style::metrics::padding);
toggle_button_ = new QToolButton(header);
toggle_button_->setObjectName("panelSectionHeaderButton");
toggle_button_->setText(title);
toggle_button_->setCheckable(true);
toggle_button_->setChecked(true);
toggle_button_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
toggle_button_->setArrowType(Qt::DownArrow);
header_layout_->addWidget(toggle_button_);
header_layout_->addStretch(1);
layout->addWidget(header);
connect(toggle_button_, &QToolButton::toggled, this, [this](bool expanded) {
toggle_button_->setArrowType(expanded ? Qt::DownArrow : Qt::RightArrow);
body_->setVisible(expanded);
body_->setMaximumHeight(expanded ? QWIDGETSIZE_MAX : 0);
body_->setMinimumHeight(0);
setSizePolicy(QSizePolicy::Preferred,
body_expanding_ && expanded ? QSizePolicy::Expanding : QSizePolicy::Maximum);
updateGeometry();
});
}
body_ = new QWidget(this);
body_->setObjectName("panelSectionBody");
body_layout_ = new QVBoxLayout(body_);
body_layout_->setContentsMargins(style::metrics::section_body_padding,
0,
style::metrics::section_body_padding,
0);
body_layout_->setSpacing(style::metrics::padding);
body_->setMinimumHeight(0);
layout->addWidget(body_);
}
void Section::addBodyWidget(QWidget* widget) {
body_layout_->addWidget(widget);
}
void Section::clearBody() {
while (auto* item = body_layout_->takeAt(0)) {
if (auto* widget = item->widget()) widget->deleteLater();
delete item;
}
}
void Section::addHeaderWidget(QWidget* widget) {
if (!header_layout_) return;
header_layout_->addWidget(widget);
}
bool Section::isExpanded() const {
return !toggle_button_ || toggle_button_->isChecked();
}
void Section::setExpanded(bool expanded) {
if (!toggle_button_) return;
toggle_button_->setChecked(expanded);
}
void Section::setBodyExpanding(bool expanding) {
body_expanding_ = expanding;
body_->setSizePolicy(QSizePolicy::Preferred, expanding ? QSizePolicy::Expanding : QSizePolicy::Preferred);
body_layout_->setStretch(0, expanding ? 1 : 0);
setSizePolicy(QSizePolicy::Preferred,
expanding && isExpanded() ? QSizePolicy::Expanding : QSizePolicy::Maximum);
updateGeometry();
}
} // namespace bonsaiviewer::components
+61
View File
@@ -0,0 +1,61 @@
// 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_SECTION_H
#define IFCINTERFACE_COMPONENTS_SECTION_H
#include <QWidget>
class QHBoxLayout;
class QToolButton;
class QVBoxLayout;
namespace bonsaiviewer::components {
enum class SectionHeaderMode {
Visible,
Hidden,
};
class Section : public QWidget {
Q_OBJECT
public:
explicit Section(const QString& title,
SectionHeaderMode header_mode = SectionHeaderMode::Visible,
QWidget* parent = nullptr);
void addBodyWidget(QWidget* widget);
void clearBody();
void addHeaderWidget(QWidget* widget);
bool isExpanded() const;
void setExpanded(bool expanded);
void setBodyExpanding(bool expanding);
private:
QWidget* body_ = nullptr;
QVBoxLayout* body_layout_ = nullptr;
QHBoxLayout* header_layout_ = nullptr;
QToolButton* toggle_button_ = nullptr;
bool body_expanding_ = false;
};
} // namespace bonsaiviewer::components
#endif
+497
View File
@@ -0,0 +1,497 @@
// 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"
#include "../ViewerSettings.h"
namespace bonsaiviewer::components::style {
QString buildAppStyleSheet() {
const auto& theme = bonsaiviewer::ViewerSettings::instance();
QString stylesheet = QStringLiteral(R"(
QMainWindow#appWindow {
background: ${app_background};
color: ${primary_text};
selection-background-color: ${selection_background};
selection-color: ${selection_text};
}
QDialog#appDialog {
background: ${app_background};
color: ${primary_text};
}
QMessageBox,
QMessageBox QWidget,
QMessageBox QLabel {
background: ${app_background};
color: ${primary_text};
}
QFileDialog,
QFileDialog QWidget,
QFileDialog QStackedWidget,
QFileDialog QSplitter {
background: ${app_background};
color: ${primary_text};
}
QTabBar#appTabBar {
background: ${tab_bar_background};
}
QTabBar#appTabBar::tab {
background: ${tab_background};
color: ${secondary_text};
padding: 8px 14px;
margin-right: 2px;
border-bottom: 2px solid transparent;
}
QTabBar#appTabBar::tab:selected {
color: ${primary_text};
border-bottom: 2px solid ${selection_background};
}
QTabBar#appTabBar::tab:hover {
color: ${hover_text};
}
QFrame#ribbonBand {
background: ${ribbon_background};
border-top: 1px solid ${border};
}
QTabWidget#appTabWidget::pane {
border: none;
background: transparent;
}
QFrame#ribbonPage {
background: transparent;
}
QFrame#ribbonGroup {
background: transparent;
border-right: 1px solid ${border};
}
QFrame#ribbonGroup[separator="false"] {
border-right: none;
}
QLabel#ribbonGroupLabel {
font-size: ${font_small}px;
font-weight: 600;
}
QToolButton#ribbonButton {
background: transparent;
border: none;
padding: 6px 4px 4px 4px;
color: ${primary_text};
}
QToolButton#ribbonButton:hover {
background: ${ribbon_button_hover};
}
QToolButton#ribbonButton:pressed {
background: ${ribbon_button_pressed};
}
QFrame#viewportShell {
background: ${viewport_shell_background};
border-top: none;
}
QFrame#viewportFrame {
border: 1px solid ${border};
}
QDockWidget {
color: ${primary_text};
}
QLabel {
color: ${primary_text};
background: transparent;
}
QAbstractItemView,
QTreeWidget,
QListWidget,
QTableWidget,
QLineEdit,
QComboBox,
QSpinBox,
QDoubleSpinBox,
QCheckBox,
QRadioButton,
QPushButton,
QToolButton {
color: ${primary_text};
}
QLabel[textRole="secondary"] {
color: ${secondary_text};
}
QLabel[textRole="disabled"] {
color: ${disabled_text};
}
QLabel[textRole="warning"] {
color: ${warning_text};
}
QLabel#panelTitleText {
color: ${primary_text};
font-size: ${font_small}px;
font-weight: 600;
}
QToolButton#panelTitleButton {
border: none;
background: transparent;
}
QToolButton#panelTitleButton:hover {
color: ${hover_text};
background: ${ribbon_button_hover};
}
QFrame#panel {
background: ${panel_background};
border: 1px solid ${border};
border-radius: ${panel_radius}px;
}
QTreeWidget, QListWidget, QTableWidget, QAbstractScrollArea {
background: ${panel_background};
border: none;
outline: none;
gridline-color: ${border};
}
QTableWidget#modelCoordinatesTable {
font-size: ${font_small}px;
}
QTableWidget#modelCoordinatesTable QHeaderView::section {
font-size: ${font_small}px;
}
QTreeWidget::viewport, QListWidget::viewport, QTableWidget::viewport {
background: ${panel_background};
}
QHeaderView::section {
background: ${control_background};
color: ${primary_text};
border: none;
border-bottom: 1px solid ${border};
padding: 7px 8px;
font-weight: 600;
}
QTableCornerButton::section {
background: ${control_background};
border: none;
}
QScrollArea {
background: ${panel_background};
border: none;
}
QScrollArea > QWidget > QWidget {
background: ${panel_background};
}
QLineEdit {
background: ${control_background};
border: 1px solid ${border};
border-radius: ${panel_radius}px;
padding: ${padding}px ${padding}px;
color: ${primary_text};
}
QLineEdit:focus {
border: 1px solid ${control_border_focus};
}
QComboBox {
background: ${control_background};
border: 1px solid ${border};
border-radius: ${panel_radius}px;
padding: ${padding}px 24px ${padding}px ${padding}px;
}
QComboBox:focus {
border: 1px solid ${control_border_focus};
}
QComboBox::drop-down {
subcontrol-origin: padding;
subcontrol-position: top right;
width: 18px;
border: none;
background: transparent;
}
QComboBox::down-arrow {
width: 0px;
height: 0px;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 6px solid ${secondary_text};
margin-right: 4px;
}
QComboBox QAbstractItemView {
background: ${panel_background};
border: 1px solid ${border};
selection-background-color: ${selection_background};
selection-color: ${selection_text};
}
QSpinBox, QDoubleSpinBox {
background: ${control_background};
border: 1px solid ${border};
border-radius: ${panel_radius}px;
padding: ${padding}px 24px ${padding}px ${padding}px;
}
QSpinBox:focus, QDoubleSpinBox:focus {
border: 1px solid ${control_border_focus};
}
QSpinBox::up-button, QDoubleSpinBox::up-button,
QSpinBox::down-button, QDoubleSpinBox::down-button {
subcontrol-origin: padding;
width: 18px;
border: none;
background: transparent;
}
QSpinBox::up-button, QDoubleSpinBox::up-button {
subcontrol-position: top right;
}
QSpinBox::down-button, QDoubleSpinBox::down-button {
subcontrol-position: bottom right;
}
QSpinBox::up-arrow, QDoubleSpinBox::up-arrow {
width: 0px;
height: 0px;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-bottom: 5px solid ${secondary_text};
}
QSpinBox::down-arrow, QDoubleSpinBox::down-arrow {
width: 0px;
height: 0px;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 5px solid ${secondary_text};
}
QCheckBox {
background: transparent;
spacing: 8px;
}
QCheckBox::indicator {
width: 16px;
height: 16px;
border: 1px solid ${border};
border-radius: ${panel_radius}px;
background: ${control_background};
}
QCheckBox::indicator:hover {
background: ${ribbon_button_hover};
}
QCheckBox::indicator:checked {
border: 1px solid ${selection_background};
background: ${selection_background};
}
QRadioButton {
background: transparent;
color: ${primary_text};
spacing: 8px;
padding: 2px 0;
}
QRadioButton::indicator {
width: 16px;
height: 16px;
border: 1px solid ${border};
border-radius: 8px;
background: ${control_background};
}
QRadioButton::indicator:hover {
background: ${ribbon_button_hover};
}
QRadioButton::indicator:checked {
border: 1px solid ${selection_background};
background: ${selection_background};
}
QRadioButton::indicator:unchecked {
background: ${control_background};
}
QPushButton {
background: ${control_background};
border: 1px solid ${border};
border-radius: ${panel_radius}px;
padding: ${padding}px ${padding}px;
}
QPushButton:hover {
background: ${ribbon_button_hover};
}
QPushButton:pressed {
background: ${ribbon_button_pressed};
}
QMenu {
background: ${panel_background};
color: ${primary_text};
border: 1px solid ${border};
padding: 4px;
}
QMenu::item {
background: transparent;
color: ${primary_text};
padding: 6px 24px 6px 10px;
border-radius: ${panel_radius}px;
}
QMenu::item:selected {
background: ${selection_background};
color: ${selection_text};
}
QMenu::item:disabled {
color: ${disabled_text};
}
QMenu::separator {
height: 1px;
background: ${border};
margin: 4px 8px;
}
QMenu::icon {
padding-left: 2px;
}
QFrame#entityClassBox,
QGroupBox#propertySetBox {
background: ${box_background};
border: 1px solid ${border};
border-radius: ${panel_radius}px;
}
QLabel#entityClassLabel {
color: ${primary_text};
font-weight: 700;
background: transparent;
}
QWidget#keyValueTable {
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: ${scroll_handle};
border-radius: ${panel_radius}px;
min-height: 24px;
min-width: 24px;
}
QScrollBar::handle:vertical:hover, QScrollBar::handle:horizontal:hover {
background: ${scroll_handle_hover};
}
QScrollBar::add-line, QScrollBar::sub-line,
QScrollBar::add-page, QScrollBar::sub-page {
background: transparent;
border: none;
}
QStatusBar {
background: ${status_background};
}
QStatusBar QLabel {
color: ${secondary_text};
background: transparent;
border: none;
padding: 2px 8px;
}
QGroupBox {
background: transparent;
border: 1px solid ${border};
border-radius: ${panel_radius}px;
margin-top: 10px;
padding-top: 10px;
}
QGroupBox#propertySetBox::title {
subcontrol-origin: margin;
left: ${padding}px;
padding: 0 4px;
color: ${primary_text};
}
QGroupBox#propertySetBox > QWidget {
background: ${box_background};
}
QWidget#panelSection {
background: transparent;
}
QWidget#panelSectionFilterWrapper {
background: transparent;
}
QLabel#keyValueTrailingIconLabel {
background: transparent;
}
QWidget#panelScrollBody {
background: ${panel_background};
}
QFrame#panelSectionHeader {
background: ${section_header_background};
}
QToolButton#panelSectionHeaderButton {
background: transparent;
border: none;
color: ${primary_text};
font-weight: 700;
text-align: left;
padding: ${section_header_padding}px;
margin: 0;
}
QToolButton#panelSectionHeaderButton:hover {
color: ${hover_text};
}
QToolButton#panelSectionHeaderButton::menu-indicator {
image: none;
width: 0;
}
QToolButton#panelSectionFilterToggle {
background: transparent;
border: none;
padding: ${section_header_padding}px;
}
QToolButton#panelSectionFilterToggle:hover {
background: ${ribbon_button_hover};
}
QWidget#panelSectionBody {
background: transparent;
}
QLabel#keyValueValueLabel {
color: ${primary_text};
background: transparent;
}
)");
stylesheet.replace("${panel_radius}", QString::number(metrics::panel_radius));
stylesheet.replace("${padding}", QString::number(metrics::padding));
stylesheet.replace("${section_header_padding}", QString::number(metrics::section_header_padding));
stylesheet.replace("${font_small}", QString::number(typography::small));
stylesheet.replace("${app_background}", theme.color("app_background"));
stylesheet.replace("${border}", theme.color("border"));
stylesheet.replace("${selection_background}", theme.color("selection_background"));
stylesheet.replace("${selection_text}", theme.color("selection_text"));
stylesheet.replace("${tab_bar_background}", theme.color("tab_bar_background"));
stylesheet.replace("${tab_background}", theme.color("tab_background"));
stylesheet.replace("${hover_text}", theme.color("hover_text"));
stylesheet.replace("${ribbon_background}", theme.color("ribbon_background"));
stylesheet.replace("${ribbon_button_hover}", theme.color("ribbon_button_hover"));
stylesheet.replace("${ribbon_button_pressed}", theme.color("ribbon_button_pressed"));
stylesheet.replace("${viewport_shell_background}", theme.color("viewport_shell_background"));
stylesheet.replace("${viewport_background}", theme.color("viewport_background"));
stylesheet.replace("${panel_background}", theme.color("panel_background"));
stylesheet.replace("${control_background}", theme.color("control_background"));
stylesheet.replace("${control_border_focus}", theme.color("control_border_focus"));
stylesheet.replace("${box_background}", theme.color("box_background"));
stylesheet.replace("${scroll_handle}", theme.color("scroll_handle"));
stylesheet.replace("${scroll_handle_hover}", theme.color("scroll_handle_hover"));
stylesheet.replace("${status_background}", theme.color("status_background"));
stylesheet.replace("${section_header_background}", theme.color("section_header_background"));
stylesheet.replace("${primary_text}", theme.color("primary_text"));
stylesheet.replace("${secondary_text}", theme.color("secondary_text"));
stylesheet.replace("${disabled_text}", theme.color("disabled_text"));
stylesheet.replace("${warning_text}", theme.color("warning_text"));
return stylesheet;
}
} // namespace bonsaiviewer::components::style
+77
View File
@@ -0,0 +1,77 @@
// 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 bonsaiviewer::components::style::metrics {
inline constexpr int padding = 6;
inline constexpr int section_body_padding = 10;
inline constexpr int section_header_padding = 2;
inline constexpr int panel_radius = 3;
} // namespace bonsaiviewer::components::style::metrics
namespace bonsaiviewer::components::style::typography {
inline constexpr int small = 10;
} // namespace bonsaiviewer::components::style::typography
namespace bonsaiviewer::components::style::palette {
inline constexpr auto app_background = "#26292f";
inline constexpr auto border = "#3e444e";
inline constexpr auto selection_background = "#39b54a";
inline constexpr auto tab_bar_background = "#26292f";
inline constexpr auto tab_background = "#31353d";
inline constexpr auto ribbon_background = "#31353d";
inline constexpr auto ribbon_button_hover = "#3a3f48";
inline constexpr auto ribbon_button_pressed = "#24282f";
inline constexpr auto viewport_shell_background = "#202329";
inline constexpr auto viewport_background = "#2e3338";
inline constexpr auto panel_background = "#2b2f36";
inline constexpr auto control_background = "#31353d";
inline constexpr auto control_border_focus = "#5b6472";
inline constexpr auto box_background = "#26292f";
inline constexpr auto scroll_handle = "#525a67";
inline constexpr auto scroll_handle_hover = "#697385";
inline constexpr auto status_background = "#26292f";
inline constexpr auto section_header_background = "#26292f";
inline constexpr auto primary_text = "#d0d5dd";
inline constexpr auto secondary_text = "#9aa4b3";
inline constexpr auto disabled_text = "#8f98a6";
inline constexpr auto warning_text = "#e4b35a";
inline constexpr auto selection_text = "#14161a";
inline constexpr auto hover_text = "#ffffff";
} // namespace bonsaiviewer::components::style::palette
namespace bonsaiviewer::components::style {
QString buildAppStyleSheet();
} // namespace bonsaiviewer::components::style
#endif
+86
View File
@@ -0,0 +1,86 @@
// 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 "SvgIcon.h"
#include "../ViewerSettings.h"
#include <QFile>
#include <QPainter>
#include <QRegularExpression>
#include <QSvgRenderer>
namespace bonsaiviewer::components::icons {
QPixmap renderTintedSvgPixmap(const QString& icon_path, const QString& color, const QSize& size) {
QFile file(icon_path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return QIcon(icon_path).pixmap(size);
}
QString svg = QString::fromUtf8(file.readAll());
svg.replace("currentColor", color, Qt::CaseSensitive);
svg.replace(QRegularExpression(R"(stroke="[^"]*")"), QString("stroke=\"%1\"").arg(color));
svg.replace(QRegularExpression(R"(fill="none")"), "fill=\"none\"");
QSvgRenderer renderer(svg.toUtf8());
QPixmap pixmap(size);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
renderer.render(&painter);
return pixmap;
}
QIcon makeTintedSvgIcon(const QString& icon_path, const QString& normal,
const QString& active, const QString& disabled) {
QFile file(icon_path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return QIcon(icon_path);
}
QIcon icon;
icon.addPixmap(renderTintedSvgPixmap(icon_path, normal, QSize(20, 20)), QIcon::Normal, QIcon::Off);
icon.addPixmap(renderTintedSvgPixmap(icon_path, active, QSize(20, 20)), QIcon::Active, QIcon::Off);
icon.addPixmap(renderTintedSvgPixmap(icon_path, active, QSize(20, 20)), QIcon::Selected, QIcon::Off);
icon.addPixmap(renderTintedSvgPixmap(icon_path, disabled, QSize(20, 20)), QIcon::Disabled, QIcon::Off);
return icon;
}
QIcon makeAccentSvgIcon(const QString& icon_path) {
const auto& theme = bonsaiviewer::ViewerSettings::instance();
return makeTintedSvgIcon(icon_path,
theme.color("icon_accent_color"),
theme.color("icon_accent_active_color"),
theme.color("icon_disabled_color"));
}
QIcon makeSvgIcon(const QString& icon_path) {
const auto& theme = bonsaiviewer::ViewerSettings::instance();
return makeTintedSvgIcon(icon_path,
theme.color("icon_color"),
theme.color("icon_active_color"),
theme.color("icon_disabled_color"));
}
QPixmap makeSvgPixmap(const QString& icon_path, const QSize& size) {
return renderTintedSvgPixmap(icon_path, bonsaiviewer::ViewerSettings::instance().color("icon_color"), size);
}
} // namespace bonsaiviewer::components::icons
+42
View File
@@ -0,0 +1,42 @@
// 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_ICONS_SVGICON_H
#define IFCINTERFACE_COMPONENTS_ICONS_SVGICON_H
#include <QIcon>
#include <QPixmap>
#include <QString>
#include <QSize>
namespace bonsaiviewer::components::icons {
QPixmap renderTintedSvgPixmap(const QString& icon_path, const QString& color, const QSize& size);
QIcon makeTintedSvgIcon(const QString& icon_path,
const QString& normal = "#39b54a",
const QString& active = "#53c763",
const QString& disabled = "#6f7988");
QIcon makeAccentSvgIcon(const QString& icon_path);
QIcon makeSvgIcon(const QString& icon_path);
QPixmap makeSvgPixmap(const QString& icon_path, const QSize& size);
} // namespace bonsaiviewer::components::icons
#endif
+40
View File
@@ -0,0 +1,40 @@
// 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 "Tabs.h"
namespace bonsaiviewer::components {
TabBar::TabBar(QWidget* parent)
: QTabBar(parent)
{
setObjectName("appTabBar");
setExpanding(false);
setDrawBase(false);
}
TabWidget::TabWidget(QWidget* parent)
: QTabWidget(parent)
{
setObjectName("appTabWidget");
setTabBar(new TabBar(this));
}
} // namespace bonsaiviewer::components
+45
View File
@@ -0,0 +1,45 @@
// 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_TABS_H
#define IFCINTERFACE_COMPONENTS_TABS_H
#include <QTabBar>
#include <QTabWidget>
namespace bonsaiviewer::components {
class TabBar : public QTabBar {
Q_OBJECT
public:
explicit TabBar(QWidget* parent = nullptr);
};
class TabWidget : public QTabWidget {
Q_OBJECT
public:
explicit TabWidget(QWidget* parent = nullptr);
};
} // namespace bonsaiviewer::components
#endif