Source code for schrodinger.ui.qt.standard_widgets.hyperlink

from schrodinger.Qt import QtWidgets, QtGui, QtCore
from schrodinger.Qt.QtCore import Qt
from schrodinger.ui.qt.appframework2 import application
from schrodinger.ui.qt import utils
from schrodinger.ui.qt.standard.colors import LightModeColors
from schrodinger.ui.qt.standard.colors import DarkModeColors

from schrodinger.ui.qt.standard_widgets import standard_widgets_rc
LIGHT_MODE_PROP = "light_mode"


class _BaseLink(QtWidgets.QPushButton):
    """
    The _BaseLink is the base class for all public link classes. These links
    all share some common styling such as font color, size, and pointer cursor.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setStyleSheet(STYLE_SHEET)
        self.setCursor(Qt.PointingHandCursor)
        self.setProperty(LIGHT_MODE_PROP, True)

    def setLightMode(self, enabled):
        self.setProperty(LIGHT_MODE_PROP, enabled)
        utils.update_widget_style(self)


class SimpleLink(_BaseLink):
    """
    The simple link has no distinctions from the _BaseLink, and has no
    differences in styling.
    """
    pass


class ButtonWithArrowMixin:

    def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
        """
        This function does the same thing as the C++ code except it forces
        the menu indicator to be drawn.
        """
        painter = QtWidgets.QStylePainter(self)
        opt = QtWidgets.QStyleOptionButton()
        self.initStyleOption(opt)
        # Always paint "menu indicator"
        opt.features |= QtWidgets.QStyleOptionButton.HasMenu
        painter.drawControl(QtWidgets.QStyle.CE_PushButton, opt)

    def sizeHint(self) -> QtCore.QSize:
        """
        Give the button extra space to make room for menu indicator.
        QPushButton only gives space for menu indicator when menu() returns
        an actual menu, which the ToggleLink will not.
        """
        sh: QtCore.QSize = super().sizeHint()
        sh.setWidth(sh.width() + 20)
        return sh


class ToggleLink(ButtonWithArrowMixin, _BaseLink):
    """
    A toggle link supports two states: on and off. It uses the different
    check states of a QPushButton to style the link differently. Most
    importantly, there is a chevron icon to the right of the link that points
    down when the link is unchecked and that points up when the link is checked.
    Often used to expand an area below the link.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setCheckable(True)


class MenuLink(_BaseLink):
    """
    The menu link is designed to support a menu. The only difference between
    this link and the `_BaseLink` is styling. The styling differences are
    only applied when a menu is set to the button. When there is a menu,
    it has a unique pressed state that highlights the link and custom menu
    indicators.
    """
    pass


class ArrowLink(ButtonWithArrowMixin, MenuLink):
    """
    Link button with arrow at right hand side.
    """
    pass


STYLE_SHEET = f"""
_BaseLink {{
    font-weight: 600;
    background-color: transparent;
    border: 1px solid transparent;
}}
_BaseLink[light_mode="true"] {{
    color: {LightModeColors.LINK};
}}
_BaseLink[light_mode="false"] {{
    color: {DarkModeColors.LINK};
}}
_BaseLink:hover[light_mode="true"] {{
    color: {LightModeColors.LINK_HOVERED};
}}
_BaseLink:hover[light_mode="false"] {{
    color: {DarkModeColors.LINK_HOVERED};
}}
_BaseLink:disabled[light_mode="true"] {{
    color: {LightModeColors.LINK_DISABLED};
}}
_BaseLink:disabled[light_mode="false"] {{
    color: {DarkModeColors.LINK_DISABLED};
}}


/* TOGGLE LINK */

ToggleLink::menu-indicator {{
    subcontrol-position: center right;
    top: 1px;
    height: 12px;
    width: 12px;
}}

/* unchecked -> chevron down */
ToggleLink::menu-indicator[light_mode="true"] {{
    image: url(":/standard_widgets/icons/chevron_down.png");
}}
ToggleLink::menu-indicator[light_mode="false"] {{
    image: url(":/standard_widgets/icons/chevron_down_b.png") ;
}}
ToggleLink::menu-indicator[light_mode="true"]:disabled {{
    image: url(":/standard_widgets/icons/chevron_down_d.png");
}}
ToggleLink::menu-indicator[light_mode="false"]:disabled {{
    image: url(":/standard_widgets/icons/chevron_down_db.png");
}}

/* checked -> chevron up */
ToggleLink::menu-indicator[light_mode="true"]:checked {{
    image: url(":/standard_widgets/icons/chevron_up.png");
}}
ToggleLink::menu-indicator[light_mode="false"]:checked {{
    image: url(":/standard_widgets/icons/chevron_up_b.png") ;
}}
ToggleLink::menu-indicator[light_mode="true"]:disabled:checked {{
    image: url(":/standard_widgets/icons/chevron_up_d.png");
}}
ToggleLink::menu-indicator[light_mode="false"]:disabled:checked {{
    image: url(":/standard_widgets/icons/chevron_up_db.png");
}}


/* MENU LINK */

MenuLink {{
    padding: 3px 4px 3px 4px;
}}
MenuLink::menu-indicator {{
    image: url(":/standard_widgets/icons/menu_caret.png");
    subcontrol-position: center right;
    top: 1px;
    left: -3px;
    height: 11px;
    width: 11px;
}}
/* the arrow looked smaller in dark mode, so we should make icon bigger */
MenuLink::menu-indicator[light_mode="false"] {{
    height: 12px;
    width: 12px;
}}
MenuLink::menu-indicator[light_mode="true"]:disabled {{
    image: url(":/standard_widgets/icons/menu_caret_d.png");
}}
MenuLink::menu-indicator[light_mode="false"]:disabled {{
    image: url(":/standard_widgets/icons/menu_caret_db.png");
}}
MenuLink:pressed {{
    border: 1px solid #2e9cdc;
    background-color: #102e9cdc
}}
MenuLink[light_mode="true"]:pressed {{
    color: {LightModeColors.LINK_PRESSED};
}}
MenuLink[light_mode="false"]:pressed {{
    color: {DarkModeColors.LINK_PRESSED};
}}
"""