entries.py (15315B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\market\entries.py 2 import eveicon 3 from carbonui.control.contextMenu.menuData import MenuData 4 from carbon.common.script.sys.serviceConst import ROLE_GML, ROLE_QA 5 from carbonui.control.contextMenu.menuDataFactory import CreateMenuDataFromRawTuples 6 from carbonui.control.contextMenu.menuEntryData import MenuEntryData 7 from carbonui.control.dragdrop.dragdata import TypeDragData 8 from chroma import Color 9 from eve.client.script.ui.shared.market.util import does_global_market_apply 10 from eve.client.script.ui import eveColor 11 from eve.client.script.ui.control.entries.generic import Generic 12 from eve.client.script.ui.shared.market.util import should_show_location_info 13 from menu import MenuLabel 14 from carbonui import uiconst, TextColor 15 from carbonui.primitives.container import Container 16 from carbonui.primitives.fill import Fill 17 from carbonui.primitives.sprite import Sprite 18 from eve.client.script.ui.control.listgroup import ListGroup 19 from eve.client.script.ui.shared.fitting.ghostFittingHelpers import TryPreviewFitItemOnMouseAction 20 import localization 21 from eve.common.script.util.eveFormat import GetAveragePrice, FmtISKAndRound 22 from marketutil.quickbarUtil import GetTypesUnderFolder, TICKER_SETTING_NAME, TICKER_MAX_ITEMS_FROM_QUICKBAR 23 from player_messaging.client.ui_message import prompt_player_fsd_dialog 24 from shipfitting.multiBuyUtil import BuyMultipleTypesWithQty 25 import evetypes 26 from carbonui.uicore import uicore 27 from eveservices.menu import GetMenuService 28 import blue 29 BLUE_COLOR = Color.from_rgba(*eveColor.ULTRAMARINE_BLUE) 30 GREEN_COLOR = Color.from_rgba(*eveColor.SUCCESS_GREEN) 31 YELLOW_COLOR = Color.from_rgba(*eveColor.SAND_YELLOW) 32 BACKGROUND_OPACITY = 0.3 33 34 class MarketOrder(Generic): 35 __guid__ = 'listentry.MarketOrder' 36 37 def Startup(self, *args): 38 Generic.Startup(self, args) 39 self.sr.bgFill = None 40 self.orderMarker = None 41 42 def Load(self, node): 43 Generic.Load(self, node) 44 data = self.sr.node 45 show_path_info = data.inMyPath and not does_global_market_apply(data.typeID) 46 if show_path_info: 47 self.sr.label.color = YELLOW_COLOR 48 if data.markAsMine: 49 self.ShowBackground(BLUE_COLOR.with_alpha(BACKGROUND_OPACITY)) 50 self.ShowOrderMarker(eveicon.person, BLUE_COLOR) 51 elif data.flag == 1 and data.mode == 'sell': 52 self.ShowBackground(color=GREEN_COLOR.with_alpha(BACKGROUND_OPACITY)) 53 self.ShowOrderMarker(eveicon.checkmark, GREEN_COLOR) 54 else: 55 if show_path_info: 56 self.ShowOrderMarker(eveicon.location, YELLOW_COLOR) 57 elif self.orderMarker: 58 self.orderMarker.display = False 59 if self.sr.bgFill: 60 self.sr.bgFill.display = False 61 if data.isLabelOffset: 62 self.sr.label.left = 20 63 64 def ShowBackground(self, color, *args): 65 if self.sr.bgFill is None: 66 self.sr.bgFill = Fill(bgParent=self, color=color, state=uiconst.UI_DISABLED) 67 self.sr.bgFill.SetRGBA(*color) 68 self.sr.bgFill.display = True 69 70 def ShowOrderMarker(self, texturePath, color): 71 if self.orderMarker is None or self.orderMarker.destroyed: 72 self.orderMarker = Sprite(parent=self, align=uiconst.CENTERLEFT, pos=(2, 0, 16, 16), state=uiconst.UI_NORMAL) 73 self.orderMarker.LoadTooltipPanel = self.LoadMarkerTooltipPanel 74 self.orderMarker.texturePath = texturePath 75 self.orderMarker.SetRGBA(*color) 76 self.orderMarker.display = True 77 78 def Buy(self, node = None, ignoreAdvanced = False, *args): 79 if not hasattr(self, 'sr'): 80 return 81 node = node if node is not None else self.sr.node 82 sm.GetService('marketutils').Buy(self.sr.node.order.typeID, node.order, 0, ignoreAdvanced=ignoreAdvanced) 83 84 def ShowInfo(self, node = None, *args): 85 node = node if node is not None else self.sr.node 86 sm.GetService('info').ShowInfo(node.order.typeID) 87 88 def GetMenu(self): 89 self.OnClick() 90 m = [] 91 if self.sr.node.mode == 'buy': 92 m.append((MenuLabel('UI/Market/Marketbase/BuyThis'), self.Buy, (self.sr.node, True))) 93 else: 94 m += [(MenuLabel('UI/Market/Marketbase/CommandPlaceBuyOrder'), self.Buy)] 95 m.append(None) 96 m += [(MenuLabel('UI/Commands/ShowInfo'), self.ShowInfo, (self.sr.node,))] 97 if should_show_location_info(self.sr.node.order.typeID): 98 stationID = self.sr.node.order.stationID 99 solarSystemID = self.sr.node.order.solarSystemID 100 if stationID: 101 stationInfo = sm.GetService('ui').GetStationStaticInfo(stationID) 102 if stationInfo: 103 m.append(MenuEntryData(MenuLabel('UI/Common/Location'), subMenuData=GetMenuService().CelestialMenu(stationID, typeID=stationInfo.stationTypeID, parentID=stationInfo.solarSystemID, mapItem=None), texturePath=eveicon.location)) 104 else: 105 structureInfo = sm.GetService('structureDirectory').GetStructureInfo(stationID) 106 if structureInfo: 107 m.append(MenuEntryData(MenuLabel('UI/Common/Location'), subMenuData=GetMenuService().CelestialMenu(stationID, typeID=structureInfo.typeID, parentID=stationID), texturePath=eveicon.location)) 108 elif solarSystemID: 109 m += [(MenuLabel('UI/Common/SolarSystem'), GetMenuService().CelestialMenu(solarSystemID))] 110 if self.sr.node.markAsMine: 111 m.append((MenuLabel('UI/Market/Orders/ModifyOrder'), self.ModifyPrice, (self.sr.node,))) 112 m.append((MenuLabel('UI/Market/Orders/CancelOrder'), self.CancelOffer, (self.sr.node,))) 113 if session.role & ROLE_QA: 114 m.append(('GM / WM Extras', self._GetGMMenu())) 115 return m 116 117 def _GetGMMenu(self): 118 ret = [] 119 ret.append(('OrderID: %s' % (self.sr.node.order.orderID,), blue.pyos.SetClipboardData, [str(self.sr.node.order.orderID)])) 120 return ret 121 122 def _GetStationInvItemInBallpark(self, stationID): 123 ballpark = sm.GetService('michelle').GetBallpark() 124 if not ballpark: 125 return None 126 return ballpark.GetInvItem(stationID) 127 128 def OnDblClick(self, *args): 129 if self.sr.node.mode == 'buy': 130 self.Buy(ignoreAdvanced=True) 131 132 def ModifyPrice(self, node): 133 sm.GetService('marketutils').ModifyOrder(node.order) 134 135 def CancelOffer(self, node): 136 sm.GetService('marketutils').CancelOffer(node.order) 137 138 def LoadMarkerTooltipPanel(self, tooltipPanel, *args): 139 data = self.sr.node 140 tooltipPanel.LoadGeneric2ColumnTemplate() 141 markAsMine = data.markAsMine 142 canSellToOrder = data.flag 143 inMyPath = data.inMyPath and not does_global_market_apply(data.typeID) 144 145 def AddSprite(texturePath, color): 146 Sprite(parent=tooltipPanel, align=uiconst.CENTERLEFT, pos=(0, 0, 16, 16), texturePath=texturePath, color=color) 147 148 if markAsMine: 149 AddSprite(eveicon.person, BLUE_COLOR) 150 text = localization.GetByLabel('UI/Market/Marketbase/YourOrderHint') 151 tooltipPanel.AddLabelMedium(text=text) 152 elif canSellToOrder: 153 AddSprite(eveicon.checkmark, GREEN_COLOR) 154 text = localization.GetByLabel('UI/Market/Marketbase/CanSellToOrderHint') 155 tooltipPanel.AddLabelMedium(text=text, wrapWidth=200) 156 if inMyPath: 157 AddSprite(eveicon.location, YELLOW_COLOR) 158 text = localization.GetByLabel('UI/Market/Marketbase/InRouteHint') 159 tooltipPanel.AddLabelMedium(text=text, wrapWidth=200) 160 161 162 class MarketListGroup(ListGroup): 163 164 def GetMenu(self): 165 m = super(MarketListGroup, self).GetMenu() 166 if session.role & ROLE_GML: 167 market_group_info = self.sr.node.get('marketGroupInfo', None) 168 if market_group_info: 169 m.append(MenuEntryData('QA: MarketGroupID={}'.format(market_group_info.marketGroupID), func=lambda : blue.pyos.SetClipboardData(str(market_group_info.marketGroupID)))) 170 return m 171 172 173 class GenericMarketItem(Generic): 174 __guid__ = 'listentry.GenericMarketItem' 175 isDragObject = True 176 177 def Startup(self, *args): 178 labelCont = Container(name='labelCont', parent=self, padRight=20) 179 Generic.Startup(self, *args) 180 self.sr.label.SetParent(labelCont) 181 182 def Load(self, node): 183 Generic.Load(self, node) 184 self.sr.label.autoFadeSides = 16 185 if not node.get('inRange', True): 186 self.SetOpacity(0.5) 187 self.hint = localization.GetByLabel('UI/Market/Marketbase/NotAvailableInRange') 188 189 def GetDragData(self, *args): 190 return self.sr.node.scroll.GetSelectedNodes(self.sr.node) 191 192 def OnMouseEnter(self, *args): 193 Generic.OnMouseEnter(self, *args) 194 TryPreviewFitItemOnMouseAction(self.sr.node, oldWindow=False) 195 196 def OnMouseExit(self, *args): 197 Generic.OnMouseExit(self, *args) 198 TryPreviewFitItemOnMouseAction(None, oldWindow=False) 199 200 def GetHint(self): 201 return GetHintWithAvgPrice(self.sr.node) 202 203 204 class QuickbarItem(GenericMarketItem): 205 __guid__ = 'listentry.QuickbarItem' 206 207 def Load(self, node): 208 GenericMarketItem.Load(self, node) 209 self.sr.sublevel = node.Get('sublevel', 0) 210 self.sr.label.left = 12 + max(0, self.sr.sublevel * 16) 211 if node.get('extraText', ''): 212 self.sr.label.text = localization.GetByLabel('UI/Market/Marketbase/QuickbarTypeNameWithExtraText', typeName=node.label, extraText=node.get('extraText', '')) 213 else: 214 self.sr.label.text = node.label 215 if evetypes.GetMarketGroupID(node.invtype) is None: 216 self.SetOpacity(0.5) 217 if self.hint is not None: 218 self.hint += '<br>' 219 else: 220 self.hint = '' 221 self.hint += localization.GetByLabel('UI/Market/Marketbase/NotAvailableOnMarket') 222 223 def OnClick(self, *args): 224 if self.sr.node: 225 if evetypes.GetMarketGroupID(self.sr.node.invtype) is None: 226 return 227 self.sr.node.scroll.SelectNode(self.sr.node) 228 prompt_player_fsd_dialog('ListEntryClick') 229 if self.sr.node.Get('OnClick', None): 230 self.sr.node.OnClick(self) 231 232 def GetMenu(self): 233 m = [] 234 if self.sr.node and self.sr.node.Get('GetMenu', None): 235 m += self.sr.node.GetMenu(self) 236 if getattr(self, 'itemID', None) or getattr(self, 'typeID', None): 237 m += GetMenuService().GetMenuFromItemIDTypeID(getattr(self, 'itemID', None), getattr(self, 'typeID', None), includeMarketDetails=True) 238 return m 239 240 def GetDragData(self, *args): 241 nodes = self.sr.node.scroll.GetSelectedNodes(self.sr.node) 242 return nodes 243 244 def OnDropData(self, dragObj, nodes): 245 if self.sr.node.get('DropData', None): 246 self.sr.node.DropData(('quickbar', self.sr.node.parent), nodes) 247 248 249 class QuickbarGroup(ListGroup): 250 __guid__ = 'listentry.QuickbarGroup' 251 __notifyevents__ = ['OnMarketTickerSettingsUpdated'] 252 isDragObject = True 253 254 def Startup(self, *etc): 255 ListGroup.Startup(self, *etc) 256 self.favoriteIcon = Sprite(name='favoriteIcon', parent=self, align=uiconst.CENTERRIGHT, left=4, width=16, height=16, texturePath=eveicon.star, color=TextColor.NORMAL, hint=localization.GetByLabel('UI/Market/TickerFolderHint', maxItems=TICKER_MAX_ITEMS_FROM_QUICKBAR)) 257 self.favoriteIcon.display = False 258 sm.RegisterNotify(self) 259 260 def Load(self, node): 261 ListGroup.Load(self, node) 262 if node.isTickerFolder: 263 self.favoriteIcon.display = True 264 else: 265 self.favoriteIcon.display = False 266 267 def GetDragData(self, *args): 268 nodes = [self.sr.node] 269 return nodes 270 271 def GetMenu(self): 272 m = ListGroup.GetMenu(self) 273 quickbar = settings.user.ui.Get('quickbar', {}) 274 folderID = self.sr.node.id[1] 275 buyDict = GetTypesUnderFolder(folderID, quickbar) 276 if buyDict: 277 m += [(MenuLabel('UI/Market/MarketQuote/BuyAll'), 278 BuyMultipleTypesWithQty, 279 (buyDict,), 280 eveicon.isk.resolve(16))] 281 if self.IsCurrentTickerFolder(): 282 m += [(MenuLabel('UI/Market/TickerRemoveAsMarketTickerFolder'), 283 self.ToggleAsMarketTickerFolder, 284 (False,), 285 eveicon.star_slash.resolve(16))] 286 else: 287 m += [(MenuLabel('UI/Market/TickerSetAsMarketTickerFolder'), 288 self.ToggleAsMarketTickerFolder, 289 (True,), 290 eveicon.star.resolve(16))] 291 return CreateMenuDataFromRawTuples(m) 292 293 def ToggleAsMarketTickerFolder(self, setAsFolder): 294 if self.IsCurrentTickerFolder(): 295 newTickerFolder = None 296 else: 297 newTickerFolder = self.sr.node.id[1] 298 settings.char.ui.Set(TICKER_SETTING_NAME, newTickerFolder) 299 sm.ScatterEvent('OnMarketTickerSettingsUpdated', newTickerFolder) 300 301 def IsCurrentTickerFolder(self): 302 folderID = self.sr.node.id[1] 303 currentMarketTickerFolder = settings.char.ui.Get(TICKER_SETTING_NAME, 0) 304 if folderID == currentMarketTickerFolder: 305 return True 306 return False 307 308 def SetFavoriteState(self, tickerFolderID): 309 self.favoriteIcon.display = tickerFolderID == self.sr.node.id[1] 310 311 def OnMarketTickerSettingsUpdated(self, newTickerFolder): 312 self.SetFavoriteState(newTickerFolder) 313 314 315 class MarketGroupEntry(ListGroup): 316 isDragObject = True 317 318 def GetDragData(self): 319 if self.sr.node.marketGroupInfo.hasTypes: 320 return [ TypeDragData(typeID) for typeID in self.sr.node.typeIDs ] 321 322 def GetMenu(self): 323 menuData = MenuData() 324 if self.sr.node.marketGroupInfo.hasTypes: 325 menuData.AddEntry(MenuLabel('UI/Compare/CompareButton'), lambda : GetMenuService().CompareTypes(self.sr.node.typeIDs)) 326 menuData.AddSeparator() 327 return menuData + super(MarketGroupEntry, self).GetMenu() 328 329 330 class MarketMetaGroupEntry(MarketGroupEntry): 331 __guid__ = 'listentry.MarketMetaGroupEntry' 332 333 def Load(self, node): 334 ListGroup.Load(self, node) 335 self.OnToggle = node.OnToggle 336 337 def OnClick(self, *args, **kwargs): 338 ListGroup.OnClick(self, *args) 339 if self.OnToggle is not None: 340 self.OnToggle() 341 342 def GetDragData(self): 343 return [ TypeDragData(typeID) for typeID in self.sr.node.typeIDs ] 344 345 346 def GetHintWithAvgPrice(data): 347 hintTextList = [] 348 if data.showNameHint and not getattr(uicore.uilib, 'auxiliaryTooltip', None): 349 typeName = evetypes.GetName(data.typeID) 350 hintTextList.append(typeName) 351 dataHint = data.hint 352 if dataHint and dataHint not in hintTextList: 353 hintTextList += [data.hint] 354 marketPrice = GetAveragePrice(data) 355 if marketPrice: 356 marketPriceStr = FmtISKAndRound(marketPrice) 357 estimatedPrice = localization.GetByLabel('UI/Inventory/ItemEstimatedPrice', estPrice=marketPriceStr) 358 hintTextList.append(estimatedPrice) 359 hint = '<br>'.join(filter(None, hintTextList)) 360 return hint