From 679382e220f446439d65af48ec980ec9146109ff Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Fri, 15 Nov 2019 20:19:23 +0300 Subject: [PATCH 01/15] Do not separate number and unit in range tooltip, for consistency with other fields --- gui/builtinViewColumns/maxRange.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gui/builtinViewColumns/maxRange.py b/gui/builtinViewColumns/maxRange.py index b91465efc..02a5be5d9 100644 --- a/gui/builtinViewColumns/maxRange.py +++ b/gui/builtinViewColumns/maxRange.py @@ -83,12 +83,12 @@ class MaxRange(ViewColumn): lines.append('Missile flight range') lowerRange, higherRange, higherChance = missileRangeData if roundToPrec(higherChance, 3) not in (0, 1): - lines.append('{}% chance to fly {}'.format( + lines.append('{}% chance to fly {}m'.format( formatAmount((1 - higherChance) * 100, prec=3, lowest=0, highest=0), - formatAmount(lowerRange, prec=3, lowest=0, highest=3, unitName='m'))) - lines.append('{}% chance to fly {}'.format( + formatAmount(lowerRange, prec=3, lowest=0, highest=3))) + lines.append('{}% chance to fly {}m'.format( formatAmount(higherChance * 100, prec=3, lowest=0, highest=0), - formatAmount(higherRange, prec=3, lowest=0, highest=3, unitName='m'))) + formatAmount(higherRange, prec=3, lowest=0, highest=3))) else: lines.append("Optimal + Falloff") return '\n'.join(lines) From e8f9ae8a9cdb3e81c0aebc133f656e0bf73feb86 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Sat, 16 Nov 2019 19:22:37 +0300 Subject: [PATCH 02/15] Do not use hires assets on wxGTK --- gui/bitmap_loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/bitmap_loader.py b/gui/bitmap_loader.py index 928dfb15e..325cbc7e3 100644 --- a/gui/bitmap_loader.py +++ b/gui/bitmap_loader.py @@ -89,7 +89,7 @@ class BitmapLoader: @classmethod def loadBitmap(cls, name, location): if cls.scaling_factor is None: - cls.scaling_factor = int(wx.GetApp().GetTopWindow().GetContentScaleFactor()) + cls.scaling_factor = 1 if 'wxGTK' in wx.PlatformInfo else int(wx.GetApp().GetTopWindow().GetContentScaleFactor()) scale = cls.scaling_factor filename, img = cls.loadScaledBitmap(name, location, scale) From bec58a5772fdb48f532b68c5d407916543f82644 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Sun, 17 Nov 2019 17:29:16 +0300 Subject: [PATCH 03/15] Do not crash on cargo fetch failures --- service/port/shared.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/service/port/shared.py b/service/port/shared.py index 214a7f3fe..5f3988723 100644 --- a/service/port/shared.py +++ b/service/port/shared.py @@ -82,9 +82,13 @@ def fetchItem(typeName, eagerCat=False): eager = 'group.category' if eagerCat else None try: item = sMkt.getItem(typeName, eager=eager) + except (KeyboardInterrupt, SystemExit): + raise except: pyfalog.warning('service.port.shared: unable to fetch item "{}"'.format(typeName)) return None + if item is None: + return None if sMkt.getPublicityByItem(item): return item else: From e649683a4d420b1187d6538ee58e2e0322c25f87 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Sun, 17 Nov 2019 17:34:49 +0300 Subject: [PATCH 04/15] Accept XML headers with extra info --- gui/mainFrame.py | 2 +- service/port/port.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gui/mainFrame.py b/gui/mainFrame.py index 05744a504..58fc42c9e 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -771,7 +771,7 @@ class MainFrame(wx.Frame): if self.command.Submit(cmd.GuiImportCargosCommand(activeFit, [(i.ID, a) for i, a in importData[0]])): self.additionsPane.select("Cargo") return - except: + except ImportError: pyfalog.error("Attempt to import failed:\n{0}", clipboard) else: self._openAfterImport(importData) diff --git a/service/port/port.py b/service/port/port.py index 2fc4d879a..a480e90f6 100644 --- a/service/port/port.py +++ b/service/port/port.py @@ -47,7 +47,7 @@ from service.port.muta import parseMutant pyfalog = Logger(__name__) # 2017/04/05 NOTE: simple validation, for xml file -RE_XML_START = r'<\?xml\s+version="1.0"\s*\?>' +RE_XML_START = r'<\?xml\s+version="1.0"[^<>]*\?>' class Port: @@ -321,4 +321,4 @@ class Port: @staticmethod def exportFitStats(fit, callback=None): - return exportFitStats(fit, callback=callback) \ No newline at end of file + return exportFitStats(fit, callback=callback) From 7495ba67f87adffa733e1c9d95c7cc4c314aa168 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Sun, 17 Nov 2019 17:40:07 +0300 Subject: [PATCH 05/15] Revert change made for debugging --- gui/mainFrame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/mainFrame.py b/gui/mainFrame.py index 58fc42c9e..05744a504 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -771,7 +771,7 @@ class MainFrame(wx.Frame): if self.command.Submit(cmd.GuiImportCargosCommand(activeFit, [(i.ID, a) for i, a in importData[0]])): self.additionsPane.select("Cargo") return - except ImportError: + except: pyfalog.error("Attempt to import failed:\n{0}", clipboard) else: self._openAfterImport(importData) From 59d6266e2baf489ac7f572911c9fd46f9ae9f98d Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Sun, 17 Nov 2019 21:24:41 +0300 Subject: [PATCH 06/15] Do not crash on exception classes without message attribute --- service/port/port.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/service/port/port.py b/service/port/port.py index a480e90f6..3c10d9abe 100644 --- a/service/port/port.py +++ b/service/port/port.py @@ -182,7 +182,8 @@ class Port: pyfalog.critical(e) # TypeError: not all arguments converted during string formatting # return False, "Unknown Error while processing {0}" % path - return False, "Unknown error while processing %s\n\n Error: %s" % (path, e.message) + return False, "Unknown error while processing {}\n\n Error: {} {}".format( + path, type(e).__name__, getattr(e, 'message', '')) return True, fit_list From dc5cc5855e75880ef54e44e391923ab536cd159e Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Mon, 18 Nov 2019 15:18:20 +0300 Subject: [PATCH 07/15] Show range of bursts projectors, taking ship/citadel radius taken into consideration --- eos/saveddata/module.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index 03f056e21..44487ad13 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -318,10 +318,15 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): "energyDestabilizationRange", "empFieldRange", "ecmBurstRange", "warpScrambleRange", "cargoScanRange", "shipScanRange", "surveyScanRange") + maxRange = None for attr in attrs: maxRange = self.getModifiedItemAttr(attr, None) if maxRange is not None: - return maxRange + break + if maxRange is not None: + if 'burst projector' in self.item.name.lower(): + maxRange -= self.owner.ship.getModifiedItemAttr("radius") + return maxRange missileMaxRangeData = self.missileMaxRangeData if missileMaxRangeData is None: return None From 043c43022121867e3a589a9a703fb2bd16d7df7c Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Thu, 21 Nov 2019 13:00:36 +0300 Subject: [PATCH 08/15] Update staticdata to 1610407 --- eos/effects.py | 1 + staticdata/bulkdata/dogmatypeattributes.json | 12 +++++++++++- staticdata/bulkdata/dogmatypeeffects.json | 5 +++++ staticdata/phobos/metadata.json | 4 ++-- staticdata/phobos/traits.json | 12 ++++++++---- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/eos/effects.py b/eos/effects.py index 6dfedd27d..f9a29df35 100644 --- a/eos/effects.py +++ b/eos/effects.py @@ -10683,6 +10683,7 @@ class Effect3526(BaseEffect): Used by: Ships from group: Force Recon Ship (8 of 9) + Ship: Venture Skill: Cynosural Field Theory """ diff --git a/staticdata/bulkdata/dogmatypeattributes.json b/staticdata/bulkdata/dogmatypeattributes.json index 109ae83ef..27dc3e12d 100644 --- a/staticdata/bulkdata/dogmatypeattributes.json +++ b/staticdata/bulkdata/dogmatypeattributes.json @@ -215747,7 +215747,7 @@ { "attributeID": 9, "typeID": 4308, - "value": 2170.0 + "value": 2180.0 }, { "attributeID": 11, @@ -2361009,6 +2361009,11 @@ "typeID": 32880, "value": 1.0 }, + { + "attributeID": 1296, + "typeID": 32880, + "value": -50.0 + }, { "attributeID": 1547, "typeID": 32880, @@ -2890019,6 +2890024,11 @@ "typeID": 52694, "value": 380.0 }, + { + "attributeID": 1302, + "typeID": 52694, + "value": 32880.0 + }, { "attributeID": 1333, "typeID": 52694, diff --git a/staticdata/bulkdata/dogmatypeeffects.json b/staticdata/bulkdata/dogmatypeeffects.json index e98f063b6..59de1b316 100644 --- a/staticdata/bulkdata/dogmatypeeffects.json +++ b/staticdata/bulkdata/dogmatypeeffects.json @@ -167469,6 +167469,11 @@ "isDefault": false, "typeID": 32878 }, + { + "effectID": 3526, + "isDefault": false, + "typeID": 32880 + }, { "effectID": 5058, "isDefault": false, diff --git a/staticdata/phobos/metadata.json b/staticdata/phobos/metadata.json index f61529931..f8463aba1 100644 --- a/staticdata/phobos/metadata.json +++ b/staticdata/phobos/metadata.json @@ -1,10 +1,10 @@ [ { "field_name": "client_build", - "field_value": 1604553 + "field_value": 1610407 }, { "field_name": "dump_time", - "field_value": 1573560935 + "field_value": 1574329773 } ] \ No newline at end of file diff --git a/staticdata/phobos/traits.json b/staticdata/phobos/traits.json index 06b07ed64..e8c548d5d 100644 --- a/staticdata/phobos/traits.json +++ b/staticdata/phobos/traits.json @@ -733,7 +733,7 @@ "text": "reduction in Small Energy Turret activation cost" }, { - "number": "5%", + "number": "10%", "text": "bonus to Small Energy Turret damage" } ], @@ -10287,6 +10287,10 @@ { "number": "2+", "text": "bonus to ship warp core strength" + }, + { + "number": "50%", + "text": "reduction in Industrial Cynosural Field Generator liquid ozone consumption" } ], "header": "Role Bonus:" @@ -10405,7 +10409,7 @@ { "bonuses": [ { - "number": "10%", + "number": "15%", "text": "bonus to Small Hybrid Turret damage" } ], @@ -14922,7 +14926,7 @@ "text": "reduction in Microwarpdrive signature radius penalty" }, { - "number": "5%", + "number": "10%", "text": "bonus to Small Projectile Turret damage" } ], @@ -18810,7 +18814,7 @@ { "bonuses": [ { - "number": "5%", + "number": "10%", "text": "bonus to Small Hybrid Turret damage" }, { From aa56ab8d6ca3ffafe277d35f88e6b79680987b84 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Thu, 21 Nov 2019 13:01:14 +0300 Subject: [PATCH 09/15] Bump version --- version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.yml b/version.yml index 44dc1322f..7b5140866 100644 --- a/version.yml +++ b/version.yml @@ -1 +1 @@ -version: v2.14.2 +version: v2.14.3 From 745c0db530a209f289ce8d6173b914cc98b66c4a Mon Sep 17 00:00:00 2001 From: Sasha Date: Thu, 21 Nov 2019 18:10:56 -0800 Subject: [PATCH 10/15] Add keyboard shortcuts to character level editor --- gui/characterEditor.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/gui/characterEditor.py b/gui/characterEditor.py index 9af767acc..4e38cc5fa 100644 --- a/gui/characterEditor.py +++ b/gui/characterEditor.py @@ -428,6 +428,28 @@ class SkillTreeView(wx.Panel): # This cuases issues with GTK, see #1866 # self.Layout() + # For level keyboard shortcuts + self.ChangeLevelEvent, CHANGE_LEVEL_EVENT = wx.lib.newevent.NewEvent() + self.Bind(wx.EVT_CHAR_HOOK, self.kbEvent) + self.Bind(CHANGE_LEVEL_EVENT, self.changeLevel) + + def kbEvent(self, event): + selection = self.skillTreeListCtrl.GetSelection() + if not selection: + return + dataType, skillID = self.skillTreeListCtrl.GetItemData(selection) + if dataType != 'skill': + return + keyCode = event.GetKeyCode() + if 48 <= keyCode <= 53 or 324 <= keyCode <= 329: + if keyCode <= 53: + level = keyCode - 48 + else: + level = keyCode - 324 + event = self.ChangeLevelEvent() + event.SetId(self.idLevels[level]) + wx.PostEvent(self, event) + def importSkills(self, evt): with wx.MessageDialog( From a09af0a9eb0cec225890e036884f04c955de1079 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Fri, 22 Nov 2019 15:45:01 +0300 Subject: [PATCH 11/15] Propagate keys to upper windows if they were not processed in here --- gui/characterEditor.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/gui/characterEditor.py b/gui/characterEditor.py index 4e38cc5fa..986e9197d 100644 --- a/gui/characterEditor.py +++ b/gui/characterEditor.py @@ -434,21 +434,24 @@ class SkillTreeView(wx.Panel): self.Bind(CHANGE_LEVEL_EVENT, self.changeLevel) def kbEvent(self, event): - selection = self.skillTreeListCtrl.GetSelection() - if not selection: - return - dataType, skillID = self.skillTreeListCtrl.GetItemData(selection) - if dataType != 'skill': - return - keyCode = event.GetKeyCode() - if 48 <= keyCode <= 53 or 324 <= keyCode <= 329: - if keyCode <= 53: - level = keyCode - 48 - else: - level = keyCode - 324 - event = self.ChangeLevelEvent() - event.SetId(self.idLevels[level]) - wx.PostEvent(self, event) + keyLevelMap = { + # Regular number keys + 48: 0, 49: 1, 50: 2, 51: 3, 52: 4, 53: 5, + # Numpad keys + wx.WXK_NUMPAD0: 0, wx.WXK_NUMPAD1: 1, wx.WXK_NUMPAD2: 2, + wx.WXK_NUMPAD3: 3, wx.WXK_NUMPAD4: 4, wx.WXK_NUMPAD5: 5} + keycode = event.GetKeyCode() + if keycode in keyLevelMap and event.GetModifiers() == wx.MOD_NONE: + level = keyLevelMap[keycode] + selection = self.skillTreeListCtrl.GetSelection() + if selection: + dataType, skillID = self.skillTreeListCtrl.GetItemData(selection) + if dataType == 'skill': + event = self.ChangeLevelEvent() + event.SetId(self.idLevels[level]) + wx.PostEvent(self, event) + return + event.Skip() def importSkills(self, evt): From 8652a2891be248b82ab082b1ea9eca998801e1ba Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Fri, 22 Nov 2019 15:46:29 +0300 Subject: [PATCH 12/15] Do not attempt to change skill levels of built-in all0/5 chars --- gui/characterEditor.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gui/characterEditor.py b/gui/characterEditor.py index 986e9197d..24ff84700 100644 --- a/gui/characterEditor.py +++ b/gui/characterEditor.py @@ -636,6 +636,8 @@ class SkillTreeView(wx.Panel): sChar = Character.getInstance() char = self.charEditor.entityEditor.getActiveEntity() + if char.name in ("All 0", "All 5"): + return selection = self.skillTreeListCtrl.GetSelection() dataType, skillID = self.skillTreeListCtrl.GetItemData(selection) From bfc928934ca5a25c50634f9086db9179f6f6bad2 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Mon, 25 Nov 2019 15:48:04 +0300 Subject: [PATCH 13/15] Put entries into different sizers --- gui/builtinContextMenus/graphFitAmmoPicker.py | 82 ++++++++++--------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/gui/builtinContextMenus/graphFitAmmoPicker.py b/gui/builtinContextMenus/graphFitAmmoPicker.py index 76d79178f..77868f314 100644 --- a/gui/builtinContextMenus/graphFitAmmoPicker.py +++ b/gui/builtinContextMenus/graphFitAmmoPicker.py @@ -62,11 +62,12 @@ class AmmoPickerFrame(AuxiliaryFrame): class AmmoPickerContents(wx.ScrolledCanvas): + indent = 15 + def __init__(self, parent, fit): wx.ScrolledCanvas.__init__(self, parent) self.SetScrollRate(0, 15) - indent = 15 mods = self.getMods(fit) drones = self.getDrones(fit) fighters = self.getFighters(fit) @@ -75,68 +76,75 @@ class AmmoPickerContents(wx.ScrolledCanvas): mainSizer = wx.BoxSizer(wx.VERTICAL) + moduleSizer = wx.BoxSizer(wx.VERTICAL) + mainSizer.Add(moduleSizer, 0, wx.ALL, 0) + + droneSizer = wx.BoxSizer(wx.VERTICAL) + mainSizer.Add(droneSizer, 0, wx.ALL, 0) + + fighterSizer = wx.BoxSizer(wx.VERTICAL) + mainSizer.Add(fighterSizer, 0, wx.ALL, 0) + firstRadio = True - currentRb = None - - def addRadioButton(text): - nonlocal firstRadio, currentRb - if not firstRadio: - rb = wx.RadioButton(self, wx.ID_ANY, text, style=wx.RB_GROUP) - rb.SetValue(True) - firstRadio = True - else: - rb = wx.RadioButton(self, wx.ID_ANY, text) - rb.SetValue(False) - rb.Bind(wx.EVT_RADIOBUTTON, self.rbSelected) - currentRb = rb - mainSizer.Add(rb, 0, wx.EXPAND | wx.ALL, 0) - - def addCheckbox(text, indentLvl=0): - cb = wx.CheckBox(self, -1, text) - mainSizer.Add(cb, 0, wx.EXPAND | wx.LEFT, indent * indentLvl) - if currentRb is not None: - self.rbCheckboxMap.setdefault(currentRb, []).append(cb) - - def addLabel(text, indentLvl=0): - text = text[0].capitalize() + text[1:] - label = wx.StaticText(self, wx.ID_ANY, text) - mainSizer.Add(label, 0, wx.EXPAND | wx.LEFT, indent * indentLvl) - if currentRb is not None: - self.rbLabelMap.setdefault(currentRb, []).append(label) for modInfo, modAmmo in mods: text = '\n'.join('{}x {}'.format(amount, item.name) for item, amount in modInfo) - addRadioButton(text) + currentRb = self.addRadioButton(moduleSizer, text, firstRadio) + firstRadio = False # Get actual module, as ammo getters need it mod = next((m for m in fit.modules if m.itemID == next(iter(modInfo))[0].ID), None) _, ammoTree = Ammo.getInstance().getModuleStructuredAmmo(mod) if len(ammoTree) == 1: for ammoCatName, ammos in ammoTree.items(): for ammo in ammos: - addCheckbox(ammo.name, indentLvl=1) + self.addCheckbox(moduleSizer, ammo.name, currentRb, indentLvl=1) else: for ammoCatName, ammos in ammoTree.items(): if len(ammos) == 1: ammo = next(iter(ammos)) - addCheckbox(ammo.name, indentLvl=1) + self.addCheckbox(moduleSizer, ammo.name, currentRb, indentLvl=1) else: - addLabel('{}:'.format(ammoCatName), indentLvl=1) + self.addLabel(moduleSizer, '{}:'.format(ammoCatName), currentRb, indentLvl=1) for ammo in ammos: - addCheckbox(ammo.name, indentLvl=2) + self.addCheckbox(moduleSizer, ammo.name, currentRb, indentLvl=2) if drones: - addRadioButton('Drones') + currentRb = self.addRadioButton(droneSizer, 'Drones', firstRadio) from gui.builtinAdditionPanes.droneView import DroneView for drone in sorted(drones, key=DroneView.droneKey): - addCheckbox('{}x {}'.format(drone.amount, drone.item.name), indentLvl=1) + self.addCheckbox(droneSizer, '{}x {}'.format(drone.amount, drone.item.name), currentRb, indentLvl=1) if fighters: - addRadioButton('Fighters') + currentRb = self.addRadioButton(fighterSizer, 'Fighters', firstRadio) from gui.builtinAdditionPanes.fighterView import FighterDisplay for fighter in sorted(fighters, key=FighterDisplay.fighterKey): - addCheckbox('{}x {}'.format(fighter.amount, fighter.item.name), indentLvl=1) + self.addCheckbox(fighterSizer, '{}x {}'.format(fighter.amount, fighter.item.name), currentRb, indentLvl=1) self.SetSizer(mainSizer) self.refreshStatus() + def addRadioButton(self, sizer, text, firstRadio=False): + if firstRadio: + rb = wx.RadioButton(self, wx.ID_ANY, text, style=wx.RB_GROUP) + rb.SetValue(True) + else: + rb = wx.RadioButton(self, wx.ID_ANY, text) + rb.SetValue(False) + rb.Bind(wx.EVT_RADIOBUTTON, self.rbSelected) + sizer.Add(rb, 0, wx.EXPAND | wx.ALL, 0) + return rb + + def addCheckbox(self, sizer, text, currentRb, indentLvl=0): + cb = wx.CheckBox(self, -1, text) + sizer.Add(cb, 0, wx.EXPAND | wx.LEFT, self.indent * indentLvl) + if currentRb is not None: + self.rbCheckboxMap.setdefault(currentRb, []).append(cb) + + def addLabel(self, sizer, text, currentRb, indentLvl=0): + text = text[0].capitalize() + text[1:] + label = wx.StaticText(self, wx.ID_ANY, text) + sizer.Add(label, 0, wx.EXPAND | wx.LEFT, self.indent * indentLvl) + if currentRb is not None: + self.rbLabelMap.setdefault(currentRb, []).append(label) + def getMods(self, fit): sMkt = Market.getInstance() sAmmo = Ammo.getInstance() From 400d0aaa225d72a19324d13341f79eaadb3192fd Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Mon, 25 Nov 2019 16:54:25 +0300 Subject: [PATCH 14/15] Rework graph ammo picker to be dialog instead of frame --- graphs/gui/frame.py | 2 +- gui/{auxFrame.py => auxWindow.py} | 10 +++++++++- gui/builtinContextMenus/graphFitAmmoPicker.py | 20 +++++++++++++++---- gui/characterEditor.py | 2 +- gui/devTools.py | 2 +- gui/errorDialog.py | 2 +- gui/esiFittings.py | 2 +- gui/itemStats.py | 2 +- gui/patternEditor.py | 2 +- gui/propertyEditor.py | 2 +- gui/setEditor.py | 2 +- gui/targetProfileEditor.py | 2 +- 12 files changed, 35 insertions(+), 15 deletions(-) rename gui/{auxFrame.py => auxWindow.py} (94%) diff --git a/graphs/gui/frame.py b/graphs/gui/frame.py index f56c08d48..ef94f4009 100644 --- a/graphs/gui/frame.py +++ b/graphs/gui/frame.py @@ -27,7 +27,7 @@ import gui.globalEvents as GE import gui.mainFrame from graphs.data.base import FitGraph from graphs.events import RESIST_MODE_CHANGED -from gui.auxFrame import AuxiliaryFrame +from gui.auxWindow import AuxiliaryFrame from gui.bitmap_loader import BitmapLoader from service.const import GraphCacheCleanupReason from service.settings import GraphSettings diff --git a/gui/auxFrame.py b/gui/auxWindow.py similarity index 94% rename from gui/auxFrame.py rename to gui/auxWindow.py index 4f3fbedb4..e42b68fab 100644 --- a/gui/auxFrame.py +++ b/gui/auxWindow.py @@ -22,7 +22,7 @@ import wx -class AuxiliaryFrame(wx.Frame): +class AuxiliaryMixin: _instance = None @@ -68,3 +68,11 @@ class AuxiliaryFrame(wx.Frame): def OnSuppressedAction(self, event): return + + +class AuxiliaryFrame(AuxiliaryMixin, wx.Frame): + pass + + +class AuxiliaryDialog(AuxiliaryMixin, wx.Dialog): + pass diff --git a/gui/builtinContextMenus/graphFitAmmoPicker.py b/gui/builtinContextMenus/graphFitAmmoPicker.py index 77868f314..cac80ce33 100644 --- a/gui/builtinContextMenus/graphFitAmmoPicker.py +++ b/gui/builtinContextMenus/graphFitAmmoPicker.py @@ -2,7 +2,7 @@ import wx import gui.mainFrame -from gui.auxFrame import AuxiliaryFrame +from gui.auxWindow import AuxiliaryDialog from gui.contextMenu import ContextMenuSingle from service.ammo import Ammo from service.market import Market @@ -32,22 +32,34 @@ class GraphFitAmmoPicker(ContextMenuSingle): GraphFitAmmoPicker.register() -class AmmoPickerFrame(AuxiliaryFrame): +class AmmoPickerFrame(AuxiliaryDialog): def __init__(self, parent, fit): super().__init__(parent, title='Choose Different Ammo', style=wx.DEFAULT_DIALOG_STYLE, resizeable=True) padding = 5 mainSizer = wx.BoxSizer(wx.VERTICAL) + contents = AmmoPickerContents(self, fit) mainSizer.Add(contents, 1, wx.EXPAND | wx.ALL, padding) + buttonSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL) + if buttonSizer: + mainSizer.Add(buttonSizer, 0, wx.EXPAND | wx.ALL, padding) + self.SetSizer(mainSizer) self.Layout() contW, contH = contents.GetVirtualSize() - bestW = min(1000, contW + padding * 2) - bestH = min(700, contH + padding * 2) + bestW = contW + padding * 2 + bestH = contH + padding * 2 + if buttonSizer: + # Yeah right... whatever + buttW, buttH = buttonSizer.GetSize() + bestW = max(bestW, buttW + padding * 2) + bestH += buttH + padding * 2 + bestW = min(1000, bestW) + bestH = min(700, bestH) self.SetSize(bestW, bestH) self.SetMinSize(wx.Size(int(bestW * 0.7), int(bestH * 0.7))) self.CenterOnParent() diff --git a/gui/characterEditor.py b/gui/characterEditor.py index 24ff84700..7025b1a2a 100644 --- a/gui/characterEditor.py +++ b/gui/characterEditor.py @@ -34,7 +34,7 @@ from wx.lib.agw.floatspin import FloatSpin import config import gui.globalEvents as GE -from gui.auxFrame import AuxiliaryFrame +from gui.auxWindow import AuxiliaryFrame from gui.bitmap_loader import BitmapLoader from gui.builtinViews.entityEditor import BaseValidator, EntityEditor, TextEntryValidatedDialog from gui.builtinViews.implantEditor import BaseImplantEditorView diff --git a/gui/devTools.py b/gui/devTools.py index 3e5ac725e..2fb6abb4a 100644 --- a/gui/devTools.py +++ b/gui/devTools.py @@ -26,7 +26,7 @@ import wx from logbook import Logger import eos.db -from gui.auxFrame import AuxiliaryFrame +from gui.auxWindow import AuxiliaryFrame from gui.builtinShipBrowser.events import FitSelected diff --git a/gui/errorDialog.py b/gui/errorDialog.py index 1e50a17bc..1825e2e5b 100644 --- a/gui/errorDialog.py +++ b/gui/errorDialog.py @@ -26,7 +26,7 @@ import wx from logbook import Logger import config -from gui.auxFrame import AuxiliaryFrame +from gui.auxWindow import AuxiliaryFrame from service.prereqsCheck import version_block diff --git a/gui/esiFittings.py b/gui/esiFittings.py index 22dec7a4f..61da04d78 100644 --- a/gui/esiFittings.py +++ b/gui/esiFittings.py @@ -8,7 +8,7 @@ from logbook import Logger import gui.globalEvents as GE from eos.db import getItem from eos.saveddata.cargo import Cargo -from gui.auxFrame import AuxiliaryFrame +from gui.auxWindow import AuxiliaryFrame from gui.display import Display from service.esi import Esi from service.esiAccess import APIException diff --git a/gui/itemStats.py b/gui/itemStats.py index 284121ecc..dda8e68ad 100644 --- a/gui/itemStats.py +++ b/gui/itemStats.py @@ -23,7 +23,7 @@ import wx import config import gui.mainFrame from eos.saveddata.module import Module -from gui.auxFrame import AuxiliaryFrame +from gui.auxWindow import AuxiliaryFrame from gui.bitmap_loader import BitmapLoader from gui.builtinItemStatsViews.itemAffectedBy import ItemAffectedBy from gui.builtinItemStatsViews.itemAttributes import ItemParams diff --git a/gui/patternEditor.py b/gui/patternEditor.py index ee22d3fd1..4c30c8c90 100644 --- a/gui/patternEditor.py +++ b/gui/patternEditor.py @@ -21,7 +21,7 @@ import wx from logbook import Logger -from gui.auxFrame import AuxiliaryFrame +from gui.auxWindow import AuxiliaryFrame from gui.bitmap_loader import BitmapLoader from gui.builtinViews.entityEditor import BaseValidator, EntityEditor from gui.utils.clipboard import fromClipboard, toClipboard diff --git a/gui/propertyEditor.py b/gui/propertyEditor.py index 2292c5ac5..06ae4bf20 100644 --- a/gui/propertyEditor.py +++ b/gui/propertyEditor.py @@ -10,7 +10,7 @@ import gui.builtinMarketBrowser.pfSearchBox as SBox import gui.display as d import gui.globalEvents as GE from eos.db.gamedata.queries import getAttributeInfo, getItem -from gui.auxFrame import AuxiliaryFrame +from gui.auxWindow import AuxiliaryFrame from gui.bitmap_loader import BitmapLoader from gui.marketBrowser import SearchBox from service.market import Market diff --git a/gui/setEditor.py b/gui/setEditor.py index 578cf18fd..8ba2213d5 100644 --- a/gui/setEditor.py +++ b/gui/setEditor.py @@ -21,7 +21,7 @@ import wx from logbook import Logger -from gui.auxFrame import AuxiliaryFrame +from gui.auxWindow import AuxiliaryFrame from gui.builtinViews.entityEditor import BaseValidator, EntityEditor from gui.builtinViews.implantEditor import BaseImplantEditorView from gui.utils.clipboard import fromClipboard, toClipboard diff --git a/gui/targetProfileEditor.py b/gui/targetProfileEditor.py index 244aec20b..e2d977a66 100644 --- a/gui/targetProfileEditor.py +++ b/gui/targetProfileEditor.py @@ -27,7 +27,7 @@ from logbook import Logger import gui.mainFrame import gui.globalEvents as GE -from gui.auxFrame import AuxiliaryFrame +from gui.auxWindow import AuxiliaryFrame from gui.bitmap_loader import BitmapLoader from gui.builtinViews.entityEditor import EntityEditor, BaseValidator from gui.utils.clipboard import toClipboard, fromClipboard From 2217aff5ab260873bc10d2e55f84a927099d7fdf Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Tue, 26 Nov 2019 14:53:47 +0300 Subject: [PATCH 15/15] Add button to add custom drone groups --- gui/builtinContextMenus/graphFitAmmoPicker.py | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/gui/builtinContextMenus/graphFitAmmoPicker.py b/gui/builtinContextMenus/graphFitAmmoPicker.py index cac80ce33..f13d63446 100644 --- a/gui/builtinContextMenus/graphFitAmmoPicker.py +++ b/gui/builtinContextMenus/graphFitAmmoPicker.py @@ -91,8 +91,8 @@ class AmmoPickerContents(wx.ScrolledCanvas): moduleSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(moduleSizer, 0, wx.ALL, 0) - droneSizer = wx.BoxSizer(wx.VERTICAL) - mainSizer.Add(droneSizer, 0, wx.ALL, 0) + self.droneSizer = wx.BoxSizer(wx.VERTICAL) + mainSizer.Add(self.droneSizer, 0, wx.ALL, 0) fighterSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(fighterSizer, 0, wx.ALL, 0) @@ -101,7 +101,7 @@ class AmmoPickerContents(wx.ScrolledCanvas): for modInfo, modAmmo in mods: text = '\n'.join('{}x {}'.format(amount, item.name) for item, amount in modInfo) - currentRb = self.addRadioButton(moduleSizer, text, firstRadio) + modRb = self.addRadioButton(moduleSizer, text, firstRadio) firstRadio = False # Get actual module, as ammo getters need it mod = next((m for m in fit.modules if m.itemID == next(iter(modInfo))[0].ID), None) @@ -109,26 +109,29 @@ class AmmoPickerContents(wx.ScrolledCanvas): if len(ammoTree) == 1: for ammoCatName, ammos in ammoTree.items(): for ammo in ammos: - self.addCheckbox(moduleSizer, ammo.name, currentRb, indentLvl=1) + self.addCheckbox(moduleSizer, ammo.name, modRb, indentLvl=1) else: for ammoCatName, ammos in ammoTree.items(): if len(ammos) == 1: ammo = next(iter(ammos)) - self.addCheckbox(moduleSizer, ammo.name, currentRb, indentLvl=1) + self.addCheckbox(moduleSizer, ammo.name, modRb, indentLvl=1) else: - self.addLabel(moduleSizer, '{}:'.format(ammoCatName), currentRb, indentLvl=1) + self.addLabel(moduleSizer, '{}:'.format(ammoCatName), modRb, indentLvl=1) for ammo in ammos: - self.addCheckbox(moduleSizer, ammo.name, currentRb, indentLvl=2) + self.addCheckbox(moduleSizer, ammo.name, modRb, indentLvl=2) if drones: - currentRb = self.addRadioButton(droneSizer, 'Drones', firstRadio) + droneRb = self.addRadioButton(self.droneSizer, 'Drones', firstRadio) from gui.builtinAdditionPanes.droneView import DroneView for drone in sorted(drones, key=DroneView.droneKey): - self.addCheckbox(droneSizer, '{}x {}'.format(drone.amount, drone.item.name), currentRb, indentLvl=1) + self.addCheckbox(self.droneSizer, '{}x {}'.format(drone.amount, drone.item.name), droneRb, indentLvl=1) + addBtn = wx.Button(self, wx.ID_ANY, '+', style=wx.BU_EXACTFIT) + addBtn.Bind(wx.EVT_BUTTON, self.OnDroneGroupAdd) + mainSizer.Add(addBtn, 0, wx.LEFT, self.indent) if fighters: - currentRb = self.addRadioButton(fighterSizer, 'Fighters', firstRadio) + fighterRb = self.addRadioButton(fighterSizer, 'Fighters', firstRadio) from gui.builtinAdditionPanes.fighterView import FighterDisplay for fighter in sorted(fighters, key=FighterDisplay.fighterKey): - self.addCheckbox(fighterSizer, '{}x {}'.format(fighter.amount, fighter.item.name), currentRb, indentLvl=1) + self.addCheckbox(fighterSizer, '{}x {}'.format(fighter.amount, fighter.item.name), fighterRb, indentLvl=1) self.SetSizer(mainSizer) self.refreshStatus() @@ -221,6 +224,12 @@ class AmmoPickerContents(wx.ScrolledCanvas): break return fighters + def OnDroneGroupAdd(self, event): + event.Skip() + sizer = wx.BoxSizer(wx.HORIZONTAL) + label = wx.StaticText() + self.droneSizer.Add(sizer, 0, wx.EXPAND | wx.LEFT, self.indent) + def refreshStatus(self): for map in (self.rbLabelMap, self.rbCheckboxMap): for rb, items in map.items():