Używam tych samych Pythonowych klas we wszystkich moich projektach. Nie zamieszczam ich za każdym razem. Jeśli jeszcze ich nie masz, skopiuj je stąd. Do nawigacji użyj funkcji szukaj w swojej przeglądarce.
Jeśli nie znalazłeś, czego szukasz, napisz do mnie, wyślę.
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