Initial revision
This commit is contained in:
parent
0c89ec778d
commit
2e44967104
|
@ -0,0 +1,53 @@
|
|||
# Abstract classes for parents and children.
|
||||
# Do not use as base class -- this is for documentation only.
|
||||
# Note that the tree must be built top down.
|
||||
|
||||
class AbstractParent():
|
||||
#
|
||||
# Upcalls from child to parent
|
||||
#
|
||||
def addchild(self, child): unimpl()
|
||||
def delchild(self, child): unimpl()
|
||||
#
|
||||
def need_mouse(self, child): unimpl()
|
||||
def no_mouse(self, child): unimpl()
|
||||
#
|
||||
def need_timer(self, child): unimpl()
|
||||
def no_timer(self, child): unimpl()
|
||||
#
|
||||
# XXX need_kbd, no_kbd; focus???
|
||||
#
|
||||
def begindrawing(self): return unimpl()
|
||||
def beginmeasuring(self): return unimpl()
|
||||
#
|
||||
def change(self, area): unimpl()
|
||||
def scroll(self, (area, (dh, dv))): unimpl()
|
||||
def settimer(self, itimer): unimpl()
|
||||
|
||||
class AbstractChild():
|
||||
#
|
||||
# Downcalls from parent to child
|
||||
#
|
||||
def destroy(self): unimpl()
|
||||
#
|
||||
def minsize(self, m): return unimpl()
|
||||
def getbounds(self): return unimpl()
|
||||
def setbounds(self, bounds): unimpl()
|
||||
def draw(self, (d, area)): unimpl()
|
||||
#
|
||||
# Downcalls only made after certain upcalls
|
||||
#
|
||||
def mouse_down(self, detail): unimpl()
|
||||
def mouse_move(self, detail): unimpl()
|
||||
def mouse_up(self, detail): unimpl()
|
||||
#
|
||||
def timer(self): unimpl()
|
||||
|
||||
# A "Split" is a child that manages one or more children.
|
||||
# (This terminology is due to DEC SRC, except for CSplits.)
|
||||
# A child of a split may be another split, a button, a slider, etc.
|
||||
# Certain upcalls and downcalls can be handled transparently, but
|
||||
# for others (e.g., all geometry related calls) this is not possible.
|
||||
|
||||
class AbstractSplit() = AbstractChild(), AbstractParent():
|
||||
pass
|
|
@ -0,0 +1,52 @@
|
|||
# HVSplit contains generic code for HSplit and VSplit.
|
||||
# HSplit and VSplit are specializations to either dimension.
|
||||
|
||||
from Split import Split
|
||||
|
||||
class HVSplit() = Split():
|
||||
#
|
||||
def create(self, (parent, hv)):
|
||||
# hv is 0 or 1 for HSplit or VSplit
|
||||
self = Split.create(self, parent)
|
||||
self.hv = hv
|
||||
return self
|
||||
#
|
||||
def minsize(self, m):
|
||||
hv, vh = self.hv, 1 - self.hv
|
||||
size = [0, 0]
|
||||
for c in self.children:
|
||||
csize = c.minsize(m)
|
||||
if csize[vh] > size[vh]: size[vh] = csize[vh]
|
||||
size[hv] = size[hv] + csize[hv]
|
||||
return size[0], size[1]
|
||||
#
|
||||
def getbounds(self):
|
||||
return self.bounds
|
||||
#
|
||||
def setbounds(self, bounds):
|
||||
self.bounds = bounds
|
||||
hv, vh = self.hv, 1 - self.hv
|
||||
mf = self.parent.beginmeasuring
|
||||
size = self.minsize(mf())
|
||||
# XXX not yet used! Later for stretching
|
||||
maxsize_hv = bounds[1][hv] - bounds[0][hv]
|
||||
origin = [self.bounds[0][0], self.bounds[0][1]]
|
||||
for c in self.children:
|
||||
size = c.minsize(mf())
|
||||
corner = [0, 0]
|
||||
corner[vh] = bounds[1][vh]
|
||||
corner[hv] = origin[hv] + size[hv]
|
||||
c.setbounds((origin[0], origin[1]), \
|
||||
(corner[0], corner[1]))
|
||||
origin[hv] = corner[hv]
|
||||
# XXX stretch
|
||||
# XXX too-small
|
||||
#
|
||||
|
||||
class HSplit() = HVSplit():
|
||||
def create(self, parent):
|
||||
return HVSplit.create(self, (parent, 0))
|
||||
|
||||
class VSplit() = HVSplit():
|
||||
def create(self, parent):
|
||||
return HVSplit.create(self, (parent, 1))
|
|
@ -0,0 +1,113 @@
|
|||
# Generic Split implementation.
|
||||
# Use as a base class for other splits.
|
||||
|
||||
Error = 'Split.Error' # Exception
|
||||
|
||||
import rect
|
||||
from util import remove
|
||||
|
||||
class Split():
|
||||
#
|
||||
# Calls from creator
|
||||
# NB derived classes may add parameters to create()
|
||||
#
|
||||
def create(self, parent):
|
||||
parent.addchild(self)
|
||||
self.parent = parent
|
||||
self.children = []
|
||||
self.mouse_interest = []
|
||||
self.timer_interest = []
|
||||
self.mouse_focus = 0
|
||||
return self
|
||||
#
|
||||
# Downcalls from parent to child
|
||||
#
|
||||
def destroy(self):
|
||||
self.parent = 0
|
||||
for child in self.children:
|
||||
child.destroy()
|
||||
self.children[:] = []
|
||||
self.mouse_interest[:] = []
|
||||
self.timer_interest[:] = []
|
||||
self.mouse_focus = 0
|
||||
#
|
||||
def minsize(self, m): return unimpl()
|
||||
def getbounds(self): return unimpl()
|
||||
def setbounds(self, bounds): unimpl()
|
||||
def draw(self, args):
|
||||
# (Could avoid calls to children outside the area)
|
||||
for child in self.children:
|
||||
child.draw(args)
|
||||
#
|
||||
# Downcalls only made after certain upcalls
|
||||
#
|
||||
def mouse_down(self, detail):
|
||||
if self.mouse_focus:
|
||||
self.mouse_focus.mouse_down(detail)
|
||||
p = detail[0]
|
||||
for child in self.mouse_interest:
|
||||
if rect.pointinrect(p, child.getbounds()):
|
||||
self.mouse_focus = child
|
||||
child.mouse_down(detail)
|
||||
def mouse_move(self, detail):
|
||||
if self.mouse_focus:
|
||||
self.mouse_focus.mouse_move(detail)
|
||||
def mouse_up(self, detail):
|
||||
if self.mouse_focus:
|
||||
self.mouse_focus.mouse_up(detail)
|
||||
self.mouse_focus = 0
|
||||
#
|
||||
def timer(self):
|
||||
for child in self.timer_interest:
|
||||
child.timer()
|
||||
#
|
||||
# Upcalls from child to parent
|
||||
#
|
||||
def addchild(self, child):
|
||||
if child in self.children:
|
||||
raise Error, 'addchild: child already inlist'
|
||||
self.children.append(child)
|
||||
def delchild(self, child):
|
||||
if child not in self.children:
|
||||
raise Error, 'delchild: child not in list'
|
||||
remove(child, self.children)
|
||||
if child in self.mouse_interest:
|
||||
remove(child, self.mouse_interest)
|
||||
if child in self.timer_interest:
|
||||
remove(child, self.timer_interest)
|
||||
if child = self.mouse_focus:
|
||||
self.mouse_focus = 0
|
||||
#
|
||||
def need_mouse(self, child):
|
||||
if child not in self.mouse_interest:
|
||||
self.mouse_interest.append(child)
|
||||
self.parent.need_mouse(self)
|
||||
def no_mouse(self, child):
|
||||
if child in self.mouse_interest:
|
||||
remove(child, self.mouse_interest)
|
||||
if not self.mouse_interest:
|
||||
self.parent.no_mouse(self)
|
||||
#
|
||||
def need_timer(self, child):
|
||||
if child not in self.timer_interest:
|
||||
self.timer_interest.append(child)
|
||||
self.parent.need_timer(self)
|
||||
def no_timer(self, child):
|
||||
if child in self.timer_interest:
|
||||
remove(child, self.timer_interest)
|
||||
if not self.timer_interest:
|
||||
self.parent.no_timer(self)
|
||||
#
|
||||
# The rest are transparent:
|
||||
#
|
||||
def begindrawing(self):
|
||||
return self.parent.begindrawing()
|
||||
def beginmeasuring(self):
|
||||
return self.parent.beginmeasuring()
|
||||
#
|
||||
def change(self, area):
|
||||
self.parent.change(area)
|
||||
def scroll(self, args):
|
||||
self.parent.scroll(args)
|
||||
def settimer(self, itimer):
|
||||
self.parent.settimer(itimer)
|
|
@ -0,0 +1,96 @@
|
|||
# A class that sits transparently between a parent and one child.
|
||||
# First create the parent, then this thing, then the child.
|
||||
# Use this as a base class for objects that are almost transparent.
|
||||
# Don't use as a base class for parents with multiple children.
|
||||
|
||||
Error = 'TransParent.Error' # Exception
|
||||
|
||||
class ManageOneChild():
|
||||
#
|
||||
# Upcalls shared with other single-child parents
|
||||
#
|
||||
def addchild(self, child):
|
||||
if self.child:
|
||||
raise Error, 'addchild: one child only'
|
||||
if not child:
|
||||
raise Error, 'addchild: bad child'
|
||||
self.child = child
|
||||
#
|
||||
def delchild(self, child):
|
||||
if not self.child:
|
||||
raise Error, 'delchild: no child'
|
||||
if child <> self.child:
|
||||
raise Error, 'delchild: not my child'
|
||||
self.child = 0
|
||||
|
||||
class TransParent() = ManageOneChild():
|
||||
#
|
||||
# Calls from creator
|
||||
# NB derived classes may add parameters to create()
|
||||
#
|
||||
def create(self, parent):
|
||||
parent.addchild(self)
|
||||
self.parent = parent
|
||||
self.child = 0 # No child yet
|
||||
#
|
||||
# Downcalls from parent to child
|
||||
#
|
||||
def destroy(self):
|
||||
del self.parent
|
||||
if self.child: self.child.destroy()
|
||||
del self.child
|
||||
#
|
||||
def minsize(self, m):
|
||||
if not self.child:
|
||||
return 0, 0
|
||||
else:
|
||||
return self.child.minsize(m)
|
||||
def getbounds(self, bounds):
|
||||
if not self.child:
|
||||
raise Error, 'getbounds w/o child'
|
||||
else:
|
||||
return self.child.getbounds()
|
||||
def setbounds(self, bounds):
|
||||
if not self.child:
|
||||
raise Error, 'setbounds w/o child'
|
||||
else:
|
||||
self.child.setbounds(bounds)
|
||||
def draw(self, args):
|
||||
if self.child:
|
||||
self.child.draw(args)
|
||||
#
|
||||
# Downcalls only made after certain upcalls
|
||||
#
|
||||
def mouse_down(self, detail):
|
||||
if self.child: self.child.mouse_down(detail)
|
||||
def mouse_move(self, detail):
|
||||
if self.child: self.child.mouse_move(detail)
|
||||
def mouse_up(self, detail):
|
||||
if self.child: self.child.mouse_up(detail)
|
||||
#
|
||||
def timer(self):
|
||||
if self.child: self.child.timer()
|
||||
#
|
||||
# Upcalls from child to parent
|
||||
#
|
||||
def need_mouse(self, child):
|
||||
self.parent.need_mouse(self)
|
||||
def no_mouse(self, child):
|
||||
self.parent.no_mouse(self)
|
||||
#
|
||||
def need_timer(self, child):
|
||||
self.parent.need_timer(self)
|
||||
def no_timer(self, child):
|
||||
self.parent.no_timer(self)
|
||||
#
|
||||
def begindrawing(self):
|
||||
return self.parent.begindrawing()
|
||||
def beginmeasuring(self):
|
||||
return self.parent.beginmeasuring()
|
||||
#
|
||||
def change(self, area):
|
||||
self.parent.change(area)
|
||||
def scroll(self, args):
|
||||
self.parent.scroll(args)
|
||||
def settimer(self, itimer):
|
||||
self.parent.settimer(itimer)
|
|
@ -0,0 +1,92 @@
|
|||
# A 'WindowParent' is the only module that uses real stdwin functionality.
|
||||
# It is the root of the tree.
|
||||
# It should have exactly one child when realized.
|
||||
|
||||
import stdwin
|
||||
from stdwinevents import *
|
||||
|
||||
from TransParent import ManageOneChild
|
||||
|
||||
Error = 'WindowParent.Error' # Exception
|
||||
|
||||
class WindowParent() = ManageOneChild():
|
||||
#
|
||||
def create(self, (title, size)):
|
||||
self.title = title
|
||||
self.size = size # (width, height)
|
||||
self.child = 0 # i.e., no child yet
|
||||
self.win = 0 # i.e., no window yet
|
||||
self.itimer = 0
|
||||
self.do_mouse = 0
|
||||
self.do_timer = 0
|
||||
return self
|
||||
#
|
||||
def need_mouse(self, child): self.do_mouse = 1
|
||||
def no_mouse(self, child): self.do_mouse = 0
|
||||
#
|
||||
def need_timer(self, child): self.do_timer = 1
|
||||
def no_timer(self, child): self.do_timer = 0
|
||||
#
|
||||
def realize(self):
|
||||
if self.win:
|
||||
raise Error, 'realize(): called twice'
|
||||
if not self.child:
|
||||
raise Error, 'realize(): no child'
|
||||
size = self.child.minsize(self.beginmeasuring())
|
||||
self.size = max(self.size[0], size[0]), \
|
||||
max(self.size[1], size[1])
|
||||
stdwin.setdefwinsize(self.size)
|
||||
self.win = stdwin.open(self.title)
|
||||
if self.itimer:
|
||||
self.win.settimer(self.itimer)
|
||||
bounds = (0, 0), self.win.getwinsize()
|
||||
self.child.setbounds(bounds)
|
||||
#
|
||||
def beginmeasuring(self):
|
||||
# Return something with which a child can measure text
|
||||
if self.win:
|
||||
return self.win.begindrawing()
|
||||
else:
|
||||
return stdwin
|
||||
#
|
||||
def begindrawing(self):
|
||||
if self.win:
|
||||
return self.win.begindrawing()
|
||||
else:
|
||||
raise Error, 'begindrawing(): not realized yet'
|
||||
#
|
||||
def change(self, area):
|
||||
if self.win:
|
||||
self.win.change(area)
|
||||
#
|
||||
def scroll(self, args):
|
||||
if self.win:
|
||||
self.win.scroll(args)
|
||||
#
|
||||
def settimer(self, itimer):
|
||||
if self.win:
|
||||
self.win.settimer(itimer)
|
||||
else:
|
||||
self.itimer = itimer
|
||||
#
|
||||
# Only call dispatch if we have a child
|
||||
#
|
||||
def dispatch(self, (type, win, detail)):
|
||||
if win <> self.win:
|
||||
return
|
||||
elif type = WE_DRAW:
|
||||
d = self.win.begindrawing()
|
||||
self.child.draw(d, detail)
|
||||
elif type = WE_MOUSE_DOWN:
|
||||
if self.do_mouse: self.child.mouse_down(detail)
|
||||
elif type = WE_MOUSE_MOVE:
|
||||
if self.do_mouse: self.child.mouse_move(detail)
|
||||
elif type = WE_MOUSE_UP:
|
||||
if self.do_mouse: self.child.mouse_up(detail)
|
||||
elif type = WE_TIMER:
|
||||
if self.do_timer: self.child.timer()
|
||||
elif type = WE_SIZE:
|
||||
self.win.change((0, 0), (10000, 10000)) # XXX
|
||||
bounds = (0, 0), self.win.getwinsize()
|
||||
self.child.setbounds(bounds)
|
||||
#
|
|
@ -0,0 +1,53 @@
|
|||
# Abstract classes for parents and children.
|
||||
# Do not use as base class -- this is for documentation only.
|
||||
# Note that the tree must be built top down.
|
||||
|
||||
class AbstractParent():
|
||||
#
|
||||
# Upcalls from child to parent
|
||||
#
|
||||
def addchild(self, child): unimpl()
|
||||
def delchild(self, child): unimpl()
|
||||
#
|
||||
def need_mouse(self, child): unimpl()
|
||||
def no_mouse(self, child): unimpl()
|
||||
#
|
||||
def need_timer(self, child): unimpl()
|
||||
def no_timer(self, child): unimpl()
|
||||
#
|
||||
# XXX need_kbd, no_kbd; focus???
|
||||
#
|
||||
def begindrawing(self): return unimpl()
|
||||
def beginmeasuring(self): return unimpl()
|
||||
#
|
||||
def change(self, area): unimpl()
|
||||
def scroll(self, (area, (dh, dv))): unimpl()
|
||||
def settimer(self, itimer): unimpl()
|
||||
|
||||
class AbstractChild():
|
||||
#
|
||||
# Downcalls from parent to child
|
||||
#
|
||||
def destroy(self): unimpl()
|
||||
#
|
||||
def minsize(self, m): return unimpl()
|
||||
def getbounds(self): return unimpl()
|
||||
def setbounds(self, bounds): unimpl()
|
||||
def draw(self, (d, area)): unimpl()
|
||||
#
|
||||
# Downcalls only made after certain upcalls
|
||||
#
|
||||
def mouse_down(self, detail): unimpl()
|
||||
def mouse_move(self, detail): unimpl()
|
||||
def mouse_up(self, detail): unimpl()
|
||||
#
|
||||
def timer(self): unimpl()
|
||||
|
||||
# A "Split" is a child that manages one or more children.
|
||||
# (This terminology is due to DEC SRC, except for CSplits.)
|
||||
# A child of a split may be another split, a button, a slider, etc.
|
||||
# Certain upcalls and downcalls can be handled transparently, but
|
||||
# for others (e.g., all geometry related calls) this is not possible.
|
||||
|
||||
class AbstractSplit() = AbstractChild(), AbstractParent():
|
||||
pass
|
|
@ -0,0 +1,52 @@
|
|||
# HVSplit contains generic code for HSplit and VSplit.
|
||||
# HSplit and VSplit are specializations to either dimension.
|
||||
|
||||
from Split import Split
|
||||
|
||||
class HVSplit() = Split():
|
||||
#
|
||||
def create(self, (parent, hv)):
|
||||
# hv is 0 or 1 for HSplit or VSplit
|
||||
self = Split.create(self, parent)
|
||||
self.hv = hv
|
||||
return self
|
||||
#
|
||||
def minsize(self, m):
|
||||
hv, vh = self.hv, 1 - self.hv
|
||||
size = [0, 0]
|
||||
for c in self.children:
|
||||
csize = c.minsize(m)
|
||||
if csize[vh] > size[vh]: size[vh] = csize[vh]
|
||||
size[hv] = size[hv] + csize[hv]
|
||||
return size[0], size[1]
|
||||
#
|
||||
def getbounds(self):
|
||||
return self.bounds
|
||||
#
|
||||
def setbounds(self, bounds):
|
||||
self.bounds = bounds
|
||||
hv, vh = self.hv, 1 - self.hv
|
||||
mf = self.parent.beginmeasuring
|
||||
size = self.minsize(mf())
|
||||
# XXX not yet used! Later for stretching
|
||||
maxsize_hv = bounds[1][hv] - bounds[0][hv]
|
||||
origin = [self.bounds[0][0], self.bounds[0][1]]
|
||||
for c in self.children:
|
||||
size = c.minsize(mf())
|
||||
corner = [0, 0]
|
||||
corner[vh] = bounds[1][vh]
|
||||
corner[hv] = origin[hv] + size[hv]
|
||||
c.setbounds((origin[0], origin[1]), \
|
||||
(corner[0], corner[1]))
|
||||
origin[hv] = corner[hv]
|
||||
# XXX stretch
|
||||
# XXX too-small
|
||||
#
|
||||
|
||||
class HSplit() = HVSplit():
|
||||
def create(self, parent):
|
||||
return HVSplit.create(self, (parent, 0))
|
||||
|
||||
class VSplit() = HVSplit():
|
||||
def create(self, parent):
|
||||
return HVSplit.create(self, (parent, 1))
|
|
@ -0,0 +1,113 @@
|
|||
# Generic Split implementation.
|
||||
# Use as a base class for other splits.
|
||||
|
||||
Error = 'Split.Error' # Exception
|
||||
|
||||
import rect
|
||||
from util import remove
|
||||
|
||||
class Split():
|
||||
#
|
||||
# Calls from creator
|
||||
# NB derived classes may add parameters to create()
|
||||
#
|
||||
def create(self, parent):
|
||||
parent.addchild(self)
|
||||
self.parent = parent
|
||||
self.children = []
|
||||
self.mouse_interest = []
|
||||
self.timer_interest = []
|
||||
self.mouse_focus = 0
|
||||
return self
|
||||
#
|
||||
# Downcalls from parent to child
|
||||
#
|
||||
def destroy(self):
|
||||
self.parent = 0
|
||||
for child in self.children:
|
||||
child.destroy()
|
||||
self.children[:] = []
|
||||
self.mouse_interest[:] = []
|
||||
self.timer_interest[:] = []
|
||||
self.mouse_focus = 0
|
||||
#
|
||||
def minsize(self, m): return unimpl()
|
||||
def getbounds(self): return unimpl()
|
||||
def setbounds(self, bounds): unimpl()
|
||||
def draw(self, args):
|
||||
# (Could avoid calls to children outside the area)
|
||||
for child in self.children:
|
||||
child.draw(args)
|
||||
#
|
||||
# Downcalls only made after certain upcalls
|
||||
#
|
||||
def mouse_down(self, detail):
|
||||
if self.mouse_focus:
|
||||
self.mouse_focus.mouse_down(detail)
|
||||
p = detail[0]
|
||||
for child in self.mouse_interest:
|
||||
if rect.pointinrect(p, child.getbounds()):
|
||||
self.mouse_focus = child
|
||||
child.mouse_down(detail)
|
||||
def mouse_move(self, detail):
|
||||
if self.mouse_focus:
|
||||
self.mouse_focus.mouse_move(detail)
|
||||
def mouse_up(self, detail):
|
||||
if self.mouse_focus:
|
||||
self.mouse_focus.mouse_up(detail)
|
||||
self.mouse_focus = 0
|
||||
#
|
||||
def timer(self):
|
||||
for child in self.timer_interest:
|
||||
child.timer()
|
||||
#
|
||||
# Upcalls from child to parent
|
||||
#
|
||||
def addchild(self, child):
|
||||
if child in self.children:
|
||||
raise Error, 'addchild: child already inlist'
|
||||
self.children.append(child)
|
||||
def delchild(self, child):
|
||||
if child not in self.children:
|
||||
raise Error, 'delchild: child not in list'
|
||||
remove(child, self.children)
|
||||
if child in self.mouse_interest:
|
||||
remove(child, self.mouse_interest)
|
||||
if child in self.timer_interest:
|
||||
remove(child, self.timer_interest)
|
||||
if child = self.mouse_focus:
|
||||
self.mouse_focus = 0
|
||||
#
|
||||
def need_mouse(self, child):
|
||||
if child not in self.mouse_interest:
|
||||
self.mouse_interest.append(child)
|
||||
self.parent.need_mouse(self)
|
||||
def no_mouse(self, child):
|
||||
if child in self.mouse_interest:
|
||||
remove(child, self.mouse_interest)
|
||||
if not self.mouse_interest:
|
||||
self.parent.no_mouse(self)
|
||||
#
|
||||
def need_timer(self, child):
|
||||
if child not in self.timer_interest:
|
||||
self.timer_interest.append(child)
|
||||
self.parent.need_timer(self)
|
||||
def no_timer(self, child):
|
||||
if child in self.timer_interest:
|
||||
remove(child, self.timer_interest)
|
||||
if not self.timer_interest:
|
||||
self.parent.no_timer(self)
|
||||
#
|
||||
# The rest are transparent:
|
||||
#
|
||||
def begindrawing(self):
|
||||
return self.parent.begindrawing()
|
||||
def beginmeasuring(self):
|
||||
return self.parent.beginmeasuring()
|
||||
#
|
||||
def change(self, area):
|
||||
self.parent.change(area)
|
||||
def scroll(self, args):
|
||||
self.parent.scroll(args)
|
||||
def settimer(self, itimer):
|
||||
self.parent.settimer(itimer)
|
|
@ -0,0 +1,96 @@
|
|||
# A class that sits transparently between a parent and one child.
|
||||
# First create the parent, then this thing, then the child.
|
||||
# Use this as a base class for objects that are almost transparent.
|
||||
# Don't use as a base class for parents with multiple children.
|
||||
|
||||
Error = 'TransParent.Error' # Exception
|
||||
|
||||
class ManageOneChild():
|
||||
#
|
||||
# Upcalls shared with other single-child parents
|
||||
#
|
||||
def addchild(self, child):
|
||||
if self.child:
|
||||
raise Error, 'addchild: one child only'
|
||||
if not child:
|
||||
raise Error, 'addchild: bad child'
|
||||
self.child = child
|
||||
#
|
||||
def delchild(self, child):
|
||||
if not self.child:
|
||||
raise Error, 'delchild: no child'
|
||||
if child <> self.child:
|
||||
raise Error, 'delchild: not my child'
|
||||
self.child = 0
|
||||
|
||||
class TransParent() = ManageOneChild():
|
||||
#
|
||||
# Calls from creator
|
||||
# NB derived classes may add parameters to create()
|
||||
#
|
||||
def create(self, parent):
|
||||
parent.addchild(self)
|
||||
self.parent = parent
|
||||
self.child = 0 # No child yet
|
||||
#
|
||||
# Downcalls from parent to child
|
||||
#
|
||||
def destroy(self):
|
||||
del self.parent
|
||||
if self.child: self.child.destroy()
|
||||
del self.child
|
||||
#
|
||||
def minsize(self, m):
|
||||
if not self.child:
|
||||
return 0, 0
|
||||
else:
|
||||
return self.child.minsize(m)
|
||||
def getbounds(self, bounds):
|
||||
if not self.child:
|
||||
raise Error, 'getbounds w/o child'
|
||||
else:
|
||||
return self.child.getbounds()
|
||||
def setbounds(self, bounds):
|
||||
if not self.child:
|
||||
raise Error, 'setbounds w/o child'
|
||||
else:
|
||||
self.child.setbounds(bounds)
|
||||
def draw(self, args):
|
||||
if self.child:
|
||||
self.child.draw(args)
|
||||
#
|
||||
# Downcalls only made after certain upcalls
|
||||
#
|
||||
def mouse_down(self, detail):
|
||||
if self.child: self.child.mouse_down(detail)
|
||||
def mouse_move(self, detail):
|
||||
if self.child: self.child.mouse_move(detail)
|
||||
def mouse_up(self, detail):
|
||||
if self.child: self.child.mouse_up(detail)
|
||||
#
|
||||
def timer(self):
|
||||
if self.child: self.child.timer()
|
||||
#
|
||||
# Upcalls from child to parent
|
||||
#
|
||||
def need_mouse(self, child):
|
||||
self.parent.need_mouse(self)
|
||||
def no_mouse(self, child):
|
||||
self.parent.no_mouse(self)
|
||||
#
|
||||
def need_timer(self, child):
|
||||
self.parent.need_timer(self)
|
||||
def no_timer(self, child):
|
||||
self.parent.no_timer(self)
|
||||
#
|
||||
def begindrawing(self):
|
||||
return self.parent.begindrawing()
|
||||
def beginmeasuring(self):
|
||||
return self.parent.beginmeasuring()
|
||||
#
|
||||
def change(self, area):
|
||||
self.parent.change(area)
|
||||
def scroll(self, args):
|
||||
self.parent.scroll(args)
|
||||
def settimer(self, itimer):
|
||||
self.parent.settimer(itimer)
|
|
@ -0,0 +1,92 @@
|
|||
# A 'WindowParent' is the only module that uses real stdwin functionality.
|
||||
# It is the root of the tree.
|
||||
# It should have exactly one child when realized.
|
||||
|
||||
import stdwin
|
||||
from stdwinevents import *
|
||||
|
||||
from TransParent import ManageOneChild
|
||||
|
||||
Error = 'WindowParent.Error' # Exception
|
||||
|
||||
class WindowParent() = ManageOneChild():
|
||||
#
|
||||
def create(self, (title, size)):
|
||||
self.title = title
|
||||
self.size = size # (width, height)
|
||||
self.child = 0 # i.e., no child yet
|
||||
self.win = 0 # i.e., no window yet
|
||||
self.itimer = 0
|
||||
self.do_mouse = 0
|
||||
self.do_timer = 0
|
||||
return self
|
||||
#
|
||||
def need_mouse(self, child): self.do_mouse = 1
|
||||
def no_mouse(self, child): self.do_mouse = 0
|
||||
#
|
||||
def need_timer(self, child): self.do_timer = 1
|
||||
def no_timer(self, child): self.do_timer = 0
|
||||
#
|
||||
def realize(self):
|
||||
if self.win:
|
||||
raise Error, 'realize(): called twice'
|
||||
if not self.child:
|
||||
raise Error, 'realize(): no child'
|
||||
size = self.child.minsize(self.beginmeasuring())
|
||||
self.size = max(self.size[0], size[0]), \
|
||||
max(self.size[1], size[1])
|
||||
stdwin.setdefwinsize(self.size)
|
||||
self.win = stdwin.open(self.title)
|
||||
if self.itimer:
|
||||
self.win.settimer(self.itimer)
|
||||
bounds = (0, 0), self.win.getwinsize()
|
||||
self.child.setbounds(bounds)
|
||||
#
|
||||
def beginmeasuring(self):
|
||||
# Return something with which a child can measure text
|
||||
if self.win:
|
||||
return self.win.begindrawing()
|
||||
else:
|
||||
return stdwin
|
||||
#
|
||||
def begindrawing(self):
|
||||
if self.win:
|
||||
return self.win.begindrawing()
|
||||
else:
|
||||
raise Error, 'begindrawing(): not realized yet'
|
||||
#
|
||||
def change(self, area):
|
||||
if self.win:
|
||||
self.win.change(area)
|
||||
#
|
||||
def scroll(self, args):
|
||||
if self.win:
|
||||
self.win.scroll(args)
|
||||
#
|
||||
def settimer(self, itimer):
|
||||
if self.win:
|
||||
self.win.settimer(itimer)
|
||||
else:
|
||||
self.itimer = itimer
|
||||
#
|
||||
# Only call dispatch if we have a child
|
||||
#
|
||||
def dispatch(self, (type, win, detail)):
|
||||
if win <> self.win:
|
||||
return
|
||||
elif type = WE_DRAW:
|
||||
d = self.win.begindrawing()
|
||||
self.child.draw(d, detail)
|
||||
elif type = WE_MOUSE_DOWN:
|
||||
if self.do_mouse: self.child.mouse_down(detail)
|
||||
elif type = WE_MOUSE_MOVE:
|
||||
if self.do_mouse: self.child.mouse_move(detail)
|
||||
elif type = WE_MOUSE_UP:
|
||||
if self.do_mouse: self.child.mouse_up(detail)
|
||||
elif type = WE_TIMER:
|
||||
if self.do_timer: self.child.timer()
|
||||
elif type = WE_SIZE:
|
||||
self.win.change((0, 0), (10000, 10000)) # XXX
|
||||
bounds = (0, 0), self.win.getwinsize()
|
||||
self.child.setbounds(bounds)
|
||||
#
|
Loading…
Reference in New Issue