Skip to content

Commit

Permalink
Merge pull request #25 from nucleic/window-snapping-2
Browse files Browse the repository at this point in the history
Window snapping 2
  • Loading branch information
sccolbert committed May 29, 2013
2 parents 52a9ed6 + 3a31646 commit de3ced3
Show file tree
Hide file tree
Showing 10 changed files with 633 additions and 199 deletions.
417 changes: 282 additions & 135 deletions enaml/qt/docking/dock_manager.py

Large diffs are not rendered by default.

77 changes: 63 additions & 14 deletions enaml/qt/docking/q_bitmap_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,35 +89,79 @@ def styleOption(self):
opt.state |= QStyle.State_Sunken
return opt

def drawBitmap(self, opt, painter):
def drawBitmap(self, bmp, opt, painter):
""" Draw the bitmap for the button.
The bitmap will be drawn with the foreground color set by
the style sheet and the style option.
Parameters
----------
bmp : QBitmap
The bitmap to draw.
opt : QStyleOption
The style option to use for drawing.
painter : QPainter
The painter to use for drawing.
"""
# hack to get the current stylesheet foreground color
hint = QStyle.SH_GroupBox_TextLabelColor
fg = self.style().styleHint(hint, opt, self)
# mask signed to unsigned which 'fromRgba' requires
painter.setPen(QColor.fromRgba(0xffffffff & fg))
size = self.size()
im_size = bmp.size()
x = size.width() / 2 - im_size.width() / 2
y = size.height() / 2 - im_size.height() / 2
source = QRect(QPoint(0, 0), im_size)
dest = QRect(QPoint(x, y), im_size)
painter.drawPixmap(dest, bmp, source)

def paintEvent(self, event):
""" Handle the paint event for the button.
"""
painter = QPainter(self)
opt = self.styleOption()
self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self)
bmp = self._bitmap
if bmp is not None:
# hack to get the current stylesheet foreground color
hint = QStyle.SH_GroupBox_TextLabelColor
fg = self.style().styleHint(hint, opt, self)
# mask signed to unsigned which 'fromRgba' requires
painter.setPen(QColor.fromRgba(0xffffffff & fg))
size = self.size()
im_size = bmp.size()
x = size.width() / 2 - im_size.width() / 2
y = size.height() / 2 - im_size.height() / 2
source = QRect(QPoint(0, 0), im_size)
dest = QRect(QPoint(x, y), im_size)
painter.drawPixmap(dest, bmp, source)
self.drawBitmap(bmp, opt, painter)


class QCheckedBitmapButton(QBitmapButton):
""" A bitmap button subclass which supports a checked bitmap.
"""
_checked_bitmap = None

def __init__(self, parent=None):
""" Initialize a QCheckedBitmapButton.
Parameters
----------
parent : QWidget or None
The parent widget of the button.
"""
super(QCheckedBitmapButton, self).__init__(parent)
self.setCheckable(True)

def checkedBitmap(self):
""" Get the bitmap associated with the button checked state.
"""
return self._checked_bitmap

def setCheckedBitmap(self, bitmap):
""" Set the bitmap associate with the button checked state.
"""
self._checked_bitmap = bitmap
self.update()

def paintEvent(self, event):
""" Handle the paint event for the button.
Expand All @@ -126,4 +170,9 @@ def paintEvent(self, event):
painter = QPainter(self)
opt = self.styleOption()
self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self)
self.drawBitmap(opt, painter)
if self.isChecked():
bmp = self._checked_bitmap or self._bitmap
else:
bmp = self._bitmap
if bmp is not None:
self.drawBitmap(bmp, opt, painter)
71 changes: 61 additions & 10 deletions enaml/qt/docking/q_dock_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,17 @@ def showMaximized(self):
""" Handle the show maximized request for the dock container.
"""
def update_buttons(bar):
def update_buttons(bar, link=False):
buttons = bar.buttons()
buttons |= bar.RestoreButton
buttons &= ~bar.MaximizeButton
if link:
buttons &= ~bar.LinkButton
bar.setButtons(buttons)
if self.isWindow():
super(QDockContainer, self).showMaximized()
update_buttons(self.dockItem().titleBarWidget())
self.setLinked(False)
update_buttons(self.dockItem().titleBarWidget(), link=True)
else:
area = self.parentDockArea()
if area is not None:
Expand All @@ -154,14 +157,17 @@ def showNormal(self):
""" Handle the show normal request for the dock container.
"""
def update_buttons(bar):
def update_buttons(bar, link=False):
buttons = bar.buttons()
buttons |= bar.MaximizeButton
buttons &= ~bar.RestoreButton
if link:
buttons |= bar.LinkButton
bar.setButtons(buttons)
if self.isWindow():
super(QDockContainer, self).showNormal()
update_buttons(self.dockItem().titleBarWidget())
self.setLinked(False)
update_buttons(self.dockItem().titleBarWidget(), link=True)
elif self.frame_state.item_is_maximized:
item = self.dockItem()
update_buttons(item.titleBarWidget())
Expand Down Expand Up @@ -238,6 +244,27 @@ def closable(self):
return item.closable()
return True

def isLinked(self):
""" Get whether or not the container is linked.
This proxies the call to the underlying dock item.
"""
item = self.dockItem()
if item is not None:
return item.isLinked()
return False

def setLinked(self, linked):
""" Set whether or not the container should be linked.
This proxies the call to the underlying dock item.
"""
item = self.dockItem()
if item is not None:
item.setLinked(linked)

def showTitleBar(self):
""" Show the title bar for the container.
Expand All @@ -258,6 +285,24 @@ def hideTitleBar(self):
if item is not None:
item.titleBarWidget().hide()

def showLinkButton(self):
""" Show the link button on the title bar.
"""
item = self.dockItem()
if item is not None:
bar = item.titleBarWidget()
bar.setButtons(bar.buttons() | bar.LinkButton)

def hideLinkButton(self):
""" Show the link button on the title bar.
"""
item = self.dockItem()
if item is not None:
bar = item.titleBarWidget()
bar.setButtons(bar.buttons() & ~bar.LinkButton)

def reset(self):
""" Reset the container to the initial pre-docked state.
Expand All @@ -267,6 +312,8 @@ def reset(self):
state.press_pos = None
self.showNormal()
self.unfloat()
self.hideLinkButton()
self.setLinked(False)
self.showTitleBar()
self.setAttribute(Qt.WA_WState_ExplicitShowHide, False)
self.setAttribute(Qt.WA_WState_Hidden, False)
Expand All @@ -278,9 +325,11 @@ def float(self):
self.hide()
self.setAttribute(Qt.WA_Hover, True)
flags = Qt.Tool | Qt.FramelessWindowHint
self.setParent(self.manager().dock_area, flags)
self.setParent(self.manager().dock_area(), flags)
self.layout().setContentsMargins(QMargins(5, 5, 5, 5))
self.setProperty('floating', True)
self.setLinked(False)
self.showLinkButton()
repolish(self)

def unfloat(self):
Expand All @@ -290,10 +339,12 @@ def unfloat(self):
self.hide()
self.setAttribute(Qt.WA_Hover, False)
flags = Qt.Widget
self.setParent(self.manager().dock_area, flags)
self.setParent(self.manager().dock_area(), flags)
self.layout().setContentsMargins(QMargins(0, 0, 0, 0))
self.unsetCursor()
self.setProperty('floating', False)
self.setLinked(False)
self.hideLinkButton()
repolish(self)

def parentDockArea(self):
Expand Down Expand Up @@ -436,7 +487,7 @@ def closeEvent(self, event):
""" Handle the close event for the dock container.
"""
self.manager()._close_container(self, event)
self.manager().close_container(self, event)

def titleBarMousePressEvent(self, event):
""" Handle a mouse press event on the title bar.
Expand Down Expand Up @@ -473,8 +524,8 @@ def titleBarMouseMoveEvent(self, event):
global_pos = event.globalPos()
if state.dragging:
if self.isWindow():
self.move(global_pos - state.press_pos)
self.manager()._frame_moved(self, global_pos)
target_pos = global_pos - state.press_pos
self.manager().drag_move_frame(self, target_pos, global_pos)
return True

# Ensure the drag has crossed the app drag threshold.
Expand Down Expand Up @@ -531,7 +582,7 @@ def titleBarMouseReleaseEvent(self, event):
if state.press_pos is not None:
self.releaseMouse()
if self.isWindow():
self.manager()._frame_released(self, event.globalPos())
self.manager().drag_release_frame(self, event.globalPos())
state.dragging = False
state.press_pos = None
return True
Expand Down
4 changes: 1 addition & 3 deletions enaml/qt/docking/q_dock_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,7 @@ def raiseFrame(self):
"""
manager = self._manager
if manager is not None:
frames = manager.dock_frames
frames.remove(self)
frames.append(self)
manager.raise_frame(self)

def titleBarGeometry(self):
""" Get the geometry rect for the title bar.
Expand Down
22 changes: 22 additions & 0 deletions enaml/qt/docking/q_dock_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,28 @@ def setIconSize(self, size):
"""
self.titleBarWidget().setIconSize(size)

def isLinked(self):
""" Get whether or not this dock item is linked.
Returns
-------
result : bool
True if the item is linked, False otherwise.
"""
return self.titleBarWidget().isLinked()

def setLinked(self, linked):
""" Set whether or not the dock item is linked.
Parameters
----------
linked : bool
True if the dock item should be linked, False otherwise.
"""
self.titleBarWidget().setLinked(linked)

def closable(self):
""" Get whether or not the dock item is closable.
Expand Down
2 changes: 1 addition & 1 deletion enaml/qt/docking/q_dock_tab_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def tabInserted(self, index):
"""
button = QDockTabCloseButton(self)
button.setObjectName("docktab-close-button")
button.setObjectName('docktab-close-button')
button.setBitmap(CLOSE_BUTTON.toBitmap())
button.setIconSize(QSize(14, 13))
button.clicked.connect(self._onCloseButtonClicked)
Expand Down
Loading

0 comments on commit de3ced3

Please sign in to comment.