1 # -*- coding: utf-8 -*-
11 from threading
import Thread
13 from minwii
.eventutils
import EventHandlerMixin
, event_handler
14 from itertools
import cycle
16 class WarpingCursor(pygame
.sprite
.DirtySprite
, EventHandlerMixin
):
18 The class for animating the warping cursor
22 def _get_theme_images(name
) :
23 basePath
= os
.path
.abspath(__file__
).split(os
.path
.sep
)[:-1]
24 basePath
.extend(['data', 'cursor'])
26 basePath
= os
.path
.sep
.join(basePath
)
27 images
= [f
for f
in os
.listdir(basePath
) if os
.path
.splitext(f
)[1] == '.png']
28 return basePath
, images
31 def __init__(self
, theme
='black-perforated', duration
=100, blinkMode
=True):
32 pygame
.sprite
.DirtySprite
.__init
__(self
)
33 imagesPath
, images
= WarpingCursor
._get
_theme
_images
(theme
)
34 flashImage
= images
.pop(images
.index('flash.png'))
35 flashImagePath
= os
.path
.sep
.join([imagesPath
, flashImage
])
36 self
.flashImage
= pygame
.image
.load(flashImagePath
).convert_alpha()
37 images
.sort(lambda a
, b
: cmp(*[int(os
.path
.splitext(f
)[0]) for f
in [a
, b
]]))
41 imagePath
= os
.path
.sep
.join([imagesPath
, img
])
42 img
= pygame
.image
.load(imagePath
).convert_alpha()
43 self
.images
.append(img
)
45 # assumes that all images have same dimensions
46 self
.width
= self
.images
[0].get_width()
47 self
.height
= self
.images
[0].get_height()
48 self
.duration
= duration
50 self
.image
= self
.images
[0]
52 # workarround cursor alignement problem
53 pygame
.event
.set_blocked(pygame
.MOUSEMOTION
)
54 pygame
.mouse
.set_pos(pygame
.mouse
.get_pos())
55 pygame
.event
.set_allowed(pygame
.MOUSEMOTION
)
57 x
, y
= pygame
.mouse
.get_pos()
58 left
= x
- self
.width
/ 2
59 top
= y
- self
.height
/ 2
60 self
.rect
= pygame
.Rect((left
, top
), (self
.width
, self
.height
))
62 self
.blinkMode
= blinkMode
66 if hasattr(self
, 'timer') :
67 try : self
.timer
.stop()
70 def _startBlink(self
) :
73 self
.iterator
= self
.iterImages()
74 self
.timer
= ForeverTimer(self
.duration
, self
.loadNext
)
77 def _stopBlink(self
) :
81 def iterImages(self
) :
82 for img
in cycle(self
.images
) :
88 self
.image
= self
.iterator
.next()
90 @event_handler(pygame
.MOUSEBUTTONDOWN
)
91 def flashOn(self
, event
) :
93 self
._blinking
= False
94 self
.image
= self
.flashImage
97 @event_handler(pygame
.MOUSEBUTTONUP
)
98 def flashOff(self
, event
) :
101 self
._blinking
= True
103 self
.image
= self
.images
[0]
106 @event_handler(pygame
.MOUSEMOTION
)
107 def move(self
, event
) :
109 x
, y
= pygame
.mouse
.get_pos()
110 rel
= (x
- self
.rect
.centerx
, y
- self
.rect
.centery
)
111 self
.rect
.move_ip(rel
)
113 def setPosition(self
, pos
) :
116 rx
, ry
= self
.rect
.centerx
, self
.rect
.centery
117 self
.rect
.move_ip(x
-rx
, y
-ry
)
120 class ForeverTimer(Thread
) :
121 def __init__(self
, duration
, func
, *args
, **kw
) :
122 Thread
.__init
__(self
)
123 self
.duration
= duration
/ 1000.
131 self
.func(*self
.args
, **self
.kw
)
132 time
.sleep(self
.duration
)