1"""
2Section Example 1:
3
4In this Section example we divide the screen in two sections and let the user
5pick a box depending on the selected Section
6
7Note:
8 - How View know nothing of what's happening inside the sections.
9 Each section knows what to do.
10 - Each event mouse input is handled by each Section even if the class
11 it's the same (ScreenPart).
12 - How on_mouse_enter/leave triggers in each Section when the mouse
13 enter or leaves the section boundaries
14
15If Python and Arcade are installed, this example can be run from the command line with:
16python -m arcade.examples.sections_demo_1
17"""
18from __future__ import annotations
19
20from typing import Optional
21
22import arcade
23
24
25class Box(arcade.SpriteSolidColor):
26 """ This is a Solid Sprite that represents a GREEN Box on the screen """
27
28 def __init__(self, section):
29 super().__init__(100, 100, color=arcade.color.APPLE_GREEN)
30 self.section = section
31
32 def on_update(self, delta_time: float = 1 / 60):
33 # update the box (this actually moves the Box by changing its position)
34 self.update()
35
36 # if we hit the ground then lay on the ground and stop movement
37 if self.bottom <= 0:
38 self.bottom = 0
39 self.stop()
40
41 def release(self):
42 self.section.hold_box = None
43 self.change_y = -10
44
45
46class ScreenPart(arcade.Section):
47 """
48 This represents a part of the View defined by its
49 boundaries (left, bottom, etc.)
50 """
51
52 def __init__(self, left: int, bottom: int, width: int, height: int,
53 **kwargs):
54 super().__init__(left, bottom, width, height, **kwargs)
55
56 self.selected: bool = False # if this section is selected
57
58 self.box: Box = Box(self) # the section Box Sprite
59
60 # position the Box inside this section using self.left + self.width
61 self.box.position = self.left + (self.width / 2), 50
62
63 # variable that will hold the Box when it's being dragged
64 self.hold_box: Optional[Box] = None
65
66 def on_update(self, delta_time: float):
67 # call on_update on the owned Box
68 self.box.on_update(delta_time)
69
70 def on_draw(self):
71 """ Draw this section """
72 if self.selected:
73 # Section is selected when mouse is within its boundaries
74 arcade.draw_lrbt_rectangle_filled(self.left, self.right, self.bottom,
75 self.top, arcade.color.GRAY)
76 arcade.draw_text(f'You\'re are on the {self.name}', self.left + 30,
77 self.top - 50, arcade.color.BLACK, 16)
78
79 # draw the box
80 self.box.draw()
81
82 def on_mouse_drag(self, x: float, y: float, dx: float, dy: float,
83 _buttons: int, _modifiers: int):
84 # if we hold a box, then whe move it at the same rate the mouse moves
85 if self.hold_box:
86 self.hold_box.position = x, y
87
88 def on_mouse_press(self, x: float, y: float, button: int, modifiers: int):
89 # if we pick a Box with the mouse, "hold" it and stop its movement
90 if self.box.collides_with_point((x, y)):
91 self.hold_box = self.box
92 self.hold_box.stop()
93
94 def on_mouse_release(self, x: float, y: float, button: int, modifiers: int):
95 # if hold_box is True because we pick it with on_mouse_press
96 # then release the Box
97 if self.hold_box:
98 self.hold_box.release()
99
100 def on_mouse_enter(self, x: float, y: float):
101 # select this section
102 self.selected = True
103
104 def on_mouse_leave(self, x: float, y: float):
105 # unselect this section
106 self.selected = False
107
108 # if we are holding this section box and we leave the section
109 # we release the box as if we release the mouse button
110 if self.hold_box:
111 self.hold_box.release()
112
113
114class GameView(arcade.View):
115
116 def __init__(self):
117 super().__init__()
118
119 # add sections to the view
120
121 # 1) First section holds half of the screen
122 self.add_section(ScreenPart(0, 0, self.window.width / 2,
123 self.window.height, name='Left'))
124
125 # 2) Second section holds the other half of the screen
126 self.add_section(ScreenPart(self.window.width / 2, 0,
127 self.window.width / 2, self.window.height,
128 name='Right'))
129
130 def on_draw(self):
131 # clear the screen
132 self.clear(arcade.color.BEAU_BLUE)
133
134 # draw a line separating each Section
135 arcade.draw_line(self.window.width / 2, 0, self.window.width / 2,
136 self.window.height, arcade.color.BLACK, 1)
137
138
139def main():
140 # create the window
141 window = arcade.Window()
142
143 # create the custom View. Sections are initialized inside the GameView init
144 view = GameView()
145
146 # show the view
147 window.show_view(view)
148
149 # run arcade loop
150 window.run()
151
152
153if __name__ == '__main__':
154 main()