this bit-o-code(TM) unifies the scroll bar logic, fixes a few probles with VScroll, and makes HScroll work.
TODO: add theme support for drawing left/right
scroll buttons as the top/bottom ones might not be reusable, but they will do for now.
if these text boxes have a wrapping problem please email me for a nice attachment, or just screen me for competance and give me CVS access to the repository.
class Scroll(Base):
"""Base scroll bar.
"""
def __init__(self):
self.scrollPos = 0 # pixel position of scroll bar
self.currentItem = 0
self.status = 0
self.barSize = 1
self.barSpace = 1
self.numItems = 1
self.numVisible = 1
self.interval = 1
Base.__init__(self)
self.setupBar()
self.setupPos()
self.start = 0
self.registerEvent(pyui.locals.LMOUSEBUTTONDOWN, self.onMouseDown)
self.registerEvent(pyui.locals.LMOUSEBUTTONUP, self.onMouseUp)
self.registerEvent(pyui.locals.MOUSEMOVE, self.onMouseMotion)
this bit-o-code(TM) unifies the scroll bar logic, fixes a few probles with VScroll, and makes HScroll work.
TODO: add theme support for drawing left/right
scroll buttons as the top/bottom ones might not be reusable, but they will do for now.
if these text boxes have a wrapping problem please email me for a nice attachment, or just screen me for competance and give me CVS access to the repository.
class Scroll(Base):
"""Base scroll bar.
"""
def __init__(self):
self.scrollPos = 0 # pixel position of scroll bar
self.currentItem = 0
self.status = 0
self.barSize = 1
self.barSpace = 1
self.numItems = 1
self.numVisible = 1
self.interval = 1
Base.__init__(self)
self.setupBar()
self.setupPos()
self.start = 0
self.registerEvent(pyui.locals.LMOUSEBUTTONDOWN, self.onMouseDown)
self.registerEvent(pyui.locals.LMOUSEBUTTONUP, self.onMouseUp)
self.registerEvent(pyui.locals.MOUSEMOVE, self.onMouseMotion)
def setNumItems(self, numItems, numVisible):
if numItems == 0:
self.numItems = 1
else:
self.numItems = numItems
self.numVisible = numVisible
self.setupBar()
self.setupPos()
self.setDirty(1)
def setupBar(self):
if self.alignment == 'v': self.barSpace = self.height - 22
else: self.barSpace = self.width - 22
if self.barSpace < 1:
self.barSpace = 1
if self.numItems < self.numVisible:
self.barSize = self.barSpace
else:
self.barSize = self.barSpace * self.numVisible / self.numItems
if self.barSize < 5:
self.barSize = 5
if self.scrollPos > self.barSpace - self.barSize:
self.scrollPos = max( self.barSpace - self.barSize, 0 )
def setupPos(self):
self.pos = 11 + self.scrollPos
item = (self.scrollPos/float(self.barSpace)) * self.numItems
if item != self.currentItem:
e = self.postEvent(pyui.locals.SCROLLPOS)
e.pos = int(item)
self.currentItem = int(item)
def draw(self):
pyui.core.gTheme.drawBack3(self.windowRect)
if self.alignment == 'v':
pyui.core.gTheme.drawScrollButtonUp((self.windowRect[0],self.windowRect[1],self.width,10) )
pyui.core.gTheme.drawScrollButtonDown((self.windowRect[0],self.windowRect[1]+self.height-10,self.width,10))
pyui.core.gTheme.drawScrollBar((self.windowRect[0], self.windowRect[1]+self.pos, self.width, self.barSize))
else:
pyui.core.gTheme.drawScrollButtonUp((self.windowRect[0],self.windowRect[1],10,self.height) )
pyui.core.gTheme.drawScrollButtonDown((self.windowRect[0]+self.width-10,self.windowRect[1],10,self.height))
pyui.core.gTheme.drawScrollBar((self.windowRect[0]+self.pos, self.windowRect[1], self.barSize, self.height))
def onMouseDown(self, event):
if not self.hit(event.pos):
self.status = 0
return 0
localpos = (event.pos[0] - self.rect[0], event.pos[1] - self.rect[1])
if self.alignment == 'v':
p = localpos[1]
extent = self.height
else:
p = localpos[0]
extent = self.width
if p < 10: # up button scroll
if self.currentItem > 0: self.scrollToItem( self.currentItem - 1 )
return 1
if p > extent - 10: # down button scroll
if self.currentItem < self.numItems: self.scrollToItem( self.currentItem + 1 )
return 1
if self.pos < p < self.pos + self.barSize: # <-- *** Just cleaned comparsion
self.status = 1 # we are scrolling
self.start = p
self.setDirty(1)
return 1
else: # unnocupied bar space
self.scrollPos = p - 11 - self.barSize/2 #center bar on cursor position
if self.scrollPos < 0:
self.scrollPos = 0
elif self.scrollPos > self.barSpace - self.barSize:
self.scrollPos = self.barSpace - self.barSize
self.setupPos()
self.status = 1
self.start = p
self.setDirty(1)
return 1
def onMouseUp(self, event):
if not self.hit(event.pos):
self.status = 0
return 0
self.status = 0
def onMouseMotion(self, event):
if self.status:
localpos = (event.pos[0] - self.rect[0], event.pos[1] - self.rect[1])
if self.alignment == 'v': p = localpos[1]
else: p = localpos[0]
diff = p - self.start
self.scrollPos = self.scrollPos + diff
if self.scrollPos < 0:
self.scrollPos = 0
elif self.scrollPos > self.barSpace - self.barSize:
self.scrollPos = self.barSpace - self.barSize
self.start = p
self.setupPos()
self.setDirty(1)
return 1
def resize(self, w, h):
Base.resize(self, w, h)
self.setupBar()
self.setupPos()
def calcSize(self):
Base.calcSize(self)
self.setupBar()
self.setupPos()
def scrollToItem(self, itemNum):
#curr = (self.scrollPos/float(self.barSpace)) * self.numItems
if int(self.currentItem) != int(itemNum):
self.scrollPos = (itemNum/float(self.numItems)) * float(self.barSpace)
if self.scrollPos < 0:
self.scrollPos = 0
elif self.scrollPos > self.barSpace - self.barSize:
self.scrollPos = self.barSpace - self.barSize
self.setupPos()
class VScroll(Scroll):
"""Vertical scroll bar.
"""
def __init__(self):
self.alignment = 'v'
Scroll.__init__(self)
class HScroll(Scroll):
"""Horizontal scroll bar.
"""
def __init__(self):
self.alignment = 'h'
Scroll.__init__(self)
arg.. the tabs/spaces are all broken.. sent it to me directly at sean@twistedmatrix.com. Thanks.