From 097ae8ffddbd3a8bcf32db264e987250ac24b49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Eertmans?= Date: Fri, 4 Aug 2023 13:33:21 +0200 Subject: [PATCH] feat(present): fix presentation size and add screen option (#232) * feat(present): fix presentation size and add screen option This kinda fixes the issue of weird resizes between two presentations * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix(ci): typing --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- manim_slides/logger.py | 1 + manim_slides/present.py | 67 ++++++++++++++++++++++++++++++++++------- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/manim_slides/logger.py b/manim_slides/logger.py index 3530d5a..684e665 100644 --- a/manim_slides/logger.py +++ b/manim_slides/logger.py @@ -25,6 +25,7 @@ HIGHLIGHTED_KEYWORDS = [ # these keywords are highlighted specially "File", "Rendering", "Rendered", + "Pressed key", ] diff --git a/manim_slides/present.py b/manim_slides/present.py index 2932669..fe26b0f 100644 --- a/manim_slides/present.py +++ b/manim_slides/present.py @@ -14,7 +14,15 @@ from click import Context, Parameter from pydantic import ValidationError from pydantic_extra_types.color import Color from PySide6.QtCore import Qt, QThread, Signal, Slot -from PySide6.QtGui import QCloseEvent, QIcon, QImage, QKeyEvent, QPixmap, QResizeEvent +from PySide6.QtGui import ( + QCloseEvent, + QIcon, + QImage, + QKeyEvent, + QPixmap, + QResizeEvent, + QScreen, +) from PySide6.QtWidgets import QApplication, QGridLayout, QLabel, QWidget from tqdm import tqdm @@ -351,7 +359,7 @@ class Display(QThread): # type: ignore change_video_signal = Signal(np.ndarray) change_info_signal = Signal(dict) - change_presentation_sigal = Signal() + change_presentation_signal = Signal() finished = Signal() def __init__( @@ -402,7 +410,7 @@ class Display(QThread): # type: ignore if -len(self) <= value < len(self): self.__current_presentation_index = value self.current_presentation.release_cap() - self.change_presentation_sigal.emit() + self.change_presentation_signal.emit() else: logger.error( f"Could not load scene number {value}, playing first scene instead." @@ -423,6 +431,10 @@ class Display(QThread): # type: ignore """Returns the background color of the current presentation.""" return self.current_presentation.background_color + def start(self) -> None: + super().start() + self.change_presentation_signal.emit() + def run(self) -> None: """Runs a series of presentations until end or exit.""" while self.run_flag: @@ -651,10 +663,15 @@ class App(QWidget): # type: ignore aspect_ratio: AspectRatio = AspectRatio.auto, resize_mode: Qt.TransformationMode = Qt.SmoothTransformation, background_color: str = "black", + screen: Optional[QScreen] = None, **kwargs: Any, ): super().__init__() + if screen: + self.setScreen(screen) + self.move(screen.geometry().topLeft()) + self.setWindowTitle(WINDOW_NAME) self.icon = QIcon(":/icon.png") self.setWindowIcon(self.icon) @@ -676,10 +693,6 @@ class App(QWidget): # type: ignore if self.aspect_ratio == AspectRatio.auto: self.label.setScaledContents(True) self.label.setAlignment(Qt.AlignCenter) - self.label.resize(self.display_width, self.display_height) - self.label.setStyleSheet( - f"background-color: {self.thread.current_background_color}" - ) self.pixmap = QPixmap(self.width(), self.height()) self.label.setPixmap(self.pixmap) @@ -694,11 +707,13 @@ class App(QWidget): # type: ignore if fullscreen: self.showFullScreen() + else: + self.resize(self.display_width, self.display_height) # connect signals self.thread.change_video_signal.connect(self.update_image) self.thread.change_info_signal.connect(self.info.update_info) - self.thread.change_presentation_sigal.connect(self.update_canvas) + self.thread.change_presentation_signal.connect(self.update_canvas) self.thread.finished.connect(self.closeAll) self.send_key_signal.connect(self.thread.set_key) @@ -756,8 +771,12 @@ class App(QWidget): # type: ignore def update_canvas(self) -> None: """Update the canvas when a presentation has changed.""" logger.debug("Updating canvas") - self.display_width, self.display_height = self.thread.current_resolution - if not self.isFullScreen(): + w, h = self.thread.current_resolution + + if not self.isFullScreen() and ( + self.display_width != w or self.display_height != h + ): + self.display_width, self.display_height = w, h self.resize(self.display_width, self.display_height) self.label.setStyleSheet( f"background-color: {self.thread.current_background_color}" @@ -998,6 +1017,14 @@ def start_at_callback( default=0, help="Start presenting at a given animation number (0 is first, -1 is last). This conflicts with slide number since animation number is absolute to the presentation.", ) +@click.option( + "--screen", + "screen_number", + metavar="NUMBER", + type=int, + default=None, + help="Presents content on the given screen (a.k.a. display).", +) @click.help_option("-h", "--help") @verbosity_option def present( @@ -1018,6 +1045,7 @@ def present( start_at_scene_number: Optional[int], start_at_slide_number: Optional[int], start_at_animation_number: Optional[int], + screen_number: Optional[int] = None, ) -> None: """ Present SCENE(s), one at a time, in order. @@ -1069,7 +1097,9 @@ def present( ext = record_to.suffix if ext.lower() != ".avi": raise click.UsageError( - "Recording only support '.avi' extension. For other video formats, please convert the resulting '.avi' file afterwards." + "Recording only support '.avi' extension. " + "For other video formats, " + "please convert the resulting '.avi' file afterwards." ) if start_at[0]: @@ -1087,6 +1117,19 @@ def present( app = QApplication.instance() app.setApplicationName("Manim Slides") + + if screen_number is not None: + try: + screen = app.screens()[screen_number] + except IndexError: + logger.error( + f"Invalid screen number {screen_number}, " + f"allowed values are from 0 to {len(app.screens())-1} (incl.)" + ) + screen = None + else: + screen = None + a = App( presentations, config=config, @@ -1101,7 +1144,9 @@ def present( start_at_scene_number=start_at_scene_number, start_at_slide_number=start_at_slide_number, start_at_animation_number=start_at_animation_number, + screen=screen, ) + a.show() # inform about CTRL+C