1990-10-31 07:24:22 -04:00
|
|
|
# Module 'StripChart'
|
|
|
|
|
|
|
|
import rect
|
1990-11-05 15:44:31 -04:00
|
|
|
from Buttons import LabelAppearance, NoReactivity
|
1990-10-31 07:24:22 -04:00
|
|
|
|
1990-11-05 15:44:31 -04:00
|
|
|
# A StripChart doesn't really look like a label but it needs a base class.
|
|
|
|
# LabelAppearance allows it to be disabled and hilited.
|
1990-10-31 07:24:22 -04:00
|
|
|
|
1990-11-05 15:44:31 -04:00
|
|
|
class StripChart() = LabelAppearance(), NoReactivity():
|
1990-10-31 07:24:22 -04:00
|
|
|
#
|
1990-11-05 15:44:31 -04:00
|
|
|
def define(self, (parent, scale)):
|
|
|
|
self.parent = parent
|
|
|
|
parent.addchild(self)
|
|
|
|
self.init_appearance()
|
1990-10-31 07:24:22 -04:00
|
|
|
self.init_reactivity()
|
|
|
|
self.ydata = []
|
|
|
|
self.scale = scale
|
|
|
|
self.resetbounds()
|
|
|
|
return self
|
|
|
|
#
|
1991-04-21 16:27:28 -03:00
|
|
|
def destroy(self):
|
|
|
|
self.parent = 0
|
|
|
|
#
|
1990-10-31 07:24:22 -04:00
|
|
|
def setbounds(self, bounds):
|
|
|
|
LabelAppearance.setbounds(self, bounds)
|
|
|
|
self.resetbounds()
|
|
|
|
#
|
|
|
|
def resetbounds(self):
|
|
|
|
(left, top), (right, bottom) = self.bounds
|
|
|
|
self.width = right-left
|
|
|
|
self.height = bottom-top
|
|
|
|
excess = len(self.ydata) - self.width
|
|
|
|
if excess > 0:
|
|
|
|
del self.ydata[:excess]
|
|
|
|
elif excess < 0:
|
|
|
|
while len(self.ydata) < self.width:
|
|
|
|
self.ydata.insert(0, 0)
|
|
|
|
#
|
|
|
|
def append(self, y):
|
|
|
|
self.ydata.append(y)
|
|
|
|
excess = len(self.ydata) - self.width
|
|
|
|
if excess > 0:
|
|
|
|
del self.ydata[:excess]
|
1990-11-05 15:44:31 -04:00
|
|
|
if self.bounds <> rect.empty:
|
|
|
|
self.parent.scroll(self.bounds, (-excess, 0))
|
|
|
|
if self.bounds <> rect.empty:
|
1990-10-31 07:24:22 -04:00
|
|
|
(left, top), (right, bottom) = self.bounds
|
|
|
|
i = len(self.ydata)
|
|
|
|
area = (left+i-1, top), (left+i, bottom)
|
1990-11-05 15:44:31 -04:00
|
|
|
self.draw(self.parent.begindrawing(), area)
|
1990-10-31 07:24:22 -04:00
|
|
|
#
|
|
|
|
def draw(self, (d, area)):
|
|
|
|
area = rect.intersect(area, self.bounds)
|
|
|
|
if area = rect.empty:
|
|
|
|
return
|
|
|
|
d.cliprect(area)
|
|
|
|
d.erase(self.bounds)
|
|
|
|
(a_left, a_top), (a_right, a_bottom) = area
|
|
|
|
(left, top), (right, bottom) = self.bounds
|
|
|
|
height = bottom - top
|
|
|
|
i1 = a_left - left
|
|
|
|
i2 = a_right - left
|
|
|
|
for i in range(max(0, i1), min(len(self.ydata), i2)):
|
|
|
|
split = bottom-self.ydata[i]*height/self.scale
|
|
|
|
d.paint((left+i, split), (left+i+1, bottom))
|
|
|
|
if not self.enabled:
|
|
|
|
self.flipenable(d)
|
|
|
|
if self.hilited:
|
|
|
|
self.fliphilite(d)
|
|
|
|
d.noclip()
|