041c0fb258446957dcf1f870286260acd318d4fd
[minwii.git] / src / app / widgets / cursors.py
1 # -*- coding: utf-8 -*-
2 """
3 Curseurs winwii
4
5 $Id$
6 $URL$
7 """
8
9 import pygame
10 import os
11 from eventutils import EventHandlerMixin, event_handler
12 from events import TIMEOUT
13 from itertools import cycle
14
15 class WarpingCursor(pygame.sprite.DirtySprite, EventHandlerMixin):
16 '''
17 The class for animating the warping cursor
18 '''
19
20 @staticmethod
21 def _get_theme_images(name) :
22 basePath = os.path.abspath(__file__).split(os.path.sep)[:-1]
23 basePath.append('data')
24 basePath.append(name)
25 basePath = os.path.sep.join(basePath)
26 images = [f for f in os.listdir(basePath) if os.path.splitext(f)[1] == '.png']
27 return basePath, images
28
29
30 def __init__(self, theme='black', duration=50, blinkMode=True):
31 pygame.sprite.DirtySprite.__init__(self)
32 imagesPath, images = WarpingCursor._get_theme_images(theme)
33 flashImage = images.pop(images.index('flash.png'))
34 flashImagePath = os.path.sep.join([imagesPath, flashImage])
35 self.flashImage = pygame.image.load(flashImagePath).convert_alpha()
36 images.sort(lambda a, b : cmp(*[int(os.path.splitext(f)[0]) for f in [a, b]]))
37
38 self.images = []
39 for img in images :
40 imagePath = os.path.sep.join([imagesPath, img])
41 img = pygame.image.load(imagePath).convert_alpha()
42 self.images.append(img)
43
44 # assumes that all images have same dimensions
45 self.width = self.images[0].get_width()
46 self.height = self.images[0].get_height()
47 self.duration = duration
48
49 self.image = self.images[0]
50 # workarround cursor alignement problem
51 pygame.event.set_blocked(pygame.MOUSEMOTION)
52 pygame.mouse.set_pos(pygame.mouse.get_pos())
53 pygame.event.set_allowed(pygame.MOUSEMOTION)
54 # ---
55 x, y = pygame.mouse.get_pos()
56 left = x - self.width / 2
57 top = y - self.height / 2
58 self.rect = pygame.Rect((left, top), (self.width, self.height))
59
60 self.blinkMode = blinkMode
61 self._startBlink()
62
63 def _startBlink(self) :
64 if self.blinkMode :
65 self._blinking = True
66 pygame.time.set_timer(TIMEOUT, self.duration)
67 self.iterator = self.iterImages()
68
69 def _stopBlink(self) :
70 if self.blinkMode :
71 pygame.time.set_timer(TIMEOUT, 0)
72
73 def iterImages(self) :
74 for img in cycle(self.images) :
75 yield img
76
77 @event_handler(TIMEOUT)
78 def loadNext(self, event) :
79 if self._blinking :
80 self.dirty = 1
81 self.image = self.iterator.next()
82
83 @event_handler(pygame.MOUSEBUTTONDOWN)
84 def flashOn(self, event) :
85 self.dirty = 1
86 self._blinking = False
87 self.image = self.flashImage
88
89 @event_handler(pygame.MOUSEBUTTONUP)
90 def flashOff(self, event) :
91 self.dirty = 1
92 if self.blinkMode :
93 self._blinking = True
94 self.loadNext(event)
95 else :
96 self.image = self.images[0]
97
98 @event_handler(pygame.MOUSEMOTION)
99 def move(self, event) :
100 self.dirty = 1
101 self.rect.move_ip(event.rel)