Exemplo n.º 1
0
def widget_popup_geometry(pos, widget):
    # type: (QPoint, QWidget) -> QRect
    widget.ensurePolished()

    if widget.testAttribute(Qt.WA_Resized):
        size = widget.size()
    else:
        size = widget.sizeHint()

    screen = QApplication.screenAt(pos)
    if screen is None:
        screen = QApplication.primaryScreen()
    screen_geom = screen.availableGeometry()
    size = size.boundedTo(screen_geom.size())
    geom = QRect(pos, size)

    if geom.top() < screen_geom.top():
        geom.moveTop(screen_geom.top())
    if geom.left() < screen_geom.left():
        geom.moveLeft(screen_geom.left())

    bottom_margin = screen_geom.bottom() - geom.bottom()
    right_margin = screen_geom.right() - geom.right()
    if bottom_margin < 0:
        # Falls over the bottom of the screen, move it up.
        geom.translate(0, bottom_margin)

    # TODO: right to left locale
    if right_margin < 0:
        # Falls over the right screen edge, move the menu to the
        # other side of pos.
        geom.translate(-size.width(), 0)

    return geom
Exemplo n.º 2
0
    def __setControlAreaVisible(self, visible):
        # type: (bool) -> None
        if self.__splitter is None or self.__splitter.count() < 2:
            return
        self.controlAreaVisible = visible
        splitter = self.__splitter  # type: QSplitter
        w = splitter.widget(0)
        # Set minimum width to 1 (overrides minimumSizeHint) when control area
        # is not visible to allow the main area to shrink further. Reset the
        # minimum width with a 0 if control area is visible.
        w.setMinimumWidth(int(not visible))

        sizes = splitter.sizes()
        current_size = sizes[0]
        if bool(current_size) == visible:
            return

        current_width = w.width()
        geom = self.geometry()
        frame = self.frameGeometry()
        framemargins = QMargins(
            frame.left() - geom.left(),
            frame.top() - geom.top(),
            frame.right() - geom.right(),
            frame.bottom() - geom.bottom()
        )
        splitter.setSizes([int(visible), QWIDGETSIZE_MAX])
        if not self.isWindow() or \
                self.windowState() not in [Qt.WindowNoState, Qt.WindowActive]:
            # not a window or not in state where we can move move/resize
            return

        # force immediate resize recalculation
        splitter.refresh()
        self.layout().invalidate()
        self.layout().activate()

        if visible:
            # move left and expand by the exposing widget's width
            diffx = -w.width()
            diffw = w.width()
        else:
            # move right and shrink by the collapsing width
            diffx = current_width
            diffw = -current_width
        newgeom = QRect(
            geom.x() + diffx, geom.y(), geom.width() + diffw, geom.height()
        )
        # bound/move by available geometry
        bounds = QApplication.desktop().availableGeometry(self)
        bounds = bounds.adjusted(
            framemargins.left(), framemargins.top(),
            -framemargins.right(), -framemargins.bottom()
        )
        newsize = newgeom.size().boundedTo(bounds.size())
        newgeom = QRect(newgeom.topLeft(), newsize)
        newgeom.moveLeft(max(newgeom.left(), bounds.left()))
        newgeom.moveRight(min(newgeom.right(), bounds.right()))
        self.setGeometry(newgeom)
Exemplo n.º 3
0
    def __setControlAreaVisible(self, visible):
        # type: (bool) -> None
        if self.__splitter is None or self.__splitter.count() < 2:
            return
        self.controlAreaVisible = visible
        splitter = self.__splitter  # type: QSplitter
        w = splitter.widget(0)
        # Set minimum width to 1 (overrides minimumSizeHint) when control area
        # is not visible to allow the main area to shrink further. Reset the
        # minimum width with a 0 if control area is visible.
        w.setMinimumWidth(int(not visible))

        sizes = splitter.sizes()
        current_size = sizes[0]
        if bool(current_size) == visible:
            return

        current_width = w.width()
        geom = self.geometry()
        frame = self.frameGeometry()
        framemargins = QMargins(
            frame.left() - geom.left(),
            frame.top() - geom.top(),
            frame.right() - geom.right(),
            frame.bottom() - geom.bottom()
        )
        splitter.setSizes([int(visible), QWIDGETSIZE_MAX])
        if not self.isWindow() or \
                self.windowState() not in [Qt.WindowNoState, Qt.WindowActive]:
            # not a window or not in state where we can move move/resize
            return

        # force immediate resize recalculation
        splitter.refresh()
        self.layout().invalidate()
        self.layout().activate()

        if visible:
            # move left and expand by the exposing widget's width
            diffx = -w.width()
            diffw = w.width()
        else:
            # move right and shrink by the collapsing width
            diffx = current_width
            diffw = -current_width
        newgeom = QRect(
            geom.x() + diffx, geom.y(), geom.width() + diffw, geom.height()
        )
        # bound/move by available geometry
        bounds = QApplication.desktop().availableGeometry(self)
        bounds = bounds.adjusted(
            framemargins.left(), framemargins.top(),
            -framemargins.right(), -framemargins.bottom()
        )
        newsize = newgeom.size().boundedTo(bounds.size())
        newgeom = QRect(newgeom.topLeft(), newsize)
        newgeom.moveLeft(max(newgeom.left(), bounds.left()))
        newgeom.moveRight(min(newgeom.right(), bounds.right()))
        self.setGeometry(newgeom)
Exemplo n.º 4
0
def dropdown_popup_geometry(geometry, origin, screen):
    # type: (QRect, QRect, QRect) -> QRect
    """
    Move/constrain the geometry for a drop down popup.

    Parameters
    ----------
    geometry : QRect
        The base popup geometry if not constrained.
    origin : QRect
        The origin rect from which the popup extends.
    screen : QRect
        The available screen geometry into which the popup must fit.

    Returns
    -------
    geometry: QRect
        Constrained drop down list geometry to fit into  screen
    """
    # if the popup  geometry extends bellow the screen and there is more room
    # above the popup origin ...
    geometry = QRect(geometry)
    geometry.moveTopLeft(origin.bottomLeft() + QPoint(0, 1))

    if geometry.bottom() > screen.bottom() \
            and origin.center().y() > screen.center().y():
        # ...flip the rect about the origin so it extends upwards
        geometry.moveBottom(origin.top() - 1)

    # fixup horizontal position if it extends outside the screen
    if geometry.left() < screen.left():
        geometry.moveLeft(screen.left())
    if geometry.right() > screen.right():
        geometry.moveRight(screen.right())

    # bounded by screen geometry
    return geometry.intersected(screen)
Exemplo n.º 5
0
def dropdown_popup_geometry(geometry, origin, screen):
    # type: (QRect, QRect, QRect) -> QRect
    """
    Move/constrain the geometry for a drop down popup.

    Parameters
    ----------
    geometry : QRect
        The base popup geometry if not constrained.
    origin : QRect
        The origin rect from which the popup extends.
    screen : QRect
        The available screen geometry into which the popup must fit.

    Returns
    -------
    geometry: QRect
        Constrained drop down list geometry to fit into  screen
    """
    # if the popup  geometry extends bellow the screen and there is more room
    # above the popup origin ...
    geometry = QRect(geometry)
    geometry.moveTopLeft(origin.bottomLeft() + QPoint(0, 1))

    if geometry.bottom() > screen.bottom() \
            and origin.center().y() > screen.center().y():
        # ...flip the rect about the origin so it extends upwards
        geometry.moveBottom(origin.top() - 1)

    # fixup horizontal position if it extends outside the screen
    if geometry.left() < screen.left():
        geometry.moveLeft(screen.left())
    if geometry.right() > screen.right():
        geometry.moveRight(screen.right())

    # bounded by screen geometry
    return geometry.intersected(screen)