Docs: screenshots and full label designer guide; icon category tabs
- README: overview, installation, designer walkthrough with light/dark screenshots and sample output, library usage, D101 pairing note - Emoji picker tabs use emoji icons so the sidebar fits at 1280px; file actions and theme toggle move to the bottom bar
This commit is contained in:
+50
-33
@@ -51,16 +51,17 @@ LABEL_PRESETS = [
|
||||
("Custom", None, None),
|
||||
]
|
||||
|
||||
# (tab label, emoji-data category, tab icon)
|
||||
EMOJI_CATEGORIES = [
|
||||
("Smileys", "Smileys & Emotion"),
|
||||
("People", "People & Body"),
|
||||
("Animals", "Animals & Nature"),
|
||||
("Food", "Food & Drink"),
|
||||
("Travel", "Travel & Places"),
|
||||
("Activities", "Activities"),
|
||||
("Objects", "Objects"),
|
||||
("Symbols", "Symbols"),
|
||||
("Flags", "Flags"),
|
||||
("Smileys", "Smileys & Emotion", "😀"),
|
||||
("People", "People & Body", "👍"),
|
||||
("Animals", "Animals & Nature", "🐶"),
|
||||
("Food", "Food & Drink", "🍎"),
|
||||
("Travel", "Travel & Places", "🚗"),
|
||||
("Activities", "Activities", "⚽"),
|
||||
("Objects", "Objects", "💡"),
|
||||
("Symbols", "Symbols", "❤️"),
|
||||
("Flags", "Flags", "🏁"),
|
||||
]
|
||||
|
||||
|
||||
@@ -92,8 +93,8 @@ EMOJI_RE = re.compile(f"(?:{_EMOJI_BASE}{_VS}{_SKIN}(?:{_ZWJ}{_EMOJI_BASE}{_VS})
|
||||
|
||||
def load_emoji_db():
|
||||
"""Return {category label: [(char, name), ...]} ordered like the emoji keyboard."""
|
||||
by_cat = {label: [] for label, _ in EMOJI_CATEGORIES}
|
||||
cat_label = {full: label for label, full in EMOJI_CATEGORIES}
|
||||
by_cat = {label: [] for label, _, _ in EMOJI_CATEGORIES}
|
||||
cat_label = {full: label for label, full, _ in EMOJI_CATEGORIES}
|
||||
for e in sorted(emoji_data_python.emoji_data, key=lambda e: e.sort_order):
|
||||
label = cat_label.get(e.category)
|
||||
if label and not e.obsoleted_by:
|
||||
@@ -282,7 +283,7 @@ class LabelApp(ttk.Window):
|
||||
super().__init__(
|
||||
title="Niimbot Label Designer",
|
||||
themename=THEMES.get(self.theme_mode, "flatly"),
|
||||
minsize=(1100, 680),
|
||||
minsize=(1200, 720),
|
||||
)
|
||||
self.option_add("*Font", UI_FONT)
|
||||
self.design = Design.from_dict(self.settings.get("design", {}))
|
||||
@@ -393,19 +394,29 @@ class LabelApp(ttk.Window):
|
||||
self.hover_name = ttk.Label(box, text=" ", bootstyle="secondary")
|
||||
self.hover_name.pack(fill="x", pady=(4, 2))
|
||||
|
||||
self.nb = ttk.Notebook(box, width=420, height=260)
|
||||
self.nb = ttk.Notebook(box, width=400, height=300)
|
||||
self.nb.pack(fill="both", expand=True)
|
||||
self.emoji_index: dict[tk.Text, list[tuple[str, str]]] = {}
|
||||
for label, _ in EMOJI_CATEGORIES:
|
||||
self._make_emoji_tab(label, self.emoji_db[label])
|
||||
self.search_tab = self._make_emoji_tab("Search", [])
|
||||
self._tab_icons = []
|
||||
for label, _, icon in EMOJI_CATEGORIES:
|
||||
photo = ImageTk.PhotoImage(emoji_thumbnail(icon, 22))
|
||||
self._tab_icons.append(photo)
|
||||
self._make_emoji_tab(label, self.emoji_db[label], image=photo)
|
||||
self.search_tab = self._make_emoji_tab("🔍", [])
|
||||
self.nb.hide(self.search_tab.master)
|
||||
self.nb.bind("<<NotebookTabChanged>>", self._tab_changed)
|
||||
|
||||
def _make_emoji_tab(self, label, entries) -> tk.Text:
|
||||
def _make_emoji_tab(self, label, entries, image=None) -> tk.Text:
|
||||
frame = ttk.Frame(self.nb)
|
||||
self.nb.add(frame, text=label)
|
||||
frame.category = label
|
||||
if image is not None:
|
||||
self.nb.add(frame, image=image, padding=(6, 2))
|
||||
else:
|
||||
self.nb.add(frame, text=label)
|
||||
txt = tk.Text(
|
||||
frame,
|
||||
width=1, # let the notebook decide the width
|
||||
height=1,
|
||||
wrap="char",
|
||||
cursor="hand2",
|
||||
spacing1=2,
|
||||
@@ -444,6 +455,10 @@ class LabelApp(ttk.Window):
|
||||
return self.emoji_index[txt][int(tag[1:])]
|
||||
return None
|
||||
|
||||
def _tab_changed(self, _event=None):
|
||||
frame = self.nametowidget(self.nb.select())
|
||||
self.hover_name.configure(text=getattr(frame, "category", " "))
|
||||
|
||||
def _picker_hover(self, event):
|
||||
entry = self._picker_entry(event)
|
||||
self.hover_name.configure(text=entry[1] if entry else " ")
|
||||
@@ -466,7 +481,7 @@ class LabelApp(ttk.Window):
|
||||
if q in n.lower()
|
||||
][:300]
|
||||
self._fill_emoji_tab(self.search_tab, hits)
|
||||
self.nb.add(self.search_tab.master, text=f"Search ({len(hits)})")
|
||||
self.nb.add(self.search_tab.master, text=f"🔍 {len(hits)}")
|
||||
self.nb.select(self.search_tab.master)
|
||||
|
||||
def _build_printer_box(self, parent):
|
||||
@@ -519,18 +534,6 @@ class LabelApp(ttk.Window):
|
||||
btn("Center H", lambda: self.center("h"))
|
||||
btn("Center V", lambda: self.center("v"))
|
||||
btn("Fit", self.fit_selected)
|
||||
sep()
|
||||
btn("New", self.new_design, "link")
|
||||
btn("Open…", self.open_design, "link")
|
||||
btn("Save…", self.save_design, "link")
|
||||
self.theme_btn = ttk.Button(
|
||||
bar,
|
||||
text="☾",
|
||||
width=3,
|
||||
bootstyle="secondary-link",
|
||||
command=self.toggle_theme,
|
||||
)
|
||||
self.theme_btn.pack(side="right")
|
||||
|
||||
def _build_canvas(self, parent):
|
||||
ttk.Label(
|
||||
@@ -567,7 +570,7 @@ class LabelApp(ttk.Window):
|
||||
self.prop_text = tk.Text(
|
||||
box,
|
||||
height=3,
|
||||
width=40,
|
||||
width=20,
|
||||
font=("DejaVu Sans", 12),
|
||||
relief="flat",
|
||||
padx=6,
|
||||
@@ -618,8 +621,22 @@ class LabelApp(ttk.Window):
|
||||
ttk.Button(
|
||||
bar, text="Save PNG…", command=self.save_png, bootstyle="secondary-outline"
|
||||
).pack(side="left", padx=(8, 0), ipady=4)
|
||||
self.theme_btn = ttk.Button(
|
||||
bar,
|
||||
text="☾",
|
||||
width=3,
|
||||
bootstyle="secondary-link",
|
||||
command=self.toggle_theme,
|
||||
)
|
||||
self.theme_btn.pack(side="right")
|
||||
for text, cmd in (
|
||||
("Save…", self.save_design),
|
||||
("Open…", self.open_design),
|
||||
("New", self.new_design),
|
||||
):
|
||||
ttk.Button(bar, text=text, command=cmd, bootstyle="link").pack(side="right")
|
||||
ttk.Label(bar, textvariable=self.status, bootstyle="secondary").pack(
|
||||
side="right"
|
||||
side="right", padx=(0, 12)
|
||||
)
|
||||
|
||||
# ---- theme
|
||||
|
||||
Reference in New Issue
Block a user