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
|
# Enthought library imports
from traits.api import HasTraits, Property
# Local, relative imports
from enable_traits import bounds_trait, coordinate_trait
class CoordinateBox(HasTraits):
"""
Represents a box in screen space, and provides convenience properties to
access bounds and coordinates in a variety of ways.
Primary attributes (not properties):
position : [x, y]
bounds : [width, height]
Secondary attributes (properties):
x, y : coordinates of the lower-left pixel of the box
x2, y2 : coordinates of the upper-right pixel of the box
width : the number of horizontal pixels in the box; equal to x2-x+1
height : the number of vertical pixels in the box; equal to y2-y+1
Note that setting x and y will modify the position, but setting any of the
other secondary attributes will modify the bounds of the box.
"""
bounds = bounds_trait
# The position relative to the container. If container is None, then
# position will be set to (0,0).
position = coordinate_trait
x = Property
y = Property
x2 = Property
y2 = Property
width = Property
height = Property
def is_in(self, x, y):
"Returns if the point x,y is in the box"
p = self.position
b = self.bounds
dx = x - p[0]
dy = y - p[1]
return (dx >= 0) and (dx < b[0]) and (dy >= 0) and (dy < b[1])
def as_coordinates(self):
"Returns a 4-tuple (x, y, x2, y2)"
p = self.position
b = self.bounds
return (p[0], p[1], p[0]+b[0]-1, p[1]+b[1]-1)
#------------------------------------------------------------------------
# Property setters and getters
#------------------------------------------------------------------------
def _get_x(self):
return self.position[0]
def _set_x(self, val):
self.position[0] = val
return
def _get_y(self):
return self.position[1]
def _set_y(self, val):
self.position[1] = val
return
def _get_width(self):
return self.bounds[0]
def _set_width(self, val):
if isinstance(val, basestring):
try:
val = float(val)
except:
pass
old_value = self.bounds[0]
self.bounds[0] = val
self.trait_property_changed( 'width', old_value, val )
return
def _get_height(self):
return self.bounds[1]
def _set_height(self, val):
if isinstance(val, basestring):
try:
val = float(val)
except:
pass
old_value = self.bounds[1]
self.bounds[1] = val
self.trait_property_changed( 'height', old_value, val )
return
def _get_x2(self):
if self.bounds[0] == 0: return self.position[0]
return self.position[0] + self.bounds[0] - 1
def _set_x2(self, val):
self.position[0] = val - self.bounds[0] + 1
return
def _old_set_x2(self, val):
new_width = val - self.position[0] + 1
if new_width < 0.0:
raise RuntimeError, "Attempted to set negative component width."
else:
self.bounds[0] = new_width
return
def _get_y2(self):
if self.bounds[1] == 0:
return self.position[1]
return self.position[1] + self.bounds[1] - 1
def _set_y2(self, val):
self.position[1] = val - self.bounds[1] + 1
return
def _old_set_y2(self, val):
new_height = val - self.position[1] + 1
if new_height < 0.0:
raise RuntimeError, "Attempted to set negative component height."
else:
self.bounds[1] = new_height
return
# EOF
|