On 28/05/2013 at 11:40, xxxxxxxx wrote:
Hi Rui,
this is a very very old implementation of a simple ListView of mine. I've used it in Description Editor
plugin. Works relatively fine, very basic. Please don't judge my coding style, this snippet is about 2
years old. :)
Maybe you can use it.
class ListView(GeUserArea) :
MOUSEWHEEL_MODE = 1027215 # Registered at Plugincafe.com
SELECTEDROW_UP = 1027216 # Registered at Plugincafe.com
SELECTEDROW_DOWN = 1027217 # Registered at Plugincafe.com
SELECTEDROW_CHANGED = 1027218 # Registered at Plugincafe.com
SELECTEDROW_PREVIOUS = 1027219 # Registered at Plugincafe.com
colors = {
"background": Vector(.2),
"lighterRow": Vector(.31),
"darkerRow": Vector(.29),
"markedRow": Vector(.38),
"text": Vector(.64705),
"markedText": Vector(1., .66, .024)
}
def __init__(
self,
parentDialog = None, # The parent-dialog, can be None if the 'Command'-Method should not be invoked on an Input-Event
initialData = (()), # Data to display, must be 2 dimensional
rowHeight = 16, # Height of a row in the ListView
columnWidths = (100,), # Widths of the columns in the ListView
minSize = (300, 100), # Minimum size of the area. If second is None, it will be calculated.
) :
self.parentDialog = parentDialog
self.rowHeight = rowHeight
self.columnWidths = tuple(columnWidths)
self.data = list(initialData)
self.selectedRow = -1
self.minSize = tuple(minSize)
# Overriden
def DrawMsg(self, x1, y1, x2, y2, msg) :
""" Called when redrawing the UserArea """
self.SetClippingRegion(x1, y1, x2, y2)
self.DrawSetPen(self.colors["background"]) # Set Background Color
self.DrawRectangle(x1, y1, x2, y2) # Fill Background
"""
Draw lighter rows
"""
self.DrawSetPen(self.colors["lighterRow"])
for i in xrange(0,len(self.data), 2) : # Iterate the specified rows
Rectangle = {
'x1': 0,
'x2': x2,
'y1': self.rowHeight * i,
'y2': self.rowHeight * (i + 1)
}
# If the selected Row is about to be drawn
if i == self.selectedRow and self.colors["markedRow"]:
self.DrawSetPen(self.colors["markedRow"])
self.DrawRectangle(**Rectangle)
self.DrawSetPen(self.colors["lighterRow"])
else:
self.DrawRectangle(**Rectangle)
"""
Draw darker rows
"""
self.DrawSetPen(self.colors["darkerRow"])
for i in xrange(1,len(self.data), 2) : # Iterate the specified rows
Rectangle = {
'x1': 0,
'x2': x2,
'y1': self.rowHeight * i,
'y2': self.rowHeight * (i + 1)
}
# If the selected Row is about to be drawn
if i == self.selectedRow and self.colors["markedRow"]:
self.DrawSetPen(self.colors["markedRow"])
self.DrawRectangle(**Rectangle)
self.DrawSetPen(self.colors["darkerRow"])
else:
self.DrawRectangle(**Rectangle)
"""
Draw data.
"""
self.DrawSetTextCol(self.colors["text"], c4d.COLOR_TRANS)
for i in xrange(len(self.data)) : # Iterate the specified rows
previousItemPosX = x1 + 5
for j in xrange(len(self.data[i])) : # Iterate the datas columns
if j >= len(self.columnWidths) :
width = self.columnWidths[-1]
else:
width = self.columnWidths[j]
textToDraw = str(self.data[i][j])
# If the selected Row is about to be drawn
if i == self.selectedRow:
self.DrawSetTextCol(self.colors["markedText"], c4d.COLOR_TRANS)
self.DrawText( txt = textToDraw,
x1 = x1 + previousItemPosX ,
y1 = y1 + i * self.rowHeight + self.rowHeight - 14,
)
self.DrawSetTextCol(self.colors["text"], c4d.COLOR_TRANS)
else:
self.DrawText( txt = textToDraw,
x1 = x1 + previousItemPosX ,
y1 = y1 + i * self.rowHeight + self.rowHeight - 14,
)
previousItemPosX += width
def InputEvent(self, msg) :
inputChannel = msg[c4d.BFM_INPUT_CHANNEL]
# Left or Right Mousebutton
if inputChannel in (c4d.BFM_INPUT_MOUSELEFT, c4d.BFM_INPUT_MOUSERIGHT, c4d.BFM_INPUT_MOUSEMIDDLE) :
positionInDialog = self.Global2Local()
mousePosX = msg[c4d.BFM_INPUT_X] + positionInDialog["x"]
mousePosY = msg[c4d.BFM_INPUT_Y] + positionInDialog["y"]
clickedRow = int(mousePosY/self.rowHeight)
msg[self.SELECTEDROW_PREVIOUS] = self.selectedRow
if clickedRow > len(self.data) - 1:
self.selectedRow = -1
else:
self.selectedRow = clickedRow
self.Redraw()
# MouseWheel switching of elements
elif inputChannel == c4d.BFM_INPUT_MOUSEWHEEL:
inputValue = msg[c4d.BFM_INPUT_VALUE]
selectedRow = self.selectedRow
# Go up (in visual), means to go back in the list
if inputValue > 0:
# Do not if data-begin is reached
if selectedRow > 0:
if self.parentDialog:
bc = c4d.BaseContainer()
bc[self.MOUSEWHEEL_MODE] = self.SELECTEDROW_UP
bc[self.SELECTEDROW_CHANGED] = -1 # Selected row + SELECTEDROW_CHANGED = newSelectedRow
self.parentDialog.Command(self.GetId(), bc)
self.selectedRow -= 1
# Go down (in visual), means to go further in the list
elif inputValue < 0:
# Do not if data-end is reached
if selectedRow <= len(self.data) -2:
if self.parentDialog:
bc = c4d.BaseContainer()
bc[self.MOUSEWHEEL_MODE] = self.SELECTEDROW_DOWN
bc[self.SELECTEDROW_CHANGED] = 1 # Selected row + SELECTEDROW_CHANGED = newSelectedRow
self.parentDialog.Command(self.GetId(), bc)
self.selectedRow += 1
self.Redraw()
# if parentDialog is defined, send Command-Message
if self.parentDialog:
self.parentDialog.Command(self.GetId(), msg)
return True
def GetMinSize(self) :
""" Returns the minimum size of the area. """
return tuple(self.minSize)
# Getters
def GetMinHeight(self) :
return self.minSize[1]
def GetSelectedRow(self) :
return self.selectedRow
def GetRowHeight(self) :
return self.rowHeight
def GetColumnWidths(self) :
return self.columnWidths
def GetParentDialog(self) :
return self.parentDialog
# Setters
def SetColors(self, **kwargs) :
for k, v in kwargs.iteritems() :
if k in self.colors.keys() :
self.colors[k] = v
def SetData(self, data) :
self.data = data
def SetRowHeight(self, height) :
self.rowHeight = height
self.minSize[1] = self.rowHeight * len(self.data)
def SetColumnWidths(self, columnWidths) :
self.columnWidths = columnWidths
def SetSelectedRow(self, index) :
if index >= len(self.data) :
self.selectedRow = -1
return False
else:
self.selectedRow = index
return True
def SetParentDialog(self, parent) :
self.parentDialog = parent
# Adders
def AppendData(self, data) :
self.data.append(data)
def InsertData_AtIndex(self, data, index) :
if index > len( self.data ) :
return False
else:
self.data.insert(index, data)
# Removers
def RemoveData(self, subData) :
if subData in self.data:
del self.data[ self.data.index(subData) ]
return True
else:
return False
def RemoveData_ByIndex(self, index) :
if index > len( self.data ) :
return False
else:
del self.data[index]
# Update
pass
-Nik