add rotate display; preserve fullscreen state when setting display surface

This commit is contained in:
ohsqueezy 2022-12-14 23:16:09 -05:00
parent 24b5d7c6e7
commit 7a16527179
4 changed files with 56 additions and 24 deletions

View File

@ -14,8 +14,7 @@ class Configuration(RawConfigParser):
default_project_file_rel_path = "config"
default_resource_paths = [".", "resource"]
def __init__(self, project_file_rel_path=None, resource_path=None,
type_declarations=None):
def __init__(self, project_file_rel_path=None, resource_path=None, type_declarations=None):
RawConfigParser.__init__(self)
self.project_file_rel_path = project_file_rel_path
self.resource_path = resource_path
@ -48,8 +47,7 @@ class Configuration(RawConfigParser):
set_option(section, "title", "", False)
set_option(section, "classifiers", "", False)
set_option(section, "resource-search-path", "./, resource/", False)
set_option(section, "installation-dir", "/usr/local/share/games/",
False)
set_option(section, "installation-dir", "/usr/local/share/games/", False)
set_option(section, "changelog", "changelog", False)
set_option(section, "description-file", "", False)
set_option(section, "init-script", "", False)
@ -472,9 +470,7 @@ class TypeDeclarations(dict):
additional_defaults = {}
def __init__(self):
dict.__init__(self, {"bool": [], "int": [], "float": [], "path": [],
"list": [], "int-list": [], "float-list": [],
"path-list": []})
dict.__init__(self, {"bool": [], "int": [], "float": [], "path": [], "list": [], "int-list": [], "float-list": [], "path-list": []})
self.add_chart(self.defaults)
self.add_chart(self.additional_defaults)

View File

@ -2,7 +2,7 @@ from os import environ
from sys import maxsize, platform
import pygame
from pygame import display, image, mouse
from pygame import image, mouse
from pygame.locals import *
from .GameChild import *
@ -49,28 +49,52 @@ class Display(GameChild):
def fullscreen_requested(self):
return not self.check_command_line(self.windowed_flag) and self.fullscreen_enabled
def set_screen(self, flags=0x0, dimensions=None, fs=False):
self.dimensions_changed = dimensions is not None
def set_screen(self, flags=0x0, dimensions=None, fs=None):
"""
Initialize the pygame display, passing along any flags, and assign the returned display surface to `self.screen`. If no
dimensions are passed, use the dimensions of the current screen surface if it exists, otherwise get dimensions from the
configuration. If `fs` is `None`, leave the fullscreen state as is, otherwise read it as a boolean and set fullscreen
accordingly.
@param flags Flags from https://www.pygame.org/docs/ref/display.html#pygame.display.set_mode. To pass multiple flags,
join them with the OR operator.
@param dimensions Dimensions of the screen surface as (width, height)
@param fs Set to True or False or omit to keep current fullscreen state
"""
# Try to auto discover dimensions if not provided
if dimensions is None:
if display.get_surface():
dimensions = display.get_surface().get_size()
if pygame.display.get_surface():
dimensions = pygame.display.get_surface().get_size()
else:
dimensions = self.get_configuration("display", "dimensions")
if fs is None:
# Get the current fullscreen state
fs = bool(pygame.display.get_surface().get_flags() & pygame.FULLSCREEN)
# Get a display surface with specified fullscreen state
if fs:
self.screen = display.set_mode(dimensions, flags | -0x80000000)
self.screen = pygame.display.set_mode(dimensions, flags | pygame.FULLSCREEN)
else:
self.screen = display.set_mode(dimensions, flags)
if self.dimensions_changed:
interpolator = self.get_game().interpolator
if interpolator.gui_enabled:
interpolator.gui.rearrange()
self.screen = pygame.display.set_mode(dimensions, flags)
# Redraw the spline interpolator interface if enabled
if self.get_game().interpolator.gui_enabled:
self.get_game().interpolator.gui.rearrange()
def rotate(self):
"""
Rotate the screen surface 90 degrees by resetting it with swapped W and H dimensions.
"""
current_width, current_height = self.get_display_surface().get_size()
self.set_screen(dimensions=(current_height, current_width))
def set_caption(self):
display.set_caption(self.caption)
pygame.display.set_caption(self.caption)
def set_icon(self):
if self.icon_path:
display.set_icon(image.load(self.icon_path).convert_alpha())
pygame.display.set_icon(image.load(self.icon_path).convert_alpha())
def set_mouse_visibility(self, visibility=None):
if visibility is None:

View File

@ -41,21 +41,26 @@ class Game(Animation):
self.delegate.enable()
def set_configuration(self):
self.configuration = Configuration(self.config_rel_path,
self.resource_path,
self.type_declarations)
self.configuration = Configuration(self.config_rel_path, self.resource_path, self.type_declarations)
def set_children(self):
"""
Create the child objects that encapsulate other parts of the framework. They're usually used as singletons or managers. Subscribe
to the pygame.QUIT event.
"""
self.delegate = Delegate(self)
self.subscribe(self.end, QUIT)
self.subscribe(self.end)
self.interpolator = Interpolator(self)
self.display = Display(self)
self.mainloop = Mainloop(self)
self.input = Input(self)
self.audio = Audio(self)
self.screen_grabber = ScreenGrabber(self)
self.video_recorder = VideoRecorder(self)
self.interpolator = Interpolator(self)
# Call this separately because it needs the display to be initialized previously
self.interpolator.init_gui()
def frame(self):
self.time_filter.update()

View File

@ -16,6 +16,13 @@ class Interpolator(list, GameChild):
def __init__(self, parent):
GameChild.__init__(self, parent)
self.set_nodesets()
self.gui_enabled = False
def init_gui(self):
"""
If the interpolator is requested on the command line, create a GUI object. This runs separately from `pgfw.Interpolator.__init__` because
the display is not available when the main `pgfw.Interpolator` is created by `pgfw.Game`.
"""
self.gui_enabled = self.check_command_line("-interpolator")
if self.gui_enabled:
self.gui = GUI(self)