From da9816d1bd3329be6392e5cb5bb6a7c613b84206 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Thu, 13 Apr 2017 20:02:20 -0400 Subject: [PATCH] Implement character skill searching --- eos/db/gamedata/queries.py | 16 ++++++++++ gui/characterEditor.py | 61 +++++++++++++++++++++++++++++++++++++- service/character.py | 9 ++++++ 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/eos/db/gamedata/queries.py b/eos/db/gamedata/queries.py index 30f51fe6b3..70d2997e8b 100644 --- a/eos/db/gamedata/queries.py +++ b/eos/db/gamedata/queries.py @@ -249,6 +249,22 @@ def searchItems(nameLike, where=None, join=None, eager=None): return items +@cachedQuery(3, "where", "nameLike", "join") +def searchSkills(nameLike, where=None, eager=None): + if not isinstance(nameLike, basestring): + raise TypeError("Need string as argument") + + items = gamedata_session.query(Item).options(*processEager(eager)).join(Item.group, Group.category) + for token in nameLike.split(' '): + token_safe = u"%{0}%".format(sqlizeString(token)) + if where is not None: + items = items.filter(and_(Item.name.like(token_safe, escape="\\"), Category.ID == 16, where)) + else: + items = items.filter(and_(Item.name.like(token_safe, escape="\\"), Category.ID == 16)) + items = items.limit(100).all() + return items + + @cachedQuery(2, "where", "itemids") def getVariations(itemids, groupIDs=None, where=None, eager=None): for itemid in itemids: diff --git a/gui/characterEditor.py b/gui/characterEditor.py index 8006fa56a7..ff56133459 100644 --- a/gui/characterEditor.py +++ b/gui/characterEditor.py @@ -63,6 +63,28 @@ def Validate(self, win): return False +class PlaceholderTextCtrl(wx.TextCtrl): + def __init__(self, *args, **kwargs): + self.default_text = kwargs.pop("placeholder", "") + kwargs["value"] = self.default_text + wx.TextCtrl.__init__(self, *args, **kwargs) + self.Bind(wx.EVT_SET_FOCUS, self.OnFocus) + self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) + + def OnFocus(self, evt): + if self.GetValue() == self.default_text: + self.SetValue("") + evt.Skip() + + def OnKillFocus(self, evt): + if self.GetValue().strip() == "": + self.SetValue(self.default_text) + evt.Skip() + + def Reset(self): + self.SetValue(self.default_text) + + class CharacterEntityEditor(EntityEditor): def __init__(self, parent): EntityEditor.__init__(self, parent, "Character") @@ -252,10 +274,16 @@ def __init__(self, parent): pmainSizer = wx.BoxSizer(wx.VERTICAL) + hSizer = wx.BoxSizer(wx.HORIZONTAL) + self.clonesChoice = wx.Choice(self, wx.ID_ANY, style=0) i = self.clonesChoice.Append("Omega Clone", None) self.clonesChoice.SetSelection(i) - pmainSizer.Add(self.clonesChoice, 0, wx.ALL | wx.EXPAND, 5) + hSizer.Add(self.clonesChoice, 5, wx.ALL | wx.EXPAND, 5) + + self.searchInput = PlaceholderTextCtrl(self, wx.ID_ANY, placeholder="Search...") + hSizer.Add(self.searchInput, 1, wx.ALL | wx.EXPAND, 5) + self.searchInput.Bind(wx.EVT_TEXT, self.delaySearch) sChar = Character.getInstance() self.alphaClones = sChar.getAlphaCloneList() @@ -268,6 +296,12 @@ def __init__(self, parent): self.clonesChoice.Bind(wx.EVT_CHOICE, self.cloneChanged) + pmainSizer.Add(hSizer, 0, wx.EXPAND | wx.ALL, 5) + + # Set up timer for skill search + self.searchTimer = wx.Timer(self) + self.Bind(wx.EVT_TIMER, self.populateSkillTreeSkillSearch, self.searchTimer) + tree = self.skillTreeListCtrl = wx.gizmos.TreeListCtrl(self, wx.ID_ANY, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT) pmainSizer.Add(tree, 1, wx.EXPAND | wx.ALL, 5) @@ -322,12 +356,20 @@ def __init__(self, parent): self.Layout() + def delaySearch(self, evt): + if self.searchInput.GetValue() == "" or self.searchInput.GetValue() == self.searchInput.default_text: + self.populateSkillTree() + else: + self.searchTimer.Stop() + self.searchTimer.Start(150, True) # 150ms + def cloneChanged(self, event): sChar = Character.getInstance() sChar.setAlphaClone(self.charEditor.entityEditor.getActiveEntity(), event.ClientData) self.populateSkillTree() def charChanged(self, event=None): + self.searchInput.Reset() char = self.charEditor.entityEditor.getActiveEntity() for i in range(self.clonesChoice.GetCount()): cloneID = self.clonesChoice.GetClientData(i) @@ -336,6 +378,23 @@ def charChanged(self, event=None): self.populateSkillTree(event) + def populateSkillTreeSkillSearch(self, event=None): + sChar = Character.getInstance() + char = self.charEditor.entityEditor.getActiveEntity() + search = self.searchInput.GetLineText(0) + + root = self.root + tree = self.skillTreeListCtrl + tree.DeleteChildren(root) + + for id, name in sChar.getSkillsByName(search): + iconId = self.skillBookImageId + childId = tree.AppendItem(root, name, iconId, data=wx.TreeItemData(id)) + level, dirty = sChar.getSkillLevel(char.ID, id) + tree.SetItemText(childId, "Level %d" % level if isinstance(level, int) else level, 1) + if dirty: + tree.SetItemTextColour(childId, wx.BLUE) + def populateSkillTree(self, event=None): sChar = Character.getInstance() char = self.charEditor.entityEditor.getActiveEntity() diff --git a/service/character.py b/service/character.py index 1e5185b699..43d603f1f6 100644 --- a/service/character.py +++ b/service/character.py @@ -272,6 +272,15 @@ def getSkills(groupID): skills.append((skill.ID, skill.name)) return skills + @staticmethod + def getSkillsByName(text): + items = eos.db.searchSkills(text) + skills = [] + for skill in items: + if skill.published is True: + skills.append((skill.ID, skill.name)) + return skills + @staticmethod def setAlphaClone(char, cloneID): char.alphaCloneID = cloneID