Merge branch 'master' of git.ucc.asn.au:/matches/honours
[matches/honours.git] / research / transmission_spectroscopy / simulator / pgu-0.18 / examples / gui18.py
1 #!/usr/bin/env python
2
3 # This is not needed if you have PGU installed
4 import sys
5 sys.path.insert(0, "..")
6
7 import math
8 import time
9 import pygame
10 import pgu
11 from pgu import gui, timer
12
13
14 class DrawingArea(gui.Widget):
15     def __init__(this, width, height):
16         gui.Widget.__init__(this, width=width, height=height)
17         this.imageBuffer = pygame.Surface((width, height))
18
19     def paint(this, surf):
20         # Paint whatever has been captured in the buffer
21         surf.blit(this.imageBuffer, (0, 0))
22
23     # Call this function to take a snapshot of whatever has been rendered
24     # onto the display over this widget.
25     def save_background(this):
26         disp = pygame.display.get_surface()
27         this.imageBuffer.blit(disp, this.get_abs_rect())
28
29 class TestDialog(gui.Dialog):
30     def __init__(this):
31         title = gui.Label("Some Dialog Box")
32         label = gui.Label("Close this window to resume.")
33         gui.Dialog.__init__(this, title, label)
34
35 class MainGui(gui.Desktop):
36     gameAreaHeight = 500
37     gameArea = None
38     menuArea = None
39     # The game engine
40     engine = None
41
42     def __init__(this, disp):
43         gui.Desktop.__init__(this)
44
45         # Setup the 'game' area where the action takes place
46         this.gameArea = DrawingArea(disp.get_width(),
47                                     this.gameAreaHeight)
48         # Setup the gui area
49         this.menuArea = gui.Container(
50             height=disp.get_height()-this.gameAreaHeight)
51
52         tbl = gui.Table(height=disp.get_height())
53         tbl.tr()
54         tbl.td(this.gameArea)
55         tbl.tr()
56         tbl.td(this.menuArea)
57
58         this.setup_menu()
59
60         this.init(tbl, disp)
61
62     def setup_menu(this):
63         tbl = gui.Table(vpadding=5, hpadding=2)
64         tbl.tr()
65
66         dlg = TestDialog()
67
68         def dialog_cb():
69             dlg.open()
70
71         btn = gui.Button("Modal dialog", height=50)
72         btn.connect(gui.CLICK, dialog_cb)
73         tbl.td(btn)
74
75         # Add a button for pausing / resuming the game clock
76         def pause_cb():
77             if (this.engine.clock.paused):
78                 this.engine.resume()
79             else:
80                 this.engine.pause()
81
82         btn = gui.Button("Pause/resume clock", height=50)
83         btn.connect(gui.CLICK, pause_cb)
84         tbl.td(btn)
85
86         # Add a slider for adjusting the game clock speed
87         tbl2 = gui.Table()
88
89         timeLabel = gui.Label("Clock speed")
90
91         tbl2.tr()
92         tbl2.td(timeLabel)
93
94         slider = gui.HSlider(value=23,min=0,max=100,size=20,height=16,width=120)
95
96         def update_speed():
97             this.engine.clock.set_speed(slider.value/10.0)
98
99         slider.connect(gui.CHANGE, update_speed)
100
101         tbl2.tr()
102         tbl2.td(slider)
103
104         tbl.td(tbl2)
105
106         this.menuArea.add(tbl, 0, 0)
107
108     def open(this, dlg, pos=None):
109         # Gray out the game area before showing the popup
110         rect = this.gameArea.get_abs_rect()
111         dark = pygame.Surface(rect.size).convert_alpha()
112         dark.fill((0,0,0,150))
113         pygame.display.get_surface().blit(dark, rect)
114         # Save whatever has been rendered to the 'game area' so we can
115         # render it as a static image while the dialog is open.
116         this.gameArea.save_background()
117         # Pause the gameplay while the dialog is visible
118         running = not(this.engine.clock.paused)
119         this.engine.pause()
120         gui.Desktop.open(this, dlg, pos)
121         while (dlg.is_open()):
122             for ev in pygame.event.get():
123                 this.event(ev)
124             rects = this.update()
125             if (rects):
126                 pygame.display.update(rects)
127         if (running):
128             # Resume gameplay
129             this.engine.resume()
130
131     def get_render_area(this):
132         return this.gameArea.get_abs_rect()
133
134
135 class GameEngine(object):
136     def __init__(this, disp):
137         this.disp = disp
138         this.square = pygame.Surface((400,400)).convert_alpha()
139         this.square.fill((255,0,0))
140         this.app = MainGui(this.disp)
141         this.app.engine = this
142
143     # Pause the game clock
144     def pause(this):
145         this.clock.pause()
146
147     # Resume the game clock
148     def resume(this):
149         this.clock.resume()
150
151     def render(this, dest, rect):
152         # Draw a rotating square
153         angle = this.clock.get_time()*10
154         surf = pygame.transform.rotozoom(this.square, angle, 1)
155         r = surf.get_rect()
156         r.center = rect.center
157         dest.fill((0,0,0), rect)
158         this.disp.blit(surf, r)
159
160         def draw_clock(name, pt, radius, col, angle):
161             pygame.draw.circle(dest, col, pt, radius)
162             pygame.draw.line(dest, (0,0,0), pt, 
163                              (pt[0]+radius*math.cos(angle),
164                               pt[1]+radius*math.sin(angle)), 2)
165             tmp = this.font.render(name, True, (255,255,255))
166             dest.blit(tmp, (pt[0]-radius, pt[1]+radius+5))
167
168         # Draw the real time clock
169         angle = this.clock.get_real_time()*2*math.pi/10.0
170         draw_clock("Real time", (30,30), 25, (255,200,100), angle)
171
172         # Now draw the game clock
173         angle = this.clock.get_time()*2*math.pi/10.0
174         draw_clock("Game time", (90,30), 25, (255,100,255), angle)
175
176         return (rect,)
177
178     def run(this):
179         this.app.update()
180         pygame.display.flip()
181
182         this.font = pygame.font.SysFont("", 16)
183
184         this.clock = timer.Clock() #pygame.time.Clock()
185         done = False
186         while not done:
187             # Process events
188             for ev in pygame.event.get():
189                 if (ev.type == pygame.QUIT or 
190                     ev.type == pygame.KEYDOWN and ev.key == pygame.K_ESCAPE):
191                     done = True
192                 else:
193                     # Pass the event off to pgu
194                     this.app.event(ev)
195             # Render the game
196             rect = this.app.get_render_area()
197             updates = []
198             this.disp.set_clip(rect)
199             lst = this.render(this.disp, rect)
200             if (lst):
201                 updates += lst
202             this.disp.set_clip()
203
204             # Cap it at 30fps
205             this.clock.tick(30)
206
207             # Give pgu a chance to update the display
208             lst = this.app.update()
209             if (lst):
210                 updates += lst
211             pygame.display.update(updates)
212             pygame.time.wait(10)
213
214
215 ###
216 disp = pygame.display.set_mode((800, 600))
217 eng = GameEngine(disp)
218 eng.run()
219

UCC git Repository :: git.ucc.asn.au