Skip to content

Commit 0e3de2a

Browse files
Tutorial for Menu (#1608)
* Open a Window * Switching to Menu View * Setting Up the Menu View * Configuring the Menu Buttons * Finalising the Sub Menu
1 parent 61565a0 commit 0e3de2a

25 files changed

+1111
-0
lines changed
159 Bytes
Loading
870 Bytes
Loading
648 Bytes
Loading

doc/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ The Python Arcade Library
6262
tutorials/compiling_with_nuitka/index
6363
tutorials/framebuffer/index
6464
tutorials/shader_tutorials
65+
tutorials/menu/index
6566

6667
.. image:: images/example_games.svg
6768
:alt: Programming guide icon

doc/tutorials/menu/index.rst

Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
.. include:: <isonum.txt>
2+
3+
.. _menu_tutorial:
4+
5+
6+
Making a Menu with Arcade's GUI
7+
===============================
8+
9+
.. image:: menu.gif
10+
:width: 80%
11+
12+
This tutorial shows how to use most of arcade's gui's widgets.
13+
14+
Step 1: Open a Window
15+
---------------------
16+
17+
.. image:: menu_01.png
18+
:width: 50%
19+
20+
First, let's start a blank window with a view.
21+
22+
.. literalinclude:: menu_01.py
23+
:caption: Opening a Window
24+
:linenos:
25+
26+
Step 2: Switching to Menu View
27+
-------------------------------
28+
29+
.. image:: menu_02.png
30+
:width: 50%
31+
32+
For this section we will switch the current view of the window to the menu view.
33+
34+
35+
Imports
36+
~~~~~~~
37+
38+
First we will import the arcade gui:
39+
40+
.. literalinclude:: menu_02.py
41+
:caption: Importing arcade.gui
42+
:lines: 4-5
43+
:emphasize-lines: 2
44+
45+
Modify the MainView
46+
~~~~~~~~~~~~~~~~~~~~
47+
48+
We are going to add a button to change the view. For drawing a button we would
49+
need a ``UIManager``.
50+
51+
.. literalinclude:: menu_02.py
52+
:caption: Intialising the Manager
53+
:lines: 16-19
54+
:emphasize-lines: 4
55+
56+
After initialising the manager we need to enable it when the view is shown and
57+
disable it when the view is hiddien.
58+
59+
.. literalinclude:: menu_02.py
60+
:caption: Enabling the Manager
61+
:pyobject: MainView.on_show_view
62+
:emphasize-lines: 5-6
63+
64+
.. literalinclude:: menu_02.py
65+
:caption: Disabling the Manager
66+
:pyobject: MainView.on_hide_view
67+
68+
We also need to draw the childrens of the menu in ``on_draw``.
69+
70+
.. literalinclude:: menu_02.py
71+
:caption: Drawing Children's of the Manager
72+
:pyobject: MainView.on_draw
73+
:emphasize-lines: 6-7
74+
75+
Now we have successfully setup the manager, only thing left it to add the button.
76+
We are using ``UIAnchorLayout`` to position the button. We also setup a function
77+
which is called when the button is clicked.
78+
79+
.. literalinclude:: menu_02.py
80+
:caption: Initialising the Button
81+
:lines: 21-37
82+
83+
Initialise the Menu View
84+
~~~~~~~~~~~~~~~~~~~~~~~~
85+
86+
We make a boiler plate view just like we did in Step-1 for switiching the view
87+
when the pause button is clicked.
88+
89+
.. literalinclude:: menu_02.py
90+
:caption: Initialise the Menu View
91+
:pyobject: MenuView
92+
93+
Program Listings
94+
~~~~~~~~~~~~~~~~
95+
96+
* :ref:`menu_02` |larr| Where we are right now
97+
* :ref:`menu_02_diff` |larr| What we changed to get here
98+
99+
100+
Step 3: Setting Up the Menu View
101+
--------------------------------
102+
103+
.. image:: menu_03.png
104+
:width: 50%
105+
106+
In this step we will setup the display buttons of the actual menu. The code
107+
written in this section is written for ``MenuView``
108+
109+
Initialising the Buttons
110+
~~~~~~~~~~~~~~~~~~~~~~~~
111+
112+
First we setup buttons for resume, starting a new game, volume, options and exit.
113+
114+
.. literalinclude:: menu_03.py
115+
:caption: Initialising the Buttons
116+
:lines: 67-72
117+
118+
Displaying the Buttons in a Grid
119+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120+
121+
After setting up the buttons we add them to ``UIGridLayout``, so that they can
122+
displayed in a grid like manner.
123+
124+
.. literalinclude:: menu_03.py
125+
:caption: Setting up the Grid
126+
:lines: 74-90
127+
128+
Final code for the ``__init__`` method after these.
129+
130+
.. literalinclude:: menu_03.py
131+
:caption: __init__
132+
:pyobject: MenuView.__init__
133+
134+
Program Listings
135+
~~~~~~~~~~~~~~~~
136+
137+
* :ref:`menu_03` |larr| Where we are right now
138+
* :ref:`menu_03_diff` |larr| What we changed to get here
139+
140+
141+
Step 4: Configuring the Menu Buttons
142+
------------------------------------
143+
144+
.. image:: menu_04.png
145+
:width: 50%
146+
147+
We basically add event listener for ``on_click`` for buttons.
148+
149+
Adding ``on_click`` Callback for Resume, Start New Game and Exit
150+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
151+
152+
First we will add the event listener to resume, start_new_game and exit button
153+
as they don't have much to explain.
154+
155+
.. literalinclude:: menu_04.py
156+
:caption: Adding callback for button events 1
157+
:lines: 94-107
158+
159+
Adding ``on_click`` Callback for Volume and Options
160+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
161+
162+
Now we need to implement an actual menu for volume and options, for that we have
163+
to make a class that acts like a window. Using ``UIMouseFilterMixin`` we catch
164+
all the events happening for the parent and respond nothing to them. Thus
165+
making it act like a window/view.
166+
167+
.. literalinclude:: menu_04.py
168+
:caption: Making a Fake Window.
169+
:pyobject: SubMenu
170+
171+
We have got ourselves a fake window currently. We now, pair it up with the
172+
volume and options button to trigger it when they are clicked.
173+
174+
.. literalinclude:: menu_04.py
175+
:caption: Adding callback for button events 2
176+
:lines: 109-123
177+
178+
Program Listings
179+
~~~~~~~~~~~~~~~~
180+
181+
* :ref:`menu_04` |larr| Where we are right now
182+
* :ref:`menu_04_diff` |larr| What we changed to get here
183+
184+
Step 5: Finalising the Fake Window aka the Sub Menu
185+
---------------------------------------------------
186+
187+
.. image:: menu_05.png
188+
:width: 50%
189+
190+
We finalise the menu or you can call it the last step!
191+
192+
Editing the Parameters for the Sub Menu
193+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
194+
195+
We will edit the parameters for the sub menu to suit our needs. Will explain
196+
later why are those parameters needed.
197+
198+
.. literalinclude:: menu_05.py
199+
:caption: Editing parameters
200+
:lines: 153-156
201+
202+
We also need to change accordingly the places where we have used this class i.e
203+
options and volume ``on_click`` event listener. The layer parameter being set
204+
1, means that this layer is always drawn on top i.e its the first layer.
205+
206+
.. literalinclude:: menu_05.py
207+
:caption: Editing arguments
208+
:lines: 109-131
209+
210+
Now you might be getting a little idea why we have edited the parameters but
211+
follow on to actually know the reason.
212+
213+
214+
Adding a Title label
215+
--------------------
216+
217+
We will be adding a ``UILabel`` that explains the menu. ``UISpace`` is a widget
218+
that can be used to add space around some widget, you can set its color to the
219+
background color so it appears invisible.
220+
221+
.. literalinclude:: menu_05.py
222+
:caption: Adding title label
223+
:lines: 179-181
224+
225+
Adding it to the widget layout.
226+
227+
.. literalinclude:: menu_05.py
228+
:caption: Adding title label to the layout
229+
:lines: 213-215
230+
231+
232+
Adding a Input Field
233+
~~~~~~~~~~~~~~~~~~~~~
234+
235+
We will use ``UIInputText`` to add an input field. The ``with_border()``
236+
function creates a border around the widget with color(default argument is
237+
black) black and thickness(default argument is 2px) 2px. Add this just below
238+
the title label.
239+
240+
.. literalinclude:: menu_05.py
241+
:caption: Adding input field
242+
:lines: 183
243+
244+
Adding it to the widget layout.
245+
246+
.. literalinclude:: menu_05.py
247+
:caption: Adding input field to the layout
248+
:lines: 213-216
249+
:emphasize-lines: 4
250+
251+
If you paid attention when we defined the ``input_text`` variable we passed the
252+
``text`` parameter with our ``input_text_default`` argument. We basically added
253+
those parameters in our sub menu so that it can be used by both volume and
254+
options button, with texts respecting their names. We will repeat this again
255+
in the last also for those of you who are skipping through this section :P.
256+
257+
Adding a Toggle Button
258+
~~~~~~~~~~~~~~~~~~~~~~
259+
260+
Don't go on the section title much, in arcade the ``UITextureToggle`` is not
261+
really a button it switches between two textures when clicked. Yes, it
262+
functions like a button but by "is not really a button" we meant that it
263+
doesn't inherits the button class. We also pair it up horizontally with the
264+
toggle label.
265+
266+
.. literalinclude:: menu_05.py
267+
:caption: Adding toggle button
268+
:lines: 189-201
269+
270+
Adding it to the widget layout. Add this line after you have added the input
271+
field.
272+
273+
.. literalinclude:: menu_05.py
274+
:caption: Adding toggle button to the layout
275+
:lines: 217
276+
277+
Adding a Dropdowm
278+
~~~~~~~~~~~~~~~~~
279+
280+
We add a dropdowm by using ``UIDropdown``.
281+
282+
.. literalinclude:: menu_05.py
283+
:caption: Adding dropdown
284+
:lines: 203-204
285+
286+
Adding it to the widget layout.
287+
288+
.. literalinclude:: menu_05.py
289+
:caption: Adding dropdown to the layout
290+
:lines: 218
291+
292+
Adding a Slider
293+
~~~~~~~~~~~~~~~
294+
295+
The final widget. In arcade you can use ``UISlider`` to implement a slider.
296+
Theres a functionality to style the slider, this is also present for
297+
``UIFlatButton`` and ``UITextureButton``.
298+
299+
.. literalinclude:: menu_05.py
300+
:caption: Adding slider
301+
:lines: 206-207
302+
303+
Adding it to the widget layout.
304+
305+
.. literalinclude:: menu_05.py
306+
:caption: Adding slider to the layout
307+
:lines: 219-220
308+
309+
Finishing touches
310+
~~~~~~~~~~~~~~~~~
311+
312+
As we mentioned earlier, to explain the use of those parameters to the class.
313+
We basically used them so it can be used by both options and volume as we
314+
wanted to have different text for both.
315+
For those who have read the full tutorial line-by-line;
316+
'They will never know'. :D.
317+
We also recommend to see the full code for this section.
318+
319+
320+
Program Listings
321+
~~~~~~~~~~~~~~~~
322+
323+
* :ref:`menu_05` |larr| Where we are right now
324+
* :ref:`menu_05_diff` |larr| What we changed to get here

doc/tutorials/menu/menu.gif

57.5 KB
Loading

doc/tutorials/menu/menu_01.png

5.33 KB
Loading

doc/tutorials/menu/menu_01.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
Menu.
3+
4+
Shows the usage of almost every gui widget, switching views and making a modal.
5+
"""
6+
import arcade
7+
8+
# Screen title and size
9+
SCREEN_WIDTH = 800
10+
SCREEN_HEIGHT = 600
11+
SCREEN_TITLE = "Making a Menu"
12+
13+
14+
class MainView(arcade.View):
15+
""" Main application class."""
16+
17+
def __init__(self):
18+
super().__init__()
19+
20+
def on_show_view(self):
21+
""" This is run once when we switch to this view """
22+
arcade.set_background_color(arcade.color.DARK_BLUE_GRAY)
23+
24+
def on_draw(self):
25+
""" Render the screen. """
26+
# Clear the screen
27+
self.clear()
28+
29+
30+
def main():
31+
window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, resizable=True)
32+
main_view = MainView()
33+
window.show_view(main_view)
34+
arcade.run()
35+
36+
37+
if __name__ == "__main__":
38+
main()

doc/tutorials/menu/menu_01.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
:orphan:
2+
3+
.. _menu_01:
4+
5+
menu_01.py Full Listing
6+
-------------------------------------
7+
8+
.. literalinclude:: menu_01.py
9+
:caption: menu_01.py
10+
:linenos:

doc/tutorials/menu/menu_02.png

6.46 KB
Loading

0 commit comments

Comments
 (0)