Skip to content

Commit

Permalink
Improve search UIX
Browse files Browse the repository at this point in the history
* Each search indices can be set
* Set indices appear as a button
* clicking the button removes the indices
  • Loading branch information
bicobus committed Jan 6, 2024
1 parent be071f9 commit f9f33d7
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 31 deletions.
23 changes: 20 additions & 3 deletions src/pycestorieseditor/pil2wx.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,16 @@ def create_icon(color=None):
color = "#2ecc71"
img = Image.new('RGBA', (16, 16))
draw = ImageDraw.Draw(img)
draw.rectangle([(1, 1), (14, 14)], fill=color, outline="black")
draw.rectangle(((1, 1), (14, 14)), fill=color, outline="black")
return img


def pil_create_x():
img = Image.new('RGBA', (16, 16))
draw = ImageDraw.Draw(img)
draw.ellipse((1, 1, 15, 15), fill="#ECECEC", outline="#8C8C8C")
draw.line((4, 4, 11, 11), width=2, fill="black")
draw.line((12, 4, 4, 12), fill="black")
return img


Expand All @@ -23,12 +32,12 @@ def default_background():
img = Image.new('RGBA', (445, 805))
draw = ImageDraw.Draw(img)

draw.rectangle([(0, 0), (445, 805)], fill="#ECECEC")
draw.rectangle(((0, 0), (445, 805)), fill="#ECECEC")

for x, y in matrice:
draw.line([(-10, x), (y, -10)], fill="#8C8C8C", width=10)

draw.rectangle([(0, 0), (444, 804)], fill=None, outline="black")
draw.rectangle(((0, 0), (444, 804)), fill=None, outline="black")
return wximage2bitmap(pil2wximage(img))


Expand All @@ -46,3 +55,11 @@ def pil2wximage(img: Image.Image):

def wximage2bitmap(img):
return img.ConvertToBitmap()


def wxicon(color=None):
return wximage2bitmap(pil2wximage(create_icon(color)))


def wxcloseicon():
return wximage2bitmap(pil2wximage(pil_create_x()))
132 changes: 104 additions & 28 deletions src/pycestorieseditor/wxui.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import os
import re
from collections import namedtuple
from contextlib import suppress
from dataclasses import dataclass
from functools import lru_cache
Expand All @@ -20,18 +21,36 @@
from pygments.styles import get_style_by_name
from wx import stc
from wx.lib import expando
from wx.lib import buttons
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin, ColumnSorterMixin

from pycestorieseditor import APPNAME
from pycestorieseditor.ceevents import (
get_ebucket, Ceevent, init_xsdfile, process_module, CePath, create_ebucket,
scan_for_images, create_imgbucket, get_imgbucket, init_index, get_indexes,
get_ebucket,
Ceevent,
init_xsdfile,
process_module,
CePath,
create_ebucket,
scan_for_images,
create_imgbucket,
get_imgbucket,
init_index,
get_indexes,
)
from pycestorieseditor.ceevents_template import (
RestrictedListOfFlagsType, Options, Option,
RestrictedListOfConsequencesValue, ceevents_modal, MenuOption, MenuOptions,
RestrictedListOfFlagsType,
Options,
Option,
RestrictedListOfConsequencesValue,
ceevents_modal,
MenuOption,
MenuOptions,
)
from pycestorieseditor.pil2wx import (
hex2rgb,
wxicon,
)
from pycestorieseditor.pil2wx import hex2rgb, create_icon, pil2wximage, wximage2bitmap

style = get_style_by_name("default")

Expand Down Expand Up @@ -1332,12 +1351,22 @@ def __init__(self, parent, text, color, *args, **kwargs):
super().__init__(*args, **kwargs)
self._text = text
self._color = color
img = wx.StaticBitmap(parent, wx.ID_ANY, wximage2bitmap(pil2wximage(create_icon(color))))
img = wx.StaticBitmap(parent, wx.ID_ANY, wxicon(color))
label = wx.StaticText(parent, wx.ID_ANY, label=text)
self.Add(img, 0, wx.ALIGN_CENTER_VERTICAL, 0)
self.Add(label, 0, wx.EXPAND, 0)


class SearchIndice(wx.BoxSizer):
def __init__(self, parent, term, *args, **kwargs):
super().__init__(*args, **kwargs)
self.term = term
self.text = f"{term[0]: {term[1]}}" if term[0] else f"{term[2]}"
bmp = wx.ArtProvider.GetBitmap(wx.ART_CLOSE, wx.ART_OTHER, (16, 16))
self.b = buttons.ThemedGenBitmapTextButton(parent, wx.ID_ANY, bmp, self.text)
self.Add(self.b, 0, wx.EXPAND, 0)


class CeListItem(wx.ListItem):
def __init__(self, item, wxid: int):
super().__init__()
Expand Down Expand Up @@ -1386,6 +1415,7 @@ def _filter_skillid(skill, stack: list[Ceevent]):


search = re.compile(r"""(?:(?P<tag>text|skill):"(?P<value>[^"]+)")+|(\w+)""")
indice = namedtuple("indice", "iid term button")


class MainWindow(wx.Frame):
Expand All @@ -1395,6 +1425,8 @@ def __init__(self, conffile, *args, **kwds):
self._conffile = conffile
self._load_conf()

self._indices: list[indice] = []

self.Center()
self.SetSizeHints(800, 400, 800, 600)

Expand All @@ -1414,11 +1446,15 @@ def __init__(self, conffile, *args, **kwds):
)
self.panel_search = wx.Panel(self.window_1_pane_1, wx.ID_ANY, style=wx.BORDER_SIMPLE)
self.panel_search.SetMinSize((240, -1))
self.panel_search_indices = wx.StaticBox(
self.window_1_pane_1, wx.ID_ANY, "Search indices"
)

topsizer = wx.BoxSizer(wx.VERTICAL)
leftsizer = wx.BoxSizer(wx.VERTICAL)
self.leftsizer = wx.BoxSizer(wx.VERTICAL)
legendsizer = wx.WrapSizer(wx.HORIZONTAL)
searchsizer = wx.BoxSizer(wx.HORIZONTAL)
self.indicessizer = wx.WrapSizer(wx.HORIZONTAL)
rightsizer = wx.BoxSizer(wx.VERTICAL)

# - Legend ---
Expand Down Expand Up @@ -1450,21 +1486,27 @@ def __init__(self, conffile, *args, **kwds):
self.celb = CeListBox(self.window_1_pane_2, wx.ID_ANY, cb=self.cb_toggle_enable)

topsizer.Add(self.window_1, 1, wx.EXPAND | wx.FIXED_MINSIZE, 0)
leftsizer.Add(self.panel_leg, 2, wx.EXPAND | wx.ALL, 5)

self.leftsizer.Add(self.panel_leg, 2, wx.EXPAND | wx.ALL, 5)
legendsizer.Add(lg_one, 0, wx.EXPAND | wx.LEFT, 5)
legendsizer.Add(lg_two, 0, wx.EXPAND | wx.LEFT, 5)
leftsizer.Add(self.panel_search, 0, wx.EXPAND | wx.ALL, 0)

self.leftsizer.Add(self.panel_search_indices, 1, wx.EXPAND | wx.ALL, 5)

self.leftsizer.Add(self.panel_search, 0, wx.EXPAND | wx.ALL, 0)
searchsizer.Add(searchlbl, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 4)
searchsizer.Add(
self.searchent, 1, wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.FIXED_MINSIZE, 0
)
searchsizer.Add(searchbnt, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 1)

rightsizer.Add(self.celb, 1, wx.EXPAND, 0)

self.window_1_pane_2.SetSizer(rightsizer)
self.panel_search.SetSizer(searchsizer)
self.panel_search_indices.SetSizer(self.indicessizer)
self.panel_leg.SetSizer(legendsizer)
self.window_1_pane_1.SetSizer(leftsizer)
self.window_1_pane_1.SetSizer(self.leftsizer)
self.window_1.SplitVertically(self.window_1_pane_1, self.window_1_pane_2, 200)
self.panel_1.SetSizer(topsizer)

Expand All @@ -1473,6 +1515,7 @@ def __init__(self, conffile, *args, **kwds):
self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.celb.on_clicked_event, self.celb)
self.Bind(wx.EVT_BUTTON, self.on_reset_event, searchbnt)
self.Bind(wx.EVT_TEXT, self.on_text_event, self.searchent)
self.Bind(wx.EVT_SEARCH, self.on_text_enter_event, self.searchent)
self.Bind(wx.EVT_SEARCH_CANCEL, self.on_reset_event, self.searchent)

def cb_toggle_enable(self):
Expand Down Expand Up @@ -1502,36 +1545,69 @@ def _load_conf(self):
def on_reset_event(self, event):
if event.EventType != wx.EVT_SEARCH_CANCEL.typeId: # not EVT_BUTTON
self.searchent.SetValue("")
for item in self.indicessizer.GetChildren():
widget = item.Sizer
self.indicessizer.Hide(widget)
self.indicessizer.Remove(widget)
self._indices = []
self.celb.populate()
event.Skip()

def on_text_event(self, event):
if self.searchent.IsEmpty() or len(self.searchent.Value) < 3:
event.Skip()
return

names = []
def build_constraints_and_populate(self, with_search_value=True):
filterstr = []
constraints = []
for term in search.findall(self.searchent.Value):
match term:
if with_search_value:
indices = chain(self._indices, search.findall(self.searchent.Value))
else:
indices = self._indices
for ind in indices:
match ind.term if isinstance(ind, indice) else ind:
case ("text", value, ""):
constraints.append((_filter_text, value))
case ("skill", value, ""):
constraints.append((_filter_skillid, value))
case ("", "", value):
names.append(value)
filterstr.append(value)

filterstr = " ".join(names)
ebucket = get_ebucket()
items = ebucket.values()
if constraints:
for c, value in constraints:
items = c(value, items)
if filterstr:
items = filter(lambda x: filterstr in x.name.value, ebucket.values())
else:
if not constraints:
event.Skip()
return
items = ebucket.values()
for c, value in constraints:
items = c(value, items)
for string in filterstr:
items = list(filter(lambda x: string in x.name.value, items))

self.celb.populate(list(items))

def on_remove_indice(self, event):
i: indice = list(filter(lambda x: event.EventObject is x.button, self._indices))[0]
for j, item in enumerate(self.indicessizer.GetChildren()):
if item is i.iid:
widget = item.Sizer
self.indicessizer.Hide(widget)
self.indicessizer.Remove(widget)
self._indices.pop(self._indices.index(i))
self.searchent.SetFocus()
self.leftsizer.Layout()
self.panel_search_indices.FitInside()
self.build_constraints_and_populate(with_search_value=False)

def on_text_enter_event(self, event):
for term in search.findall(self.searchent.Value):
lbl = SearchIndice(self.panel_search_indices, term)
iid = self.indicessizer.Add(lbl, 0, wx.EXPAND | wx.LEFT, 5)
self.Bind(wx.EVT_BUTTON, self.on_remove_indice, lbl.b)
self._indices.append(indice(iid, lbl.term, lbl.b))
self.leftsizer.Layout()
self.panel_search_indices.FitInside()
self.searchent.Clear()
self.searchent.SetFocus()

def on_text_event(self, event):
if self.searchent.IsEmpty() or len(self.searchent.Value) < 3:
event.Skip()
return

self.build_constraints_and_populate()
event.Skip()

0 comments on commit f9f33d7

Please sign in to comment.