Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions BlocksScreen/lib/panels/mainWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,15 +547,13 @@ def _handle_notify_service_state_changed_message(
"""Handle websocket service messages"""
entry = data.get("params")
if entry:
if not self._popup_toggle:
if self._popup_toggle:
return
service_entry: dict = entry[0]
service_name, service_info = service_entry.popitem()
self.popup.new_message(
message_type=Popup.MessageType.INFO,
message=f"""{service_name} service changed state to
{service_info.get("sub_state")}
""",
message=f"{service_name} service changed state to \n{service_info.get('sub_state')}",
)

@api_handler
Expand All @@ -564,15 +562,17 @@ def _handle_notify_gcode_response_message(self, method, data, metadata) -> None:
_gcode_response = data.get("params")
self.gcode_response[list].emit(_gcode_response)
if _gcode_response:
if not self._popup_toggle:
if self._popup_toggle:
return
_gcode_msg_type, _message = str(_gcode_response[0]).split(" ", maxsplit=1)
_msg_type = Popup.MessageType.UNKNOWN
if _gcode_msg_type == "!!":
popupWhitelist = ["filament runout", "no filament"]
if _message.lower() in popupWhitelist or _gcode_msg_type == "!!":
_msg_type = Popup.MessageType.ERROR
elif _gcode_msg_type == "//":
_msg_type = Popup.MessageType.INFO
self.popup.new_message(message_type=_msg_type, message=str(_message))
self.popup.new_message(
message_type=_msg_type,
message=str(_message),
userInput=True,
)

@api_handler
def _handle_error_message(self, method, data, metadata) -> None:
Expand All @@ -581,17 +581,24 @@ def _handle_error_message(self, method, data, metadata) -> None:
if "metadata" in data.get("message", "").lower():
# Quick fix, don't care about no metadata errors
return
if not self._popup_toggle:
if self._popup_toggle:
return
text = data
if isinstance(data, dict):
if "message" in data:
text = f"{data['message']}"
else:
text = data
self.popup.new_message(
message_type=Popup.MessageType.ERROR,
message=str(data),
message=str(text),
userInput=True,
)

@api_handler
def _handle_notify_cpu_throttled_message(self, method, data, metadata) -> None:
"""Handle websocket cpu throttled messages"""
if not self._popup_toggle:
if self._popup_toggle:
return
self.popup.new_message(
message_type=Popup.MessageType.WARNING,
Expand Down
89 changes: 64 additions & 25 deletions BlocksScreen/lib/panels/widgets/popupDialogWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
from collections import deque
from typing import Deque
from PyQt6 import QtCore, QtGui, QtWidgets


BASE_POPUP_TIMEOUT = 6000
from lib.utils.icon_button import IconButton


class Popup(QtWidgets.QDialog):
Expand All @@ -25,9 +23,10 @@ class ColorCode(enum.Enum):

def __init__(self, parent) -> None:
super().__init__(parent)
self.popup_timeout = BASE_POPUP_TIMEOUT
self.timeout_timer = QtCore.QTimer(self)
self.timeout_timer.setSingleShot(True)
self.messages: Deque = deque()
self.isShown = False
self.persistent_notifications: Deque = deque()
self.message_type: Popup.MessageType = Popup.MessageType.INFO
self.default_background_color = QtGui.QColor(164, 164, 164)
Expand All @@ -48,20 +47,32 @@ def __init__(self, parent) -> None:
self.slide_out_animation = QtCore.QPropertyAnimation(self, b"geometry")
self.slide_out_animation.setDuration(200)
self.slide_out_animation.setEasingCurve(QtCore.QEasingCurve.Type.InCubic)
self.slide_in_animation.finished.connect(self.on_slide_in_finished)

self.SingleTime = QtCore.QTimer(self)
self.SingleTime.setInterval(5000)
self.SingleTime.setSingleShot(True)
self.SingleTime.timeout.connect(self._add_popup)

self.slide_out_animation.finished.connect(self.on_slide_out_finished)
self.timeout_timer.timeout.connect(self.slide_out_animation.start)
self.slide_in_animation.finished.connect(self.on_slide_in_finished)
self.timeout_timer.timeout.connect(lambda: self.slide_out_animation.start())
self.actionbtn.clicked.connect(self.slide_out_animation.start)

def on_slide_in_finished(self):
"""Handle slide in animation finished"""
if self.userInput:
return
self.timeout_timer.start()

def on_slide_out_finished(self):
"""Handle slide out animation finished"""
self.close()
self.hide()
self.isShown = False
self.timeout_timer.stop()
self._add_popup()

def _calculate_target_geometry(self) -> QtCore.QRect:
"""Calculate on end posisition rect for popup"""
app_instance = QtWidgets.QApplication.instance()
main_window = app_instance.activeWindow() if app_instance else None
if main_window is None and app_instance:
Expand Down Expand Up @@ -89,38 +100,49 @@ def updateMask(self) -> None:

def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:
"""Re-implemented method, handle mouse press events"""
if self.userInput:
return
self.timeout_timer.stop()
self.slide_out_animation.setStartValue(self.slide_in_animation.currentValue())
self.slide_in_animation.stop()
self.slide_out_animation.start()

def set_timeout(self, value: int) -> None:
"""Set popup timeout"""
if not isinstance(value, int):
raise ValueError("Expected type int ")
self.popup_timeout = value

def new_message(
self,
message_type: MessageType = MessageType.INFO,
message: str = "",
timeout: int = 0,
timeout: int = 6000,
userInput: bool = False,
):
"""Create new popup message

Args:
message_type (MessageType, optional): Message Level, See `MessageType` Types. Defaults to MessageType.INFO.
message (str, optional): The message. Defaults to "".
timeout (int, optional): How long the message stays for, in milliseconds. Defaults to 0.
userInput (bool,optional): If the user is required to click to make the popup disappear. Defaults to False.

Returns:
_type_: _description_
"""
self.messages.append(
{"message": message, "type": message_type, "timeout": timeout}
{
"message": message,
"type": message_type,
"timeout": timeout,
"userInput": userInput,
}
)
return self._add_popup()

def _add_popup(self) -> None:
"""Add popup to queue"""
if self.isShown:
if self.SingleTime.isActive():
return
self.SingleTime.start()
return

if (
self.messages
and self.slide_in_animation.state()
Expand All @@ -131,27 +153,45 @@ def _add_popup(self) -> None:
message_entry = self.messages.popleft()
self.message_type = message_entry.get("type")
message = message_entry.get("message")
timeout = message_entry.get("timeout")
self.timeout_timer.setInterval(timeout)
if message == self.text_label.text():
self.messages = deque(
m for m in self.messages if m.get("message") != message
)
return
self.userInput = message_entry.get("userInput")

self.text_label.setText(message)

match self.message_type:
case Popup.MessageType.INFO:
self.icon_label.setPixmap(self.info_icon)
case Popup.MessageType.WARNING:
self.icon_label.setPixmap(self.warning_icon)
case Popup.MessageType.ERROR:
self.icon_label.setPixmap(self.error_icon)
self.timeout_timer.setInterval(self.popup_timeout)

end_rect = self._calculate_target_geometry()
start_rect = end_rect.translated(0, -end_rect.height())
start_rect = end_rect.translated(0, -end_rect.height() * 2)

self.slide_in_animation.setStartValue(start_rect)
self.slide_in_animation.setEndValue(end_rect)
self.slide_out_animation.setStartValue(end_rect)
self.slide_out_animation.setEndValue(start_rect)
self.setGeometry(start_rect)
self.open()
if not self.userInput:
self.actionbtn.clearPixmap()
else:
self.actionbtn.setPixmap(
QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg")
)
self.setGeometry(end_rect)
self.show()

def showEvent(self, a0: QtGui.QShowEvent) -> None:
"""Re-implementation, widget show"""
self.slide_in_animation.start()
self.isShown = True
super().showEvent(a0)

def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
Expand Down Expand Up @@ -183,8 +223,7 @@ def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
painter.drawRoundedRect(self.rect(), 10, 10)

def _setupUI(self) -> None:
self.vertical_layout = QtWidgets.QVBoxLayout(self)
self.horizontal_layout = QtWidgets.QHBoxLayout()
self.horizontal_layout = QtWidgets.QHBoxLayout(self)
self.horizontal_layout.setContentsMargins(5, 5, 5, 5)

self.icon_label = QtWidgets.QLabel(self)
Expand All @@ -210,8 +249,8 @@ def _setupUI(self) -> None:
self.text_label.setFont(font)

self.spacer = QtWidgets.QSpacerItem(60, 60)
self.actionbtn = IconButton(self)
self.actionbtn.setMaximumSize(QtCore.QSize(60, 60))

self.horizontal_layout.addWidget(self.text_label, 1)
self.horizontal_layout.addItem(self.spacer)

self.vertical_layout.addLayout(self.horizontal_layout)
self.horizontal_layout.addWidget(self.text_label)
self.horizontal_layout.addWidget(self.actionbtn)
4 changes: 2 additions & 2 deletions BlocksScreen/lib/ui/resources/icon_resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@
<file>media/btn_icons/center_arrows.svg</file>
<file>media/btn_icons/confirm_stl_window.svg</file>
<file>media/btn_icons/horizontal_scroll_bar.svg</file>
<file>media/btn_icons/info.svg</file>
<file>media/btn_icons/error.svg</file>
<file>media/btn_icons/info_prints.svg</file>
<file>media/btn_icons/error.svg</file>
<file>media/btn_icons/info.svg</file>
<file>media/btn_icons/LCD_settings.svg</file>
<file>media/btn_icons/LEDs.svg</file>
<file>media/btn_icons/LEDs_off.svg</file>
Expand Down
Loading
Loading