mirror of
https://github.com/3b1b/manim.git
synced 2025-09-01 00:48:45 +00:00
Move logic for window size and position into Window class
This commit is contained in:
parent
178cca0ca5
commit
d4c5c4736a
3 changed files with 54 additions and 56 deletions
|
@ -5,7 +5,6 @@ import colour
|
|||
import importlib
|
||||
import inspect
|
||||
import os
|
||||
import screeninfo
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
|
@ -311,48 +310,15 @@ def get_resolution(args: Optional[Namespace] = None, global_config: Optional[dic
|
|||
return int(width_str), int(height_str)
|
||||
|
||||
|
||||
def get_window_position(monitor: screeninfo.Monitor, position_string: str, size: tuple[int, int]):
|
||||
# Find position (Perhaps factor this out)
|
||||
# Position might be specified with a string of the form
|
||||
# x,y for integers x and y
|
||||
if "," in position_string:
|
||||
return tuple(map(int, position_string.split(",")))
|
||||
elif len(position_string) == 2:
|
||||
# Alternatively, it might be specified with a string like
|
||||
# UR, OO, DL, etc. specifying what corner it should go to
|
||||
char_to_n = {"L": 0, "U": 0, "O": 1, "R": 2, "D": 2}
|
||||
width_diff = monitor.width - size[0]
|
||||
height_diff = monitor.height - size[1]
|
||||
x_step = char_to_n[position_string[1]] * width_diff // 2
|
||||
y_step = char_to_n[position_string[0]] * height_diff // 2
|
||||
return (monitor.x + x_step, -monitor.y + y_step)
|
||||
else:
|
||||
raise Exception("Window position string must be either a tuple of integers, or a pair of from \"ULORD\"")
|
||||
|
||||
|
||||
def get_window_config(args: Namespace, global_config: dict) -> dict:
|
||||
# Default to making window half the screen size
|
||||
# but make it full screen if -f is passed in
|
||||
try:
|
||||
monitors = screeninfo.get_monitors()
|
||||
except screeninfo.ScreenInfoError:
|
||||
# Default fallback
|
||||
monitors = [screeninfo.Monitor(width=1920, height=1080)]
|
||||
mon_index = global_config["window"]["monitor"]
|
||||
monitor = monitors[min(mon_index, len(monitors) - 1)]
|
||||
|
||||
width, height = get_resolution(args, global_config)
|
||||
aspect_ratio = width / height
|
||||
|
||||
window_width = monitor.width
|
||||
if not (args.full_screen or global_config["window"]["full_screen"]):
|
||||
window_width //= 2
|
||||
window_height = int(window_width / aspect_ratio)
|
||||
size = (window_width, window_height)
|
||||
|
||||
default_position = get_window_position(monitor, global_config["window"]["position"], size)
|
||||
|
||||
return dict(size=size, default_position=default_position)
|
||||
window_config = global_config["window"]
|
||||
# Todo, this correction of configuration should maybe happen elsewhere
|
||||
for key in "position", "size":
|
||||
if window_config.get(key):
|
||||
window_config[key] = eval(window_config[key])
|
||||
if args.full_screen:
|
||||
window_config["full_screen"] = True
|
||||
return window_config
|
||||
|
||||
|
||||
def get_camera_config(args: Optional[Namespace] = None, global_config: Optional[dict] = None) -> dict:
|
||||
|
|
|
@ -26,14 +26,16 @@ directories:
|
|||
# but here a user can specify a different cache location
|
||||
cache: ""
|
||||
window:
|
||||
# Set the position of window on screen, you can use directions, e.g. UL/DR/OL/OO/...
|
||||
# also, you can also specify the position(pixel) of the upper left corner of
|
||||
# the window on the monitor, e.g. "960,540"
|
||||
position: UR
|
||||
# If using multiple monitors, which one should show the window?
|
||||
monitor: 0
|
||||
# The position of window on screen. UR -> Upper Right, and likewise DL -> Down and Left,
|
||||
# UO would be upper middle, etc.
|
||||
position_string: UR
|
||||
# If using multiple monitors, which one should show the window
|
||||
monitor_index: 0
|
||||
# If not full screen, the default to give it half the screen width
|
||||
full_screen: False
|
||||
# Other optional specifications that override the above
|
||||
# position: (500, 500) # Specific position, in pixel coordiantes, for upper right corner
|
||||
# size: (1920, 1080) # Specific size, in pixels
|
||||
file_writer_config:
|
||||
# If break_into_partial_movies is set to True, then many small
|
||||
# files will be written corresponding to each Scene.play and
|
||||
|
|
|
@ -6,8 +6,10 @@ import moderngl_window as mglw
|
|||
from moderngl_window.context.pyglet.window import Window as PygletWindow
|
||||
from moderngl_window.timers.clock import Timer
|
||||
from functools import wraps
|
||||
import screeninfo
|
||||
|
||||
from manimlib.config import get_global_config
|
||||
from manimlib.constants import ASPECT_RATIO
|
||||
from manimlib.constants import FRAME_SHAPE
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
@ -29,20 +31,24 @@ class Window(PygletWindow):
|
|||
def __init__(
|
||||
self,
|
||||
scene: Optional[Scene] = None,
|
||||
size: tuple[int, int] = (1280, 720),
|
||||
default_position: tuple[int, int] = (0, 0),
|
||||
position_string: str = "UR",
|
||||
monitor_index: int = 1,
|
||||
full_screen: bool = False,
|
||||
size: Optional[tuple[int, int]] = None,
|
||||
position: Optional[tuple[int, int]] = None,
|
||||
samples: int = 0
|
||||
):
|
||||
super().__init__(size=size, samples=samples)
|
||||
|
||||
self.scene = scene
|
||||
self.default_size = size
|
||||
self.default_position = default_position
|
||||
self.pressed_keys = set()
|
||||
self.size = size
|
||||
self.monitor = self.get_monitor(monitor_index)
|
||||
self.default_size = size or self.get_default_size(full_screen)
|
||||
self.default_position = position or self.position_from_string(position_string)
|
||||
|
||||
super().__init__(samples=samples)
|
||||
self.to_default_position()
|
||||
|
||||
self.pressed_keys = set()
|
||||
|
||||
|
||||
if self.scene:
|
||||
self.init_for_scene(scene)
|
||||
|
||||
|
@ -66,6 +72,30 @@ class Window(PygletWindow):
|
|||
mglw.activate_context(window=self, ctx=self.ctx)
|
||||
self.timer.start()
|
||||
|
||||
def get_monitor(self, index):
|
||||
try:
|
||||
monitors = screeninfo.get_monitors()
|
||||
return monitors[min(index, len(monitors) - 1)]
|
||||
except screeninfo.ScreenInfoError:
|
||||
# Default fallback
|
||||
return screeninfo.Monitor(width=1920, height=1080)
|
||||
|
||||
def get_default_size(self, full_screen=False):
|
||||
width = self.monitor.width // (1 if full_screen else 2)
|
||||
height = int(width // ASPECT_RATIO)
|
||||
return (width, height)
|
||||
|
||||
def position_from_string(self, position_string):
|
||||
# Alternatively, it might be specified with a string like
|
||||
# UR, OO, DL, etc. specifying what corner it should go to
|
||||
char_to_n = {"L": 0, "U": 0, "O": 1, "R": 2, "D": 2}
|
||||
size = self.default_size
|
||||
width_diff = self.monitor.width - size[0]
|
||||
height_diff = self.monitor.height - size[1]
|
||||
x_step = char_to_n[position_string[1]] * width_diff // 2
|
||||
y_step = char_to_n[position_string[0]] * height_diff // 2
|
||||
return (self.monitor.x + x_step, -self.monitor.y + y_step)
|
||||
|
||||
def focus(self):
|
||||
"""
|
||||
Puts focus on this window by hiding and showing it again.
|
||||
|
|
Loading…
Add table
Reference in a new issue