Merge remote-tracking branch 'origin/master' into attrGroup
# Conflicts: # eve.db
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
|
||||
import config
|
||||
|
||||
versionString = "{0} {1} - {2} {3}".format(config.version, config.tag, config.expansionName, config.expansionVersion)
|
||||
versionString = "{0}".format(config.version)
|
||||
licenses = (
|
||||
"pyfa is released under GNU GPLv3 - see included LICENSE file",
|
||||
"All EVE-Online related materials are property of CCP hf.",
|
||||
|
||||
@@ -4,6 +4,7 @@ import wx
|
||||
from service.fit import Fit
|
||||
import gui.globalEvents as GE
|
||||
import gui.mainFrame
|
||||
from gui.utils.helpers_wxPython import HandleCtrlBackspace
|
||||
|
||||
|
||||
class NotesView(wx.Panel):
|
||||
@@ -17,9 +18,16 @@ class NotesView(wx.Panel):
|
||||
self.SetSizer(mainSizer)
|
||||
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
|
||||
self.Bind(wx.EVT_TEXT, self.onText)
|
||||
self.editNotes.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
|
||||
self.saveTimer = wx.Timer(self)
|
||||
self.Bind(wx.EVT_TIMER, self.delayedSave, self.saveTimer)
|
||||
|
||||
def OnKeyDown(self, event):
|
||||
if event.RawControlDown() and event.GetKeyCode() == wx.WXK_BACK:
|
||||
HandleCtrlBackspace(self.editNotes)
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
def fitChanged(self, event):
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(event.fitID)
|
||||
|
||||
34
gui/builtinContextMenus/fillWithModule.py
Normal file
34
gui/builtinContextMenus/fillWithModule.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from gui.contextMenu import ContextMenu
|
||||
import gui.mainFrame
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import gui.globalEvents as GE
|
||||
from service.settings import ContextMenuSettings
|
||||
import gui.fitCommands as cmd
|
||||
|
||||
|
||||
class FillWithModule(ContextMenu):
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.settings = ContextMenuSettings.getInstance()
|
||||
|
||||
def display(self, srcContext, selection):
|
||||
if not self.settings.get('moduleFill'):
|
||||
return False
|
||||
return srcContext in ("fittingModule")
|
||||
|
||||
def getText(self, itmContext, selection):
|
||||
return u"Fill With {0}".format(itmContext if itmContext is not None else "Module")
|
||||
|
||||
def activate(self, fullContext, selection, i):
|
||||
|
||||
srcContext = fullContext[0]
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
|
||||
if srcContext == "fittingModule":
|
||||
self.mainFrame.command.Submit(cmd.GuiFillWithModuleCommand(fitID, selection[0].itemID))
|
||||
return # the command takes care of the PostEvent
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
|
||||
FillWithModule.register()
|
||||
@@ -26,7 +26,10 @@ class MarketJump(ContextMenu):
|
||||
|
||||
sMkt = Market.getInstance()
|
||||
item = getattr(selection[0], "item", selection[0])
|
||||
isMutated = getattr(selection[0], "isMutated", False)
|
||||
mktGrp = sMkt.getMarketGroupByItem(item)
|
||||
if mktGrp is None and isMutated:
|
||||
mktGrp = sMkt.getMarketGroupByItem(selection[0].baseItem)
|
||||
|
||||
# 1663 is Special Edition Festival Assets, we don't have root group for it
|
||||
if mktGrp is None or mktGrp.ID == 1663:
|
||||
@@ -43,7 +46,10 @@ class MarketJump(ContextMenu):
|
||||
if srcContext in ("fittingCharge", "projectedCharge"):
|
||||
item = selection[0].charge
|
||||
elif hasattr(selection[0], "item"):
|
||||
item = selection[0].item
|
||||
if getattr(selection[0], "isMutated", False):
|
||||
item = selection[0].baseItem
|
||||
else:
|
||||
item = selection[0].item
|
||||
else:
|
||||
item = selection[0]
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import math
|
||||
|
||||
import wx
|
||||
import wx.lib.newevent
|
||||
|
||||
from gui.attribute_gauge import AttributeGauge
|
||||
from eos.utils.float import floatUnerr
|
||||
|
||||
_ValueChanged, EVT_VALUE_CHANGED = wx.lib.newevent.NewEvent()
|
||||
|
||||
@@ -58,22 +61,41 @@ class AttributeSlider(wx.Panel):
|
||||
|
||||
self.inverse = inverse
|
||||
|
||||
# The internal slider basically represents the percentage towards the end of the range. It has to be normalized
|
||||
# in this way, otherwise when we start off with a base, if the range is skewed to one side, the base value won't
|
||||
# be centered. We use a range of -100,100 so that we can depend on the SliderValue to contain the percentage
|
||||
# toward one end
|
||||
def getStep(valRange):
|
||||
"""
|
||||
Find step for the passed range, which is based on 1, 2 or 5.
|
||||
Step returned will make sure that range fits 10..50 of them,
|
||||
as close to 10 as possible.
|
||||
"""
|
||||
steps = {1: None, 2: None, 5: None}
|
||||
for baseInc in steps:
|
||||
baseIncAmount = valRange / baseInc
|
||||
incScale = math.floor(math.log10(baseIncAmount) - 1)
|
||||
steps[baseInc] = baseInc * 10 ** incScale
|
||||
chosenBase = min(steps, key=lambda base: valRange / steps[base])
|
||||
chosenStep = steps[chosenBase]
|
||||
if inverse:
|
||||
chosenStep *= -1
|
||||
return chosenStep
|
||||
|
||||
# Additionally, since we want the slider to be accurate to 3 decimal places, we need to blow out the two ends here
|
||||
# (if we have a slider that needs to land on 66.66% towards the right, it will actually be converted to 66%. Se we need it to support 6,666)
|
||||
#
|
||||
# self.SliderMinValue = -100
|
||||
# self.SliderMaxValue = 100
|
||||
# self.SliderValue = 0
|
||||
def getDigitPlaces(minValue, maxValue):
|
||||
minDigits = 3
|
||||
maxDigits = 5
|
||||
currentDecision = minDigits
|
||||
for value in (floatUnerr(minValue), floatUnerr(maxValue)):
|
||||
for currentDigit in range(minDigits, maxDigits + 1):
|
||||
if round(value, currentDigit) == value:
|
||||
if currentDigit > currentDecision:
|
||||
currentDecision = currentDigit
|
||||
break
|
||||
# Max decimal places we can afford to show was not enough
|
||||
else:
|
||||
return maxDigits
|
||||
return currentDecision
|
||||
|
||||
range = [self.UserMinValue, self.UserMaxValue]
|
||||
self.ctrl = wx.SpinCtrlDouble(self, min=minValue, max=maxValue, inc=getStep(maxValue - minValue))
|
||||
self.ctrl.SetDigits(getDigitPlaces(minValue, maxValue))
|
||||
|
||||
self.ctrl = wx.SpinCtrlDouble(self, min=min(range), max=max(range))
|
||||
self.ctrl.SetDigits(3)
|
||||
|
||||
self.ctrl.Bind(wx.EVT_SPINCTRLDOUBLE, self.UpdateValue)
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@ from service.attribute import Attribute
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
|
||||
|
||||
def defaultSort(item):
|
||||
return (item.attributes['metaLevel'].value if 'metaLevel' in item.attributes else 0, item.name)
|
||||
|
||||
|
||||
class ItemCompare(wx.Panel):
|
||||
def __init__(self, parent, stuff, item, items, context=None):
|
||||
# Start dealing with Price stuff to get that thread going
|
||||
@@ -27,8 +31,7 @@ class ItemCompare(wx.Panel):
|
||||
self.currentSort = None
|
||||
self.sortReverse = False
|
||||
self.item = item
|
||||
self.items = sorted(items,
|
||||
key=lambda x: x.attributes['metaLevel'].value if 'metaLevel' in x.attributes else 0)
|
||||
self.items = sorted(items, key=defaultSort)
|
||||
self.attrs = {}
|
||||
|
||||
# get a dict of attrName: attrInfo of all unique attributes across all items
|
||||
@@ -126,10 +129,15 @@ class ItemCompare(wx.Panel):
|
||||
# starts at 0 while the list has the item name as column 0.
|
||||
attr = str(list(self.attrs.keys())[sort - 1])
|
||||
func = lambda _val: _val.attributes[attr].value if attr in _val.attributes else 0.0
|
||||
# Clicked on a column that's not part of our array (price most likely)
|
||||
except IndexError:
|
||||
# Clicked on a column that's not part of our array (price most likely)
|
||||
self.sortReverse = False
|
||||
func = lambda _val: _val.attributes['metaLevel'].value if 'metaLevel' in _val.attributes else 0.0
|
||||
# Price
|
||||
if sort == len(self.attrs) + 1:
|
||||
func = lambda i: i.price.price if i.price.price != 0 else float("Inf")
|
||||
# Something else
|
||||
else:
|
||||
self.sortReverse = False
|
||||
func = defaultSort
|
||||
|
||||
self.items = sorted(self.items, key=func, reverse=self.sortReverse)
|
||||
|
||||
@@ -160,7 +168,7 @@ class ItemCompare(wx.Panel):
|
||||
self.paramList.SetItem(i, x + 1, valueUnit)
|
||||
|
||||
# Add prices
|
||||
self.paramList.SetItem(i, len(self.attrs) + 1, formatAmount(item.price.price, 3, 3, 9, currency=True))
|
||||
self.paramList.SetItem(i, len(self.attrs) + 1, formatAmount(item.price.price, 3, 3, 9, currency=True) if item.price.price else "")
|
||||
|
||||
self.paramList.RefreshRows()
|
||||
self.Layout()
|
||||
|
||||
@@ -15,7 +15,6 @@ class ItemDescription(wx.Panel):
|
||||
fgcolor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
|
||||
|
||||
self.description = wx.html.HtmlWindow(self)
|
||||
|
||||
if not item.description:
|
||||
return
|
||||
|
||||
@@ -24,8 +23,11 @@ class ItemDescription(wx.Panel):
|
||||
desc = re.sub("<( *)font( *)color( *)=(.*?)>(?P<inside>.*?)<( *)/( *)font( *)>", "\g<inside>", desc)
|
||||
# Strip URLs
|
||||
desc = re.sub("<( *)a(.*?)>(?P<inside>.*?)<( *)/( *)a( *)>", "\g<inside>", desc)
|
||||
desc = "<body bgcolor='" + bgcolor.GetAsString(wx.C2S_HTML_SYNTAX) + "' text='" + fgcolor.GetAsString(
|
||||
wx.C2S_HTML_SYNTAX) + "' >" + desc + "</body>"
|
||||
desc = "<body style='background-color: {}; color: {}'>{}</body>".format(
|
||||
bgcolor.GetAsString(wx.C2S_CSS_SYNTAX),
|
||||
fgcolor.GetAsString(wx.C2S_CSS_SYNTAX),
|
||||
desc
|
||||
)
|
||||
|
||||
self.description.SetPage(desc)
|
||||
|
||||
|
||||
@@ -22,38 +22,67 @@ class ItemMutator(wx.Panel):
|
||||
self.item = item
|
||||
self.timer = None
|
||||
self.activeFit = gui.mainFrame.MainFrame.getInstance().getActiveFit()
|
||||
|
||||
font = parent.GetFont()
|
||||
font.SetWeight(wx.BOLD)
|
||||
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
sourceItemsSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
sourceItemsSizer.Add(BitmapLoader.getStaticBitmap(stuff.item.iconID, self, "icons"), 0, wx.LEFT, 5)
|
||||
sourceItemsSizer.Add(BitmapLoader.getStaticBitmap(stuff.mutaplasmid.item.iconID, self, "icons"), 0, wx.LEFT, 0)
|
||||
sourceItemShort = "{} {}".format(stuff.mutaplasmid.item.name.split(" ")[0], stuff.baseItem.name)
|
||||
sourceItemText = wx.StaticText(self, wx.ID_ANY, sourceItemShort)
|
||||
sourceItemText.SetFont(font)
|
||||
sourceItemsSizer.Add(sourceItemText, 0, wx.LEFT, 10)
|
||||
mainSizer.Add(sourceItemsSizer, 0, wx.TOP | wx.EXPAND, 10)
|
||||
|
||||
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
self.goodColor = wx.Colour(96, 191, 0)
|
||||
self.badColor = wx.Colour(255, 64, 0)
|
||||
|
||||
self.event_mapping = {}
|
||||
|
||||
for m in sorted(stuff.mutators.values(), key=lambda x: x.attribute.displayName):
|
||||
# create array for the two ranges
|
||||
min_t = [m.minValue, m.minMod, None]
|
||||
max_t = [m.maxValue, m.maxMod, None]
|
||||
# Format: [raw value, modifier applied to base raw value, display value]
|
||||
range1 = (m.minValue, m.attribute.unit.SimplifyValue(m.minValue))
|
||||
range2 = (m.maxValue, m.attribute.unit.SimplifyValue(m.maxValue))
|
||||
|
||||
# Then we need to determine if it's better than original, which will be the color
|
||||
min_t[2] = min_t[1] < 1 if not m.highIsGood else 1 < min_t[1]
|
||||
max_t[2] = max_t[1] < 1 if not m.highIsGood else 1 < max_t[1]
|
||||
|
||||
# Lastly, we need to determine which range value is "worse" (left side) or "better" (right side)
|
||||
if (m.highIsGood and min_t[1] > max_t[1]) or (not m.highIsGood and min_t[1] < max_t[1]):
|
||||
better_range = min_t
|
||||
# minValue/maxValue do not always correspond to min/max, because these are
|
||||
# just base value multiplied by minMod/maxMod, and in case base is negative
|
||||
# minValue is actually bigger than maxValue
|
||||
if range1[0] <= range2[0]:
|
||||
minRange = range1
|
||||
maxRange = range2
|
||||
else:
|
||||
better_range = max_t
|
||||
minRange = range2
|
||||
maxRange = range1
|
||||
|
||||
if (m.highIsGood and max_t[1] < min_t[1]) or (not m.highIsGood and max_t[1] > min_t[1]):
|
||||
worse_range = max_t
|
||||
if (m.highIsGood and minRange[0] >= maxRange[0]) or (not m.highIsGood and minRange[0] <= maxRange[0]):
|
||||
betterRange = minRange
|
||||
worseRange = maxRange
|
||||
else:
|
||||
worse_range = min_t
|
||||
betterRange = maxRange
|
||||
worseRange = minRange
|
||||
|
||||
if minRange[1] >= maxRange[1]:
|
||||
displayMaxRange = minRange
|
||||
displayMinRange = maxRange
|
||||
else:
|
||||
displayMaxRange = maxRange
|
||||
displayMinRange = minRange
|
||||
|
||||
# If base value is outside of mutation range, make sure that center of slider
|
||||
# corresponds to the value which is closest available to actual base value. It's
|
||||
# how EVE handles it
|
||||
if minRange[0] <= m.baseValue <= maxRange[0]:
|
||||
sliderBaseValue = m.baseValue
|
||||
else:
|
||||
sliderBaseValue = max(minRange[0], min(maxRange[0], m.baseValue))
|
||||
|
||||
headingSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
font = parent.GetFont()
|
||||
font.SetWeight(wx.BOLD)
|
||||
|
||||
headingSizer.Add(BitmapLoader.getStaticBitmap(m.attribute.iconID, self, "icons"), 0, wx.RIGHT, 10)
|
||||
|
||||
displayName = wx.StaticText(self, wx.ID_ANY, m.attribute.displayName)
|
||||
@@ -61,25 +90,25 @@ class ItemMutator(wx.Panel):
|
||||
|
||||
headingSizer.Add(displayName, 3, wx.ALL | wx.EXPAND, 0)
|
||||
|
||||
worst_val = ItemParams.FormatValue(*m.attribute.unit.PreformatValue(worse_range[0]), rounding='dec')
|
||||
worst_text = wx.StaticText(self, wx.ID_ANY, worst_val)
|
||||
worst_text.SetForegroundColour(self.goodColor if worse_range[2] else self.badColor)
|
||||
worseVal = ItemParams.FormatValue(*m.attribute.unit.PreformatValue(worseRange[0]), rounding='dec')
|
||||
worseText = wx.StaticText(self, wx.ID_ANY, worseVal)
|
||||
worseText.SetForegroundColour(self.badColor)
|
||||
|
||||
best_val = ItemParams.FormatValue(*m.attribute.unit.PreformatValue(better_range[0]), rounding='dec')
|
||||
best_text = wx.StaticText(self, wx.ID_ANY, best_val)
|
||||
best_text.SetForegroundColour(self.goodColor if better_range[2] else self.badColor)
|
||||
betterVal = ItemParams.FormatValue(*m.attribute.unit.PreformatValue(betterRange[0]), rounding='dec')
|
||||
betterText = wx.StaticText(self, wx.ID_ANY, betterVal)
|
||||
betterText.SetForegroundColour(self.goodColor)
|
||||
|
||||
headingSizer.Add(worst_text, 0, wx.ALL | wx.EXPAND, 0)
|
||||
headingSizer.Add(worseText, 0, wx.ALL | wx.EXPAND, 0)
|
||||
headingSizer.Add(wx.StaticText(self, wx.ID_ANY, " ─ "), 0, wx.RIGHT | wx.LEFT | wx.EXPAND, 5)
|
||||
headingSizer.Add(best_text, 0, wx.RIGHT | wx.EXPAND, 10)
|
||||
headingSizer.Add(betterText, 0, wx.RIGHT | wx.EXPAND, 10)
|
||||
|
||||
mainSizer.Add(headingSizer, 0, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
slider = AttributeSlider(parent=self,
|
||||
baseValue=m.attribute.unit.SimplifyValue(m.baseValue),
|
||||
minValue=m.attribute.unit.SimplifyValue(min_t[0]),
|
||||
maxValue=m.attribute.unit.SimplifyValue(max_t[0]),
|
||||
inverse=better_range is min_t)
|
||||
baseValue=m.attribute.unit.SimplifyValue(sliderBaseValue),
|
||||
minValue=displayMinRange[1],
|
||||
maxValue=displayMaxRange[1],
|
||||
inverse=displayMaxRange is worseRange)
|
||||
slider.SetValue(m.attribute.unit.SimplifyValue(m.value), False)
|
||||
slider.Bind(EVT_VALUE_CHANGED, self.changeMutatedValue)
|
||||
self.event_mapping[slider] = m
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import wx
|
||||
import gui.utils.color as colorUtils
|
||||
import gui.utils.draw as drawUtils
|
||||
from gui.utils.helpers_wxPython import HandleCtrlBackspace
|
||||
|
||||
SearchButton, EVT_SEARCH_BTN = wx.lib.newevent.NewEvent()
|
||||
CancelButton, EVT_CANCEL_BTN = wx.lib.newevent.NewEvent()
|
||||
@@ -55,7 +56,7 @@ class PFSearchBox(wx.Window):
|
||||
|
||||
self.EditBox.Bind(wx.EVT_SET_FOCUS, self.OnEditSetFocus)
|
||||
self.EditBox.Bind(wx.EVT_KILL_FOCUS, self.OnEditKillFocus)
|
||||
|
||||
self.EditBox.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress)
|
||||
self.EditBox.Bind(wx.EVT_TEXT, self.OnText)
|
||||
self.EditBox.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter)
|
||||
|
||||
@@ -83,6 +84,12 @@ class PFSearchBox(wx.Window):
|
||||
self.Clear()
|
||||
event.Skip()
|
||||
|
||||
def OnKeyPress(self, event):
|
||||
if event.RawControlDown() and event.GetKeyCode() == wx.WXK_BACK:
|
||||
HandleCtrlBackspace(self.EditBox)
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
def Clear(self):
|
||||
self.EditBox.Clear()
|
||||
# self.EditBox.ChangeValue(self.descriptiveText)
|
||||
|
||||
@@ -81,6 +81,11 @@ class PFContextMenuPref(PreferenceView):
|
||||
rbSizerRow3.Add(self.rbBox7, 1, wx.TOP | wx.RIGHT, 5)
|
||||
self.rbBox7.Bind(wx.EVT_RADIOBOX, self.OnSetting7Change)
|
||||
|
||||
self.rbBox8 = wx.RadioBox(panel, -1, "Fill with module", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS)
|
||||
self.rbBox8.SetSelection(self.settings.get('moduleFill'))
|
||||
rbSizerRow3.Add(self.rbBox8, 1, wx.TOP | wx.RIGHT, 5)
|
||||
self.rbBox8.Bind(wx.EVT_RADIOBOX, self.OnSetting8Change)
|
||||
|
||||
mainSizer.Add(rbSizerRow3, 1, wx.ALL | wx.EXPAND, 0)
|
||||
|
||||
panel.SetSizer(mainSizer)
|
||||
@@ -107,6 +112,9 @@ class PFContextMenuPref(PreferenceView):
|
||||
def OnSetting7Change(self, event):
|
||||
self.settings.set('project', event.GetInt())
|
||||
|
||||
def OnSetting8Change(self, event):
|
||||
self.settings.set('moduleFill', event.GetInt())
|
||||
|
||||
def getImage(self):
|
||||
return BitmapLoader.getBitmap("settings_menu", "gui")
|
||||
|
||||
|
||||
@@ -76,10 +76,6 @@ class PFGeneralPref(PreferenceView):
|
||||
self.cbGaugeAnimation = wx.CheckBox(panel, wx.ID_ANY, "Animate gauges", wx.DefaultPosition, wx.DefaultSize, 0)
|
||||
mainSizer.Add(self.cbGaugeAnimation, 0, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
self.cbExportCharges = wx.CheckBox(panel, wx.ID_ANY, "Export loaded charges", wx.DefaultPosition,
|
||||
wx.DefaultSize, 0)
|
||||
mainSizer.Add(self.cbExportCharges, 0, wx.ALL | wx.EXPAND, 5)
|
||||
|
||||
self.cbOpenFitInNew = wx.CheckBox(panel, wx.ID_ANY, "Open fittings in a new page by default",
|
||||
wx.DefaultPosition, wx.DefaultSize, 0)
|
||||
mainSizer.Add(self.cbOpenFitInNew, 0, wx.ALL | wx.EXPAND, 5)
|
||||
@@ -133,7 +129,6 @@ class PFGeneralPref(PreferenceView):
|
||||
self.cbShowTooltip.SetValue(self.sFit.serviceFittingOptions["showTooltip"] or False)
|
||||
self.cbMarketShortcuts.SetValue(self.sFit.serviceFittingOptions["showMarketShortcuts"] or False)
|
||||
self.cbGaugeAnimation.SetValue(self.sFit.serviceFittingOptions["enableGaugeAnimation"])
|
||||
self.cbExportCharges.SetValue(self.sFit.serviceFittingOptions["exportCharges"])
|
||||
self.cbOpenFitInNew.SetValue(self.sFit.serviceFittingOptions["openFitInNew"])
|
||||
self.chPriceSource.SetStringSelection(self.sFit.serviceFittingOptions["priceSource"])
|
||||
self.chPriceSystem.SetStringSelection(self.sFit.serviceFittingOptions["priceSystem"])
|
||||
@@ -151,7 +146,6 @@ class PFGeneralPref(PreferenceView):
|
||||
self.cbShowTooltip.Bind(wx.EVT_CHECKBOX, self.onCBShowTooltip)
|
||||
self.cbMarketShortcuts.Bind(wx.EVT_CHECKBOX, self.onCBShowShortcuts)
|
||||
self.cbGaugeAnimation.Bind(wx.EVT_CHECKBOX, self.onCBGaugeAnimation)
|
||||
self.cbExportCharges.Bind(wx.EVT_CHECKBOX, self.onCBExportCharges)
|
||||
self.cbOpenFitInNew.Bind(wx.EVT_CHECKBOX, self.onCBOpenFitInNew)
|
||||
self.chPriceSource.Bind(wx.EVT_CHOICE, self.onPricesSourceSelection)
|
||||
self.chPriceSystem.Bind(wx.EVT_CHOICE, self.onPriceSelection)
|
||||
@@ -220,9 +214,6 @@ class PFGeneralPref(PreferenceView):
|
||||
def onCBGaugeAnimation(self, event):
|
||||
self.sFit.serviceFittingOptions["enableGaugeAnimation"] = self.cbGaugeAnimation.GetValue()
|
||||
|
||||
def onCBExportCharges(self, event):
|
||||
self.sFit.serviceFittingOptions["exportCharges"] = self.cbExportCharges.GetValue()
|
||||
|
||||
def onCBOpenFitInNew(self, event):
|
||||
self.sFit.serviceFittingOptions["openFitInNew"] = self.cbOpenFitInNew.GetValue()
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import gui.utils.fonts as fonts
|
||||
from .events import FitSelected, SearchSelected, ImportSelected, Stage1Selected, Stage2Selected, Stage3Selected
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
from service.fit import Fit
|
||||
from gui.utils.helpers_wxPython import HandleCtrlBackspace
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
@@ -72,7 +73,7 @@ class NavigationPanel(SFItem.SFBrowserItem):
|
||||
|
||||
# self.BrowserSearchBox.Bind(wx.EVT_TEXT_ENTER, self.OnBrowserSearchBoxEnter)
|
||||
# self.BrowserSearchBox.Bind(wx.EVT_KILL_FOCUS, self.OnBrowserSearchBoxLostFocus)
|
||||
self.BrowserSearchBox.Bind(wx.EVT_KEY_DOWN, self.OnBrowserSearchBoxEsc)
|
||||
self.BrowserSearchBox.Bind(wx.EVT_KEY_DOWN, self.OnBrowserSearchBoxKeyPress)
|
||||
self.BrowserSearchBox.Bind(wx.EVT_TEXT, self.OnScheduleSearch)
|
||||
|
||||
self.SetMinSize(size)
|
||||
@@ -103,9 +104,11 @@ class NavigationPanel(SFItem.SFBrowserItem):
|
||||
def OnBrowserSearchBoxLostFocus(self, event):
|
||||
self.BrowserSearchBox.Show(False)
|
||||
|
||||
def OnBrowserSearchBoxEsc(self, event):
|
||||
def OnBrowserSearchBoxKeyPress(self, event):
|
||||
if event.GetKeyCode() == wx.WXK_ESCAPE:
|
||||
self.BrowserSearchBox.Show(False)
|
||||
elif event.RawControlDown() and event.GetKeyCode() == wx.WXK_BACK:
|
||||
HandleCtrlBackspace(self.BrowserSearchBox)
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ import wx
|
||||
import gui.mainFrame
|
||||
from gui.statsView import StatsView
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
from gui.utils.numberFormatter import formatAmount, roundToPrec
|
||||
from eos.utils.spoolSupport import SpoolType, SpoolOptions
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
@@ -148,27 +149,55 @@ class FirepowerViewFull(StatsView):
|
||||
else:
|
||||
self.stEff.Hide()
|
||||
|
||||
stats = (("labelFullDpsWeapon", lambda: fit.weaponDPS, 3, 0, 0, "%s DPS", None),
|
||||
("labelFullDpsDrone", lambda: fit.droneDPS, 3, 0, 0, "%s DPS", None),
|
||||
("labelFullVolleyTotal", lambda: fit.totalVolley, 3, 0, 0, "%s", "Volley: %.1f"),
|
||||
("labelFullDpsTotal", lambda: fit.totalDPS, 3, 0, 0, "%s", None))
|
||||
# See GH issue #
|
||||
# if fit is not None and fit.totalYield > 0:
|
||||
# self.miningyield.Show()
|
||||
# else:
|
||||
# self.miningyield.Hide()
|
||||
def dpsToolTip(preSpool, fullSpool, prec, lowest, highest):
|
||||
if roundToPrec(preSpool, prec) == roundToPrec(fullSpool, prec):
|
||||
return ""
|
||||
else:
|
||||
return "Spool up: {}-{}".format(
|
||||
formatAmount(preSpool, prec, lowest, highest),
|
||||
formatAmount(fullSpool, prec, lowest, highest))
|
||||
|
||||
# TODO: fetch spoolup option
|
||||
defaultSpoolValue = 1
|
||||
stats = (
|
||||
(
|
||||
"labelFullDpsWeapon",
|
||||
lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False)).total,
|
||||
lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).total,
|
||||
lambda: fit.getWeaponDps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).total,
|
||||
3, 0, 0, "{}{} DPS"),
|
||||
(
|
||||
"labelFullDpsDrone",
|
||||
lambda: fit.getDroneDps().total,
|
||||
lambda: fit.getDroneDps().total,
|
||||
lambda: fit.getDroneDps().total,
|
||||
3, 0, 0, "{}{} DPS"),
|
||||
(
|
||||
"labelFullVolleyTotal",
|
||||
lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False)).total,
|
||||
lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).total,
|
||||
lambda: fit.getTotalVolley(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).total,
|
||||
3, 0, 0, "{}{}"),
|
||||
(
|
||||
"labelFullDpsTotal",
|
||||
lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False)).total,
|
||||
lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).total,
|
||||
lambda: fit.getTotalDps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).total,
|
||||
3, 0, 0, "{}{}"))
|
||||
|
||||
counter = 0
|
||||
for labelName, value, prec, lowest, highest, valueFormat, altFormat in stats:
|
||||
for labelName, val, preSpoolVal, fullSpoolVal, prec, lowest, highest, valueFormat in stats:
|
||||
label = getattr(self, labelName)
|
||||
value = value() if fit is not None else 0
|
||||
value = value if value is not None else 0
|
||||
if self._cachedValues[counter] != value:
|
||||
valueStr = formatAmount(value, prec, lowest, highest)
|
||||
label.SetLabel(valueFormat % valueStr)
|
||||
tipStr = valueFormat % valueStr if altFormat is None else altFormat % value
|
||||
label.SetToolTip(wx.ToolTip(tipStr))
|
||||
self._cachedValues[counter] = value
|
||||
val = val() if fit is not None else 0
|
||||
preSpoolVal = preSpoolVal() if fit is not None else 0
|
||||
fullSpoolVal = fullSpoolVal() if fit is not None else 0
|
||||
if self._cachedValues[counter] != val:
|
||||
tooltipText = dpsToolTip(preSpoolVal, fullSpoolVal, prec, lowest, highest)
|
||||
label.SetLabel(valueFormat.format(
|
||||
formatAmount(val, prec, lowest, highest),
|
||||
"\u02e2" if tooltipText else ""))
|
||||
label.SetToolTip(wx.ToolTip(tooltipText))
|
||||
self._cachedValues[counter] = val
|
||||
counter += 1
|
||||
|
||||
self.panel.Layout()
|
||||
|
||||
@@ -21,7 +21,35 @@
|
||||
import wx
|
||||
from gui.statsView import StatsView
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
from gui.utils.numberFormatter import formatAmount, roundToPrec
|
||||
from eos.utils.spoolSupport import SpoolType, SpoolOptions
|
||||
|
||||
|
||||
stats = [
|
||||
(
|
||||
"labelRemoteCapacitor", "Capacitor:", "{}{} GJ/s", "capacitorInfo", "Capacitor restored",
|
||||
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Capacitor", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Capacitor", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Capacitor", 0),
|
||||
3, 0, 0),
|
||||
(
|
||||
"labelRemoteShield", "Shield:", "{}{} HP/s", "shieldActive", "Shield restored",
|
||||
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Shield", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Shield", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Shield", 0),
|
||||
3, 0, 0),
|
||||
(
|
||||
"labelRemoteArmor", "Armor:", "{}{} HP/s", "armorActive", "Armor restored",
|
||||
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Armor", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Armor", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Armor", 0),
|
||||
3, 0, 0),
|
||||
(
|
||||
"labelRemoteHull", "Hull:", "{}{} HP/s", "hullActive", "Hull restored",
|
||||
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Hull", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Hull", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Hull", 0),
|
||||
3, 0, 0)]
|
||||
|
||||
|
||||
class OutgoingViewFull(StatsView):
|
||||
@@ -48,56 +76,46 @@ class OutgoingViewFull(StatsView):
|
||||
|
||||
contentSizer.Add(sizerOutgoing, 0, wx.EXPAND, 0)
|
||||
|
||||
counter = 0
|
||||
|
||||
rr_list = [
|
||||
("RemoteCapacitor", "Capacitor:", "capacitorInfo", "Capacitor GJ/s per second transferred remotely."),
|
||||
("RemoteShield", "Shield:", "shieldActive", "Shield hitpoints per second repaired remotely."),
|
||||
("RemoteArmor", "Armor:", "armorActive", "Armor hitpoints per second repaired remotely."),
|
||||
("RemoteHull", "Hull:", "hullActive", "Hull hitpoints per second repaired remotely."),
|
||||
]
|
||||
|
||||
for outgoingType, label, image, tooltip in rr_list:
|
||||
for labelName, labelDesc, valueFormat, image, tooltip, val, preSpoolVal, fullSpoolVal, prec, lowest, highest in stats:
|
||||
baseBox = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
baseBox.Add(BitmapLoader.getStaticBitmap("%s_big" % image, parent, "gui"), 0, wx.ALIGN_CENTER)
|
||||
|
||||
if "Capacitor" in outgoingType:
|
||||
lbl = wx.StaticText(parent, wx.ID_ANY, "0 GJ/s")
|
||||
else:
|
||||
lbl = wx.StaticText(parent, wx.ID_ANY, "0 HP/s")
|
||||
|
||||
lbl = wx.StaticText(parent, wx.ID_ANY, valueFormat.format(0, ""))
|
||||
lbl.SetToolTip(wx.ToolTip(tooltip))
|
||||
|
||||
setattr(self, "label%s" % outgoingType, lbl)
|
||||
setattr(self, labelName, lbl)
|
||||
|
||||
baseBox.Add(lbl, 0, wx.ALIGN_CENTER)
|
||||
self._cachedValues.append(0)
|
||||
counter += 1
|
||||
|
||||
sizerOutgoing.Add(baseBox, 1, wx.ALIGN_LEFT)
|
||||
|
||||
def refreshPanel(self, fit):
|
||||
# If we did anything intresting, we'd update our labels to reflect the new fit's stats here
|
||||
|
||||
stats = [
|
||||
("labelRemoteArmor", lambda: fit.remoteReps["Armor"], 3, 0, 0, "%s HP/s", None),
|
||||
("labelRemoteShield", lambda: fit.remoteReps["Shield"], 3, 0, 0, "%s HP/s", None),
|
||||
("labelRemoteHull", lambda: fit.remoteReps["Hull"], 3, 0, 0, "%s HP/s", None),
|
||||
("labelRemoteCapacitor", lambda: fit.remoteReps["Capacitor"], 3, 0, 0, "%s GJ/s", None),
|
||||
]
|
||||
def formatTooltip(text, preSpool, fullSpool, prec, lowest, highest):
|
||||
if roundToPrec(preSpool, prec) == roundToPrec(fullSpool, prec):
|
||||
return False, text
|
||||
else:
|
||||
return True, "{}\nSpool up: {}-{}".format(
|
||||
text,
|
||||
formatAmount(preSpool, prec, lowest, highest),
|
||||
formatAmount(fullSpool, prec, lowest, highest))
|
||||
|
||||
# TODO: fetch spoolup option
|
||||
defaultSpoolValue = 1
|
||||
counter = 0
|
||||
for labelName, value, prec, lowest, highest, valueFormat, altFormat in stats:
|
||||
for labelName, labelDesc, valueFormat, image, tooltip, val, preSpoolVal, fullSpoolVal, prec, lowest, highest in stats:
|
||||
label = getattr(self, labelName)
|
||||
value = value() if fit is not None else 0
|
||||
value = value if value is not None else 0
|
||||
if self._cachedValues[counter] != value:
|
||||
valueStr = formatAmount(value, prec, lowest, highest)
|
||||
label.SetLabel(valueFormat % valueStr)
|
||||
tipStr = valueFormat % valueStr if altFormat is None else altFormat % value
|
||||
label.SetToolTip(wx.ToolTip(tipStr))
|
||||
self._cachedValues[counter] = value
|
||||
val = val(fit, defaultSpoolValue) if fit is not None else 0
|
||||
preSpoolVal = preSpoolVal(fit) if fit is not None else 0
|
||||
fullSpoolVal = fullSpoolVal(fit) if fit is not None else 0
|
||||
if self._cachedValues[counter] != val:
|
||||
hasSpool, tooltipText = formatTooltip(tooltip, preSpoolVal, fullSpoolVal, prec, lowest, highest)
|
||||
label.SetLabel(valueFormat.format(
|
||||
formatAmount(val, prec, lowest, highest),
|
||||
"\u02e2" if hasSpool else ""))
|
||||
label.SetToolTip(wx.ToolTip(tooltipText))
|
||||
self._cachedValues[counter] = val
|
||||
counter += 1
|
||||
self.panel.Layout()
|
||||
self.headerPanel.Layout()
|
||||
|
||||
@@ -20,7 +20,35 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from gui.statsView import StatsView
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
from gui.utils.numberFormatter import formatAmount, roundToPrec
|
||||
from eos.utils.spoolSupport import SpoolType, SpoolOptions
|
||||
|
||||
|
||||
stats = [
|
||||
(
|
||||
"labelRemoteCapacitor", "Capacitor:", "{}{} GJ/s", "capacitorInfo", "Capacitor restored",
|
||||
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Capacitor", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Capacitor", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Capacitor", 0),
|
||||
3, 0, 0),
|
||||
(
|
||||
"labelRemoteShield", "Shield:", "{}{} HP/s", "shieldActive", "Shield restored",
|
||||
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Shield", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Shield", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Shield", 0),
|
||||
3, 0, 0),
|
||||
(
|
||||
"labelRemoteArmor", "Armor:", "{}{} HP/s", "armorActive", "Armor restored",
|
||||
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Armor", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Armor", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Armor", 0),
|
||||
3, 0, 0),
|
||||
(
|
||||
"labelRemoteHull", "Hull:", "{}{} HP/s", "hullActive", "Hull restored",
|
||||
lambda fit, spool: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, spool, False)).get("Hull", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True)).get("Hull", 0),
|
||||
lambda fit: fit.getRemoteReps(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True)).get("Hull", 0),
|
||||
3, 0, 0)]
|
||||
|
||||
|
||||
class OutgoingViewMinimal(StatsView):
|
||||
@@ -47,56 +75,46 @@ class OutgoingViewMinimal(StatsView):
|
||||
|
||||
contentSizer.Add(sizerOutgoing, 0, wx.EXPAND, 0)
|
||||
|
||||
counter = 0
|
||||
|
||||
rr_list = [
|
||||
("RemoteCapacitor", "Capacitor:", "capacitorInfo", "Capacitor GJ/s per second transferred remotely."),
|
||||
("RemoteShield", "Shield:", "shieldActive", "Shield hitpoints per second repaired remotely."),
|
||||
("RemoteArmor", "Armor:", "armorActive", "Armor hitpoints per second repaired remotely."),
|
||||
("RemoteHull", "Hull:", "hullActive", "Hull hitpoints per second repaired remotely."),
|
||||
]
|
||||
|
||||
for outgoingType, label, image, tooltip in rr_list:
|
||||
for labelName, labelDesc, valueFormat, image, tooltip, val, preSpoolVal, fullSpoolVal, prec, lowest, highest in stats:
|
||||
baseBox = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
baseBox.Add(wx.StaticText(contentPanel, wx.ID_ANY, label), 0, wx.ALIGN_CENTER)
|
||||
|
||||
if "Capacitor" in outgoingType:
|
||||
lbl = wx.StaticText(parent, wx.ID_ANY, "0 GJ/s")
|
||||
else:
|
||||
lbl = wx.StaticText(parent, wx.ID_ANY, "0 HP/s")
|
||||
baseBox.Add(wx.StaticText(contentPanel, wx.ID_ANY, labelDesc), 0, wx.ALIGN_CENTER)
|
||||
|
||||
lbl = wx.StaticText(parent, wx.ID_ANY, valueFormat.format(0, ""))
|
||||
lbl.SetToolTip(wx.ToolTip(tooltip))
|
||||
|
||||
setattr(self, "label%s" % outgoingType, lbl)
|
||||
setattr(self, labelName, lbl)
|
||||
|
||||
baseBox.Add(lbl, 0, wx.ALIGN_CENTER)
|
||||
self._cachedValues.append(0)
|
||||
counter += 1
|
||||
|
||||
sizerOutgoing.Add(baseBox, 1, wx.ALIGN_LEFT)
|
||||
|
||||
def refreshPanel(self, fit):
|
||||
# If we did anything intresting, we'd update our labels to reflect the new fit's stats here
|
||||
|
||||
stats = [
|
||||
("labelRemoteArmor", lambda: fit.remoteReps["Armor"], 3, 0, 0, "%s HP/s", None),
|
||||
("labelRemoteShield", lambda: fit.remoteReps["Shield"], 3, 0, 0, "%s HP/s", None),
|
||||
("labelRemoteHull", lambda: fit.remoteReps["Hull"], 3, 0, 0, "%s HP/s", None),
|
||||
("labelRemoteCapacitor", lambda: fit.remoteReps["Capacitor"], 3, 0, 0, "%s GJ/s", None),
|
||||
]
|
||||
def formatTooltip(text, preSpool, fullSpool, prec, lowest, highest):
|
||||
if roundToPrec(preSpool, prec) == roundToPrec(fullSpool, prec):
|
||||
return False, text
|
||||
else:
|
||||
return True, "{}\nSpool up: {}-{}".format(
|
||||
text,
|
||||
formatAmount(preSpool, prec, lowest, highest),
|
||||
formatAmount(fullSpool, prec, lowest, highest))
|
||||
|
||||
# TODO: fetch spoolup option
|
||||
defaultSpoolValue = 1
|
||||
counter = 0
|
||||
for labelName, value, prec, lowest, highest, valueFormat, altFormat in stats:
|
||||
for labelName, labelDesc, valueFormat, image, tooltip, val, preSpoolVal, fullSpoolVal, prec, lowest, highest in stats:
|
||||
label = getattr(self, labelName)
|
||||
value = value() if fit is not None else 0
|
||||
value = value if value is not None else 0
|
||||
if self._cachedValues[counter] != value:
|
||||
valueStr = formatAmount(value, prec, lowest, highest)
|
||||
label.SetLabel(valueFormat % valueStr)
|
||||
tipStr = valueFormat % valueStr if altFormat is None else altFormat % value
|
||||
label.SetToolTip(wx.ToolTip(tipStr))
|
||||
self._cachedValues[counter] = value
|
||||
val = val(fit, defaultSpoolValue) if fit is not None else 0
|
||||
preSpoolVal = preSpoolVal(fit) if fit is not None else 0
|
||||
fullSpoolVal = fullSpoolVal(fit) if fit is not None else 0
|
||||
if self._cachedValues[counter] != val:
|
||||
hasSpool, tooltipText = formatTooltip(tooltip, preSpoolVal, fullSpoolVal, prec, lowest, highest)
|
||||
label.SetLabel(valueFormat.format(
|
||||
formatAmount(val, prec, lowest, highest),
|
||||
"\u02e2" if hasSpool else ""))
|
||||
label.SetToolTip(wx.ToolTip(tooltipText))
|
||||
self._cachedValues[counter] = val
|
||||
counter += 1
|
||||
self.panel.Layout()
|
||||
self.headerPanel.Layout()
|
||||
|
||||
@@ -63,15 +63,20 @@ class RechargeViewFull(StatsView):
|
||||
|
||||
# Add an empty label first for correct alignment.
|
||||
sizerTankStats.Add(wx.StaticText(contentPanel, wx.ID_ANY, ""), 0)
|
||||
toolTipText = {"shieldPassive": "Passive shield recharge", "shieldActive": "Active shield boost",
|
||||
"armorActive": "Armor repair amount", "hullActive": "Hull repair amount"}
|
||||
toolTipText = {
|
||||
"shieldPassive": "Passive shield recharge",
|
||||
"shieldActive": "Active shield boost",
|
||||
"armorActive": "Armor repair amount",
|
||||
"hullActive": "Hull repair amount"}
|
||||
for tankType in ("shieldPassive", "shieldActive", "armorActive", "hullActive"):
|
||||
bitmap = BitmapLoader.getStaticBitmap("%s_big" % tankType, contentPanel, "gui")
|
||||
tooltip = wx.ToolTip(toolTipText[tankType])
|
||||
bitmap.SetToolTip(tooltip)
|
||||
sizerTankStats.Add(bitmap, 0, wx.ALIGN_CENTER)
|
||||
|
||||
toolTipText = {"reinforced": "Reinforced", "sustained": "Sustained"}
|
||||
toolTipText = {
|
||||
"reinforced": "Reinforced",
|
||||
"sustained": "Sustained"}
|
||||
for stability in ("reinforced", "sustained"):
|
||||
bitmap = BitmapLoader.getStaticBitmap("regen%s_big" % stability.capitalize(), contentPanel, "gui")
|
||||
tooltip = wx.ToolTip(toolTipText[stability])
|
||||
@@ -85,7 +90,6 @@ class RechargeViewFull(StatsView):
|
||||
tankTypeCap = tankType[0].capitalize() + tankType[1:]
|
||||
lbl = wx.StaticText(contentPanel, wx.ID_ANY, "0.0", style=wx.ALIGN_RIGHT)
|
||||
setattr(self, "labelTank%s%s" % (stability.capitalize(), tankTypeCap), lbl)
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box.Add(lbl, 0, wx.EXPAND)
|
||||
|
||||
@@ -115,9 +119,23 @@ class RechargeViewFull(StatsView):
|
||||
unitlbl = getattr(self, "unitLabelTank%s%sActive" % (stability.capitalize(), name.capitalize()))
|
||||
unitlbl.SetLabel(unit)
|
||||
if tank is not None:
|
||||
lbl.SetLabel("%.1f" % tank["%sRepair" % name])
|
||||
amount = tank["{}Repair".format(name)]
|
||||
else:
|
||||
lbl.SetLabel("0.0")
|
||||
amount = 0
|
||||
|
||||
if tank is not None and name == "armor":
|
||||
preSpoolAmount = tank["armorRepairPreSpool"]
|
||||
fullSpoolAmount = tank["armorRepairFullSpool"]
|
||||
if round(preSpoolAmount, 1) != round(fullSpoolAmount, 1):
|
||||
ttText = "Spool up: {:.1f}-{:.1f}".format(preSpoolAmount, fullSpoolAmount)
|
||||
else:
|
||||
ttText = ""
|
||||
else:
|
||||
ttText = ""
|
||||
|
||||
lbl.SetLabel("{:.1f}{}".format(amount, "\u02e2" if ttText else ""))
|
||||
lbl.SetToolTip(wx.ToolTip(ttText))
|
||||
unitlbl.SetToolTip(wx.ToolTip(ttText))
|
||||
|
||||
if fit is not None:
|
||||
label = getattr(self, "labelTankSustainedShieldPassive")
|
||||
|
||||
@@ -27,7 +27,7 @@ from gui.viewColumn import ViewColumn
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
from gui.utils.listFormatter import formatList
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.utils.spoolSupport import SpoolType, SpoolOptions
|
||||
|
||||
|
||||
class Miscellanea(ViewColumn):
|
||||
@@ -93,7 +93,9 @@ class Miscellanea(ViewColumn):
|
||||
text = ""
|
||||
tooltip = ""
|
||||
elif max(doomsday_duration / doomsday_dottime, 1) > 1:
|
||||
text = "{0} dmg over {1} s".format(formatAmount(volley * (doomsday_duration / doomsday_dottime), 3, 0, 3), doomsday_duration / 1000)
|
||||
text = "{} over {}s".format(
|
||||
formatAmount(volley * (doomsday_duration / doomsday_dottime), 3, 0, 6),
|
||||
formatAmount((doomsday_duration / 1000), 0, 0, 0))
|
||||
tooltip = "Raw damage done over time"
|
||||
else:
|
||||
text = "{0} dmg".format(formatAmount(volley * (doomsday_duration / doomsday_dottime), 3, 0, 3))
|
||||
@@ -115,16 +117,13 @@ class Miscellanea(ViewColumn):
|
||||
text = "{0}".format(formatAmount(trackingSpeed, 3, 0, 3))
|
||||
tooltip = "tracking speed"
|
||||
info.append((text, tooltip))
|
||||
maxBonusDamage = stuff.getModifiedItemAttr("damageMultiplierBonusMax")
|
||||
bonusDamagePerCycle = stuff.getModifiedItemAttr("damageMultiplierBonusPerCycle")
|
||||
cycleTime = stuff.getModifiedItemAttr("speed")
|
||||
if maxBonusDamage and bonusDamagePerCycle and cycleTime:
|
||||
cyclesToFullDamage = int(maxBonusDamage / bonusDamagePerCycle)
|
||||
timeToFullDamage = (cycleTime / 1000) * cyclesToFullDamage
|
||||
if cyclesToFullDamage:
|
||||
text = "{0}s".format(formatAmount(timeToFullDamage, 3, 0, 3))
|
||||
tooltip = "spool-up time"
|
||||
info.append((text, tooltip))
|
||||
# TODO: fetch spoolup option
|
||||
defaultSpoolValue = 1
|
||||
spoolTime = stuff.getSpoolData(spoolOptions=SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False))[1]
|
||||
if spoolTime:
|
||||
text = "{0}s".format(formatAmount(spoolTime, 3, 0, 3))
|
||||
tooltip = "spool up time"
|
||||
info.append((text, tooltip))
|
||||
if not info:
|
||||
return "", None
|
||||
text = ' | '.join(i[0] for i in info)
|
||||
@@ -333,39 +332,61 @@ class Miscellanea(ViewColumn):
|
||||
tooltip = "Sensor recalibration time"
|
||||
return text, tooltip
|
||||
elif itemGroup == "Remote Armor Repairer":
|
||||
repAmount = stuff.getModifiedItemAttr("armorDamageAmount")
|
||||
cycleTime = stuff.getModifiedItemAttr("duration")
|
||||
if not repAmount or not cycleTime:
|
||||
rps = stuff.getRemoteReps(ignoreState=True)[1]
|
||||
if not rps:
|
||||
return "", None
|
||||
repPerSec = float(repAmount) * 1000 / cycleTime
|
||||
text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3, forceSign=True))
|
||||
text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True))
|
||||
tooltip = "Armor repaired per second"
|
||||
return text, tooltip
|
||||
elif itemGroup == "Remote Shield Booster":
|
||||
repAmount = stuff.getModifiedItemAttr("shieldBonus")
|
||||
cycleTime = stuff.cycleTime
|
||||
if not repAmount or not cycleTime:
|
||||
elif itemGroup == "Mutadaptive Remote Armor Repairer":
|
||||
# TODO: fetch spoolup option
|
||||
defaultSpoolValue = 1
|
||||
spoolOptDefault = SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False)
|
||||
spoolOptPre = SpoolOptions(SpoolType.SCALE, 0, True)
|
||||
spoolOptFull = SpoolOptions(SpoolType.SCALE, 1, True)
|
||||
rrType, rps = stuff.getRemoteReps(spoolOptions=spoolOptDefault, ignoreState=True)
|
||||
rrTypePre, rpsPre = stuff.getRemoteReps(spoolOptions=spoolOptPre, ignoreState=True)
|
||||
rrTypeFull, rpsFull = stuff.getRemoteReps(spoolOptions=spoolOptFull, ignoreState=True)
|
||||
if not rps:
|
||||
return "", None
|
||||
repPerSec = float(repAmount) * 1000 / cycleTime
|
||||
text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3, forceSign=True))
|
||||
text = []
|
||||
tooltip = []
|
||||
text.append("{}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True)))
|
||||
tooltip.append("Armor repaired per second")
|
||||
spoolTime = stuff.getSpoolData(spoolOptDefault)[1]
|
||||
if spoolTime:
|
||||
text.append("{}s".format(formatAmount(spoolTime, 3, 0, 3)))
|
||||
tooltip.append("spool up time")
|
||||
text = " | ".join(text)
|
||||
tooltip = " and ".join(tooltip)
|
||||
spoolTimePre = stuff.getSpoolData(spoolOptPre)[1]
|
||||
spoolTimeFull = stuff.getSpoolData(spoolOptFull)[1]
|
||||
if spoolTimePre != spoolTimeFull:
|
||||
tooltip = "{}\nSpool up: {}-{} over {}s".format(
|
||||
tooltip,
|
||||
formatAmount(rpsPre, 3, 0, 3),
|
||||
formatAmount(rpsFull, 3, 0, 3),
|
||||
formatAmount(spoolTimeFull - spoolTimePre, 3, 0, 3))
|
||||
return text, tooltip
|
||||
elif itemGroup == "Remote Shield Booster":
|
||||
rps = stuff.getRemoteReps(ignoreState=True)[1]
|
||||
if not rps:
|
||||
return "", None
|
||||
text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True))
|
||||
tooltip = "Shield transferred per second"
|
||||
return text, tooltip
|
||||
elif itemGroup == "Remote Capacitor Transmitter":
|
||||
repAmount = stuff.getModifiedItemAttr("powerTransferAmount")
|
||||
cycleTime = stuff.cycleTime
|
||||
if not repAmount or not cycleTime:
|
||||
rps = stuff.getRemoteReps(ignoreState=True)[1]
|
||||
if not rps:
|
||||
return "", None
|
||||
repPerSec = float(repAmount) * 1000 / cycleTime
|
||||
text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3, forceSign=True))
|
||||
text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True))
|
||||
tooltip = "Energy transferred per second"
|
||||
return text, tooltip
|
||||
elif itemGroup == "Remote Hull Repairer":
|
||||
repAmount = stuff.getModifiedItemAttr("structureDamageAmount")
|
||||
cycleTime = stuff.cycleTime
|
||||
if not repAmount or not cycleTime:
|
||||
rps = stuff.getRemoteReps(ignoreState=True)[1]
|
||||
if not rps:
|
||||
return "", None
|
||||
repPerSec = float(repAmount) * 1000 / cycleTime
|
||||
text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3, forceSign=True))
|
||||
text = "{0}/s".format(formatAmount(rps, 3, 0, 3, forceSign=True))
|
||||
tooltip = "Structure repaired per second"
|
||||
return text, tooltip
|
||||
elif itemGroup == "Gang Coordinator":
|
||||
@@ -463,28 +484,11 @@ class Miscellanea(ViewColumn):
|
||||
tooltip = "Mining Yield per second ({0} per hour)".format(formatAmount(minePerSec * 3600, 3, 0, 3))
|
||||
return text, tooltip
|
||||
elif itemGroup == "Logistic Drone":
|
||||
armorAmount = stuff.getModifiedItemAttr("armorDamageAmount")
|
||||
shieldAmount = stuff.getModifiedItemAttr("shieldBonus")
|
||||
hullAmount = stuff.getModifiedItemAttr("structureDamageAmount")
|
||||
repAmount = armorAmount or shieldAmount or hullAmount
|
||||
cycleTime = stuff.getModifiedItemAttr("duration")
|
||||
if not repAmount or not cycleTime:
|
||||
repType, rps = stuff.getRemoteReps(ignoreState=True)
|
||||
if not repType:
|
||||
return "", None
|
||||
repPerSecPerDrone = repPerSec = float(repAmount) * 1000 / cycleTime
|
||||
|
||||
if isinstance(stuff, Drone):
|
||||
repPerSec *= stuff.amount
|
||||
|
||||
text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3))
|
||||
ttEntries = []
|
||||
if hullAmount is not None and repAmount == hullAmount:
|
||||
ttEntries.append("structure")
|
||||
if armorAmount is not None and repAmount == armorAmount:
|
||||
ttEntries.append("armor")
|
||||
if shieldAmount is not None and repAmount == shieldAmount:
|
||||
ttEntries.append("shield")
|
||||
|
||||
tooltip = "{0} HP repaired per second\n{1} HP/s per drone".format(formatList(ttEntries).capitalize(), repPerSecPerDrone)
|
||||
text = "{}/s".format(formatAmount(rps, 3, 0, 3))
|
||||
tooltip = "{} HP repaired per second\n{} HP/s per drone".format(repType, formatAmount(rps / stuff.amount, 3, 0, 3))
|
||||
return text, tooltip
|
||||
elif itemGroup == "Energy Neutralizer Drone":
|
||||
neutAmount = stuff.getModifiedItemAttr("energyNeutralizerAmount")
|
||||
@@ -500,7 +504,7 @@ class Miscellanea(ViewColumn):
|
||||
text = "{0}s".format(cycleTime)
|
||||
tooltip = "Spoolup time"
|
||||
return text, tooltip
|
||||
elif itemGroup in ("Siege Module", "Cynosural Field"):
|
||||
elif itemGroup in ("Siege Module", "Cynosural Field Generator"):
|
||||
amt = stuff.getModifiedItemAttr("consumptionQuantity")
|
||||
if amt:
|
||||
typeID = stuff.getModifiedItemAttr("consumptionType")
|
||||
|
||||
@@ -22,6 +22,7 @@ import wx
|
||||
|
||||
from eos.saveddata.cargo import Cargo
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.price import PriceStatus
|
||||
from service.price import Price as ServicePrice
|
||||
from gui.viewColumn import ViewColumn
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
@@ -45,13 +46,16 @@ class Price(ViewColumn):
|
||||
if stuff.isEmpty:
|
||||
return ""
|
||||
|
||||
price = stuff.item.price
|
||||
priceObj = stuff.item.price
|
||||
|
||||
if not price or not price.isValid:
|
||||
if not priceObj.isValid:
|
||||
return False
|
||||
|
||||
# Fetch actual price as float to not modify its value on Price object
|
||||
price = price.price
|
||||
price = priceObj.price
|
||||
|
||||
if price == 0:
|
||||
return ""
|
||||
|
||||
if isinstance(stuff, Drone) or isinstance(stuff, Cargo):
|
||||
price *= stuff.amount
|
||||
@@ -63,10 +67,12 @@ class Price(ViewColumn):
|
||||
|
||||
def callback(item):
|
||||
price = item[0]
|
||||
text = formatAmount(price.price, 3, 3, 9, currency=True) if price.price else ""
|
||||
if price.failed:
|
||||
text += " (!)"
|
||||
colItem.SetText(text)
|
||||
textItems = []
|
||||
if price.price:
|
||||
textItems.append(formatAmount(price.price, 3, 3, 9, currency=True))
|
||||
if price.status == PriceStatus.fail:
|
||||
textItems.append("(!)")
|
||||
colItem.SetText(" ".join(textItems))
|
||||
|
||||
display.SetItem(colItem)
|
||||
|
||||
|
||||
@@ -129,7 +129,12 @@ class CharacterEntityEditor(EntityEditor):
|
||||
|
||||
def DoRename(self, entity, name):
|
||||
sChar = Character.getInstance()
|
||||
sChar.rename(entity, name)
|
||||
|
||||
if entity.alphaCloneID:
|
||||
trimmed_name = re.sub('[ \(\u03B1\)]+$', '', name)
|
||||
sChar.rename(entity, trimmed_name)
|
||||
else:
|
||||
sChar.rename(entity, name)
|
||||
|
||||
def DoCopy(self, entity, name):
|
||||
sChar = Character.getInstance()
|
||||
|
||||
@@ -188,6 +188,7 @@ from gui.builtinContextMenus import ( # noqa: E402,F401
|
||||
marketJump,
|
||||
# droneSplit,
|
||||
itemRemove,
|
||||
fillWithModule,
|
||||
droneRemoveStack,
|
||||
ammoPattern,
|
||||
project,
|
||||
|
||||
@@ -18,9 +18,13 @@
|
||||
# =============================================================================
|
||||
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
from service.port.eft import EFT_OPTIONS
|
||||
from service.port.multibuy import MULTIBUY_OPTIONS
|
||||
from service.settings import SettingsProvider
|
||||
|
||||
|
||||
@@ -37,39 +41,53 @@ class CopySelectDialog(wx.Dialog):
|
||||
style=wx.DEFAULT_DIALOG_STYLE)
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
self.settings = SettingsProvider.getInstance().getSettings("pyfaExport", {"format": 0, "options": 0})
|
||||
self.copyFormats = OrderedDict((
|
||||
("EFT", (CopySelectDialog.copyFormatEft, EFT_OPTIONS)),
|
||||
("MultiBuy", (CopySelectDialog.copyFormatMultiBuy, MULTIBUY_OPTIONS)),
|
||||
("ESI", (CopySelectDialog.copyFormatEsi, None)),
|
||||
("EFS", (CopySelectDialog.copyFormatEfs, None)),
|
||||
# ("XML", (CopySelectDialog.copyFormatXml, None)),
|
||||
# ("DNA", (CopySelectDialog.copyFormatDna, None)),
|
||||
))
|
||||
|
||||
self.copyFormats = {
|
||||
"EFT": CopySelectDialog.copyFormatEft,
|
||||
"XML": CopySelectDialog.copyFormatXml,
|
||||
"DNA": CopySelectDialog.copyFormatDna,
|
||||
"ESI": CopySelectDialog.copyFormatEsi,
|
||||
"MultiBuy": CopySelectDialog.copyFormatMultiBuy,
|
||||
"EFS": CopySelectDialog.copyFormatEfs
|
||||
}
|
||||
defaultFormatOptions = {}
|
||||
for formatId, formatOptions in self.copyFormats.values():
|
||||
if formatOptions is None:
|
||||
continue
|
||||
defaultFormatOptions[formatId] = {opt[0]: opt[3] for opt in formatOptions}
|
||||
|
||||
self.settings = SettingsProvider.getInstance().getSettings("pyfaExport", {"format": 0, "options": defaultFormatOptions})
|
||||
# Options used to be stored as int (EFT export options only),
|
||||
# overwrite them with new format when needed
|
||||
if isinstance(self.settings["options"], int):
|
||||
self.settings["options"] = defaultFormatOptions
|
||||
|
||||
self.options = {}
|
||||
|
||||
for i, format in enumerate(self.copyFormats.keys()):
|
||||
if i == 0:
|
||||
rdo = wx.RadioButton(self, wx.ID_ANY, format, style=wx.RB_GROUP)
|
||||
initialized = False
|
||||
for formatName, formatData in self.copyFormats.items():
|
||||
formatId, formatOptions = formatData
|
||||
if not initialized:
|
||||
rdo = wx.RadioButton(self, wx.ID_ANY, formatName, style=wx.RB_GROUP)
|
||||
initialized = True
|
||||
else:
|
||||
rdo = wx.RadioButton(self, wx.ID_ANY, format)
|
||||
rdo = wx.RadioButton(self, wx.ID_ANY, formatName)
|
||||
rdo.Bind(wx.EVT_RADIOBUTTON, self.Selected)
|
||||
if self.settings['format'] == self.copyFormats[format]:
|
||||
if self.settings['format'] == formatId:
|
||||
rdo.SetValue(True)
|
||||
self.copyFormat = self.copyFormats[format]
|
||||
self.copyFormat = formatId
|
||||
mainSizer.Add(rdo, 0, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
if format == "EFT":
|
||||
if formatOptions:
|
||||
bsizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.options[formatId] = {}
|
||||
|
||||
for x, v in EFT_OPTIONS.items():
|
||||
ch = wx.CheckBox(self, -1, v['name'])
|
||||
self.options[x] = ch
|
||||
if self.settings['options'] & x:
|
||||
ch.SetValue(True)
|
||||
bsizer.Add(ch, 1, wx.EXPAND | wx.TOP | wx.BOTTOM, 3)
|
||||
for optId, optName, optDesc, _ in formatOptions:
|
||||
checkbox = wx.CheckBox(self, -1, optName)
|
||||
self.options[formatId][optId] = checkbox
|
||||
if self.settings['options'].get(formatId, {}).get(optId, defaultFormatOptions.get(formatId, {}).get(optId)):
|
||||
checkbox.SetValue(True)
|
||||
bsizer.Add(checkbox, 1, wx.EXPAND | wx.TOP | wx.BOTTOM, 3)
|
||||
mainSizer.Add(bsizer, 1, wx.EXPAND | wx.LEFT, 20)
|
||||
|
||||
buttonSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL)
|
||||
@@ -83,21 +101,21 @@ class CopySelectDialog(wx.Dialog):
|
||||
|
||||
def Selected(self, event):
|
||||
obj = event.GetEventObject()
|
||||
format = obj.GetLabel()
|
||||
self.copyFormat = self.copyFormats[format]
|
||||
formatName = obj.GetLabel()
|
||||
self.copyFormat = self.copyFormats[formatName][0]
|
||||
self.toggleOptions()
|
||||
self.Fit()
|
||||
|
||||
def toggleOptions(self):
|
||||
for ch in self.options.values():
|
||||
ch.Enable(self.GetSelected() == CopySelectDialog.copyFormatEft)
|
||||
for formatId in self.options:
|
||||
for checkbox in self.options[formatId].values():
|
||||
checkbox.Enable(self.GetSelected() == formatId)
|
||||
|
||||
def GetSelected(self):
|
||||
return self.copyFormat
|
||||
|
||||
def GetOptions(self):
|
||||
i = 0
|
||||
for x, v in self.options.items():
|
||||
if v.IsChecked():
|
||||
i = i ^ x
|
||||
return i
|
||||
options = {}
|
||||
for formatId in self.options:
|
||||
options[formatId] = {optId: ch.IsChecked() for optId, ch in self.options[formatId].items()}
|
||||
return options
|
||||
|
||||
@@ -67,7 +67,7 @@ class ErrorFrame(wx.Frame):
|
||||
from eos.config import gamedata_version, gamedata_date
|
||||
|
||||
time = datetime.datetime.fromtimestamp(int(gamedata_date)).strftime('%Y-%m-%d %H:%M:%S')
|
||||
version = "pyfa v" + config.getVersion() + '\nEVE Data Version: {} ({})\n\n'.format(gamedata_version, time) # gui.aboutData.versionString
|
||||
version = "pyfa " + config.getVersion() + '\nEVE Data Version: {} ({})\n\n'.format(gamedata_version, time) # gui.aboutData.versionString
|
||||
|
||||
desc = "pyfa has experienced an unexpected issue. Below is a message that contains crucial\n" \
|
||||
"information about how this was triggered. Please contact the developers with the\n" \
|
||||
|
||||
@@ -2,6 +2,7 @@ from .guiToggleModuleState import GuiModuleStateChangeCommand
|
||||
from .guiAddModule import GuiModuleAddCommand
|
||||
from .guiRemoveModule import GuiModuleRemoveCommand
|
||||
from .guiAddCharge import GuiModuleAddChargeCommand
|
||||
from .guiFillWithModule import GuiFillWithModuleCommand
|
||||
from .guiSwapCloneModule import GuiModuleSwapOrCloneCommand
|
||||
from .guiRemoveCargo import GuiRemoveCargoCommand
|
||||
from .guiAddCargo import GuiAddCargoCommand
|
||||
|
||||
50
gui/fitCommands/guiFillWithModule.py
Normal file
50
gui/fitCommands/guiFillWithModule.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import wx
|
||||
import gui.mainFrame
|
||||
from gui import globalEvents as GE
|
||||
from .calc.fitAddModule import FitAddModuleCommand
|
||||
from service.fit import Fit
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class GuiFillWithModuleCommand(wx.Command):
|
||||
def __init__(self, fitID, itemID, position=None):
|
||||
"""
|
||||
Handles adding an item, usually a module, to the Fitting Window.
|
||||
|
||||
:param fitID: The fit ID that we are modifying
|
||||
:param itemID: The item that is to be added to the Fitting View. If this turns out to be a charge, we attempt to
|
||||
set the charge on the underlying module (requires position)
|
||||
:param position: Optional. The position in fit.modules that we are attempting to set the item to
|
||||
"""
|
||||
wx.Command.__init__(self, True, "Module Add: {}".format(itemID))
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
self.sFit = Fit.getInstance()
|
||||
self.fitID = fitID
|
||||
self.itemID = itemID
|
||||
self.internal_history = wx.CommandProcessor()
|
||||
self.position = position
|
||||
self.old_mod = None
|
||||
|
||||
def Do(self):
|
||||
pyfalog.debug("{} Do()".format(self))
|
||||
pyfalog.debug("Trying to append a module")
|
||||
added_modules = 0
|
||||
success = self.internal_history.Submit(FitAddModuleCommand(self.fitID, self.itemID))
|
||||
while (success):
|
||||
added_modules += 1
|
||||
success = self.internal_history.Submit(FitAddModuleCommand(self.fitID, self.itemID))
|
||||
|
||||
if added_modules > 0:
|
||||
self.sFit.recalc(self.fitID)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID, action="modadd", typeID=self.itemID))
|
||||
return True
|
||||
return False
|
||||
|
||||
def Undo(self):
|
||||
pyfalog.debug("{} Undo()".format(self))
|
||||
for _ in self.internal_history.Commands:
|
||||
self.internal_history.Undo()
|
||||
self.sFit.recalc(self.fitID)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID, action="moddel", typeID=self.itemID))
|
||||
return True
|
||||
@@ -91,7 +91,7 @@ class ItemStatsDialog(wx.Dialog):
|
||||
|
||||
self.SetMinSize((300, 200))
|
||||
if "wxGTK" in wx.PlatformInfo: # GTK has huge tab widgets, give it a bit more room
|
||||
self.SetSize((580, 500))
|
||||
self.SetSize((640, 620))
|
||||
else:
|
||||
self.SetSize((550, 500))
|
||||
# self.SetMaxSize((500, -1))
|
||||
@@ -168,8 +168,9 @@ class ItemStatsContainer(wx.Panel):
|
||||
self.mutator = ItemMutator(self.nbContainer, stuff, item)
|
||||
self.nbContainer.AddPage(self.mutator, "Mutations")
|
||||
|
||||
self.desc = ItemDescription(self.nbContainer, stuff, item)
|
||||
self.nbContainer.AddPage(self.desc, "Description")
|
||||
if item.description:
|
||||
self.desc = ItemDescription(self.nbContainer, stuff, item)
|
||||
self.nbContainer.AddPage(self.desc, "Description")
|
||||
|
||||
self.params = ItemParams(self.nbContainer, stuff, item, context)
|
||||
self.nbContainer.AddPage(self.params, "Attributes")
|
||||
|
||||
@@ -703,10 +703,6 @@ class MainFrame(wx.Frame):
|
||||
fit = db_getFit(self.getActiveFit())
|
||||
toClipboard(Port.exportEft(fit, options))
|
||||
|
||||
def clipboardEftImps(self, options):
|
||||
fit = db_getFit(self.getActiveFit())
|
||||
toClipboard(Port.exportEftImps(fit))
|
||||
|
||||
def clipboardDna(self, options):
|
||||
fit = db_getFit(self.getActiveFit())
|
||||
toClipboard(Port.exportDna(fit))
|
||||
@@ -721,7 +717,7 @@ class MainFrame(wx.Frame):
|
||||
|
||||
def clipboardMultiBuy(self, options):
|
||||
fit = db_getFit(self.getActiveFit())
|
||||
toClipboard(Port.exportMultiBuy(fit))
|
||||
toClipboard(Port.exportMultiBuy(fit, options))
|
||||
|
||||
def clipboardEfs(self, options):
|
||||
fit = db_getFit(self.getActiveFit())
|
||||
@@ -744,22 +740,22 @@ class MainFrame(wx.Frame):
|
||||
|
||||
def exportToClipboard(self, event):
|
||||
CopySelectDict = {CopySelectDialog.copyFormatEft: self.clipboardEft,
|
||||
# CopySelectDialog.copyFormatEftImps: self.clipboardEftImps,
|
||||
CopySelectDialog.copyFormatXml: self.clipboardXml,
|
||||
CopySelectDialog.copyFormatDna: self.clipboardDna,
|
||||
CopySelectDialog.copyFormatEsi: self.clipboardEsi,
|
||||
CopySelectDialog.copyFormatMultiBuy: self.clipboardMultiBuy,
|
||||
CopySelectDialog.copyFormatEfs: self.clipboardEfs}
|
||||
dlg = CopySelectDialog(self)
|
||||
dlg.ShowModal()
|
||||
selected = dlg.GetSelected()
|
||||
options = dlg.GetOptions()
|
||||
btnPressed = dlg.ShowModal()
|
||||
|
||||
settings = SettingsProvider.getInstance().getSettings("pyfaExport")
|
||||
settings["format"] = selected
|
||||
settings["options"] = options
|
||||
if btnPressed == wx.ID_OK:
|
||||
selected = dlg.GetSelected()
|
||||
options = dlg.GetOptions()
|
||||
|
||||
CopySelectDict[selected](options)
|
||||
settings = SettingsProvider.getInstance().getSettings("pyfaExport")
|
||||
settings["format"] = selected
|
||||
settings["options"] = options
|
||||
CopySelectDict[selected](options.get(selected))
|
||||
|
||||
try:
|
||||
dlg.Destroy()
|
||||
|
||||
@@ -6,3 +6,23 @@ def YesNoDialog(question='Are you sure you want to do this?', caption='Yes or no
|
||||
result = dlg.ShowModal() == wx.ID_YES
|
||||
dlg.Destroy()
|
||||
return result
|
||||
|
||||
|
||||
def HandleCtrlBackspace(textControl):
|
||||
"""
|
||||
Handles the behavior of Windows ctrl+space
|
||||
deletes everything from the cursor to the left,
|
||||
up to the next whitespace.
|
||||
"""
|
||||
curPos = textControl.GetInsertionPoint()
|
||||
searchText = textControl.GetValue()
|
||||
foundChar = False
|
||||
for startIndex in range(curPos, -1, -1):
|
||||
if startIndex - 1 < 0:
|
||||
break
|
||||
if searchText[startIndex - 1] != " ":
|
||||
foundChar = True
|
||||
elif foundChar:
|
||||
break
|
||||
textControl.Remove(startIndex, curPos)
|
||||
textControl.SetInsertionPoint(startIndex)
|
||||
Reference in New Issue
Block a user