Stage 2 now sums total fittings in category and sets the cache to True if t_fits > 0 Stage 3 sets the cache to True if number of fits for ship > 0. This takes care of creating new fits If fit is deleted, and there are no other fits for the ship, it reverts back to stage 2, which should set the correct value in the cache
1831 lines
62 KiB
Python
1831 lines
62 KiB
Python
import wx
|
|
import copy
|
|
from gui import bitmapLoader
|
|
import gui.mainFrame
|
|
import gui.globalEvents as GE
|
|
import time
|
|
from gui.PFListPane import PFListPane
|
|
import service
|
|
|
|
from wx.lib.buttons import GenBitmapButton
|
|
|
|
import gui.utils.colorUtils as colorUtils
|
|
import gui.utils.drawUtils as drawUtils
|
|
import gui.utils.animUtils as animUtils
|
|
import gui.utils.animEffects as animEffects
|
|
|
|
import gui.sfBrowserItem as SFItem
|
|
from gui.contextMenu import ContextMenu
|
|
|
|
import service
|
|
|
|
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()
|
|
|
|
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
|
|
|
|
|
|
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","icons")
|
|
else:
|
|
self.bmpArrow = bitmapLoader.getBitmap("up-arrow2","icons")
|
|
|
|
# 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 (mx > x and mx < x + bmp.GetWidth()) and (my > y and 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, "icons"))
|
|
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()
|
|
|
|
class NavigationPanel(SFItem.SFBrowserItem):
|
|
def __init__(self,parent, size = (-1,24)):
|
|
SFItem.SFBrowserItem.__init__(self,parent,size = size)
|
|
|
|
self.rewBmpH = bitmapLoader.getBitmap("frewind_small","icons")
|
|
self.forwBmp = bitmapLoader.getBitmap("fforward_small","icons")
|
|
self.searchBmpH = bitmapLoader.getBitmap("fsearch_small","icons")
|
|
self.newBmpH = bitmapLoader.getBitmap("fit_add_small","icons")
|
|
self.resetBmpH = bitmapLoader.getBitmap("freset_small","icons")
|
|
self.switchBmpH = bitmapLoader.getBitmap("fit_switch_view_mode_small","icons")
|
|
|
|
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.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.switchBmp, "Hide empty ship groups", clickCallback = self.ToggleEmptyGroupsView, hoverBitmap = self.switchBmpH, show = False)
|
|
self.toolbar.AddButton(self.searchBmp, "Search fittings", clickCallback = self.ToggleSearchBox, hoverBitmap = self.searchBmpH)
|
|
|
|
self.padding = 4
|
|
self.lastSearch = ""
|
|
self.recentSearches = []
|
|
self.inSearch = False
|
|
|
|
self.fontSmall = wx.FontFromPixelSize((0,12),wx.SWISS, wx.NORMAL, wx.NORMAL, False)
|
|
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 and len(realsearch) >= 0:
|
|
if self.inSearch == True:
|
|
self.inSearch = False
|
|
if len(self.shipBrowser.browseHist) > 0:
|
|
stage,data = self.shipBrowser.browseHist.pop()
|
|
self.gotoStage(stage,data)
|
|
else:
|
|
if search:
|
|
wx.PostEvent(self.shipBrowser,SearchSelected(text=search, back = False))
|
|
self.inSearch = True
|
|
else:
|
|
self.inSearch = 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.lastSearch = self.BrowserSearchBox.GetValue()
|
|
self.BrowserSearchBox.ChangeValue("")
|
|
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 ToggleEmptyGroupsView(self):
|
|
if self.shipBrowser.filterShipsWithNoFits:
|
|
self.shipBrowser.filterShipsWithNoFits = False
|
|
self.btnSwitch.label = "Hide empty ship groups"
|
|
else:
|
|
self.shipBrowser.filterShipsWithNoFits = True
|
|
self.btnSwitch.label = "Show empty ship groups"
|
|
|
|
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 = service.Fit.getInstance()
|
|
fitID = sFit.newFit(shipID, "%s fit" %shipName)
|
|
self.shipBrowser.fitIDMustEditName = fitID
|
|
wx.PostEvent(self.Parent,Stage3Selected(shipID=shipID, back = True))
|
|
wx.PostEvent(self.mainFrame, FitSelected(fitID=fitID))
|
|
|
|
def OnHistoryReset(self):
|
|
if self.shipBrowser.browseHist:
|
|
self.shipBrowser.browseHist = []
|
|
self.gotoStage(1,0)
|
|
|
|
def OnHistoryBack(self):
|
|
if len(self.shipBrowser.browseHist) > 0:
|
|
stage,data = self.shipBrowser.browseHist.pop()
|
|
self.gotoStage(stage,data)
|
|
|
|
def AdjustChannels(self, 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):
|
|
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, back = 1))
|
|
elif stage == 4:
|
|
self.shipBrowser._activeStage = 4
|
|
self.stStatus.SetLabel("Search: %s" % data.capitalize())
|
|
self.Layout()
|
|
wx.PostEvent(self.Parent,SearchSelected(text=data, back = True))
|
|
else:
|
|
wx.PostEvent(self.Parent,Stage1Selected())
|
|
|
|
|
|
class ShipBrowser(wx.Panel):
|
|
def __init__(self, parent):
|
|
wx.Panel.__init__ (self, parent,style = 0)
|
|
|
|
self._lastWidth = 0
|
|
self._activeStage = 1
|
|
self._lastStage = 0
|
|
self.browseHist = []
|
|
self.lastStage = (0,0)
|
|
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
|
|
|
self.categoryList=[]
|
|
self.categoryFitCache = {}
|
|
|
|
self._stage1Data = -1
|
|
self._stage2Data = -1
|
|
self._stage3Data = -1
|
|
self._stage3ShipName = ""
|
|
self.fitIDMustEditName = -1
|
|
self.filterShipsWithNoFits = False
|
|
|
|
self.racesFilter = {}
|
|
|
|
self.showRacesFilterInStage2Only = True
|
|
|
|
for race in self.RACE_ORDER:
|
|
if race:
|
|
self.racesFilter[race] = False
|
|
|
|
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
|
|
|
|
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
|
|
|
self.lpane = PFWidgetsContainer(self)
|
|
layout = wx.HORIZONTAL
|
|
|
|
self.navpanel = NavigationPanel(self)
|
|
mainSizer.Add(self.navpanel, 0 , wx.EXPAND)
|
|
self.raceselect = RaceSelector(self, layout = layout, animate = False)
|
|
container = wx.BoxSizer(wx.VERTICAL if layout == wx.HORIZONTAL else wx.HORIZONTAL)
|
|
|
|
if layout == wx.HORIZONTAL:
|
|
container.Add(self.lpane,1,wx.EXPAND)
|
|
container.Add(self.raceselect,0,wx.EXPAND)
|
|
else:
|
|
container.Add(self.raceselect,0,wx.EXPAND)
|
|
container.Add(self.lpane,1,wx.EXPAND)
|
|
|
|
mainSizer.Add(container, 1, wx.EXPAND)
|
|
self.SetSizer(mainSizer)
|
|
self.Layout()
|
|
self.Show()
|
|
|
|
self.Bind(wx.EVT_SIZE, self.SizeRefreshList)
|
|
self.Bind(EVT_SB_STAGE2_SEL, self.stage2)
|
|
self.Bind(EVT_SB_STAGE1_SEL, self.stage1)
|
|
self.Bind(EVT_SB_STAGE3_SEL, self.stage3)
|
|
self.Bind(EVT_SB_SEARCH_SEL, self.searchStage)
|
|
|
|
self.mainFrame.Bind(GE.FIT_CHANGED, self.RefreshList)
|
|
|
|
self.stage1(None)
|
|
|
|
def GetBrowserContainer(self):
|
|
return self.lpane
|
|
|
|
def RefreshContent(self):
|
|
stage = self.GetActiveStage()
|
|
if stage == 1:
|
|
return
|
|
stageData = self.GetStageData(stage)
|
|
self.navpanel.gotoStage(stage, stageData)
|
|
|
|
def RefreshList(self, event):
|
|
stage = self.GetActiveStage()
|
|
if stage == 3 or stage == 4:
|
|
self.lpane.RefreshList(True)
|
|
event.Skip()
|
|
|
|
def SizeRefreshList(self, event):
|
|
ewidth, eheight = event.GetSize()
|
|
self.Layout()
|
|
self.lpane.Layout()
|
|
self.lpane.RefreshList(True)
|
|
event.Skip()
|
|
|
|
def __del__(self):
|
|
pass
|
|
|
|
def GetActiveStage(self):
|
|
return self._activeStage
|
|
|
|
def GetLastStage(self):
|
|
return self._lastStage
|
|
|
|
def GetStageData(self, stage):
|
|
if stage == 1:
|
|
return self._stage1Data
|
|
if stage == 2:
|
|
return self._stage2Data
|
|
if stage == 3:
|
|
return self._stage3Data
|
|
return -1
|
|
|
|
def GetStage3ShipName(self):
|
|
return self._stage3ShipName
|
|
|
|
def ToggleRacesFilter(self, race):
|
|
if self.racesFilter[race]:
|
|
self.racesFilter[race] = False
|
|
else:
|
|
self.racesFilter[race] = True
|
|
|
|
def GetRaceFilterState(self, race):
|
|
return self.racesFilter[race]
|
|
|
|
def stage1(self, event):
|
|
self._lastStage = self._activeStage
|
|
self._activeStage = 1
|
|
self.lastdata = 0
|
|
|
|
self.navpanel.ShowNewFitButton(False)
|
|
self.navpanel.ShowSwitchEmptyGroupsButton(False)
|
|
|
|
sMarket = service.Market.getInstance()
|
|
sFit = service.Fit.getInstance()
|
|
self.lpane.ShowLoading(False)
|
|
|
|
self.lpane.Freeze()
|
|
self.lpane.RemoveAllChildren()
|
|
|
|
if len(self.categoryList) == 0:
|
|
# set cache of category list
|
|
self.categoryList = list(sMarket.getShipRoot())
|
|
self.categoryList.sort(key=lambda ship: ship.name)
|
|
|
|
# set map & cache of fittings per category
|
|
for cat in self.categoryList:
|
|
self.categoryFitCache[cat.ID] = sFit.groupHasFits(cat.ID)
|
|
|
|
for ship in self.categoryList:
|
|
if self.filterShipsWithNoFits and not self.categoryFitCache[ship.ID]:
|
|
continue
|
|
else:
|
|
self.lpane.AddWidget(CategoryItem(self.lpane, ship.ID, (ship.name, 0)))
|
|
|
|
self.navpanel.ShowSwitchEmptyGroupsButton(True)
|
|
|
|
self.lpane.RefreshList()
|
|
self.lpane.Thaw()
|
|
self.raceselect.RebuildRaces(self.RACE_ORDER)
|
|
if self.showRacesFilterInStage2Only:
|
|
self.raceselect.Show(False)
|
|
self.Layout()
|
|
|
|
RACE_ORDER = ["amarr", "caldari", "gallente", "minmatar", "sisters", "ore", "serpentis", "angel", "blood", "sansha", "guristas", "jove", None]
|
|
|
|
def raceNameKey(self, ship):
|
|
return self.RACE_ORDER.index(ship.race), ship.name
|
|
|
|
def stage2Callback(self, data):
|
|
if self.GetActiveStage() != 2:
|
|
return
|
|
|
|
categoryID = self._stage2Data
|
|
ships = list(data[1])
|
|
sFit = service.Fit.getInstance()
|
|
|
|
ships.sort(key=self.raceNameKey)
|
|
racesList = []
|
|
subRacesFilter = {}
|
|
t_fits = 0 # total number of fits in this category
|
|
|
|
for ship in ships:
|
|
if ship.race:
|
|
if ship.race not in racesList:
|
|
racesList.append(ship.race)
|
|
|
|
for race,state in self.racesFilter.iteritems():
|
|
if race in racesList:
|
|
subRacesFilter[race] = self.racesFilter[race]
|
|
|
|
override = True
|
|
for race, state in subRacesFilter.iteritems():
|
|
if state:
|
|
override = False
|
|
break
|
|
|
|
for ship in ships:
|
|
fits = sFit.countFitsWithShip(ship.ID)
|
|
t_fits += fits
|
|
filter = subRacesFilter[ship.race] if ship.race else True
|
|
|
|
if override:
|
|
filter = True
|
|
|
|
if self.filterShipsWithNoFits:
|
|
if fits>0:
|
|
if filter:
|
|
self.lpane.AddWidget(ShipItem(self.lpane, ship.ID, (ship.name, fits), ship.race))
|
|
else:
|
|
if filter:
|
|
self.lpane.AddWidget(ShipItem(self.lpane, ship.ID, (ship.name, fits), ship.race))
|
|
|
|
self.raceselect.RebuildRaces(racesList)
|
|
|
|
# refresh category cache
|
|
if t_fits == 0:
|
|
self.categoryFitCache[categoryID] = False
|
|
else:
|
|
self.categoryFitCache[categoryID] = True
|
|
|
|
self.lpane.ShowLoading(False)
|
|
|
|
self.lpane.RefreshList()
|
|
|
|
if self.showRacesFilterInStage2Only:
|
|
self.raceselect.Show(True)
|
|
self.Layout()
|
|
|
|
def stage2(self, event):
|
|
back = event.back
|
|
|
|
if not back:
|
|
self.browseHist.append( (1,0) )
|
|
|
|
self._lastStage = self._activeStage
|
|
self._activeStage = 2
|
|
categoryID = event.categoryID
|
|
self.lastdata = categoryID
|
|
|
|
self.lpane.ShowLoading()
|
|
|
|
self.lpane.RemoveAllChildren()
|
|
|
|
|
|
sMarket = service.Market.getInstance()
|
|
sMarket.getShipListDelayed(categoryID, self.stage2Callback)
|
|
|
|
self._stage2Data = categoryID
|
|
|
|
self.navpanel.ShowNewFitButton(False)
|
|
self.navpanel.ShowSwitchEmptyGroupsButton(True)
|
|
|
|
def nameKey(self, info):
|
|
return info[1]
|
|
|
|
def stage3(self, event):
|
|
|
|
self.lpane.ShowLoading(False)
|
|
|
|
if event.back == 0:
|
|
self.browseHist.append( (2,self._stage2Data) )
|
|
elif event.back == -1:
|
|
if len(self.navpanel.recentSearches)>0:
|
|
self.browseHist.append((4, self.navpanel.lastSearch))
|
|
|
|
shipID = event.shipID
|
|
self.lastdata = shipID
|
|
self._lastStage = self._activeStage
|
|
self._activeStage = 3
|
|
|
|
sFit = service.Fit.getInstance()
|
|
sMarket = service.Market.getInstance()
|
|
|
|
ship = sMarket.getItem(shipID)
|
|
categoryID = ship.group.ID
|
|
|
|
self.lpane.Freeze()
|
|
self.lpane.RemoveAllChildren()
|
|
fitList = sFit.getFitsWithShip(shipID)
|
|
|
|
if len(fitList) == 0:
|
|
stage,data = self.browseHist.pop()
|
|
self.lpane.Thaw()
|
|
self.navpanel.gotoStage(stage,data)
|
|
return
|
|
|
|
self.categoryFitCache[categoryID] = True
|
|
|
|
self.navpanel.ShowNewFitButton(True)
|
|
self.navpanel.ShowSwitchEmptyGroupsButton(False)
|
|
|
|
if self.showRacesFilterInStage2Only:
|
|
self.raceselect.Show(False)
|
|
self.Layout()
|
|
|
|
fitList.sort(key=self.nameKey)
|
|
shipName = ship.name
|
|
|
|
self._stage3ShipName = shipName
|
|
self._stage3Data = shipID
|
|
|
|
for ID, name, booster, timestamp in fitList:
|
|
self.lpane.AddWidget(FitItem(self.lpane, ID, (shipName, name, booster, timestamp),shipID))
|
|
|
|
self.lpane.RefreshList()
|
|
self.lpane.Thaw()
|
|
self.raceselect.RebuildRaces(self.RACE_ORDER)
|
|
|
|
def searchStage(self, event):
|
|
|
|
self.lpane.ShowLoading(False)
|
|
|
|
self.navpanel.ShowNewFitButton(False)
|
|
self.navpanel.ShowSwitchEmptyGroupsButton(False)
|
|
|
|
if not event.back:
|
|
if self._activeStage !=4:
|
|
if len(self.browseHist) >0:
|
|
self.browseHist.append( (self._activeStage, self.lastdata) )
|
|
else:
|
|
self.browseHist.append((1,0))
|
|
self._lastStage = self._activeStage
|
|
self._activeStage = 4
|
|
|
|
sMarket = service.Market.getInstance()
|
|
sFit = service.Fit.getInstance()
|
|
query = event.text
|
|
|
|
self.lpane.Freeze()
|
|
|
|
self.lpane.RemoveAllChildren()
|
|
if query:
|
|
ships = sMarket.searchShips(query)
|
|
fitList = sFit.searchFits(query)
|
|
|
|
for ship in ships:
|
|
self.lpane.AddWidget(ShipItem(self.lpane, ship.ID, (ship.name, len(sFit.getFitsWithShip(ship.ID))), ship.race))
|
|
|
|
for ID, name, shipID, shipName, booster, timestamp in fitList:
|
|
self.lpane.AddWidget(FitItem(self.lpane, ID, (shipName, name, booster, timestamp), shipID))
|
|
if len(ships) == 0 and len(fitList) == 0 :
|
|
self.lpane.AddWidget(PFStaticText(self.lpane, label = u"No matching results."))
|
|
self.lpane.RefreshList(doFocus = False)
|
|
self.lpane.Thaw()
|
|
|
|
self.raceselect.RebuildRaces(self.RACE_ORDER)
|
|
|
|
if self.showRacesFilterInStage2Only:
|
|
self.raceselect.Show(False)
|
|
self.Layout()
|
|
|
|
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())
|
|
|
|
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.EXPAND|wx.TOP, 10 )
|
|
self.SetSizer(mainSizer)
|
|
self.Layout()
|
|
def GetType(self):
|
|
return -1
|
|
|
|
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
|
|
|
|
class CategoryItem(SFItem.SFBrowserItem):
|
|
def __init__(self,parent, categoryID, fittingInfo, size = (0,16)):
|
|
SFItem.SFBrowserItem.__init__(self,parent,size = size)
|
|
|
|
if categoryID:
|
|
self.shipBmp = bitmapLoader.getBitmap("ship_small","icons")
|
|
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.FontFromPixelSize((0,15),wx.SWISS, wx.NORMAL, wx.NORMAL, False)
|
|
|
|
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()
|
|
|
|
def OUT_QUAD (self, 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
|
|
#===============================================================================
|
|
|
|
|
|
class ShipItem(SFItem.SFBrowserItem):
|
|
def __init__(self, parent, shipID=None, shipFittingInfo=("Test", 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.FontFromPixelSize((0,15),wx.SWISS, wx.NORMAL, wx.BOLD, False)
|
|
self.fontNormal = wx.FontFromPixelSize((0,14),wx.SWISS, wx.NORMAL, wx.NORMAL, False)
|
|
self.fontSmall = wx.FontFromPixelSize((0,12),wx.SWISS, wx.NORMAL, wx.NORMAL, False)
|
|
|
|
self.shipBmp = None
|
|
if shipID:
|
|
self.shipBmp = bitmapLoader.getBitmap(str(shipID),"ships")
|
|
if not self.shipBmp:
|
|
self.shipBmp = bitmapLoader.getBitmap("ship_no_image_big","icons")
|
|
|
|
self.shipFittingInfo = shipFittingInfo
|
|
self.shipName, self.shipFits = shipFittingInfo
|
|
|
|
self.newBmp = bitmapLoader.getBitmap("fit_add_small", "icons")
|
|
self.acceptBmp = bitmapLoader.getBitmap("faccept_small", "icons")
|
|
|
|
self.shipEffBk = bitmapLoader.getBitmap("fshipbk_big","icons")
|
|
|
|
img = wx.ImageFromBitmap(self.shipEffBk)
|
|
img = img.Mirror(False)
|
|
self.shipEffBkMirrored = wx.BitmapFromImage(img)
|
|
|
|
self.raceBmp = bitmapLoader.getBitmap("race_%s_small" % self.shipRace, "icons")
|
|
|
|
if not self.raceBmp:
|
|
self.raceBmp = bitmapLoader.getBitmap("fit_delete_small","icons")
|
|
|
|
self.raceDropShadowBmp = drawUtils.CreateDropShadowBitmap(self.raceBmp, 0.2)
|
|
|
|
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 = service.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 = []
|
|
contexts.append(("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()
|
|
|
|
def OUT_QUAD (self, 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, fittings = self.shipFittingInfo
|
|
if fittings > 0:
|
|
wx.PostEvent(self.shipBrowser,Stage3Selected(shipID=self.shipID, back = -1 if self.shipBrowser.GetActiveStage() == 4 else 0))
|
|
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 = service.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.toolbarx + self.animCount
|
|
|
|
self.shipEffx = self.padding + (rect.height - self.shipEffBk.GetWidth())/2
|
|
self.shipEffy = (rect.height - self.shipEffBk.GetHeight())/2
|
|
|
|
self.shipEffx = 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.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, 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, fittings = self.shipFittingInfo
|
|
|
|
if fittings <1:
|
|
fformat = "No fits"
|
|
else:
|
|
if 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))
|
|
|
|
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)
|
|
|
|
|
|
class FitItem(SFItem.SFBrowserItem):
|
|
def __init__(self, parent, fitID=None, shipFittingInfo=("Test", "cnc's avatar", 0, 0 ), 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
|
|
|
|
# @todo: replace all getActiveFit() in class with this variable and test
|
|
self.activeFit = self.mainFrame.getActiveFit()
|
|
|
|
if shipID:
|
|
self.shipBmp = bitmapLoader.getBitmap(str(shipID),"ships")
|
|
|
|
if not self.shipBmp:
|
|
self.shipBmp = bitmapLoader.getBitmap("ship_no_image_big","icons")
|
|
|
|
self.shipFittingInfo = shipFittingInfo
|
|
self.shipName, self.fitName, self.fitBooster, self.timestamp = shipFittingInfo
|
|
|
|
# access these by index based on toggle for booster fit
|
|
|
|
self.fitMenu = wx.Menu()
|
|
self.toggleItem = self.fitMenu.Append(-1, "Booster Fit", kind=wx.ITEM_CHECK)
|
|
self.fitMenu.Check(self.toggleItem.GetId(), self.fitBooster)
|
|
self.Bind(wx.EVT_MENU, self.OnPopupItemSelected, self.toggleItem)
|
|
|
|
if self.activeFit:
|
|
# If there is an active fit, get menu for setting individual boosters
|
|
self.fitMenu.AppendSeparator()
|
|
boosterMenu = self.mainFrame.additionsPane.gangPage.FitDNDPopupMenu
|
|
self.fitMenu.AppendMenu(wx.ID_ANY, 'Set Booster', boosterMenu)
|
|
|
|
self.boosterBmp = bitmapLoader.getBitmap("fleet_fc_small", "icons")
|
|
self.copyBmp = bitmapLoader.getBitmap("fit_add_small", "icons")
|
|
self.renameBmp = bitmapLoader.getBitmap("fit_rename_small", "icons")
|
|
self.deleteBmp = bitmapLoader.getBitmap("fit_delete_small","icons")
|
|
self.acceptBmp = bitmapLoader.getBitmap("faccept_small", "icons")
|
|
|
|
self.shipEffBk = bitmapLoader.getBitmap("fshipbk_big","icons")
|
|
|
|
img = wx.ImageFromBitmap(self.shipEffBk)
|
|
img = img.Mirror(False)
|
|
self.shipEffBkMirrored = wx.BitmapFromImage(img)
|
|
|
|
self.dragTLFBmp = None
|
|
|
|
self.bkBitmap = None
|
|
|
|
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.FontFromPixelSize((0,15),wx.SWISS, wx.NORMAL, wx.BOLD, False)
|
|
self.fontNormal = wx.FontFromPixelSize((0,14),wx.SWISS, wx.NORMAL, wx.NORMAL, False)
|
|
self.fontSmall = wx.FontFromPixelSize((0,12),wx.SWISS, wx.NORMAL, wx.NORMAL, False)
|
|
|
|
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.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
|
|
#=======================================================================
|
|
|
|
self.selTimerID = wx.NewId()
|
|
|
|
self.selTimer = wx.Timer(self,self.selTimerID)
|
|
self.selTimer.Start(100)
|
|
|
|
self.Bind(wx.EVT_RIGHT_UP, self.OnContextMenu)
|
|
|
|
def OnPopupItemSelected(self, event):
|
|
''' Fires when fit menu item is selected '''
|
|
# currently only have one menu option (toggle booster)
|
|
sFit = service.Fit.getInstance()
|
|
sFit.toggleBoostFit(self.fitID)
|
|
self.fitBooster = not self.fitBooster
|
|
self.boosterBtn.Show(self.fitBooster)
|
|
self.fitMenu.Check(self.toggleItem.GetId(), self.fitBooster)
|
|
wx.PostEvent(self.mainFrame, BoosterListUpdated())
|
|
event.Skip()
|
|
|
|
def OnContextMenu(self, event):
|
|
''' Handles context menu for fit. Dragging is handled by MouseLeftUp() '''
|
|
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
|
|
self.PopupMenu(self.fitMenu, pos)
|
|
|
|
event.Skip()
|
|
|
|
def GetType(self):
|
|
return 3
|
|
|
|
def OnTimer(self, event):
|
|
|
|
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()
|
|
|
|
def CalculateDelta(self, start, end, delta):
|
|
return start + (end-start)*delta
|
|
|
|
def OUT_QUAD (self, 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 = service.Fit.getInstance()
|
|
fitID = sFit.copyFit(self.fitID)
|
|
self.shipBrowser.fitIDMustEditName = fitID
|
|
wx.PostEvent(self.shipBrowser,Stage3Selected(shipID=self.shipID, back=True))
|
|
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 = service.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))
|
|
self.Refresh()
|
|
else:
|
|
self.tcFitName.SetValue(self.fitName)
|
|
|
|
def deleteBtnCB(self):
|
|
if self.tcFitName.IsShown():
|
|
self.RestoreEditButton()
|
|
return
|
|
|
|
self.deleteFit()
|
|
|
|
def deleteFit(self, event=None):
|
|
if self.deleted:
|
|
return
|
|
else:
|
|
self.deleted = True
|
|
|
|
sFit = service.Fit.getInstance()
|
|
|
|
sFit.deleteFit(self.fitID)
|
|
|
|
if 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, back=True))
|
|
|
|
wx.PostEvent(self.mainFrame, FitRemoved(fitID=self.fitID))
|
|
|
|
def MouseLeftUp(self, event):
|
|
|
|
if self.dragging and self.dragged:
|
|
self.dragging = False
|
|
self.dragged = False
|
|
if self.HasCapture():
|
|
self.ReleaseMouse()
|
|
self.dragWindow.Show(False)
|
|
self.dragWindow = None
|
|
|
|
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:
|
|
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):
|
|
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.toolbarx + self.animCount
|
|
|
|
self.shipEffx = self.padding + (rect.height - self.shipEffBk.GetWidth())/2
|
|
self.shipEffy = (rect.height - self.shipEffBk.GetHeight())/2
|
|
|
|
self.shipEffx = 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.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)
|
|
|
|
shipName, fittings, booster, timestamp = self.shipFittingInfo
|
|
|
|
mdc.SetFont(self.fontNormal)
|
|
|
|
fitDate = time.localtime(self.timestamp)
|
|
fitLocalDate = "%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)
|
|
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 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
|
|
|