ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/ns_dev/Python/NinoCode/Active_prgs/MClock/mclock.py
Revision: 8
Committed: Sat May 5 04:21:19 2012 UTC (13 years, 10 months ago) by ninoborges
Content type: text/x-python
File size: 8663 byte(s)
Log Message:
Initial Import

File Contents

# User Rev Content
1 ninoborges 8 #!/usr/bin/env python
2    
3     """M CLOCK 2.0."""
4    
5     from __future__ import division
6    
7     import sys
8     import time
9     import math
10     import Tkinter
11    
12     class MClock:
13    
14     def __init__(self, radius=200, segments=9):
15     self.segments = segments
16     self.root = Tkinter.Tk()
17     self.root.wm_title("M Clock 2.0")
18     self.canvas = Tkinter.Canvas(self.root,
19     width=2*radius, height=2*radius,
20     bg="black", highlightthickness=0)
21     self.canvas.pack(expand=True, fill="both")
22     self.canvas.bind("<Configure>", self.on_configure)
23     self.canvas.bind("<ButtonPress-1>", self.on_press)
24     self.canvas.bind("<B1-Motion>", self.on_motion)
25     self.canvas.bind("<ButtonRelease-1>", self.on_release)
26     if sys.platform == "win32":
27     self.canvas.bind("<3>", self.on_zoom)
28     self.credits += "\n(right button toggles full screen mode)"
29     self.recalc(radius*2, radius*2)
30    
31     def on_configure(self, event):
32     self.recalc(event.width, event.height)
33    
34     credits = ("M Clock 2.0\n"
35     "by Guido van Rossum\n"
36     "after a design by Rob Juda")
37    
38     creditid = None
39     showtext = False
40    
41     def on_press(self, event):
42     self.creditid = self.canvas.create_text(
43     self.canvas.canvasx(event.x),
44     self.canvas.canvasy(event.y),
45     anchor="s", text=self.credits,
46     font="Helvetica 16 bold", justify="center")
47     self.showtext = not self.showtext
48    
49     def on_motion(self, event):
50     creditid = self.creditid
51     if creditid:
52     oldx, oldy = self.canvas.coords(creditid)
53     self.canvas.move(creditid,
54     self.canvas.canvasx(event.x) - oldx,
55     self.canvas.canvasy(event.y) - oldy)
56    
57     def on_release(self, event):
58     creditid = self.creditid
59     if creditid:
60     self.creditid = None
61     self.canvas.delete(creditid)
62    
63     def on_zoom(self, event):
64     if self.root.wm_overrideredirect():
65     self.root.wm_overrideredirect(False)
66     self.root.wm_state("normal")
67     self.root.wm_geometry("400x400")
68     else:
69     self.root.wm_overrideredirect(True)
70     self.root.wm_state("zoomed")
71    
72     def recalc(self, width, height):
73     radius = min(width, height) // 2
74     self.width = width
75     self.height = height
76     self.radius = radius
77     self.bigsize = radius * .975
78     self.litsize = radius * .67
79     self.canvas.configure(scrollregion=(-width//2, -height//2,
80     width//2, height//2))
81    
82     def demo(self, speed=1, colors=(0, 1, 2), segments=None):
83     if segments is not None:
84     self.segments = segments
85     if self.creditid:
86     text = "N=%s\nv=%s\n%s" % (self.segments, speed, list(colors))
87     self.canvas.itemconfigure(self.creditid, text=text)
88     hh, mm, ss = time.localtime()[3:6]
89     self.showtext = False
90     while not self.showtext:
91     try:
92     self.draw(hh, mm, ss, colors)
93     except Tkinter.TclError:
94     break
95     self.root.update()
96     ss += speed
97     mm, ss = divmod(mm*60 + ss, 60)
98     hh, mm = divmod(hh*60 + mm, 60)
99     hh %= 24
100    
101     def run(self):
102     self.redraw()
103     self.root.mainloop()
104    
105     def redraw(self):
106     t = time.time()
107     hh, mm, ss = time.localtime(t)[3:6]
108     self.draw(hh, mm, ss)
109     self.root.after(int(1000 * (1 - t%1.0)), self.redraw)
110    
111     ids = ()
112    
113     def draw(self, hh, mm, ss, colors=(0, 1, 2)):
114     radius = self.radius
115     bigsize = self.bigsize
116     litsize = self.litsize
117     # Delete old items
118     if self.ids:
119     self.canvas.delete(*self.ids)
120     self.ids = []
121     # Set bigd, litd to angles in degrees for big, little hands
122     # 12 => 90, 3 => 0, etc.
123     bigd = (90 - (mm*60 + ss) / 10) % 360
124     litd = (90 - (hh*3600 + mm*60 + ss) / 120) % 360
125     # Set bigr, litr to the same values in radians
126     bigr = bigd * math.pi / 180
127     litr = litd * math.pi / 180
128     # Draw the background colored arcs
129     self.drawbg(bigd, litd, colors)
130     # Draw the hands
131     b = self.canvas.create_line(0, 0,
132     bigsize*math.cos(bigr),
133     -bigsize*math.sin(bigr),
134     width=radius/50, capstyle="round")
135     l = self.canvas.create_line(0, 0,
136     litsize*math.cos(litr),
137     -litsize*math.sin(litr),
138     width=radius/33, capstyle="round")
139     self.ids.append(b)
140     self.ids.append(l)
141     # Draw the text
142     if self.showtext:
143     t = self.canvas.create_text(-bigsize, bigsize,
144     text="%02d:%02d:%02d" % (hh, mm, ss),
145     fill="white", anchor="sw",
146     font="helvetica 16 bold")
147     self.ids.append(t)
148     if self.creditid:
149     self.canvas.tag_raise(self.creditid)
150    
151     def drawbg(self, bigd, litd, colors=(0, 1, 2)):
152     # This is tricky. We have to simulate a white background with
153     # three transparent discs in front of it; one disc is
154     # stationary and the other two are attached to the big and
155     # little hands, respectively. Each disc has 9 pie segments in
156     # sucessive shades of pigment applied to it, ranging from
157     # fully transparent to only allowing one of the three colors
158     # Cyan, Magenta, Yellow through.
159     N = self.segments
160     table = []
161     for angle, colorindex in [(bigd - 180/N, 0),
162     (litd - 180/N, 1),
163     ( 90 - 180/N, 2)]:
164     angle %= 360
165     for i in range(N):
166     color = 255
167     if colorindex in colors:
168     color = (N-1-i)*color//(N-1)
169     table.append((angle, color, colorindex))
170     angle += 360/N
171     if angle >= 360:
172     angle -= 360
173     table.append((0, color, colorindex))
174     table.sort()
175     table.append((360, None))
176     radius = self.radius
177     fill = [0, 0, 0]
178     for i, (angle, color, colorindex) in enumerate(table[:-1]):
179     fill[colorindex] = color
180     if table[i+1][0] > angle:
181     extent = table[i+1][0] - angle
182     if extent < 1.:
183     # XXX Work around a bug in Tk for very small angles
184     extent = 1.
185     id = self.canvas.create_arc(-radius, -radius, radius, radius,
186     fill="#%02x%02x%02x" % tuple(fill),
187     outline="",
188     start=angle,
189     extent=extent)
190     self.ids.append(id)
191    
192     def main():
193     MClock().run()
194    
195     def demo():
196     mc = MClock()
197     save_credits = mc.credits
198     mc.credits = ""
199     mc.demo(0, ())
200     mc.demo(1, ())
201     mc.demo(10, ())
202     mc.demo(100, ())
203     mc.demo(1000, ())
204     mc.demo(0, (2,))
205     mc.demo(10, (2,))
206     mc.demo(0, (1,))
207     mc.demo(10, (1,))
208     mc.demo(0, (0,))
209     mc.demo(10, (0,))
210     mc.demo(0, (0, 1, 2,))
211     mc.demo(1, (0, 1, 2,))
212     mc.demo(10, (0, 1, 2,))
213     mc.demo(100, (0, 1, 2,))
214     mc.demo(0, (0, 1, 2,), 2)
215     mc.demo(1, (0, 1, 2,))
216     mc.demo(10, (0, 1, 2,))
217     mc.demo(0, (0, 1, 2,), 3)
218     mc.demo(1, (0, 1, 2,))
219     mc.demo(10, (0, 1, 2,))
220     mc.demo(0, (0, 1, 2,), 4)
221     mc.demo(1, (0, 1, 2,))
222     mc.demo(10, (0, 1, 2,))
223     mc.demo(0, (0, 1, 2,), 5)
224     mc.demo(1, (0, 1, 2,))
225     mc.demo(10, (0, 1, 2,))
226     mc.demo(0, (0, 1, 2,), 6)
227     mc.demo(1, (0, 1, 2,))
228     mc.demo(10, (0, 1, 2,))
229     mc.demo(0, (0, 1, 2,), 32)
230     mc.demo(1, (0, 1, 2,))
231     mc.demo(10, (0, 1, 2,))
232     mc.demo(0, (0, 1, 2,), 128)
233     mc.demo(1, (0, 1, 2,))
234     mc.demo(10, (0, 1, 2,))
235     mc.demo(0, (0, 1, 2,), 9) # Reset
236     mc.credits = save_credits
237     mc.run()
238    
239    
240     if __name__ == "__main__":
241     if "-d" in sys.argv[1:] or "demo" in sys.argv[0]:
242     demo()
243     else:
244     main()