Skip to content

Commit dd324e1

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 dd324e1

File tree

1 file changed

+35
-18
lines changed

1 file changed

+35
-18
lines changed

arcade/camera/camera_2d.py

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ 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,use arcade.LBWH or arcade.types.Viewport")
117+
114118
width, height = viewport.size
115119
half_width = width / 2
116120
half_height = height / 2
@@ -148,7 +152,7 @@ def __init__(
148152
left=left, right=right, top=top, bottom=bottom, near=near, far=far
149153
)
150154

151-
self.viewport: Rect = viewport or LRBT(0, 0, width, height)
155+
self._viewport: Rect = viewport or LRBT(0, 0, width, height)
152156
"""
153157
A rect which describes how the final projection should be mapped
154158
from unit-space. defaults to the size of the render_target or window
@@ -264,7 +268,7 @@ def use(self) -> None:
264268
_projection = generate_orthographic_matrix(self.projection_data, self.zoom)
265269
_view = generate_view_matrix(self.view_data)
266270

267-
self._window.ctx.viewport = self.viewport.lbwh_int
271+
self._window.ctx.viewport = self._viewport.lbwh_int
268272
self._window.ctx.scissor = None if not self.scissor else self.scissor.lbwh_int
269273
self._window.projection = _projection
270274
self._window.view = _view
@@ -297,7 +301,7 @@ def project(self, world_coordinate: Point) -> Vec2:
297301

298302
return project_orthographic(
299303
world_coordinate,
300-
self.viewport.lbwh_int,
304+
self._viewport.lbwh_int,
301305
_view,
302306
_projection,
303307
)
@@ -320,7 +324,9 @@ def unproject(self, screen_coordinate: Point) -> Vec3:
320324

321325
_projection = generate_orthographic_matrix(self.projection_data, self.zoom)
322326
_view = generate_view_matrix(self.view_data)
323-
return unproject_orthographic(screen_coordinate, self.viewport.lbwh_int, _view, _projection)
327+
return unproject_orthographic(
328+
screen_coordinate, self._viewport.lbwh_int, _view, _projection
329+
)
324330

325331
def equalise(self) -> None:
326332
"""
@@ -444,7 +450,7 @@ def update_values(
444450
value = XYWH(value.x, value.y, w, h)
445451

446452
if viewport:
447-
self.viewport = value
453+
self._viewport = value
448454

449455
if projection:
450456
x, y = self._projection_data.rect.x, self._projection_data.rect.y
@@ -467,7 +473,7 @@ def aabb(self) -> Rect:
467473
ux, uy, *_ = up
468474
rx, ry = uy, -ux # up x Z'
469475

470-
l, r, b, t = self.viewport.lrbt
476+
l, r, b, t = self._viewport.lrbt
471477
x, y = self.position
472478

473479
x_points = (
@@ -727,89 +733,100 @@ def projection_far(self) -> float:
727733
def projection_far(self, new_far: float) -> None:
728734
self._projection_data.far = new_far
729735

736+
@property
737+
def viewport(self) -> Rect:
738+
return self._viewport
739+
740+
@viewport.setter
741+
def viewport(self, viewport: Rect) -> None:
742+
if not isinstance(viewport, Rect):
743+
raise TypeError("viewport must be a Rect type,use arcade.LBWH or arcade.types.Viewport")
744+
745+
self._viewport = viewport
746+
730747
@property
731748
def viewport_width(self) -> int:
732749
"""
733750
The width of the viewport.
734751
Defines the number of pixels drawn too horizontally.
735752
"""
736-
return int(self.viewport.width)
753+
return int(self._viewport.width)
737754

738755
@viewport_width.setter
739756
def viewport_width(self, new_width: int) -> None:
740-
self.viewport = self.viewport.resize(new_width, anchor=Vec2(0.0, 0.0))
757+
self._viewport = self._viewport.resize(new_width, anchor=Vec2(0.0, 0.0))
741758

742759
@property
743760
def viewport_height(self) -> int:
744761
"""
745762
The height of the viewport.
746763
Defines the number of pixels drawn too vertically.
747764
"""
748-
return int(self.viewport.height)
765+
return int(self._viewport.height)
749766

750767
@viewport_height.setter
751768
def viewport_height(self, new_height: int) -> None:
752-
self.viewport = self.viewport.resize(height=new_height, anchor=Vec2(0.0, 0.0))
769+
self._viewport = self._viewport.resize(height=new_height, anchor=Vec2(0.0, 0.0))
753770

754771
@property
755772
def viewport_left(self) -> int:
756773
"""
757774
The left most pixel drawn to on the X axis.
758775
"""
759-
return int(self.viewport.left)
776+
return int(self._viewport.left)
760777

761778
@viewport_left.setter
762779
def viewport_left(self, new_left: int) -> None:
763780
"""
764781
Set the left most pixel drawn to.
765782
This moves the position of the viewport, and does not change the size.
766783
"""
767-
self.viewport = self.viewport.align_left(new_left)
784+
self._viewport = self._viewport.align_left(new_left)
768785

769786
@property
770787
def viewport_right(self) -> int:
771788
"""
772789
The right most pixel drawn to on the X axis.
773790
"""
774-
return int(self.viewport.right)
791+
return int(self._viewport.right)
775792

776793
@viewport_right.setter
777794
def viewport_right(self, new_right: int) -> None:
778795
"""
779796
Set the right most pixel drawn to.
780797
This moves the position of the viewport, and does not change the size.
781798
"""
782-
self.viewport = self.viewport.align_right(new_right)
799+
self._viewport = self._viewport.align_right(new_right)
783800

784801
@property
785802
def viewport_bottom(self) -> int:
786803
"""
787804
The bottom most pixel drawn to on the Y axis.
788805
"""
789-
return int(self.viewport.bottom)
806+
return int(self._viewport.bottom)
790807

791808
@viewport_bottom.setter
792809
def viewport_bottom(self, new_bottom: int) -> None:
793810
"""
794811
Set the bottom most pixel drawn to.
795812
This moves the position of the viewport, and does not change the size.
796813
"""
797-
self.viewport = self.viewport.align_bottom(new_bottom)
814+
self._viewport = self._viewport.align_bottom(new_bottom)
798815

799816
@property
800817
def viewport_top(self) -> int:
801818
"""
802819
The top most pixel drawn to on the Y axis.
803820
"""
804-
return int(self.viewport.top)
821+
return int(self._viewport.top)
805822

806823
@viewport_top.setter
807824
def viewport_top(self, new_top: int) -> None:
808825
"""
809826
Set the top most pixel drawn to.
810827
This moves the position of the viewport, and does not change the size.
811828
"""
812-
self.viewport = self.viewport.align_top(new_top)
829+
self._viewport = self._viewport.align_top(new_top)
813830

814831
@property
815832
def up(self) -> Vec2:

0 commit comments

Comments
 (0)