new scroll bar code

2002-04-25
2002-04-26
  • James Bailey

    James Bailey - 2002-04-25

    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)

     
    • Sean Riley

      Sean Riley - 2002-04-26

      arg.. the tabs/spaces are all broken.. sent it to me directly at sean@twistedmatrix.com. Thanks.

       

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks