vibefpmgui.widgets

Small widgets shared by the window's parts.

  1"""Small widgets shared by the window's parts."""
  2
  3from qtpy.QtCore import QSize, Qt, Signal
  4from qtpy.QtWidgets import QDialog, QLabel, QLineEdit, QMenu, QPushButton, QSizePolicy
  5
  6
  7class StatusLabel(QLabel):
  8    """A label for a line of status whose text keeps changing (an editor's
  9    status line, a panel's progress): it asks for its text's width when
 10    there's room, but needs only a little. A plain label's minimum width is
 11    its whole text, so a longer status ("154 AI review notes", "… · context
 12    ~14k of 32k") made the window wider, past the screen's edge for a window
 13    filling it. When narrow, the text is cut off at the right."""
 14
 15    MINIMUM_WIDTH = 40
 16
 17    def minimumSizeHint(self) -> QSize:
 18        hint = super().minimumSizeHint()
 19        return QSize(min(hint.width(), self.MINIMUM_WIDTH), hint.height())
 20
 21
 22class HistoryLineEdit(QLineEdit):
 23    """A field for commands, as a shell's: Enter sends its text
 24    (``submitted``), remembers it, and clears the field; Up and Down go
 25    through what was sent (Down past the last one: what was being typed).
 26    The history is this field's own, for as long as it lives (not saved)."""
 27
 28    submitted = Signal(str)
 29
 30    def __init__(self, parent=None):
 31        super().__init__(parent)
 32        self.history: list[str] = []
 33        self._index = 0  # (in history; len(history): the text being typed, not sent yet)
 34        self._draft = ""
 35        self.returnPressed.connect(self._submit)
 36
 37    def _submit(self):
 38        text = self.text().strip()
 39        if not text:
 40            return
 41        if not self.history or self.history[-1] != text:  # (the same twice in a row: kept once)
 42            self.history.append(text)
 43        self._index, self._draft = len(self.history), ""
 44        self.clear()
 45        self.submitted.emit(text)
 46
 47    def keyPressEvent(self, event):
 48        key = event.key()
 49        if key == Qt.Key_Up and self._index > 0:
 50            if self._index == len(self.history):
 51                self._draft = self.text()
 52            self._index -= 1
 53            self.setText(self.history[self._index])
 54        elif key == Qt.Key_Down and self._index < len(self.history):
 55            self._index += 1
 56            self.setText(self._draft if self._index == len(self.history) else self.history[self._index])
 57        elif key in (Qt.Key_Up, Qt.Key_Down):
 58            pass  # (no earlier, or later, entry)
 59        else:
 60            super().keyPressEvent(event)
 61
 62
 63def run_dialog(dialog: QDialog) -> int:
 64    """Show a dialog until it's closed, then let it go (a dialog that's a
 65    child of the window would otherwise stay, hidden, until the app quits)."""
 66    try:
 67        return dialog.exec()
 68    finally:
 69        dialog.deleteLater()
 70
 71
 72class StayOpenMenu(QMenu):
 73    """A menu that stays open when a checkable item is clicked (to tick several)."""
 74
 75    def mouseReleaseEvent(self, event):
 76        action = self.activeAction()
 77        if action is not None and action.isCheckable() and action.isEnabled():
 78            action.trigger()
 79            return
 80        super().mouseReleaseEvent(event)
 81
 82
 83class MenuButton(QPushButton):
 84    """A button that opens a menu, its text cut short with "…" to fit (it
 85    doesn't make the panel it's in wider); the whole text is its tooltip."""
 86
 87    def __init__(self, parent=None):
 88        super().__init__(parent)
 89        self._full_text = ""
 90        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
 91
 92    def set_full_text(self, text: str):
 93        self._full_text = text
 94        self._elide()
 95
 96    def full_text(self) -> str:
 97        return self._full_text
 98
 99    def minimumSizeHint(self):
100        hint = super().minimumSizeHint()
101        return QSize(60, hint.height())
102
103    def sizeHint(self):
104        hint = super().sizeHint()
105        return QSize(60, hint.height())
106
107    def resizeEvent(self, event):
108        super().resizeEvent(event)
109        self._elide()
110
111    def _elide(self):
112        room = max(10, self.width() - 40)  # (the menu arrow and the margins)
113        self.setText(self.fontMetrics().elidedText(self._full_text, Qt.ElideRight, room))
class StatusLabel(PySide6.QtWidgets.QLabel):
 8class StatusLabel(QLabel):
 9    """A label for a line of status whose text keeps changing (an editor's
10    status line, a panel's progress): it asks for its text's width when
11    there's room, but needs only a little. A plain label's minimum width is
12    its whole text, so a longer status ("154 AI review notes", "… · context
13    ~14k of 32k") made the window wider, past the screen's edge for a window
14    filling it. When narrow, the text is cut off at the right."""
15
16    MINIMUM_WIDTH = 40
17
18    def minimumSizeHint(self) -> QSize:
19        hint = super().minimumSizeHint()
20        return QSize(min(hint.width(), self.MINIMUM_WIDTH), hint.height())

A label for a line of status whose text keeps changing (an editor's status line, a panel's progress): it asks for its text's width when there's room, but needs only a little. A plain label's minimum width is its whole text, so a longer status ("154 AI review notes", "… · context ~14k of 32k") made the window wider, past the screen's edge for a window filling it. When narrow, the text is cut off at the right.

MINIMUM_WIDTH = 40
def minimumSizeHint(self) -> PySide6.QtCore.QSize:
18    def minimumSizeHint(self) -> QSize:
19        hint = super().minimumSizeHint()
20        return QSize(min(hint.width(), self.MINIMUM_WIDTH), hint.height())

minimumSizeHint(self, /) -> PySide6.QtCore.QSize

staticMetaObject = PySide6.QtCore.QMetaObject("StatusLabel" inherits "QLabel": )
class HistoryLineEdit(PySide6.QtWidgets.QLineEdit):
23class HistoryLineEdit(QLineEdit):
24    """A field for commands, as a shell's: Enter sends its text
25    (``submitted``), remembers it, and clears the field; Up and Down go
26    through what was sent (Down past the last one: what was being typed).
27    The history is this field's own, for as long as it lives (not saved)."""
28
29    submitted = Signal(str)
30
31    def __init__(self, parent=None):
32        super().__init__(parent)
33        self.history: list[str] = []
34        self._index = 0  # (in history; len(history): the text being typed, not sent yet)
35        self._draft = ""
36        self.returnPressed.connect(self._submit)
37
38    def _submit(self):
39        text = self.text().strip()
40        if not text:
41            return
42        if not self.history or self.history[-1] != text:  # (the same twice in a row: kept once)
43            self.history.append(text)
44        self._index, self._draft = len(self.history), ""
45        self.clear()
46        self.submitted.emit(text)
47
48    def keyPressEvent(self, event):
49        key = event.key()
50        if key == Qt.Key_Up and self._index > 0:
51            if self._index == len(self.history):
52                self._draft = self.text()
53            self._index -= 1
54            self.setText(self.history[self._index])
55        elif key == Qt.Key_Down and self._index < len(self.history):
56            self._index += 1
57            self.setText(self._draft if self._index == len(self.history) else self.history[self._index])
58        elif key in (Qt.Key_Up, Qt.Key_Down):
59            pass  # (no earlier, or later, entry)
60        else:
61            super().keyPressEvent(event)

A field for commands, as a shell's: Enter sends its text (submitted), remembers it, and clears the field; Up and Down go through what was sent (Down past the last one: what was being typed). The history is this field's own, for as long as it lives (not saved).

HistoryLineEdit(parent=None)
31    def __init__(self, parent=None):
32        super().__init__(parent)
33        self.history: list[str] = []
34        self._index = 0  # (in history; len(history): the text being typed, not sent yet)
35        self._draft = ""
36        self.returnPressed.connect(self._submit)

__init__(self, arg__1: str, /, parent: PySide6.QtWidgets.QWidget | None = None, *, inputMask: str | None = None, text: str | None = None, maxLength: int | None = None, frame: bool | None = None, echoMode: PySide6.QtWidgets.QLineEdit.EchoMode | None = None, displayText: str | None = None, cursorPosition: int | None = None, alignment: PySide6.QtCore.Qt.AlignmentFlag | None = None, modified: bool | None = None, hasSelectedText: bool | None = None, selectedText: str | None = None, dragEnabled: bool | None = None, readOnly: bool | None = None, undoAvailable: bool | None = None, redoAvailable: bool | None = None, acceptableInput: bool | None = None, placeholderText: str | None = None, cursorMoveStyle: PySide6.QtCore.Qt.CursorMoveStyle | None = None, clearButtonEnabled: bool | None = None) -> None __init__(self, /, parent: PySide6.QtWidgets.QWidget | None = None, *, inputMask: str | None = None, text: str | None = None, maxLength: int | None = None, frame: bool | None = None, echoMode: PySide6.QtWidgets.QLineEdit.EchoMode | None = None, displayText: str | None = None, cursorPosition: int | None = None, alignment: PySide6.QtCore.Qt.AlignmentFlag | None = None, modified: bool | None = None, hasSelectedText: bool | None = None, selectedText: str | None = None, dragEnabled: bool | None = None, readOnly: bool | None = None, undoAvailable: bool | None = None, redoAvailable: bool | None = None, acceptableInput: bool | None = None, placeholderText: str | None = None, cursorMoveStyle: PySide6.QtCore.Qt.CursorMoveStyle | None = None, clearButtonEnabled: bool | None = None) -> None

Initialize self. See help(type(self)) for accurate signature.

def submitted(unknown):

The type of the None singleton.

history: list[str]
def keyPressEvent(self, event):
48    def keyPressEvent(self, event):
49        key = event.key()
50        if key == Qt.Key_Up and self._index > 0:
51            if self._index == len(self.history):
52                self._draft = self.text()
53            self._index -= 1
54            self.setText(self.history[self._index])
55        elif key == Qt.Key_Down and self._index < len(self.history):
56            self._index += 1
57            self.setText(self._draft if self._index == len(self.history) else self.history[self._index])
58        elif key in (Qt.Key_Up, Qt.Key_Down):
59            pass  # (no earlier, or later, entry)
60        else:
61            super().keyPressEvent(event)

keyPressEvent(self, arg__1: PySide6.QtGui.QKeyEvent, /) -> None

staticMetaObject = PySide6.QtCore.QMetaObject("HistoryLineEdit" inherits "QLineEdit": Methods: #49 type=Signal, signature=submitted(QString), parameters=QString )
def run_dialog(dialog: PySide6.QtWidgets.QDialog) -> int:
64def run_dialog(dialog: QDialog) -> int:
65    """Show a dialog until it's closed, then let it go (a dialog that's a
66    child of the window would otherwise stay, hidden, until the app quits)."""
67    try:
68        return dialog.exec()
69    finally:
70        dialog.deleteLater()

Show a dialog until it's closed, then let it go (a dialog that's a child of the window would otherwise stay, hidden, until the app quits).

class StayOpenMenu(PySide6.QtWidgets.QMenu):
73class StayOpenMenu(QMenu):
74    """A menu that stays open when a checkable item is clicked (to tick several)."""
75
76    def mouseReleaseEvent(self, event):
77        action = self.activeAction()
78        if action is not None and action.isCheckable() and action.isEnabled():
79            action.trigger()
80            return
81        super().mouseReleaseEvent(event)

A menu that stays open when a checkable item is clicked (to tick several).

def mouseReleaseEvent(self, event):
76    def mouseReleaseEvent(self, event):
77        action = self.activeAction()
78        if action is not None and action.isCheckable() and action.isEnabled():
79            action.trigger()
80            return
81        super().mouseReleaseEvent(event)

mouseReleaseEvent(self, arg__1: PySide6.QtGui.QMouseEvent, /) -> None

staticMetaObject = PySide6.QtCore.QMetaObject("StayOpenMenu" inherits "QMenu": )