Wholesale copy of all Kindred Create additions that don't conflict with upstream FreeCAD code: - kindred-icons/ (1444 Catppuccin Mocha SVG icon overrides) - src/Mod/Create/ (Kindred Create workbench) - src/Gui/ Kindred source files (FileOrigin, OriginManager, OriginSelectorWidget, CommandOrigin, BreadcrumbToolBar, EditingContext) - src/Gui/Icons/ (Kindred branding and silo icons) - src/Gui/PreferencePacks/KindredCreate/ - src/Gui/Stylesheets/ (KindredCreate.qss, images_dark-light/) - package/ (rattler-build recipe) - docs/ (architecture, guides, specifications) - .gitea/ (CI workflows, issue templates) - mods/silo, mods/ztools submodules - .gitmodules (Kindred submodule URLs) - resources/ (kindred-create.desktop, kindred-create.xml) - banner-logo-light.png, CONTRIBUTING.md
196 lines
6.2 KiB
C++
196 lines
6.2 KiB
C++
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||
|
||
/***************************************************************************
|
||
* Copyright (c) 2025 Kindred Systems *
|
||
* *
|
||
* This file is part of Kindred Create. *
|
||
* *
|
||
* This library is free software; you can redistribute it and/or *
|
||
* modify it under the terms of the GNU Library General Public *
|
||
* License as published by the Free Software Foundation; either *
|
||
* version 2 of the License, or (at your option) any later version. *
|
||
* *
|
||
* This library 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 *
|
||
* GNU Library General Public License for more details. *
|
||
* *
|
||
* You should have received a copy of the GNU Library General Public *
|
||
* License along with this library; see the file COPYING.LIB. If not, *
|
||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||
* Suite 330, Boston, MA 02111-1307, USA *
|
||
* *
|
||
***************************************************************************/
|
||
|
||
#include "BreadcrumbToolBar.h"
|
||
#include "EditingContext.h"
|
||
|
||
#include <QColor>
|
||
#include <QLabel>
|
||
#include <QToolButton>
|
||
|
||
#include "Application.h"
|
||
#include "Document.h"
|
||
|
||
using namespace Gui;
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Stylesheet template for breadcrumb chip buttons
|
||
// ---------------------------------------------------------------------------
|
||
|
||
static QString chipStyle(const QString& bgHex)
|
||
{
|
||
// Darken background slightly for contrast, use white text
|
||
QColor bg(bgHex);
|
||
QColor textColor(QStringLiteral("#cdd6f4")); // Catppuccin Text
|
||
|
||
return QStringLiteral(
|
||
"QToolButton {"
|
||
" background-color: %1;"
|
||
" color: %2;"
|
||
" border: none;"
|
||
" border-radius: 4px;"
|
||
" padding: 2px 8px;"
|
||
" font-weight: bold;"
|
||
" font-size: 11px;"
|
||
"}"
|
||
"QToolButton:hover {"
|
||
" background-color: %3;"
|
||
"}"
|
||
"QToolButton:pressed {"
|
||
" background-color: %4;"
|
||
"}"
|
||
)
|
||
.arg(bg.name(), textColor.name(), bg.lighter(120).name(), bg.darker(120).name());
|
||
}
|
||
|
||
static QString separatorStyle()
|
||
{
|
||
return QStringLiteral(
|
||
"QLabel {"
|
||
" color: #6c7086;" // Catppuccin Overlay0
|
||
" font-size: 11px;"
|
||
" padding: 0 2px;"
|
||
"}"
|
||
);
|
||
}
|
||
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Construction
|
||
// ---------------------------------------------------------------------------
|
||
|
||
BreadcrumbToolBar::BreadcrumbToolBar(QWidget* parent)
|
||
: QToolBar(parent)
|
||
{
|
||
setObjectName(QStringLiteral("BreadcrumbToolBar"));
|
||
setWindowTitle(tr("Editing Context"));
|
||
setMovable(false);
|
||
setFloatable(false);
|
||
setIconSize(QSize(16, 16));
|
||
|
||
// Thin toolbar with minimal margins
|
||
setStyleSheet(QStringLiteral(
|
||
"QToolBar {"
|
||
" background: #1e1e2e;" // Catppuccin Base
|
||
" border: none;"
|
||
" spacing: 2px;"
|
||
" padding: 2px 4px;"
|
||
" max-height: 24px;"
|
||
"}"
|
||
));
|
||
}
|
||
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Update display from context
|
||
// ---------------------------------------------------------------------------
|
||
|
||
void BreadcrumbToolBar::updateContext(const EditingContext& ctx)
|
||
{
|
||
clearSegments();
|
||
buildSegments(ctx);
|
||
}
|
||
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Build breadcrumb segments
|
||
// ---------------------------------------------------------------------------
|
||
|
||
void BreadcrumbToolBar::clearSegments()
|
||
{
|
||
for (auto* btn : _segments) {
|
||
removeAction(btn->defaultAction());
|
||
delete btn;
|
||
}
|
||
_segments.clear();
|
||
|
||
for (auto* sep : _separators) {
|
||
delete sep;
|
||
}
|
||
_separators.clear();
|
||
|
||
clear();
|
||
}
|
||
|
||
void BreadcrumbToolBar::buildSegments(const EditingContext& ctx)
|
||
{
|
||
if (ctx.breadcrumb.isEmpty()) {
|
||
return;
|
||
}
|
||
|
||
for (int i = 0; i < ctx.breadcrumb.size(); ++i) {
|
||
// Add separator between segments
|
||
if (i > 0) {
|
||
auto* sep = new QLabel(QStringLiteral("\u203A")); // › character
|
||
sep->setStyleSheet(separatorStyle());
|
||
addWidget(sep);
|
||
_separators.append(sep);
|
||
}
|
||
|
||
auto* btn = new QToolButton(this);
|
||
btn->setText(ctx.breadcrumb[i]);
|
||
btn->setAutoRaise(true);
|
||
|
||
// Apply color from breadcrumb colors
|
||
QString color;
|
||
if (i < ctx.breadcrumbColors.size()) {
|
||
color = ctx.breadcrumbColors[i];
|
||
}
|
||
else {
|
||
color = ctx.color;
|
||
}
|
||
btn->setStyleSheet(chipStyle(color));
|
||
|
||
// Make clickable: clicking a parent segment navigates up
|
||
int segmentIndex = i;
|
||
connect(btn, &QToolButton::clicked, this, [this, segmentIndex]() {
|
||
segmentClicked(segmentIndex);
|
||
});
|
||
|
||
addWidget(btn);
|
||
_segments.append(btn);
|
||
}
|
||
}
|
||
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Navigation: clicking a breadcrumb segment
|
||
// ---------------------------------------------------------------------------
|
||
|
||
void BreadcrumbToolBar::segmentClicked(int index)
|
||
{
|
||
// Clicking the last segment does nothing (already there)
|
||
if (index >= _segments.size() - 1) {
|
||
return;
|
||
}
|
||
|
||
// Clicking a parent segment exits the current edit mode
|
||
auto* guiDoc = Application::Instance->activeDocument();
|
||
if (guiDoc && guiDoc->getInEdit()) {
|
||
guiDoc->resetEdit();
|
||
}
|
||
}
|
||
|
||
#include "moc_BreadcrumbToolBar.cpp"
|