import math # noinspection PyPackageRequirements import wx import eos.config import gui.fitCommands as cmd import gui.mainFrame from eos.utils.spoolSupport import SpoolType, SpoolOptions from gui.contextMenu import ContextMenuSingle from service.fit import Fit from service.settings import ContextMenuSettings class ChangeModuleSpool(ContextMenuSingle): def __init__(self): self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.settings = ContextMenuSettings.getInstance() self.resetId = None def display(self, callingWindow, srcContext, mainItem): if not self.settings.get('spoolup'): return False if srcContext not in ('fittingModule', 'projectedModule') or self.mainFrame.getActiveFit() is None: return False if mainItem is None or mainItem.isEmpty: return False self.mod = mainItem self.context = srcContext return self.mod.item.group.name in ("Precursor Weapon", "Mutadaptive Remote Armor Repairer") def getText(self, callingWindow, itmContext, mainItem): return "Spoolup Cycles" def getSubMenu(self, callingWindow, context, mainItem, rootMenu, i, pitem): m = wx.Menu() if "wxMSW" in wx.PlatformInfo: bindmenu = rootMenu else: bindmenu = m isNotDefault = self.mod.spoolType is not None and self.mod.spoolAmount is not None cycleDefault = self.mod.getSpoolData(spoolOptions=SpoolOptions(SpoolType.SCALE, eos.config.settings['globalDefaultSpoolupPercentage'], True))[0] cycleCurrent = self.mod.getSpoolData(spoolOptions=SpoolOptions(SpoolType.SCALE, eos.config.settings['globalDefaultSpoolupPercentage'], False))[0] cycleMin = self.mod.getSpoolData(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True))[0] cycleMax = self.mod.getSpoolData(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True))[0] cycleTotalMin = min(cycleDefault, cycleCurrent, cycleMin) cycleTotalMax = max(cycleDefault, cycleCurrent, cycleMax) def findCycles(val1, val2): # Try to compose list of 21 steps max (0-20) maxSteps = 20 valDiff = val2 - val1 valScale = valDiff / maxSteps minStep = math.ceil(round(valScale, 9)) maxStep = math.floor(round(valDiff / 4, 9)) # Check steps from smallest to highest and see if we can go from min value # to max value using those for currentStep in range(minStep, maxStep + 1): if valDiff % currentStep == 0: return set(range(val1, val2 + currentStep, currentStep)) # Otherwise just split range in halves and go both ends using min values else: cycles = set() while val2 >= val1: cycles.add(val1) cycles.add(val2) val1 += minStep val2 -= minStep return cycles self.cycleMap = {} cyclesToShow = findCycles(cycleMin, cycleMax) for cycle in range(cycleTotalMin, cycleTotalMax + 1): menuId = ContextMenuSingle.nextID() # Show default only for current value and when not overriden if not isNotDefault and cycle == cycleDefault: text = "{} (default)".format(cycle) # Always show current selection and stuff which we decided to show via the cycles function elif cycle == cycleCurrent or cycle in cyclesToShow: text = "{}".format(cycle) # Ignore the rest to not have very long menu else: continue item = wx.MenuItem(m, menuId, text, kind=wx.ITEM_CHECK) bindmenu.Bind(wx.EVT_MENU, self.handleSpoolChange, item) m.Append(item) item.Check(isNotDefault and cycle == cycleCurrent) self.cycleMap[menuId] = cycle self.resetId = ContextMenuSingle.nextID() item = wx.MenuItem(m, self.resetId, "Reset") bindmenu.Bind(wx.EVT_MENU, self.handleSpoolChange, item) m.Append(item) return m def handleSpoolChange(self, event): if event.Id == self.resetId: spoolType = None spoolAmount = None elif event.Id in self.cycleMap: spoolType = SpoolType.CYCLES spoolAmount = self.cycleMap[event.Id] else: return fitID = self.mainFrame.getActiveFit() fit = Fit.getInstance().getFit(fitID) if self.context == 'fittingModule': if self.mod in fit.modules: position = fit.modules.index(self.mod) self.mainFrame.command.Submit(cmd.GuiChangeLocalModuleSpoolCommand( fitID=fitID, position=position, spoolType=spoolType, spoolAmount=spoolAmount)) elif self.context == 'projectedModule': if self.mod in fit.projectedModules: position = fit.projectedModules.index(self.mod) self.mainFrame.command.Submit(cmd.GuiChangeProjectedModuleSpoolCommand( fitID=fitID, position=position, spoolType=spoolType, spoolAmount=spoolAmount)) ChangeModuleSpool.register()