Breakout shipBrowser into individual class files
This commit is contained in:
0
gui/builtinShipBrowser/__init__.py
Normal file
0
gui/builtinShipBrowser/__init__.py
Normal file
129
gui/builtinShipBrowser/categoryItem.py
Normal file
129
gui/builtinShipBrowser/categoryItem.py
Normal file
@@ -0,0 +1,129 @@
|
||||
# coding: utf-8
|
||||
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
from gui.builtinShipBrowser.sfBrowserItem import SFBrowserItem
|
||||
import gui.utils.colorUtils as colorUtils
|
||||
import gui.utils.drawUtils as drawUtils
|
||||
import gui.utils.fonts as fonts
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from .events import *
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class CategoryItem(SFBrowserItem):
|
||||
def __init__(self, parent, categoryID, fittingInfo, size=(0, 16)):
|
||||
SFBrowserItem.__init__(self, parent, size=size)
|
||||
|
||||
if categoryID:
|
||||
self.shipBmp = BitmapLoader.getBitmap("ship_small", "gui")
|
||||
else:
|
||||
self.shipBmp = wx.EmptyBitmap(16, 16)
|
||||
|
||||
self.dropShadowBitmap = drawUtils.CreateDropShadowBitmap(self.shipBmp, 0.2)
|
||||
|
||||
self.categoryID = categoryID
|
||||
self.fittingInfo = fittingInfo
|
||||
self.shipBrowser = self.Parent.Parent
|
||||
|
||||
self.padding = 4
|
||||
|
||||
self.fontBig = wx.Font(fonts.BIG, wx.SWISS, wx.NORMAL, wx.NORMAL)
|
||||
|
||||
self.animTimerId = wx.NewId()
|
||||
|
||||
self.animTimer = wx.Timer(self, self.animTimerId)
|
||||
self.animStep = 0
|
||||
self.animPeriod = 10
|
||||
self.animDuration = 100
|
||||
|
||||
self.Bind(wx.EVT_TIMER, self.OnTimer)
|
||||
|
||||
# =====================================================================
|
||||
# Disabled - it will be added as an option to Preferences
|
||||
self.animCount = 0
|
||||
# self.animTimer.Start(self.animPeriod)
|
||||
# =====================================================================
|
||||
|
||||
def OnTimer(self, event):
|
||||
step = self.OUT_QUAD(self.animStep, 0, 10, self.animDuration)
|
||||
self.animCount = 10 - step
|
||||
self.animStep += self.animPeriod
|
||||
if self.animStep > self.animDuration or self.animCount < 0:
|
||||
self.animCount = 0
|
||||
self.animTimer.Stop()
|
||||
self.Refresh()
|
||||
|
||||
@staticmethod
|
||||
def OUT_QUAD(t, b, c, d):
|
||||
t = float(t)
|
||||
b = float(b)
|
||||
c = float(c)
|
||||
d = float(d)
|
||||
|
||||
t /= d
|
||||
|
||||
return -c * t * (t - 2) + b
|
||||
|
||||
def GetType(self):
|
||||
return 1
|
||||
|
||||
def MouseLeftUp(self, event):
|
||||
|
||||
categoryID = self.categoryID
|
||||
wx.PostEvent(self.shipBrowser, Stage2Selected(categoryID=categoryID, back=False))
|
||||
|
||||
def UpdateElementsPos(self, mdc):
|
||||
rect = self.GetRect()
|
||||
self.shipBmpx = self.padding
|
||||
self.shipBmpy = (rect.height - self.shipBmp.GetWidth()) / 2
|
||||
|
||||
self.shipBmpx -= self.animCount
|
||||
|
||||
mdc.SetFont(self.fontBig)
|
||||
categoryName, fittings = self.fittingInfo
|
||||
wtext, htext = mdc.GetTextExtent(categoryName)
|
||||
|
||||
self.catx = self.shipBmpx + self.shipBmp.GetWidth() + self.padding
|
||||
self.caty = (rect.height - htext) / 2
|
||||
|
||||
def DrawItem(self, mdc):
|
||||
# rect = self.GetRect()
|
||||
self.UpdateElementsPos(mdc)
|
||||
|
||||
windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
|
||||
textColor = colorUtils.GetSuitableColor(windowColor, 1)
|
||||
|
||||
mdc.SetTextForeground(textColor)
|
||||
mdc.DrawBitmap(self.dropShadowBitmap, self.shipBmpx + 1, self.shipBmpy + 1)
|
||||
mdc.DrawBitmap(self.shipBmp, self.shipBmpx, self.shipBmpy, 0)
|
||||
|
||||
mdc.SetFont(self.fontBig)
|
||||
|
||||
categoryName, fittings = self.fittingInfo
|
||||
|
||||
mdc.DrawText(categoryName, self.catx, self.caty)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Waiting for total #fits impl in eos/service
|
||||
#
|
||||
# mdc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL, False))
|
||||
#
|
||||
# if fittings <1:
|
||||
# fformat = "No fits"
|
||||
# else:
|
||||
# if fittings == 1:
|
||||
# fformat = "%d fit"
|
||||
# else:
|
||||
# fformat = "%d fits"
|
||||
#
|
||||
# if fittings>0:
|
||||
# xtext, ytext = mdc.GetTextExtent(fformat % fittings)
|
||||
# ypos = (rect.height - ytext)/2
|
||||
# else:
|
||||
# xtext, ytext = mdc.GetTextExtent(fformat)
|
||||
# ypos = (rect.height - ytext)/2
|
||||
# =============================================================================
|
||||
14
gui/builtinShipBrowser/events.py
Normal file
14
gui/builtinShipBrowser/events.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx.lib.newevent
|
||||
|
||||
FitRenamed, EVT_FIT_RENAMED = wx.lib.newevent.NewEvent()
|
||||
FitSelected, EVT_FIT_SELECTED = wx.lib.newevent.NewEvent()
|
||||
FitRemoved, EVT_FIT_REMOVED = wx.lib.newevent.NewEvent()
|
||||
|
||||
BoosterListUpdated, BOOSTER_LIST_UPDATED = wx.lib.newevent.NewEvent()
|
||||
|
||||
Stage1Selected, EVT_SB_STAGE1_SEL = wx.lib.newevent.NewEvent()
|
||||
Stage2Selected, EVT_SB_STAGE2_SEL = wx.lib.newevent.NewEvent()
|
||||
Stage3Selected, EVT_SB_STAGE3_SEL = wx.lib.newevent.NewEvent()
|
||||
SearchSelected, EVT_SB_SEARCH_SEL = wx.lib.newevent.NewEvent()
|
||||
ImportSelected, EVT_SB_IMPORT_SEL = wx.lib.newevent.NewEvent()
|
||||
604
gui/builtinShipBrowser/fitItem.py
Normal file
604
gui/builtinShipBrowser/fitItem.py
Normal file
@@ -0,0 +1,604 @@
|
||||
# coding: utf-8
|
||||
|
||||
import re
|
||||
import time
|
||||
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
import gui.builtinShipBrowser.sfBrowserItem as SFItem
|
||||
import gui.globalEvents as GE
|
||||
import gui.mainFrame
|
||||
import gui.utils.colorUtils as colorUtils
|
||||
import gui.utils.drawUtils as drawUtils
|
||||
import gui.utils.fonts as fonts
|
||||
from events import *
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui.builtinShipBrowser.pfBitmapFrame import PFBitmapFrame
|
||||
from service.fit import Fit
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class FitItem(SFItem.SFBrowserItem):
|
||||
def __init__(self, parent, fitID=None, shipFittingInfo=("Test", "TestTrait", "cnc's avatar", 0, 0, None), shipID=None,
|
||||
itemData=None,
|
||||
id=wx.ID_ANY, pos=wx.DefaultPosition,
|
||||
size=(0, 40), style=0):
|
||||
|
||||
# =====================================================================
|
||||
# animCount should be 10 if we enable animation in Preferences
|
||||
# =====================================================================
|
||||
|
||||
self.animCount = 0
|
||||
self.selectedDelta = 0
|
||||
|
||||
SFItem.SFBrowserItem.__init__(self, parent, size=size)
|
||||
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
self._itemData = itemData
|
||||
|
||||
self.fitID = fitID
|
||||
|
||||
self.shipID = shipID
|
||||
|
||||
self.shipBrowser = self.Parent.Parent
|
||||
|
||||
self.shipBmp = None
|
||||
|
||||
self.deleted = False
|
||||
|
||||
if shipID:
|
||||
self.shipBmp = BitmapLoader.getBitmap(str(shipID), "renders")
|
||||
|
||||
if not self.shipBmp:
|
||||
self.shipBmp = BitmapLoader.getBitmap("ship_no_image_big", "gui")
|
||||
|
||||
self.shipFittingInfo = shipFittingInfo
|
||||
self.shipName, self.shipTrait, self.fitName, self.fitBooster, self.timestamp, self.notes = shipFittingInfo
|
||||
|
||||
self.shipTrait = re.sub("<.*?>", " ", self.shipTrait)
|
||||
# see GH issue #62
|
||||
|
||||
# Disabling this due to change in gang boosts Nov 2016
|
||||
# if self.fitBooster is None: self.fitBooster = False
|
||||
self.fitBooster = False
|
||||
|
||||
self.boosterBmp = BitmapLoader.getBitmap("fleet_fc_small", "gui")
|
||||
self.copyBmp = BitmapLoader.getBitmap("fit_add_small", "gui")
|
||||
self.renameBmp = BitmapLoader.getBitmap("fit_rename_small", "gui")
|
||||
self.deleteBmp = BitmapLoader.getBitmap("fit_delete_small", "gui")
|
||||
self.acceptBmp = BitmapLoader.getBitmap("faccept_small", "gui")
|
||||
self.shipEffBk = BitmapLoader.getBitmap("fshipbk_big", "gui")
|
||||
|
||||
img = wx.ImageFromBitmap(self.shipEffBk)
|
||||
img = img.Mirror(False)
|
||||
self.shipEffBkMirrored = wx.BitmapFromImage(img)
|
||||
|
||||
self.dragTLFBmp = None
|
||||
|
||||
self.bkBitmap = None
|
||||
|
||||
self.__setToolTip()
|
||||
|
||||
self.padding = 4
|
||||
self.editWidth = 150
|
||||
|
||||
self.dragging = False
|
||||
self.dragged = False
|
||||
self.dragMotionTrail = 5
|
||||
self.dragMotionTrigger = self.dragMotionTrail
|
||||
self.dragWindow = None
|
||||
|
||||
self.fontBig = wx.Font(fonts.BIG, wx.SWISS, wx.NORMAL, wx.BOLD)
|
||||
self.fontNormal = wx.Font(fonts.NORMAL, wx.SWISS, wx.NORMAL, wx.NORMAL)
|
||||
self.fontSmall = wx.Font(fonts.SMALL, wx.SWISS, wx.NORMAL, wx.NORMAL)
|
||||
|
||||
self.SetDraggable()
|
||||
|
||||
self.boosterBtn = self.toolbar.AddButton(self.boosterBmp, "Booster", show=self.fitBooster)
|
||||
self.toolbar.AddButton(self.copyBmp, "Copy", self.copyBtnCB)
|
||||
self.renameBtn = self.toolbar.AddButton(self.renameBmp, "Rename", self.renameBtnCB)
|
||||
self.toolbar.AddButton(self.deleteBmp, "Delete", self.deleteBtnCB)
|
||||
|
||||
self.tcFitName = wx.TextCtrl(self, wx.ID_ANY, "%s" % self.fitName, wx.DefaultPosition, (self.editWidth, -1),
|
||||
wx.TE_PROCESS_ENTER)
|
||||
|
||||
if self.shipBrowser.fitIDMustEditName != self.fitID:
|
||||
self.tcFitName.Show(False)
|
||||
else:
|
||||
self.tcFitName.SetFocus()
|
||||
self.tcFitName.SelectAll()
|
||||
self.shipBrowser.fitIDMustEditName = -1
|
||||
self.renameBtn.SetBitmap(self.acceptBmp)
|
||||
|
||||
self.tcFitName.Bind(wx.EVT_TEXT_ENTER, self.renameFit)
|
||||
self.tcFitName.Bind(wx.EVT_KILL_FOCUS, self.editLostFocus)
|
||||
self.tcFitName.Bind(wx.EVT_KEY_DOWN, self.editCheckEsc)
|
||||
self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.OnMouseCaptureLost)
|
||||
|
||||
self.animTimerId = wx.NewId()
|
||||
self.animTimer = wx.Timer(self, self.animTimerId)
|
||||
self.animStep = 0
|
||||
self.animPeriod = 10
|
||||
self.animDuration = 100
|
||||
|
||||
self.maxDelta = 48
|
||||
|
||||
self.Bind(wx.EVT_TIMER, self.OnTimer)
|
||||
|
||||
# =====================================================================
|
||||
# DISABLED - it will be added as an option in PREFERENCES
|
||||
|
||||
# if self.shipBrowser.GetActiveStage() != 4 and self.shipBrowser.GetLastStage() !=3:
|
||||
# self.animTimer.Start(self.animPeriod)
|
||||
# else:
|
||||
# self.animCount = 0
|
||||
# =====================================================================
|
||||
|
||||
"""
|
||||
# Remove this bit as the time stuff is non-functional (works... but not exactly sure what it's meant to do)
|
||||
self.selTimerID = wx.NewId()
|
||||
|
||||
self.selTimer = wx.Timer(self, self.selTimerID)
|
||||
self.selTimer.Start(100)
|
||||
"""
|
||||
|
||||
self.Bind(wx.EVT_RIGHT_UP, self.OnContextMenu)
|
||||
self.Bind(wx.EVT_MIDDLE_UP, self.OpenNewTab)
|
||||
|
||||
def __setToolTip(self):
|
||||
sFit = Fit.getInstance()
|
||||
# show no tooltip if no trait available or setting is disabled
|
||||
if self.shipTrait and sFit.serviceFittingOptions["showShipBrowserTooltip"]:
|
||||
notes = ""
|
||||
if self.notes:
|
||||
notes = u'─' * 20 + u"\nNotes: {}\n".format(self.notes[:197] + '...' if len(self.notes) > 200 else self.notes)
|
||||
self.SetToolTip(wx.ToolTip(u'{}\n{}{}\n{}'.format(self.shipName, notes, u'─' * 20, self.shipTrait)))
|
||||
|
||||
def OnKeyDown(self, event):
|
||||
if event.GetKeyCode() == 32: # space
|
||||
self.selectFit(event)
|
||||
event.Skip()
|
||||
|
||||
def OpenNewTab(self, evt):
|
||||
self.selectFit(newTab=True)
|
||||
|
||||
def OnToggleBooster(self, event):
|
||||
sFit = Fit.getInstance()
|
||||
sFit.toggleBoostFit(self.fitID)
|
||||
self.fitBooster = not self.fitBooster
|
||||
self.boosterBtn.Show(self.fitBooster)
|
||||
self.Refresh()
|
||||
wx.PostEvent(self.mainFrame, BoosterListUpdated())
|
||||
event.Skip()
|
||||
|
||||
def OnProjectToFit(self, event):
|
||||
activeFit = self.mainFrame.getActiveFit()
|
||||
if activeFit:
|
||||
sFit = Fit.getInstance()
|
||||
projectedFit = sFit.getFit(self.fitID)
|
||||
sFit.project(activeFit, projectedFit)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFit))
|
||||
self.mainFrame.additionsPane.select("Projected")
|
||||
|
||||
def OnAddCommandFit(self, event):
|
||||
activeFit = self.mainFrame.getActiveFit()
|
||||
if activeFit:
|
||||
sFit = Fit.getInstance()
|
||||
commandFit = sFit.getFit(self.fitID)
|
||||
sFit.addCommandFit(activeFit, commandFit)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFit))
|
||||
self.mainFrame.additionsPane.select("Command")
|
||||
|
||||
def OnMouseCaptureLost(self, event):
|
||||
""" Destroy drag information (GH issue #479)"""
|
||||
if self.dragging and self.dragged:
|
||||
self.dragging = False
|
||||
self.dragged = False
|
||||
if self.HasCapture():
|
||||
self.ReleaseMouse()
|
||||
self.dragWindow.Show(False)
|
||||
self.dragWindow = None
|
||||
|
||||
def OnContextMenu(self, event):
|
||||
""" Handles context menu for fit. Dragging is handled by MouseLeftUp() """
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.mainFrame.getActiveFit())
|
||||
|
||||
if not fit:
|
||||
return
|
||||
|
||||
pos = wx.GetMousePosition()
|
||||
pos = self.ScreenToClient(pos)
|
||||
|
||||
# Even though we may not select a booster, automatically set this so that the fleet pane knows which fit we're applying
|
||||
self.mainFrame.additionsPane.gangPage.draggedFitID = self.fitID
|
||||
|
||||
menu = wx.Menu()
|
||||
# toggleItem = menu.Append(wx.ID_ANY, "Booster Fit", kind=wx.ITEM_CHECK)
|
||||
# menu.Check(toggleItem.GetId(), self.fitBooster)
|
||||
# self.Bind(wx.EVT_MENU, self.OnToggleBooster, toggleItem)
|
||||
|
||||
# if fit and not fit.isStructure:
|
||||
# # If there is an active fit, get menu for setting individual boosters
|
||||
# menu.AppendSeparator()
|
||||
# boosterMenu = self.mainFrame.additionsPane.gangPage.buildBoostermenu()
|
||||
# menu.AppendSubMenu(boosterMenu, 'Set Booster')
|
||||
|
||||
if fit:
|
||||
newTabItem = menu.Append(wx.ID_ANY, "Open in new tab")
|
||||
self.Bind(wx.EVT_MENU, self.OpenNewTab, newTabItem)
|
||||
|
||||
projectedItem = menu.Append(wx.ID_ANY, "Project onto Active Fit")
|
||||
self.Bind(wx.EVT_MENU, self.OnProjectToFit, projectedItem)
|
||||
|
||||
commandItem = menu.Append(wx.ID_ANY, "Add Command Booster")
|
||||
self.Bind(wx.EVT_MENU, self.OnAddCommandFit, commandItem)
|
||||
|
||||
self.PopupMenu(menu, pos)
|
||||
|
||||
event.Skip()
|
||||
|
||||
def GetType(self):
|
||||
return 3
|
||||
|
||||
def OnTimer(self, event):
|
||||
|
||||
# @todo: figure out what exactly this is supposed to accomplish
|
||||
if self.selTimerID == event.GetId():
|
||||
ctimestamp = time.time()
|
||||
interval = 5
|
||||
if ctimestamp < self.timestamp + interval:
|
||||
delta = (ctimestamp - self.timestamp) / interval
|
||||
self.selectedDelta = self.CalculateDelta(0x0, self.maxDelta, delta)
|
||||
self.Refresh()
|
||||
else:
|
||||
self.selectedDelta = self.maxDelta
|
||||
self.selTimer.Stop()
|
||||
|
||||
if self.animTimerId == event.GetId():
|
||||
step = self.OUT_QUAD(self.animStep, 0, 10, self.animDuration)
|
||||
self.animCount = 10 - step
|
||||
self.animStep += self.animPeriod
|
||||
if self.animStep > self.animDuration or self.animCount < 0:
|
||||
self.animCount = 0
|
||||
self.animTimer.Stop()
|
||||
self.Refresh()
|
||||
|
||||
@staticmethod
|
||||
def CalculateDelta(start, end, delta):
|
||||
return start + (end - start) * delta
|
||||
|
||||
@staticmethod
|
||||
def OUT_QUAD(t, b, c, d):
|
||||
t = float(t)
|
||||
b = float(b)
|
||||
c = float(c)
|
||||
d = float(d)
|
||||
|
||||
t /= d
|
||||
|
||||
return -c * t * (t - 2) + b
|
||||
|
||||
def editLostFocus(self, event):
|
||||
self.RestoreEditButton()
|
||||
self.Refresh()
|
||||
|
||||
def editCheckEsc(self, event):
|
||||
if event.GetKeyCode() == wx.WXK_ESCAPE:
|
||||
self.RestoreEditButton()
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
def copyBtnCB(self):
|
||||
if self.tcFitName.IsShown():
|
||||
self.RestoreEditButton()
|
||||
return
|
||||
|
||||
self.copyFit()
|
||||
|
||||
def copyFit(self, event=None):
|
||||
sFit = Fit.getInstance()
|
||||
fitID = sFit.copyFit(self.fitID)
|
||||
self.shipBrowser.fitIDMustEditName = fitID
|
||||
wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=self.shipID))
|
||||
wx.PostEvent(self.mainFrame, FitSelected(fitID=fitID))
|
||||
|
||||
def renameBtnCB(self):
|
||||
if self.tcFitName.IsShown():
|
||||
self.RestoreEditButton()
|
||||
self.renameFit()
|
||||
else:
|
||||
self.tcFitName.SetValue(self.fitName)
|
||||
self.tcFitName.Show()
|
||||
self.renameBtn.SetBitmap(self.acceptBmp)
|
||||
self.tcFitName.SetFocus()
|
||||
self.tcFitName.SelectAll()
|
||||
|
||||
self.Refresh()
|
||||
|
||||
def renameFit(self, event=None):
|
||||
sFit = Fit.getInstance()
|
||||
self.tcFitName.Show(False)
|
||||
self.editWasShown = 0
|
||||
fitName = self.tcFitName.GetValue()
|
||||
if fitName:
|
||||
self.fitName = fitName
|
||||
sFit.renameFit(self.fitID, self.fitName)
|
||||
wx.PostEvent(self.mainFrame, FitRenamed(fitID=self.fitID))
|
||||
else:
|
||||
self.tcFitName.SetValue(self.fitName)
|
||||
|
||||
def deleteBtnCB(self):
|
||||
if self.tcFitName.IsShown():
|
||||
self.RestoreEditButton()
|
||||
return
|
||||
|
||||
# to prevent accidental deletion, give dialog confirmation unless shift is depressed
|
||||
if wx.GetMouseState().ShiftDown() or wx.GetMouseState().MiddleDown():
|
||||
self.deleteFit()
|
||||
else:
|
||||
dlg = wx.MessageDialog(
|
||||
self,
|
||||
"Do you really want to delete this fit?",
|
||||
"Confirm Delete",
|
||||
wx.YES | wx.NO | wx.ICON_QUESTION
|
||||
)
|
||||
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
self.deleteFit()
|
||||
|
||||
def deleteFit(self, event=None):
|
||||
pyfalog.debug("Deleting ship fit.")
|
||||
if self.deleted:
|
||||
return
|
||||
else:
|
||||
self.deleted = True
|
||||
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.fitID)
|
||||
|
||||
# need to delete from import cache before actually deleting fit
|
||||
if self.shipBrowser.GetActiveStage() == 5:
|
||||
if fit in self.shipBrowser.lastdata: # remove fit from import cache
|
||||
self.shipBrowser.lastdata.remove(fit)
|
||||
|
||||
sFit.deleteFit(self.fitID)
|
||||
|
||||
# Notify other areas that a fit has been deleted
|
||||
wx.PostEvent(self.mainFrame, FitRemoved(fitID=self.fitID))
|
||||
|
||||
# todo: would a simple RefreshList() work here instead of posting that a stage has been selected?
|
||||
if self.shipBrowser.GetActiveStage() == 5:
|
||||
wx.PostEvent(self.shipBrowser, ImportSelected(fits=self.shipBrowser.lastdata))
|
||||
elif self.shipBrowser.GetActiveStage() == 4:
|
||||
wx.PostEvent(self.shipBrowser, SearchSelected(text=self.shipBrowser.navpanel.lastSearch, back=True))
|
||||
else:
|
||||
wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=self.shipID))
|
||||
|
||||
def MouseLeftUp(self, event):
|
||||
if self.dragging and self.dragged:
|
||||
self.OnMouseCaptureLost(event)
|
||||
|
||||
targetWnd = wx.FindWindowAtPointer()
|
||||
|
||||
if not targetWnd:
|
||||
return
|
||||
|
||||
wnd = targetWnd
|
||||
while wnd is not None:
|
||||
handler = getattr(wnd, "handleDrag", None)
|
||||
if handler:
|
||||
handler("fit", self.fitID)
|
||||
break
|
||||
else:
|
||||
wnd = wnd.Parent
|
||||
event.Skip()
|
||||
return
|
||||
|
||||
if self.dragging:
|
||||
self.dragging = False
|
||||
|
||||
if self.tcFitName.IsShown():
|
||||
self.RestoreEditButton()
|
||||
else:
|
||||
activeFitID = self.mainFrame.getActiveFit()
|
||||
if activeFitID != self.fitID:
|
||||
self.selectFit()
|
||||
|
||||
def MouseLeftDown(self, event):
|
||||
self.dragging = True
|
||||
|
||||
def MouseMove(self, event):
|
||||
pos = self.ClientToScreen(event.GetPosition())
|
||||
if self.dragging:
|
||||
if not self.dragged:
|
||||
if self.dragMotionTrigger < 0:
|
||||
if not self.HasCapture():
|
||||
self.CaptureMouse()
|
||||
self.dragWindow = PFBitmapFrame(self, pos, self.dragTLFBmp)
|
||||
self.dragWindow.Show()
|
||||
self.dragged = True
|
||||
self.dragMotionTrigger = self.dragMotionTrail
|
||||
else:
|
||||
self.dragMotionTrigger -= 1
|
||||
if self.dragWindow:
|
||||
pos.x += 3
|
||||
pos.y += 3
|
||||
self.dragWindow.SetPosition(pos)
|
||||
return
|
||||
|
||||
def selectFit(self, event=None, newTab=False):
|
||||
if newTab:
|
||||
wx.PostEvent(self.mainFrame, FitSelected(fitID=self.fitID, startup=2))
|
||||
else:
|
||||
wx.PostEvent(self.mainFrame, FitSelected(fitID=self.fitID))
|
||||
|
||||
def RestoreEditButton(self):
|
||||
self.tcFitName.Show(False)
|
||||
self.renameBtn.SetBitmap(self.renameBmp)
|
||||
self.Refresh()
|
||||
|
||||
def UpdateElementsPos(self, mdc):
|
||||
rect = self.GetRect()
|
||||
|
||||
self.toolbarx = rect.width - self.toolbar.GetWidth() - self.padding
|
||||
self.toolbary = (rect.height - self.toolbar.GetHeight()) / 2
|
||||
|
||||
self.toolbarx += self.animCount
|
||||
|
||||
self.shipEffx = self.padding + (rect.height - self.shipEffBk.GetWidth()) / 2
|
||||
self.shipEffy = (rect.height - self.shipEffBk.GetHeight()) / 2
|
||||
|
||||
self.shipEffx -= self.animCount
|
||||
|
||||
self.shipBmpx = self.padding + (rect.height - self.shipBmp.GetWidth()) / 2
|
||||
self.shipBmpy = (rect.height - self.shipBmp.GetHeight()) / 2
|
||||
|
||||
self.shipBmpx -= self.animCount
|
||||
|
||||
self.textStartx = self.shipEffx + self.shipEffBk.GetWidth() + self.padding
|
||||
|
||||
self.fitNamey = (rect.height - self.shipBmp.GetHeight()) / 2
|
||||
|
||||
mdc.SetFont(self.fontBig)
|
||||
wtext, htext = mdc.GetTextExtent(self.fitName)
|
||||
|
||||
self.timestampy = self.fitNamey + htext
|
||||
|
||||
mdc.SetFont(self.fontSmall)
|
||||
|
||||
wlabel, hlabel = mdc.GetTextExtent(self.toolbar.hoverLabel)
|
||||
|
||||
self.thoverx = self.toolbarx - self.padding - wlabel
|
||||
self.thovery = (rect.height - hlabel) / 2
|
||||
self.thoverw = wlabel
|
||||
|
||||
def DrawItem(self, mdc):
|
||||
rect = self.GetRect()
|
||||
|
||||
windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
|
||||
textColor = colorUtils.GetSuitableColor(windowColor, 1)
|
||||
|
||||
mdc.SetTextForeground(textColor)
|
||||
|
||||
self.UpdateElementsPos(mdc)
|
||||
|
||||
self.toolbar.SetPosition((self.toolbarx, self.toolbary))
|
||||
|
||||
if self.GetState() & SFItem.SB_ITEM_HIGHLIGHTED:
|
||||
shipEffBk = self.shipEffBkMirrored
|
||||
else:
|
||||
shipEffBk = self.shipEffBk
|
||||
|
||||
mdc.DrawBitmap(shipEffBk, self.shipEffx, self.shipEffy, 0)
|
||||
|
||||
mdc.DrawBitmap(self.shipBmp, self.shipBmpx, self.shipBmpy, 0)
|
||||
|
||||
mdc.SetFont(self.fontNormal)
|
||||
|
||||
fitDate = self.timestamp.strftime("%m/%d/%Y %H:%M")
|
||||
fitLocalDate = fitDate # "%d/%02d/%02d %02d:%02d" % (fitDate[0], fitDate[1], fitDate[2], fitDate[3], fitDate[4])
|
||||
pfdate = drawUtils.GetPartialText(mdc, fitLocalDate,
|
||||
self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw)
|
||||
|
||||
mdc.DrawText(pfdate, self.textStartx, self.timestampy)
|
||||
|
||||
mdc.SetFont(self.fontSmall)
|
||||
mdc.DrawText(self.toolbar.hoverLabel, self.thoverx, self.thovery)
|
||||
|
||||
mdc.SetFont(self.fontBig)
|
||||
|
||||
psname = drawUtils.GetPartialText(mdc, self.fitName,
|
||||
self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw)
|
||||
|
||||
mdc.DrawText(psname, self.textStartx, self.fitNamey)
|
||||
|
||||
if self.tcFitName.IsShown():
|
||||
self.AdjustControlSizePos(self.tcFitName, self.textStartx, self.toolbarx - self.editWidth - self.padding)
|
||||
|
||||
tdc = wx.MemoryDC()
|
||||
self.dragTLFBmp = wx.EmptyBitmap((self.toolbarx if self.toolbarx < 200 else 200), rect.height, 24)
|
||||
tdc.SelectObject(self.dragTLFBmp)
|
||||
tdc.Blit(0, 0, (self.toolbarx if self.toolbarx < 200 else 200), rect.height, mdc, 0, 0, wx.COPY)
|
||||
tdc.SelectObject(wx.NullBitmap)
|
||||
|
||||
def AdjustControlSizePos(self, editCtl, start, end):
|
||||
fnEditSize = editCtl.GetSize()
|
||||
wSize = self.GetSize()
|
||||
fnEditPosX = end
|
||||
fnEditPosY = (wSize.height - fnEditSize.height) / 2
|
||||
if fnEditPosX < start:
|
||||
editCtl.SetSize((self.editWidth + fnEditPosX - start, -1))
|
||||
editCtl.SetPosition((start, fnEditPosY))
|
||||
else:
|
||||
editCtl.SetSize((self.editWidth, -1))
|
||||
editCtl.SetPosition((fnEditPosX, fnEditPosY))
|
||||
|
||||
def GetState(self):
|
||||
activeFitID = self.mainFrame.getActiveFit()
|
||||
|
||||
if self.highlighted and not activeFitID == self.fitID:
|
||||
state = SFItem.SB_ITEM_HIGHLIGHTED
|
||||
|
||||
else:
|
||||
if activeFitID == self.fitID:
|
||||
if self.highlighted:
|
||||
state = SFItem.SB_ITEM_SELECTED | SFItem.SB_ITEM_HIGHLIGHTED
|
||||
else:
|
||||
state = SFItem.SB_ITEM_SELECTED
|
||||
else:
|
||||
state = SFItem.SB_ITEM_NORMAL
|
||||
return state
|
||||
|
||||
def Refresh(self):
|
||||
activeFit = self.mainFrame.getActiveFit()
|
||||
if activeFit == self.fitID and not self.deleted:
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(activeFit)
|
||||
if fit is not None: # sometimes happens when deleting fits, dunno why.
|
||||
self.timestamp = fit.modifiedCoalesce
|
||||
self.notes = fit.notes
|
||||
self.__setToolTip()
|
||||
|
||||
SFItem.SFBrowserItem.Refresh(self)
|
||||
|
||||
def RenderBackground(self):
|
||||
rect = self.GetRect()
|
||||
|
||||
windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
|
||||
|
||||
# activeFitID = self.mainFrame.getActiveFit()
|
||||
state = self.GetState()
|
||||
|
||||
sFactor = 0.2
|
||||
mFactor = None
|
||||
eFactor = 0
|
||||
|
||||
if state == SFItem.SB_ITEM_HIGHLIGHTED:
|
||||
mFactor = 0.45
|
||||
eFactor = 0.30
|
||||
|
||||
elif state == SFItem.SB_ITEM_SELECTED | SFItem.SB_ITEM_HIGHLIGHTED:
|
||||
eFactor = 0.3
|
||||
mFactor = 0.4
|
||||
|
||||
elif state == SFItem.SB_ITEM_SELECTED:
|
||||
eFactor = (self.maxDelta - self.selectedDelta) / 100 + 0.25
|
||||
else:
|
||||
sFactor = 0
|
||||
|
||||
if self.bkBitmap:
|
||||
if self.bkBitmap.eFactor == eFactor and self.bkBitmap.sFactor == sFactor and self.bkBitmap.mFactor == mFactor \
|
||||
and rect.width == self.bkBitmap.GetWidth() and rect.height == self.bkBitmap.GetHeight():
|
||||
return
|
||||
else:
|
||||
del self.bkBitmap
|
||||
|
||||
self.bkBitmap = drawUtils.RenderGradientBar(windowColor, rect.width, rect.height, sFactor, eFactor, mFactor)
|
||||
self.bkBitmap.state = state
|
||||
self.bkBitmap.sFactor = sFactor
|
||||
self.bkBitmap.eFactor = eFactor
|
||||
self.bkBitmap.mFactor = mFactor
|
||||
274
gui/builtinShipBrowser/navigationPanel.py
Normal file
274
gui/builtinShipBrowser/navigationPanel.py
Normal file
@@ -0,0 +1,274 @@
|
||||
# coding: utf-8
|
||||
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
import gui.builtinShipBrowser.sfBrowserItem as SFItem
|
||||
import gui.mainFrame
|
||||
import gui.utils.colorUtils as colorUtils
|
||||
import gui.utils.drawUtils as drawUtils
|
||||
import gui.utils.fonts as fonts
|
||||
from events import *
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from service.fit import Fit
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class NavigationPanel(SFItem.SFBrowserItem):
|
||||
def __init__(self, parent, size=(-1, 24)):
|
||||
SFItem.SFBrowserItem.__init__(self, parent, size=size)
|
||||
|
||||
self.rewBmpH = BitmapLoader.getBitmap("frewind_small", "gui")
|
||||
self.forwBmp = BitmapLoader.getBitmap("fforward_small", "gui")
|
||||
self.searchBmpH = BitmapLoader.getBitmap("fsearch_small", "gui")
|
||||
self.newBmpH = BitmapLoader.getBitmap("fit_add_small", "gui")
|
||||
self.resetBmpH = BitmapLoader.getBitmap("freset_small", "gui")
|
||||
self.switchBmpH = BitmapLoader.getBitmap("fit_switch_view_mode_small", "gui")
|
||||
self.recentBmpH = BitmapLoader.getBitmap("frecent_small", "gui")
|
||||
|
||||
switchImg = BitmapLoader.getImage("fit_switch_view_mode_small", "gui")
|
||||
switchImg = switchImg.AdjustChannels(1, 1, 1, 0.4)
|
||||
self.switchBmpD = wx.BitmapFromImage(switchImg)
|
||||
|
||||
recentImg = BitmapLoader.getImage("frecent_small", "gui")
|
||||
recentImg = recentImg.AdjustChannels(1, 1, 1, 0.4)
|
||||
self.recentBmpD = wx.BitmapFromImage(recentImg)
|
||||
|
||||
self.resetBmp = self.AdjustChannels(self.resetBmpH)
|
||||
self.rewBmp = self.AdjustChannels(self.rewBmpH)
|
||||
self.searchBmp = self.AdjustChannels(self.searchBmpH)
|
||||
self.switchBmp = self.AdjustChannels(self.switchBmpH)
|
||||
self.recentBmp = self.AdjustChannels(self.recentBmpH)
|
||||
self.newBmp = self.AdjustChannels(self.newBmpH)
|
||||
|
||||
self.toolbar.AddButton(self.resetBmp, "Ship groups", clickCallback=self.OnHistoryReset,
|
||||
hoverBitmap=self.resetBmpH)
|
||||
self.toolbar.AddButton(self.rewBmp, "Back", clickCallback=self.OnHistoryBack, hoverBitmap=self.rewBmpH)
|
||||
self.btnNew = self.toolbar.AddButton(self.newBmp, "New fitting", clickCallback=self.OnNewFitting,
|
||||
hoverBitmap=self.newBmpH, show=False)
|
||||
self.btnSwitch = self.toolbar.AddButton(self.switchBmpD, "Hide empty ship groups",
|
||||
clickCallback=self.ToggleEmptyGroupsView, hoverBitmap=self.switchBmpH,
|
||||
show=False)
|
||||
self.btnRecent = self.toolbar.AddButton(self.recentBmpD, "Recent Fits",
|
||||
clickCallback=self.ToggleRecentShips, hoverBitmap=self.recentBmpH,
|
||||
show=True)
|
||||
|
||||
modifier = "CTRL" if 'wxMac' not in wx.PlatformInfo else "CMD"
|
||||
self.toolbar.AddButton(self.searchBmp, "Search fittings ({}+F)".format(modifier), clickCallback=self.ToggleSearchBox,
|
||||
hoverBitmap=self.searchBmpH)
|
||||
|
||||
self.padding = 4
|
||||
self.lastSearch = ""
|
||||
self.recentSearches = [] # not used?
|
||||
self.inSearch = False
|
||||
|
||||
self.fontSmall = wx.Font(fonts.SMALL, wx.SWISS, wx.NORMAL, wx.NORMAL)
|
||||
w, h = size
|
||||
self.BrowserSearchBox = wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition,
|
||||
(-1, h - 2 if 'wxGTK' in wx.PlatformInfo else -1),
|
||||
wx.TE_PROCESS_ENTER | (wx.BORDER_NONE if 'wxGTK' in wx.PlatformInfo else 0))
|
||||
self.BrowserSearchBox.Show(False)
|
||||
|
||||
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_TEXT, self.OnScheduleSearch)
|
||||
|
||||
self.SetMinSize(size)
|
||||
self.shipBrowser = self.Parent
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
self.Bind(wx.EVT_SIZE, self.OnResize)
|
||||
|
||||
def OnScheduleSearch(self, event):
|
||||
search = self.BrowserSearchBox.GetValue()
|
||||
# Make sure we do not count wildcard as search symbol
|
||||
realsearch = search.replace("*", "")
|
||||
if len(realsearch) >= 3:
|
||||
self.lastSearch = search
|
||||
wx.PostEvent(self.shipBrowser, SearchSelected(text=search, back=False))
|
||||
|
||||
def ToggleSearchBox(self):
|
||||
if self.BrowserSearchBox.IsShown():
|
||||
self.BrowserSearchBox.Show(False)
|
||||
else:
|
||||
self.BrowserSearchBox.Show(True)
|
||||
self.BrowserSearchBox.ChangeValue("")
|
||||
self.BrowserSearchBox.SetFocus()
|
||||
|
||||
def OnBrowserSearchBoxEnter(self, event):
|
||||
self.OnBrowserSearchBoxLostFocus(None)
|
||||
|
||||
def OnBrowserSearchBoxLostFocus(self, event):
|
||||
self.BrowserSearchBox.Show(False)
|
||||
|
||||
def OnBrowserSearchBoxEsc(self, event):
|
||||
if event.GetKeyCode() == wx.WXK_ESCAPE:
|
||||
self.BrowserSearchBox.Show(False)
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
def OnResize(self, event):
|
||||
self.Refresh()
|
||||
|
||||
def ToggleRecentShips(self, bool=None, emitEvent=True):
|
||||
# this is so janky. Need to revaluate pretty much entire ship browser. >.<
|
||||
toggle = bool if bool is not None else not self.shipBrowser.recentFits
|
||||
|
||||
if not toggle:
|
||||
self.shipBrowser.recentFits = False
|
||||
self.btnRecent.label = "Recent Fits"
|
||||
self.btnRecent.normalBmp = self.recentBmpD
|
||||
|
||||
if emitEvent:
|
||||
wx.PostEvent(self.shipBrowser, Stage1Selected())
|
||||
else:
|
||||
self.shipBrowser.recentFits = True
|
||||
self.btnRecent.label = "Hide Recent Fits"
|
||||
self.btnRecent.normalBmp = self.recentBmp
|
||||
|
||||
if emitEvent:
|
||||
sFit = Fit.getInstance()
|
||||
fits = sFit.getRecentFits()
|
||||
wx.PostEvent(self.shipBrowser, ImportSelected(fits=fits, back=True, recent=True))
|
||||
|
||||
def ToggleEmptyGroupsView(self):
|
||||
if self.shipBrowser.filterShipsWithNoFits:
|
||||
self.shipBrowser.filterShipsWithNoFits = False
|
||||
self.btnSwitch.label = "Hide empty ship groups"
|
||||
self.btnSwitch.normalBmp = self.switchBmpD
|
||||
else:
|
||||
self.shipBrowser.filterShipsWithNoFits = True
|
||||
self.btnSwitch.label = "Show empty ship groups"
|
||||
self.btnSwitch.normalBmp = self.switchBmp
|
||||
|
||||
stage = self.shipBrowser.GetActiveStage()
|
||||
|
||||
if stage == 1:
|
||||
wx.PostEvent(self.shipBrowser, Stage1Selected())
|
||||
elif stage == 2:
|
||||
categoryID = self.shipBrowser.GetStageData(stage)
|
||||
wx.PostEvent(self.shipBrowser, Stage2Selected(categoryID=categoryID, back=True))
|
||||
|
||||
def ShowNewFitButton(self, show):
|
||||
self.btnNew.Show(show)
|
||||
self.Refresh()
|
||||
|
||||
def ShowSwitchEmptyGroupsButton(self, show):
|
||||
self.btnSwitch.Show(show)
|
||||
self.Refresh()
|
||||
|
||||
def OnNewFitting(self):
|
||||
stage = self.Parent.GetActiveStage()
|
||||
if stage == 3:
|
||||
shipID = self.Parent.GetStageData(stage)
|
||||
shipName = self.Parent.GetStage3ShipName()
|
||||
sFit = Fit.getInstance()
|
||||
fitID = sFit.newFit(shipID, "%s fit" % shipName)
|
||||
self.shipBrowser.fitIDMustEditName = fitID
|
||||
wx.PostEvent(self.Parent, Stage3Selected(shipID=shipID))
|
||||
wx.PostEvent(self.mainFrame, FitSelected(fitID=fitID))
|
||||
|
||||
def OnHistoryReset(self):
|
||||
self.ToggleRecentShips(False, False)
|
||||
if self.shipBrowser.browseHist:
|
||||
self.shipBrowser.browseHist = []
|
||||
self.gotoStage(1, 0)
|
||||
|
||||
def OnHistoryBack(self):
|
||||
self.ToggleRecentShips(False, False)
|
||||
if len(self.shipBrowser.browseHist) > 0:
|
||||
stage, data = self.shipBrowser.browseHist.pop()
|
||||
self.gotoStage(stage, data)
|
||||
|
||||
@staticmethod
|
||||
def AdjustChannels(bitmap):
|
||||
img = wx.ImageFromBitmap(bitmap)
|
||||
img = img.AdjustChannels(1.05, 1.05, 1.05, 1)
|
||||
return wx.BitmapFromImage(img)
|
||||
|
||||
def UpdateElementsPos(self, mdc):
|
||||
rect = self.GetRect()
|
||||
|
||||
self.toolbarx = self.padding
|
||||
self.toolbary = (rect.height - self.toolbar.GetHeight()) / 2
|
||||
|
||||
mdc.SetFont(self.fontSmall)
|
||||
|
||||
wlabel, hlabel = mdc.GetTextExtent(self.toolbar.hoverLabel)
|
||||
|
||||
self.thoverx = self.toolbar.GetWidth() + self.padding
|
||||
self.thovery = (rect.height - hlabel) / 2
|
||||
self.thoverw = wlabel
|
||||
|
||||
self.browserBoxX = self.thoverx
|
||||
bEditBoxWidth, bEditBoxHeight = self.BrowserSearchBox.GetSize()
|
||||
self.browserBoxY = (rect.height - bEditBoxHeight) / 2
|
||||
|
||||
self.bEditBoxWidth = rect.width - self.browserBoxX - self.padding
|
||||
|
||||
def DrawItem(self, mdc):
|
||||
rect = self.GetRect()
|
||||
|
||||
windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
|
||||
textColor = colorUtils.GetSuitableColor(windowColor, 1)
|
||||
sepColor = colorUtils.GetSuitableColor(windowColor, 0.2)
|
||||
|
||||
mdc.SetTextForeground(textColor)
|
||||
|
||||
self.UpdateElementsPos(mdc)
|
||||
self.BrowserSearchBox.SetPosition((self.browserBoxX, self.browserBoxY))
|
||||
self.BrowserSearchBox.SetSize(wx.Size(self.bEditBoxWidth, -1))
|
||||
|
||||
self.toolbar.SetPosition((self.toolbarx, self.toolbary))
|
||||
mdc.SetFont(self.fontSmall)
|
||||
mdc.DrawText(self.toolbar.hoverLabel, self.thoverx, self.thovery)
|
||||
mdc.SetPen(wx.Pen(sepColor, 1))
|
||||
mdc.DrawLine(0, rect.height - 1, rect.width, rect.height - 1)
|
||||
|
||||
def RenderBackground(self):
|
||||
rect = self.GetRect()
|
||||
|
||||
windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
|
||||
|
||||
sFactor = 0.1
|
||||
|
||||
shipGroupsFilter = getattr(self.shipBrowser, "filterShipsWithNoFits", None)
|
||||
if shipGroupsFilter:
|
||||
sFactor = 0.15
|
||||
mFactor = 0.25
|
||||
else:
|
||||
mFactor = 0.2
|
||||
|
||||
eFactor = 0.1
|
||||
|
||||
if self.bkBitmap:
|
||||
if self.bkBitmap.eFactor == eFactor and self.bkBitmap.sFactor == sFactor and self.bkBitmap.mFactor == mFactor \
|
||||
and rect.width == self.bkBitmap.GetWidth() and rect.height == self.bkBitmap.GetHeight():
|
||||
return
|
||||
else:
|
||||
del self.bkBitmap
|
||||
|
||||
self.bkBitmap = drawUtils.RenderGradientBar(windowColor, rect.width, rect.height, sFactor, eFactor, mFactor, 2)
|
||||
|
||||
self.bkBitmap.sFactor = sFactor
|
||||
self.bkBitmap.eFactor = eFactor
|
||||
self.bkBitmap.mFactor = mFactor
|
||||
|
||||
def gotoStage(self, stage, data=None):
|
||||
self.shipBrowser.recentFits = False
|
||||
if stage == 1:
|
||||
wx.PostEvent(self.Parent, Stage1Selected())
|
||||
elif stage == 2:
|
||||
wx.PostEvent(self.Parent, Stage2Selected(categoryID=data, back=True))
|
||||
elif stage == 3:
|
||||
wx.PostEvent(self.Parent, Stage3Selected(shipID=data))
|
||||
elif stage == 4:
|
||||
self.shipBrowser._activeStage = 4
|
||||
wx.PostEvent(self.Parent, SearchSelected(text=data, back=True))
|
||||
elif stage == 5:
|
||||
wx.PostEvent(self.Parent, ImportSelected(fits=data))
|
||||
else:
|
||||
wx.PostEvent(self.Parent, Stage1Selected())
|
||||
|
||||
14
gui/builtinShipBrowser/pfBitmapButton.py
Normal file
14
gui/builtinShipBrowser/pfBitmapButton.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import wx
|
||||
from wx.lib.buttons import GenBitmapButton
|
||||
|
||||
|
||||
class PFGenBitmapButton(GenBitmapButton):
|
||||
def __init__(self, parent, id, bitmap, pos, size, style):
|
||||
GenBitmapButton.__init__(self, parent, id, bitmap, pos, size, style)
|
||||
self.bgcolor = wx.Brush(wx.WHITE)
|
||||
|
||||
def SetBackgroundColour(self, color):
|
||||
self.bgcolor = wx.Brush(color)
|
||||
|
||||
def GetBackgroundBrush(self, dc):
|
||||
return self.bgcolor
|
||||
59
gui/builtinShipBrowser/pfBitmapFrame.py
Normal file
59
gui/builtinShipBrowser/pfBitmapFrame.py
Normal file
@@ -0,0 +1,59 @@
|
||||
import wx
|
||||
|
||||
|
||||
class PFBitmapFrame(wx.Frame):
|
||||
def __init__(self, parent, pos, bitmap):
|
||||
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=pos, size=wx.DefaultSize,
|
||||
style=wx.NO_BORDER | wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP)
|
||||
img = bitmap.ConvertToImage()
|
||||
img = img.ConvertToGreyscale()
|
||||
bitmap = wx.BitmapFromImage(img)
|
||||
self.bitmap = bitmap
|
||||
self.SetSize((bitmap.GetWidth(), bitmap.GetHeight()))
|
||||
self.Bind(wx.EVT_PAINT, self.OnWindowPaint)
|
||||
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnWindowEraseBk)
|
||||
self.Bind(wx.EVT_TIMER, self.OnTimer)
|
||||
|
||||
self.timer = wx.Timer(self, wx.ID_ANY)
|
||||
self.direction = 1
|
||||
self.transp = 0
|
||||
self.SetSize((bitmap.GetWidth(), bitmap.GetHeight()))
|
||||
|
||||
self.SetTransparent(0)
|
||||
self.Refresh()
|
||||
|
||||
def OnTimer(self, event):
|
||||
self.transp += 20 * self.direction
|
||||
if self.transp > 200:
|
||||
self.transp = 200
|
||||
self.timer.Stop()
|
||||
if self.transp < 0:
|
||||
self.transp = 0
|
||||
self.timer.Stop()
|
||||
wx.Frame.Show(self, False)
|
||||
self.Destroy()
|
||||
return
|
||||
self.SetTransparent(self.transp)
|
||||
|
||||
def Show(self, showWnd=True):
|
||||
if showWnd:
|
||||
wx.Frame.Show(self, showWnd)
|
||||
self.Parent.SetFocus()
|
||||
self.direction = 1
|
||||
self.timer.Start(5)
|
||||
else:
|
||||
self.direction = -1
|
||||
self.timer.Start(5)
|
||||
|
||||
def OnWindowEraseBk(self, event):
|
||||
pass
|
||||
|
||||
def OnWindowPaint(self, event):
|
||||
rect = self.GetRect()
|
||||
canvas = wx.EmptyBitmap(rect.width, rect.height)
|
||||
mdc = wx.BufferedPaintDC(self)
|
||||
mdc.SelectObject(canvas)
|
||||
mdc.DrawBitmap(self.bitmap, 0, 0)
|
||||
mdc.SetPen(wx.Pen("#000000", width=1))
|
||||
mdc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||
mdc.DrawRectangle(0, 0, rect.width, rect.height)
|
||||
162
gui/builtinShipBrowser/pfListPane.py
Normal file
162
gui/builtinShipBrowser/pfListPane.py
Normal file
@@ -0,0 +1,162 @@
|
||||
# =============================================================================
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
# =============================================================================
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
|
||||
class PFListPane(wx.ScrolledWindow):
|
||||
def __init__(self, parent):
|
||||
wx.ScrolledWindow.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(1, 1),
|
||||
style=wx.TAB_TRAVERSAL)
|
||||
|
||||
self._wList = []
|
||||
self._wCount = 0
|
||||
self.itemsHeight = 1
|
||||
|
||||
self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
|
||||
|
||||
self.SetVirtualSize((1, 1))
|
||||
self.SetScrollRate(0, 1)
|
||||
|
||||
self.Bind(wx.EVT_SCROLLWIN_LINEUP, self.MScrollUp)
|
||||
self.Bind(wx.EVT_SCROLLWIN_LINEDOWN, self.MScrollDown)
|
||||
# self.Bind(wx.EVT_CHILD_FOCUS, self.OnChildFocus)
|
||||
# self.Bind(wx.EVT_LEFT_DOWN, self.ForceFocus)
|
||||
self.SetFocus()
|
||||
# self.Bind(wx.EVT_MOUSE_CAPTURE_CHANGED, self.ForceFocus)
|
||||
self.Bind(wx.EVT_SCROLLWIN_THUMBRELEASE, self.ForceFocus)
|
||||
|
||||
def ForceFocus(self, event):
|
||||
if self.FindFocus() and self.FindFocus().Parent != self:
|
||||
self.SetFocus()
|
||||
event.Skip()
|
||||
|
||||
def OnChildFocus(self, event):
|
||||
event.Skip()
|
||||
child = event.GetWindow()
|
||||
self.ScrollChildIntoView(child)
|
||||
|
||||
def MScrollUp(self, event):
|
||||
|
||||
posy = self.GetScrollPos(wx.VERTICAL)
|
||||
posy -= self.itemsHeight
|
||||
self.Scroll(0, posy)
|
||||
|
||||
event.Skip()
|
||||
|
||||
def MScrollDown(self, event):
|
||||
|
||||
posy = self.GetScrollPos(wx.VERTICAL)
|
||||
posy += self.itemsHeight
|
||||
self.Scroll(0, posy)
|
||||
|
||||
event.Skip()
|
||||
|
||||
def ScrollChildIntoView(self, child):
|
||||
"""
|
||||
Scrolls the panel such that the specified child window is in view.
|
||||
"""
|
||||
sppu_x, sppu_y = self.GetScrollPixelsPerUnit()
|
||||
vs_x, vs_y = self.GetViewStart()
|
||||
cr = child.GetRect()
|
||||
clntsz = self.GetSize()
|
||||
new_vs_x, new_vs_y = -1, -1
|
||||
|
||||
# is it before the left edge?
|
||||
if cr.x < 0 < sppu_x:
|
||||
new_vs_x = vs_x + (cr.x / sppu_x)
|
||||
|
||||
# is it above the top?
|
||||
if cr.y < 0 < sppu_y:
|
||||
new_vs_y = vs_y + (cr.y / sppu_y)
|
||||
|
||||
# For the right and bottom edges, scroll enough to show the
|
||||
# whole control if possible, but if not just scroll such that
|
||||
# the top/left edges are still visible
|
||||
|
||||
# is it past the right edge ?
|
||||
if cr.right > clntsz.width and sppu_x > 0:
|
||||
diff = (cr.right - clntsz.width + 1) / sppu_x
|
||||
if cr.x - diff * sppu_x > 0:
|
||||
new_vs_x = vs_x + diff
|
||||
else:
|
||||
new_vs_x = vs_x + (cr.x / sppu_x)
|
||||
|
||||
# is it below the bottom ?
|
||||
if cr.bottom > clntsz.height and sppu_y > 0:
|
||||
diff = (cr.bottom - clntsz.height + 1) / sppu_y
|
||||
if cr.y - diff * sppu_y > 0:
|
||||
new_vs_y = vs_y + diff
|
||||
else:
|
||||
new_vs_y = vs_y + (cr.y / sppu_y)
|
||||
|
||||
# if we need to adjust
|
||||
if new_vs_x != -1 or new_vs_y != -1:
|
||||
self.Scroll(new_vs_x, new_vs_y)
|
||||
|
||||
def AddWidget(self, widget):
|
||||
widget.Reparent(self)
|
||||
self._wList.append(widget)
|
||||
self._wCount += 1
|
||||
|
||||
def GetWidgetList(self):
|
||||
return self._wList
|
||||
|
||||
# Override this method if needed ( return False by default if we do not want to scroll to selected widget)
|
||||
def IsWidgetSelectedByContext(self, widget):
|
||||
return False
|
||||
|
||||
def RefreshList(self, doRefresh=False, doFocus=False):
|
||||
maxy = 0
|
||||
|
||||
selected = None
|
||||
for i in xrange(len(self._wList)):
|
||||
iwidth, iheight = self._wList[i].GetSize()
|
||||
xa, ya = self.CalcScrolledPosition((0, maxy))
|
||||
self._wList[i].SetPosition((xa, ya))
|
||||
if self.IsWidgetSelectedByContext(i):
|
||||
selected = self._wList[i]
|
||||
maxy += iheight
|
||||
|
||||
self.SetVirtualSize((1, maxy))
|
||||
cwidth, cheight = self.GetVirtualSize()
|
||||
|
||||
if selected:
|
||||
self.ScrollChildIntoView(selected)
|
||||
# selected.SetFocus()
|
||||
elif doFocus:
|
||||
self.SetFocus()
|
||||
|
||||
for i in xrange(len(self._wList)):
|
||||
iwidth, iheight = self._wList[i].GetSize()
|
||||
self._wList[i].SetSize((cwidth, iheight))
|
||||
if doRefresh is True:
|
||||
self._wList[i].Refresh()
|
||||
self.itemsHeight = max(self.itemsHeight, iheight - 1)
|
||||
|
||||
def RemoveWidget(self, child):
|
||||
child.Destroy()
|
||||
self._wList.remove(child)
|
||||
|
||||
def RemoveAllChildren(self):
|
||||
for widget in self._wList:
|
||||
widget.Destroy()
|
||||
|
||||
self._wList = []
|
||||
23
gui/builtinShipBrowser/pfStaticText.py
Normal file
23
gui/builtinShipBrowser/pfStaticText.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# coding: utf-8
|
||||
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class PFStaticText(wx.Panel):
|
||||
def __init__(self, parent, label=wx.EmptyString):
|
||||
wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=parent.GetSize())
|
||||
self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
|
||||
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
text = wx.StaticText(self, wx.ID_ANY, label, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE)
|
||||
text.Wrap(-1)
|
||||
mainSizer.Add(text, 1, wx.ALL, 10)
|
||||
self.SetSizer(mainSizer)
|
||||
self.Layout()
|
||||
|
||||
@staticmethod
|
||||
def GetType():
|
||||
return -1
|
||||
35
gui/builtinShipBrowser/pfWidgetContainer.py
Normal file
35
gui/builtinShipBrowser/pfWidgetContainer.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from gui.builtinShipBrowser.pfListPane import PFListPane
|
||||
import gui.mainFrame
|
||||
import gui.utils.animUtils as animUtils
|
||||
|
||||
|
||||
class PFWidgetsContainer(PFListPane):
|
||||
def __init__(self, parent):
|
||||
PFListPane.__init__(self, parent)
|
||||
|
||||
self.anim = animUtils.LoadAnimation(self, label="", size=(100, 12))
|
||||
self.anim.Stop()
|
||||
self.anim.Show(False)
|
||||
|
||||
def ShowLoading(self, mode=True):
|
||||
if mode:
|
||||
aweight, aheight = self.anim.GetSize()
|
||||
cweight, cheight = self.GetSize()
|
||||
ax = (cweight - aweight) / 2
|
||||
ay = (cheight - aheight) / 2
|
||||
self.anim.SetPosition((ax, ay))
|
||||
self.anim.Show()
|
||||
self.anim.Play()
|
||||
else:
|
||||
self.anim.Stop()
|
||||
self.anim.Show(False)
|
||||
|
||||
def IsWidgetSelectedByContext(self, widget):
|
||||
mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
stage = self.Parent.GetActiveStage()
|
||||
fit = mainFrame.getActiveFit()
|
||||
if stage == 3 or stage == 4:
|
||||
if self._wList[widget].GetType() == 3:
|
||||
if fit == self._wList[widget].fitID:
|
||||
return True
|
||||
return False
|
||||
271
gui/builtinShipBrowser/raceSelector.py
Normal file
271
gui/builtinShipBrowser/raceSelector.py
Normal file
@@ -0,0 +1,271 @@
|
||||
# coding: utf-8
|
||||
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
import gui.utils.animEffects as animEffects
|
||||
import gui.utils.colorUtils as colorUtils
|
||||
import gui.utils.drawUtils as drawUtils
|
||||
from events import *
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class RaceSelector(wx.Window):
|
||||
def __init__(self, parent, id=wx.ID_ANY, label="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=0,
|
||||
layout=wx.VERTICAL, animate=False):
|
||||
wx.Window.__init__(self, parent, id, pos=pos, size=size, style=style)
|
||||
|
||||
self.animTimerID = wx.NewId()
|
||||
self.animTimer = wx.Timer(self, self.animTimerID)
|
||||
self.animPeriod = 25
|
||||
self.animDuration = 250
|
||||
self.animStep = 0
|
||||
self.maxWidth = 24
|
||||
self.minWidth = 5 if animate else self.maxWidth
|
||||
self.maxHeight = 24
|
||||
self.minHeight = 10 if animate else self.maxHeight
|
||||
|
||||
self.direction = 0 if animate else 1
|
||||
self.layout = layout
|
||||
self.animate = animate
|
||||
|
||||
if layout == wx.VERTICAL:
|
||||
self.SetSize(wx.Size(self.minWidth, -1))
|
||||
self.SetMinSize(wx.Size(self.minWidth, -1))
|
||||
else:
|
||||
self.SetSize(wx.Size(-1, self.minHeight))
|
||||
self.SetMinSize(wx.Size(-1, self.minHeight))
|
||||
|
||||
self.checkTimerID = wx.NewId()
|
||||
self.checkTimer = wx.Timer(self, self.checkTimerID)
|
||||
self.checkPeriod = 250
|
||||
self.checkMaximize = True
|
||||
self.shipBrowser = self.Parent
|
||||
self.raceBmps = []
|
||||
self.raceNames = []
|
||||
self.hoveredItem = None
|
||||
|
||||
if layout == wx.VERTICAL:
|
||||
self.buttonsBarPos = (4, 0)
|
||||
else:
|
||||
self.buttonsBarPos = (0, 4)
|
||||
|
||||
self.buttonsPadding = 4
|
||||
|
||||
if layout == wx.VERTICAL:
|
||||
self.bmpArrow = BitmapLoader.getBitmap("down-arrow2", "gui")
|
||||
else:
|
||||
self.bmpArrow = BitmapLoader.getBitmap("up-arrow2", "gui")
|
||||
|
||||
# Make the bitmaps have the same color as window text
|
||||
|
||||
sysTextColour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
|
||||
|
||||
img = self.bmpArrow.ConvertToImage()
|
||||
if layout == wx.VERTICAL:
|
||||
img = img.Rotate90(False)
|
||||
img.Replace(0, 0, 0, sysTextColour[0], sysTextColour[1], sysTextColour[2])
|
||||
if layout == wx.VERTICAL:
|
||||
img = img.Scale(self.minWidth, 8, wx.IMAGE_QUALITY_HIGH)
|
||||
|
||||
self.bmpArrow = wx.BitmapFromImage(img)
|
||||
|
||||
self.RebuildRaces(self.shipBrowser.RACE_ORDER)
|
||||
|
||||
self.Bind(wx.EVT_ENTER_WINDOW, self.OnWindowEnter)
|
||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnWindowLeave)
|
||||
self.Bind(wx.EVT_TIMER, self.OnTimer)
|
||||
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnBackgroundErase)
|
||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
|
||||
self.Bind(wx.EVT_MOTION, self.OnMouseMove)
|
||||
self.Bind(wx.EVT_SIZE, self.OnSizeUpdate)
|
||||
|
||||
self.Layout()
|
||||
|
||||
def OnMouseMove(self, event):
|
||||
mx, my = event.GetPosition()
|
||||
|
||||
location = self.HitTest(mx, my)
|
||||
if location != self.hoveredItem:
|
||||
self.hoveredItem = location
|
||||
self.Refresh()
|
||||
if location is not None:
|
||||
self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
|
||||
else:
|
||||
self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
|
||||
|
||||
def OnSizeUpdate(self, event):
|
||||
self.CalcButtonsBarPos()
|
||||
|
||||
self.Refresh()
|
||||
|
||||
event.Skip()
|
||||
|
||||
def CalcButtonsBarPos(self):
|
||||
|
||||
if self.layout == wx.HORIZONTAL:
|
||||
rect = self.GetRect()
|
||||
width = 0
|
||||
height = 0
|
||||
for bmp in self.raceBmps:
|
||||
width += bmp.GetWidth() + self.buttonsPadding
|
||||
height = max(bmp.GetHeight(), height)
|
||||
|
||||
posx = (rect.width - width) / 2
|
||||
posy = (rect.height - height) / 2
|
||||
|
||||
self.buttonsBarPos = (posx, posy)
|
||||
|
||||
def OnLeftUp(self, event):
|
||||
|
||||
mx, my = event.GetPosition()
|
||||
|
||||
toggle = self.HitTest(mx, my)
|
||||
|
||||
if toggle is not None:
|
||||
self.Refresh()
|
||||
|
||||
self.shipBrowser.ToggleRacesFilter(self.raceNames[toggle])
|
||||
|
||||
stage = self.shipBrowser.GetActiveStage()
|
||||
|
||||
if stage == 2:
|
||||
categoryID = self.shipBrowser.GetStageData(stage)
|
||||
wx.PostEvent(self.shipBrowser, Stage2Selected(categoryID=categoryID, back=True))
|
||||
event.Skip()
|
||||
|
||||
def HitTest(self, mx, my):
|
||||
x, y = self.buttonsBarPos
|
||||
padding = self.buttonsPadding
|
||||
|
||||
for bmp in self.raceBmps:
|
||||
if (x < mx < x + bmp.GetWidth()) and (y < my < y + bmp.GetHeight()):
|
||||
return self.raceBmps.index(bmp)
|
||||
if self.layout == wx.VERTICAL:
|
||||
y += bmp.GetHeight() + padding
|
||||
else:
|
||||
x += bmp.GetWidth() + padding
|
||||
|
||||
return None
|
||||
|
||||
def RebuildRaces(self, races):
|
||||
self.raceBmps = []
|
||||
for race in races:
|
||||
if race:
|
||||
self.raceBmps.append(BitmapLoader.getBitmap("race_%s_small" % race, "gui"))
|
||||
self.raceNames = races
|
||||
self.CalcButtonsBarPos()
|
||||
self.Refresh()
|
||||
|
||||
def OnBackgroundErase(self, event):
|
||||
pass
|
||||
|
||||
def OnPaint(self, event):
|
||||
rect = self.GetRect()
|
||||
|
||||
windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
|
||||
# bkColor = colorUtils.GetSuitableColor(windowColor, 0.1)
|
||||
sepColor = colorUtils.GetSuitableColor(windowColor, 0.2)
|
||||
|
||||
mdc = wx.BufferedPaintDC(self)
|
||||
|
||||
bkBitmap = drawUtils.RenderGradientBar(windowColor, rect.width, rect.height, 0.1, 0.1, 0.2, 2)
|
||||
mdc.DrawBitmap(bkBitmap, 0, 0, True)
|
||||
|
||||
x, y = self.buttonsBarPos
|
||||
|
||||
if self.direction == 1:
|
||||
for raceBmp in self.raceBmps:
|
||||
dropShadow = drawUtils.CreateDropShadowBitmap(raceBmp, 0.2)
|
||||
|
||||
if self.shipBrowser.GetRaceFilterState(self.raceNames[self.raceBmps.index(raceBmp)]):
|
||||
bmp = raceBmp
|
||||
else:
|
||||
img = wx.ImageFromBitmap(raceBmp)
|
||||
if self.hoveredItem == self.raceBmps.index(raceBmp):
|
||||
img = img.AdjustChannels(1, 1, 1, 0.7)
|
||||
else:
|
||||
img = img.AdjustChannels(1, 1, 1, 0.4)
|
||||
bmp = wx.BitmapFromImage(img)
|
||||
|
||||
if self.layout == wx.VERTICAL:
|
||||
mdc.DrawBitmap(dropShadow, rect.width - self.buttonsPadding - bmp.GetWidth() + 1, y + 1)
|
||||
mdc.DrawBitmap(bmp, rect.width - self.buttonsPadding - bmp.GetWidth(), y)
|
||||
y += raceBmp.GetHeight() + self.buttonsPadding
|
||||
mdc.SetPen(wx.Pen(sepColor, 1))
|
||||
mdc.DrawLine(rect.width - 1, 0, rect.width - 1, rect.height)
|
||||
else:
|
||||
mdc.DrawBitmap(dropShadow, x + 1, self.buttonsPadding + 1)
|
||||
mdc.DrawBitmap(bmp, x, self.buttonsPadding)
|
||||
x += raceBmp.GetWidth() + self.buttonsPadding
|
||||
mdc.SetPen(wx.Pen(sepColor, 1))
|
||||
mdc.DrawLine(0, 0, rect.width, 0)
|
||||
|
||||
if self.direction < 1:
|
||||
if self.layout == wx.VERTICAL:
|
||||
mdc.DrawBitmap(self.bmpArrow, -2, (rect.height - self.bmpArrow.GetHeight()) / 2)
|
||||
else:
|
||||
mdc.SetPen(wx.Pen(sepColor, 1))
|
||||
mdc.DrawLine(0, 0, rect.width, 0)
|
||||
mdc.DrawBitmap(self.bmpArrow, (rect.width - self.bmpArrow.GetWidth()) / 2, -2)
|
||||
|
||||
def OnTimer(self, event):
|
||||
if event.GetId() == self.animTimerID:
|
||||
start = 0
|
||||
if self.layout == wx.VERTICAL:
|
||||
end = self.maxWidth - self.minWidth
|
||||
else:
|
||||
end = self.maxHeight - self.minHeight
|
||||
|
||||
step = animEffects.OUT_CIRC(self.animStep, start, end, self.animDuration)
|
||||
self.animStep += self.animPeriod * self.direction
|
||||
|
||||
self.AdjustSize((self.minWidth if self.layout == wx.VERTICAL else self.minHeight) + step)
|
||||
|
||||
if self.animStep > self.animDuration or self.animStep < 0:
|
||||
self.animTimer.Stop()
|
||||
self.animStep = self.animDuration if self.direction == 1 else 0
|
||||
self.Parent.GetBrowserContainer().RefreshList(True)
|
||||
|
||||
if event.GetId() == self.checkTimerID:
|
||||
if self.checkMaximize:
|
||||
self.direction = 1
|
||||
else:
|
||||
self.direction = -1
|
||||
|
||||
if not self.animTimer.IsRunning():
|
||||
self.animTimer.Start(self.animPeriod)
|
||||
|
||||
def AdjustSize(self, delta):
|
||||
self.SetMinSize(wx.Size(delta, -1) if self.layout == wx.VERTICAL else wx.Size(-1, delta))
|
||||
self.Parent.Layout()
|
||||
self.Refresh()
|
||||
|
||||
def OnWindowEnter(self, event):
|
||||
if not self.animate:
|
||||
return
|
||||
|
||||
if not self.checkTimer.IsRunning():
|
||||
self.checkTimer.Start(self.checkPeriod, wx.TIMER_ONE_SHOT)
|
||||
self.checkMaximize = True
|
||||
|
||||
event.Skip()
|
||||
|
||||
def OnWindowLeave(self, event):
|
||||
if self.hoveredItem is not None:
|
||||
self.hoveredItem = None
|
||||
self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
|
||||
self.Refresh()
|
||||
|
||||
if not self.animate:
|
||||
return
|
||||
|
||||
if not self.checkTimer.IsRunning():
|
||||
self.checkTimer.Start(self.checkPeriod, wx.TIMER_ONE_SHOT)
|
||||
self.checkMaximize = False
|
||||
|
||||
event.Skip()
|
||||
|
||||
433
gui/builtinShipBrowser/sfBrowserItem.py
Normal file
433
gui/builtinShipBrowser/sfBrowserItem.py
Normal file
@@ -0,0 +1,433 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import gui.utils.drawUtils as drawUtils
|
||||
|
||||
SB_ITEM_NORMAL = 0
|
||||
SB_ITEM_SELECTED = 1
|
||||
SB_ITEM_HIGHLIGHTED = 2
|
||||
SB_ITEM_DISABLED = 4
|
||||
|
||||
BTN_NORMAL = 1
|
||||
BTN_PRESSED = 2
|
||||
BTN_HOVER = 4
|
||||
BTN_DISABLED = 8
|
||||
|
||||
|
||||
class PFBaseButton(object):
|
||||
def __init__(self, normalBitmap=wx.NullBitmap, label="", callback=None, hoverBitmap=None, disabledBitmap=None,
|
||||
show=True):
|
||||
|
||||
self.normalBmp = normalBitmap
|
||||
self.dropShadowOpacity = 0.2
|
||||
self.dropShadowBmp = drawUtils.CreateDropShadowBitmap(self.normalBmp, self.dropShadowOpacity)
|
||||
self.hoverBmp = hoverBitmap
|
||||
self.disabledBmp = disabledBitmap
|
||||
self.label = label
|
||||
self.show = show
|
||||
|
||||
self.callback = callback
|
||||
|
||||
self.state = BTN_NORMAL
|
||||
# state : BTN_STUFF
|
||||
|
||||
def Show(self, show):
|
||||
self.show = show
|
||||
|
||||
def Hide(self):
|
||||
self.show = False
|
||||
|
||||
def IsVisible(self):
|
||||
return self.show
|
||||
|
||||
def SetCallback(self, callback):
|
||||
self.callback = callback
|
||||
|
||||
def GetCallback(self):
|
||||
return self.callback
|
||||
|
||||
def DoCallback(self):
|
||||
if self.callback:
|
||||
self.callback()
|
||||
|
||||
def SetState(self, state=BTN_NORMAL):
|
||||
self.state = state
|
||||
|
||||
def GetState(self):
|
||||
return self.state
|
||||
|
||||
def GetSize(self):
|
||||
w = self.normalBmp.GetWidth()
|
||||
h = self.normalBmp.GetHeight()
|
||||
return w, h
|
||||
|
||||
def GetBitmap(self):
|
||||
return self.normalBmp
|
||||
|
||||
def SetBitmap(self, bitmap):
|
||||
self.normalBmp = bitmap
|
||||
self.dropShadowBmp = drawUtils.CreateDropShadowBitmap(self.normalBmp, self.dropShadowOpacity)
|
||||
|
||||
def GetLabel(self):
|
||||
return self.label
|
||||
|
||||
def GetHoverBitmap(self):
|
||||
if self.hoverBmp is None:
|
||||
return self.normalBmp
|
||||
return self.hoverBmp
|
||||
|
||||
def GetDisabledBitmap(self):
|
||||
if self.disabledBmp is None:
|
||||
return self.normalBmp
|
||||
return self.disabledBmp
|
||||
|
||||
def GetDropShadowBitmap(self):
|
||||
return self.dropShadowBmp
|
||||
|
||||
|
||||
class PFToolbar(object):
|
||||
def __init__(self, parent):
|
||||
self.Parent = parent
|
||||
self.buttons = []
|
||||
self.toolbarX = 0
|
||||
self.toolbarY = 0
|
||||
self.padding = 2
|
||||
self.hoverLabel = ""
|
||||
|
||||
def SetPosition(self, pos):
|
||||
self.toolbarX, self.toolbarY = pos
|
||||
|
||||
def AddButton(self, btnBitmap, label="", clickCallback=None, hoverBitmap=None, disabledBitmap=None, show=True):
|
||||
btn = PFBaseButton(btnBitmap, label, clickCallback, hoverBitmap, disabledBitmap, show)
|
||||
self.buttons.append(btn)
|
||||
return btn
|
||||
|
||||
def ClearState(self):
|
||||
for button in self.buttons:
|
||||
button.SetState()
|
||||
self.hoverLabel = ""
|
||||
|
||||
def MouseMove(self, event):
|
||||
doRefresh = False
|
||||
changeCursor = False
|
||||
bx = self.toolbarX
|
||||
self.hoverLabel = ""
|
||||
|
||||
for button in self.buttons:
|
||||
if not button.IsVisible():
|
||||
continue
|
||||
|
||||
state = button.GetState()
|
||||
if self.HitTest((bx, self.toolbarY), event.GetPosition(), button.GetSize()):
|
||||
changeCursor = True
|
||||
if not state & BTN_HOVER:
|
||||
button.SetState(state | BTN_HOVER)
|
||||
self.hoverLabel = button.GetLabel()
|
||||
self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
|
||||
doRefresh = True
|
||||
else:
|
||||
if state & BTN_HOVER:
|
||||
button.SetState(state ^ BTN_HOVER)
|
||||
doRefresh = True
|
||||
|
||||
bwidth, bheight = button.GetSize()
|
||||
bx += bwidth + self.padding
|
||||
|
||||
if not changeCursor:
|
||||
self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
|
||||
return doRefresh
|
||||
|
||||
def MouseClick(self, event):
|
||||
bx = self.toolbarX
|
||||
for button in self.buttons:
|
||||
if not button.IsVisible():
|
||||
continue
|
||||
|
||||
state = button.GetState()
|
||||
if state & BTN_PRESSED:
|
||||
button.SetState(state ^ BTN_PRESSED)
|
||||
if self.HitTest((bx, self.toolbarY), event.GetPosition(), button.GetSize()):
|
||||
return button
|
||||
else:
|
||||
return False
|
||||
bwidth, bheight = button.GetSize()
|
||||
bx += bwidth + self.padding
|
||||
|
||||
bx = self.toolbarX
|
||||
for button in self.buttons:
|
||||
if not button.IsVisible():
|
||||
continue
|
||||
|
||||
state = button.GetState()
|
||||
|
||||
if self.HitTest((bx, self.toolbarY), event.GetPosition(), button.GetSize()):
|
||||
|
||||
if event.LeftDown() or event.LeftDClick():
|
||||
button.SetState(state | BTN_PRESSED)
|
||||
return button
|
||||
|
||||
elif event.LeftUp():
|
||||
button.SetState(state | (not BTN_PRESSED))
|
||||
return button
|
||||
|
||||
bwidth, bheight = button.GetSize()
|
||||
bx += bwidth + self.padding
|
||||
|
||||
return None
|
||||
|
||||
def GetWidth(self):
|
||||
bx = 0
|
||||
for button in self.buttons:
|
||||
if not button.IsVisible():
|
||||
continue
|
||||
|
||||
bwidth, bheight = button.GetSize()
|
||||
bx += bwidth + self.padding
|
||||
|
||||
return bx
|
||||
|
||||
def GetHeight(self):
|
||||
height = 0
|
||||
for button in self.buttons:
|
||||
if not button.IsVisible():
|
||||
continue
|
||||
|
||||
bwidth, bheight = button.GetSize()
|
||||
height = max(height, bheight)
|
||||
|
||||
return height
|
||||
|
||||
@staticmethod
|
||||
def HitTest(target, position, area):
|
||||
x, y = target
|
||||
px, py = position
|
||||
aX, aY = area
|
||||
if (x < px < x + aX) and (y < py < y + aY):
|
||||
return True
|
||||
return False
|
||||
|
||||
def Render(self, pdc):
|
||||
bx = self.toolbarX
|
||||
for button in self.buttons:
|
||||
if not button.IsVisible():
|
||||
continue
|
||||
|
||||
by = self.toolbarY
|
||||
tbx = bx
|
||||
|
||||
btnState = button.GetState()
|
||||
|
||||
bmp = button.GetDisabledBitmap()
|
||||
dropShadowBmp = button.GetDropShadowBitmap()
|
||||
|
||||
if btnState & BTN_NORMAL:
|
||||
bmp = button.GetBitmap()
|
||||
|
||||
if btnState & BTN_HOVER:
|
||||
bmp = button.GetHoverBitmap()
|
||||
|
||||
if btnState & BTN_PRESSED:
|
||||
bmp = button.GetBitmap()
|
||||
by += self.padding / 2
|
||||
tbx += self.padding / 2
|
||||
|
||||
bmpWidth = bmp.GetWidth()
|
||||
|
||||
pdc.DrawBitmap(dropShadowBmp, bx + self.padding / 2, self.toolbarY + self.padding / 2)
|
||||
pdc.DrawBitmap(bmp, tbx, by)
|
||||
|
||||
bx += bmpWidth + self.padding
|
||||
|
||||
|
||||
class SFBrowserItem(wx.Window):
|
||||
def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=(0, 16), style=0):
|
||||
wx.Window.__init__(self, parent, id, pos, size, style)
|
||||
|
||||
self.highlighted = False
|
||||
self.selected = False
|
||||
self.bkBitmap = None
|
||||
|
||||
self.canBeDragged = False
|
||||
|
||||
self.toolbar = PFToolbar(self)
|
||||
|
||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
|
||||
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
|
||||
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
|
||||
|
||||
|
||||
if "wxMSW" in wx.PlatformInfo:
|
||||
self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDown)
|
||||
|
||||
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
|
||||
self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow)
|
||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
|
||||
self.Bind(wx.EVT_MOTION, self.OnMotion)
|
||||
self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
|
||||
self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
|
||||
|
||||
def OnFocus(self, evt):
|
||||
self.SetHighlighted(True)
|
||||
self.Refresh()
|
||||
evt.Skip()
|
||||
|
||||
def OnKillFocus(self, evt):
|
||||
self.SetHighlighted(False)
|
||||
self.Refresh()
|
||||
evt.Skip()
|
||||
|
||||
def Refresh(self):
|
||||
self.RenderBackground()
|
||||
wx.Window.Refresh(self)
|
||||
|
||||
def OnPaint(self, event):
|
||||
mdc = wx.BufferedPaintDC(self)
|
||||
|
||||
self.RenderBackground()
|
||||
|
||||
mdc.DrawBitmap(self.bkBitmap, 0, 0)
|
||||
|
||||
self.DrawItem(mdc)
|
||||
self.toolbar.Render(mdc)
|
||||
|
||||
def DrawItem(self, mdc):
|
||||
pass
|
||||
|
||||
def OnEraseBackground(self, event):
|
||||
pass
|
||||
|
||||
def OnKeyDown(self, event):
|
||||
pass
|
||||
|
||||
def MouseLeftUp(self, event):
|
||||
pass
|
||||
|
||||
def MouseLeftDown(self, event):
|
||||
pass
|
||||
|
||||
def MouseMove(self, event):
|
||||
pass
|
||||
|
||||
def SetDraggable(self, mode=True):
|
||||
self.canBeDragged = mode
|
||||
|
||||
def OnLeftUp(self, event):
|
||||
|
||||
if self.HasCapture():
|
||||
self.ReleaseMouse()
|
||||
if not self.canBeDragged:
|
||||
mposx, mposy = wx.GetMousePosition()
|
||||
rect = self.GetRect()
|
||||
rect.top = rect.left = 0
|
||||
cx, cy = self.ScreenToClient((mposx, mposy))
|
||||
if not rect.Contains((cx, cy)):
|
||||
self.SetHighlighted(False)
|
||||
self.toolbar.ClearState()
|
||||
self.Refresh()
|
||||
return
|
||||
|
||||
btn = self.toolbar.MouseClick(event)
|
||||
|
||||
if btn is not None:
|
||||
if btn is not False:
|
||||
if btn.GetState() & BTN_NORMAL:
|
||||
btn.DoCallback()
|
||||
self.Refresh()
|
||||
else:
|
||||
self.Refresh()
|
||||
return
|
||||
|
||||
self.MouseLeftUp(event)
|
||||
|
||||
def OnLeftDown(self, event):
|
||||
if not self.HasCapture():
|
||||
self.CaptureMouse()
|
||||
|
||||
btn = self.toolbar.MouseClick(event)
|
||||
|
||||
if btn is not None:
|
||||
if btn.GetState() & BTN_PRESSED:
|
||||
self.Refresh()
|
||||
return
|
||||
|
||||
self.MouseLeftDown(event)
|
||||
|
||||
def OnEnterWindow(self, event):
|
||||
self.SetHighlighted(True)
|
||||
self.toolbar.ClearState()
|
||||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
def OnLeaveWindow(self, event):
|
||||
self.SetHighlighted(False)
|
||||
self.toolbar.ClearState()
|
||||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
def OnMotion(self, event):
|
||||
if self.toolbar.MouseMove(event):
|
||||
self.Refresh()
|
||||
|
||||
self.MouseMove(event)
|
||||
|
||||
event.Skip()
|
||||
|
||||
@staticmethod
|
||||
def GetType():
|
||||
return -1
|
||||
|
||||
def SetSelected(self, select=True):
|
||||
self.selected = select
|
||||
|
||||
def SetHighlighted(self, highlight=True):
|
||||
self.highlighted = highlight
|
||||
|
||||
def GetState(self):
|
||||
|
||||
if self.highlighted and not self.selected:
|
||||
state = SB_ITEM_HIGHLIGHTED
|
||||
|
||||
elif self.selected:
|
||||
if self.highlighted:
|
||||
state = SB_ITEM_SELECTED | SB_ITEM_HIGHLIGHTED
|
||||
else:
|
||||
state = SB_ITEM_SELECTED
|
||||
else:
|
||||
state = SB_ITEM_NORMAL
|
||||
|
||||
return state
|
||||
|
||||
def RenderBackground(self):
|
||||
rect = self.GetRect()
|
||||
|
||||
windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
|
||||
|
||||
state = self.GetState()
|
||||
|
||||
sFactor = 0.2
|
||||
mFactor = None
|
||||
eFactor = 0
|
||||
|
||||
if state == SB_ITEM_HIGHLIGHTED:
|
||||
mFactor = 0.45
|
||||
eFactor = 0.30
|
||||
|
||||
elif state == SB_ITEM_SELECTED | SB_ITEM_HIGHLIGHTED:
|
||||
eFactor = 0.3
|
||||
elif state == SB_ITEM_SELECTED:
|
||||
eFactor = 0.15
|
||||
else:
|
||||
sFactor = 0.0
|
||||
|
||||
if self.bkBitmap:
|
||||
if self.bkBitmap.eFactor == eFactor and self.bkBitmap.sFactor == sFactor and self.bkBitmap.mFactor == mFactor \
|
||||
and rect.width == self.bkBitmap.GetWidth() and rect.height == self.bkBitmap.GetHeight():
|
||||
return
|
||||
else:
|
||||
del self.bkBitmap
|
||||
|
||||
self.bkBitmap = drawUtils.RenderGradientBar(windowColor, rect.width, rect.height, sFactor, eFactor, mFactor)
|
||||
self.bkBitmap.state = state
|
||||
self.bkBitmap.sFactor = sFactor
|
||||
self.bkBitmap.eFactor = eFactor
|
||||
self.bkBitmap.mFactor = mFactor
|
||||
285
gui/builtinShipBrowser/shipItem.py
Normal file
285
gui/builtinShipBrowser/shipItem.py
Normal file
@@ -0,0 +1,285 @@
|
||||
import re
|
||||
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
import gui.builtinShipBrowser.sfBrowserItem as SFItem
|
||||
import gui.mainFrame
|
||||
import gui.utils.colorUtils as colorUtils
|
||||
import gui.utils.drawUtils as drawUtils
|
||||
import gui.utils.fonts as fonts
|
||||
from events import *
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui.contextMenu import ContextMenu
|
||||
from service.fit import Fit
|
||||
from service.market import Market
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class ShipItem(SFItem.SFBrowserItem):
|
||||
def __init__(self, parent, shipID=None, shipFittingInfo=("Test", "TestTrait", 2), itemData=None,
|
||||
id=wx.ID_ANY, pos=wx.DefaultPosition,
|
||||
size=(0, 40), style=0):
|
||||
SFItem.SFBrowserItem.__init__(self, parent, size=size)
|
||||
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
self._itemData = itemData
|
||||
|
||||
self.shipRace = itemData
|
||||
|
||||
self.shipID = shipID
|
||||
|
||||
self.fontBig = wx.Font(fonts.BIG, wx.SWISS, wx.NORMAL, wx.BOLD)
|
||||
self.fontNormal = wx.Font(fonts.NORMAL, wx.SWISS, wx.NORMAL, wx.NORMAL)
|
||||
self.fontSmall = wx.Font(fonts.SMALL, wx.SWISS, wx.NORMAL, wx.NORMAL)
|
||||
|
||||
self.shipBmp = None
|
||||
if shipID:
|
||||
self.shipBmp = BitmapLoader.getBitmap(str(shipID), "renders")
|
||||
if not self.shipBmp:
|
||||
self.shipBmp = BitmapLoader.getBitmap("ship_no_image_big", "gui")
|
||||
|
||||
self.shipFittingInfo = shipFittingInfo
|
||||
self.shipName, self.shipTrait, self.shipFits = shipFittingInfo
|
||||
self.shipTrait = re.sub("<.*?>", " ", self.shipTrait)
|
||||
|
||||
self.newBmp = BitmapLoader.getBitmap("fit_add_small", "gui")
|
||||
self.acceptBmp = BitmapLoader.getBitmap("faccept_small", "gui")
|
||||
|
||||
self.shipEffBk = BitmapLoader.getBitmap("fshipbk_big", "gui")
|
||||
|
||||
img = wx.ImageFromBitmap(self.shipEffBk)
|
||||
img = img.Mirror(False)
|
||||
self.shipEffBkMirrored = wx.BitmapFromImage(img)
|
||||
|
||||
self.raceBmp = BitmapLoader.getBitmap("race_%s_small" % self.shipRace, "gui")
|
||||
|
||||
if not self.raceBmp:
|
||||
self.raceBmp = BitmapLoader.getBitmap("fit_delete_small", "gui")
|
||||
|
||||
self.raceDropShadowBmp = drawUtils.CreateDropShadowBitmap(self.raceBmp, 0.2)
|
||||
|
||||
sFit = Fit.getInstance()
|
||||
if self.shipTrait and sFit.serviceFittingOptions["showShipBrowserTooltip"]:
|
||||
self.SetToolTip(wx.ToolTip(self.shipTrait))
|
||||
|
||||
self.shipBrowser = self.Parent.Parent
|
||||
|
||||
self.editWidth = 150
|
||||
self.padding = 4
|
||||
|
||||
self.tcFitName = wx.TextCtrl(self, wx.ID_ANY, "%s fit" % self.shipName, wx.DefaultPosition, (120, -1),
|
||||
wx.TE_PROCESS_ENTER)
|
||||
self.tcFitName.Show(False)
|
||||
|
||||
self.newBtn = self.toolbar.AddButton(self.newBmp, "New", self.newBtnCB)
|
||||
|
||||
self.tcFitName.Bind(wx.EVT_TEXT_ENTER, self.createNewFit)
|
||||
self.tcFitName.Bind(wx.EVT_KILL_FOCUS, self.editLostFocus)
|
||||
self.tcFitName.Bind(wx.EVT_KEY_DOWN, self.editCheckEsc)
|
||||
|
||||
self.animTimerId = wx.NewId()
|
||||
|
||||
self.animTimer = wx.Timer(self, self.animTimerId)
|
||||
self.animStep = 0
|
||||
self.animPeriod = 10
|
||||
self.animDuration = 100
|
||||
|
||||
self.Bind(wx.EVT_CONTEXT_MENU, self.OnShowPopup)
|
||||
|
||||
self.marketInstance = Market.getInstance()
|
||||
self.baseItem = self.marketInstance.getItem(self.shipID)
|
||||
|
||||
# =====================================================================
|
||||
# DISABLED - it will be added as an option in PREFERENCES
|
||||
|
||||
self.animCount = 0
|
||||
|
||||
# if self.shipBrowser.GetActiveStage() != 4 and self.shipBrowser.GetLastStage() !=2:
|
||||
# self.Bind(wx.EVT_TIMER, self.OnTimer)
|
||||
# self.animTimer.Start(self.animPeriod)
|
||||
# else:
|
||||
# self.animCount = 0
|
||||
# =====================================================================
|
||||
|
||||
def OnShowPopup(self, event):
|
||||
pos = event.GetPosition()
|
||||
pos = self.ScreenToClient(pos)
|
||||
contexts = [("baseShip", "Ship Basic")]
|
||||
menu = ContextMenu.getMenu(self.baseItem, *contexts)
|
||||
self.PopupMenu(menu, pos)
|
||||
|
||||
def OnTimer(self, event):
|
||||
step = self.OUT_QUAD(self.animStep, 0, 10, self.animDuration)
|
||||
self.animCount = 10 - step
|
||||
self.animStep += self.animPeriod
|
||||
if self.animStep > self.animDuration or self.animCount < 0:
|
||||
self.animCount = 0
|
||||
self.animTimer.Stop()
|
||||
self.Refresh()
|
||||
|
||||
@staticmethod
|
||||
def OUT_QUAD(t, b, c, d):
|
||||
t = float(t)
|
||||
b = float(b)
|
||||
c = float(c)
|
||||
d = float(d)
|
||||
|
||||
t /= d
|
||||
|
||||
return -c * t * (t - 2) + b
|
||||
|
||||
def GetType(self):
|
||||
return 2
|
||||
|
||||
def MouseLeftUp(self, event):
|
||||
if self.tcFitName.IsShown():
|
||||
self.tcFitName.Show(False)
|
||||
self.newBtn.SetBitmap(self.newBmp)
|
||||
self.Refresh()
|
||||
else:
|
||||
shipName, shipTrait, fittings = self.shipFittingInfo
|
||||
if fittings > 0:
|
||||
wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=self.shipID, back=True))
|
||||
else:
|
||||
self.newBtnCB()
|
||||
|
||||
def newBtnCB(self):
|
||||
if self.tcFitName.IsShown():
|
||||
self.tcFitName.Show(False)
|
||||
self.createNewFit()
|
||||
else:
|
||||
self.tcFitName.SetValue("%s fit" % self.shipName)
|
||||
self.tcFitName.Show()
|
||||
|
||||
self.tcFitName.SetFocus()
|
||||
self.tcFitName.SelectAll()
|
||||
|
||||
self.newBtn.SetBitmap(self.acceptBmp)
|
||||
|
||||
self.Refresh()
|
||||
|
||||
def editLostFocus(self, event):
|
||||
self.tcFitName.Show(False)
|
||||
self.newBtn.SetBitmap(self.newBmp)
|
||||
self.Refresh()
|
||||
|
||||
def editCheckEsc(self, event):
|
||||
if event.GetKeyCode() == wx.WXK_ESCAPE:
|
||||
self.tcFitName.Show(False)
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
def createNewFit(self, event=None):
|
||||
self.tcFitName.Show(False)
|
||||
|
||||
sFit = Fit.getInstance()
|
||||
fitID = sFit.newFit(self.shipID, self.tcFitName.GetValue())
|
||||
|
||||
wx.PostEvent(self.shipBrowser, Stage3Selected(shipID=self.shipID, back=False))
|
||||
wx.PostEvent(self.mainFrame, FitSelected(fitID=fitID))
|
||||
|
||||
def UpdateElementsPos(self, mdc):
|
||||
rect = self.GetRect()
|
||||
|
||||
self.toolbarx = rect.width - self.toolbar.GetWidth() - self.padding
|
||||
self.toolbary = (rect.height - self.toolbar.GetHeight()) / 2
|
||||
|
||||
self.toolbarx += self.animCount
|
||||
|
||||
self.shipEffx = self.padding + (rect.height - self.shipEffBk.GetWidth()) / 2
|
||||
self.shipEffy = (rect.height - self.shipEffBk.GetHeight()) / 2
|
||||
|
||||
self.shipEffx -= self.animCount
|
||||
|
||||
self.shipBmpx = self.padding + (rect.height - self.shipBmp.GetWidth()) / 2
|
||||
self.shipBmpy = (rect.height - self.shipBmp.GetHeight()) / 2
|
||||
|
||||
self.shipBmpx -= self.animCount
|
||||
|
||||
self.raceBmpx = self.shipEffx + self.shipEffBk.GetWidth() + self.padding
|
||||
self.raceBmpy = (rect.height - self.raceBmp.GetHeight()) / 2
|
||||
|
||||
self.textStartx = self.raceBmpx + self.raceBmp.GetWidth() + self.padding
|
||||
|
||||
self.shipNamey = (rect.height - self.shipBmp.GetHeight()) / 2
|
||||
|
||||
shipName, shipTrait, fittings = self.shipFittingInfo
|
||||
|
||||
mdc.SetFont(self.fontBig)
|
||||
wtext, htext = mdc.GetTextExtent(shipName)
|
||||
|
||||
self.fittingsy = self.shipNamey + htext
|
||||
|
||||
mdc.SetFont(self.fontSmall)
|
||||
|
||||
wlabel, hlabel = mdc.GetTextExtent(self.toolbar.hoverLabel)
|
||||
|
||||
self.thoverx = self.toolbarx - self.padding - wlabel
|
||||
self.thovery = (rect.height - hlabel) / 2
|
||||
self.thoverw = wlabel
|
||||
|
||||
def DrawItem(self, mdc):
|
||||
# rect = self.GetRect()
|
||||
|
||||
windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
|
||||
textColor = colorUtils.GetSuitableColor(windowColor, 1)
|
||||
|
||||
mdc.SetTextForeground(textColor)
|
||||
|
||||
self.UpdateElementsPos(mdc)
|
||||
|
||||
self.toolbar.SetPosition((self.toolbarx, self.toolbary))
|
||||
|
||||
if self.GetState() & SFItem.SB_ITEM_HIGHLIGHTED:
|
||||
shipEffBk = self.shipEffBkMirrored
|
||||
else:
|
||||
shipEffBk = self.shipEffBk
|
||||
|
||||
mdc.DrawBitmap(shipEffBk, self.shipEffx, self.shipEffy, 0)
|
||||
|
||||
mdc.DrawBitmap(self.shipBmp, self.shipBmpx, self.shipBmpy, 0)
|
||||
|
||||
mdc.DrawBitmap(self.raceDropShadowBmp, self.raceBmpx + 1, self.raceBmpy + 1)
|
||||
mdc.DrawBitmap(self.raceBmp, self.raceBmpx, self.raceBmpy)
|
||||
|
||||
shipName, shipTrait, fittings = self.shipFittingInfo
|
||||
|
||||
if fittings < 1:
|
||||
fformat = "No fits"
|
||||
elif fittings == 1:
|
||||
fformat = "%d fit"
|
||||
else:
|
||||
fformat = "%d fits"
|
||||
|
||||
mdc.SetFont(self.fontNormal)
|
||||
mdc.DrawText(fformat % fittings if fittings > 0 else fformat, self.textStartx, self.fittingsy)
|
||||
|
||||
mdc.SetFont(self.fontSmall)
|
||||
mdc.DrawText(self.toolbar.hoverLabel, self.thoverx, self.thovery)
|
||||
|
||||
mdc.SetFont(self.fontBig)
|
||||
|
||||
psname = drawUtils.GetPartialText(mdc, shipName,
|
||||
self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw)
|
||||
|
||||
mdc.DrawText(psname, self.textStartx, self.shipNamey)
|
||||
|
||||
if self.tcFitName.IsShown():
|
||||
self.AdjustControlSizePos(self.tcFitName, self.textStartx, self.toolbarx - self.editWidth - self.padding)
|
||||
|
||||
def AdjustControlSizePos(self, editCtl, start, end):
|
||||
fnEditSize = editCtl.GetSize()
|
||||
wSize = self.GetSize()
|
||||
fnEditPosX = end
|
||||
fnEditPosY = (wSize.height - fnEditSize.height) / 2
|
||||
if fnEditPosX < start:
|
||||
editCtl.SetSize((self.editWidth + fnEditPosX - start, -1))
|
||||
editCtl.SetPosition((start, fnEditPosY))
|
||||
else:
|
||||
editCtl.SetSize((self.editWidth, -1))
|
||||
editCtl.SetPosition((fnEditPosX, fnEditPosY))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user