2017-02-27 21:15:20 +08:00
/*******************************************************************************
2017-06-10 04:04:02 +08:00
* * Qt Advanced Docking System
2017-02-27 21:15:20 +08:00
* * Copyright ( C ) 2017 Uwe Kindler
2017-06-10 04:04:02 +08:00
* *
* * This library is free software ; you can redistribute it and / or
* * modify it under the terms of the GNU Lesser General Public
* * License as published by the Free Software Foundation ; either
* * version 2.1 of the License , or ( at your option ) any later version .
* *
* * This library is distributed in the hope that it will be useful ,
2017-02-27 21:15:20 +08:00
* * but WITHOUT ANY WARRANTY ; without even the implied warranty of
2017-06-10 04:04:02 +08:00
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* * Lesser General Public License for more details .
* *
* * You should have received a copy of the GNU Lesser General Public
* * License along with this library ; If not , see < http : //www.gnu.org/licenses/>.
2017-02-27 21:15:20 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-02-25 05:44:02 +08:00
//============================================================================
2018-08-24 19:41:58 +08:00
/// \file DockWidgetTab.cpp
2017-02-25 05:44:02 +08:00
/// \author Uwe Kindler
2017-02-27 21:15:20 +08:00
/// \date 27.02.2017
2018-08-24 19:41:58 +08:00
/// \brief Implementation of CDockWidgetTab class
2017-02-25 05:44:02 +08:00
//============================================================================
2017-02-27 21:15:20 +08:00
2017-02-25 05:44:02 +08:00
//============================================================================
// INCLUDES
//============================================================================
2020-05-24 15:14:33 +08:00
# include "FloatingDragPreview.h"
2019-10-07 05:47:36 +08:00
# include "ElidingLabel.h"
2018-08-24 19:41:58 +08:00
# include "DockWidgetTab.h"
2017-02-25 05:44:02 +08:00
2017-02-27 21:15:20 +08:00
# include <QBoxLayout>
# include <QLabel>
# include <QMouseEvent>
# include <QStyle>
2017-02-28 22:23:02 +08:00
# include <QApplication>
2017-03-01 21:09:56 +08:00
# include <QSplitter>
2017-03-28 18:01:27 +08:00
# include <QDebug>
2018-11-08 17:04:29 +08:00
# include <QToolButton>
# include <QPushButton>
2018-11-09 17:07:56 +08:00
# include <QMenu>
2017-02-27 21:15:20 +08:00
2017-03-01 21:09:56 +08:00
# include "ads_globals.h"
2017-02-27 21:15:20 +08:00
# include "DockWidget.h"
2017-02-28 22:23:02 +08:00
# include "DockAreaWidget.h"
2017-03-01 21:09:56 +08:00
# include "FloatingDockContainer.h"
2017-03-02 18:43:48 +08:00
# include "DockOverlay.h"
# include "DockManager.h"
2019-10-18 14:31:26 +08:00
# include "IconProvider.h"
2017-02-27 21:15:20 +08:00
2018-11-08 17:04:29 +08:00
2017-02-25 05:44:02 +08:00
namespace ads
{
2017-03-01 21:09:56 +08:00
2018-11-05 19:00:56 +08:00
using tTabLabel = CElidingLabel ;
2017-03-01 21:09:56 +08:00
2017-02-27 21:15:20 +08:00
/**
2018-08-24 19:41:58 +08:00
* Private data class of CDockWidgetTab class ( pimpl )
2017-02-27 21:15:20 +08:00
*/
2018-08-24 19:41:58 +08:00
struct DockWidgetTabPrivate
2017-02-27 21:15:20 +08:00
{
2018-08-24 19:41:58 +08:00
CDockWidgetTab * _this ;
2017-02-27 21:15:20 +08:00
CDockWidget * DockWidget ;
2018-12-11 22:19:59 +08:00
QLabel * IconLabel = nullptr ;
2018-11-05 19:00:56 +08:00
tTabLabel * TitleLabel ;
2020-01-16 22:24:01 +08:00
QPoint GlobalDragStartMousePosition ;
2020-02-20 01:36:57 +08:00
QPoint DragStartMousePosition ;
2017-02-27 21:15:20 +08:00
bool IsActiveTab = false ;
2017-02-28 22:23:02 +08:00
CDockAreaWidget * DockArea = nullptr ;
2017-03-01 21:09:56 +08:00
eDragState DragState = DraggingInactive ;
2019-11-26 21:40:56 +08:00
IFloatingWidget * FloatingWidget = nullptr ;
2018-01-02 15:01:23 +08:00
QIcon Icon ;
2019-09-10 15:23:12 +08:00
QAbstractButton * CloseButton = nullptr ;
2018-11-08 17:04:29 +08:00
QSpacerItem * IconTextSpacer ;
2019-11-28 17:32:39 +08:00
QPoint TabDragStartPosition ;
2020-10-31 20:56:16 +08:00
QSize IconSize ;
2017-02-27 21:15:20 +08:00
/**
* Private data constructor
*/
2018-08-24 19:41:58 +08:00
DockWidgetTabPrivate ( CDockWidgetTab * _public ) ;
2017-02-27 21:15:20 +08:00
/**
* Creates the complete layout including all controls
*/
void createLayout ( ) ;
2017-02-28 22:23:02 +08:00
/**
* Moves the tab depending on the position in the given mouse event
*/
void moveTab ( QMouseEvent * ev ) ;
2017-03-01 21:09:56 +08:00
/**
* Test function for current drag state
*/
2019-12-16 15:41:15 +08:00
bool isDraggingState ( eDragState dragState ) const
2017-03-01 21:09:56 +08:00
{
return this - > DragState = = dragState ;
}
/**
* Starts floating of the dock widget that belongs to this title bar
2017-03-02 18:43:48 +08:00
* Returns true , if floating has been started and false if floating
* is not possible for any reason
2017-03-01 21:09:56 +08:00
*/
2018-12-20 22:29:38 +08:00
bool startFloating ( eDragState DraggingState = DraggingFloatingWidget ) ;
2018-11-08 19:57:25 +08:00
/**
* Returns true if the given config flag is set
*/
bool testConfigFlag ( CDockManager : : eConfigFlag Flag ) const
{
2020-06-11 14:06:37 +08:00
return CDockManager : : testConfigFlag ( Flag ) ;
2018-11-08 19:57:25 +08:00
}
2019-09-10 15:23:12 +08:00
/**
* Creates the close button as QPushButton or as QToolButton
*/
QAbstractButton * createCloseButton ( ) const
{
if ( testConfigFlag ( CDockManager : : TabCloseButtonIsToolButton ) )
{
2019-09-13 14:27:02 +08:00
auto Button = new QToolButton ( ) ;
Button - > setAutoRaise ( true ) ;
return Button ;
2019-09-10 15:23:12 +08:00
}
else
{
return new QPushButton ( ) ;
}
}
2019-11-28 17:32:39 +08:00
2020-08-21 14:09:13 +08:00
/**
* Update the close button visibility from current feature / config
*/
void updateCloseButtonVisibility ( bool active )
{
bool DockWidgetClosable = DockWidget - > features ( ) . testFlag ( CDockWidget : : DockWidgetClosable ) ;
bool ActiveTabHasCloseButton = testConfigFlag ( CDockManager : : ActiveTabHasCloseButton ) ;
bool AllTabsHaveCloseButton = testConfigFlag ( CDockManager : : AllTabsHaveCloseButton ) ;
bool TabHasCloseButton = ( ActiveTabHasCloseButton & & active ) | AllTabsHaveCloseButton ;
CloseButton - > setVisible ( DockWidgetClosable & & TabHasCloseButton ) ;
}
2020-09-02 15:04:59 +08:00
/**
* Update the size policy of the close button depending on the
* RetainTabSizeWhenCloseButtonHidden feature
*/
void updateCloseButtonSizePolicy ( )
{
auto Features = DockWidget - > features ( ) ;
auto SizePolicy = CloseButton - > sizePolicy ( ) ;
SizePolicy . setRetainSizeWhenHidden ( Features . testFlag ( CDockWidget : : DockWidgetClosable )
& & testConfigFlag ( CDockManager : : RetainTabSizeWhenCloseButtonHidden ) ) ;
CloseButton - > setSizePolicy ( SizePolicy ) ;
}
2019-11-28 17:32:39 +08:00
template < typename T >
IFloatingWidget * createFloatingWidget ( T * Widget , bool OpaqueUndocking )
{
if ( OpaqueUndocking )
{
return new CFloatingDockContainer ( Widget ) ;
}
else
{
2019-12-16 18:18:22 +08:00
auto w = new CFloatingDragPreview ( Widget ) ;
_this - > connect ( w , & CFloatingDragPreview : : draggingCanceled , [ = ] ( )
2019-12-16 18:10:59 +08:00
{
DragState = DraggingInactive ;
} ) ;
return w ;
2019-11-28 17:32:39 +08:00
}
}
2020-02-20 01:36:57 +08:00
/**
* Saves the drag start position in global and local coordinates
*/
void saveDragStartMousePosition ( const QPoint & GlobalPos )
{
GlobalDragStartMousePosition = GlobalPos ;
DragStartMousePosition = _this - > mapFromGlobal ( GlobalPos ) ;
}
2020-05-11 01:30:34 +08:00
2020-10-31 20:56:16 +08:00
/**
* Update the icon in case the icon size changed
*/
void updateIcon ( )
{
if ( ! IconLabel | | Icon . isNull ( ) )
{
return ;
}
if ( IconSize . isValid ( ) )
{
IconLabel - > setPixmap ( Icon . pixmap ( IconSize ) ) ;
}
else
{
IconLabel - > setPixmap ( Icon . pixmap ( _this - > style ( ) - > pixelMetric ( QStyle : : PM_SmallIconSize , nullptr , _this ) ) ) ;
}
IconLabel - > setVisible ( true ) ;
}
2017-02-27 21:15:20 +08:00
} ;
2018-08-24 19:41:58 +08:00
// struct DockWidgetTabPrivate
2017-02-27 21:15:20 +08:00
2017-03-13 04:41:50 +08:00
2017-02-27 21:15:20 +08:00
//============================================================================
2018-08-24 19:41:58 +08:00
DockWidgetTabPrivate : : DockWidgetTabPrivate ( CDockWidgetTab * _public ) :
2017-02-27 21:15:20 +08:00
_this ( _public )
{
}
//============================================================================
2018-08-24 19:41:58 +08:00
void DockWidgetTabPrivate : : createLayout ( )
2017-02-27 21:15:20 +08:00
{
2018-11-05 19:00:56 +08:00
TitleLabel = new tTabLabel ( ) ;
2020-04-24 15:29:33 +08:00
TitleLabel - > setElideMode ( Qt : : ElideRight ) ;
2018-11-05 19:00:56 +08:00
TitleLabel - > setText ( DockWidget - > windowTitle ( ) ) ;
2018-08-29 14:47:05 +08:00
TitleLabel - > setObjectName ( " dockWidgetTabLabel " ) ;
2018-11-08 17:04:29 +08:00
TitleLabel - > setAlignment ( Qt : : AlignCenter ) ;
2020-02-06 22:21:19 +08:00
_this - > connect ( TitleLabel , SIGNAL ( elidedChanged ( bool ) ) , SIGNAL ( elidedChanged ( bool ) ) ) ;
2018-11-08 17:04:29 +08:00
2019-09-10 15:23:12 +08:00
CloseButton = createCloseButton ( ) ;
2018-11-08 17:04:29 +08:00
CloseButton - > setObjectName ( " tabCloseButton " ) ;
2020-02-05 15:57:57 +08:00
internal : : setButtonIcon ( CloseButton , QStyle : : SP_TitleBarCloseButton , TabCloseIcon ) ;
2019-05-14 21:32:50 +08:00
CloseButton - > setSizePolicy ( QSizePolicy : : Fixed , QSizePolicy : : Fixed ) ;
2020-09-02 15:04:59 +08:00
updateCloseButtonSizePolicy ( ) ;
2020-02-05 15:33:40 +08:00
internal : : setToolTip ( CloseButton , QObject : : tr ( " Close Tab " ) ) ;
2018-11-09 17:07:56 +08:00
_this - > connect ( CloseButton , SIGNAL ( clicked ( ) ) , SIGNAL ( closeRequested ( ) ) ) ;
2018-11-08 17:04:29 +08:00
QFontMetrics fm ( TitleLabel - > font ( ) ) ;
int Spacing = qRound ( fm . height ( ) / 4.0 ) ;
// Fill the layout
QBoxLayout * Layout = new QBoxLayout ( QBoxLayout : : LeftToRight ) ;
Layout - > setContentsMargins ( 2 * Spacing , 0 , 0 , 0 ) ;
Layout - > setSpacing ( 0 ) ;
_this - > setLayout ( Layout ) ;
Layout - > addWidget ( TitleLabel , 1 ) ;
Layout - > addSpacing ( Spacing ) ;
Layout - > addWidget ( CloseButton ) ;
Layout - > addSpacing ( qRound ( Spacing * 4.0 / 3.0 ) ) ;
Layout - > setAlignment ( Qt : : AlignCenter ) ;
2017-02-27 21:15:20 +08:00
TitleLabel - > setVisible ( true ) ;
}
2017-02-28 22:23:02 +08:00
//============================================================================
2018-08-24 19:41:58 +08:00
void DockWidgetTabPrivate : : moveTab ( QMouseEvent * ev )
2017-02-28 22:23:02 +08:00
{
ev - > accept ( ) ;
2021-01-03 03:29:59 +08:00
QPoint Distance = internal : : globalPositionOf ( ev ) - GlobalDragStartMousePosition ;
2020-01-16 04:15:29 +08:00
Distance . setY ( 0 ) ;
auto TargetPos = Distance + TabDragStartPosition ;
2020-02-20 05:07:17 +08:00
TargetPos . rx ( ) = qMax ( TargetPos . x ( ) , 0 ) ;
TargetPos . rx ( ) = qMin ( _this - > parentWidget ( ) - > rect ( ) . right ( ) - _this - > width ( ) + 1 , TargetPos . rx ( ) ) ;
2020-01-16 04:15:29 +08:00
_this - > move ( TargetPos ) ;
2017-02-28 22:23:02 +08:00
_this - > raise ( ) ;
}
2017-02-27 21:15:20 +08:00
2017-03-01 21:09:56 +08:00
//============================================================================
2018-12-20 22:29:38 +08:00
bool DockWidgetTabPrivate : : startFloating ( eDragState DraggingState )
2017-03-01 21:09:56 +08:00
{
2018-09-14 19:21:29 +08:00
auto dockContainer = DockWidget - > dockContainer ( ) ;
2019-07-21 15:53:24 +08:00
ADS_PRINT ( " isFloating " < < dockContainer - > isFloating ( ) ) ;
ADS_PRINT ( " areaCount " < < dockContainer - > dockAreaCount ( ) ) ;
ADS_PRINT ( " widgetCount " < < DockWidget - > dockAreaWidget ( ) - > dockWidgetsCount ( ) ) ;
2017-03-02 18:43:48 +08:00
// if this is the last dock widget inside of this floating widget,
2017-09-06 21:45:22 +08:00
// then it does not make any sense, to make it floating because
2017-03-02 18:43:48 +08:00
// it is already floating
2018-09-14 19:21:29 +08:00
if ( dockContainer - > isFloating ( )
& & ( dockContainer - > visibleDockAreaCount ( ) = = 1 )
2018-09-14 14:46:10 +08:00
& & ( DockWidget - > dockAreaWidget ( ) - > dockWidgetsCount ( ) = = 1 ) )
2017-03-02 18:43:48 +08:00
{
return false ;
}
2019-07-21 15:53:24 +08:00
ADS_PRINT ( " startFloating " ) ;
2018-12-20 22:29:38 +08:00
DragState = DraggingState ;
2019-11-26 21:40:56 +08:00
IFloatingWidget * FloatingWidget = nullptr ;
2020-06-11 14:06:37 +08:00
bool OpaqueUndocking = CDockManager : : testConfigFlag ( CDockManager : : OpaqueUndocking ) | |
2019-11-26 21:40:56 +08:00
( DraggingFloatingWidget ! = DraggingState ) ;
2019-12-16 18:10:59 +08:00
2019-11-28 17:32:39 +08:00
// If section widget has multiple tabs, we take only one tab
// If it has only one single tab, we can move the complete
// dock area into floating widget
2020-04-27 13:48:15 +08:00
QSize Size ;
2018-09-14 14:46:10 +08:00
if ( DockArea - > dockWidgetsCount ( ) > 1 )
2017-03-01 21:09:56 +08:00
{
2019-11-28 17:32:39 +08:00
FloatingWidget = createFloatingWidget ( DockWidget , OpaqueUndocking ) ;
2020-04-27 13:48:15 +08:00
Size = DockWidget - > size ( ) ;
2017-03-01 21:09:56 +08:00
}
else
{
2019-11-28 17:32:39 +08:00
FloatingWidget = createFloatingWidget ( DockArea , OpaqueUndocking ) ;
2020-04-27 13:48:15 +08:00
Size = DockArea - > size ( ) ;
2017-03-01 21:09:56 +08:00
}
2018-12-20 22:29:38 +08:00
if ( DraggingFloatingWidget = = DraggingState )
{
2020-01-16 22:24:01 +08:00
FloatingWidget - > startFloating ( DragStartMousePosition , Size , DraggingFloatingWidget , _this ) ;
2018-12-20 22:29:38 +08:00
auto Overlay = DockWidget - > dockManager ( ) - > containerOverlay ( ) ;
Overlay - > setAllowedAreas ( OuterDockAreas ) ;
this - > FloatingWidget = FloatingWidget ;
}
2018-12-20 23:25:30 +08:00
else
{
2020-01-16 22:24:01 +08:00
FloatingWidget - > startFloating ( DragStartMousePosition , Size , DraggingInactive , nullptr ) ;
2018-12-20 23:25:30 +08:00
}
2019-11-27 22:50:18 +08:00
2017-03-02 18:43:48 +08:00
return true ;
2017-03-01 21:09:56 +08:00
}
2017-02-27 21:15:20 +08:00
//============================================================================
2018-08-24 19:41:58 +08:00
CDockWidgetTab : : CDockWidgetTab ( CDockWidget * DockWidget , QWidget * parent ) :
2017-02-27 21:15:20 +08:00
QFrame ( parent ) ,
2018-08-24 19:41:58 +08:00
d ( new DockWidgetTabPrivate ( this ) )
2017-02-27 21:15:20 +08:00
{
2017-03-02 18:43:48 +08:00
setAttribute ( Qt : : WA_NoMousePropagation , true ) ;
2017-02-27 21:15:20 +08:00
d - > DockWidget = DockWidget ;
d - > createLayout ( ) ;
2020-06-11 14:06:37 +08:00
if ( CDockManager : : testConfigFlag ( CDockManager : : FocusHighlighting ) )
2020-05-23 17:17:31 +08:00
{
setFocusPolicy ( Qt : : ClickFocus ) ;
}
2017-02-27 21:15:20 +08:00
}
//============================================================================
2018-08-24 19:41:58 +08:00
CDockWidgetTab : : ~ CDockWidgetTab ( )
2017-02-27 21:15:20 +08:00
{
2019-07-21 15:53:24 +08:00
ADS_PRINT ( " ~CDockWidgetTab() " ) ;
2017-02-27 21:15:20 +08:00
delete d ;
}
//============================================================================
2018-08-24 19:41:58 +08:00
void CDockWidgetTab : : mousePressEvent ( QMouseEvent * ev )
2017-02-27 21:15:20 +08:00
{
if ( ev - > button ( ) = = Qt : : LeftButton )
{
ev - > accept ( ) ;
2021-01-03 03:29:59 +08:00
d - > saveDragStartMousePosition ( internal : : globalPositionOf ( ev ) ) ;
2017-03-01 21:09:56 +08:00
d - > DragState = DraggingMousePressed ;
2021-01-22 13:18:34 +08:00
Q_EMIT clicked ( ) ;
2017-02-27 21:15:20 +08:00
return ;
}
2019-01-23 14:43:07 +08:00
Super : : mousePressEvent ( ev ) ;
2017-02-27 21:15:20 +08:00
}
//============================================================================
2018-08-24 19:41:58 +08:00
void CDockWidgetTab : : mouseReleaseEvent ( QMouseEvent * ev )
2017-02-27 21:15:20 +08:00
{
2019-12-16 20:56:20 +08:00
if ( ev - > button ( ) = = Qt : : LeftButton )
{
auto CurrentDragState = d - > DragState ;
2020-01-16 22:24:01 +08:00
d - > GlobalDragStartMousePosition = QPoint ( ) ;
2020-02-20 01:36:57 +08:00
d - > DragStartMousePosition = QPoint ( ) ;
2019-12-16 20:56:20 +08:00
d - > DragState = DraggingInactive ;
2019-12-13 18:52:50 +08:00
2019-12-16 20:56:20 +08:00
switch ( CurrentDragState )
2019-12-13 18:52:50 +08:00
{
2019-12-16 20:56:20 +08:00
case DraggingTab :
// End of tab moving, emit signal
if ( d - > DockArea )
{
2021-01-22 13:18:34 +08:00
Q_EMIT moved ( internal : : globalPositionOf ( ev ) ) ;
2019-12-16 20:56:20 +08:00
}
break ;
2019-12-13 18:52:50 +08:00
2019-12-16 20:56:20 +08:00
case DraggingFloatingWidget :
d - > FloatingWidget - > finishDragging ( ) ;
break ;
2019-12-13 18:52:50 +08:00
2019-12-16 20:56:20 +08:00
default : ; // do nothing
}
}
2019-12-13 18:52:50 +08:00
2019-01-23 14:43:07 +08:00
Super : : mouseReleaseEvent ( ev ) ;
2017-02-27 21:15:20 +08:00
}
//============================================================================
2018-08-24 19:41:58 +08:00
void CDockWidgetTab : : mouseMoveEvent ( QMouseEvent * ev )
2017-02-27 21:15:20 +08:00
{
2017-03-01 21:09:56 +08:00
if ( ! ( ev - > buttons ( ) & Qt : : LeftButton ) | | d - > isDraggingState ( DraggingInactive ) )
{
d - > DragState = DraggingInactive ;
2019-01-23 14:43:07 +08:00
Super : : mouseMoveEvent ( ev ) ;
2017-03-01 21:09:56 +08:00
return ;
}
2018-10-12 15:17:14 +08:00
// move floating window
2017-03-01 21:09:56 +08:00
if ( d - > isDraggingState ( DraggingFloatingWidget ) )
2017-02-28 22:23:02 +08:00
{
2018-08-24 20:04:21 +08:00
d - > FloatingWidget - > moveFloating ( ) ;
2019-01-23 14:43:07 +08:00
Super : : mouseMoveEvent ( ev ) ;
2017-02-28 22:23:02 +08:00
return ;
}
2017-02-27 21:15:20 +08:00
2017-02-28 22:23:02 +08:00
// move tab
2017-03-01 21:09:56 +08:00
if ( d - > isDraggingState ( DraggingTab ) )
2017-02-28 22:23:02 +08:00
{
2018-08-24 20:04:21 +08:00
// Moving the tab is always allowed because it does not mean moving the
// dock widget around
d - > moveTab ( ev ) ;
2017-02-28 22:23:02 +08:00
}
2020-02-20 05:07:17 +08:00
auto MappedPos = mapToParent ( ev - > pos ( ) ) ;
bool MouseOutsideBar = ( MappedPos . x ( ) < 0 ) | | ( MappedPos . x ( ) > parentWidget ( ) - > rect ( ) . right ( ) ) ;
2018-10-15 21:09:59 +08:00
// Maybe a fixed drag distance is better here ?
2021-01-03 03:29:59 +08:00
int DragDistanceY = qAbs ( d - > GlobalDragStartMousePosition . y ( ) - internal : : globalPositionOf ( ev ) . y ( ) ) ;
2020-02-20 05:07:17 +08:00
if ( DragDistanceY > = CDockManager : : startDragDistance ( ) | | MouseOutsideBar )
2017-03-01 21:09:56 +08:00
{
2018-09-14 14:46:10 +08:00
// If this is the last dock area in a dock container with only
// one single dock widget it does not make sense to move it to a new
// floating widget and leave this one empty
if ( d - > DockArea - > dockContainer ( ) - > isFloating ( )
& & d - > DockArea - > openDockWidgetsCount ( ) = = 1
& & d - > DockArea - > dockContainer ( ) - > visibleDockAreaCount ( ) = = 1 )
{
return ;
}
2020-02-16 21:37:14 +08:00
// Floating is only allowed for widgets that are floatable
// If we do non opaque undocking, then can create the drag preview
// if the widget is movable.
auto Features = d - > DockWidget - > features ( ) ;
if ( Features . testFlag ( CDockWidget : : DockWidgetFloatable )
| | ( Features . testFlag ( CDockWidget : : DockWidgetMovable ) & & ! CDockManager : : testConfigFlag ( CDockManager : : OpaqueUndocking ) ) )
2018-08-24 20:04:21 +08:00
{
2019-11-28 17:32:39 +08:00
// If we undock, we need to restore the initial position of this
// tab because it looks strange if it remains on its dragged position
2020-06-11 14:06:37 +08:00
if ( d - > isDraggingState ( DraggingTab ) & & ! CDockManager : : testConfigFlag ( CDockManager : : OpaqueUndocking ) )
2019-11-28 17:32:39 +08:00
{
2020-02-20 05:07:17 +08:00
parentWidget ( ) - > layout ( ) - > update ( ) ;
2019-11-28 17:32:39 +08:00
}
2018-08-10 18:54:09 +08:00
d - > startFloating ( ) ;
}
2017-03-02 18:43:48 +08:00
return ;
2017-03-01 21:09:56 +08:00
}
2018-09-14 14:46:10 +08:00
else if ( d - > DockArea - > openDockWidgetsCount ( ) > 1
2021-01-03 03:29:59 +08:00
& & ( internal : : globalPositionOf ( ev ) - d - > GlobalDragStartMousePosition ) . manhattanLength ( ) > = QApplication : : startDragDistance ( ) ) // Wait a few pixels before start moving
2017-02-28 22:23:02 +08:00
{
2019-11-28 17:32:39 +08:00
// If we start dragging the tab, we save its inital position to
// restore it later
if ( DraggingTab ! = d - > DragState )
{
d - > TabDragStartPosition = this - > pos ( ) ;
}
2018-08-24 20:04:21 +08:00
d - > DragState = DraggingTab ;
2017-02-28 22:23:02 +08:00
return ;
}
2019-01-23 14:43:07 +08:00
Super : : mouseMoveEvent ( ev ) ;
2017-02-27 21:15:20 +08:00
}
2017-02-25 05:44:02 +08:00
2017-02-27 21:15:20 +08:00
2018-11-09 17:07:56 +08:00
//============================================================================
void CDockWidgetTab : : contextMenuEvent ( QContextMenuEvent * ev )
{
ev - > accept ( ) ;
2019-12-16 20:56:20 +08:00
if ( d - > isDraggingState ( DraggingFloatingWidget ) )
{
return ;
}
2018-11-09 17:07:56 +08:00
2020-02-20 01:36:57 +08:00
d - > saveDragStartMousePosition ( ev - > globalPos ( ) ) ;
2018-11-09 17:07:56 +08:00
QMenu Menu ( this ) ;
2020-01-31 21:27:01 +08:00
const bool isFloatable = d - > DockWidget - > features ( ) . testFlag ( CDockWidget : : DockWidgetFloatable ) ;
const bool isNotOnlyTabInContainer = ! d - > DockArea - > dockContainer ( ) - > hasTopLevelDockWidget ( ) ;
const bool isDetachable = isFloatable & & isNotOnlyTabInContainer ;
2019-11-25 22:59:08 +08:00
auto Action = Menu . addAction ( tr ( " Detach " ) , this , SLOT ( detachDockWidget ( ) ) ) ;
2020-01-31 21:27:01 +08:00
Action - > setEnabled ( isDetachable ) ;
2018-11-09 17:07:56 +08:00
Menu . addSeparator ( ) ;
2019-07-11 21:12:39 +08:00
Action = Menu . addAction ( tr ( " Close " ) , this , SIGNAL ( closeRequested ( ) ) ) ;
2018-11-09 17:07:56 +08:00
Action - > setEnabled ( isClosable ( ) ) ;
Menu . addAction ( tr ( " Close Others " ) , this , SIGNAL ( closeOtherTabsRequested ( ) ) ) ;
2020-01-15 17:03:50 +08:00
Menu . exec ( ev - > globalPos ( ) ) ;
2018-11-09 17:07:56 +08:00
}
2017-02-27 21:15:20 +08:00
//============================================================================
2018-08-24 19:41:58 +08:00
bool CDockWidgetTab : : isActiveTab ( ) const
2017-02-27 21:15:20 +08:00
{
return d - > IsActiveTab ;
}
//============================================================================
2018-08-24 19:41:58 +08:00
void CDockWidgetTab : : setActiveTab ( bool active )
2017-02-27 21:15:20 +08:00
{
2020-09-02 15:04:59 +08:00
d - > updateCloseButtonVisibility ( active ) ;
2020-06-05 18:14:26 +08:00
2020-06-06 02:42:43 +08:00
// Focus related stuff
2020-06-11 14:06:37 +08:00
if ( CDockManager : : testConfigFlag ( CDockManager : : FocusHighlighting ) & & ! d - > DockWidget - > dockManager ( ) - > isRestoringState ( ) )
2020-06-05 18:14:26 +08:00
{
bool UpdateFocusStyle = false ;
if ( active & & ! hasFocus ( ) )
{
setFocus ( Qt : : OtherFocusReason ) ;
UpdateFocusStyle = true ;
}
if ( d - > IsActiveTab = = active )
{
if ( UpdateFocusStyle )
{
updateStyle ( ) ;
}
return ;
}
}
else if ( d - > IsActiveTab = = active )
2020-05-13 17:17:43 +08:00
{
2020-06-05 13:27:44 +08:00
return ;
2020-05-13 17:17:43 +08:00
}
2020-05-23 17:17:31 +08:00
2017-02-27 21:15:20 +08:00
d - > IsActiveTab = active ;
2020-05-11 01:30:34 +08:00
updateStyle ( ) ;
2017-02-27 21:15:20 +08:00
update ( ) ;
2020-02-07 18:49:45 +08:00
updateGeometry ( ) ;
2017-02-27 21:15:20 +08:00
2021-01-22 13:18:34 +08:00
Q_EMIT activeTabChanged ( ) ;
2017-02-27 21:15:20 +08:00
}
//============================================================================
2018-08-24 19:41:58 +08:00
CDockWidget * CDockWidgetTab : : dockWidget ( ) const
2017-02-27 21:15:20 +08:00
{
return d - > DockWidget ;
}
2017-02-28 22:23:02 +08:00
2020-02-15 05:56:48 +08:00
//============================================================================
void CDockWidgetTab : : setDockAreaWidget ( CDockAreaWidget * DockArea )
{
d - > DockArea = DockArea ;
}
//============================================================================
CDockAreaWidget * CDockWidgetTab : : dockAreaWidget ( ) const
{
return d - > DockArea ;
}
2018-01-02 15:01:23 +08:00
//============================================================================
2018-08-24 19:41:58 +08:00
void CDockWidgetTab : : setIcon ( const QIcon & Icon )
2018-01-02 15:01:23 +08:00
{
2018-11-08 17:04:29 +08:00
QBoxLayout * Layout = qobject_cast < QBoxLayout * > ( layout ( ) ) ;
2018-12-11 22:19:59 +08:00
if ( ! d - > IconLabel & & Icon . isNull ( ) )
{
return ;
}
if ( ! d - > IconLabel )
{
d - > IconLabel = new QLabel ( ) ;
d - > IconLabel - > setAlignment ( Qt : : AlignVCenter ) ;
d - > IconLabel - > setSizePolicy ( QSizePolicy : : Fixed , QSizePolicy : : Preferred ) ;
2020-02-05 15:33:40 +08:00
internal : : setToolTip ( d - > IconLabel , d - > TitleLabel - > toolTip ( ) ) ;
2018-12-11 22:19:59 +08:00
Layout - > insertWidget ( 0 , d - > IconLabel , Qt : : AlignVCenter ) ;
Layout - > insertSpacing ( 1 , qRound ( 1.5 * Layout - > contentsMargins ( ) . left ( ) / 2.0 ) ) ;
}
else if ( Icon . isNull ( ) )
{
// Remove icon label and spacer item
Layout - > removeWidget ( d - > IconLabel ) ;
Layout - > removeItem ( Layout - > itemAt ( 0 ) ) ;
delete d - > IconLabel ;
d - > IconLabel = nullptr ;
}
2018-01-02 15:01:23 +08:00
d - > Icon = Icon ;
2020-10-31 20:56:16 +08:00
d - > updateIcon ( ) ;
2018-01-02 15:01:23 +08:00
}
//============================================================================
2018-08-24 19:41:58 +08:00
const QIcon & CDockWidgetTab : : icon ( ) const
2018-01-02 15:01:23 +08:00
{
return d - > Icon ;
}
2018-09-07 19:13:44 +08:00
2018-10-12 15:17:14 +08:00
//============================================================================
QString CDockWidgetTab : : text ( ) const
{
return d - > TitleLabel - > text ( ) ;
}
2018-09-07 19:13:44 +08:00
//============================================================================
void CDockWidgetTab : : mouseDoubleClickEvent ( QMouseEvent * event )
{
// If this is the last dock area in a dock container it does not make
// sense to move it to a new floating widget and leave this one
// empty
2019-07-11 21:12:39 +08:00
if ( ( ! d - > DockArea - > dockContainer ( ) - > isFloating ( ) | | d - > DockArea - > dockWidgetsCount ( ) > 1 )
& & d - > DockWidget - > features ( ) . testFlag ( CDockWidget : : DockWidgetFloatable ) )
2018-09-07 19:13:44 +08:00
{
2021-01-03 03:29:59 +08:00
d - > saveDragStartMousePosition ( internal : : globalPositionOf ( event ) ) ;
2018-12-20 22:29:38 +08:00
d - > startFloating ( DraggingInactive ) ;
2018-09-07 19:13:44 +08:00
}
Super : : mouseDoubleClickEvent ( event ) ;
}
2018-09-14 19:21:29 +08:00
//============================================================================
void CDockWidgetTab : : setVisible ( bool visible )
{
2021-01-10 02:02:25 +08:00
visible & = ! d - > DockWidget - > features ( ) . testFlag ( CDockWidget : : NoTab ) ;
2020-05-20 02:26:57 +08:00
Super : : setVisible ( visible ) ;
2018-09-14 19:21:29 +08:00
}
2018-11-08 17:04:29 +08:00
2019-01-16 19:23:07 +08:00
//============================================================================
void CDockWidgetTab : : setText ( const QString & title )
{
d - > TitleLabel - > setText ( title ) ;
}
2020-04-11 03:06:43 +08:00
//============================================================================
2020-02-06 22:21:19 +08:00
bool CDockWidgetTab : : isTitleElided ( ) const
{
return d - > TitleLabel - > isElided ( ) ;
}
2019-01-16 19:23:07 +08:00
2018-11-09 17:07:56 +08:00
//============================================================================
bool CDockWidgetTab : : isClosable ( ) const
{
return d - > DockWidget & & d - > DockWidget - > features ( ) . testFlag ( CDockWidget : : DockWidgetClosable ) ;
}
//===========================================================================
2019-11-25 22:59:08 +08:00
void CDockWidgetTab : : detachDockWidget ( )
2018-11-09 17:07:56 +08:00
{
2019-07-11 21:12:39 +08:00
if ( ! d - > DockWidget - > features ( ) . testFlag ( CDockWidget : : DockWidgetFloatable ) )
{
return ;
}
2020-02-20 01:36:57 +08:00
d - > saveDragStartMousePosition ( QCursor : : pos ( ) ) ;
2018-12-20 22:29:38 +08:00
d - > startFloating ( DraggingInactive ) ;
2018-11-09 17:07:56 +08:00
}
2017-02-25 05:44:02 +08:00
2019-01-23 14:43:07 +08:00
//============================================================================
bool CDockWidgetTab : : event ( QEvent * e )
{
2020-01-15 17:03:50 +08:00
# ifndef QT_NO_TOOLTIP
2019-01-23 14:43:07 +08:00
if ( e - > type ( ) = = QEvent : : ToolTipChange )
{
const auto text = toolTip ( ) ;
d - > TitleLabel - > setToolTip ( text ) ;
}
2020-01-15 17:03:50 +08:00
# endif
2019-01-23 14:43:07 +08:00
return Super : : event ( e ) ;
}
2019-09-13 20:19:43 +08:00
//============================================================================
void CDockWidgetTab : : onDockWidgetFeaturesChanged ( )
{
2020-09-02 15:04:59 +08:00
d - > updateCloseButtonSizePolicy ( ) ;
d - > updateCloseButtonVisibility ( isActiveTab ( ) ) ;
2019-09-13 20:19:43 +08:00
}
2020-04-11 03:06:43 +08:00
//============================================================================
void CDockWidgetTab : : setElideMode ( Qt : : TextElideMode mode )
{
d - > TitleLabel - > setElideMode ( mode ) ;
}
2020-05-11 01:30:34 +08:00
//============================================================================
void CDockWidgetTab : : updateStyle ( )
{
2020-06-07 23:19:07 +08:00
internal : : repolishStyle ( this , internal : : RepolishDirectChildren ) ;
2020-05-11 01:30:34 +08:00
}
2020-10-31 20:56:16 +08:00
//============================================================================
QSize CDockWidgetTab : : iconSize ( ) const
{
return d - > IconSize ;
}
//============================================================================
void CDockWidgetTab : : setIconSize ( const QSize & Size )
{
d - > IconSize = Size ;
d - > updateIcon ( ) ;
}
2019-01-23 14:43:07 +08:00
} // namespace ads
2017-02-25 05:44:02 +08:00
//---------------------------------------------------------------------------
2018-08-24 19:41:58 +08:00
// EOF DockWidgetTab.cpp