menu_04.py Full Listing
menu_04.py
1"""
2Menu.
3
4Shows the usage of almost every gui widget, switching views and making a modal.
5"""
6
7import arcade
8import arcade.gui
9
10# Screen title and size
11SCREEN_WIDTH = 800
12SCREEN_HEIGHT = 600
13SCREEN_TITLE = "Making a Menu"
14
15
16class MainView(arcade.View):
17 """This is the class where your normal game would go."""
18
19 def __init__(self):
20 super().__init__()
21
22 self.manager = arcade.gui.UIManager()
23
24 switch_menu_button = arcade.gui.UIFlatButton(text="Pause", width=150)
25
26 # Initialise the button with an on_click event.
27 @switch_menu_button.event("on_click")
28 def on_click_switch_button(event):
29 # Passing the main view into menu view as an argument.
30 menu_view = MenuView(self)
31 self.window.show_view(menu_view)
32
33 # Use the anchor to position the button on the screen.
34 self.anchor = self.manager.add(arcade.gui.UIAnchorLayout())
35
36 self.anchor.add(
37 anchor_x="center_x",
38 anchor_y="center_y",
39 child=switch_menu_button,
40 )
41
42 def on_hide_view(self):
43 # Disable the UIManager when the view is hidden.
44 self.manager.disable()
45
46 def on_show_view(self):
47 """This is run once when we switch to this view"""
48 arcade.set_background_color(arcade.color.DARK_BLUE_GRAY)
49
50 # Enable the UIManager when the view is showm.
51 self.manager.enable()
52
53 def on_draw(self):
54 """Render the screen."""
55 # Clear the screen
56 self.clear()
57
58 # Draw the manager.
59 self.manager.draw()
60
61
62class MenuView(arcade.View):
63 """Main menu view class."""
64
65 def __init__(self, main_view):
66 super().__init__()
67
68 self.manager = arcade.gui.UIManager()
69
70 resume_button = arcade.gui.UIFlatButton(text="Resume", width=150)
71 start_new_game_button = arcade.gui.UIFlatButton(text="Start New Game", width=150)
72 volume_button = arcade.gui.UIFlatButton(text="Volume", width=150)
73 options_button = arcade.gui.UIFlatButton(text="Options", width=150)
74
75 exit_button = arcade.gui.UIFlatButton(text="Exit", width=320)
76
77 # Initialise a grid in which widgets can be arranged.
78 self.grid = arcade.gui.UIGridLayout(
79 column_count=2, row_count=3, horizontal_spacing=20, vertical_spacing=20
80 )
81
82 # Adding the buttons to the layout.
83 self.grid.add(resume_button, column=0, row=0)
84 self.grid.add(start_new_game_button, column=1, row=0)
85 self.grid.add(volume_button, column=0, row=1)
86 self.grid.add(options_button, column=1, row=1)
87 self.grid.add(exit_button, column=0, row=2, column_span=2)
88
89 self.anchor = self.manager.add(arcade.gui.UIAnchorLayout())
90
91 self.anchor.add(
92 anchor_x="center_x",
93 anchor_y="center_y",
94 child=self.grid,
95 )
96
97 self.main_view = main_view
98
99 @resume_button.event("on_click")
100 def on_click_resume_button(event):
101 # Pass already created view because we are resuming.
102 self.window.show_view(self.main_view)
103
104 @start_new_game_button.event("on_click")
105 def on_click_start_new_game_button(event):
106 # Create a new view because we are starting a new game.
107 main_view = MainView()
108 self.window.show_view(main_view)
109
110 @exit_button.event("on_click")
111 def on_click_exit_button(event):
112 arcade.exit()
113
114 @volume_button.event("on_click")
115 def on_click_volume_button(event):
116 volume_menu = SubMenu()
117 self.manager.add(volume_menu, layer=1)
118
119 @options_button.event("on_click")
120 def on_click_options_button(event):
121 options_menu = SubMenu()
122 self.manager.add(options_menu, layer=1)
123
124 def on_hide_view(self):
125 # Disable the UIManager when the view is hidden.
126 self.manager.disable()
127
128 def on_show_view(self):
129 """This is run once when we switch to this view"""
130
131 # Makes the background darker
132 arcade.set_background_color([rgb - 50 for rgb in arcade.color.DARK_BLUE_GRAY])
133
134 # Enable the UIManager when the view is showm.
135 self.manager.enable()
136
137 def on_draw(self):
138 """Render the screen."""
139 # Clear the screen
140 self.clear()
141 self.manager.draw()
142
143
144class SubMenu(arcade.gui.UIMouseFilterMixin, arcade.gui.UIAnchorLayout):
145 """Acts like a fake view/window."""
146
147 def __init__(
148 self,
149 ):
150 super().__init__(size_hint=(1, 1))
151
152 # Setup frame which will act like the window.
153 frame = self.add(arcade.gui.UIAnchorLayout(width=300, height=400, size_hint=None))
154 frame.with_padding(all=20)
155
156 # Add a background to the window.
157 frame.with_background(
158 texture=arcade.gui.NinePatchTexture(
159 left=7,
160 right=7,
161 bottom=7,
162 top=7,
163 texture=arcade.load_texture(
164 ":resources:gui_basic_assets/window/dark_blue_gray_panel.png"
165 ),
166 )
167 )
168
169 back_button = arcade.gui.UIFlatButton(text="Back", width=250)
170 # The type of event listener we used earlier for the button will not work here.
171 back_button.on_click = self.on_click_back_button
172
173 # Internal widget layout to handle widgets in this class.
174 widget_layout = arcade.gui.UIBoxLayout(align="left", space_between=10)
175
176 widget_layout.add(back_button)
177
178 frame.add(child=widget_layout, anchor_x="center_x", anchor_y="top")
179
180 def on_click_back_button(self, event):
181 # Removes the widget from the manager.
182 # After this the manager will respond to its events like it previously did.
183 self.parent.remove(self)
184
185
186def main():
187 window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, resizable=True)
188 main_view = MainView()
189 window.show_view(main_view)
190 arcade.run()
191
192
193if __name__ == "__main__":
194 main()