/* This file is part of KDDockWidgets. SPDX-FileCopyrightText: 2019-2023 Klarälvdalens Datakonsult AB, a KDAB Group company Author: Sérgio Martins SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only Contact KDAB at for commercial licensing options. */ #include "FrameworkWidgetFactory.h" #include "Config.h" #include "private/Frame_p.h" #include "private/TitleBar_p.h" #include "private/multisplitter/Separator_p.h" #include "private/FloatingWindow_p.h" #include "private/indicators/ClassicIndicators_p.h" #include "private/indicators/NullIndicators_p.h" #include "private/Utils_p.h" #include "private/TabWidget_p.h" #include #ifdef KDDOCKWIDGETS_QTWIDGETS #include "private/widgets/FrameWidget_p.h" #include "private/widgets/TitleBarWidget_p.h" #include "private/widgets/TabBarWidget_p.h" #include "private/widgets/SideBarWidget_p.h" #include "private/widgets/TabWidgetWidget_p.h" #include "private/multisplitter/Separator_qwidget.h" #include "private/widgets/FloatingWindowWidget_p.h" #include "private/indicators/SegmentedIndicators_p.h" #include #include #else #include "DockWidgetQuick.h" #include "private/quick/FrameQuick_p.h" #include "private/quick/TitleBarQuick_p.h" #include "private/quick/TabWidgetQuick_p.h" #include "private/quick/TabBarQuick_p.h" #include "private/quick/FloatingWindowQuick_p.h" #include "private/quick/RubberBandQuick.h" #include "private/multisplitter/Separator_quick.h" #endif // clazy:excludeall=ctor-missing-parent-argument using namespace KDDockWidgets; DropIndicatorType DefaultWidgetFactory::s_dropIndicatorType = DropIndicatorType::Classic; FrameworkWidgetFactory::~FrameworkWidgetFactory() { } #ifdef KDDOCKWIDGETS_QTWIDGETS Frame *DefaultWidgetFactory::createFrame(QWidgetOrQuick *parent, FrameOptions options) const { return new FrameWidget(parent, options); } TitleBar *DefaultWidgetFactory::createTitleBar(Frame *frame) const { return new TitleBarWidget(frame); } TitleBar *DefaultWidgetFactory::createTitleBar(FloatingWindow *fw) const { return new TitleBarWidget(fw); } TabBar *DefaultWidgetFactory::createTabBar(TabWidget *parent) const { return new TabBarWidget(parent); } TabWidget *DefaultWidgetFactory::createTabWidget(Frame *parent, TabWidgetOptions options) const { return new TabWidgetWidget(parent, options); } Layouting::Separator *DefaultWidgetFactory::createSeparator(Layouting::Widget *parent) const { return new Layouting::SeparatorWidget(parent); } FloatingWindow *DefaultWidgetFactory::createFloatingWindow(MainWindowBase *parent, FloatingWindowFlags flags) const { return new FloatingWindowWidget(QRect(), parent, flags); } FloatingWindow *DefaultWidgetFactory::createFloatingWindow(Frame *frame, MainWindowBase *parent, QRect suggestedGeometry) const { return new FloatingWindowWidget(frame, suggestedGeometry, parent); } DropIndicatorOverlayInterface *DefaultWidgetFactory::createDropIndicatorOverlay(DropArea *dropArea) const { #ifdef Q_OS_WASM // On WASM windows don't support translucency, which is required for the classic indicators. return new SegmentedIndicators(dropArea); #endif switch (s_dropIndicatorType) { case DropIndicatorType::Classic: return new ClassicIndicators(dropArea); case DropIndicatorType::Segmented: return new SegmentedIndicators(dropArea); case DropIndicatorType::None: return new NullIndicators(dropArea); } return new ClassicIndicators(dropArea); } QWidgetOrQuick *DefaultWidgetFactory::createRubberBand(QWidgetOrQuick *parent) const { return new QRubberBand(QRubberBand::Rectangle, parent); } SideBar *DefaultWidgetFactory::createSideBar(SideBarLocation loc, MainWindowBase *parent) const { return new SideBarWidget(loc, parent); } QAbstractButton *DefaultWidgetFactory::createTitleBarButton(QWidget *parent, TitleBarButtonType type) const { if (!parent) { qWarning() << Q_FUNC_INFO << "Parent not provided"; return nullptr; } auto button = new Button(parent); button->setIcon(iconForButtonType(type, parent->devicePixelRatioF())); return button; } #else Frame *DefaultWidgetFactory::createFrame(QWidgetOrQuick *parent, FrameOptions options) const { return new FrameQuick(parent, options); } TitleBar *DefaultWidgetFactory::createTitleBar(Frame *frame) const { return new TitleBarQuick(frame); } TitleBar *DefaultWidgetFactory::createTitleBar(FloatingWindow *fw) const { return new TitleBarQuick(fw); } /*Separator *DefaultWidgetFactory::createSeparator(QWidgetAdapter *parent) const { return new SeparatorQuick(parent); }*/ FloatingWindow *DefaultWidgetFactory::createFloatingWindow(MainWindowBase *parent, FloatingWindowFlags flags) const { return new FloatingWindowQuick(parent, flags); } FloatingWindow *DefaultWidgetFactory::createFloatingWindow(Frame *frame, MainWindowBase *parent, QRect suggestedGeometry) const { return new FloatingWindowQuick(frame, suggestedGeometry, parent); } DropIndicatorOverlayInterface *DefaultWidgetFactory::createDropIndicatorOverlay(DropArea *dropArea) const { switch (s_dropIndicatorType) { case DropIndicatorType::Classic: return new ClassicIndicators(dropArea); case DropIndicatorType::Segmented: qWarning() << "Segmented indicators not supported for QtQuick yet"; return new NullIndicators(dropArea); case DropIndicatorType::None: return new NullIndicators(dropArea); } return new ClassicIndicators(dropArea); } TabBar *DefaultWidgetFactory::createTabBar(TabWidget *parent) const { return new TabBarQuick(parent); } TabWidget *DefaultWidgetFactory::createTabWidget(Frame *parent, TabWidgetOptions) const { return new TabWidgetQuick(parent); } Layouting::Separator *DefaultWidgetFactory::createSeparator(Layouting::Widget *parent) const { return new Layouting::SeparatorQuick(parent); } QWidgetOrQuick *DefaultWidgetFactory::createRubberBand(QWidgetOrQuick *parent) const { return new RubberBandQuick(parent); } SideBar *DefaultWidgetFactory::createSideBar(SideBarLocation loc, MainWindowBase *parent) const { Q_UNUSED(loc); Q_UNUSED(parent); qWarning() << Q_FUNC_INFO << "Not implemented yet"; return nullptr; } QUrl DefaultWidgetFactory::titleBarFilename() const { return QUrl(QStringLiteral("qrc:/kddockwidgets/private/quick/qml/TitleBar.qml")); } QUrl DefaultWidgetFactory::dockwidgetFilename() const { return QUrl(QStringLiteral("qrc:/kddockwidgets/private/quick/qml/DockWidget.qml")); } QUrl DefaultWidgetFactory::frameFilename() const { return QUrl(QStringLiteral("qrc:/kddockwidgets/private/quick/qml/Frame.qml")); } QUrl DefaultWidgetFactory::floatingWindowFilename() const { return QUrl(QStringLiteral("qrc:/kddockwidgets/private/quick/qml/FloatingWindow.qml")); } #endif // QtQuick // iconForButtonType impl is the same for QtQuick and QtWidgets QIcon DefaultWidgetFactory::iconForButtonType(TitleBarButtonType type, qreal dpr) const { auto key = std::make_pair(type, dpr); auto it = m_cachedIcons.find(key); if (it != m_cachedIcons.end()) return *it; QString iconName; switch (type) { case TitleBarButtonType::AutoHide: iconName = QStringLiteral("auto-hide"); break; case TitleBarButtonType::UnautoHide: iconName = QStringLiteral("unauto-hide"); break; case TitleBarButtonType::Close: iconName = QStringLiteral("close"); break; case TitleBarButtonType::Minimize: iconName = QStringLiteral("min"); break; case TitleBarButtonType::Maximize: iconName = QStringLiteral("max"); break; case TitleBarButtonType::Normal: // We're using the same icon as dock/float iconName = QStringLiteral("dock-float"); break; case TitleBarButtonType::Float: iconName = QStringLiteral("dock-float"); break; } if (iconName.isEmpty()) return {}; QIcon icon(QStringLiteral(":/img/%1.png").arg(iconName)); auto atScopeEnd = qScopeGuard([&icon, this, key] { m_cachedIcons.insert(key, icon); }); if (!scalingFactorIsSupported(dpr)) return icon; // Not using Qt's sugar syntax, which doesn't support 1.5x anyway when we need it. // Simply add the high-res files and Qt will pick them when needed if (scalingFactorIsSupported(1.5)) icon.addFile(QStringLiteral(":/img/%1-1.5x.png").arg(iconName)); icon.addFile(QStringLiteral(":/img/%1-2x.png").arg(iconName)); return icon; } void DefaultWidgetFactory::clearIconCache() { m_cachedIcons.clear(); }