1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
""" The base class for moveable shapes. """
# Standard library imports.
import math
# Enthought library imports.
from enable.colors import ColorTrait
from enable.component import Component
from enable.enable_traits import Pointer
from kiva.constants import MODERN
from kiva.fonttools import Font
from traits.api import Float, Property, Str, Tuple
class Shape(Component):
""" The base class for moveable shapes. """
#### 'Component' interface ################################################
# The background color of this component.
bgcolor = 'transparent'
#### 'Shape' interface ####################################################
# The coordinates of the center of the shape.
center = Property(Tuple)
# The fill color.
fill_color = ColorTrait
# The pointer for the 'normal' event state.
normal_pointer = Pointer('arrow')
# The pointer for the 'moving' event state.
moving_pointer = Pointer('hand')
# The text color.
text_color = ColorTrait
# The text displayed in the shape.
text = Str
#### 'Private' interface ##################################################
# The difference between the location of a mouse-click and the component's
# origin.
_offset_x = Float
_offset_y = Float
###########################################################################
# 'Interactor' interface
###########################################################################
def normal_key_pressed(self, event):
""" Event handler. """
print 'normal_key_pressed', event.character
return
def normal_left_down(self, event):
""" Event handler. """
if self.is_in(event.x, event.y):
self.event_state = 'moving'
event.window.mouse_owner = self
event.window.set_pointer(self.moving_pointer)
self._offset_x = event.x - self.x
self._offset_y = event.y - self.y
# move this shape to the top of the z order. The components are
# drawn in order, so the last one will be drawn on top
siblings = self.container.components
if len(siblings) > 1:
siblings.remove(self)
siblings.append(self)
return
def moving_mouse_move(self, event):
""" Event handler. """
top = event.y + self._offset_y
bottom = event.y - self._offset_y
left = event.x - self._offset_x
right = event.x + self._offset_x
# Keep the shape fully in the container
if bottom < 0:
bottom = 0
elif top > self.container.height:
bottom = self.container.height - self.height
if left < 0:
left = 0
elif right > self.container.width:
left = self.container.width - self.width
self.position = [left, bottom]
self.request_redraw()
return
def moving_left_up(self, event):
""" Event handler. """
self.event_state = 'normal'
event.window.set_pointer(self.normal_pointer)
event.window.mouse_owner = None
self.request_redraw()
return
def moving_mouse_leave(self, event):
""" Event handler. """
self.moving_left_up(event)
return
###########################################################################
# 'Shape' interface
###########################################################################
def _get_center(self):
""" Property getter. """
dx, dy = self.bounds
ox, oy = self.position
cx = ox + dx/2
cy = oy + dy/2
return cx, cy
def _text_default(self):
""" Trait initializer. """
return type(self).__name__
###########################################################################
# Protected 'Shape' interface
###########################################################################
def _distance_between(self, (x1, y1), (x2, y2)):
""" Return the distance between two points. """
return math.sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2))
def _draw_text(self, gc):
""" Draw the shape's text. """
if len(self.text) > 0:
gc.set_fill_color(self._get_text_color(self.event_state))
gc.set_font(Font(family=MODERN, size=16))
tx, ty, tw, th = gc.get_text_extent(self.text)
dx, dy = self.bounds
x, y = self.position
gc.set_text_position(x+(dx-tw)/2, y+(dy-th)/2)
gc.show_text(self.text)
return
def _get_fill_color(self, event_state):
""" Return the fill color based on the event state. """
if event_state == 'normal':
fill_color = self.fill_color_
else:
r, g, b, a = self.fill_color_
fill_color = (r, g, b, 0.5)
return fill_color
def _get_text_color(self, event_state):
""" Return the text color based on the event state. """
if event_state == 'normal':
text_color = self.text_color_
else:
r, g, b, a = self.text_color_
text_color = (r, g, b, 0.5)
return text_color
#### EOF ######################################################################
|