12#include "TitleBar_p.h"
14#include "FloatingWindow_p.h"
16#include "WindowBeingDragged_p.h"
21#include "MDILayoutWidget_p.h"
22#include "TabWidget_p.h"
23#include "DockWidgetBase_p.h"
24#include "DockRegistry_p.h"
27#include <QWindowStateChangeEvent>
31TitleBar::TitleBar(Frame *parent)
32 : QWidgetAdapter(parent)
35 , m_floatingWindow(nullptr)
36 , m_genericWidget(nullptr)
37 , m_supportsAutoHide((
Config::self().flags() &
Config::Flag_AutoHideSupport) ==
Config::Flag_AutoHideSupport)
39 connect(m_frame, &Frame::numDockWidgetsChanged,
this, &TitleBar::updateCloseButton);
40 connect(m_frame, &Frame::isFocusedChanged,
this, &TitleBar::isFocusedChanged);
41 connect(m_frame, &Frame::isInMainWindowChanged,
this, &TitleBar::updateAutoHideButton);
49TitleBar::TitleBar(FloatingWindow *parent)
50 : QWidgetAdapter(parent)
53 , m_floatingWindow(parent)
54 , m_genericWidget(nullptr)
55 , m_supportsAutoHide((
Config::self().flags() &
Config::Flag_AutoHideSupport) ==
Config::Flag_AutoHideSupport)
57 connect(m_floatingWindow, &FloatingWindow::numFramesChanged,
this, &TitleBar::updateButtons);
58 connect(m_floatingWindow, &FloatingWindow::windowStateChanged,
this, &TitleBar::updateMaximizeButton);
59 connect(m_floatingWindow, &FloatingWindow::activatedChanged,
this, &TitleBar::isFocusedChanged);
64 : QWidgetAdapter(parent)
65 , Draggable(this, false)
67 , m_floatingWindow(nullptr)
68 , m_genericWidget(parent)
69 , m_supportsAutoHide(false)
78 connect(
this, &TitleBar::isFocusedChanged,
this, [
this] {
92bool TitleBar::onDoubleClicked()
98 }
else if (supportsFloatingButton()) {
108 if (m_floatingWindow || m_genericWidget)
112 return m_frame->mainWindow();
114 qWarning() << Q_FUNC_INFO <<
"null frame and null floating window";
118bool TitleBar::isMDI()
const
120 QObject *p =
const_cast<TitleBar *
>(
this);
122 if (qobject_cast<const QWindow *>(p)) {
127 if (qobject_cast<MDILayoutWidget *>(p))
130 if (qobject_cast<DropArea *>(p)) {
142void TitleBar::updateButtons()
146 updateMaximizeButton();
147 updateMinimizeButton();
148 updateAutoHideButton();
151void TitleBar::updateCloseButton()
154 const bool anyNonClosable = frame() ? frame()->anyNonClosable()
155 : (floatingWindow() ? floatingWindow()->anyNonClosable()
158 setCloseButtonEnabled(!anyNonClosable);
161void TitleBar::toggleMaximized()
163 if (!m_floatingWindow)
166 if (m_floatingWindow->isMaximizedOverride())
167 m_floatingWindow->showNormal();
169 m_floatingWindow->showMaximized();
174 QWidgetAdapter::focusInEvent(ev);
180 m_frame->FocusScope::focus(ev->
reason());
183bool TitleBar::isOverlayed()
const
185 return m_frame && m_frame->isOverlayed();
188void TitleBar::setCloseButtonEnabled(
bool enabled)
190 if (enabled != m_closeButtonEnabled) {
191 m_closeButtonEnabled = enabled;
192 Q_EMIT closeButtonEnabledChanged(enabled);
196void TitleBar::setFloatButtonVisible(
bool visible)
198 if (visible != m_floatButtonVisible) {
199 m_floatButtonVisible = visible;
200 Q_EMIT floatButtonVisibleChanged(visible);
204void TitleBar::setFloatButtonToolTip(
const QString &tip)
206 if (tip != m_floatButtonToolTip) {
207 m_floatButtonToolTip = tip;
208 Q_EMIT floatButtonToolTipChanged(tip);
212void TitleBar::setTitle(
const QString &title)
214 if (title != m_title) {
217 Q_EMIT titleChanged();
221void TitleBar::setIcon(
const QIcon &icon)
224 Q_EMIT iconChanged();
227std::unique_ptr<WindowBeingDragged> TitleBar::makeWindow()
237 qWarning() <<
"TitleBar::makeWindow shouldn't be called on invisible title bar"
238 <<
this << window()->isVisible();
240 qWarning() <<
"this=" <<
this <<
"; actual=" << m_frame->actualTitleBar();
241 }
else if (m_floatingWindow) {
242 qWarning() <<
"Has floating window with titlebar=" << m_floatingWindow->titleBar()
243 <<
"; fw->isVisible=" << m_floatingWindow->isVisible();
250 if (m_floatingWindow) {
252 return std::unique_ptr<WindowBeingDragged>(
new WindowBeingDragged(m_floatingWindow,
this));
255 if (FloatingWindow *fw = QWidgetAdapter::floatingWindow()) {
256 if (m_frame->isTheOnlyFrame()) {
257 qCDebug(hovering) <<
"TitleBar::makeWindow no detach needed";
258 return std::unique_ptr<WindowBeingDragged>(
new WindowBeingDragged(fw,
this));
262 QRect r = m_frame->QWidgetAdapter::geometry();
267 floatingWindow->show();
269 auto draggable = KDDockWidgets::usesNativeTitleBar() ?
static_cast<Draggable *
>(floatingWindow)
270 : static_cast<Draggable *>(this);
271 return std::unique_ptr<WindowBeingDragged>(
new WindowBeingDragged(floatingWindow, draggable));
277 return dockWidgets.
isEmpty() ? nullptr : dockWidgets.
first();
280bool TitleBar::supportsFloatingButton()
const
305 return !m_floatingWindow || m_floatingWindow->hasSingleFrame();
308bool TitleBar::supportsMaximizeButton()
const
310 return m_floatingWindow && m_floatingWindow->supportsMaximizeButton();
313bool TitleBar::supportsMinimizeButton()
const
315 return m_floatingWindow && m_floatingWindow->supportsMinimizeButton();
318bool TitleBar::supportsAutoHideButton()
const
321 return m_supportsAutoHide && m_frame && (m_frame->isInMainWindow() || m_frame->isOverlayed());
324bool TitleBar::hasIcon()
const
326 return !m_icon.isNull();
329bool TitleBar::isFocused()
const
332 return m_frame->isFocused();
333 else if (m_floatingWindow)
334 return m_floatingWindow->isActiveWindow();
335#ifdef KDDOCKWIDGETS_QTWIDGETS
337 else if (m_genericWidget)
338 return m_genericWidget->isActiveWindow();
343QIcon TitleBar::icon()
const
348void TitleBar::onCloseClicked()
353 if (closeOnlyCurrentTab) {
358 qWarning() << Q_FUNC_INFO <<
"Frame with no dock widgets";
361 if (m_frame->isTheOnlyFrame() && m_frame->isInFloatingWindow()) {
362 m_frame->window()->close();
367 }
else if (m_floatingWindow) {
369 if (closeOnlyCurrentTab) {
370 if (Frame *f = m_floatingWindow->singleFrame()) {
375 qWarning() << Q_FUNC_INFO <<
"Frame with no dock widgets";
378 m_floatingWindow->close();
381 m_floatingWindow->close();
383 }
else if (m_genericWidget) {
384 if (
auto window = m_genericWidget->window())
389bool TitleBar::isFloating()
const
391 if (m_floatingWindow)
395 return m_frame->isFloating();
400 qWarning() <<
"TitleBar::isFloating: shouldn't happen";
406 if (m_floatingWindow) {
408 for (Frame *f : m_floatingWindow->frames()) {
409 result << f->dockWidgets();
415 return m_frame->dockWidgets();
420 qWarning() <<
"TitleBar::dockWidget: shouldn't happen";
424void TitleBar::onFloatClicked()
431 qWarning() <<
"TitleBar::onFloatClicked: empty list. Shouldn't happen";
435 if (dockWidgets.
size() == 1) {
437 dockWidgets[0]->setFloating(
false);
443 if (!dockWidgets.
constFirst()->hasPreviousDockedLocation()) {
450 for (
auto dock : qAsConst(dockWidgets)) {
452 if (!current && dock->isCurrentTab())
456 dock->dptr()->m_lastPosition->m_tabIndex = i;
457 dock->setFloating(
false);
468 if (dockWidgets.
size() == 1) {
471 dockWidgets[0]->setFloating(
true);
478void TitleBar::onMaximizeClicked()
483void TitleBar::onMinimizeClicked()
485 if (!m_floatingWindow)
488 if (m_floatingWindow->isUtilityWindow()) {
494 m_floatingWindow->showMinimized();
497void TitleBar::onAutoHideClicked()
501 qWarning() << Q_FUNC_INFO <<
"Minimize not supported on floating windows";
505 const auto dockwidgets = m_frame->dockWidgets();
507 if (isOverlayed() && dockwidgets.size() != 1) {
509 qWarning() << Q_FUNC_INFO <<
"There can only be a single dock widget per titlebar overlayed";
514 const auto currentDw = m_frame->currentDockWidget();
515 auto registry = DockRegistry::self();
518 auto dw = dockwidgets.first();
520 auto sideBarGroup = groupedAutoHide ? registry->sideBarGroupingFor(dw) :
DockWidgetBase::List();
521 if (sideBarGroup.isEmpty()) {
525 for (
auto it = sideBarGroup.rbegin(); it != sideBarGroup.rend(); ++it) {
528 dw->setAsCurrentTab();
529 registry->removeSideBarGrouping(sideBarGroup);
534 registry->addSideBarGrouping(dockwidgets);
537 if (groupedAutoHide || dw == currentDw)
543bool TitleBar::closeButtonEnabled()
const
545 return m_closeButtonEnabled;
548bool TitleBar::floatButtonVisible()
const
550 return m_floatButtonVisible;
553QString TitleBar::floatButtonToolTip()
const
555 return m_floatButtonToolTip;
558void TitleBar::updateFloatButton()
560 setFloatButtonToolTip(floatingWindow() ? tr(
"Dock window") : tr(
"Undock window"));
561 setFloatButtonVisible(supportsFloatingButton());
564bool TitleBar::isWindow()
const
566 return m_floatingWindow !=
nullptr;
569TabBar *TitleBar::tabBar()
const
571 if (m_floatingWindow && m_floatingWindow->hasSingleFrame()) {
572 if (Frame *frame = m_floatingWindow->singleFrame()) {
573 return frame->tabWidget()->tabBar();
576 qWarning() << Q_FUNC_INFO <<
"Expected a frame";
579 }
else if (m_frame) {
580 return m_frame->tabWidget()->tabBar();
Application-wide config to tune certain behaviours of the framework.
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
Q_INVOKABLE void restoreFromSideBar(KDDockWidgets::DockWidgetBase *)
Removes the dock widget from the sidebar and docks it into the main window again.
Qt::FocusReason reason() const const
QObject * parent() const const
void moveTopLeft(const QPoint &position)
const T & constFirst() const const
bool isEmpty() const const