sellItemEntry.py (17039B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\market\sellItemEntry.py 2 from carbon.common.script.util.timerstuff import AutoTimer 3 from carbonui import const as uiconst, Density 4 from carbonui.control.singlelineedits.singleLineEditInteger import SingleLineEditInteger 5 from carbonui.primitives.container import Container 6 from carbonui.primitives.containerAutoSize import ContainerAutoSize 7 from carbonui.primitives.fill import Fill 8 from carbonui.primitives.line import Line 9 from carbonui.primitives.sprite import Sprite 10 from carbonui.control.buttonIcon import ButtonIcon 11 from eve.client.script.ui.shared.market.util import get_regional_average_text, get_regional_best_text, get_item_jumps_quote_text 12 from eve.client.script.ui.control.eveIcon import Icon 13 from eve.client.script.ui.control.eveLabel import Label 14 from eve.client.script.ui.control.eveLoadingWheel import LoadingWheel 15 from eve.client.script.ui.shared.industry.views.errorFrame import ErrorFrame 16 from eve.client.script.ui.shared.market.buySellItemContainerBase import BuySellItemContainerBase 17 from eve.client.script.ui.shared.market.deltaContainer import SellDeltaContainer 18 from eve.client.script.ui.shared.market.singleLineEditMarketPrice import SingleLineEditMarketPrice 19 from eve.client.script.ui.util.uix import GetTechLevelIcon 20 from eve.common.script.util.eveFormat import FmtISK 21 import evetypes 22 from localization import GetByLabel 23 from carbonui.uicore import uicore 24 from marketutil import ticks 25 NA_CHAR = '-' 26 27 class SellItemContainer(BuySellItemContainerBase): 28 __guid__ = 'uicls.SellItemContainer' 29 belowColor = '<color=0xffff5050>' 30 aboveColor = '<color=0xff00ff00>' 31 totaLabelPath = 'UI/Market/MarketQuote/AskTotal' 32 33 def ApplyAttributes(self, attributes): 34 self.isReadOnly = attributes.isReadOnly 35 self.item = attributes.item 36 self.typeID = self.item.typeID 37 BuySellItemContainerBase.ApplyAttributes(self, attributes) 38 self.adjustQtyAndPriceTimer = None 39 self.isUpdating = False 40 self.singleton = self.item.singleton 41 self.itemID = self.item.itemID 42 self.itemName = evetypes.GetName(self.typeID) 43 self.brokersFee = 0.0 44 self.sccSurcharge = 0.0 45 self.rawBrokerFeePercentage = 0.0 46 self.salesTax = 0.0 47 self.totalSum = 0.0 48 self.stationID = attributes.stationID 49 self.limits = self.quoteSvc.GetSkillLimits(self.stationID) 50 self.solarSystemID = attributes.solarSystemID 51 self.regionID = self.GetRegionID() 52 self.locationID = self.item.locationID 53 self.bestBid = attributes.bestBid 54 self.bestPrice = attributes.bestPrice 55 self.totalStrikethroughLine = None 56 self.priceAmountWarning = None 57 self.rightCont = Container(name='rightCont', parent=self, align=uiconst.TORIGHT_PROP, width=0.3) 58 self.priceCont = Container(name='priceCont', parent=self, align=uiconst.TORIGHT_PROP, width=0.22) 59 self.qtyCont = Container(name='qtyCont', parent=self, align=uiconst.TORIGHT_PROP, width=0.15) 60 self.itemCont = Container(name='itemCont', parent=self, align=uiconst.TORIGHT_PROP, width=0.33) 61 self.deleteCont = Container(name='deleteCont', parent=self.itemCont, align=uiconst.TORIGHT, width=24) 62 self.totalCont = ContainerAutoSize(name='totalCont', parent=self.rightCont, align=uiconst.CENTERRIGHT, padRight=4) 63 self.deleteButton = ButtonIcon(texturePath='res:/UI/Texture/Icons/73_16_210.png', pos=(0, 0, 16, 16), align=uiconst.CENTERRIGHT, parent=self.deleteCont, hint=GetByLabel('UI/Generic/RemoveItem'), idx=0, func=self.RemoveItem) 64 self.deleteCont.display = False 65 self.textCont = Container(name='textCont', parent=self.itemCont, align=uiconst.TOALL) 66 self.errorBg = ErrorFrame(bgParent=self) 67 self.DrawItem() 68 self.DrawQty() 69 self.DrawPrice() 70 self.DrawTotal() 71 self.DrawDelta() 72 self.estimatedSellCount = self.GetSellCountEstimate() 73 self.SetTotalSumAndLabel() 74 self.brokersFeePerc = self.limits.GetBrokersFeeForLocation(self.stationID) 75 self.UpdateBrokersFee() 76 self.GetSalesTax() 77 self.ShowNoSellOrders() 78 self.UpdateOrderStateInUI() 79 80 @staticmethod 81 def GetRegionID(): 82 return cfg.mapSystemCache.Get(session.solarsystemid2).regionID 83 84 def OnDurationChanged(self, duration): 85 if self.IsImmediateOrder(): 86 self.priceEdit.DeactivateTickAlignment() 87 self.SetPrice(self.bestPrice) 88 else: 89 self.priceEdit.ActivateTickAlignment() 90 self.OnChange() 91 92 def ShowNoSellOrders(self, force = False): 93 if self.IsImmediateOrder() and (self.bestBid is None or force): 94 uicore.animations.FadeIn(self.errorBg, 0.35, duration=0.3) 95 96 @staticmethod 97 def GetDuration(): 98 from eve.client.script.ui.shared.market.sellMulti import SellItems 99 wnd = SellItems.GetIfOpen() 100 if not wnd: 101 return 102 return wnd.durationCombo.GetValue() 103 104 def DrawQty(self): 105 qty = self.item.stacksize 106 self.qtyEdit = SingleLineEditInteger(name='qtyEdit', parent=self.qtyCont, align=uiconst.TOTOP, top=8, padLeft=4, minValue=1, maxValue=qty, density=Density.COMPACT) 107 self.qtyEdit.SetValue(qty) 108 self.qtyEdit.OnChange = self.OnChange 109 self.qtyEdit.hint = GetByLabel('UI/Common/Quantity') 110 111 def DrawPrice(self): 112 self.priceEdit = SingleLineEditMarketPrice(name='priceEdit', parent=self.priceCont, align=uiconst.TOTOP, top=8, padLeft=8, isBuy=False, isTickActivated=not self.IsImmediateOrder(), readonly=self.isReadOnly, density=Density.COMPACT) 113 if self.IsImmediateOrder(): 114 self.SetPrice(self.bestPrice) 115 else: 116 self.SetPrice(ticks.increment_to_next_tick(self.bestPrice)) 117 self.priceEdit.OnChange = self.OnChange 118 self.priceEdit.hint = GetByLabel('UI/Market/MarketQuote/AskPrice') 119 120 def DrawDelta(self): 121 self.deltaContainer = SellDeltaContainer(parent=self.totalCont, delta=self.GetDelta(), func=self.OpenMarket, top=16, align=uiconst.TOPRIGHT) 122 self.deltaContainer.LoadTooltipPanel = self.LoadDeltaTooltip 123 self.UpdateDelta() 124 125 def GetTradeWndClass(self): 126 from eve.client.script.ui.shared.market.sellMulti import SellItems 127 return SellItems 128 129 def LoadDeltaTooltip(self, tooltipPanel, *args): 130 tooltipPanel.LoadGeneric2ColumnTemplate() 131 tooltipPanel.cellPadding = (4, 1, 4, 1) 132 tooltipPanel.AddLabelLarge(text=GetByLabel('UI/Market/MarketQuote/AskPrice')) 133 tooltipPanel.AddLabelLarge(text=FmtISK(self.priceEdit.GetValue()), align=uiconst.CENTERRIGHT) 134 tooltipPanel.AddSpacer(1, 8, colSpan=tooltipPanel.columns) 135 tooltipPanel.AddLabelMedium(text='%s %s' % (get_regional_average_text(self.typeID), self.GetDeltaText())) 136 tooltipPanel.AddLabelMedium(text=FmtISK(self.averagePrice), align=uiconst.CENTERRIGHT) 137 tooltipPanel.AddLabelMedium(text=get_regional_best_text(self.typeID)) 138 bestMatch = tooltipPanel.AddLabelMedium(text='', align=uiconst.CENTERRIGHT) 139 bestMatchDetails = tooltipPanel.AddLabelSmall(text='', align=uiconst.CENTERRIGHT, colSpan=tooltipPanel.columns) 140 if not self.bestBid: 141 bestMatch.text = GetByLabel('UI/Contracts/ContractEntry/NoBids') 142 bestMatchDetails.text = GetByLabel('UI/Market/MarketQuote/ImmediateWillFail') 143 bestMatch.color = (1.0, 0.275, 0.0, 1.0) 144 bestMatchDetails.color = (1.0, 0.275, 0.0, 1.0) 145 else: 146 bestMatch.text = FmtISK(self.bestBid.price) 147 bestMatchText, volRemaining = self.GetBestMatchText() 148 bestMatchDetails.text = bestMatchText 149 bestMatchDetails.SetAlpha(0.6) 150 if volRemaining: 151 vol = tooltipPanel.AddLabelSmall(text=volRemaining, align=uiconst.CENTERRIGHT, colSpan=tooltipPanel.columns) 152 vol.SetAlpha(0.6) 153 154 def GetBestMatchText(self): 155 jumps = max(self.bestBid.jumps - max(0, self.bestBid.range), 0) 156 minVolumeText = None 157 jumpText = get_item_jumps_quote_text(self.typeID, jumps, self.stationID, self.bestBid.stationID) 158 if 1 < self.bestBid.minVolume <= self.bestBid.volRemaining: 159 minVolumeText = GetByLabel('UI/Market/MarketQuote/SimpleMinimumVolume', min=self.bestBid.minVolume) 160 return (GetByLabel('UI/Market/MarketQuote/SellQuantity', volRemaining=long(self.bestBid.volRemaining), jumpText=jumpText), minVolumeText) 161 162 def DrawItem(self): 163 iconCont = Container(parent=self.textCont, align=uiconst.TOLEFT, width=32, padding=4) 164 self.iconInnerCont = Container(name='iconInnerCont', parent=iconCont, align=uiconst.CENTERLEFT, pos=(0, 0, 32, 32)) 165 self.wheel = LoadingWheel(parent=self.iconInnerCont, pos=(0, 0, 48, 48), align=uiconst.CENTER, idx=0) 166 self.wheel.display = False 167 self.techIcon = Sprite(parent=self.iconInnerCont, pos=(0, 0, 16, 16), align=uiconst.TOPLEFT, state=uiconst.UI_NORMAL) 168 self.icon = Icon(parent=self.iconInnerCont, typeID=self.typeID, state=uiconst.UI_DISABLED, ignoreSize=True, pos=(0, 0, 32, 32)) 169 GetTechLevelIcon(self.techIcon, 1, self.typeID) 170 itemName = GetByLabel('UI/Contracts/ContractsWindow/ShowInfoLink', showInfoName=self.itemName, info=('showinfo', self.typeID, self.item.itemID)) 171 self.itemNameLabel = Label(text=itemName, parent=self.textCont, left=40, align=uiconst.CENTERLEFT, state=uiconst.UI_NORMAL, autoFadeSides=35, fontsize=12) 172 173 def UpdateBrokersFee(self): 174 feeInfo = self.quoteSvc.GetBrokersFeeInfo(self.stationID, None, self.totalSum, self.brokersFeePerc, None) 175 surchargeFeeInfo = self.quoteSvc.GetSccSurchargeFeeInfo(self.stationID, None, self.totalSum) 176 feeAmount = feeInfo.amt 177 self.brokersFee = feeAmount 178 self.rawBrokerFeePercentage = feeInfo.rawPercentage 179 self.sccSurcharge = surchargeFeeInfo.sccSurchargeAmt 180 181 def GetSalesTax(self): 182 tax = self.totalSum * self.limits['acc'] 183 self.salesTax = tax 184 185 def GetTotalSum(self): 186 self.GetTotalSumAndDisplaySum() 187 return self.totalSum 188 189 def GetTotalSumAndDisplaySum(self): 190 price = self.GetPrice() 191 qty = self.GetQty() 192 sumToDisplay = price * qty 193 totalSum = sumToDisplay 194 if self.IsImmediateOrder(): 195 if self.estimatedSellCount == 0: 196 totalSum = 0 197 elif self.estimatedSellCount < qty: 198 sumToDisplay = self.estimatedSellCount * price 199 totalSum = sumToDisplay 200 self.totalSum = totalSum 201 return (totalSum, sumToDisplay) 202 203 def UpdateTotalSumLabel(self, totalSum, sumToDisplay): 204 self.totalLabel.text = FmtISK(sumToDisplay) 205 if sumToDisplay != totalSum: 206 self.ConstructTotalStrikethroughLine() 207 self.totalStrikethroughLine.width = self.totalLabel.textwidth 208 self.ChangeTotalStrikethroughDisplay(display=True) 209 else: 210 self.ChangeTotalStrikethroughDisplay(display=False) 211 212 def OnChange(self, *args): 213 if self.adjustQtyAndPriceTimer: 214 self.adjustQtyAndPriceTimer.KillTimer() 215 self.adjustQtyAndPriceTimer = AutoTimer(200, self.AdjustQtyAndPrice_thread, *args) 216 self.SetItemLoading() 217 218 def AdjustQtyAndPrice_thread(self, *args): 219 self.adjustQtyAndPriceTimer = None 220 if self.destroyed: 221 return 222 self.estimatedSellCount = self.GetSellCountEstimate() 223 self.SetTotalSumAndLabel() 224 self.UpdateBrokersFee() 225 self.GetSalesTax() 226 self.deltaContainer.display = True 227 self.UpdateDelta() 228 self.wheel.display = False 229 self.isUpdating = False 230 if self.parentEditFunc: 231 self.parentEditFunc(args) 232 self.UpdateOrderStateInUI() 233 234 def SetItemLoading(self): 235 self.totalLabel.text = NA_CHAR 236 self.deltaContainer.display = False 237 self.wheel.display = True 238 self.isUpdating = True 239 240 def SetTotalSumAndLabel(self): 241 totalSum, displaySum = self.GetTotalSumAndDisplaySum() 242 self.UpdateTotalSumLabel(totalSum, displaySum) 243 244 def UpdateOrderStateInUI(self): 245 duration = self.GetDuration() 246 if duration != 0: 247 self.ChangePriceAmountWarningDisplay(display=False) 248 self.HideNoSellOrders() 249 return 250 qty = self.GetQty() 251 if self.estimatedSellCount == 0: 252 self.ShowNoSellOrders(force=True) 253 self.ChangePriceAmountWarningDisplay(display=False) 254 elif self.estimatedSellCount < qty: 255 self.HideNoSellOrders() 256 self.PrepareWarningInfo(self.estimatedSellCount, qty) 257 else: 258 self.HideNoSellOrders() 259 self.ChangePriceAmountWarningDisplay(display=False) 260 261 def PrepareWarningInfo(self, estimatedSellCount, qtyToSell): 262 self.ConstructPriceAmountWarning() 263 self.ConstructQtyBg() 264 self.ChangePriceAmountWarningDisplay(display=True) 265 self.priceAmountWarning.info = (estimatedSellCount, qtyToSell) 266 267 def GetPrice(self): 268 price = self.priceEdit.GetValue() 269 return price 270 271 def GetQty(self): 272 qty = self.qtyEdit.GetValue() 273 return qty 274 275 def GetQtyToSell(self): 276 qty = self.GetQty() 277 if self.IsImmediateOrder(): 278 return min(self.estimatedSellCount, qty) 279 else: 280 return qty 281 282 def IsImmediateOrder(self): 283 isImmediate = self.GetDuration() == 0 284 return isImmediate 285 286 def SetQtyAndPrice(self, newQty, newPrice): 287 self.qtyEdit.SetValue(newQty) 288 self.SetPrice(newPrice) 289 self.OnChange() 290 291 def SetPrice(self, newPrice): 292 self.priceEdit.SetValue(newPrice) 293 294 def GetSellCountEstimate(self): 295 return self.quoteSvc.GetSellCountEstimate(self.typeID, self.stationID, self.GetPrice(), self.GetQty()) 296 297 def MakeSingle(self): 298 self.height = 80 299 self.qtyCont.width = 0 300 self.itemCont.width = 0.42 301 self.rightCont.width = 0.36 302 self.itemNameLabel.fontsize = 14 303 self.itemNameLabel.left = 72 304 self.icon.SetSize(64, 64) 305 self.wheel.SetSize(64, 64) 306 self.iconInnerCont.SetSize(64, 64) 307 self.priceEdit.padLeft = 4 308 self.priceEdit.align = uiconst.TOBOTTOM 309 self.qtyEdit.top = 14 310 self.priceEdit.top = 14 311 self.qtyEdit.SetParent(self.priceCont) 312 if self.priceAmountWarning: 313 self.priceAmountWarning.top = -10 314 315 def RemoveSingle(self): 316 self.height = 40 317 self.qtyCont.width = 0.15 318 self.itemCont.width = 0.33 319 self.rightCont.width = 0.3 320 self.itemNameLabel.fontsize = 12 321 self.itemNameLabel.left = 40 322 self.icon.SetSize(32, 32) 323 self.wheel.SetSize(48, 48) 324 self.iconInnerCont.SetSize(32, 32) 325 self.priceEdit.align = uiconst.TOTOP 326 self.qtyEdit.top = 8 327 self.priceEdit.top = 8 328 self.priceEdit.padLeft = 8 329 self.qtyEdit.SetParent(self.qtyCont) 330 if self.priceAmountWarning: 331 self.priceAmountWarning.top = 0 332 333 def ConstructPriceAmountWarning(self): 334 if self.priceAmountWarning: 335 return None 336 cont = Container(name='priceAmountWarning', parent=self.itemCont, align=uiconst.TORIGHT, left=-4, width=16, idx=0) 337 self.priceAmountWarning = Sprite(parent=cont, pos=(0, 0, 16, 16), align=uiconst.CENTER, texturePath='res:/ui/texture/icons/44_32_7.png') 338 self.priceAmountWarning.SetRGBA(1.0, 0.3, 0.3, 0.8) 339 self.priceAmountWarning.info = (None, None) 340 self.priceAmountWarning.GetHint = self.GetWarningHint 341 342 def ConstructQtyBg(self): 343 if getattr(self.qtyEdit, 'warningBg', None): 344 return 345 warningBg = Fill(bgParent=self.qtyEdit, color=(1, 0, 0, 0.3)) 346 self.qtyEdit.warningBg = warningBg 347 348 def ConstructTotalStrikethroughLine(self): 349 if self.totalStrikethroughLine: 350 return 351 self.totalStrikethroughLine = Line(parent=self.totalCont, align=uiconst.TOPRIGHT, pos=(2, 9, 0, 1), idx=0, color=(1, 1, 1, 0.8)) 352 353 def ChangeTotalStrikethroughDisplay(self, display = False): 354 if self.totalStrikethroughLine: 355 self.totalStrikethroughLine.display = display 356 357 def ChangePriceAmountWarningDisplay(self, display = False): 358 if self.priceAmountWarning: 359 self.priceAmountWarning.display = display 360 if getattr(self.qtyEdit, 'warningBg', None): 361 self.qtyEdit.warningBg.display = display 362 363 def GetWarningHint(self): 364 estimatedSellCount, qtyToSell = self.priceAmountWarning.info 365 if estimatedSellCount is None or qtyToSell is None: 366 return 367 txt = GetByLabel('UI/Market/MarketQuote/QtyPriceWarning', estimatedSellNum=int(estimatedSellCount), tryingToSellNum=qtyToSell) 368 return txt