Skip to content
Merged
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
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,14 @@ API in a way that is not compatible with how it was used in 2.6.
* Removed `arcade.gui.widgets.UIPadding` this is now general available in `arcade.gui.widgets.UIWidget`
* Removed `arcade.gui.widgets.UITexturePane` this is now general available in `arcade.gui.widgets.UIWidget`
* Removed `arcade.gui.widgets.UIAnchorWidget` replaced by `arcade.gui.widgets.UIAnchorLayout`

* Resources
* removed unsused resources from `resources/gui_basic_assets`
* `items/shield_gold.png`
* `items/sword_gold.png`
* `slider_thumb.png`
* `slider_track.png`
* `toggle/switch_green.png`
* `toggle/switch_red.png`
### Featured Updates

* The texture atlas has been heavily reworked to be more efficient.
Expand Down Expand Up @@ -131,6 +138,10 @@ API in a way that is not compatible with how it was used in 2.6.
* Update and add example code.
* Iterable (providing direct children)

* Updated widgets
* `arcade.gui.widgets.text.UIInputText` emits `on_change` event when new text input or set
* `arcade.gui.widgets.slider.UITextureSlider` texture names changed to fit general naming pattern

* New widgets:

* `arcade.gui.widgets.dropdown.UIDropdown`
Expand All @@ -152,6 +163,8 @@ API in a way that is not compatible with how it was used in 2.6.
* `arcade.gui.UIAnchorLayout`
* `arcade.gui.UIGridLayout` [PR1478](https://github.com/pythonarcade/arcade/pull/1478)

* Added color consistent assets to `arcade.resources.gui_basic_assets`
* Provide GUI friendly color constants in `arcade.uicolor`
* Replace deprecated usage of `arcade.draw_text`

### Misc Changes
Expand Down
2 changes: 1 addition & 1 deletion arcade/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.0.0-dev.33
3.0.0-dev.36
2 changes: 2 additions & 0 deletions arcade/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ def configure_logging(level: int | None = None):
# Module imports
from arcade import color as color
from arcade import csscolor as csscolor
from arcade import uicolor as uicolor
from arcade import camera as camera
from arcade import key as key
from arcade import resources as resources
Expand Down Expand Up @@ -387,6 +388,7 @@ def configure_logging(level: int | None = None):
"rect",
"color",
"csscolor",
"uicolor",
"key",
"resources",
"types",
Expand Down
70 changes: 2 additions & 68 deletions arcade/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from arcade.clock import GLOBAL_CLOCK, GLOBAL_FIXED_CLOCK, _setup_clock, _setup_fixed_clock
from arcade.color import TRANSPARENT_BLACK
from arcade.context import ArcadeContext
from arcade.sections import SectionManager
from arcade.types import LBWH, Color, Rect, RGBANormalized, RGBOrA255
from arcade.utils import is_raspberry_pi
from arcade.window_commands import get_display_size, set_window
Expand Down Expand Up @@ -979,37 +978,21 @@ def show_view(self, new_view: View) -> None:
# remove previously shown view's handlers
if self._current_view is not None:
self._current_view.on_hide_view()
if self._current_view.has_sections:
self.remove_handlers(self._current_view.section_manager)
self.remove_handlers(self._current_view)

# push new view's handlers
self._current_view = new_view
if new_view.has_sections:
section_manager_managed_events = new_view.section_manager.managed_events
section_handlers = {
event_type: getattr(new_view.section_manager, event_type, None)
for event_type in section_manager_managed_events
}
if section_handlers:
self.push_handlers(**section_handlers)
else:
section_manager_managed_events = set()

# Note: Excluding on_show because this even can trigger multiple times.
# It should only be called once when the view is shown.
view_handlers = {
event_type: getattr(new_view, event_type, None)
for event_type in self.event_types
if event_type != "on_show"
and event_type not in section_manager_managed_events
and hasattr(new_view, event_type)
if event_type != "on_show" and hasattr(new_view, event_type)
}
if view_handlers:
self.push_handlers(**view_handlers)
self._current_view.on_show_view()
if self._current_view.has_sections:
self._current_view.section_manager.on_show_view()

# Note: After the View has been pushed onto pyglet's stack of event handlers
# (via push_handlers()), pyglet
Expand All @@ -1028,18 +1011,9 @@ def hide_view(self) -> None:
return

self._current_view.on_hide_view()
if self._current_view.has_sections:
self._current_view.section_manager.on_hide_view()
self.remove_handlers(self._current_view.section_manager)
self.remove_handlers(self._current_view)
self._current_view = None

# def _create(self) -> None:
# super()._create()

# def _recreate(self, changes) -> None:
# super()._recreate(changes)

def flip(self) -> None:
"""
Present the rendered content to the screen.
Expand Down Expand Up @@ -1249,7 +1223,7 @@ class View:
Subclassing the window is very inflexible since you can't easily switch
your update and draw logic.

A view is a way to encapsulate that logic so you can easily switch between
A view is a way to encapsulate that logic, so you can easily switch between
different parts of your game. Maybe you have a title screen, a game screen,
and a game over screen. Each of these could be a different view.

Expand All @@ -1261,46 +1235,6 @@ class View:

def __init__(self, window: Window | None = None) -> None:
self.window = arcade.get_window() if window is None else window
self.key: int | None = None
self._section_manager: SectionManager | None = None

@property
def section_manager(self) -> SectionManager:
"""The section manager for this view.

If the view has section manager one will be created.
"""
if self._section_manager is None:
self._section_manager = SectionManager(self)
return self._section_manager

@property
def has_sections(self) -> bool:
"""Returns ``True`` if this view has sections."""
if self._section_manager is None:
return False
else:
return self.section_manager.has_sections

def add_section(
self,
section: arcade.Section,
at_index: int | None = None,
at_draw_order: int | None = None,
) -> None:
"""
Adds a section to the view Section Manager.

Args:
section:
The section to add to this section manager
at_index (optional):
The index to insert the section for event capture and
update events. If ``None`` it will be added at the end.
at_draw_order (optional):
Inserts the section in a specific draw order. Overwrites section.draw_order
"""
self.section_manager.add_section(section, at_index, at_draw_order)

def clear(
self,
Expand Down
27 changes: 14 additions & 13 deletions arcade/camera/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pyglet.math import Mat4, Vec2, Vec3
from typing_extensions import Self

from arcade.types import Point
from arcade.types import LBWH, Point, Rect
from arcade.window_commands import get_window

if TYPE_CHECKING:
Expand All @@ -29,28 +29,28 @@ class ViewportProjector:

def __init__(
self,
viewport: tuple[int, int, int, int] | None = None,
viewport: Rect | None = None,
*,
context: ArcadeContext | None = None,
):
self._ctx = context or get_window().ctx
self._viewport = viewport or self._ctx.viewport
self._ctx: ArcadeContext = context or get_window().ctx
self._viewport: Rect = viewport or LBWH(*self._ctx.viewport)
self._projection_matrix: Mat4 = Mat4.orthogonal_projection(
0.0, self._viewport[2], 0.0, self._viewport[3], -100, 100
0.0, self._viewport.width, 0.0, self._viewport.height, -100, 100
)

@property
def viewport(self) -> tuple[int, int, int, int]:
def viewport(self) -> Rect:
"""
The viewport use to derive projection and view matrix.
"""
return self._viewport

@viewport.setter
def viewport(self, viewport: tuple[int, int, int, int]) -> None:
def viewport(self, viewport: Rect) -> None:
self._viewport = viewport
self._projection_matrix = Mat4.orthogonal_projection(
0, viewport[2], 0, viewport[3], -100, 100
0, viewport.width, 0, viewport.height, -100, 100
)

def use(self) -> None:
Expand All @@ -60,7 +60,7 @@ def use(self) -> None:
"""
self._ctx.current_camera = self

self._ctx.viewport = self._viewport
self._ctx.viewport = self.viewport.viewport # get the integer 4-tuple LBWH

self._ctx.view_matrix = Mat4()
self._ctx.projection_matrix = self._projection_matrix
Expand Down Expand Up @@ -121,18 +121,19 @@ def use(self) -> None:
cache's the window viewport to determine the projection matrix.
"""

viewport = self.viewport.viewport
# If the viewport is correct and the default camera is in use,
# then don't waste time resetting the view and projection matrices
if self._ctx.viewport == self.viewport and self._ctx.current_camera == self:
if self._ctx.viewport == viewport and self._ctx.current_camera == self:
return

# If the viewport has changed while the default camera is active then the
# default needs to update itself.
# If it was another camera's viewport being used the default camera should not update.
if self._ctx.viewport != self.viewport and self._ctx.current_camera == self:
self.viewport = self._ctx.viewport
if self._ctx.viewport != viewport and self._ctx.current_camera == self:
self.viewport = LBWH(*self._ctx.viewport)
else:
self._ctx.viewport = self.viewport
self._ctx.viewport = viewport

self._ctx.current_camera = self

Expand Down
30 changes: 15 additions & 15 deletions arcade/clock.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ class Clock:
only certain elements rather than everything.

Args:
initial_elapsed (float, optional): The amount of time the clock should assume has
initial_elapsed: The amount of time the clock should assume has
already occurred. Defaults to 0.0
initial_tick (int, optional): The number of ticks the clock should assume has already
initial_tick: The number of ticks the clock should assume has already
occurred. Defaults to 0.
tick_speed (float, optional): A multiplier on how the 'speed' of time.
tick_speed: A multiplier on how the 'speed' of time.
i.e. a value of 0.5 means time elapsed half as fast for this clock. Defaults to 1.0.
"""

Expand All @@ -40,7 +40,7 @@ def tick(self, delta_time: float):
Update the clock with the time that has passed since the last tick.

Args:
delta_time (float): The amount of time that has passed since the last tick.
delta_time: The amount of time that has passed since the last tick.
"""
self._tick_delta_time = delta_time * self._tick_speed
self._elapsed_time += self._tick_delta_time
Expand All @@ -51,7 +51,7 @@ def set_tick_speed(self, new_tick_speed: float):
Set the speed of time for this clock.

Args:
new_tick_speed (float): A multiplier on the 'speed' of time.
new_tick_speed: A multiplier on the 'speed' of time.
i.e. a value of 0.5 means time elapsed half as fast for this clock.
"""
self._tick_speed = new_tick_speed
Expand All @@ -61,7 +61,7 @@ def time_since(self, time: float) -> float:
Calculate the amount of time that has passed since the given time.

Args:
time (float): The time to compare against.
time: The time to compare against.
"""
return self._elapsed_time - time

Expand All @@ -70,7 +70,7 @@ def ticks_since(self, tick: int) -> int:
Calculate the number of ticks that have occurred since the given tick.

Args:
tick (int): The tick to compare against.
tick: The tick to compare against.
"""
return self._tick - tick

Expand Down Expand Up @@ -123,8 +123,8 @@ class FixedClock(Clock):
Arcade provides a global fixed clock which is automatically ticked every update

Args:
sibling (Clock): The unfixed clock which this clock will sync with.
fixed_tick_rate (float, optional): The fixed number of seconds that pass
sibling: The unfixed clock which this clock will sync with.
fixed_tick_rate: The fixed number of seconds that pass
for this clock every tick. Defaults to ``1.0 / 60.0``.
"""

Expand All @@ -138,7 +138,7 @@ def set_tick_speed(self, new_tick_speed: float):
Set the speed of time for this clock.

Args:
new_tick_speed (float): A multiplier on the 'speed' of time.
new_tick_speed: A multiplier on the 'speed' of time.
i.e. a value of 0.5 means time elapsed half as fast for this clock
"""
raise ValueError(
Expand All @@ -150,7 +150,7 @@ def tick(self, delta_time: float):
Update the clock with the time that has passed since the last tick.

Args:
delta_time (float): The amount of time that has passed since the last tick.
delta_time: The amount of time that has passed since the last tick.
"""
if delta_time != self._fixed_rate:
raise ValueError(
Expand Down Expand Up @@ -184,11 +184,11 @@ def _setup_clock(initial_elapsed: float = 0.0, initial_tick: int = 0, tick_speed
Private method used by the arcade window to setup the global clock post initialization.

Args:
initial_elapsed (float, optional): The amount of time the clock should assume
initial_elapsed: The amount of time the clock should assume
has already occurred. Defaults to 0.0
initial_tick (int, optional): The number of ticks the clock should assume has
initial_tick: The number of ticks the clock should assume has
already occurred. Defaults to 0.
tick_speed (float, optional): A multiplier on the 'speed' of time.
tick_speed: A multiplier on the 'speed' of time.
i.e. a value of 0.5 means time elapsed half as fast for this clock.
Defaults to 1.0.
"""
Expand All @@ -203,7 +203,7 @@ def _setup_fixed_clock(fixed_tick_rate: float = 1.0 / 60.0):
post initialization.

Args:
fixed_tick_rate (float, optional): The fixed number of seconds that pass
fixed_tick_rate: The fixed number of seconds that pass
for this clock every tick. Defaults to 1.0 / 60.0
"""
GLOBAL_FIXED_CLOCK._elapsed_time = GLOBAL_CLOCK.time # noqa: SLF001
Expand Down
Loading