I use the same Python classes in all my projects. I don’t post them every time. If you don’t already have them, copy them from here. Use find function of your browser to navigate.
If you didn’t find what you looking for, chat me, I send you.
NewListBox, NewListBoxItem
class NewListBox(Window): def __init__(self): Window.__init__(self) self.items = [] self.selected = None self.basePos = 0 self.itemWidth = 100 self.itemStep = 4 self.totalItemHeight = 0 self.scrollbar = None self.scrollBarPos = 0.0 self.manualMode = False self.selectEvent = None def __del__(self): Window.__del__(self) self.items = [] self.selected = None self.basePos = 0 self.itemWidth = 100 self.itemStep = 4 self.totalItemHeight = 0 self.scrollbar = None self.scrollBarPos = 0.0 self.manualMode = False self.selectEvent = None def SetSize(self, w, h): Window.SetSize(self, w, h + self.itemStep) # self.SetItemWidth(w) self.UpdateList() def SetScrollBar(self, scrollbar): self.scrollbar = scrollbar self.scrollbar.SetScrollEvent(__mem_func__(self.__OnScroll)) self.scrollbar.SetScrollStep(0.07) self.UpdateList() def CalcTotalItemHeight(self): return self.totalItemHeight def ConfigureScrollBar(self): if self.scrollbar: itemheight = self.CalcTotalItemHeight() myheight = self.GetHeight() - 2 * self.itemStep dif = 0.97 if itemheight > myheight and itemheight != 0: dif = 1.0 * myheight / itemheight self.scrollbar.SetScrollStep(0.12 * dif) self.scrollbar.SetMiddleBarSize(dif) def __OnScroll(self, position=None): pos = self.scrollbar.GetPos() if position == None else position self.scrollBarPos = pos toscr = self.CalcTotalItemHeight() - self.GetHeight() + 2 * self.itemStep self.basePos = toscr * pos self.UpdateList() def GetScrollBarPosition(self): return self.scrollBarPos def OnScroll(self, pos): self.__OnScroll(pos) def SelectItem(self, item): self.selected = item if self.selectEvent: self.selectEvent(item) def AppendItem(self, item): item.SetParent(self) # item.SetWidth(self.itemWidth) item.Show() self.items.append(item) if not self.manualMode: self.UpdateList() def RemoveItem(self, item): item.Hide() self.items.remove(item) self.UpdateList() def ClearItems(self): map(lambda wnd: wnd.Hide(), self.items) del self.items[:] self.basePos = 0 if self.scrollbar: self.scrollbar.SetPos(0) self.UpdateList() def UpdateList(self): self.ConfigureScrollBar() self.RecalcItemPositions() def IsEmpty(self): return len(self.items) == 0 def SetItemWidth(self, w): self.itemWidth = w for item in self.items: item.SetWidth(w) def RecalcItemPositions(self): curbp = self.basePos itemheight = self.CalcTotalItemHeight() myheight = self.GetHeight() - 2 * self.itemStep if itemheight < myheight: curbp = 0 fromPos = curbp curPos = 0 curX = 0 toPos = curbp + self.GetHeight() for item in self.items: hw = item.GetHeight() if curPos + hw < fromPos: item.Hide() elif curPos < fromPos < curPos + hw: item.SetRenderMin(fromPos - curPos) item.Show() elif curPos < toPos < curPos + hw: item.SetRenderMax(toPos - curPos) item.Show() elif curPos > toPos: item.Hide() else: item.SetRenderMin(0) item.Show() item.SetPosition(curX, curPos - fromPos) curX += item.GetWidth() if curX >= self.GetWidth(): curX = 0 curPos += hw + self.itemStep elif self.items.index(item) == len(self.items) - 1: curPos += item.GetHeight() # if len(self.items): # curPos += self.items[-1].GetHeight() self.totalItemHeight = curPos class NewListBoxItem(Window): def __init__(self): Window.__init__(self) self.width = 0 self.height = 0 self.minh = 0 self.maxh = 0 self.components = [] def __del__(self): Window.__del__(self) def SetColor(self, color=0xff0099ff): self.color = color def SetParent(self, parent): Window.SetParent(self, parent) def SetHeight(self, h): self.SetSize(self.width, h) def SetWidth(self, w): self.SetSize(w, self.height) def SetSize(self, w, h): self.width = w self.height = h self.maxh = h Window.SetSize(self, w, h) def SetRenderMin(self, minh): self.minh = minh self.maxh = self.height self.RecalculateRenderedComponents() def SetRenderMax(self, maxh): self.maxh = maxh self.minh = 0 self.RecalculateRenderedComponents() def RegisterComponent(self, component): mtype = type(component).__name__ if mtype == "Bar": (x, y, w, h) = component.GetRect() (x, y) = component.GetLocalPosition() component.__list_data = [x, y, w, h] if component not in self.components: self.components.append(component) component.Show() def UnregisterComponent(self, component): if component in self.components: self.components.remove(component) component.Hide() def RecalculateRenderedComponents(self): for component in self.components: (xl, yl) = component.GetLocalPosition() (x, y, w, h) = component.GetRect() mtype = type(component).__name__ if mtype == "TextLine": (w, h) = component.GetTextSize() if yl + h < self.minh: component.Hide() elif yl > self.maxh: component.Hide() else: if mtype == "ExpandedImageBox" or mtype == "ExpandedButton": miny = 0 if self.minh > 0 and yl < self.minh: miny = -float(self.minh - yl) / float(h) maxy = 0 if h != 0: maxy = float(self.maxh - yl - h) / float(h) maxy = min(0, max(-1, maxy)) component.SetRenderingRect(0.0, miny, 0.0, maxy) component.Show() elif mtype == "Bar": component.SetSize(w, min(self.maxh + self.minh, h)) component.Show() else: if yl < self.minh or yl + h > self.maxh: component.Hide() else: component.Show() def OnRender(self): x, y = self.GetGlobalPosition() grp.SetColor(self.color) grp.RenderBar(x, y + self.minh, self.GetWidth(), self.maxh - self.minh)
ExpandedButton
class ExpandedButton(ExpandedImageBox):
def __init__(self):
ExpandedImageBox.__init__(self)
self.images = {"UP": "", "OVER": "", "DOWN": ""}
self.state = "NORMAL"
self.xScale = 1.0
self.yScale = 1.0
self.rect = {}
self.isDown = False
self.ButtonText = None
self.eventDict = {}
self.argsDict = {}
def __del__(self):
ExpandedImageBox.__del__(self)
self.eventDict = {}
self.argsDict = {}
def SetScale(self, xScale, yScale):
self.xScale = float(xScale)
self.yScale = float(yScale)
ExpandedImageBox.SetScale(self, xScale, yScale)
def SetRenderingRect(self, left, top, right, bottom):
ExpandedImageBox.SetRenderingRect(self, left, top, right, bottom)
self.rect = (left, top, right, bottom)
def LoadImage(self, imgPath):
ExpandedImageBox.LoadImage(self, imgPath)
if self.xScale and self.yScale:
ExpandedImageBox.SetScale(self, self.xScale, self.yScale)
if self.rect:
self.SetRenderingRect(*self.rect)
def SetUpVisual(self, filename):
self.images["UP"] = filename
if self.state == "NORMAL":
self.LoadImage(filename)
def SetOverVisual(self, filename):
self.images["OVER"] = filename
if self.state == "OVER":
self.LoadImage(filename)
def SetDownVisual(self, filename):
self.images["DOWN"] = filename
if self.state == "DOWN":
self.LoadImage(filename)
def GetUpVisualFileName(self):
return self.images["UP"]
def GetOverVisualFileName(self):
return self.images["OVER"]
def GetDownVisualFileName(self):
return self.images["DOWN"]
def SetTextColor(self, color):
if not self.ButtonText:
return
self.ButtonText.SetPackedFontColor(color)
def SetRGBTextColor(self, r, g, b):
if not self.ButtonText:
return
self.ButtonText.SetFontColor(r, g, b)
def SetTextPosition(self, x, y):
if self.ButtonText:
self.ButtonText.SetHorizontalAlignLeft()
self.ButtonText.SetPosition(x, y)
def SetText(self, text, height=4):
if not self.ButtonText:
textLine = TextLine()
textLine.SetParent(self)
textLine.SetPosition(self.GetWidth() / 2, self.GetHeight() / 2)
textLine.SetVerticalAlignCenter()
textLine.SetHorizontalAlignCenter()
textLine.Show()
self.ButtonText = textLine
self.ButtonText.SetText(text)
def GetText(self):
if self.ButtonText:
return self.ButtonText.GetText()
def IsDown(self):
return self.isDown
def Enable(self):
try:
apply(self.eventDict["ENABLE"], self.argsDict["ENABLE"])
except KeyError:
pass
self.SetUp()
def SetEnableEvent(self, func, *args):
self.eventDict["ENABLE"] = __mem_func__(func)
self.argsDict["ENABLE"] = args
def Disable(self):
try:
apply(self.eventDict["DISABLE"], self.argsDict["DISABLE"])
except KeyError:
pass
self.Down()
def SetDisableEvent(self, func, *args):
self.eventDict["DISABLE"] = __mem_func__(func)
self.argsDict["DISABLE"] = args
def SetUp(self):
self.isDown = False
self.LoadImage(self.images["UP"])
def Down(self):
self.isDown = True
self.LoadImage(self.images["DOWN"])
def OnMouseLeftButtonUp(self):
if self.isDown:
return
self.state = "NORMAL"
if self.IsIn():
self.LoadImage(self.images["OVER"])
snd.PlaySound("sound/ui/click.wav")
try:
apply(self.eventDict["MOUSE_CLICK"], self.argsDict["MOUSE_CLICK"])
except KeyError:
pass
else:
self.LoadImage(self.images["UP"])
def SAFE_SetEvent(self, func, *args):
self.eventDict["MOUSE_CLICK"] = __mem_func__(func)
self.argsDict["MOUSE_CLICK"] = args
def SetEvent(self, func, *args):
self.eventDict["MOUSE_CLICK"] = func
self.argsDict["MOUSE_CLICK"] = args
def SetMouseLeftButtonDownEvent(self, func, *args):
self.eventDict["MOUSE_DOWN"] = func
self.argsDict["MOUSE_DOWN"] = args
def GetEvent(self):
return self.eventFunc, self.eventArgs
def OnMouseOverIn(self):
if self.isDown:
return
self.LoadImage(self.images["OVER"])
def OnMouseOverOut(self):
if self.isDown:
return
self.LoadImage(self.images["UP"])
def OnMouseLeftButtonDown(self):
if self.isDown:
return
self.state = "DOWN"
self.LoadImage(self.images["DOWN"])
try:
apply(self.eventDict["MOUSE_DOWN"], self.argsDict["MOUSE_DOWN"])
except KeyError:
pass
def SetMouseDoubleClickEvent(self, func, *args):
if self.isDown:
return
self.eventDict["MOUSE_DOUBLE_CLICK"] = __mem_func__(func)
self.argsDict["MOUSE_DOUBLE_CLICK"] = args
def OnMouseLeftButtonDoubleClick(self):
if self.isDown:
return
try:
apply(self.eventDict["MOUSE_DOUBLE_CLICK"], self.argsDict["MOUSE_DOUBLE_CLICK"])
except KeyError:
pass