Skip to content

Commit

Permalink
feat: UX improvements, configure hover cursor icons
Browse files Browse the repository at this point in the history
  • Loading branch information
tomlin7 committed Apr 4, 2024
1 parent 2a1d0c5 commit 9992c66
Show file tree
Hide file tree
Showing 27 changed files with 133 additions and 28 deletions.
3 changes: 3 additions & 0 deletions biscuit/core/components/editors/texteditor/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import tkinter as tk
from tkinter.font import Font

Expand Down Expand Up @@ -143,6 +145,7 @@ def copy(self, *_):
self.text.event_copy()

def goto(self, position):
self.text.focus_set()
self.text.goto(position)

def goto_line(self, line):
Expand Down
2 changes: 1 addition & 1 deletion biscuit/core/components/floating/autocomplete/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __init__(self, master: AutoComplete, *args, **kwargs) -> None:

self.kind = Kind(self)
self.text = tk.Text(self,
font=self.base.settings.font, fg=self.fg, bg=self.bg,
font=self.base.settings.font, fg=self.fg, bg=self.bg, cursor="hand2",
relief=tk.FLAT, highlightthickness=0, width=30, height=1)

self.text.tag_config("term", foreground=self.base.theme.biscuit, font=self.base.settings.font_bold)
Expand Down
2 changes: 1 addition & 1 deletion biscuit/core/components/floating/autocomplete/kind.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def __init__(self, master: CompletionItem, kind: int=1, *args, **kwargs) -> None
self.master = master
self.base = master.base

self.config(**self.base.theme.editors.autocomplete.item)
self.config(**self.base.theme.editors.autocomplete.item, cursor="hand2")
self.set_kind(kind)

def set_kind(self, kind: int=1):
Expand Down
12 changes: 12 additions & 0 deletions biscuit/core/components/floating/definitions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ def __init__(self, master, *args, **kwargs) -> None:
self.bind("<Escape>", self.hide)

def refresh_geometry(self, pos: str, tab: Text):
"""Refresh the geometry of the window."""

tab.update_idletasks()

pos_x, pos_y = tab.winfo_rootx(), tab.winfo_rooty()
Expand All @@ -54,6 +56,8 @@ def refresh_geometry(self, pos: str, tab: Text):
self.geometry("+{}+{}".format(pos_x + bbx_x - 1, pos_y + bbx_y + bbx_h))

def show(self, tab: Text, jump: Jump):
"""Show the definitions window."""

self.update_locations(jump.locations)
self.active = True
self.latest_tab = tab
Expand All @@ -64,20 +68,28 @@ def show(self, tab: Text, jump: Jump):
self.focus_set()

def hide(self, *_):
"""Hide the definitions window."""

self.active = False
self.withdraw()
self.clear()

def clear(self):
"""Clear all active items."""

for item in self.active_items:
item.destroy()
self.active_items = []

def choose(self, path: str, start: JumpLocationRange):
"""Choose a definition and go to it."""

self.base.goto_location(path, start)
self.hide()

def update_locations(self, locations: list[JumpLocationRange]) -> None:
"""Update the list of locations."""

for location in locations:
i = LocationItem(self, location)
i.pack(fill=tk.X, expand=True)
Expand Down
2 changes: 2 additions & 0 deletions biscuit/core/components/floating/findreplace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@


class FindReplace(Toplevel):
"""Floating find and replace window"""

def __init__(self, base, *args, **kwargs) -> None:
super().__init__(base, *args, **kwargs)
self.offset = 10
Expand Down
2 changes: 1 addition & 1 deletion biscuit/core/components/floating/menu/menuitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def __init__(self, master, text, command=lambda *_:..., *args, **kwargs) -> None
super().__init__(master, *args, **kwargs)
self.command = command

self.config(text=text, anchor=tk.W, font=("Segoe UI", 10),
self.config(text=text, anchor=tk.W, font=("Segoe UI", 10), cursor="hand2",
padx=20, pady=2, **self.base.theme.menu.item
)
self.bind("<Button-1>", self.onclick)
Expand Down
26 changes: 26 additions & 0 deletions biscuit/core/components/floating/notifications/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def __init__(self, base) -> None:
self.base.register_onupdate(self.follow_root)

def info(self, text: str) -> Notification:
"""Create an info notification"""

instance = Notification(self, "info", text=text, fg=self.base.theme.biscuit)
instance.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
self.count += 1
Expand All @@ -65,6 +67,8 @@ def info(self, text: str) -> Notification:
return instance

def warning(self, text: str) -> Notification:
"""Create a warning notification"""

instance = Notification(self, "warning", text=text, fg="yellow")
instance.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
self.count += 1
Expand All @@ -75,6 +79,8 @@ def warning(self, text: str) -> Notification:
return instance

def error(self, text: str) -> Notification:
"""Create an error notification"""

instance = Notification(self, "error", text=text, fg="red")
instance.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
self.count += 1
Expand All @@ -85,6 +91,15 @@ def error(self, text: str) -> Notification:
return instance

def notify(self, text: str, kind: int) -> Notification:
"""Create a notification based on kind
1: info
2: warning
3: error
Args:
text (str): notification text
kind (int): notification kind
"""
match kind:
case 1:
self.error(text)
Expand All @@ -94,6 +109,8 @@ def notify(self, text: str, kind: int) -> Notification:
self.info(text)

def follow_root(self) -> None:
"""Follow root window position"""

if not self.active:
return

Expand All @@ -103,6 +120,9 @@ def follow_root(self) -> None:
self.geometry(f"+{int(x)}+{int(y)}")

def show(self, *_) -> None:
"""Toggle notification visibility
Also updates title based on count."""

if self.count:
self.title.config(text=f"NOTIFICATIONS ({self.count})")
else:
Expand All @@ -118,15 +138,21 @@ def show(self, *_) -> None:
self.base.statusbar.update_notifications()

def hide(self, *_) -> None:
"""Hide notifications"""

self.active = False
self.withdraw()

def clear(self, *_) -> None:
"""Clear all notifications"""

for i in self.notifications:
i.delete()
self.count = 0

def delete(self, notification: Notification) -> None:
"""Delete a notification"""

self.notifications.remove(notification)
self.count -= 1
notification.destroy()
Expand Down
2 changes: 1 addition & 1 deletion biscuit/core/components/floating/palette/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def __init__(self, master: Palette, text: str, command: str, description="", *ar
self.command = command

self.bg, self.fg, self.hbg, self.hfg = self.base.theme.palette.item.values()
self.config(font=self.base.settings.uifont, fg=self.fg, bg=self.bg,
self.config(font=self.base.settings.uifont, fg=self.fg, bg=self.bg, cursor="hand2",
padx=10, pady=3, relief=tk.FLAT, highlightthickness=0, width=30, height=1)

self.tag_config("term", foreground=self.base.theme.biscuit)
Expand Down
16 changes: 11 additions & 5 deletions biscuit/core/components/utils/bubble.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@


class Bubble(Toplevel):
"""
+===============+
|| Text ||
+===============+
"""
"""Hover bubble for showing information/tips"""

def __init__(self, master, text, bd=1, *args, **kw) -> None:
super().__init__(master, *args, **kw)
self.overrideredirect(True)
Expand All @@ -19,16 +16,25 @@ def __init__(self, master, text, bd=1, *args, **kw) -> None:
self.withdraw()

def get_pos(self) -> str:
"""Get the position of the bubble.
To be reconfigured in inherited classes."""

return (f"+{self.master.winfo_rootx() + self.master.winfo_width() + 5}" +
f"+{int(self.master.winfo_rooty() + (self.master.winfo_height() - self.winfo_height())/2)}")

def change_text(self, text) -> None:
"""Change the text of the bubble"""

self.label.config(text=text)

def show(self, *_) -> None:
"""Show the bubble"""

self.update_idletasks()
self.geometry(self.get_pos())
self.deiconify()

def hide(self, *_) -> None:
"""Hide the bubble"""

self.withdraw()
7 changes: 5 additions & 2 deletions biscuit/core/components/utils/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@


class Button(Menubutton):
"""A Flat style button"""
"""A flat style button"""

def __init__(self, master, text, command=lambda _: None, *args, **kwargs) -> None:
super().__init__(master, text=text, *args, **kwargs)
self.config(pady=5, font=("Segoi UI", 10), **self.base.theme.utils.button)
self.config(pady=5, font=("Segoi UI", 10), cursor="hand2", **self.base.theme.utils.button)
self.set_command(command)

def set_command(self, command) -> None:
"""Set the command for the button"""

self.bind('<Button-1>', command)
16 changes: 14 additions & 2 deletions biscuit/core/components/utils/buttonsentry.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import tkinter as tk

from hintedtext import HintedEntry

from .frame import Frame
from .iconbutton import IconButton

from hintedtext import HintedEntry


class ButtonsEntry(Frame):
"""Entry with buttons"""

def __init__(self, master, hint="", buttons=(), textvariable=None, *args, **kwargs):
super().__init__(master, *args, **kwargs)
self.config(padx=1, pady=1, bg=self.base.theme.border)
Expand All @@ -20,20 +22,30 @@ def __init__(self, master, hint="", buttons=(), textvariable=None, *args, **kwar
self.add_buttons(buttons)

def add_button(self, icon: str, event=lambda _: None, icon2: str=None):
"""Add a button to the entry"""

b=IconButton(self, icon, event, icon2)
b.grid(row=0, column=self.column, sticky='')
b.config(**self.base.theme.utils.buttonsentry.button)
self.column += 1

def add_buttons(self, buttons):
"""Add multiple buttons to the entry"""

for btn in buttons:
self.add_button(*btn)

def get(self, *args):
"""Get the entry text"""

return self.entry.get(*args)

def delete(self, *args):
"""Delete the entry text"""

return self.entry.delete(*args)

def insert(self, *args):
"""Insert text into the entry"""

return self.entry.insert(*args)
14 changes: 12 additions & 2 deletions biscuit/core/components/utils/closelistitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@


class CloseListItem(Frame):
"""For implementing a list of closeable items.
A varient of IconLabelButton that comes with a close icon
on the right side of the button.
"""
A varient of IconLabelButton that has a close icon on the right side of the button.
"""

def __init__(self, master, text=None, icon=None, function=lambda *_: None, closefn=lambda *_:None, iconside=tk.LEFT, padx=5, pady=1, *args, **kwargs) -> None:
super().__init__(master, padx=padx, pady=pady, *args, **kwargs)
self.function = function
Expand Down Expand Up @@ -68,9 +70,13 @@ def on_click(self, *_) -> None:
self.function()

def change_text(self, text) -> None:
"""Change the text of the item"""

self.text_label.config(text=text)

def change_icon(self, icon) -> None:
"""Change the icon of the item"""

self.icon_label.config(text=icon)

def set_pack_data(self, **kwargs) -> None:
Expand All @@ -80,11 +86,15 @@ def get_pack_data(self):
return self.pack_data

def show(self) -> None:
"""Show the item"""

if not self.visible:
self.visible = True
self.pack(**self.get_pack_data())

def hide(self) -> None:
"""Hide the item"""

if self.visible:
self.visible = False
self.pack_forget()
1 change: 1 addition & 0 deletions biscuit/core/components/utils/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

class Frame(tk.Frame):
"""normal frame with reference to base"""

def __init__(self, master, *args, **kwargs) -> None:
super().__init__(master, *args, **kwargs)
self.master = master
Expand Down
3 changes: 2 additions & 1 deletion biscuit/core/components/utils/icon.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@


class Icon(Label):
"""Button with only an icon"""
"""Label with only an icon"""

def __init__(self, master, icon: str="", iconsize: int=14, *args, **kwargs) -> None:
super().__init__(master, *args, **kwargs)
self.config(font=("codicon", iconsize))
Expand Down
3 changes: 2 additions & 1 deletion biscuit/core/components/utils/iconbutton.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

class IconButton(Menubutton):
"""Button with only an icon"""

def __init__(self, master, icon, event=lambda *_:..., icon2=None, iconsize=14, *args, **kwargs) -> None:
super().__init__(master, *args, **kwargs)
self.config(**self.base.theme.utils.iconbutton)
self.config(cursor="hand2", **self.base.theme.utils.iconbutton)
self.icons = [icon, icon2]
self.icon2 = icon2
self.switch = False
Expand Down
4 changes: 2 additions & 2 deletions biscuit/core/components/utils/iconlabelbutton.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ def __init__(self, master, text=None, icon=None, function=lambda *_: None, icons

if icon:
self.icon_label = tk.Label(self, text=self.codicon if self.toggle else " ", anchor=tk.E,
bg=self.bg, fg=self.fg, font=("codicon", iconsize))
bg=self.bg, fg=self.fg, font=("codicon", iconsize), cursor="hand2")
self.icon_label.pack(side=iconside, fill=tk.BOTH, expand=expandicon)

if text:
self.text_label = tk.Label(self, text=self.text, anchor=tk.W, pady=2,
bg=self.bg, fg=self.fg, font=("Segoe UI", 10))
bg=self.bg, fg=self.fg, font=("Segoe UI", 10), cursor="hand2")
self.text_label.pack(side=iconside, fill=tk.BOTH, expand=True)

self.config_bindings()
Expand Down
5 changes: 3 additions & 2 deletions biscuit/core/components/utils/linklabel.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@


class LinkLabel(Label):
"""A Flat style button"""
"""Label that acts as a link"""

def __init__(self, master, text, command=lambda _: None, *args, **kwargs) -> None:
super().__init__(master, text=text, *args, **kwargs)
self.config(font=("Segoi UI", 10), **self.base.theme.utils.linklabel)
self.config(font=("Segoi UI", 10), cursor="hand2", **self.base.theme.utils.linklabel)
self.set_command(command)

def set_command(self, command) -> None:
Expand Down
Loading

0 comments on commit 9992c66

Please sign in to comment.