scrollColumnHeader.py (11412B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\control\scrollColumnHeader.py 2 import eveicon 3 from carbonui.primitives.container import Container 4 from carbonui.primitives.sprite import Sprite 5 from eve.client.script.ui.control.eveLabel import EveLabelSmall 6 from eve.client.script.ui.control.themeColored import LineThemeColored 7 import carbonui.const as uiconst 8 import uthread 9 import blue 10 from carbonui.uicore import uicore 11 COLUMNMINSIZE = 24 12 COLUMNMINDEFAULTSIZE = 80 13 SETTING_KEY_STATE = 'ScrollColumnHeader_State' 14 SETTING_KEY_SIZE = 'ScrollColumnHeader_Size' 15 16 class ScrollColumnHeader(Container): 17 default_name = 'ScrollColumnHeader' 18 default_align = uiconst.TOTOP 19 default_height = 16 20 default_state = uiconst.UI_PICKCHILDREN 21 default_clipChildren = True 22 default_padBottom = 0 23 24 def ApplyAttributes(self, attributes): 25 Container.ApplyAttributes(self, attributes) 26 self.settingsID = attributes.settingsID 27 self.scroll = attributes.scroll 28 self.entryClass = attributes.entryClass 29 self.rightAlignedHeaderContainer = Container(parent=self, align=uiconst.TORIGHT) 30 self.headerContainer = Container(parent=self, clipChildren=True) 31 self.columnIDs = [] 32 self.fixedColumns = None 33 self.defaultColumn = None 34 self.minSizeByColumnID = {} 35 if self.scroll and self.entryClass: 36 self.SetDefaultColumn(*self.entryClass.GetDefaultColumnAndDirection()) 37 self.SetMinSizeByColumnID(self.entryClass.GetColumnsMinSize()) 38 self.SetFixedColumns(self.entryClass.GetFixedColumns()) 39 self.SetRightAlignedColumns(self.entryClass.GetRightAlignedColumns()) 40 self.SetStretchColumns(self.entryClass.GetStretchColumns()) 41 self.CreateColumns(self.entryClass.GetColumns()) 42 43 def Close(self, *args): 44 Container.Close(self, *args) 45 self.OnSortingChange = None 46 self.OnColumnSizeChange = None 47 self.OnColumnSizeReset = None 48 self.scroll = None 49 50 def SetDefaultColumn(self, columnID, direction): 51 self.defaultColumn = (columnID, direction) 52 53 def SetRightAlignedColumns(self, rightAlignedColumns): 54 self.rightAlignedColumns = rightAlignedColumns 55 56 def SetStretchColumns(self, stretchColumns): 57 self.stretchColumns = stretchColumns 58 59 def SetMinSizeByColumnID(self, minSizes): 60 self.minSizeByColumnID = minSizes 61 62 def SetFixedColumns(self, fixedColumns): 63 self.fixedColumns = fixedColumns 64 65 def CreateColumns(self, columns): 66 self.headerContainer.Flush() 67 self.rightAlignedHeaderContainer.Flush() 68 self.rightAlignedHeaderContainer.width = 0 69 self.headers = [] 70 self.columnIDs = columns 71 sizes = self.GetColumnSizes() 72 for columnID in columns: 73 isRigthAligned = True if self.rightAlignedColumns and columnID in self.rightAlignedColumns else False 74 isStretchColumn = True if self.stretchColumns and columnID in self.stretchColumns else False 75 header = Container(parent=self.rightAlignedHeaderContainer if isRigthAligned else self.headerContainer, align=uiconst.TOLEFT, state=uiconst.UI_NORMAL) 76 header.OnClick = (self.ClickHeader, header) 77 header.columnID = columnID 78 header.sortTriangle = None 79 if not isStretchColumn: 80 header.OnDblClick = (self.DblClickHeader, header) 81 if self.fixedColumns and columnID not in self.fixedColumns: 82 scaler = Container(parent=header, align=uiconst.TOPRIGHT, width=4, height=self.height - 1, state=uiconst.UI_NORMAL) 83 scaler.OnMouseDown = (self.StartHeaderScale, header) 84 scaler.cursor = uiconst.UICURSOR_LEFT_RIGHT_DRAG 85 label = EveLabelSmall(parent=header, text=columnID, align=uiconst.CENTERLEFT, left=uiconst.LABELTABMARGIN + 8, state=uiconst.UI_DISABLED, maxLines=1) 86 header.label = label 87 if isStretchColumn: 88 header.width = label.width + label.left + 20 89 elif self.fixedColumns and columnID in self.fixedColumns: 90 header.width = self.fixedColumns[columnID] 91 if header.width <= 32: 92 label.Hide() 93 elif columnID in sizes: 94 header.width = max(self.minSizeByColumnID.get(columnID, COLUMNMINSIZE), sizes[columnID]) 95 else: 96 header.width = max(self.minSizeByColumnID.get(columnID, COLUMNMINSIZE), max(COLUMNMINDEFAULTSIZE, label.textwidth + 24)) 97 if isRigthAligned: 98 self.rightAlignedHeaderContainer.width += header.width 99 self.headers.append(header) 100 101 self.UpdateActiveState() 102 103 def UpdateActiveState(self): 104 currentActive, currentDirection = self.GetActiveColumnAndDirection() 105 for each in self.headers: 106 if each.columnID == currentActive: 107 if not each.sortTriangle: 108 each.sortTriangle = Sprite(align=uiconst.CENTERRIGHT, pos=(3, -1, 16, 16), parent=each, name='directionIcon', idx=0) 109 texturePath = eveicon.caret_up if currentDirection else eveicon.caret_down 110 each.sortTriangle.texturePath = texturePath 111 each.sortTriangle.state = uiconst.UI_DISABLED 112 rightMargin = 20 113 else: 114 if each.sortTriangle: 115 each.sortTriangle.Hide() 116 rightMargin = 6 117 each.label.width = each.width - each.label.left - 4 118 if each.sortTriangle and each.sortTriangle.display: 119 each.label.SetRightAlphaFade(each.width - rightMargin - each.label.left, uiconst.SCROLL_COLUMN_FADEWIDTH) 120 else: 121 each.label.SetRightAlphaFade() 122 if each.width <= 32 or each.width - each.label.left - rightMargin - 6 < each.label.textwidth: 123 each.hint = each.label.text 124 else: 125 each.hint = None 126 127 def GetColumns(self): 128 return self.columnIDs 129 130 def GetActiveColumnAndDirection(self): 131 all = settings.char.ui.Get(SETTING_KEY_STATE, {}) 132 currentActive, currentDirection = None, True 133 if self.settingsID in all: 134 currentActive, currentDirection = all[self.settingsID] 135 if currentActive not in self.columnIDs: 136 return (None, True) 137 return (currentActive, currentDirection) 138 if self.defaultColumn is not None: 139 columnID, direction = self.defaultColumn 140 if columnID in self.columnIDs: 141 return self.defaultColumn 142 if self.columnIDs: 143 currentActive, currentDirection = self.columnIDs[0], True 144 return (currentActive, currentDirection) 145 146 def SetActiveColumn(self, columnID, doCallback = True): 147 currentActive, currentDirection = self.GetActiveColumnAndDirection() 148 if currentActive == columnID: 149 sortDirection = not currentDirection 150 else: 151 sortDirection = currentDirection 152 all = settings.char.ui.Get(SETTING_KEY_STATE, {}) 153 all[self.settingsID] = (columnID, sortDirection) 154 settings.char.ui.Set(SETTING_KEY_STATE, all) 155 self.UpdateActiveState() 156 if doCallback: 157 self.OnSortingChange() 158 159 def DblClickHeader(self, header): 160 if not self.ColumnIsFixed(header.columnID): 161 self.SetActiveColumn(header.columnID, doCallback=False) 162 self.OnColumnSizeReset(header.columnID) 163 164 def ClickHeader(self, header): 165 self.SetActiveColumn(header.columnID) 166 167 def StartHeaderScale(self, header, mouseButton, *args): 168 if mouseButton == uiconst.MOUSELEFT: 169 self.startScaleX = uicore.uilib.x 170 self.startScaleWidth = header.width 171 uthread.new(self.ScaleHeader, header) 172 173 def ScaleHeader(self, header): 174 while not self.destroyed and uicore.uilib.leftbtn: 175 diff = self.startScaleX - uicore.uilib.x 176 header.width = max(self.minSizeByColumnID.get(header.columnID, COLUMNMINSIZE), self.startScaleWidth - diff) 177 self.UpdateActiveState() 178 blue.pyos.synchro.Yield() 179 180 currentSizes = self.RegisterCurrentSizes() 181 self.UpdateActiveState() 182 self.OnColumnSizeChange(header.columnID, header.width, currentSizes) 183 184 def GetColumnSizes(self): 185 if self.entryClass: 186 defaultSizes = self.entryClass.GetColumnsDefaultSize() 187 else: 188 defaultSizes = {} 189 current = settings.char.ui.Get(SETTING_KEY_SIZE, {}).get(self.settingsID, defaultSizes) 190 if self.fixedColumns: 191 current.update(self.fixedColumns) 192 for each in self.headers: 193 if hasattr(each, 'columnID') and each.columnID not in current: 194 current[each.columnID] = each.width 195 196 return current 197 198 def GetColumnWidths(self): 199 columnWidthsByName = self.GetColumnSizes() 200 columnWidths = [ columnWidthsByName[header] for header in self.GetColumns() ] 201 return columnWidths 202 203 def ColumnIsFixed(self, columnID): 204 return columnID in self.fixedColumns 205 206 def SetColumnSize(self, columnID, size): 207 if columnID in self.fixedColumns: 208 return 209 columnSize = max(self.minSizeByColumnID.get(columnID, COLUMNMINSIZE), size) 210 for each in self.headers: 211 if hasattr(each, 'columnID') and each.columnID == columnID: 212 each.width = columnSize 213 break 214 215 self.UpdateActiveState() 216 currentSizes = self.RegisterCurrentSizes() 217 self.OnColumnSizeChange(columnID, columnSize, currentSizes) 218 219 def RegisterCurrentSizes(self): 220 sizes = {} 221 for each in self.headers: 222 if hasattr(each, 'columnID'): 223 sizes[each.columnID] = each.width 224 225 all = settings.char.ui.Get(SETTING_KEY_SIZE, {}) 226 all[self.settingsID] = sizes 227 settings.char.ui.Set(SETTING_KEY_SIZE, all) 228 return sizes 229 230 def OnSortingChange(self): 231 if self.scroll and self.entryClass: 232 columns = self.entryClass.GetColumns() 233 activeColumn, columnDirection = self.GetActiveColumnAndDirection() 234 activeColumnIndex = columns.index(activeColumn) 235 236 def GetSortValue(_node): 237 return _node.sortValues[activeColumnIndex] 238 239 sortedScrollNodes = sorted(self.scroll.GetNodes(), key=GetSortValue, reverse=not columnDirection) 240 self.scroll.SetOrderedNodes(sortedScrollNodes) 241 242 def OnColumnSizeChange(self, columnID, newSize, currentSizes): 243 if self.scroll and self.entryClass: 244 columnWidths = self.GetColumnWidths() 245 for node in self.scroll.GetNodes(): 246 node.columnWidths = columnWidths 247 if node.panel: 248 node.panel.OnColumnResize(columnWidths) 249 250 def OnColumnSizeReset(self, columnID): 251 if self.scroll and self.entryClass: 252 minSize = self.minSizeByColumnID.get(columnID, COLUMNMINSIZE) 253 defaultSizes = self.entryClass.GetColumnsDefaultSize() 254 if defaultSizes: 255 resetSize = defaultSizes.get(columnID, minSize) 256 else: 257 resetSize = minSize 258 self.SetColumnSize(columnID, resetSize)