<s> from atom . api import IntEnum <EOL> from enaml . qt . QtCore import ( <EOL> Qt , QSize , QPoint , QRect , QMargins , QEvent , QObject , QPropertyAnimation , <EOL> Signal <EOL> ) <EOL> from enaml . qt . QtGui import ( <EOL> QBoxLayout , QSizePolicy , QFrame , QPushButton , QStyle , QStyleOption , <EOL> QStylePainter , QStyleOptionButton , QApplication , QVBoxLayout , QHBoxLayout , <EOL> QLayout <EOL> ) <EOL> from . event_types import ( <EOL> QDockItemEvent , DockItemExtended , DockItemRetracted , <EOL> DockAreaContentsChanged <EOL> ) <EOL> from . utils import repolish <EOL> class QDockBar ( QFrame ) : <EOL> """<STR_LIT>""" <EOL> class Position ( IntEnum ) : <EOL> """<STR_LIT>""" <EOL> North = <NUM_LIT:0> <EOL> East = <NUM_LIT:1> <EOL> South = <NUM_LIT:2> <EOL> West = <NUM_LIT:3> <EOL> North = Position . North <EOL> East = Position . East <EOL> South = Position . South <EOL> West = Position . West <EOL> LayoutPositions = [ <EOL> QBoxLayout . LeftToRight , <EOL> QBoxLayout . TopToBottom , <EOL> QBoxLayout . LeftToRight , <EOL> QBoxLayout . TopToBottom , <EOL> ] <EOL> def __init__ ( self , parent = None , position = Position . North ) : <EOL> """<STR_LIT>""" <EOL> super ( QDockBar , self ) . __init__ ( parent ) <EOL> assert isinstance ( position , QDockBar . Position ) <EOL> self . setProperty ( '<STR_LIT>' , int ( position ) ) <EOL> layout = QBoxLayout ( self . LayoutPositions [ position ] ) <EOL> layout . setContentsMargins ( QMargins ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) ) <EOL> layout . addStretch ( <NUM_LIT:1> ) <EOL> self . setLayout ( layout ) <EOL> self . updateSpacing ( ) <EOL> def event ( self , event ) : <EOL> """<STR_LIT>""" <EOL> if event . type ( ) == QEvent . StyleChange : <EOL> self . updateSpacing ( ) <EOL> return super ( QDockBar , self ) . event ( event ) <EOL> def updateSpacing ( self ) : <EOL> """<STR_LIT>""" <EOL> opt = QStyleOption ( ) <EOL> opt . initFrom ( self ) <EOL> style = self . style ( ) <EOL> spacing = style . pixelMetric ( QStyle . PM_ToolBarItemSpacing , opt , self ) <EOL> self . layout ( ) . setSpacing ( spacing ) <EOL> def position ( self ) : <EOL> """<STR_LIT>""" <EOL> return QDockBar . Position ( self . property ( '<STR_LIT>' ) ) <EOL> def isEmpty ( self ) : <EOL> """<STR_LIT>""" <EOL> layout = self . layout ( ) <EOL> for index in xrange ( layout . count ( ) ) : <EOL> item = layout . itemAt ( index ) <EOL> if item . widget ( ) is not None : <EOL> return False <EOL> return True <EOL> def addButton ( self , button ) : <EOL> """<STR_LIT>""" <EOL> return self . insertButton ( - <NUM_LIT:1> , button ) <EOL> def insertButton ( self , index , button ) : <EOL> """<STR_LIT>""" <EOL> assert isinstance ( button , QDockBarButton ) <EOL> layout = self . layout ( ) <EOL> if index < <NUM_LIT:0> : <EOL> index = layout . count ( ) <EOL> if index == layout . count ( ) : <EOL> index = max ( <NUM_LIT:0> , index - <NUM_LIT:1> ) <EOL> layout . insertWidget ( index , button ) <EOL> class QDockBarButton ( QPushButton ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , parent = None ) : <EOL> """<STR_LIT>""" <EOL> super ( QDockBarButton , self ) . __init__ ( parent ) <EOL> self . setSizePolicy ( QSizePolicy ( QSizePolicy . Fixed , QSizePolicy . Fixed ) ) <EOL> self . setCheckable ( True ) <EOL> def position ( self ) : <EOL> """<STR_LIT>""" <EOL> parent = self . parent ( ) <EOL> if isinstance ( parent , QDockBar ) : <EOL> return parent . position ( ) <EOL> return QDockBar . North <EOL> def onAlerted ( self , level ) : <EOL> """<STR_LIT>""" <EOL> self . setProperty ( u'<STR_LIT>' , level or None ) <EOL> repolish ( self ) <EOL> def sizeHint ( self ) : <EOL> """<STR_LIT>""" <EOL> hint = super ( QDockBarButton , self ) . sizeHint ( ) <EOL> p = self . position ( ) <EOL> if p == QDockBar . East or p == QDockBar . West : <EOL> hint . transpose ( ) <EOL> return hint <EOL> def paintEvent ( self , event ) : <EOL> """<STR_LIT>""" <EOL> painter = QStylePainter ( self ) <EOL> opt = QStyleOptionButton ( ) <EOL> self . initStyleOption ( opt ) <EOL> opt . state &= ~ QStyle . State_HasFocus <EOL> p = self . position ( ) <EOL> if p == QDockBar . East : <EOL> size = opt . rect . size ( ) <EOL> size . transpose ( ) <EOL> opt . rect . setSize ( size ) <EOL> painter . rotate ( <NUM_LIT> ) <EOL> painter . translate ( <NUM_LIT:0> , - size . height ( ) ) <EOL> elif p == QDockBar . West : <EOL> size = opt . rect . size ( ) <EOL> size . transpose ( ) <EOL> opt . rect . setSize ( size ) <EOL> painter . rotate ( - <NUM_LIT> ) <EOL> painter . translate ( - size . width ( ) , <NUM_LIT:0> ) <EOL> painter . drawControl ( QStyle . CE_PushButton , opt ) <EOL> class QDockBarItemHandle ( QFrame ) : <EOL> """<STR_LIT>""" <EOL> handleMoved = Signal ( QPoint ) <EOL> def __init__ ( self , parent = None ) : <EOL> """<STR_LIT>""" <EOL> super ( QDockBarItemHandle , self ) . __init__ ( parent ) <EOL> policy = QSizePolicy ( QSizePolicy . Minimum , QSizePolicy . Minimum ) <EOL> self . setSizePolicy ( policy ) <EOL> self . _press_pos = QPoint ( ) <EOL> self . _size_hint = QSize ( <NUM_LIT:5> , <NUM_LIT:5> ) <EOL> def sizeHint ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _size_hint <EOL> def mousePressEvent ( self , event ) : <EOL> """<STR_LIT>""" <EOL> event . ignore ( ) <EOL> if event . button ( ) == Qt . LeftButton : <EOL> self . _press_pos = event . pos ( ) <EOL> event . accept ( ) <EOL> def mouseReleaseEvent ( self , event ) : <EOL> """<STR_LIT>""" <EOL> event . ignore ( ) <EOL> if event . button ( ) == Qt . LeftButton : <EOL> self . _press_pos = QPoint ( ) <EOL> event . accept ( ) <EOL> def mouseMoveEvent ( self , event ) : <EOL> """<STR_LIT>""" <EOL> event . ignore ( ) <EOL> if not self . _press_pos . isNull ( ) : <EOL> self . handleMoved . emit ( event . pos ( ) - self . _press_pos ) <EOL> event . accept ( ) <EOL> class QDockBarItem ( QFrame ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , parent = None , position = QDockBar . North ) : <EOL> """<STR_LIT>""" <EOL> super ( QDockBarItem , self ) . __init__ ( parent ) <EOL> assert isinstance ( position , QDockBar . Position ) <EOL> self . setProperty ( '<STR_LIT>' , int ( position ) ) <EOL> self . _user_size = QSize ( ) <EOL> self . _animation = None <EOL> self . _widget = None <EOL> handle = QDockBarItemHandle ( ) <EOL> handle . handleMoved . connect ( self . _onHandleMoved ) <EOL> if position == QDockBar . North or position == QDockBar . South : <EOL> layout = QVBoxLayout ( ) <EOL> handle . setCursor ( Qt . SizeVerCursor ) <EOL> else : <EOL> layout = QHBoxLayout ( ) <EOL> handle . setCursor ( Qt . SizeHorCursor ) <EOL> layout . addWidget ( handle , <NUM_LIT:0> ) <EOL> layout . setSpacing ( <NUM_LIT:0> ) <EOL> layout . setContentsMargins ( QMargins ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) ) <EOL> layout . setSizeConstraint ( QLayout . SetMinimumSize ) <EOL> self . setLayout ( layout ) <EOL> def _onHandleMoved ( self , delta ) : <EOL> """<STR_LIT>""" <EOL> animation = self . _animation <EOL> if animation and animation . state ( ) == animation . Running : <EOL> return <EOL> p = self . position ( ) <EOL> if p == QDockBar . North : <EOL> delta = QSize ( <NUM_LIT:0> , delta . y ( ) ) <EOL> elif p == QDockBar . East : <EOL> delta = QSize ( - delta . x ( ) , <NUM_LIT:0> ) <EOL> elif p == QDockBar . South : <EOL> delta = QSize ( <NUM_LIT:0> , - delta . y ( ) ) <EOL> else : <EOL> delta = QSize ( delta . x ( ) , <NUM_LIT:0> ) <EOL> user_size = self . size ( ) + delta <EOL> user_size = user_size . expandedTo ( self . minimumSize ( ) ) <EOL> parent = self . parent ( ) <EOL> if parent is not None : <EOL> user_size = user_size . boundedTo ( parent . size ( ) ) <EOL> self . _user_size = user_size <EOL> if p == QDockBar . East or p == QDockBar . South : <EOL> d = user_size - self . size ( ) <EOL> p = self . pos ( ) - QPoint ( d . width ( ) , d . height ( ) ) <EOL> self . setGeometry ( QRect ( p , user_size ) ) <EOL> else : <EOL> self . resize ( user_size ) <EOL> def widget ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _widget <EOL> def setWidget ( self , widget ) : <EOL> """<STR_LIT>""" <EOL> old = self . _widget <EOL> if old is not None : <EOL> old . setParent ( None ) <EOL> self . _widget = widget <EOL> if widget is not None : <EOL> index = ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:0> ) [ self . position ( ) ] <EOL> layout = self . layout ( ) <EOL> layout . insertWidget ( index , widget , <NUM_LIT:1> ) <EOL> def position ( self ) : <EOL> """<STR_LIT>""" <EOL> return QDockBar . Position ( self . property ( '<STR_LIT>' ) ) <EOL> def animation ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _animation <EOL> def setAnimation ( self , animation ) : <EOL> """<STR_LIT>""" <EOL> self . _animation = animation <EOL> def sizeHint ( self ) : <EOL> """<STR_LIT>""" <EOL> user = self . _user_size <EOL> if user . isValid ( ) : <EOL> return user <EOL> return super ( QDockBarItem , self ) . sizeHint ( ) <EOL> class QDockBarManager ( QObject ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , parent ) : <EOL> """<STR_LIT>""" <EOL> super ( QDockBarManager , self ) . __init__ ( parent ) <EOL> self . _dock_bars = [ None , None , None , None ] <EOL> self . _active_items = { } <EOL> self . _widgets = { } <EOL> _layout_coords = [ <EOL> ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> ( <NUM_LIT:1> , <NUM_LIT:2> , <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> ( <NUM_LIT:2> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> ] <EOL> @ staticmethod <EOL> def _prepareAnimation ( item ) : <EOL> """<STR_LIT>""" <EOL> animation = item . animation ( ) <EOL> if animation is not None : <EOL> animation . stop ( ) <EOL> animation . finished . disconnect ( ) <EOL> else : <EOL> animation = QPropertyAnimation ( item , '<STR_LIT>' ) <EOL> item . setAnimation ( animation ) <EOL> return animation <EOL> def _getDockBar ( self , position , create = True ) : <EOL> """<STR_LIT>""" <EOL> dock_bar = self . _dock_bars [ position ] <EOL> if dock_bar is not None : <EOL> return dock_bar <EOL> if create : <EOL> dock_bar = self . _dock_bars [ position ] = QDockBar ( position = position ) <EOL> coords = self . _layout_coords [ position ] <EOL> layout = self . parent ( ) . primaryPane ( ) . layout ( ) <EOL> layout . addWidget ( dock_bar , * coords ) <EOL> return dock_bar <EOL> def _trackForResize ( self , item , slide_out ) : <EOL> """<STR_LIT>""" <EOL> active = self . _active_items <EOL> install = len ( active ) == <NUM_LIT:0> <EOL> active [ item ] = slide_out <EOL> if install : <EOL> self . parent ( ) . centralPane ( ) . installEventFilter ( self ) <EOL> def _untrackForResize ( self , item ) : <EOL> """<STR_LIT>""" <EOL> active = self . _active_items <EOL> active . pop ( item , None ) <EOL> if len ( active ) == <NUM_LIT:0> : <EOL> self . parent ( ) . centralPane ( ) . removeEventFilter ( self ) <EOL> def _slideOut ( self , item ) : <EOL> """<STR_LIT>""" <EOL> self . _trackForResize ( item , True ) <EOL> animation = self . _prepareAnimation ( item ) <EOL> animation . finished . connect ( self . _onSlideOutFinished ) <EOL> start_geo , end_geo = self . _animationGeo ( item ) <EOL> if item . isVisible ( ) : <EOL> start_geo = item . geometry ( ) <EOL> else : <EOL> item . setGeometry ( start_geo ) <EOL> item . show ( ) <EOL> item . raise_ ( ) <EOL> animation . setStartValue ( start_geo ) <EOL> animation . setEndValue ( end_geo ) <EOL> animation . start ( ) <EOL> def _slideIn ( self , item ) : <EOL> """<STR_LIT>""" <EOL> if not item . isVisible ( ) : <EOL> return <EOL> self . _trackForResize ( item , False ) <EOL> animation = self . _prepareAnimation ( item ) <EOL> animation . finished . connect ( self . _onSlideInFinished ) <EOL> start_geo = item . geometry ( ) <EOL> end_geo , ignored = self . _animationGeo ( item ) <EOL> animation . setStartValue ( start_geo ) <EOL> animation . setEndValue ( end_geo ) <EOL> animation . start ( ) <EOL> def _animationGeo ( self , item ) : <EOL> """<STR_LIT>""" <EOL> pane = self . parent ( ) . centralPane ( ) <EOL> hint = item . sizeHint ( ) . boundedTo ( pane . size ( ) ) <EOL> position = item . position ( ) <EOL> if position == QDockBar . North : <EOL> start_pos = QPoint ( <NUM_LIT:0> , - hint . height ( ) ) <EOL> end_pos = QPoint ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> size = QSize ( pane . width ( ) , hint . height ( ) ) <EOL> elif position == QDockBar . East : <EOL> start_pos = QPoint ( pane . width ( ) , <NUM_LIT:0> ) <EOL> end_pos = QPoint ( pane . width ( ) - hint . width ( ) , <NUM_LIT:0> ) <EOL> size = QSize ( hint . width ( ) , pane . height ( ) ) <EOL> elif position == QDockBar . South : <EOL> start_pos = QPoint ( <NUM_LIT:0> , pane . height ( ) ) <EOL> end_pos = QPoint ( <NUM_LIT:0> , pane . height ( ) - hint . height ( ) ) <EOL> size = QSize ( pane . width ( ) , hint . height ( ) ) <EOL> else : <EOL> start_pos = QPoint ( - hint . width ( ) , <NUM_LIT:0> ) <EOL> end_pos = QPoint ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> size = QSize ( hint . width ( ) , pane . height ( ) ) <EOL> start_geo = QRect ( start_pos , size ) <EOL> end_geo = QRect ( end_pos , size ) <EOL> return start_geo , end_geo <EOL> def _toggleCheckedButtons ( self , allowed ) : <EOL> """<STR_LIT>""" <EOL> for key in self . _widgets : <EOL> if isinstance ( key , QDockBarButton ) : <EOL> if key is not allowed and key . isChecked ( ) : <EOL> key . setChecked ( False ) <EOL> def _onButtonToggled ( self , checked ) : <EOL> """<STR_LIT>""" <EOL> button = self . sender ( ) <EOL> if checked : <EOL> self . _toggleCheckedButtons ( button ) <EOL> item = self . _widgets . get ( button ) <EOL> if item is not None : <EOL> if checked : <EOL> self . _slideOut ( item ) <EOL> else : <EOL> self . _slideIn ( item ) <EOL> def _onSlideOutFinished ( self ) : <EOL> """<STR_LIT>""" <EOL> item = self . sender ( ) . targetObject ( ) <EOL> item . setAnimation ( None ) <EOL> container = item . widget ( ) <EOL> area = container . manager ( ) . dock_area ( ) <EOL> if area . dockEventsEnabled ( ) : <EOL> event = QDockItemEvent ( DockItemExtended , container . objectName ( ) ) <EOL> QApplication . postEvent ( area , event ) <EOL> def _onSlideInFinished ( self ) : <EOL> """<STR_LIT>""" <EOL> item = self . sender ( ) . targetObject ( ) <EOL> item . setAnimation ( None ) <EOL> item . hide ( ) <EOL> self . _untrackForResize ( item ) <EOL> container = item . widget ( ) <EOL> area = container . manager ( ) . dock_area ( ) <EOL> if area . dockEventsEnabled ( ) : <EOL> event = QDockItemEvent ( DockItemRetracted , container . objectName ( ) ) <EOL> QApplication . postEvent ( area , event ) <EOL> def _onButtonPressed ( self ) : <EOL> """<STR_LIT>""" <EOL> button = self . sender ( ) <EOL> container = self . _widgets [ button ] . widget ( ) <EOL> container . dockItem ( ) . clearAlert ( ) <EOL> def addContainer ( self , container , position , index = - <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> assert isinstance ( position , QDockBar . Position ) <EOL> self . removeContainer ( container ) <EOL> container . setPinned ( True , quiet = True ) <EOL> container . frame_state . in_dock_bar = True <EOL> button = QDockBarButton ( ) <EOL> button . setText ( container . title ( ) ) <EOL> button . setIcon ( container . icon ( ) ) <EOL> button . toggled . connect ( self . _onButtonToggled ) <EOL> button . pressed . connect ( self . _onButtonPressed ) <EOL> container . alerted . connect ( button . onAlerted ) <EOL> dock_bar = self . _getDockBar ( position ) <EOL> dock_bar . insertButton ( index , button ) <EOL> item = QDockBarItem ( self . parent ( ) . centralPane ( ) , position = position ) <EOL> item . hide ( ) <EOL> item . setWidget ( container ) <EOL> container . show ( ) <EOL> self . _widgets [ button ] = item <EOL> self . _widgets [ container ] = button <EOL> event = QEvent ( DockAreaContentsChanged ) <EOL> QApplication . sendEvent ( self . parent ( ) , event ) <EOL> def removeContainer ( self , container ) : <EOL> """<STR_LIT>""" <EOL> button = self . _widgets . pop ( container , None ) <EOL> if button is not None : <EOL> container . setParent ( None ) <EOL> container . setPinned ( False , quiet = True ) <EOL> container . frame_state . in_dock_bar = False <EOL> container . alerted . disconnect ( button . onAlerted ) <EOL> item = self . _widgets . pop ( button ) <EOL> item . setParent ( None ) <EOL> self . _untrackForResize ( item ) <EOL> dock_bar = self . _getDockBar ( button . position ( ) ) <EOL> button . toggled . disconnect ( self . _onButtonToggled ) <EOL> button . setParent ( None ) <EOL> if dock_bar . isEmpty ( ) : <EOL> self . _dock_bars [ dock_bar . position ( ) ] = None <EOL> dock_bar . setParent ( None ) <EOL> event = QEvent ( DockAreaContentsChanged ) <EOL> QApplication . sendEvent ( self . parent ( ) , event ) <EOL> def dockBarGeometry ( self , position ) : <EOL> """<STR_LIT>""" <EOL> bar = self . _getDockBar ( position , create = False ) <EOL> if bar is None : <EOL> return QRect ( ) <EOL> pos = bar . mapTo ( self . parent ( ) , QPoint ( <NUM_LIT:0> , <NUM_LIT:0> ) ) <EOL> return QRect ( pos , bar . size ( ) ) <EOL> def dockBarContainers ( self ) : <EOL> """<STR_LIT>""" <EOL> res = [ ] <EOL> for value in self . _widgets . itervalues ( ) : <EOL> if isinstance ( value , QDockBarItem ) : <EOL> res . append ( ( value . widget ( ) , value . position ( ) ) ) <EOL> return res <EOL> def dockBarPosition ( self , container ) : <EOL> """<STR_LIT>""" <EOL> button = self . _widgets . get ( container ) <EOL> if button is not None : <EOL> return button . position ( ) <EOL> def clearDockBars ( self ) : <EOL> """<STR_LIT>""" <EOL> for bar in self . _dock_bars : <EOL> if bar is not None : <EOL> bar . setParent ( None ) <EOL> self . _dock_bars = [ None , None , None , None ] <EOL> self . _active_items = { } <EOL> self . _widgets = { } <EOL> def isEmpty ( self ) : <EOL> """<STR_LIT>""" <EOL> return len ( self . _widgets ) == <NUM_LIT:0> <EOL> def extendContainer ( self , container ) : <EOL> """<STR_LIT>""" <EOL> button = self . _widgets . get ( container ) <EOL> if button is not None : <EOL> button . setChecked ( True ) <EOL> def retractContainer ( self , container ) : <EOL> """<STR_LIT>""" <EOL> button = self . _widgets . get ( container ) <EOL> if button is not None : <EOL> button . setChecked ( False ) <EOL> def eventFilter ( self , obj , event ) : <EOL> """<STR_LIT>""" <EOL> if event . type ( ) == QEvent . Resize : <EOL> active = self . _active_items <EOL> for item , slide_out in active . iteritems ( ) : <EOL> start , end = self . _animationGeo ( item ) <EOL> animation = item . animation ( ) <EOL> if slide_out : <EOL> if animation is None : <EOL> item . setGeometry ( end ) <EOL> else : <EOL> animation . pause ( ) <EOL> animation . setStartValue ( start ) <EOL> animation . setEndValue ( end ) <EOL> animation . resume ( ) <EOL> elif animation is not None : <EOL> animation . pause ( ) <EOL> animation . setStartValue ( end ) <EOL> animation . setEndValue ( start ) <EOL> animation . resume ( ) <EOL> return False </s>
