Initial GUI commit. Still need to actually handle the attribute change
This commit is contained in:
@@ -422,6 +422,9 @@ def getOverrides(itemID, eager=None):
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
def getAllOverrides(eager=None):
|
||||
return saveddata_session.query(Override).all()
|
||||
|
||||
def removeInvalid(fits):
|
||||
invalids = [f for f in fits if f.isInvalid]
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ TextTyped, EVT_TEXT = wx.lib.newevent.NewEvent()
|
||||
|
||||
class PFSearchBox(wx.Window):
|
||||
def __init__(self, parent, id = wx.ID_ANY, value = "", pos = wx.DefaultPosition, size = wx.Size(-1,24), style = 0):
|
||||
wx.Window.__init__(self, parent, id, pos, size, style = 0)
|
||||
wx.Window.__init__(self, parent, id, pos, size, style = style)
|
||||
|
||||
self.isSearchButtonVisible = False
|
||||
self.isCancelButtonVisible = False
|
||||
|
||||
@@ -53,6 +53,7 @@ from gui.copySelectDialog import CopySelectDialog
|
||||
from gui.utils.clipboard import toClipboard, fromClipboard
|
||||
from gui.fleetBrowser import FleetBrowser
|
||||
from gui.updateDialog import UpdateDialog
|
||||
from gui.propertyEditor import AttributeEditor
|
||||
from gui.builtinViews import *
|
||||
|
||||
from time import gmtime, strftime
|
||||
@@ -329,6 +330,10 @@ class MainFrame(wx.Frame):
|
||||
dlg=CharacterEditor(self)
|
||||
dlg.Show()
|
||||
|
||||
def showAttrEditor(self, event):
|
||||
dlg=AttributeEditor(self)
|
||||
dlg.Show()
|
||||
|
||||
def showTargetResistsEditor(self, event):
|
||||
dlg=ResistsEditorDlg(self)
|
||||
dlg.ShowModal()
|
||||
@@ -416,6 +421,8 @@ class MainFrame(wx.Frame):
|
||||
self.Bind(wx.EVT_MENU, self.saveCharAs, id = menuBar.saveCharAsId)
|
||||
# Save current character
|
||||
self.Bind(wx.EVT_MENU, self.revertChar, id = menuBar.revertCharId)
|
||||
# Open attribute editor
|
||||
self.Bind(wx.EVT_MENU, self.showAttrEditor, id = menuBar.attrEditor)
|
||||
|
||||
#Clipboard exports
|
||||
self.Bind(wx.EVT_MENU, self.exportToClipboard, id=wx.ID_COPY)
|
||||
|
||||
@@ -40,6 +40,7 @@ class MainMenuBar(wx.MenuBar):
|
||||
self.saveCharId = wx.NewId()
|
||||
self.saveCharAsId = wx.NewId()
|
||||
self.revertCharId = wx.NewId()
|
||||
self.attrEditor = wx.NewId()
|
||||
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
@@ -102,6 +103,10 @@ class MainMenuBar(wx.MenuBar):
|
||||
preferencesItem.SetBitmap(BitmapLoader.getBitmap("preferences_small", "gui"))
|
||||
windowMenu.AppendItem(preferencesItem)
|
||||
|
||||
attrItem = wx.MenuItem(windowMenu, self.attrEditor, "Attribute Editor\tCTRL+A")
|
||||
attrItem.SetBitmap(BitmapLoader.getBitmap("preferences_small", "gui"))
|
||||
windowMenu.AppendItem(attrItem)
|
||||
|
||||
# Help menu
|
||||
helpMenu = wx.Menu()
|
||||
self.Append(helpMenu, "&Help")
|
||||
|
||||
@@ -103,8 +103,8 @@ class MarketBrowser(wx.Panel):
|
||||
self.marketView.jump(item)
|
||||
|
||||
class SearchBox(SBox.PFSearchBox):
|
||||
def __init__(self, parent):
|
||||
SBox.PFSearchBox.__init__(self, parent)
|
||||
def __init__(self, parent, **kwargs):
|
||||
SBox.PFSearchBox.__init__(self, parent, **kwargs)
|
||||
cancelBitmap = BitmapLoader.getBitmap("fit_delete_small","gui")
|
||||
searchBitmap = BitmapLoader.getBitmap("fsearch_small","gui")
|
||||
self.SetSearchBitmap(searchBitmap)
|
||||
|
||||
136
gui/propertyEditor.py
Normal file
136
gui/propertyEditor.py
Normal file
@@ -0,0 +1,136 @@
|
||||
import wx
|
||||
import wx.propgrid as wxpg
|
||||
import eos.db
|
||||
|
||||
import gui.PFSearchBox as SBox
|
||||
from gui.marketBrowser import SearchBox
|
||||
import gui.display as d
|
||||
import service
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class AttributeEditor( wx.Frame ):
|
||||
|
||||
def __init__( self, parent ):
|
||||
wx.Frame.__init__(self, parent, wx.ID_ANY, title="Attribute Editor", size=wx.Size(700,500))
|
||||
|
||||
self.panel = panel = wx.Panel(self, wx.ID_ANY)
|
||||
topsizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
leftsizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
self.searchBox = SearchBox(panel, style=wx.DOUBLE_BORDER if 'wxMSW' in wx.PlatformInfo else wx.SIMPLE_BORDER)
|
||||
self.itemView = ItemView(panel)
|
||||
self.pg = AttributeGrid(panel)
|
||||
|
||||
topsizer.Add(leftsizer, 1, wx.ALL|wx.EXPAND, 5)
|
||||
topsizer.Add(self.pg, 1, wx.ALL|wx.EXPAND, 5)
|
||||
|
||||
leftsizer.Add(self.searchBox, 0, wx.EXPAND)
|
||||
leftsizer.Add(self.itemView, 1, wx.EXPAND)
|
||||
|
||||
panel.SetSizer(topsizer)
|
||||
topsizer.SetSizeHints(panel)
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(panel, 1, wx.EXPAND)
|
||||
self.SetSizer(sizer)
|
||||
self.SetAutoLayout(True)
|
||||
|
||||
|
||||
# This is literally a stripped down version of the market.
|
||||
class ItemView(d.Display):
|
||||
DEFAULT_COLS = ["Base Icon",
|
||||
"Base Name",
|
||||
"attr:power,,,True",
|
||||
"attr:cpu,,,True"]
|
||||
|
||||
def __init__(self, parent):
|
||||
d.Display.__init__(self, parent)
|
||||
self.parent = parent
|
||||
sMkt = service.Market.getInstance()
|
||||
self.things = sMkt.getItemsWithOverrides()
|
||||
self.items = self.things
|
||||
|
||||
# Bind search actions
|
||||
parent.Parent.searchBox.Bind(SBox.EVT_TEXT_ENTER, self.scheduleSearch)
|
||||
parent.Parent.searchBox.Bind(SBox.EVT_SEARCH_BTN, self.scheduleSearch)
|
||||
parent.Parent.searchBox.Bind(SBox.EVT_CANCEL_BTN, self.clearSearch)
|
||||
parent.Parent.searchBox.Bind(SBox.EVT_TEXT, self.scheduleSearch)
|
||||
|
||||
self.update(self.items)
|
||||
|
||||
def clearSearch(self, event=None):
|
||||
if event:
|
||||
self.parent.Parent.searchBox.Clear()
|
||||
self.items = self.things
|
||||
self.update(self.items)
|
||||
|
||||
def scheduleSearch(self, event=None):
|
||||
sMkt = service.Market.getInstance()
|
||||
|
||||
search = self.parent.Parent.searchBox.GetLineText(0)
|
||||
# Make sure we do not count wildcard as search symbol
|
||||
realsearch = search.replace("*", "")
|
||||
# Show nothing if query is too short
|
||||
if len(realsearch) < 3:
|
||||
self.clearSearch()
|
||||
return
|
||||
|
||||
self.parent.searchMode = True
|
||||
sMkt.searchItems(search, self.populateSearch, False)
|
||||
|
||||
def populateSearch(self, items):
|
||||
self.items = list(items)
|
||||
self.update(items)
|
||||
|
||||
|
||||
class AttributeGrid(wxpg.PropertyGrid):
|
||||
|
||||
def __init__(self, parent):
|
||||
wxpg.PropertyGrid.__init__(self, parent, style=wxpg.PG_HIDE_MARGIN|wxpg.PG_HIDE_CATEGORIES|wxpg.PG_BOLD_MODIFIED|wxpg.PG_TOOLTIPS)
|
||||
self.parent = parent
|
||||
|
||||
self.Bind( wxpg.EVT_PG_CHANGED, self.OnPropGridChange )
|
||||
self.Bind( wxpg.EVT_PG_SELECTED, self.OnPropGridSelect )
|
||||
self.Bind( wxpg.EVT_PG_RIGHT_CLICK, self.OnPropGridRightClick )
|
||||
|
||||
parent.Parent.itemView.Bind(wx.EVT_LIST_ITEM_SELECTED, self.itemActivated)
|
||||
parent.Parent.itemView.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.itemActivated)
|
||||
|
||||
def itemActivated(self, event):
|
||||
self.Clear()
|
||||
sel = event.EventObject.GetFirstSelected()
|
||||
item = self.parent.Parent.itemView.items[sel]
|
||||
|
||||
for key in sorted(item.attributes.keys()):
|
||||
override = item.overrides.get(key, None)
|
||||
default = item.attributes[key].value
|
||||
if override and override != item.attributes[key].value:
|
||||
prop = wxpg.FloatProperty(key, value=override)
|
||||
prop.defaultValue = default
|
||||
prop.SetModifiedStatus(True)
|
||||
else:
|
||||
prop = wxpg.FloatProperty(key, value=default)
|
||||
|
||||
self.Append(prop)
|
||||
|
||||
def OnPropGridChange(self, event):
|
||||
p = event.GetProperty()
|
||||
if p:
|
||||
logger.debug('%s changed to "%s"' % (p.GetName(), p.GetValueAsString()))
|
||||
|
||||
def OnPropGridSelect(self, event):
|
||||
p = event.GetProperty()
|
||||
if p:
|
||||
logger.debug('%s selected' % (event.GetProperty().GetName()))
|
||||
else:
|
||||
logger.debug('Nothing selected')
|
||||
|
||||
def OnPropGridRightClick(self, event):
|
||||
p = event.GetProperty()
|
||||
if p:
|
||||
logger.debug('%s right clicked' % (event.GetProperty().GetName()))
|
||||
else:
|
||||
logger.debug('Nothing right clicked')
|
||||
@@ -116,12 +116,15 @@ class SearchWorkerThread(threading.Thread):
|
||||
while self.searchRequest is None:
|
||||
cv.wait()
|
||||
|
||||
request, callback = self.searchRequest
|
||||
request, callback, filterOn = self.searchRequest
|
||||
self.searchRequest = None
|
||||
cv.release()
|
||||
sMkt = Market.getInstance()
|
||||
# Rely on category data provided by eos as we don't hardcode them much in service
|
||||
filter = eos.types.Category.name.in_(sMkt.SEARCH_CATEGORIES)
|
||||
if filterOn:
|
||||
# Rely on category data provided by eos as we don't hardcode them much in service
|
||||
filter = eos.types.Category.name.in_(sMkt.SEARCH_CATEGORIES)
|
||||
else:
|
||||
filter=None
|
||||
results = eos.db.searchItems(request, where=filter,
|
||||
join=(eos.types.Item.group, eos.types.Group.category),
|
||||
eager=("icon", "group.category", "metaGroup", "metaGroup.parent"))
|
||||
@@ -133,9 +136,9 @@ class SearchWorkerThread(threading.Thread):
|
||||
items.add(item)
|
||||
wx.CallAfter(callback, items)
|
||||
|
||||
def scheduleSearch(self, text, callback):
|
||||
def scheduleSearch(self, text, callback, filterOn=True):
|
||||
self.cv.acquire()
|
||||
self.searchRequest = (text, callback)
|
||||
self.searchRequest = (text, callback, filterOn)
|
||||
self.cv.notify()
|
||||
self.cv.release()
|
||||
|
||||
@@ -665,9 +668,16 @@ class Market():
|
||||
ships.add(item)
|
||||
return ships
|
||||
|
||||
def searchItems(self, name, callback):
|
||||
def searchItems(self, name, callback, filterOn=True):
|
||||
"""Find items according to given text pattern"""
|
||||
self.searchWorkerThread.scheduleSearch(name, callback)
|
||||
self.searchWorkerThread.scheduleSearch(name, callback, filterOn)
|
||||
|
||||
def getItemsWithOverrides(self):
|
||||
overrides = eos.db.getAllOverrides()
|
||||
items = set()
|
||||
for x in overrides:
|
||||
items.add(x.item)
|
||||
return list(items)
|
||||
|
||||
def directAttrRequest(self, items, attribs):
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user