Skip to content

Commit acdd56e

Browse files
committed
Make viewport a property/setter and raise TypeError if not a Rect
This commit makes viewport a property of Camera2D and adds a setter for it. In the setter, and in __init__, we check that Viewport is a Rect and raise a TypeError if it is not. Without this check, an error will be raised after either calling `Camera2D.equalise()` or in `Camera2D.use()`, which may confuse users as to why the error is occurring. Backtrace when calling `Camera2D.equalise()` with a non-rect viewport: ``` File "E:\Projects\SpaceGame\SpaceGame\gamemodes\basegame.py", line 128, in setup_two_player_cameras player_one_camera.equalise() File "E:\Programs\python-arcade\arcade\camera\camera_2d.py", line 336, in equalise self._projection_data.rect = XYWH(x, y, self.viewport_width, self.viewport_height) ^^^^^^^^^^^^^^^^^^^ File "E:\Programs\python-arcade\arcade\camera\camera_2d.py", line 751, in viewport_width return int(self._viewport.width) ``` Backtrace when calling `Camera2D.use()` with a non-rect viewport: ``` File "E:\Projects\SpaceGame\SpaceGame\gamemodes\pvp.py", line 139, in on_draw self.cameras[player].use() File "E:\Programs\python-arcade\arcade\camera\camera_2d.py", line 271, in use self._window.ctx.viewport = self._viewport.lbwh_int ```
1 parent 33e5960 commit acdd56e

File tree

1 file changed

+37
-18
lines changed

1 file changed

+37
-18
lines changed

arcade/camera/camera_2d.py

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ def __init__(
111111
# but we need to have some form of default size.
112112
render_target = render_target or self._window.ctx.screen
113113
viewport = viewport or LBWH(*render_target.viewport)
114+
115+
if not isinstance(viewport, Rect):
116+
raise TypeError('viewport must be a Rect type,' \
117+
'use arcade.LBWH or arcade.types.Viewport')
118+
114119
width, height = viewport.size
115120
half_width = width / 2
116121
half_height = height / 2
@@ -148,7 +153,7 @@ def __init__(
148153
left=left, right=right, top=top, bottom=bottom, near=near, far=far
149154
)
150155

151-
self.viewport: Rect = viewport or LRBT(0, 0, width, height)
156+
self._viewport: Rect = viewport or LRBT(0, 0, width, height)
152157
"""
153158
A rect which describes how the final projection should be mapped
154159
from unit-space. defaults to the size of the render_target or window
@@ -264,7 +269,7 @@ def use(self) -> None:
264269
_projection = generate_orthographic_matrix(self.projection_data, self.zoom)
265270
_view = generate_view_matrix(self.view_data)
266271

267-
self._window.ctx.viewport = self.viewport.lbwh_int
272+
self._window.ctx.viewport = self._viewport.lbwh_int
268273
self._window.ctx.scissor = None if not self.scissor else self.scissor.lbwh_int
269274
self._window.projection = _projection
270275
self._window.view = _view
@@ -297,7 +302,7 @@ def project(self, world_coordinate: Point) -> Vec2:
297302

298303
return project_orthographic(
299304
world_coordinate,
300-
self.viewport.lbwh_int,
305+
self._viewport.lbwh_int,
301306
_view,
302307
_projection,
303308
)
@@ -320,7 +325,9 @@ def unproject(self, screen_coordinate: Point) -> Vec3:
320325

321326
_projection = generate_orthographic_matrix(self.projection_data, self.zoom)
322327
_view = generate_view_matrix(self.view_data)
323-
return unproject_orthographic(screen_coordinate, self.viewport.lbwh_int, _view, _projection)
328+
return unproject_orthographic(screen_coordinate,
329+
self._viewport.lbwh_int,
330+
_view, _projection)
324331

325332
def equalise(self) -> None:
326333
"""
@@ -444,7 +451,7 @@ def update_values(
444451
value = XYWH(value.x, value.y, w, h)
445452

446453
if viewport:
447-
self.viewport = value
454+
self._viewport = value
448455

449456
if projection:
450457
x, y = self._projection_data.rect.x, self._projection_data.rect.y
@@ -467,7 +474,7 @@ def aabb(self) -> Rect:
467474
ux, uy, *_ = up
468475
rx, ry = uy, -ux # up x Z'
469476

470-
l, r, b, t = self.viewport.lrbt
477+
l, r, b, t = self._viewport.lrbt
471478
x, y = self.position
472479

473480
x_points = (
@@ -727,89 +734,101 @@ def projection_far(self) -> float:
727734
def projection_far(self, new_far: float) -> None:
728735
self._projection_data.far = new_far
729736

737+
@property
738+
def viewport(self) -> Rect:
739+
return self._viewport
740+
741+
@viewport.setter
742+
def viewport(self, viewport: Rect) -> None:
743+
if not isinstance(viewport, Rect):
744+
raise TypeError('viewport must be a Rect type,' \
745+
'use arcade.LBWH or arcade.types.Viewport')
746+
747+
self._viewport = viewport
748+
730749
@property
731750
def viewport_width(self) -> int:
732751
"""
733752
The width of the viewport.
734753
Defines the number of pixels drawn too horizontally.
735754
"""
736-
return int(self.viewport.width)
755+
return int(self._viewport.width)
737756

738757
@viewport_width.setter
739758
def viewport_width(self, new_width: int) -> None:
740-
self.viewport = self.viewport.resize(new_width, anchor=Vec2(0.0, 0.0))
759+
self._viewport = self._viewport.resize(new_width, anchor=Vec2(0.0, 0.0))
741760

742761
@property
743762
def viewport_height(self) -> int:
744763
"""
745764
The height of the viewport.
746765
Defines the number of pixels drawn too vertically.
747766
"""
748-
return int(self.viewport.height)
767+
return int(self._viewport.height)
749768

750769
@viewport_height.setter
751770
def viewport_height(self, new_height: int) -> None:
752-
self.viewport = self.viewport.resize(height=new_height, anchor=Vec2(0.0, 0.0))
771+
self._viewport = self._viewport.resize(height=new_height, anchor=Vec2(0.0, 0.0))
753772

754773
@property
755774
def viewport_left(self) -> int:
756775
"""
757776
The left most pixel drawn to on the X axis.
758777
"""
759-
return int(self.viewport.left)
778+
return int(self._viewport.left)
760779

761780
@viewport_left.setter
762781
def viewport_left(self, new_left: int) -> None:
763782
"""
764783
Set the left most pixel drawn to.
765784
This moves the position of the viewport, and does not change the size.
766785
"""
767-
self.viewport = self.viewport.align_left(new_left)
786+
self._viewport = self._viewport.align_left(new_left)
768787

769788
@property
770789
def viewport_right(self) -> int:
771790
"""
772791
The right most pixel drawn to on the X axis.
773792
"""
774-
return int(self.viewport.right)
793+
return int(self._viewport.right)
775794

776795
@viewport_right.setter
777796
def viewport_right(self, new_right: int) -> None:
778797
"""
779798
Set the right most pixel drawn to.
780799
This moves the position of the viewport, and does not change the size.
781800
"""
782-
self.viewport = self.viewport.align_right(new_right)
801+
self._viewport = self._viewport.align_right(new_right)
783802

784803
@property
785804
def viewport_bottom(self) -> int:
786805
"""
787806
The bottom most pixel drawn to on the Y axis.
788807
"""
789-
return int(self.viewport.bottom)
808+
return int(self._viewport.bottom)
790809

791810
@viewport_bottom.setter
792811
def viewport_bottom(self, new_bottom: int) -> None:
793812
"""
794813
Set the bottom most pixel drawn to.
795814
This moves the position of the viewport, and does not change the size.
796815
"""
797-
self.viewport = self.viewport.align_bottom(new_bottom)
816+
self._viewport = self._viewport.align_bottom(new_bottom)
798817

799818
@property
800819
def viewport_top(self) -> int:
801820
"""
802821
The top most pixel drawn to on the Y axis.
803822
"""
804-
return int(self.viewport.top)
823+
return int(self._viewport.top)
805824

806825
@viewport_top.setter
807826
def viewport_top(self, new_top: int) -> None:
808827
"""
809828
Set the top most pixel drawn to.
810829
This moves the position of the viewport, and does not change the size.
811830
"""
812-
self.viewport = self.viewport.align_top(new_top)
831+
self._viewport = self._viewport.align_top(new_top)
813832

814833
@property
815834
def up(self) -> Vec2:

0 commit comments

Comments
 (0)