diff --git a/gui/builtinPreferenceViews/pyfaDatabasePreferences.py b/gui/builtinPreferenceViews/pyfaDatabasePreferences.py index e69de29bb..aa95c3f98 100644 --- a/gui/builtinPreferenceViews/pyfaDatabasePreferences.py +++ b/gui/builtinPreferenceViews/pyfaDatabasePreferences.py @@ -0,0 +1,121 @@ +import wx + +from gui.preferenceView import PreferenceView +from gui.bitmapLoader import BitmapLoader + +import gui.mainFrame +import service +import config + +import logging + +logger = logging.getLogger(__name__) + +from eos.db.saveddata.loadDefaultDatabaseValues import DefaultDatabaseValues + + +class PFGeneralPref ( PreferenceView): + title = "Database" + + def populatePanel( self, panel ): + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + self.dirtySettings = False + #self.openFitsSettings = service.SettingsProvider.getInstance().getSettings("pyfaPrevOpenFits", {"enabled": False, "pyfaOpenFits": []}) + + mainSizer = wx.BoxSizer( wx.VERTICAL ) + + self.stTitle = wx.StaticText( panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stTitle.Wrap( -1 ) + self.stTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) ) + mainSizer.Add( self.stTitle, 0, wx.ALL, 5 ) + + self.stSubTitle = wx.StaticText( panel, wx.ID_ANY, u"(Cannot be changed while Pyfa is running.)", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stSubTitle.Wrap( -1 ) + self.stSubTitle.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) + mainSizer.Add( self.stSubTitle, 0, wx.ALL, 5 ) + + self.m_staticline1 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) + mainSizer.Add( self.m_staticline1, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 ) + + #Save in Root + self.cbsaveInRoot = wx.CheckBox( panel, wx.ID_ANY, u"Using Executable Path for Saved Fit Database and Settings", wx.DefaultPosition, wx.DefaultSize, 0 ) + mainSizer.Add( self.cbsaveInRoot, 0, wx.ALL|wx.EXPAND, 5 ) + + #Database path + self.stSetUserPath = wx.StaticText( panel, wx.ID_ANY, u"Pyfa User Path:", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stSetUserPath.Wrap( -1 ) + mainSizer.Add( self.stSetUserPath, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + self.inputUserPath = wx.TextCtrl(panel, wx.ID_ANY, config.savePath, wx.DefaultPosition, wx.DefaultSize, 0) + self.inputUserPath.SetEditable(False) + self.inputUserPath.SetBackgroundColour((200, 200, 200)) + mainSizer.Add(self.inputUserPath, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5) + + #Save DB + self.stFitDB = wx.StaticText( panel, wx.ID_ANY, u"Fitting Database:", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stFitDB.Wrap( -1 ) + mainSizer.Add( self.stFitDB, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.inputFitDB = wx.TextCtrl(panel, wx.ID_ANY, config.saveDB, wx.DefaultPosition, wx.DefaultSize, 0) + self.inputFitDB.SetEditable(False) + self.inputFitDB.SetBackgroundColour((200, 200, 200)) + mainSizer.Add(self.inputFitDB, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5) + + #Game Data DB + self.stGameDB = wx.StaticText( panel, wx.ID_ANY, u"Game Database:", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stGameDB.Wrap( -1 ) + mainSizer.Add( self.stGameDB, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.inputGameDB = wx.TextCtrl(panel, wx.ID_ANY, config.gameDB, wx.DefaultPosition, wx.DefaultSize, 0) + self.inputGameDB.SetEditable(False) + self.inputGameDB.SetBackgroundColour((200, 200, 200)) + mainSizer.Add(self.inputGameDB, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5) + + + defCharSizer = wx.BoxSizer( wx.HORIZONTAL ) + + self.cbsaveInRoot.SetValue(config.saveInRoot) + self.cbsaveInRoot.Bind(wx.EVT_CHECKBOX, self.onCBsaveInRoot) + + self.inputUserPath.Bind(wx.EVT_LEAVE_WINDOW, self.OnWindowLeave) + self.inputFitDB.Bind(wx.EVT_LEAVE_WINDOW, self.OnWindowLeave) + self.inputGameDB.Bind(wx.EVT_LEAVE_WINDOW, self.OnWindowLeave) + + panel.SetSizer( mainSizer ) + panel.Layout() + + + def onCBsaveInRoot(self, event): + # We don't want users to be able to actually change this, + # so if they try and change it, set it back to the current setting + self.cbsaveInRoot.SetValue(config.saveInRoot) + + # If we ever enable it might need this. + ''' + config.saveInRoot = self.cbsaveInRoot.GetValue() + ''' + + def getImage(self): + return BitmapLoader.getBitmap("prefs_settings", "gui") + + def OnWindowLeave(self, event): + # We don't want to do anything when they leave, + # but in the future we'd want to make sure settings + # changed get saved. + pass + + ''' + #Set database path + config.defPaths(self.inputFitDBPath.GetValue()) + + logger.debug("Running database import") + if self.cbimportDefaults is True: + # Import default database values + # Import values that must exist otherwise Pyfa breaks + DefaultDatabaseValues.importRequiredDefaults() + # Import default values for damage profiles + DefaultDatabaseValues.importDamageProfileDefaults() + # Import default values for target resist profiles + DefaultDatabaseValues.importResistProfileDefaults() + ''' + +PFGeneralPref.register() diff --git a/gui/builtinPreferenceViews/pyfaEnginePreferences.py b/gui/builtinPreferenceViews/pyfaEnginePreferences.py index e69de29bb..a79f590b9 100644 --- a/gui/builtinPreferenceViews/pyfaEnginePreferences.py +++ b/gui/builtinPreferenceViews/pyfaEnginePreferences.py @@ -0,0 +1,89 @@ +import logging + +import wx + +import gui.globalEvents as GE +import gui.mainFrame +import service +from gui.bitmapLoader import BitmapLoader +from gui.preferenceView import PreferenceView + +logger = logging.getLogger(__name__) + + +class PFFittingEnginePref ( PreferenceView): + title = "Fitting Engine" + + def populatePanel( self, panel ): + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + self.dirtySettings = False + #self.openFitsSettings = service.SettingsProvider.getInstance().getSettings("pyfaPrevOpenFits", {"enabled": False, "pyfaOpenFits": []}) + + mainSizer = wx.BoxSizer( wx.VERTICAL ) + + self.stTitle = wx.StaticText( panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stTitle.Wrap( -1 ) + self.stTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) ) + mainSizer.Add( self.stTitle, 0, wx.ALL, 5 ) + + self.m_staticline1 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) + mainSizer.Add( self.m_staticline1, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 ) + + self.cbGlobalForceReload = wx.CheckBox( panel, wx.ID_ANY, u"Factor in reload time", wx.DefaultPosition, wx.DefaultSize, 0 ) + mainSizer.Add( self.cbGlobalForceReload, 0, wx.ALL|wx.EXPAND, 5 ) + + self.cbGlobalForceReloadText = wx.StaticText( panel, wx.ID_ANY, u" Ignores reload when calculating capacitor usage,\n damage, and tank.", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.cbGlobalForceReloadText.Wrap( -1 ) + self.cbGlobalForceReloadText.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) + mainSizer.Add( self.cbGlobalForceReloadText, 0, wx.ALL, 5 ) + + # Future code once new cap sim is implemented + ''' + self.cbGlobalForceReactivationTimer = wx.CheckBox( panel, wx.ID_ANY, u"Factor in reactivation timer", wx.DefaultPosition, wx.DefaultSize, 0 ) + mainSizer.Add( self.cbGlobalForceReactivationTimer, 0, wx.ALL|wx.EXPAND, 5 ) + + self.cbGlobalForceReactivationTimerText = wx.StaticText( panel, wx.ID_ANY, u" Ignores reactivation timer when calculating capacitor usage,\n damage, and tank.", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.cbGlobalForceReactivationTimerText.Wrap( -1 ) + self.cbGlobalForceReactivationTimerText.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) + mainSizer.Add( self.cbGlobalForceReactivationTimerText, 0, wx.ALL, 5 ) + ''' + + # Future code once for mining laser crystal + ''' + self.cbGlobalMiningSpecialtyCrystal = wx.CheckBox( panel, wx.ID_ANY, u"Factor in reactivation timer", wx.DefaultPosition, wx.DefaultSize, 0 ) + mainSizer.Add( self.cbGlobalMiningSpecialtyCrystal, 0, wx.ALL|wx.EXPAND, 5 ) + + self.cbGlobalMiningSpecialtyCrystalText = wx.StaticText( panel, wx.ID_ANY, u" If enabled, displays the Specialty Crystal mining amount.\n This is the amount mined when using crystals and mining the matching asteroid.", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.cbGlobalMiningSpecialtyCrystalText.Wrap( -1 ) + self.cbGlobalMiningSpecialtyCrystalText.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) + mainSizer.Add( self.cbGlobalMiningSpecialtyCrystalText, 0, wx.ALL, 5 ) + ''' + + + self.sFit = service.Fit.getInstance() + + self.cbGlobalForceReload.SetValue(self.sFit.serviceFittingOptions["useGlobalForceReload"]) + + self.cbGlobalForceReload.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalForceReloadStateChange) + + panel.SetSizer( mainSizer ) + panel.Layout() + + + def OnCBGlobalForceReloadStateChange(self, event): + self.sFit.serviceFittingOptions["useGlobalForceReload"] = self.cbGlobalForceReload.GetValue() + fitID = self.mainFrame.getActiveFit() + self.sFit.refreshFit(fitID) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) + event.Skip() + + def getImage(self): + return BitmapLoader.getBitmap("prefs_settings", "gui") + + def OnWindowLeave(self, event): + # We don't want to do anything when they leave, + # but in the future we might. + pass + + +PFFittingEnginePref.register() diff --git a/gui/builtinPreferenceViews/pyfaLoggingPreferences.py b/gui/builtinPreferenceViews/pyfaLoggingPreferences.py index e69de29bb..4d574fb93 100644 --- a/gui/builtinPreferenceViews/pyfaLoggingPreferences.py +++ b/gui/builtinPreferenceViews/pyfaLoggingPreferences.py @@ -0,0 +1,67 @@ +import wx + +from gui.preferenceView import PreferenceView +from gui.bitmapLoader import BitmapLoader + +import gui.mainFrame +import service +import config + + +class PFGeneralPref ( PreferenceView): + title = "Logging" + + def populatePanel( self, panel ): + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + self.dirtySettings = False + #self.openFitsSettings = service.SettingsProvider.getInstance().getSettings("pyfaPrevOpenFits", {"enabled": False, "pyfaOpenFits": []}) + + mainSizer = wx.BoxSizer( wx.VERTICAL ) + + self.stTitle = wx.StaticText( panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stTitle.Wrap( -1 ) + self.stTitle.SetFont( wx.Font( 12, 70, 90, 90, False, wx.EmptyString ) ) + mainSizer.Add( self.stTitle, 0, wx.ALL, 5 ) + + self.stSubTitle = wx.StaticText( panel, wx.ID_ANY, u"(Cannot be changed while Pyfa is running.)", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.stSubTitle.Wrap( -1 ) + self.stSubTitle.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) + mainSizer.Add( self.stSubTitle, 0, wx.ALL, 5 ) + + self.m_staticline1 = wx.StaticLine( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) + mainSizer.Add( self.m_staticline1, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 ) + + #Debug Logging + self.cbdebugLogging = wx.CheckBox( panel, wx.ID_ANY, u"Debug Logging Enabled", wx.DefaultPosition, wx.DefaultSize, 0 ) + mainSizer.Add( self.cbdebugLogging, 0, wx.ALL|wx.EXPAND, 5 ) + + + defCharSizer = wx.BoxSizer( wx.HORIZONTAL ) + + self.cbdebugLogging.SetValue(config.debug) + self.cbdebugLogging.Bind(wx.EVT_CHECKBOX, self.onCBdebugLogging) + + panel.SetSizer( mainSizer ) + panel.Layout() + + + def onCBdebugLogging(self, event): + # We don't want users to be able to actually change this, + # so if they try and change it, set it back to the current setting + self.cbdebugLogging.SetValue(config.debug) + + # In case we do, down there road, here's a bit of a start. + ''' + if self.cbdebugLogging.GetValue() is True: + self.cbdebugLogging.SetValue(False) + config.Debug = self.cbdebugLogging.GetValue() + else: + self.cbdebugLogging.SetValue(True) + config.Debug = self.cbdebugLogging.GetValue() + ''' + + def getImage(self): + return BitmapLoader.getBitmap("prefs_settings", "gui") + + +PFGeneralPref.register() diff --git a/gui/builtinPreferenceViews/pyfaStatViewPreferences.py b/gui/builtinPreferenceViews/pyfaStatViewPreferences.py index e69de29bb..d2a2a3ccd 100644 --- a/gui/builtinPreferenceViews/pyfaStatViewPreferences.py +++ b/gui/builtinPreferenceViews/pyfaStatViewPreferences.py @@ -0,0 +1,167 @@ +import wx + +from gui.preferenceView import PreferenceView +from gui.bitmapLoader import BitmapLoader + +import gui.mainFrame +import service +from service.crest import CrestModes + +from wx.lib.intctrl import IntCtrl + + +class PFStatViewPref(PreferenceView): + title = "Statistics Panel" + + def populatePanel(self, panel): + self.settings = service.settings.statViewSettings.getInstance() + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + + self.dirtySettings = False + dlgWidth = panel.GetParent().GetParent().ClientSize.width + mainSizer = wx.BoxSizer(wx.VERTICAL) + + self.stTitle = wx.StaticText(panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0) + self.stTitle.Wrap(-1) + self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString)) + + mainSizer.Add(self.stTitle, 0, wx.ALL, 5) + + self.stInfo = wx.StaticText(panel, wx.ID_ANY, u"Changes require restart of Pyfa to take effect.", + wx.DefaultPosition, wx.DefaultSize, 0) + self.stInfo.Wrap(dlgWidth - 50) + mainSizer.Add(self.stInfo, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5) + + # Row 1 + self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL) + mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5) + + rbSizerRow1 = wx.BoxSizer(wx.HORIZONTAL) + + self.rbResources = wx.RadioBox(panel, -1, "Resources", wx.DefaultPosition, wx.DefaultSize, + ['None', 'Minimal', 'Full'], 1, wx.RA_SPECIFY_COLS) + # Disable minimal as we don't have a view for this yet + self.rbResources.EnableItem(1, False) + self.rbResources.SetSelection(self.settings.get('resources')) + rbSizerRow1.Add(self.rbResources, 1, wx.TOP | wx.RIGHT, 5) + self.rbResources.Bind(wx.EVT_RADIOBOX, self.OnResourcesChange) + + self.rbResistances = wx.RadioBox(panel, -1, "Resistances", wx.DefaultPosition, wx.DefaultSize, + ['None', 'Minimal', 'Full'], 1, wx.RA_SPECIFY_COLS) + # Disable minimal as we don't have a view for this yet + self.rbResistances.EnableItem(1, False) + self.rbResistances.SetSelection(self.settings.get('resistances')) + rbSizerRow1.Add(self.rbResistances, 1, wx.ALL, 5) + self.rbResistances.Bind(wx.EVT_RADIOBOX, self.OnResistancesChange) + + self.rbRecharge = wx.RadioBox(panel, -1, "Shield/Armor Tank", wx.DefaultPosition, wx.DefaultSize, + ['None', 'Minimal', 'Full'], 1, wx.RA_SPECIFY_COLS) + # Disable minimal as we don't have a view for this yet + self.rbRecharge.EnableItem(1, False) + self.rbRecharge.SetSelection(self.settings.get('recharge')) + rbSizerRow1.Add(self.rbRecharge, 1, wx.ALL, 5) + self.rbRecharge.Bind(wx.EVT_RADIOBOX, self.OnRechargeChange) + + mainSizer.Add(rbSizerRow1, 1, wx.ALL | wx.EXPAND, 0) + + # Row 2 + self.m_staticline2 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL) + mainSizer.Add(self.m_staticline2, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5) + + rbSizerRow2 = wx.BoxSizer(wx.HORIZONTAL) + + self.rbFirepower = wx.RadioBox(panel, -1, "Firepower", wx.DefaultPosition, wx.DefaultSize, + ['None', 'Minimal', 'Full'], 1, wx.RA_SPECIFY_COLS) + # Disable minimal as we don't have a view for this yet + self.rbFirepower.EnableItem(1, False) + self.rbFirepower.SetSelection(self.settings.get('firepower')) + rbSizerRow2.Add(self.rbFirepower, 1, wx.TOP | wx.RIGHT, 5) + self.rbFirepower.Bind(wx.EVT_RADIOBOX, self.OnFirepowerChange) + + self.rbCapacitor = wx.RadioBox(panel, -1, "Capacitor", wx.DefaultPosition, wx.DefaultSize, + ['None', 'Minimal', 'Full'], 1, wx.RA_SPECIFY_COLS) + # Disable minimal as we don't have a view for this yet + self.rbCapacitor.EnableItem(1, False) + self.rbCapacitor.SetSelection(self.settings.get('capacitor')) + rbSizerRow2.Add(self.rbCapacitor, 1, wx.ALL, 5) + self.rbCapacitor.Bind(wx.EVT_RADIOBOX, self.OnCapacitorChange) + + self.rbMisc = wx.RadioBox(panel, -1, "Misc", wx.DefaultPosition, wx.DefaultSize, ['None', 'Minimal', 'Full'], 1, + wx.RA_SPECIFY_COLS) + # Disable full as we don't have a view for this yet + self.rbMisc.EnableItem(2, False) + self.rbMisc.SetSelection(self.settings.get('targetingmisc')) + rbSizerRow2.Add(self.rbMisc, 1, wx.ALL, 5) + self.rbMisc.Bind(wx.EVT_RADIOBOX, self.OnTargetingMiscChange) + + mainSizer.Add(rbSizerRow2, 1, wx.ALL | wx.EXPAND, 0) + + # Row 3 + self.m_staticline3 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL) + mainSizer.Add(self.m_staticline3, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5) + + rbSizerRow3 = wx.BoxSizer(wx.HORIZONTAL) + + self.rbPrice = wx.RadioBox(panel, -1, "Price", wx.DefaultPosition, wx.DefaultSize, ['None', 'Minimal', 'Full'], + 1, wx.RA_SPECIFY_COLS) + # Disable minimal as we don't have a view for this yet + self.rbPrice.EnableItem(1, False) + self.rbPrice.SetSelection(self.settings.get('price')) + rbSizerRow3.Add(self.rbPrice, 1, wx.TOP | wx.RIGHT, 5) + self.rbPrice.Bind(wx.EVT_RADIOBOX, self.OnPriceChange) + + # We don't have views for these.....yet + ''' + self.rbMining = wx.RadioBox(panel, -1, "Mining", wx.DefaultPosition, wx.DefaultSize, + ['None', 'Minimal', 'Full'], 1, wx.RA_SPECIFY_COLS) + self.rbMining.SetSelection(self.settings.get('miningyield')) + rbSizerRow3.Add(self.rbMining, 1, wx.ALL, 5) + self.rbMining.Bind(wx.EVT_RADIOBOX, self.OnMiningYieldChange) + + self.rbDrones = wx.RadioBox(panel, -1, "Drones", wx.DefaultPosition, wx.DefaultSize, + ['None', 'Minimal', 'Full'], 1, wx.RA_SPECIFY_COLS) + self.rbDrones.SetSelection(self.settings.get('drones')) + rbSizerRow3.Add(self.rbDrones, 1, wx.ALL, 5) + self.rbDrones.Bind(wx.EVT_RADIOBOX, self.OnDroneChange) + ''' + + mainSizer.Add(rbSizerRow3, 1, wx.ALL | wx.EXPAND, 0) + + panel.SetSizer(mainSizer) + panel.Layout() + + # serviceStatViewDefaultSettings = {"resources": 2, "resistances": 2, "recharge": 2, "firepower": 2, "capacitor": 1, + # "targetingmisc": 2, "price": 2, "miningyield": 0} + + def OnResourcesChange(self, event): + self.settings.set('resources', event.GetInt()) + + def OnResistancesChange(self, event): + self.settings.set('resistances', event.GetInt()) + + def OnRechargeChange(self, event): + self.settings.set('recharge', event.GetInt()) + + def OnFirepowerChange(self, event): + self.settings.set('firepower', event.GetInt()) + + def OnCapacitorChange(self, event): + self.settings.set('capacitor', event.GetInt()) + + def OnTargetingMiscChange(self, event): + self.settings.set('targetingmisc', event.GetInt()) + + def OnPriceChange(self, event): + self.settings.set('price', event.GetInt()) + + def OnMiningYieldChange(self, event): + self.settings.set('miningyield', event.GetInt()) + + def OnDroneChange(self, event): + self.settings.set('drones', event.GetInt()) + + def getImage(self): + return BitmapLoader.getBitmap("pref-gauges_big", "gui") + + +PFStatViewPref.register() \ No newline at end of file diff --git a/gui/builtinStatsViews/targetingMiscViewMinimal.py b/gui/builtinStatsViews/targetingMiscViewMinimal.py index e69de29bb..e0564aaac 100644 --- a/gui/builtinStatsViews/targetingMiscViewMinimal.py +++ b/gui/builtinStatsViews/targetingMiscViewMinimal.py @@ -0,0 +1,251 @@ +# ============================================================================= +# Copyright (C) 2010 Diego Duclos +# +# This file is part of pyfa. +# +# pyfa is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyfa is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with pyfa. If not, see . +# ============================================================================= + +# noinspection PyPackageRequirements +import wx +from gui.statsView import StatsView +from gui.utils.numberFormatter import formatAmount + +try: + from collections import OrderedDict +except ImportError: + from utils.compat import OrderedDict + + +class TargetingMiscViewMinimal(StatsView): + name = "targetingmiscViewMinimal" + + def __init__(self, parent): + StatsView.__init__(self) + self.parent = parent + self._cachedValues = [] + + def getHeaderText(self, fit): + return "Targeting && Misc" + + def getTextExtentW(self, text): + width, height = self.parent.GetTextExtent(text) + return width + + def populatePanel(self, contentPanel, headerPanel): + contentSizer = contentPanel.GetSizer() + + self.panel = contentPanel + self.headerPanel = headerPanel + gridTargetingMisc = wx.FlexGridSizer(1, 3) + contentSizer.Add(gridTargetingMisc, 0, wx.EXPAND | wx.ALL, 0) + gridTargetingMisc.AddGrowableCol(0) + gridTargetingMisc.AddGrowableCol(2) + # Targeting + + gridTargeting = wx.FlexGridSizer(5, 2) + gridTargeting.AddGrowableCol(1) + + gridTargetingMisc.Add(gridTargeting, 0, wx.ALIGN_LEFT | wx.ALL, 5) + + labels = (("Targets", "Targets", ""), + ("Range", "Range", "km"), + ("Scan res.", "ScanRes", "mm"), + ("Sensor str.", "SensorStr", ""), + ("Drone range", "CtrlRange", "km")) + + for header, labelShort, unit in labels: + gridTargeting.Add(wx.StaticText(contentPanel, wx.ID_ANY, "%s: " % header), 0, wx.ALIGN_LEFT) + + box = wx.BoxSizer(wx.HORIZONTAL) + gridTargeting.Add(box, 0, wx.ALIGN_LEFT) + + lbl = wx.StaticText(contentPanel, wx.ID_ANY, "0 %s" % unit) + setattr(self, "label%s" % labelShort, lbl) + box.Add(lbl, 0, wx.ALIGN_LEFT) + + self._cachedValues.append({"main": 0}) + + # Misc + gridTargetingMisc.Add(wx.StaticLine(contentPanel, wx.ID_ANY, style=wx.VERTICAL), 0, wx.EXPAND, 3) + gridMisc = wx.FlexGridSizer(5, 2) + gridMisc.AddGrowableCol(1) + gridTargetingMisc.Add(gridMisc, 0, wx.ALIGN_LEFT | wx.ALL, 5) + + labels = (("Speed", "Speed", "m/s"), + ("Align time", "AlignTime", "s"), + ("Signature", "SigRadius", "m"), + ("Warp Speed", "WarpSpeed", "AU/s"), + ("Cargo", "Cargo", u"m\u00B3")) + + for header, labelShort, unit in labels: + gridMisc.Add(wx.StaticText(contentPanel, wx.ID_ANY, "%s: " % header), 0, wx.ALIGN_LEFT) + + box = wx.BoxSizer(wx.HORIZONTAL) + gridMisc.Add(box, 0, wx.ALIGN_LEFT) + + lbl = wx.StaticText(contentPanel, wx.ID_ANY, "0 %s" % unit) + setattr(self, "labelFull%s" % labelShort, lbl) + box.Add(lbl, 0, wx.ALIGN_LEFT) + + self._cachedValues.append({"main": 0}) + + def refreshPanel(self, fit): + # If we did anything interesting, we'd update our labels to reflect the new fit's stats here + + cargoNamesOrder = OrderedDict(( + ("fleetHangarCapacity", "Fleet hangar"), + ("shipMaintenanceBayCapacity", "Maintenance bay"), + ("specialAmmoHoldCapacity", "Ammo hold"), + ("specialFuelBayCapacity", "Fuel bay"), + ("specialShipHoldCapacity", "Ship hold"), + ("specialSmallShipHoldCapacity", "Small ship hold"), + ("specialMediumShipHoldCapacity", "Medium ship hold"), + ("specialLargeShipHoldCapacity", "Large ship hold"), + ("specialIndustrialShipHoldCapacity", "Industrial ship hold"), + ("specialOreHoldCapacity", "Ore hold"), + ("specialMineralHoldCapacity", "Mineral hold"), + ("specialMaterialBayCapacity", "Material bay"), + ("specialGasHoldCapacity", "Gas hold"), + ("specialSalvageHoldCapacity", "Salvage hold"), + ("specialCommandCenterHoldCapacity", "Command center hold"), + ("specialPlanetaryCommoditiesHoldCapacity", "Planetary goods hold"), + ("specialQuafeHoldCapacity", "Quafe hold") + )) + + cargoValues = { + "main": lambda: fit.ship.getModifiedItemAttr("capacity"), + "fleetHangarCapacity": lambda: fit.ship.getModifiedItemAttr("fleetHangarCapacity"), + "shipMaintenanceBayCapacity": lambda: fit.ship.getModifiedItemAttr("shipMaintenanceBayCapacity"), + "specialAmmoHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialAmmoHoldCapacity"), + "specialFuelBayCapacity": lambda: fit.ship.getModifiedItemAttr("specialFuelBayCapacity"), + "specialShipHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialShipHoldCapacity"), + "specialSmallShipHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialSmallShipHoldCapacity"), + "specialMediumShipHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialMediumShipHoldCapacity"), + "specialLargeShipHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialLargeShipHoldCapacity"), + "specialIndustrialShipHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialIndustrialShipHoldCapacity"), + "specialOreHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialOreHoldCapacity"), + "specialMineralHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialMineralHoldCapacity"), + "specialMaterialBayCapacity": lambda: fit.ship.getModifiedItemAttr("specialMaterialBayCapacity"), + "specialGasHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialGasHoldCapacity"), + "specialSalvageHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialSalvageHoldCapacity"), + "specialCommandCenterHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialCommandCenterHoldCapacity"), + "specialPlanetaryCommoditiesHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialPlanetaryCommoditiesHoldCapacity"), + "specialQuafeHoldCapacity": lambda: fit.ship.getModifiedItemAttr("specialQuafeHoldCapacity") + } + + stats = (("labelTargets", {"main": lambda: fit.maxTargets}, 3, 0, 0, ""), + ("labelRange", {"main": lambda: fit.maxTargetRange / 1000}, 3, 0, 0, "km"), + ("labelScanRes", {"main": lambda: fit.ship.getModifiedItemAttr("scanResolution")}, 3, 0, 0, "mm"), + ("labelSensorStr", {"main": lambda: fit.scanStrength}, 3, 0, 0, ""), + ("labelCtrlRange", {"main": lambda: fit.extraAttributes["droneControlRange"] / 1000}, 3, 0, 0, "km"), + ("labelFullSpeed", {"main": lambda: fit.maxSpeed}, 3, 0, 0, "m/s"), + ("labelFullAlignTime", {"main": lambda: fit.alignTime}, 3, 0, 0, "s"), + ("labelFullSigRadius", {"main": lambda: fit.ship.getModifiedItemAttr("signatureRadius")}, 3, 0, 9, ""), + ("labelFullWarpSpeed", {"main": lambda: fit.warpSpeed}, 3, 0, 0, "AU/s"), + ("labelFullCargo", cargoValues, 4, 0, 9, u"m\u00B3")) + + counter = 0 + RADII = [("Pod", 25), ("Interceptor", 33), ("Frigate", 38), + ("Destroyer", 83), ("Cruiser", 130), + ("Battlecruiser", 265), ("Battleship", 420), + ("Carrier", 3000)] + for labelName, valueDict, prec, lowest, highest, unit in stats: + label = getattr(self, labelName) + newValues = {} + for valueAlias, value in valueDict.items(): + value = value() if fit is not None else 0 + value = value if value is not None else 0 + newValues[valueAlias] = value + if self._cachedValues[counter] != newValues: + mainValue = newValues["main"] + otherValues = dict((k, newValues[k]) for k in filter(lambda k: k != "main", newValues)) + if labelName == "labelFullCargo": + # Get sum of all cargoholds except for maintenance bay + additionalCargo = sum(otherValues.values()) + if additionalCargo > 0: + label.SetLabel("%s+%s %s" % (formatAmount(mainValue, prec, lowest, highest), + formatAmount(additionalCargo, prec, lowest, highest), + unit)) + else: + label.SetLabel("%s %s" % (formatAmount(mainValue, prec, lowest, highest), unit)) + else: + label.SetLabel("%s %s" % (formatAmount(mainValue, prec, lowest, highest), unit)) + # Tooltip stuff + if fit: + if labelName == "labelScanRes": + lockTime = "%s\n" % "Lock Times".center(30) + for size, radius in RADII: + left = "%.1fs" % fit.calculateLockTime(radius) + right = "%s [%d]" % (size, radius) + lockTime += "%5s\t%s\n" % (left, right) + label.SetToolTip(wx.ToolTip(lockTime)) + elif labelName == "labelFullSigRadius": + label.SetToolTip(wx.ToolTip("Probe Size: %.3f" % (fit.probeSize or 0))) + elif labelName == "labelFullWarpSpeed": + label.SetToolTip(wx.ToolTip("Max Warp Distance: %.1f AU" % fit.maxWarpDistance)) + elif labelName == "labelSensorStr": + if fit.jamChance > 0: + label.SetToolTip(wx.ToolTip("Type: %s\n%.1f%% Chance of Jam" % (fit.scanType, fit.jamChance))) + else: + label.SetToolTip(wx.ToolTip("Type: %s" % fit.scanType)) + elif labelName == "labelFullAlignTime": + alignTime = "Align:\t%.3fs" % mainValue + mass = 'Mass:\t{:,.0f}kg'.format(fit.ship.getModifiedItemAttr("mass")) + agility = "Agility:\t%.3fx" % (fit.ship.getModifiedItemAttr("agility") or 0) + label.SetToolTip(wx.ToolTip("%s\n%s\n%s" % (alignTime, mass, agility))) + elif labelName == "labelFullCargo": + tipLines = [u"Cargohold: {:,.2f}m\u00B3 / {:,.2f}m\u00B3".format(fit.cargoBayUsed, newValues["main"])] + for attrName, tipAlias in cargoNamesOrder.items(): + if newValues[attrName] > 0: + tipLines.append(u"{}: {:,.2f}m\u00B3".format(tipAlias, newValues[attrName])) + label.SetToolTip(wx.ToolTip(u"\n".join(tipLines))) + else: + label.SetToolTip(wx.ToolTip("%.1f" % mainValue)) + else: + label.SetToolTip(wx.ToolTip("")) + self._cachedValues[counter] = newValues + elif labelName == "labelFullWarpSpeed": + if fit: + label.SetToolTip(wx.ToolTip("Max Warp Distance: %.1f AU" % fit.maxWarpDistance)) + else: + label.SetToolTip(wx.ToolTip("")) + elif labelName == "labelSensorStr": + if fit: + if fit.jamChance > 0: + label.SetToolTip(wx.ToolTip("Type: %s\n%.1f%% Chance of Jam" % (fit.scanType, fit.jamChance))) + else: + label.SetToolTip(wx.ToolTip("Type: %s" % fit.scanType)) + else: + label.SetToolTip(wx.ToolTip("")) + elif labelName == "labelFullCargo": + if fit: + cachedCargo = self._cachedValues[counter] + # if you add stuff to cargo, the capacity doesn't change and thus it is still cached + # This assures us that we force refresh of cargo tooltip + tipLines = [u"Cargohold: {:,.2f}m\u00B3 / {:,.2f}m\u00B3".format(fit.cargoBayUsed, cachedCargo["main"])] + for attrName, tipAlias in cargoNamesOrder.items(): + if cachedCargo[attrName] > 0: + tipLines.append(u"{}: {:,.2f}m\u00B3".format(tipAlias, cachedCargo[attrName])) + label.SetToolTip(wx.ToolTip(u"\n".join(tipLines))) + else: + label.SetToolTip(wx.ToolTip("")) + + counter += 1 + + self.panel.Layout() + self.headerPanel.Layout() + + +TargetingMiscViewMinimal.register()