23
#include "PreCompiled.h"
27
# include <QApplication>
30
# include <QDockWidget>
31
# include <QHeaderView>
37
# include <QSpacerItem>
40
# include <QTextStream>
41
# include <QTimerEvent>
47
#include <QPainterPath>
48
#include <QPropertyAnimation>
51
#include <unordered_map>
53
#include "OverlayWidgets.h"
55
#include <Base/Tools.h>
56
#include <Base/Console.h>
57
#include <App/Application.h>
58
#include "Application.h"
59
#include "BitmapFactory.h"
64
#include "MainWindow.h"
67
#include "OverlayManager.h"
68
#include "OverlayParams.h"
69
#include "TaskView/TaskView.h"
71
#include "TreeParams.h"
72
#include "propertyeditor/PropertyEditor.h"
74
FC_LOG_LEVEL_INIT("Dock", true, true);
78
OverlayDragFrame *OverlayTabWidget::_DragFrame;
79
QDockWidget *OverlayTabWidget::_DragFloating;
80
QWidget *OverlayTabWidget::_Dragging;
81
OverlayTabWidget *OverlayTabWidget::_LeftOverlay;
82
OverlayTabWidget *OverlayTabWidget::_RightOverlay;
83
OverlayTabWidget *OverlayTabWidget::_TopOverlay;
84
OverlayTabWidget *OverlayTabWidget::_BottomOverlay;
86
static inline int widgetMinSize(const QWidget *widget, bool margin=false)
88
return widget->fontMetrics().ascent()
89
+ widget->fontMetrics().descent() + (margin?4:0);
94
OverlayProxyWidget::OverlayProxyWidget(OverlayTabWidget *tabOverlay)
95
:QWidget(tabOverlay->parentWidget()), owner(tabOverlay), _hintColor(QColor(50,50,50,150))
97
dockArea = owner->getDockArea();
98
timer.setSingleShot(true);
99
QObject::connect(&timer, &QTimer::timeout, this, &OverlayProxyWidget::onTimer);
100
setAttribute(Qt::WA_TransparentForMouseEvents, true);
103
bool OverlayProxyWidget::isActivated() const
105
return drawLine && isVisible();
108
OverlayProxyWidget::HitTest OverlayProxyWidget::hitTest(const QPoint &globalPt, bool delay)
110
if (!isVisible() || !owner->count())
111
return HitTest::HitNone;
113
auto pt = mapFromGlobal(globalPt);
115
QTabBar *tabbar = owner->tabBar();
116
if (tabbar->isVisible() && tabbar->tabAt(pt)>=0) {
117
ToolTip::showText(globalPt, QObject::tr("Press ESC to hide hint"), this);
118
return HitTest::HitOuter;
121
HitTest hit = HitTest::HitNone;
122
QRect rect = this->getRect();
123
QSize s = this->size();
124
int hintSize = OverlayParams::getDockOverlayHintTriggerSize();
128
case Qt::LeftDockWidgetArea:
129
if (pt.y() >= 0 && pt.y() <= s.height() && pt.x() > 0 && pt.x() < hintSize)
130
hit = HitTest::HitOuter;
132
case Qt::RightDockWidgetArea:
133
if (pt.y() >= 0 && pt.y() <= s.height() && pt.x() < s.width() && pt.x() > -hintSize)
134
hit = HitTest::HitOuter;
136
case Qt::TopDockWidgetArea:
137
if (pt.x() >= 0 && pt.x() <= s.width() && pt.y() > 0 && pt.y() < hintSize)
138
hit = HitTest::HitOuter;
140
case Qt::BottomDockWidgetArea:
141
if (pt.x() >= 0 && pt.x() <= s.width() && pt.y() < s.height() && pt.y() > -hintSize)
142
hit = HitTest::HitOuter;
145
if (rect.contains(pt)) {
146
hit = HitTest::HitInner;
147
ToolTip::showText(globalPt, QObject::tr("Press ESC to hide hint"), this);
151
if (owner->getState() == OverlayTabWidget::State::HintHidden) {
152
if (hit == HitTest::HitNone)
153
owner->setState(OverlayTabWidget::State::Normal);
155
hit = HitTest::HitNone;
159
if (hit != HitTest::HitNone) {
163
if (!timer.isActive())
164
timer.start(OverlayParams::getDockOverlayHintDelay());
168
owner->setState(OverlayTabWidget::State::Hint);
173
auto view = getMainWindow()->activeWindow();
174
auto overlayOnHoverAllowed = view && view->onHasMsg("AllowsOverlayOnHover");
176
if(owner->getState() != OverlayTabWidget::State::Hidden
177
&& hit == HitTest::HitOuter
178
&& overlayOnHoverAllowed
179
&& OverlayParams::getDockOverlayActivateOnHover()) {
180
if (owner->isVisible() && owner->tabBar()->isVisible()) {
181
QSize size = owner->tabBar()->size();
182
QPoint pt = owner->tabBar()->mapToGlobal(
183
QPoint(size.width(), size.height()));
184
QPoint pos = QCursor::pos();
185
switch(this->dockArea) {
186
case Qt::LeftDockWidgetArea:
187
case Qt::RightDockWidgetArea:
188
if (pos.y() < pt.y())
189
return HitTest::HitNone;
191
case Qt::TopDockWidgetArea:
192
case Qt::BottomDockWidgetArea:
193
if (pos.x() < pt.x())
194
return HitTest::HitNone;
200
owner->setState(OverlayTabWidget::State::Showing);
203
} else if (!drawLine) {
206
if (!timer.isActive())
207
timer.start(OverlayParams::getDockOverlayHintDelay());
210
owner->setState(OverlayTabWidget::State::Normal);
218
void OverlayProxyWidget::onTimer()
220
hitTest(QCursor::pos(), false);
223
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
224
void OverlayProxyWidget::enterEvent(QEvent *)
226
void OverlayProxyWidget::enterEvent(QEnterEvent *)
233
if (!timer.isActive())
234
timer.start(OverlayParams::getDockOverlayHintDelay());
238
void OverlayProxyWidget::hideEvent(QHideEvent *)
243
void OverlayProxyWidget::onMousePress()
248
if (owner->getState() == OverlayTabWidget::State::HintHidden)
251
owner->setState(OverlayTabWidget::State::Showing);
254
QBrush OverlayProxyWidget::hintColor() const
259
void OverlayProxyWidget::setHintColor(const QBrush &brush)
264
QRect OverlayProxyWidget::getRect() const
266
QRect rect = this->rect();
267
if (owner->isVisible() && owner->tabBar()->isVisible()) {
268
QSize size = owner->tabBar()->size();
269
QPoint pt = owner->tabBar()->mapToGlobal(
270
QPoint(size.width(), size.height()));
271
pt = this->mapFromGlobal(pt);
272
switch(this->dockArea) {
273
case Qt::LeftDockWidgetArea:
274
case Qt::RightDockWidgetArea:
277
case Qt::TopDockWidgetArea:
278
case Qt::BottomDockWidgetArea:
279
rect.setLeft(pt.x());
285
switch(this->dockArea) {
286
case Qt::LeftDockWidgetArea:
287
if (int offset = OverlayParams::getDockOverlayHintLeftOffset())
288
rect.moveTop(std::max(rect.top()+offset, rect.bottom()-10));
289
if (int length = OverlayParams::getDockOverlayHintLeftLength())
290
rect.setHeight(std::min(length, rect.height()));
292
case Qt::RightDockWidgetArea:
293
if (int offset = OverlayParams::getDockOverlayHintRightOffset())
294
rect.moveTop(std::max(rect.top()+offset, rect.bottom()-10));
295
if (int length = OverlayParams::getDockOverlayHintRightLength())
296
rect.setHeight(std::min(length, rect.height()));
298
case Qt::TopDockWidgetArea:
299
if (int offset = OverlayParams::getDockOverlayHintTopOffset())
300
rect.moveLeft(std::max(rect.left()+offset, rect.right()-10));
301
if (int length = OverlayParams::getDockOverlayHintTopLength())
302
rect.setWidth(std::min(length, rect.width()));
304
case Qt::BottomDockWidgetArea:
305
if (int offset = OverlayParams::getDockOverlayHintBottomOffset())
306
rect.moveLeft(std::max(rect.left()+offset, rect.right()-10));
307
if (int length = OverlayParams::getDockOverlayHintBottomLength())
308
rect.setWidth(std::min(length, rect.width()));
316
void OverlayProxyWidget::paintEvent(QPaintEvent *)
320
QPainter painter(this);
321
painter.setOpacity(_hintColor.color().alphaF());
322
painter.setPen(Qt::transparent);
323
painter.setBrush(_hintColor);
325
QRect rect = this->getRect();
326
painter.drawRect(rect);
329
OverlayToolButton::OverlayToolButton(QWidget *parent)
332
setCursor(Qt::ArrowCursor);
337
OverlayTabWidget::OverlayTabWidget(QWidget *parent, Qt::DockWidgetArea pos)
338
:QTabWidget(parent), dockArea(pos)
347
splitter = new OverlaySplitter(this);
349
_graphicsEffect = new OverlayGraphicsEffect(splitter);
350
splitter->setGraphicsEffect(_graphicsEffect);
352
_graphicsEffectTab = new OverlayGraphicsEffect(this);
353
_graphicsEffectTab->setEnabled(false);
354
tabBar()->setGraphicsEffect(_graphicsEffectTab);
356
Command *cmdHide = nullptr;
358
case Qt::LeftDockWidgetArea:
360
setTabPosition(QTabWidget::West);
361
splitter->setOrientation(Qt::Vertical);
362
cmdHide = Application::Instance->commandManager().getCommandByName("Std_DockOverlayToggleLeft");
364
case Qt::RightDockWidgetArea:
365
_RightOverlay = this;
366
setTabPosition(QTabWidget::East);
367
splitter->setOrientation(Qt::Vertical);
368
cmdHide = Application::Instance->commandManager().getCommandByName("Std_DockOverlayToggleRight");
370
case Qt::TopDockWidgetArea:
372
setTabPosition(QTabWidget::North);
373
splitter->setOrientation(Qt::Horizontal);
374
cmdHide = Application::Instance->commandManager().getCommandByName("Std_DockOverlayToggleTop");
376
case Qt::BottomDockWidgetArea:
377
_BottomOverlay = this;
378
setTabPosition(QTabWidget::South);
379
splitter->setOrientation(Qt::Horizontal);
380
cmdHide = Application::Instance->commandManager().getCommandByName("Std_DockOverlayToggleBottom");
386
proxyWidget = new OverlayProxyWidget(this);
388
_setOverlayMode(proxyWidget,OverlayOption::Enable);
390
setOverlayMode(true);
393
actTransparent.setCheckable(true);
394
actTransparent.setData(QStringLiteral("OBTN Transparent"));
395
actTransparent.setParent(this);
396
addAction(&actTransparent);
398
actAutoHide.setData(QStringLiteral("OBTN AutoHide"));
400
actEditHide.setData(QStringLiteral("OBTN EditHide"));
402
actEditShow.setData(QStringLiteral("OBTN EditShow"));
404
actTaskShow.setData(QStringLiteral("OBTN TaskShow"));
406
actNoAutoMode.setData(QStringLiteral("OBTN NoAutoMode"));
408
actAutoMode.setData(QStringLiteral("OBTN AutoMode"));
409
actAutoMode.setParent(this);
411
autoModeMenu.setToolTipsVisible(true);
412
autoModeMenu.addAction(&actNoAutoMode);
413
autoModeMenu.addAction(&actAutoHide);
414
autoModeMenu.addAction(&actEditShow);
415
autoModeMenu.addAction(&actEditHide);
416
autoModeMenu.addAction(&actTaskShow);
417
addAction(&actAutoMode);
419
actOverlay.setData(QStringLiteral("OBTN Overlay"));
420
actOverlay.setParent(this);
421
addAction(&actOverlay);
424
cmdHide->addTo(this);
429
connect(tabBar(), &QTabBar::tabBarClicked, this, &OverlayTabWidget::onCurrentChanged);
430
connect(tabBar(), &QTabBar::tabMoved, this, &OverlayTabWidget::onTabMoved);
431
tabBar()->installEventFilter(this);
433
timer.setSingleShot(true);
434
connect(&timer, &QTimer::timeout, this, &OverlayTabWidget::setupLayout);
436
repaintTimer.setSingleShot(true);
437
connect(&repaintTimer, &QTimer::timeout, this, &OverlayTabWidget::onRepaint);
439
_animator = new QPropertyAnimation(this, "animation", this);
440
_animator->setStartValue(0.0);
441
_animator->setEndValue(1.0);
442
connect(_animator, &QAbstractAnimation::stateChanged,
443
this, &OverlayTabWidget::onAnimationStateChanged);
446
void OverlayTabWidget::refreshIcons()
449
App::GetApplication()
450
.GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow")
451
->GetASCII("StyleSheet", "None");
455
if (isStyleSheetDark(curStyleSheet)) {
456
actOverlay.setIcon(BitmapFactory().pixmap("qss:overlay/icons/overlay_light.svg"));
457
actNoAutoMode.setIcon(BitmapFactory().pixmap("qss:overlay/icons/mode_light.svg"));
458
actTaskShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/taskshow_light.svg"));
459
actEditShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/editshow_light.svg"));
460
actEditHide.setIcon(BitmapFactory().pixmap("qss:overlay/icons/edithide_light.svg"));
461
actTransparent.setIcon(BitmapFactory().pixmap("qss:overlay/icons/transparent_light.svg"));
462
pxAutoHide = BitmapFactory().pixmap("qss:overlay/icons/autohide_light.svg");
465
actOverlay.setIcon(BitmapFactory().pixmap("qss:overlay/icons/overlay.svg"));
466
actNoAutoMode.setIcon(BitmapFactory().pixmap("qss:overlay/icons/mode.svg"));
467
actTaskShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/taskshow.svg"));
468
actEditShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/editshow.svg"));
469
actEditHide.setIcon(BitmapFactory().pixmap("qss:overlay/icons/edithide.svg"));
470
actTransparent.setIcon(BitmapFactory().pixmap("qss:overlay/icons/transparent.svg"));
471
pxAutoHide = BitmapFactory().pixmap("qss:overlay/icons/autohide.svg");
474
actAutoHide.setIcon(rotateAutoHideIcon(pxAutoHide, dockArea));
479
void OverlayTabWidget::onAnimationStateChanged()
481
if (_animator->state() != QAbstractAnimation::Running) {
483
if (_animator->startValue().toReal() == 0.0) {
485
OverlayManager::instance()->refresh();
487
if (_state == State::Showing)
488
setState(State::Normal);
492
void OverlayTabWidget::setAnimation(qreal t)
494
if (t != _animation) {
500
void OverlayTabWidget::startShow()
502
if (isVisible() || _state > State::Normal) {
506
int duration = OverlayParams::getDockOverlayAnimationDuration();
507
bool setmode = _state != State::Showing;
509
_animator->setStartValue(1.0);
510
_animator->setEndValue(0.0);
511
_animator->setDuration(duration);
512
_animator->setEasingCurve((QEasingCurve::Type)OverlayParams::getDockOverlayAnimationCurve());
515
else if (_state == State::Showing)
516
setState(State::Normal);
521
setOverlayMode(overlaid);
524
QWidget *OverlayTabWidget::createTitleButton(QAction *action, int size)
526
auto button = new OverlayToolButton(nullptr);
527
button->setObjectName(action->data().toString());
528
button->setDefaultAction(action);
529
button->setAutoRaise(true);
530
button->setContentsMargins(0,0,0,0);
531
button->setFixedSize(size,size);
535
void OverlayTabWidget::startHide()
538
|| _state > State::Normal
539
|| (_animator->state() == QAbstractAnimation::Running
540
&& _animator->startValue().toReal() == 0.0))
542
int duration = OverlayParams::getDockOverlayAnimationDuration();
546
_animator->setStartValue(0.0);
547
_animator->setEndValue(1.0);
548
_animator->setDuration(duration);
549
_animator->setEasingCurve((QEasingCurve::Type)OverlayParams::getDockOverlayAnimationCurve());
554
bool OverlayTabWidget::event(QEvent *ev)
557
case QEvent::MouseButtonRelease:
558
if(mouseGrabber() == this) {
564
case QEvent::MouseMove:
565
case QEvent::ContextMenu:
566
if(QApplication::mouseButtons() == Qt::NoButton && mouseGrabber() == this) {
572
case QEvent::MouseButtonPress:
578
return QTabWidget::event(ev);
581
int OverlayTabWidget::testAlpha(const QPoint &_pos, int radiusScale)
583
if (!count() || (!isOverlaid() && !isTransparent()) || !isVisible())
586
if (tabBar()->isVisible() && tabBar()->tabAt(tabBar()->mapFromGlobal(_pos))>=0)
589
if (titleBar->isVisible() && titleBar->rect().contains(titleBar->mapFromGlobal(_pos)))
592
if (!splitter->isVisible())
595
auto pos = splitter->mapFromGlobal(_pos);
596
QSize size = splitter->size();
597
if (pos.x() < 0 || pos.y() < 0
598
|| pos.x() >= size.width()
599
|| pos.y() >= size.height())
601
if (this->rect().contains(this->mapFromGlobal(_pos)))
606
if (_image.isNull()) {
607
auto pixmap = splitter->grab();
608
_imageScale = pixmap.devicePixelRatio();
609
_image = pixmap.toImage();
612
int res = qAlpha(_image.pixel(pos*_imageScale));
613
int radius = OverlayParams::getDockOverlayAlphaRadius() * radiusScale;
614
if (res || radius<=0 )
617
radius *= _imageScale;
618
for (int i=-radius; i<radius; ++i) {
619
for (int j=-radius; j<radius; ++j) {
620
if (pos.x()+i < 0 || pos.y()+j < 0
621
|| pos.x()+i >= size.width()
622
|| pos.y()+j >= size.height())
624
res = qAlpha(_image.pixel(pos*_imageScale + QPoint(i,j)));
632
void OverlayTabWidget::paintEvent(QPaintEvent *ev)
634
Base::StateLocker guard(repainting);
636
if (!_image.isNull())
638
QTabWidget::paintEvent(ev);
641
void OverlayTabWidget::onRepaint()
643
Base::StateLocker guard(repainting);
645
if (!_image.isNull())
650
void OverlayTabWidget::scheduleRepaint()
656
repaintTimer.start(100);
660
QColor OverlayTabWidget::effectColor() const
662
return _graphicsEffect->color();
665
void OverlayTabWidget::setEffectColor(const QColor &color)
667
_graphicsEffect->setColor(color);
668
_graphicsEffectTab->setColor(color);
671
int OverlayTabWidget::effectWidth() const
673
return _graphicsEffect->size().width();
676
void OverlayTabWidget::setEffectWidth(int s)
678
auto size = _graphicsEffect->size();
680
_graphicsEffect->setSize(size);
681
_graphicsEffectTab->setSize(size);
684
int OverlayTabWidget::effectHeight() const
686
return _graphicsEffect->size().height();
689
void OverlayTabWidget::setEffectHeight(int s)
691
auto size = _graphicsEffect->size();
693
_graphicsEffect->setSize(size);
694
_graphicsEffectTab->setSize(size);
697
qreal OverlayTabWidget::effectOffsetX() const
699
return _graphicsEffect->offset().x();
702
void OverlayTabWidget::setEffectOffsetX(qreal d)
704
auto offset = _graphicsEffect->offset();
706
_graphicsEffect->setOffset(offset);
707
_graphicsEffectTab->setOffset(offset);
710
qreal OverlayTabWidget::effectOffsetY() const
712
return _graphicsEffect->offset().y();
715
void OverlayTabWidget::setEffectOffsetY(qreal d)
717
auto offset = _graphicsEffect->offset();
719
_graphicsEffect->setOffset(offset);
720
_graphicsEffectTab->setOffset(offset);
723
qreal OverlayTabWidget::effectBlurRadius() const
725
return _graphicsEffect->blurRadius();
728
void OverlayTabWidget::setEffectBlurRadius(qreal r)
730
_graphicsEffect->setBlurRadius(r);
731
_graphicsEffectTab->setBlurRadius(r);
734
bool OverlayTabWidget::effectEnabled() const
736
return _effectEnabled;
739
void OverlayTabWidget::setEffectEnabled(bool enable)
741
_effectEnabled = enable;
744
bool OverlayTabWidget::eventFilter(QObject *o, QEvent *ev)
746
if(ev->type() == QEvent::Resize && o == tabBar()) {
747
if (_state <= State::Normal)
750
return QTabWidget::eventFilter(o, ev);
753
void OverlayTabWidget::restore(ParameterGrp::handle handle)
761
std::string widgets = handle->GetASCII("Widgets","");
762
for(auto &name : QString::fromUtf8(widgets.c_str()).split(QLatin1Char(','))) {
765
OverlayManager::instance()->registerDockWidget(name, this);
766
auto dock = getMainWindow()->findChild<QDockWidget*>(name);
768
addWidget(dock, dock->windowTitle());
770
int width = handle->GetInt("Width", 0);
771
int height = handle->GetInt("Height", 0);
772
int offset1 = handle->GetInt("Offset1", 0);
773
int offset2 = handle->GetInt("Offset3", 0);
774
setOffset(QSize(offset1,offset2));
775
setSizeDelta(handle->GetInt("Offset2", 0));
776
if(width && height) {
777
QRect rect(0, 0, width, height);
779
case Qt::RightDockWidgetArea:
780
rect.moveRight(parentWidget()->size().width());
782
case Qt::BottomDockWidgetArea:
783
rect.moveBottom(parentWidget()->size().height());
790
if (handle->GetBool("AutoHide", false))
791
setAutoMode(AutoMode::AutoHide);
792
else if (handle->GetBool("EditHide", false))
793
setAutoMode(AutoMode::EditHide);
794
else if (handle->GetBool("EditShow", false))
795
setAutoMode(AutoMode::EditShow);
796
else if (handle->GetBool("TaskShow", false))
797
setAutoMode(AutoMode::TaskShow);
799
setAutoMode(AutoMode::NoAutoMode);
801
setTransparent(handle->GetBool("Transparent", false));
804
std::string savedSizes = handle->GetASCII("Sizes","");
807
for(auto &size : QString::fromUtf8(savedSizes.c_str()).split(QLatin1Char(','))) {
808
sizes.append(size.toInt());
809
_sizemap[dockWidget(idx++)] = sizes.back();
812
FC_LOG("restore " << objectName().toUtf8().constData() << " " << savedSizes);
814
getSplitter()->setSizes(sizes);
818
void OverlayTabWidget::saveTabs()
823
std::ostringstream os, os2;
825
auto sizes = splitter->sizes();
827
for(int i=0,c=splitter->count(); i<c; ++i) {
828
auto dock = dockWidget(i);
831
if(dock->objectName().size()) {
832
os << dock->objectName().toUtf8().constData() << ",";
839
_sizemap[dock] = sizes[i];
841
Base::StateLocker lock(_saving);
842
hGrp->SetASCII("Widgets", os.str().c_str());
843
hGrp->SetASCII("Sizes", os2.str().c_str());
844
FC_LOG("save " << objectName().toUtf8().constData() << " " << os2.str());
847
void OverlayTabWidget::onTabMoved(int from, int to)
849
QWidget *w = splitter->widget(from);
850
splitter->insertWidget(to,w);
854
void OverlayTabWidget::setTitleBar(QWidget *w)
859
void OverlayTabWidget::changeEvent(QEvent *e)
861
QTabWidget::changeEvent(e);
862
if (e->type() == QEvent::LanguageChange)
866
void OverlayTabWidget::retranslate()
868
actTransparent.setToolTip(tr("Toggle transparent mode"));
869
actNoAutoMode.setText(tr("None"));
870
actNoAutoMode.setToolTip(tr("Turn off auto hide/show"));
871
actAutoHide.setText(tr("Auto hide"));
872
actAutoHide.setToolTip(tr("Auto hide docked widgets on leave"));
873
actEditHide.setText(tr("Hide on edit"));
874
actEditHide.setToolTip(tr("Auto hide docked widgets on editing"));
875
actEditShow.setText(tr("Show on edit"));
876
actEditShow.setToolTip(tr("Auto show docked widgets on editing"));
877
actTaskShow.setText(tr("Auto task"));
878
actTaskShow.setToolTip(tr("Auto show task view for any current task, and hide the view when there is no task."));
879
actOverlay.setToolTip(tr("Toggle overlay"));
883
void OverlayTabWidget::syncAutoMode()
886
App::GetApplication()
887
.GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow")
888
->GetASCII("StyleSheet", "None");
890
QAction* action = nullptr;
892
case AutoMode::AutoHide:
893
action = &actAutoHide;
894
if (isStyleSheetDark(curStyleSheet)) {
895
QPixmap pxAutoHideMode =
896
BitmapFactory().pixmap("qss:overlay/icons/autohide_lighter.svg");
897
pxAutoHideMode = rotateAutoHideIcon(pxAutoHideMode, dockArea);
898
action->setIcon(pxAutoHideMode);
899
actNoAutoMode.setIcon(BitmapFactory().pixmap("qss:overlay/icons/mode_light.svg"));
900
actTaskShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/taskshow_light.svg"));
901
actEditShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/editshow_light.svg"));
902
actEditHide.setIcon(BitmapFactory().pixmap("qss:overlay/icons/edithide_light.svg"));
905
QPixmap pxAutoHideMode = BitmapFactory().pixmap("qss:overlay/icons/autohide.svg");
906
pxAutoHideMode = rotateAutoHideIcon(pxAutoHideMode, dockArea);
907
action->setIcon(pxAutoHideMode);
908
actNoAutoMode.setIcon(
909
BitmapFactory().pixmap("qss:overlay/icons/mode_lightgray.svg"));
911
BitmapFactory().pixmap("qss:overlay/icons/taskshow_lightgray.svg"));
913
BitmapFactory().pixmap("qss:overlay/icons/editshow_lightgray.svg"));
915
BitmapFactory().pixmap("qss:overlay/icons/edithide_lightgray.svg"));
918
case AutoMode::EditShow:
919
action = &actEditShow;
920
if (isStyleSheetDark(curStyleSheet)) {
921
QPixmap pxEditShowMode =
922
BitmapFactory().pixmap("qss:overlay/icons/editshow_lighter.svg");
923
action->setIcon(pxEditShowMode);
924
QPixmap pxAutoHideMode =
925
BitmapFactory().pixmap("qss:overlay/icons/autohide_light.svg");
926
pxAutoHideMode = rotateAutoHideIcon(pxAutoHideMode, dockArea);
927
actAutoHide.setIcon(pxAutoHideMode);
928
actNoAutoMode.setIcon(BitmapFactory().pixmap("qss:overlay/icons/mode_light.svg"));
929
actTaskShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/taskshow_light.svg"));
930
actEditHide.setIcon(BitmapFactory().pixmap("qss:overlay/icons/edithide_light.svg"));
933
QPixmap pxEditShowMode = BitmapFactory().pixmap("qss:overlay/icons/editshow.svg");
934
action->setIcon(pxEditShowMode);
935
QPixmap pxAutoHideMode =
936
BitmapFactory().pixmap("qss:overlay/icons/autohide_lightgray.svg");
937
pxAutoHideMode = rotateAutoHideIcon(pxAutoHideMode, dockArea);
938
actAutoHide.setIcon(pxAutoHideMode);
939
actNoAutoMode.setIcon(
940
BitmapFactory().pixmap("qss:overlay/icons/mode_lightgray.svg"));
942
BitmapFactory().pixmap("qss:overlay/icons/taskshow_lightgray.svg"));
944
BitmapFactory().pixmap("qss:overlay/icons/edithide_lightgray.svg"));
947
case AutoMode::TaskShow:
948
action = &actTaskShow;
949
if (isStyleSheetDark(curStyleSheet)) {
950
QPixmap pxTaskShowMode =
951
BitmapFactory().pixmap("qss:overlay/icons/taskshow_lighter.svg");
952
action->setIcon(pxTaskShowMode);
953
QPixmap pxAutoHideMode =
954
BitmapFactory().pixmap("qss:overlay/icons/autohide_light.svg");
955
pxAutoHideMode = rotateAutoHideIcon(pxAutoHideMode, dockArea);
956
actNoAutoMode.setIcon(BitmapFactory().pixmap("qss:overlay/icons/mode_light.svg"));
957
actEditShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/editshow_light.svg"));
958
actAutoHide.setIcon(pxAutoHideMode);
959
actEditHide.setIcon(BitmapFactory().pixmap("qss:overlay/icons/edithide_light.svg"));
962
QPixmap pxTaskShowMode = BitmapFactory().pixmap("qss:overlay/icons/taskshow.svg");
963
action->setIcon(pxTaskShowMode);
964
QPixmap pxAutoHideMode =
965
BitmapFactory().pixmap("qss:overlay/icons/autohide_lightgray.svg");
966
pxAutoHideMode = rotateAutoHideIcon(pxAutoHideMode, dockArea);
967
actNoAutoMode.setIcon(
968
BitmapFactory().pixmap("qss:overlay/icons/mode_lightgray.svg"));
970
BitmapFactory().pixmap("qss:overlay/icons/editshow_lightgray.svg"));
971
actAutoHide.setIcon(pxAutoHideMode);
973
BitmapFactory().pixmap("qss:overlay/icons/edithide_lightgray.svg"));
976
case AutoMode::EditHide:
977
action = &actEditHide;
978
if (isStyleSheetDark(curStyleSheet)) {
979
QPixmap pxEditHideMode =
980
BitmapFactory().pixmap("qss:overlay/icons/edithide_lighter.svg");
981
action->setIcon(pxEditHideMode);
982
QPixmap pxAutoHideMode =
983
BitmapFactory().pixmap("qss:overlay/icons/autohide_light.svg");
984
pxAutoHideMode = rotateAutoHideIcon(pxAutoHideMode, dockArea);
985
actNoAutoMode.setIcon(BitmapFactory().pixmap("qss:overlay/icons/mode_light.svg"));
986
actEditShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/editshow_light.svg"));
987
actAutoHide.setIcon(pxAutoHideMode);
988
actTaskShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/taskshow_light.svg"));
991
QPixmap pxEditHideMode = BitmapFactory().pixmap("qss:overlay/icons/edithide.svg");
992
action->setIcon(pxEditHideMode);
993
QPixmap pxAutoHideMode =
994
BitmapFactory().pixmap("qss:overlay/icons/autohide_lightgray.svg");
995
pxAutoHideMode = rotateAutoHideIcon(pxAutoHideMode, dockArea);
996
actNoAutoMode.setIcon(
997
BitmapFactory().pixmap("qss:overlay/icons/mode_lightgray.svg"));
999
BitmapFactory().pixmap("qss:overlay/icons/editshow_lightgray.svg"));
1000
actAutoHide.setIcon(pxAutoHideMode);
1001
actTaskShow.setIcon(
1002
BitmapFactory().pixmap("qss:overlay/icons/taskshow_lightgray.svg"));
1006
action = &actNoAutoMode;
1007
if (isStyleSheetDark(curStyleSheet)) {
1008
QPixmap pxNoAutoMode = BitmapFactory().pixmap("qss:overlay/icons/mode_lighter.svg");
1009
action->setIcon(pxNoAutoMode);
1010
QPixmap pxAutoHideMode =
1011
BitmapFactory().pixmap("qss:overlay/icons/autohide_light.svg");
1012
pxAutoHideMode = rotateAutoHideIcon(pxAutoHideMode, dockArea);
1013
actTaskShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/taskshow_light.svg"));
1014
actEditShow.setIcon(BitmapFactory().pixmap("qss:overlay/icons/editshow_light.svg"));
1015
actAutoHide.setIcon(pxAutoHideMode);
1016
actEditHide.setIcon(BitmapFactory().pixmap("qss:overlay/icons/edithide_light.svg"));
1019
QPixmap pxNoAutoMode = BitmapFactory().pixmap("qss:overlay/icons/mode.svg");
1020
action->setIcon(pxNoAutoMode);
1021
QPixmap pxAutoHideMode =
1022
BitmapFactory().pixmap("qss:overlay/icons/autohide_lightgray.svg");
1023
pxAutoHideMode = rotateAutoHideIcon(pxAutoHideMode, dockArea);
1024
actTaskShow.setIcon(
1025
BitmapFactory().pixmap("qss:overlay/icons/taskshow_lightgray.svg"));
1026
actEditShow.setIcon(
1027
BitmapFactory().pixmap("qss:overlay/icons/editshow_lightgray.svg"));
1028
actAutoHide.setIcon(pxAutoHideMode);
1029
actEditHide.setIcon(
1030
BitmapFactory().pixmap("qss:overlay/icons/edithide_lightgray.svg"));
1034
actAutoMode.setIcon(action->icon());
1035
if (action == &actNoAutoMode) {
1036
actAutoMode.setToolTip(tr("Select auto show/hide mode"));
1039
actAutoMode.setToolTip(action->toolTip());
1043
void OverlayTabWidget::onAction(QAction *action)
1045
if (action == &actAutoMode) {
1046
action = autoModeMenu.exec(QCursor::pos());
1047
if (action == &actNoAutoMode)
1048
setAutoMode(AutoMode::NoAutoMode);
1049
else if (action == &actAutoHide)
1050
setAutoMode(AutoMode::AutoHide);
1051
else if (action == &actEditShow)
1052
setAutoMode(AutoMode::EditShow);
1053
else if (action == &actTaskShow)
1054
setAutoMode(AutoMode::TaskShow);
1055
else if (action == &actEditHide)
1056
setAutoMode(AutoMode::EditHide);
1059
else if(action == &actOverlay) {
1060
OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleActive);
1062
} else if(action == &actTransparent) {
1064
Base::StateLocker lock(_saving);
1065
hGrp->SetBool("Transparent", actTransparent.isChecked());
1068
OverlayManager::instance()->refresh(this);
1071
void OverlayTabWidget::setState(State state)
1073
if (_state == state)
1077
if (_state == State::Hidden) {
1081
else if (_state == State::Showing) {
1086
case State::Showing:
1089
if (dockArea == Qt::RightDockWidgetArea)
1090
setTabPosition(East);
1091
else if (dockArea == Qt::BottomDockWidgetArea)
1092
setTabPosition(South);
1093
if (this->count() == 1)
1095
_graphicsEffectTab->setEnabled(false);
1098
if (state == State::Showing)
1099
OverlayManager::instance()->refresh(this);
1102
if (_state == State::HintHidden || _state == State::Hidden)
1105
if (this->count() && OverlayParams::getDockOverlayHintTabBar()) {
1106
tabBar()->setToolTip(proxyWidget->toolTip());
1110
_graphicsEffectTab->setEnabled(true);
1113
proxyWidget->raise();
1114
if (dockArea == Qt::RightDockWidgetArea)
1115
setTabPosition(West);
1116
else if (dockArea == Qt::BottomDockWidgetArea)
1117
setTabPosition(North);
1118
OverlayManager::instance()->refresh(this);
1121
case State::HintHidden:
1122
if (_state != State::Hidden)
1124
proxyWidget->hide();
1126
_graphicsEffectTab->setEnabled(true);
1137
bool OverlayTabWidget::checkAutoHide() const
1139
if (autoMode == AutoMode::AutoHide) {
1143
if (OverlayParams::getDockOverlayAutoView()) {
1144
auto view = getMainWindow()->activeWindow();
1150
if (!view->onHasMsg("AllowsOverlayOnHover")) {
1154
if (!view->onHasMsg("CanPan")
1155
&& view->parentWidget()
1156
&& view->parentWidget()->isMaximized()) {
1161
if (autoMode == AutoMode::EditShow) {
1162
return !Application::Instance->editDocument()
1163
&& (!Control().taskPanel() || Control().taskPanel()->isEmpty(false));
1166
if (autoMode == AutoMode::EditHide && Application::Instance->editDocument()) {
1173
void OverlayTabWidget::leaveEvent(QEvent*)
1175
if (titleBar && QWidget::mouseGrabber() == titleBar)
1177
OverlayManager::instance()->refresh();
1180
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
1181
void OverlayTabWidget::enterEvent(QEvent*)
1183
void OverlayTabWidget::enterEvent(QEnterEvent*)
1186
revealTime = QTime();
1187
OverlayManager::instance()->refresh();
1190
void OverlayTabWidget::setRevealTime(const QTime &time)
1195
void OverlayTabWidget::_setOverlayMode(QWidget *widget, OverlayOption option)
1200
#if QT_VERSION>QT_VERSION_CHECK(5,12,2) && QT_VERSION < QT_VERSION_CHECK(5,12,6)
1202
widget->setStyleSheet(OverlayManager::instance()->getStyleSheet());
1205
if (qobject_cast<QScrollBar*>(widget)) {
1206
auto parent = widget->parentWidget();
1208
parent = parent->parentWidget();
1209
if (qobject_cast<PropertyEditor::PropertyEditor*>(parent)) {
1210
auto scrollArea = static_cast<QAbstractScrollArea*>(parent);
1211
if (scrollArea->verticalScrollBar() == widget) {
1212
if (!OverlayParams::getDockOverlayHidePropertyViewScrollBar()
1213
|| option == OverlayOption::Disable)
1214
widget->setStyleSheet(QString());
1216
static QString _style = QStringLiteral("*{width:0}");
1217
widget->setStyleSheet(_style);
1221
auto treeView = qobject_cast<TreeWidget*>(parent);
1223
auto scrollArea = static_cast<QAbstractScrollArea*>(parent);
1224
if (scrollArea->verticalScrollBar() == widget) {
1225
if (!TreeParams::getHideScrollBar() || option == OverlayOption::Disable)
1226
widget->setStyleSheet(QString());
1228
static QString _style = QStringLiteral("*{width:0}");
1229
widget->setStyleSheet(_style);
1235
auto header = treeView->header();
1236
if (!TreeParams::getHideHeaderView() || option==OverlayOption::Disable)
1237
header->setStyleSheet(QString());
1239
static QString _style = QStringLiteral(
1240
"QHeaderView:section {"
1242
"background-color: transparent;"
1244
"border: transparent;}");
1245
header->setStyleSheet(_style);
1251
auto tabbar = qobject_cast<QTabBar*>(widget);
1253
if(!tabbar->autoHide() || tabbar->count()>1) {
1254
if(!OverlayManager::instance()->getHideTab())
1255
tabbar->setVisible(true);
1257
tabbar->setVisible(option == OverlayOption::Disable
1258
|| (option == OverlayOption::ShowTab && tabbar->count()>1));
1263
if (!qobject_cast<QScrollArea*>(widget)
1264
|| !qobject_cast<Dialog::Clipping*>(widget->parentWidget())) {
1265
if(option != OverlayOption::Disable) {
1266
widget->setWindowFlags(widget->windowFlags() | Qt::FramelessWindowHint);
1268
widget->setWindowFlags(widget->windowFlags() & ~Qt::FramelessWindowHint);
1270
widget->setAttribute(Qt::WA_NoSystemBackground, option != OverlayOption::Disable);
1271
widget->setAttribute(Qt::WA_TranslucentBackground, option != OverlayOption::Disable);
1275
void OverlayTabWidget::setOverlayMode(QWidget *widget, OverlayOption option)
1277
if(!widget || (qobject_cast<QDialog*>(widget)
1278
&& !qobject_cast<Dialog::Clipping*>(widget))
1279
|| qobject_cast<TaskView::TaskBox*>(widget))
1282
if(widget != tabBar()) {
1283
if(OverlayParams::getDockOverlayAutoMouseThrough()
1284
&& option == OverlayOption::ShowTab) {
1285
widget->setMouseTracking(true);
1289
_setOverlayMode(widget, option);
1291
if(qobject_cast<QComboBox*>(widget)) {
1296
for(auto child : widget->children())
1297
setOverlayMode(qobject_cast<QWidget*>(child), option);
1300
void OverlayTabWidget::setTransparent(bool enable)
1302
if(actTransparent.isChecked() == enable)
1305
Base::StateLocker lock(_saving);
1306
hGrp->SetBool("Transparent", enable);
1308
actTransparent.setChecked(enable);
1309
OverlayManager::instance()->refresh(this);
1312
bool OverlayTabWidget::isTransparent() const
1314
if (!actTransparent.isChecked())
1316
if(OverlayParams::getDockOverlayAutoView()) {
1317
auto view = getMainWindow()->activeWindow();
1318
if (!view) return false;
1319
if(!view->onHasMsg("CanPan")
1320
&& view->parentWidget()
1321
&& view->parentWidget()->isMaximized())
1327
bool OverlayTabWidget::isOverlaid(QueryOption option) const
1329
if (option != QueryOption::QueryOverlay
1330
&& currentTransparent != isTransparent())
1331
return option == QueryOption::TransparencyChanged;
1335
void OverlayTabWidget::setAutoMode(AutoMode mode)
1337
if (autoMode == mode)
1342
bool autohide = false, editshow = false, edithide = false, taskshow = false;
1344
case AutoMode::AutoHide:
1347
case AutoMode::EditShow:
1350
case AutoMode::EditHide:
1353
case AutoMode::TaskShow:
1359
Base::StateLocker lock(_saving);
1360
hGrp->SetBool("AutoHide", autohide);
1361
hGrp->SetBool("EditShow", editshow);
1362
hGrp->SetBool("EditHide", edithide);
1363
hGrp->SetBool("TaskShow", taskshow);
1366
OverlayManager::instance()->refresh(this);
1369
QDockWidget *OverlayTabWidget::currentDockWidget() const
1372
for(int size : splitter->sizes()) {
1375
return dockWidget(index);
1377
return dockWidget(currentIndex());
1380
QDockWidget *OverlayTabWidget::dockWidget(int index) const
1382
if(index < 0 || index >= splitter->count())
1384
return qobject_cast<QDockWidget*>(splitter->widget(index));
1387
void OverlayTabWidget::updateSplitterHandles()
1389
if (overlaid || _state > State::Normal)
1391
for (int i=0, c=splitter->count(); i<c; ++i) {
1392
auto handle = qobject_cast<OverlaySplitterHandle*>(splitter->handle(i));
1394
handle->showTitle(true);
1398
bool OverlayTabWidget::onEscape()
1400
if (getState() == OverlayTabWidget::State::Hint
1401
|| getState() == OverlayTabWidget::State::Hidden) {
1402
setState(OverlayTabWidget::State::HintHidden);
1407
if (titleBar->isVisible() && titleBar->underMouse()) {
1411
for (int i=0, c=splitter->count(); i<c; ++i) {
1412
auto handle = qobject_cast<OverlaySplitterHandle*>(splitter->handle(i));
1413
if (handle->isVisible() && handle->underMouse()) {
1414
handle->showTitle(false);
1421
void OverlayTabWidget::setOverlayMode(bool enable)
1425
if(!isVisible() || !count())
1430
if (_state <= State::Normal) {
1431
titleBar->setVisible(!enable || OverlayManager::instance()->isMouseTransparent());
1432
for (int i=0, c=splitter->count(); i<c; ++i) {
1433
auto handle = qobject_cast<OverlaySplitterHandle*>(splitter->handle(i));
1435
handle->showTitle(!enable);
1440
stylesheet = OverlayManager::instance()->getStyleSheet();
1441
currentTransparent = isTransparent();
1443
OverlayOption option;
1444
if(!enable && isTransparent()) {
1445
option = OverlayOption::ShowTab;
1448
&& (autoMode == AutoMode::EditShow || autoMode == AutoMode::AutoHide)) {
1449
option = OverlayOption::Disable;
1451
option = enable?OverlayOption::Enable:OverlayOption::Disable;
1453
setProperty("transparent", option != OverlayOption::Disable);
1455
proxyWidget->setStyleSheet(stylesheet);
1456
this->setStyleSheet(stylesheet);
1457
setOverlayMode(this, option);
1459
_graphicsEffect->setEnabled(effectEnabled() && (enable || isTransparent()));
1461
if (_state == State::Hint && OverlayParams::getDockOverlayHintTabBar()) {
1462
tabBar()->setToolTip(proxyWidget->toolTip());
1464
} else if (OverlayParams::getDockOverlayHideTabBar() || count()==1) {
1467
tabBar()->setToolTip(QString());
1468
tabBar()->setVisible(!enable || !OverlayManager::instance()->getHideTab());
1471
setRect(rectOverlay);
1474
const QRect &OverlayTabWidget::getRect()
1479
bool OverlayTabWidget::getAutoHideRect(QRect &rect) const
1482
int hintWidth = OverlayParams::getDockOverlayHintSize();
1484
case Qt::LeftDockWidgetArea:
1485
case Qt::RightDockWidgetArea:
1486
if (_TopOverlay->isVisible() && _TopOverlay->_state <= State::Normal)
1487
rect.setTop(std::max(rect.top(), _TopOverlay->rectOverlay.bottom()));
1488
if (dockArea == Qt::RightDockWidgetArea)
1489
rect.setLeft(rect.left() + std::max(rect.width()-hintWidth,0));
1491
rect.setRight(rect.right() - std::max(rect.width()-hintWidth,0));
1493
case Qt::TopDockWidgetArea:
1494
case Qt::BottomDockWidgetArea:
1495
if (_LeftOverlay->isVisible() && _LeftOverlay->_state <= State::Normal)
1496
rect.setLeft(std::max(rect.left(),_LeftOverlay->rectOverlay.right()));
1497
if (dockArea == Qt::TopDockWidgetArea)
1498
rect.setBottom(rect.bottom() - std::max(rect.height()-hintWidth,0));
1500
rect.setTop(rect.top() + std::max(rect.height()-hintWidth,0));
1501
if (_RightOverlay->isVisible() && _RightOverlay->_state <= State::Normal) {
1502
QPoint offset = getMainWindow()->getMdiArea()->pos();
1503
rect.setRight(std::min(rect.right(), _RightOverlay->x()-offset.x()));
1510
return _state != State::Showing && overlaid && checkAutoHide();
1513
void OverlayTabWidget::setOffset(const QSize &ofs)
1518
Base::StateLocker lock(_saving);
1519
hGrp->SetInt("Offset1", ofs.width());
1520
hGrp->SetInt("Offset3", ofs.height());
1525
void OverlayTabWidget::setSizeDelta(int delta)
1527
if(sizeDelta != delta) {
1529
Base::StateLocker lock(_saving);
1530
hGrp->SetInt("Offset2", delta);
1536
void OverlayTabWidget::setRect(QRect rect)
1538
if(busy || !parentWidget() || !getMainWindow() || !getMainWindow()->getMdiArea())
1541
if (rect.width() == 0)
1542
rect.setWidth(OverlayParams::getDockOverlayMinimumSize()*3);
1543
if (rect.height() == 0)
1544
rect.setHeight(OverlayParams::getDockOverlayMinimumSize()*3);
1547
case Qt::LeftDockWidgetArea:
1549
if (rect.width() < OverlayParams::getDockOverlayMinimumSize())
1550
rect.setWidth(OverlayParams::getDockOverlayMinimumSize());
1552
case Qt::RightDockWidgetArea:
1553
if (rect.width() < OverlayParams::getDockOverlayMinimumSize())
1554
rect.setLeft(rect.right()-OverlayParams::getDockOverlayMinimumSize());
1556
case Qt::TopDockWidgetArea:
1558
if (rect.height() < OverlayParams::getDockOverlayMinimumSize())
1559
rect.setHeight(OverlayParams::getDockOverlayMinimumSize());
1561
case Qt::BottomDockWidgetArea:
1562
if (rect.height() < OverlayParams::getDockOverlayMinimumSize())
1563
rect.setTop(rect.bottom()-OverlayParams::getDockOverlayMinimumSize());
1569
if (hGrp && rect.size() != rectOverlay.size()) {
1570
Base::StateLocker lock(_saving);
1571
hGrp->SetInt("Width", rect.width());
1572
hGrp->SetInt("Height", rect.height());
1576
QPoint offset = getMainWindow()->getMdiArea()->pos();
1578
if (getAutoHideRect(rect) || _state == State::Hint || _state == State::Hidden) {
1579
QRect rectHint = rect;
1580
if (_state != State::Hint && _state != State::Hidden)
1582
else if (count() && OverlayParams::getDockOverlayHintTabBar()) {
1584
case Qt::LeftDockWidgetArea:
1585
case Qt::RightDockWidgetArea:
1586
if (dockArea == Qt::LeftDockWidgetArea)
1587
rect.setWidth(tabBar()->width());
1589
rect.setLeft(rect.left() + rect.width() - tabBar()->width());
1590
rect.setHeight(std::max(rect.height(),
1591
tabBar()->y() + tabBar()->sizeHint().height() + 5));
1593
case Qt::BottomDockWidgetArea:
1594
case Qt::TopDockWidgetArea:
1595
if (dockArea == Qt::TopDockWidgetArea)
1596
rect.setHeight(tabBar()->height());
1598
rect.setTop(rect.top() + rect.height() - tabBar()->height());
1599
rect.setWidth(std::max(rect.width(),
1600
tabBar()->x() + tabBar()->sizeHint().width() + 5));
1606
setGeometry(rect.translated(offset));
1608
proxyWidget->setGeometry(rectHint.translated(offset));
1610
proxyWidget->show();
1611
proxyWidget->raise();
1613
proxyWidget->hide();
1616
setGeometry(rectOverlay.translated(offset));
1618
for (int i = 0, count = splitter->count(); i < count; ++i) {
1619
splitter->widget(i)->show();
1622
if (!isVisible() && count()) {
1623
proxyWidget->hide();
1629
void OverlayTabWidget::addWidget(QDockWidget *dock, const QString &title)
1631
if (!getMainWindow() || !getMainWindow()->getMdiArea())
1634
OverlayManager::instance()->registerDockWidget(dock->objectName(), this);
1636
OverlayManager::setFocusView();
1637
getMainWindow()->removeDockWidget(dock);
1639
auto titleWidget = dock->titleBarWidget();
1640
if(titleWidget && titleWidget->objectName()==QStringLiteral("OverlayTitle")) {
1643
auto w = new QWidget();
1644
w->setObjectName(QStringLiteral("OverlayTitle"));
1645
dock->setTitleBarWidget(w);
1647
titleWidget->deleteLater();
1651
splitter->addWidget(dock);
1652
auto dummyWidget = new QWidget(this);
1653
addTab(dummyWidget, title);
1654
connect(dock, &QObject::destroyed, dummyWidget, &QObject::deleteLater);
1656
dock->setFeatures(dock->features() & ~QDockWidget::DockWidgetFloatable);
1658
QRect rect = dock->geometry();
1659
QSize sizeMain = getMainWindow()->getMdiArea()->size();
1661
case Qt::LeftDockWidgetArea:
1662
case Qt::RightDockWidgetArea:
1663
if (rect.width() > sizeMain.width()/3)
1664
rect.setWidth(sizeMain.width()/3);
1666
case Qt::TopDockWidgetArea:
1667
case Qt::BottomDockWidgetArea:
1668
if (rect.height() > sizeMain.height()/3)
1669
rect.setHeight(sizeMain.height()/3);
1680
int OverlayTabWidget::dockWidgetIndex(QDockWidget *dock) const
1682
return splitter->indexOf(dock);
1685
void OverlayTabWidget::removeWidget(QDockWidget *dock, QDockWidget *lastDock)
1687
int index = dockWidgetIndex(dock);
1691
OverlayManager::instance()->unregisterDockWidget(dock->objectName(), this);
1693
OverlayManager::setFocusView();
1696
getMainWindow()->tabifyDockWidget(lastDock, dock);
1698
getMainWindow()->addDockWidget(dockArea, dock);
1700
auto w = this->widget(index);
1707
w = dock->titleBarWidget();
1708
if(w && w->objectName() == QStringLiteral("OverlayTitle")) {
1709
dock->setTitleBarWidget(nullptr);
1712
OverlayManager::instance()->setupTitleBar(dock);
1714
dock->setFeatures(dock->features() | QDockWidget::DockWidgetFloatable);
1716
setOverlayMode(dock, OverlayOption::Disable);
1721
void OverlayTabWidget::resizeEvent(QResizeEvent *ev)
1723
QTabWidget::resizeEvent(ev);
1724
if (_state <= State::Normal)
1728
void OverlayTabWidget::setupLayout()
1730
if (_state > State::Normal)
1737
if(dockArea==Qt::LeftDockWidgetArea || dockArea==Qt::RightDockWidgetArea)
1738
tsize = tabBar()->width();
1740
tsize = tabBar()->height();
1743
int titleBarSize = widgetMinSize(this, true);
1744
QRect rect, rectTitle;
1745
switch(tabPosition()) {
1747
rectTitle = QRect(tabSize, 0, this->width()-tabSize, titleBarSize);
1748
rect = QRect(rectTitle.left(), rectTitle.bottom(),
1749
rectTitle.width(), this->height()-rectTitle.height());
1752
rectTitle = QRect(0, 0, this->width()-tabSize, titleBarSize);
1753
rect = QRect(rectTitle.left(), rectTitle.bottom(),
1754
rectTitle.width(), this->height()-rectTitle.height());
1757
rectTitle = QRect(0, tabSize, titleBarSize, this->height()-tabSize);
1758
rect = QRect(rectTitle.right(), rectTitle.top(),
1759
this->width()-rectTitle.width(), rectTitle.height());
1762
rectTitle = QRect(0, 0, titleBarSize, this->height()-tabSize);
1763
rect = QRect(rectTitle.right(), rectTitle.top(),
1764
this->width()-rectTitle.width(), rectTitle.height());
1767
if (_animation != 0.0) {
1769
case Qt::LeftDockWidgetArea:
1770
rect.moveLeft(rect.left() - _animation * rect.width());
1772
case Qt::RightDockWidgetArea:
1773
rect.moveLeft(rect.left() + _animation * rect.width());
1775
case Qt::TopDockWidgetArea:
1776
rect.moveTop(rect.top() - _animation * rect.height());
1778
case Qt::BottomDockWidgetArea:
1779
rect.moveTop(rect.top() + _animation * rect.height());
1785
splitter->setGeometry(rect);
1786
titleBar->setGeometry(rectTitle);
1789
void OverlayTabWidget::setCurrent(QDockWidget *widget)
1791
int index = dockWidgetIndex(widget);
1793
setCurrentIndex(index);
1796
void OverlayTabWidget::onSplitterResize(int index)
1798
const auto &sizes = splitter->sizes();
1799
if (index >= 0 && index < sizes.count()) {
1800
if (sizes[index] == 0) {
1801
if (currentIndex() == index) {
1803
for (int i=index+1; i<sizes.count(); ++i) {
1811
for (int i=index-1; i>=0 ;--i) {
1820
setCurrentIndex(index);
1826
void OverlayTabWidget::onCurrentChanged(int index)
1828
setState(State::Showing);
1830
auto sizes = splitter->sizes();
1832
int size = splitter->orientation()==Qt::Vertical ?
1833
height()-tabBar()->height() : width()-tabBar()->width();
1834
for(auto &s : sizes) {
1840
splitter->setSizes(sizes);
1841
onSplitterResize(index);
1845
void OverlayTabWidget::onSizeGripMove(const QPoint &p)
1847
if (!getMainWindow() || !getMainWindow()->getMdiArea())
1850
QPoint pos = mapFromGlobal(p) + this->pos();
1851
QPoint offset = getMainWindow()->getMdiArea()->pos();
1852
QRect rect = this->rectOverlay.translated(offset);
1855
case Qt::LeftDockWidgetArea:
1856
if (pos.x() - rect.left() < OverlayParams::getDockOverlayMinimumSize())
1858
rect.setRight(pos.x());
1860
case Qt::RightDockWidgetArea:
1861
if (rect.right() - pos.x() < OverlayParams::getDockOverlayMinimumSize())
1863
rect.setLeft(pos.x());
1865
case Qt::TopDockWidgetArea:
1866
if (pos.y() - rect.top() < OverlayParams::getDockOverlayMinimumSize())
1868
rect.setBottom(pos.y());
1871
if (rect.bottom() - pos.y() < OverlayParams::getDockOverlayMinimumSize())
1873
rect.setTop(pos.y());
1876
this->setRect(rect.translated(-offset));
1877
OverlayManager::instance()->refresh();
1880
QLayoutItem *OverlayTabWidget::prepareTitleWidget(QWidget *widget, const QList<QAction*> &actions)
1882
bool vertical = false;
1883
QBoxLayout *layout = nullptr;
1884
auto tabWidget = qobject_cast<OverlayTabWidget*>(widget->parentWidget());
1886
layout = new QBoxLayout(QBoxLayout::LeftToRight, widget);
1888
switch(tabWidget->getDockArea()) {
1889
case Qt::LeftDockWidgetArea:
1890
layout = new QBoxLayout(QBoxLayout::LeftToRight, widget);
1892
case Qt::RightDockWidgetArea:
1893
layout = new QBoxLayout(QBoxLayout::RightToLeft, widget);
1895
case Qt::TopDockWidgetArea:
1896
layout = new QBoxLayout(QBoxLayout::TopToBottom, widget);
1899
case Qt::BottomDockWidgetArea:
1900
layout = new QBoxLayout(QBoxLayout::BottomToTop, widget);
1908
layout->addSpacing(5);
1909
layout->setContentsMargins(1,1,1,1);
1910
int buttonSize = widgetMinSize(widget);
1911
auto spacer = new QSpacerItem(buttonSize,buttonSize,
1912
vertical?QSizePolicy::Minimum:QSizePolicy::Expanding,
1913
vertical?QSizePolicy::Expanding:QSizePolicy::Minimum);
1914
layout->addSpacerItem(spacer);
1916
for(auto action : actions)
1917
layout->addWidget(OverlayTabWidget::createTitleButton(action, buttonSize));
1920
auto grip = new OverlaySizeGrip(tabWidget, vertical);
1921
QObject::connect(grip, &OverlaySizeGrip::dragMove,
1922
tabWidget, &OverlayTabWidget::onSizeGripMove);
1923
layout->addWidget(grip);
1930
bool OverlayTabWidget::isStyleSheetDark(std::string curStyleSheet)
1932
if (curStyleSheet.find("dark") != std::string::npos
1933
|| curStyleSheet.find("Dark") != std::string::npos) {
1939
QPixmap OverlayTabWidget::rotateAutoHideIcon(QPixmap pxAutoHide, Qt::DockWidgetArea dockArea)
1942
case Qt::LeftDockWidgetArea:
1945
case Qt::RightDockWidgetArea:
1946
return pxAutoHide.transformed(QTransform().scale(-1, 1));
1948
case Qt::TopDockWidgetArea:
1949
return pxAutoHide.transformed(QTransform().rotate(90));
1951
case Qt::BottomDockWidgetArea:
1952
return pxAutoHide.transformed(QTransform().rotate(-90));
1962
OverlayTitleBar::OverlayTitleBar(QWidget * parent)
1965
setFocusPolicy(Qt::ClickFocus);
1966
setMouseTracking(true);
1967
setCursor(Qt::OpenHandCursor);
1970
void OverlayTitleBar::setTitleItem(QLayoutItem *item)
1975
void OverlayTitleBar::paintEvent(QPaintEvent *)
1980
QDockWidget *dock = qobject_cast<QDockWidget*>(parentWidget());
1981
int vertical = false;
1982
int flags = Qt::AlignCenter;
1984
OverlayTabWidget *tabWidget = qobject_cast<OverlayTabWidget*>(parentWidget());
1986
switch(tabWidget->getDockArea()) {
1987
case Qt::TopDockWidgetArea:
1990
case Qt::RightDockWidgetArea:
1991
flags = Qt::AlignRight;
1993
case Qt::BottomDockWidgetArea:
1996
case Qt::LeftDockWidgetArea:
1997
flags = Qt::AlignLeft;
2002
dock = tabWidget->dockWidget(0);
2008
QPainter painter(this);
2009
if (qobject_cast<OverlayTabWidget*>(parentWidget()))
2010
painter.fillRect(this->rect(), painter.background());
2012
QRect r = titleItem->geometry();
2015
painter.translate(r.left(), r.top() + r.width());
2016
painter.rotate(-90);
2017
painter.translate(-r.left(), -r.top());
2021
if (OverlayManager::instance()->isMouseTransparent()) {
2023
timerId = startTimer(500);
2024
title = blink ? tr("Mouse pass through, ESC to stop") : dock->windowTitle();
2030
title = dock->windowTitle();
2032
QString text = painter.fontMetrics().elidedText(
2033
title, Qt::ElideRight, r.width());
2034
painter.drawText(r, flags, text);
2037
void OverlayTitleBar::timerEvent(QTimerEvent *ev)
2039
if (timerId == ev->timerId()) {
2046
isNear(const QPoint &a, const QPoint &b, int tol = 16)
2049
return d.x()*d.x() + d.y()*d.y() < tol;
2052
void OverlayTitleBar::endDrag()
2054
if (OverlayTabWidget::_Dragging == this) {
2055
OverlayTabWidget::_Dragging = nullptr;
2056
setCursor(Qt::OpenHandCursor);
2057
if (OverlayTabWidget::_DragFrame)
2058
OverlayTabWidget::_DragFrame->hide();
2059
if (OverlayTabWidget::_DragFloating)
2060
OverlayTabWidget::_DragFrame->hide();
2064
void OverlayTitleBar::mouseMoveEvent(QMouseEvent *me)
2067
if (!(me->buttons() & Qt::LeftButton))
2068
ignoreMouse = false;
2075
if (OverlayTabWidget::_Dragging != this && mouseMovePending && (me->buttons() & Qt::LeftButton)) {
2076
if (isNear(dragOffset, me->pos()))
2078
mouseMovePending = false;
2079
OverlayTabWidget::_Dragging = this;
2082
if (OverlayTabWidget::_Dragging != this)
2085
if (!(me->buttons() & Qt::LeftButton)) {
2090
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
2091
QPoint point = me->globalPos();
2093
QPoint point = me->globalPosition().toPoint();
2096
OverlayManager::instance()->dragDockWidget(point,
2102
void OverlayTitleBar::mousePressEvent(QMouseEvent *me)
2104
mouseMovePending = false;
2105
QWidget *parent = parentWidget();
2106
if (OverlayTabWidget::_Dragging || !parent || !getMainWindow() || me->button() != Qt::LeftButton)
2109
dragSize = parent->size();
2110
OverlayTabWidget *tabWidget = qobject_cast<OverlayTabWidget*>(parent);
2112
if(QApplication::queryKeyboardModifiers() == Qt::ShiftModifier) {
2119
for (int s : tabWidget->getSplitter()->sizes()) {
2122
if (tabWidget == OverlayTabWidget::_TopOverlay
2123
|| tabWidget == OverlayTabWidget::_BottomOverlay) {
2124
dragSize.setWidth(s + this->width());
2125
dragSize.setHeight(tabWidget->height());
2128
dragSize.setHeight(s + this->height());
2129
dragSize.setWidth(tabWidget->width());
2133
ignoreMouse = false;
2134
QSize mwSize = getMainWindow()->size();
2135
dragSize.setWidth(std::max(OverlayParams::getDockOverlayMinimumSize(),
2136
static_cast<long>(std::min(mwSize.width()/2, dragSize.width()))));
2137
dragSize.setHeight(std::max(OverlayParams::getDockOverlayMinimumSize(),
2138
static_cast<long>(std::min(mwSize.height()/2, dragSize.height()))));
2140
dragOffset = me->pos();
2141
setCursor(Qt::ClosedHandCursor);
2142
mouseMovePending = true;
2145
void OverlayTitleBar::mouseReleaseEvent(QMouseEvent *me)
2152
setCursor(Qt::OpenHandCursor);
2153
mouseMovePending = false;
2154
if (OverlayTabWidget::_Dragging != this)
2157
if (me->button() != Qt::LeftButton)
2160
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
2161
QPoint point = me->globalPos();
2163
QPoint point = me->globalPosition().toPoint();
2166
OverlayTabWidget::_Dragging = nullptr;
2167
OverlayManager::instance()->dragDockWidget(point,
2172
if (OverlayTabWidget::_DragFrame)
2173
OverlayTabWidget::_DragFrame->hide();
2174
if (OverlayTabWidget::_DragFloating)
2175
OverlayTabWidget::_DragFloating->hide();
2178
void OverlayTitleBar::keyPressEvent(QKeyEvent *ke)
2180
if (OverlayTabWidget::_Dragging == this && ke->key() == Qt::Key_Escape)
2187
OverlayDragFrame::OverlayDragFrame(QWidget * parent)
2192
void OverlayDragFrame::paintEvent(QPaintEvent *)
2194
QPainter painter(this);
2195
painter.drawRect(0, 0, this->width()-1, this->height()-1);
2196
painter.setOpacity(0.3);
2197
painter.setBrush(QBrush(Qt::blue));
2198
painter.drawRect(0, 0, this->width()-1, this->height()-1);
2201
QSize OverlayDragFrame::sizeHint() const
2206
QSize OverlayDragFrame::minimumSizeHint() const
2208
return minimumSize();
2213
OverlaySizeGrip::OverlaySizeGrip(QWidget * parent, bool vertical)
2214
:QWidget(parent), vertical(vertical)
2217
this->setFixedHeight(6);
2218
this->setMinimumWidth(widgetMinSize(this,true));
2219
this->setCursor(Qt::SizeVerCursor);
2222
this->setFixedWidth(6);
2223
this->setMinimumHeight(widgetMinSize(this,true));
2224
this->setCursor(Qt::SizeHorCursor);
2226
setMouseTracking(true);
2229
void OverlaySizeGrip::paintEvent(QPaintEvent*)
2231
QPainter painter(this);
2232
painter.setPen(Qt::transparent);
2233
painter.setOpacity(0.5);
2234
painter.setBrush(QBrush(Qt::black, Qt::Dense6Pattern));
2235
QRect rect(this->rect());
2236
painter.drawRect(rect);
2239
void OverlaySizeGrip::mouseMoveEvent(QMouseEvent *me)
2241
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
2242
QPoint point = me->globalPos();
2244
QPoint point = me->globalPosition().toPoint();
2247
if ((me->buttons() & Qt::LeftButton)) {
2248
Q_EMIT dragMove(point);
2252
void OverlaySizeGrip::mousePressEvent(QMouseEvent *)
2256
void OverlaySizeGrip::mouseReleaseEvent(QMouseEvent *)
2262
OverlaySplitter::OverlaySplitter(QWidget *parent)
2267
QSplitterHandle * OverlaySplitter::createHandle()
2269
auto widget = new OverlaySplitterHandle(this->orientation(), this);
2270
widget->setObjectName(QStringLiteral("OverlaySplitHandle"));
2271
QList<QAction*> actions;
2272
actions.append(&widget->actFloat);
2273
widget->setTitleItem(OverlayTabWidget::prepareTitleWidget(widget, actions));
2279
OverlaySplitterHandle::OverlaySplitterHandle(Qt::Orientation orientation, QSplitter *parent)
2280
: QSplitterHandle(orientation, parent)
2282
setMouseTracking(true);
2283
setFocusPolicy(Qt::ClickFocus);
2286
QObject::connect(&actFloat, &QAction::triggered, this, &OverlaySplitterHandle::onAction);
2287
timer.setSingleShot(true);
2288
QObject::connect(&timer, &QTimer::timeout, this, &OverlaySplitterHandle::onTimer);
2291
void OverlaySplitterHandle::refreshIcons()
2293
actFloat.setIcon(BitmapFactory().pixmap("qss:overlay/icons/float.svg"));
2296
void OverlaySplitterHandle::onTimer()
2298
if (isVisible() && qApp->widgetAt(QCursor::pos()) != this)
2302
void OverlaySplitterHandle::showEvent(QShowEvent *ev)
2304
if (OverlayParams::getDockOverlaySplitterHandleTimeout() > 0
2305
&& qApp->widgetAt(QCursor::pos()) != this)
2306
timer.start(OverlayParams::getDockOverlaySplitterHandleTimeout());
2307
QSplitterHandle::showEvent(ev);
2310
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
2311
void OverlaySplitterHandle::enterEvent(QEvent *ev)
2313
void OverlaySplitterHandle::enterEvent(QEnterEvent *ev)
2317
QSplitterHandle::enterEvent(ev);
2320
void OverlaySplitterHandle::leaveEvent(QEvent *ev)
2322
if (OverlayParams::getDockOverlaySplitterHandleTimeout() > 0)
2323
timer.start(OverlayParams::getDockOverlaySplitterHandleTimeout());
2324
QSplitterHandle::leaveEvent(ev);
2327
QSize OverlaySplitterHandle::sizeHint() const
2329
QSize size = QSplitterHandle::sizeHint();
2330
int minSize = widgetMinSize(this,true);
2331
if (this->orientation() == Qt::Vertical)
2332
size.setHeight(std::max(minSize, size.height()));
2334
size.setWidth(std::max(minSize, size.width()));
2338
void OverlaySplitterHandle::onAction()
2340
auto action = qobject_cast<QAction*>(sender());
2341
if(action == &actFloat) {
2342
QDockWidget *dock = dockWidget();
2344
OverlayManager::instance()->floatDockWidget(dock);
2348
QDockWidget *OverlaySplitterHandle::dockWidget()
2350
QSplitter *parent = splitter();
2354
if (parent->handle(this->idx) != this) {
2356
for (int i=0, c=parent->count(); i<c; ++i) {
2357
if (parent->handle(i) == this) {
2363
return qobject_cast<QDockWidget*>(parent->widget(this->idx));
2366
void OverlaySplitterHandle::retranslate()
2368
actFloat.setToolTip(QObject::tr("Toggle floating window"));
2371
void OverlaySplitterHandle::changeEvent(QEvent *e)
2373
QSplitterHandle::changeEvent(e);
2374
if (e->type() == QEvent::LanguageChange)
2378
void OverlaySplitterHandle::setTitleItem(QLayoutItem *item)
2383
void OverlaySplitterHandle::showTitle(bool enable)
2385
if (_showTitle == enable)
2390
setCursor(this->orientation() == Qt::Horizontal
2391
? Qt::SizeHorCursor : Qt::SizeVerCursor);
2392
if (OverlayParams::getDockOverlaySplitterHandleTimeout() > 0
2393
&& qApp->widgetAt(QCursor::pos()) != this)
2394
timer.start(OverlayParams::getDockOverlaySplitterHandleTimeout());
2396
_showTitle = enable;
2397
for (auto child : findChildren<QWidget*>(QString(), Qt::FindDirectChildrenOnly))
2398
child->setVisible(enable);
2402
void OverlaySplitterHandle::paintEvent(QPaintEvent *e)
2408
QSplitterHandle::paintEvent(e);
2412
int flags = Qt::AlignCenter;
2413
auto tabWidget = qobject_cast<OverlayTabWidget*>(
2414
splitter() ? splitter()->parentWidget() : nullptr);
2417
switch(tabWidget->getDockArea()) {
2418
case Qt::TopDockWidgetArea:
2419
case Qt::RightDockWidgetArea:
2420
flags = Qt::AlignRight;
2422
case Qt::BottomDockWidgetArea:
2423
case Qt::LeftDockWidgetArea:
2424
flags = Qt::AlignLeft;
2431
QDockWidget *dock = dockWidget();
2433
QSplitterHandle::paintEvent(e);
2437
QPainter painter(this);
2438
painter.fillRect(this->rect(), painter.background());
2440
QRect r = titleItem->geometry();
2441
if (this->orientation() != Qt::Vertical) {
2443
painter.translate(r.left(), r.top() + r.width());
2444
painter.rotate(-90);
2445
painter.translate(-r.left(), -r.top());
2447
QString text = painter.fontMetrics().elidedText(
2448
dock->windowTitle(), Qt::ElideRight, r.width());
2450
painter.drawText(r, flags, text);
2453
void OverlaySplitterHandle::endDrag()
2455
auto tabWidget = qobject_cast<OverlayTabWidget*>(splitter()->parentWidget());
2458
tabWidget->onSplitterResize(this->idx);
2460
OverlayTabWidget::_Dragging = nullptr;
2461
setCursor(this->orientation() == Qt::Horizontal
2462
? Qt::SizeHorCursor : Qt::SizeVerCursor);
2463
if (OverlayTabWidget::_DragFrame)
2464
OverlayTabWidget::_DragFrame->hide();
2465
if (OverlayTabWidget::_DragFloating)
2466
OverlayTabWidget::_DragFloating->hide();
2469
void OverlaySplitterHandle::keyPressEvent(QKeyEvent *ke)
2471
if (OverlayTabWidget::_Dragging == this && ke->key() == Qt::Key_Escape)
2475
void OverlaySplitterHandle::mouseMoveEvent(QMouseEvent *me)
2477
if (OverlayTabWidget::_Dragging != this)
2480
if (!(me->buttons() & Qt::LeftButton)) {
2485
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
2486
QPoint point = me->globalPos();
2488
QPoint point = me->globalPosition().toPoint();
2491
if (dragging == 1) {
2492
OverlayTabWidget *overlay = qobject_cast<OverlayTabWidget*>(
2493
splitter()->parentWidget());
2494
QPoint pos = me->pos();
2496
switch(overlay->getDockArea()) {
2497
case Qt::LeftDockWidgetArea:
2498
case Qt::RightDockWidgetArea:
2499
if (pos.x() < 0 || pos.x() > overlay->width())
2502
case Qt::TopDockWidgetArea:
2503
case Qt::BottomDockWidgetArea:
2504
if (pos.y() < 0 || pos.y() > overlay->height())
2511
if (dragging == 1) {
2512
QPoint offset = parentWidget()->mapFromGlobal(point) - dragOffset;
2513
moveSplitter(this->orientation() == Qt::Horizontal ? offset.x() : offset.y());
2516
setCursor(Qt::ClosedHandCursor);
2519
OverlayManager::instance()->dragDockWidget(point,
2525
void OverlaySplitterHandle::mousePressEvent(QMouseEvent *me)
2527
if (OverlayTabWidget::_Dragging || !getMainWindow() || me->button() != Qt::LeftButton)
2530
OverlayTabWidget::_Dragging = this;
2532
dragOffset = me->pos();
2533
auto dock = dockWidget();
2535
dragSize = dock->size();
2540
QSize mwSize = getMainWindow()->size();
2541
dragSize.setWidth(std::max(OverlayParams::getDockOverlayMinimumSize(),
2542
static_cast<long>(std::min(mwSize.width()/2, dragSize.width()))));
2543
dragSize.setHeight(std::max(OverlayParams::getDockOverlayMinimumSize(),
2544
static_cast<long>(std::min(mwSize.height()/2, dragSize.height()))));
2548
void OverlaySplitterHandle::mouseReleaseEvent(QMouseEvent *me)
2550
if (OverlayTabWidget::_Dragging != this || me->button() != Qt::LeftButton)
2553
if (dragging == 1) {
2559
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
2560
QPoint point = me->globalPos();
2562
QPoint point = me->globalPosition().toPoint();
2565
OverlayManager::instance()->dragDockWidget(point,
2576
OverlayGraphicsEffect::OverlayGraphicsEffect(QObject *parent) :
2577
QGraphicsEffect(parent),
2586
extern Q_WIDGETS_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0 );
2589
void OverlayGraphicsEffect::draw(QPainter* painter)
2592
if (!_enabled || _blurRadius + _size.height() <= 0 || _blurRadius + _size.width() <= 0) {
2593
drawSource(painter);
2597
PixmapPadMode mode = QGraphicsEffect::PadToEffectiveBoundingRect;
2599
QPixmap px = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
2606
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) {
2608
getMainWindow()->showMessage(
2609
QStringLiteral("dock overlay redraw %1").arg(count++));
2613
QTransform restoreTransform = painter->worldTransform();
2614
painter->setWorldTransform(QTransform());
2617
QImage tmp(px.size(), QImage::Format_ARGB32_Premultiplied);
2618
tmp.setDevicePixelRatio(px.devicePixelRatioF());
2620
QPainter tmpPainter(&tmp);
2622
tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
2623
if(_size.width() == 0 && _size.height() == 0)
2624
tmpPainter.drawPixmap(QPoint(0, 0), px);
2627
auto splitter = qobject_cast<QSplitter*>(parent());
2630
for (int size : splitter->sizes()) {
2634
QWidget *w = splitter->widget(i);
2635
if (w->findChild<TaskView::TaskView*>())
2637
QRect rect = w->geometry();
2638
if (splitter->orientation() == Qt::Vertical)
2639
clip.addRect(rect.x(), rect.y()+4,
2640
rect.width(), rect.height()-4);
2642
clip.addRect(rect.x()+4, rect.y(),
2643
rect.width()-4, rect.height());
2645
if (clip.isEmpty()) {
2646
drawSource(painter);
2649
tmpPainter.setClipPath(clip);
2652
for (int x=-_size.width();x<=_size.width();++x) {
2653
for (int y=-_size.height();y<=_size.height();++y) {
2655
tmpPainter.drawPixmap(QPoint(x, y), px);
2656
tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
2664
QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
2665
blurred.setDevicePixelRatio(px.devicePixelRatioF());
2667
QPainter blurPainter(&blurred);
2668
qt_blurImage(&blurPainter, tmp, blurRadius(), false, true);
2674
tmpPainter.begin(&tmp);
2675
tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
2676
tmpPainter.fillRect(tmp.rect(), color());
2680
painter->drawImage(QPointF(offset.x()+_offset.x(), offset.y()+_offset.y()), tmp);
2683
painter->drawPixmap(offset, px, QRectF());
2686
QWidget *focus = qApp->focusWidget();
2688
QWidget *widget = qobject_cast<QWidget*>(this->parent());
2689
if (auto *edit = qobject_cast<QPlainTextEdit*>(focus)) {
2690
if (!edit->isReadOnly() && edit->isEnabled()) {
2691
for(auto w=edit->parentWidget(); w; w=w->parentWidget()) {
2693
QRect r = edit->cursorRect();
2694
QRect rect(edit->viewport()->mapTo(widget, r.topLeft()),
2695
edit->viewport()->mapTo(widget, r.bottomRight()));
2698
painter->fillRect(rect.translated(offset), Qt::white);
2707
painter->setWorldTransform(restoreTransform);
2710
QRectF OverlayGraphicsEffect::boundingRectFor(const QRectF& rect) const
2714
return rect.united(rect.adjusted(-_blurRadius - _size.width() + _offset.x(),
2715
-_blurRadius - _size.height()+ _offset.y(),
2716
_blurRadius + _size.width() + _offset.x(),
2717
_blurRadius + _size.height() + _offset.y()));
2720
#include "moc_OverlayWidgets.cpp"