1: from System.Windows import Application
2: from System.Windows.Controls import UserControl
3: from System.Windows.Controls import TextBlock
4: from System.Windows.Controls import Canvas
5: from System.Windows.Media import Colors
6: from System.Windows.Media import SolidColorBrush
7: from System.Windows import Visibility
8: from System.Windows import FontWeights
9: from System.Windows import HorizontalAlignment
10: from System.Windows.Media.Animation import Storyboard
11: from System import Random;
12: import math
13:
14: class App:
15: def __init__(self):
16: self.root = Application.Current.LoadRootVisual(UserControl(), "app.xaml");
17: spinner = Spinner(self.root,['Tarn','Leah','Alex','Mick','John','Rex','Jack','Jill','Elle']);
18:
19:
20: class Spinner():
21: def __init__(self, root, names):
22: self.root = root;
23: self.names = names
24: self.radius = 0;
25: self.textBlocks = [];
26: self.mainText = Block(self.root.layout_root,self.centreClick);
27: self.mainText.SetPosition(100.0,100.0);
28: self.mainText.HorizontalAlignment = HorizontalAlignment.Center;
29: self.selectedItem = None;
30: self.angle = 0;
31: self.diff = 0;
32: self.target = 0;
33: self.drag = False;
34: self.createTextBlocks(self.names[0], self.names);
35: self.root.MouseLeftButtonDown += self.leftButtonDown;
36: self.root.MouseLeftButtonUp += self.leftButtonUp;
37: self.root.MouseMove += self.mouseMove;
38: self.sb = Storyboard();
39: self.root.Resources.Add("sb",self.sb); 40: self.sb.Completed += self.enterFrame;
41: self.sb.Begin();
42: def centreClick(self,item):
43: self.selectedItem = item;
44: self.state = "Selected";
45: pass;
46: def createTextBlocks(self, item, list):
47: self.state = "Expanding";
48: self.mainText.text.Opacity = 1;
49: self.mainText.text.Text = item;
50: self.velocity = 0.01;
51: for textBlock in self.textBlocks:
52: textBlock.dispose();
53: textBlocks = [];
54: i = 0;
55: list = filter(lambda m: (m != item), list)
56:
57: for title in list:
58: textBox = Block(self.root.layout_root,self.centreClick);
59: textBox.text.Text = title;
60: textBox.angle = i * 2 * math.pi / list.__len__();
61: textBox.HorizontalAlignment = HorizontalAlignment.Center;
62: textBox.radius = -(100/list.__len__()) * i;
63: textBox.SetPosition2(0);
64: self.textBlocks.append(textBox);
65: i += 1;
66: def enterFrame(self, object, e):
67: diff = ((self.target - self.diff)-self.angle) ;
68: if (self.drag == True):
69: oldAngle = self.angle;
70: if (diff > math.pi): diff = diff - math.pi * 2;
71: if (diff <= -math.pi): diff = diff + math.pi * 2;
72: self.angle = self.angle + ((diff) * 0.2);
73: self.velocity = self.angle - oldAngle;
74: else:
75: self.angle = self.angle + self.velocity;
76: if (math.fabs(self.velocity) > 0.01):
77: self.velocity = self.velocity * 0.90;
78: self.angle = self.angle % (2 * math.pi);
79:
80: if (self.state == "Expanding"):
81: expandComplete = True;
82: for textBlock in self.textBlocks:
83: if (textBlock.Expand(100) == False): expandComplete = False;
84: if (self.state == "Selected"):
85: expandComplete = True;
86: if (self.selectedItem != self.mainText):
87: self.mainText.text.Opacity -= 0.10;
88: self.selectedItem.moveTo(100,100);
89: for textBlock in self.textBlocks:
90: if (self.selectedItem != textBlock):
91: textBlock.text.Opacity -= 0.010;
92: if (textBlock.Expand(200) == False): expandComplete = False;
93: if (expandComplete == True):
94: self.createTextBlocks(self.selectedItem.text.Text, self.names);
95: for textBlock in self.textBlocks:
96: if (self.selectedItem != textBlock): textBlock.SetPosition2(self.angle);
97: self.sb.Begin();
98: def leftButtonUp(self,object,e):
99: self.root.ReleaseMouseCapture();
100: self.drag = False;
101: def mouseMove(self, object, e):
102: if (self.drag == True):
103: self.target = self.getAngle(e);
104: def leftButtonDown(self, object, e):
105: self.root.CaptureMouse();
106: angle = self.getAngle(e);
107: self.diff = angle - self.angle;
108: self.target = self.getAngle(e);
109: self.drag = True;
110: def getAngle(self, e):
111: x = e.GetPosition(self.root).X-100;
112: y = e.GetPosition(self.root).Y-100;
113: angle = (math.atan2(x,y));
114: if (angle < 0): angle = angle + (math.pi*2);
115: return angle;
116:
117: class Block():
118: def __init__(self, canvas, clicked):
119: self.clicked = clicked;
120: self.canvas = canvas;
121: self.text = TextBlock();
122: self.text.Foreground = SolidColorBrush(Colors.White);
123: self.offset = 100;
124: self.radius = 10;
125: self.angle = 0;
126: canvas.Children.Add(self.text);
127: self.text.MouseEnter += self.mouseOver;
128: self.text.MouseLeave += self.mouseOut;
129: self.text.MouseLeftButtonDown += self.mouseClick;
130: def dispose(self):
131: self.canvas.Children.Remove(self.text);
132: def moveTo(self, x, y):
133: self.text.FontWeight = FontWeights.Normal;
134: currentX = self.text.GetValue(Canvas.LeftProperty);
135: currentY = self.text.GetValue(Canvas.TopProperty);
136: newX = currentX + ( (x - currentX) * 0.1);
137: newY = currentY + ( (y - currentY) * 0.1);
138: self.SetPosition(newX,newY);
139: def Expand(self, max):
140: if (self.radius < max):
141: self.radius += 1;
142: return False;
143: def mouseClick(self,sender,e):
144: self.clicked(self);
145: def mouseOver(self,sender,e):
146: self.text.FontWeight = FontWeights.Bold;
147: def mouseOut(self,sender,e):
148: self.text.FontWeight = FontWeights.Normal;
149: def SetPosition(self, x, y):
150: self.text.SetValue(Canvas.LeftProperty, x);
151: self.text.SetValue(Canvas.TopProperty, y);
152: def SetPosition2(self, angle):
153: if (self.radius < 20):self.text.Visibility = Visibility.Collapsed;
154: else:self.text.Visibility=Visibility.Visible;
155: self.SetPosition( (math.sin(self.angle + angle) * self.radius) + self.offset, (math.cos(self.angle + angle) * self.radius) + self.offset);
156:
157:
158: App()