def __init__(self, parent, marketBrowser): wx.TreeCtrl.__init__(self, parent, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT) self.root = self.AddRoot("root") self.imageList = CachingImageList(16, 16) self.SetImageList(self.imageList) self.sMkt = marketBrowser.sMkt self.marketBrowser = marketBrowser # Form market tree root sMkt = self.sMkt for mktGrp in sMkt.getMarketRoot(): iconId = self.addImage(sMkt.getIconByMarketGroup(mktGrp)) childId = self.AppendItem(self.root, mktGrp.name, iconId, data=wx.TreeItemData(mktGrp.ID)) # All market groups which were never expanded are dummies, here we assume # that all root market groups are expandable self.AppendItem(childId, "dummy") self.SortChildren(self.root) # Add recently used modules node rumIconId = self.addImage("market_small", "gui") self.AppendItem(self.root, "Recently Used Modules", rumIconId, data=wx.TreeItemData(RECENTLY_USED_MODULES)) # Bind our lookup method to when the tree gets expanded self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.expandLookup)
def __init__(self, parent, size=wx.DefaultSize, style=0): wx.ListCtrl.__init__(self, parent, size=size, style=wx.LC_REPORT | style) self.imageList = CachingImageList(16, 16) self.SetImageList(self.imageList, wx.IMAGE_LIST_SMALL) self.activeColumns = [] self.columnsMinWidth = [] self.Bind(wx.EVT_LIST_COL_END_DRAG, self.resizeChecker) self.Bind(wx.EVT_LIST_COL_BEGIN_DRAG, self.resizeSkip) if "wxMSW" in wx.PlatformInfo: self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBk) self.mainFrame = gui.mainFrame.MainFrame.getInstance() i = 0 for colName in self.DEFAULT_COLS: if ":" in colName: colName, params = colName.split(":", 1) params = params.split(",") colClass = ViewColumn.getColumn(colName) paramList = colClass.getParameters() paramDict = {} for x, param in enumerate(paramList): name, type, defaultValue = param value = params[x] if len(params) > x else defaultValue value = value if value != "" else defaultValue if type == bool and isinstance(value, basestring): value = bool(value) if value.lower( ) != "false" and value != "0" else False paramDict[name] = value col = colClass(self, paramDict) else: col = ViewColumn.getColumn(colName)(self, None) self.addColumn(i, col) self.columnsMinWidth.append(self.GetColumnWidth(i)) i += 1 info = wx.ListItem() # noinspection PyPropertyAccess info.m_mask = wx.LIST_MASK_WIDTH self.InsertColumnInfo(i, info) self.SetColumnWidth(i, 0) self.imageListBase = self.imageList.ImageCount
def __init__(self, parent, size=wx.DefaultSize, style=0): wx.ListCtrl.__init__(self, parent, size=size, style=wx.LC_REPORT | style) self.imageList = CachingImageList(16, 16) self.SetImageList(self.imageList, wx.IMAGE_LIST_SMALL) self.activeColumns = [] self.columnsMinWidth = [] self.Bind(wx.EVT_LIST_COL_END_DRAG, self.resizeChecker) self.Bind(wx.EVT_LIST_COL_BEGIN_DRAG, self.resizeSkip) self.mainFrame = gui.mainFrame.MainFrame.getInstance() for i, colName in enumerate(self.DEFAULT_COLS): self.insertColumnBySpec(i, colName) self.imageListBase = self.imageList.ImageCount
class MarketTree(wx.TreeCtrl): def __init__(self, parent, marketBrowser): wx.TreeCtrl.__init__(self, parent, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT) pyfalog.debug("Initialize marketTree") self.root = self.AddRoot("root") self.imageList = CachingImageList(16, 16) self.SetImageList(self.imageList) self.sMkt = marketBrowser.sMkt self.marketBrowser = marketBrowser # Form market tree root sMkt = self.sMkt for mktGrp in sMkt.getMarketRoot(): iconId = self.addImage(sMkt.getIconByMarketGroup(mktGrp)) childId = self.AppendItem(self.root, mktGrp.nameCn, iconId, data=mktGrp.ID) # All market groups which were never expanded are dummies, here we assume # that all root market groups are expandable self.AppendItem(childId, "dummy") self.SortChildren(self.root) # Add recently used modules node rumIconId = self.addImage("market_small", "gui") self.AppendItem(self.root, "最近使用的装备", rumIconId, data=RECENTLY_USED_MODULES) # Bind our lookup method to when the tree gets expanded self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.expandLookup) self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnCollapsed) def addImage(self, iconFile, location="icons"): if iconFile is None: return -1 return self.imageList.GetImageIndex(iconFile, location) def expandLookup(self, event): """Process market tree expands""" root = event.Item child = self.GetFirstChild(root)[0] # If child of given market group is a dummy if self.GetItemText(child) == "dummy": # Delete it self.Delete(child) # And add real market group contents sMkt = self.sMkt currentMktGrp = sMkt.getMarketGroup(self.GetItemData(root), eager="children") for childMktGrp in sMkt.getMarketGroupChildren(currentMktGrp): # If market should have items but it doesn't, do not show it if sMkt.marketGroupValidityCheck(childMktGrp) is False: continue iconId = self.addImage(sMkt.getIconByMarketGroup(childMktGrp)) try: childId = self.AppendItem(root, childMktGrp.nameCn, iconId, data=childMktGrp.ID) except Exception as e: pyfalog.debug("Error appending item.") pyfalog.debug(e) continue if sMkt.marketGroupHasTypesCheck(childMktGrp) is False: self.AppendItem(childId, "dummy") self.SortChildren(root) def OnCollapsed(self, event): self.CollapseAllChildren(event.Item) event.Skip() def jump(self, item): """Open market group and meta tab of given item""" sMkt = self.sMkt mg = sMkt.getMarketGroupByItem(item) jumpList = [] while mg is not None: jumpList.append(mg.ID) mg = mg.parent for id in sMkt.ROOT_MARKET_GROUPS: if id in jumpList: jumpList = jumpList[:jumpList.index(id) + 1] item = self.root for i in range(len(jumpList) - 1, -1, -1): target = jumpList[i] child, cookie = self.GetFirstChild(item) while self.GetItemData(child) != target: child, cookie = self.GetNextChild(item, cookie) item = child self.Expand(item) self.SelectItem(item)
class Display(wx.ListCtrl): def __init__(self, parent, size = wx.DefaultSize, style = 0): wx.ListCtrl.__init__(self, parent,size = size, style=wx.LC_REPORT | style ) self.imageList = CachingImageList(16, 16) self.SetImageList(self.imageList, wx.IMAGE_LIST_SMALL) self.activeColumns = [] self.columnsMinWidth = [] self.Bind(wx.EVT_LIST_COL_END_DRAG, self.resizeChecker) self.Bind(wx.EVT_LIST_COL_BEGIN_DRAG, self.resizeSkip) if "wxMSW" in wx.PlatformInfo: self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBk) self.mainFrame = gui.mainFrame.MainFrame.getInstance() i = 0 for colName in self.DEFAULT_COLS: if ":" in colName: colName, params = colName.split(":", 1) params = params.split(",") colClass = ViewColumn.getColumn(colName) paramList = colClass.getParameters() paramDict = {} for x, param in enumerate(paramList): name, type, defaultValue = param value = params[x] if len(params) > x else defaultValue value = value if value != "" else defaultValue if type == bool and isinstance(value, basestring): value = bool(value) if value.lower() != "false" and value != "0" else False paramDict[name] = value col = colClass(self, paramDict) else: col = ViewColumn.getColumn(colName)(self, None) self.addColumn(i, col) self.columnsMinWidth.append(self.GetColumnWidth(i)) i += 1 info = wx.ListItem() info.m_mask = wx.LIST_MASK_WIDTH self.InsertColumnInfo(i, info) self.SetColumnWidth(i, 0) self.imageListBase = self.imageList.ImageCount # Override native HitTestSubItem (doesn't work as it should on GTK) # Source: ObjectListView def HitTestSubItem(self, pt): """ Return a tuple indicating which (item, subItem) the given pt (client coordinates) is over. This uses the built-in version on Windows, and poor mans replacement on other platforms. """ # The buildin version works on Windows if wx.Platform == "__WXMSW__": return wx.ListCtrl.HitTestSubItem(self, pt) (rowIndex, flags) = self.HitTest(pt) # Did the point hit any item? if (flags & wx.LIST_HITTEST_ONITEM) == 0: return (-1, 0, -1) # If it did hit an item and we are not in report mode, it must be the primary cell if not self.InReportView(): return (rowIndex, wx.LIST_HITTEST_ONITEM, 0) # Find which subitem is hit right = 0 scrolledX = self.GetScrollPos(wx.HORIZONTAL) * wx.SystemSettings.GetMetric(wx.SYS_HSCROLL_Y) + pt.x for i in range(self.GetColumnCount()): left = right right += self.GetColumnWidth(i) if scrolledX < right: if (scrolledX - left) < self.imageList.GetSize(0)[0]: flag = wx.LIST_HITTEST_ONITEMICON else: flag = wx.LIST_HITTEST_ONITEMLABEL return (rowIndex, flag, i) return (rowIndex, 0, -1) def OnEraseBk(self,event): if self.GetItemCount() >0: width, height = self.GetClientSize() dc = event.GetDC() dc.DestroyClippingRegion() dc.SetClippingRegion(0, 0, width, height) x,y,w,h = dc.GetClippingBox() topItem = self.GetTopItem() bottomItem = topItem + self.GetCountPerPage() if bottomItem >= self.GetItemCount(): bottomItem = self.GetItemCount() - 1 topRect = self.GetItemRect(topItem, wx.LIST_RECT_LABEL) bottomRect = self.GetItemRect(bottomItem, wx.LIST_RECT_BOUNDS) items_rect = wx.Rect(topRect.left, 0, bottomRect.right - topRect.left, bottomRect.bottom ) updateRegion = wx.Region(x,y,w,h) updateRegion.SubtractRect(items_rect) dc.DestroyClippingRegion() dc.SetClippingRegionAsRegion(updateRegion) dc.SetBackground(wx.Brush(self.GetBackgroundColour(), wx.SOLID)) dc.Clear() dc.DestroyClippingRegion() else: event.Skip() def addColumn(self, i, col): self.activeColumns.append(col) info = wx.ListItem() info.m_mask = col.mask | wx.LIST_MASK_FORMAT | wx.LIST_MASK_WIDTH info.m_image = col.imageId info.m_text = col.columnText info.m_width = -1 info.m_format = wx.LIST_FORMAT_LEFT self.InsertColumnInfo(i, info) col.resized = False if i == 0 and col.size != wx.LIST_AUTOSIZE_USEHEADER: col.size += 4 self.SetColumnWidth(i, col.size) def getColIndex(self, colClass): for i, col in enumerate(self.activeColumns): if col.__class__ == colClass: return i return None def resizeChecker(self, event): # we veto header cell resize by default till we find a way # to assure a minimal size for the resized header cell column = event.GetColumn() wx.CallAfter(self.checkColumnSize,column) event.Skip() def resizeSkip(self, event): column = event.GetColumn() if column > len (self.activeColumns)-1: self.SetColumnWidth(column, 0) event.Veto() return colItem = self.activeColumns[column] if self.activeColumns[column].maxsize != -1: event.Veto() else: event.Skip() def checkColumnSize(self,column): colItem = self.activeColumns[column] if self.GetColumnWidth(column) < self.columnsMinWidth[column]: self.SetColumnWidth(column,self.columnsMinWidth[column]) colItem.resized = True def getLastItem( self, state = wx.LIST_STATE_DONTCARE): lastFound = -1 while True: index = self.GetNextItem( lastFound, wx.LIST_NEXT_ALL, state, ) if index == -1: break else: lastFound = index return lastFound def deselectItems(self): sel = self.GetFirstSelected() while sel != -1: self.SetItemState(sel, 0, wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED) sel = self.GetNextSelected(sel) def populate(self, stuff): if stuff is not None: listItemCount = self.GetItemCount() stuffItemCount = len(stuff) if listItemCount < stuffItemCount: for i in xrange(stuffItemCount - listItemCount): index = self.InsertStringItem(sys.maxint, "") if listItemCount > stuffItemCount: if listItemCount - stuffItemCount > 20 and stuffItemCount < 20: self.DeleteAllItems() for i in xrange(stuffItemCount): index = self.InsertStringItem(sys.maxint, "") else: for i in xrange(listItemCount - stuffItemCount): self.DeleteItem(self.getLastItem()) self.Refresh() def refresh(self, stuff): if stuff == None: return item = -1 for id, st in enumerate(stuff): item = self.GetNextItem(item) for i, col in enumerate(self.activeColumns): colItem = self.GetItem(item, i) oldText = colItem.GetText() oldImageId = colItem.GetImage() newText = col.getText(st) if newText is False: col.delayedText(st, self, colItem) newText = "" newImageId = col.getImageId(st) colItem.SetText(newText) colItem.SetImage(newImageId) mask = 0 if oldText != newText: mask |= wx.LIST_MASK_TEXT colItem.SetText(newText) if oldImageId != newImageId: mask |= wx.LIST_MASK_IMAGE colItem.SetImage(newImageId) if mask: colItem.SetMask(mask) self.SetItem(colItem) self.SetItemData(item, id) # self.Freeze() if 'wxMSW' in wx.PlatformInfo: for i,col in enumerate(self.activeColumns): if not col.resized: self.SetColumnWidth(i, col.size) else: for i, col in enumerate(self.activeColumns): if not col.resized: if col.size == wx.LIST_AUTOSIZE_USEHEADER: self.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER) headerWidth = self.GetColumnWidth(i) self.SetColumnWidth(i, wx.LIST_AUTOSIZE) baseWidth = self.GetColumnWidth(i) if baseWidth < headerWidth: self.SetColumnWidth(i, headerWidth) else: self.SetColumnWidth(i, col.size) # self.Thaw() def update(self, stuff): self.populate(stuff) self.refresh(stuff) def getColumn(self, point): row, _, col = self.HitTestSubItem(point) return col
class Display(wx.ListCtrl): DEFAULT_COLS = None def __init__(self, parent, size=wx.DefaultSize, style=0): wx.ListCtrl.__init__(self, parent, size=size, style=wx.LC_REPORT | style) self.imageList = CachingImageList(16, 16) self.SetImageList(self.imageList, wx.IMAGE_LIST_SMALL) self.activeColumns = [] self.columnsMinWidth = [] self.Bind(wx.EVT_LIST_COL_END_DRAG, self.resizeChecker) self.Bind(wx.EVT_LIST_COL_BEGIN_DRAG, self.resizeSkip) self.mainFrame = gui.mainFrame.MainFrame.getInstance() i = 0 for colName in self.DEFAULT_COLS: if ":" in colName: colName, params = colName.split(":", 1) params = params.split(",") colClass = ViewColumn.getColumn(colName) paramList = colClass.getParameters() paramDict = {} for x, param in enumerate(paramList): name, type, defaultValue = param value = params[x] if len(params) > x else defaultValue value = value if value != "" else defaultValue if type == bool and isinstance(value, str): value = bool(value) if value.lower() != "false" and value != "0" else False paramDict[name] = value col = colClass(self, paramDict) else: col = ViewColumn.getColumn(colName)(self, None) self.addColumn(i, col) self.columnsMinWidth.append(self.GetColumnWidth(i)) i += 1 info = wx.ListItem() # noinspection PyPropertyAccess info.m_mask = wx.LIST_MASK_WIDTH self.InsertColumn(i, info) self.SetColumnWidth(i, 0) self.imageListBase = self.imageList.ImageCount # Override native HitTestSubItem (doesn't work as it should on GTK) # Source: ObjectListView def HitTestSubItem(self, pt): """ Return a tuple indicating which (item, subItem) the given pt (client coordinates) is over. This uses the built-in version on Windows, and poor mans replacement on other platforms. """ # The buildin version works on Windows if wx.Platform == "__WXMSW__": return wx.ListCtrl.HitTestSubItem(self, pt) (rowIndex, flags) = self.HitTest(pt) # Did the point hit any item? if (flags & wx.LIST_HITTEST_ONITEM) == 0: return -1, 0, -1 # If it did hit an item and we are not in report mode, it must be the primary cell if not self.InReportView(): return rowIndex, wx.LIST_HITTEST_ONITEM, 0 # Find which subitem is hit right = 0 scrolledX = self.GetScrollPos(wx.HORIZONTAL) * wx.SystemSettings.GetMetric(wx.SYS_HSCROLL_Y) + pt.x for i in range(self.GetColumnCount()): left = right right += self.GetColumnWidth(i) if scrolledX < right: if (scrolledX - left) < self.imageList.GetSize(0)[0]: flag = wx.LIST_HITTEST_ONITEMICON else: flag = wx.LIST_HITTEST_ONITEMLABEL return rowIndex, flag, i return rowIndex, 0, -1 # noinspection PyPropertyAccess def addColumn(self, i, col): self.activeColumns.append(col) info = wx.ListItem() info.SetMask(col.mask | wx.LIST_MASK_FORMAT | wx.LIST_MASK_WIDTH) info.SetImage(col.imageId) info.SetText(col.columnText) info.SetWidth(-1) info.SetAlign(wx.LIST_FORMAT_LEFT) self.InsertColumn(i, info) col.resized = False if i == 0 and col.size != wx.LIST_AUTOSIZE_USEHEADER: col.size += 4 self.SetColumnWidth(i, col.size) def getColIndex(self, colClass): for i, col in enumerate(self.activeColumns): if col.__class__ == colClass: return i return None def resizeChecker(self, event): # we veto header cell resize by default till we find a way # to assure a minimal size for the resized header cell column = event.GetColumn() wx.CallAfter(self.checkColumnSize, column) event.Skip() def resizeSkip(self, event): column = event.GetColumn() if column > len(self.activeColumns) - 1: self.SetColumnWidth(column, 0) event.Veto() return # colItem = self.activeColumns[column] if self.activeColumns[column].maxsize != -1: event.Veto() else: event.Skip() def checkColumnSize(self, column): colItem = self.activeColumns[column] if self.GetColumnWidth(column) < self.columnsMinWidth[column]: self.SetColumnWidth(column, self.columnsMinWidth[column]) colItem.resized = True def getLastItem(self, state=wx.LIST_STATE_DONTCARE): lastFound = -1 while True: index = self.GetNextItem(lastFound, wx.LIST_NEXT_ALL, state) if index == -1: break else: lastFound = index return lastFound def unselectAll(self): sel = self.GetFirstSelected() while sel != -1: self.Select(sel, False) sel = self.GetNextSelected(sel) def selectAll(self): for row in range(self.GetItemCount()): self.Select(row, True) def populate(self, stuff): if stuff is not None: listItemCount = self.GetItemCount() stuffItemCount = len(stuff) if listItemCount < stuffItemCount: for i in range(stuffItemCount - listItemCount): self.InsertItem(self.GetItemCount(), "") if listItemCount > stuffItemCount: if listItemCount - stuffItemCount > 20 > stuffItemCount: self.DeleteAllItems() for i in range(stuffItemCount): self.InsertItem(self.GetItemCount(), "") else: for i in range(listItemCount - stuffItemCount): self.DeleteItem(self.getLastItem()) self.Refresh() def refresh(self, stuff): if stuff is None: return item = -1 for id_, st in enumerate(stuff): item = self.GetNextItem(item) for i, col in enumerate(self.activeColumns): colItem = self.GetItem(item, i) oldText = colItem.GetText() oldImageId = colItem.GetImage() oldColour = colItem.GetBackgroundColour() newText = col.getText(st) if newText is False: col.delayedText(st, self, colItem) newText = "\u21bb" newColour = self.columnBackground(colItem, st) newImageId = col.getImageId(st) colItem.SetText(newText) colItem.SetImage(newImageId) colItem.SetBackgroundColour(newColour) mask = 0 if oldText != newText: mask |= wx.LIST_MASK_TEXT colItem.SetText(newText) if oldImageId != newImageId: mask |= wx.LIST_MASK_IMAGE colItem.SetImage(newImageId) if mask: colItem.SetMask(mask) self.SetItem(colItem) else: if newColour != oldColour: self.SetItem(colItem) self.SetItemData(item, id_) # self.Freeze() if 'wxMSW' in wx.PlatformInfo: for i, col in enumerate(self.activeColumns): if not col.resized: self.SetColumnWidth(i, col.size) else: for i, col in enumerate(self.activeColumns): if not col.resized: if col.size == wx.LIST_AUTOSIZE_USEHEADER: self.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER) headerWidth = self.GetColumnWidth(i) self.SetColumnWidth(i, wx.LIST_AUTOSIZE) baseWidth = self.GetColumnWidth(i) if baseWidth < headerWidth: self.SetColumnWidth(i, headerWidth) else: self.SetColumnWidth(i, col.size) # self.Thaw() def update(self, stuff): self.populate(stuff) self.refresh(stuff) def getColumn(self, point): row, _, col = self.HitTestSubItem(point) return col def columnBackground(self, colItem, item): return colItem.GetBackgroundColour() def getRowByAbs(self, pointAbs): if pointAbs == wx.Point(-1, -1): return -1 pointRel = self.screenToClientFixed(pointAbs) row, flags = self.HitTest(pointRel) return row def screenToClientFixed(self, ptScreen): """ Wx' ScreenToClient implementation seems to not consider header row height when converting to screen position: https://github.com/wxWidgets/Phoenix/issues/1213 Do it ourselves here. """ if ptScreen == wx.Point(-1, -1): return wx.Point(-1, -1) ptClient = self.GetMainWindow().ScreenToClient(ptScreen) return ptClient def getSelectedRows(self): rows = [] row = self.GetFirstSelected() while row != -1: rows.append(row) row = self.GetNextSelected(row) return rows