Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added mode indicator #1194

Merged
merged 25 commits into from
Jun 24, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a7ccd08
Added mode indicator
AndreasArvidsson May 13, 2023
dc0b173
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 13, 2023
beacb69
Updated descriptions
AndreasArvidsson May 13, 2023
4a3eefa
Moved to plugins folder
AndreasArvidsson May 13, 2023
e717b32
Moved mode indicator to separate directory with its settings file
AndreasArvidsson May 13, 2023
929f88d
Updated comments
AndreasArvidsson May 13, 2023
08a6639
Update plugin/mode_indicator/mode_indicator.py
AndreasArvidsson May 14, 2023
af74cbe
Added gradient to mode indicator
AndreasArvidsson May 15, 2023
3dafbdf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 15, 2023
d25488a
Added gradient setting
AndreasArvidsson May 15, 2023
1c17549
Merge branch 'mode_indicator' of github.com:knausj85/knausj_talon int…
AndreasArvidsson May 15, 2023
df79a9f
Updated description
AndreasArvidsson May 15, 2023
846a1a3
cleanup
AndreasArvidsson May 15, 2023
b1fea8c
Added specific color for command mode.
AndreasArvidsson May 17, 2023
87b1668
Update mode_indicator.talon
AndreasArvidsson May 27, 2023
f2333b2
Updated default colors
AndreasArvidsson May 27, 2023
830ab3e
Don't apply screen scale on mac
AndreasArvidsson Jun 15, 2023
6f31919
Resize before move
AndreasArvidsson Jun 15, 2023
64f551a
Merge branch 'main' into mode_indicator
phillco Jun 24, 2023
f6466de
Added readme to mode indicator
AndreasArvidsson Jun 24, 2023
fc9c641
Merge branch 'mode_indicator' of github.com:knausj85/knausj_talon int…
AndreasArvidsson Jun 24, 2023
9bea08d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 24, 2023
4ca08d4
Update plugin/mode_indicator/README.md
AndreasArvidsson Jun 24, 2023
a195077
Added new lines
AndreasArvidsson Jun 24, 2023
7ae900a
Updated comment
AndreasArvidsson Jun 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 191 additions & 0 deletions plugin/mode_indicator/mode_indicator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
from talon import Module, app, registry, scope, skia, ui
from talon.canvas import Canvas
from talon.screen import Screen
from talon.skia.canvas import Canvas as SkiaCanvas
from talon.skia.imagefilter import ImageFilter
from talon.ui import Rect

canvas: Canvas = None
current_mode = ""
mod = Module()

setting_show = mod.setting(
"mode_indicator_show",
bool,
desc="If true the mode indicator is shown",
default=False,
)
setting_size = mod.setting(
"mode_indicator_size",
float,
desc="Mode indicator diameter in pixels",
)
setting_x = mod.setting(
"mode_indicator_x",
float,
desc="Mode indicator center X-position in percentages(0-1). 0=left, 1=right",
)
setting_y = mod.setting(
"mode_indicator_y",
float,
desc="Mode indicator center Y-position in percentages(0-1). 0=top, 1=bottom",
)
setting_color_alpha = mod.setting(
"mode_indicator_color_alpha",
float,
desc="Mode indicator alpha/opacity in percentages(0-1). 0=fully transparent, 1=fully opaque",
)
setting_color_gradient = mod.setting(
"mode_indicator_color_gradient",
float,
desc="Mode indicator gradient brightness in percentages(0-1). 0=darkest, 1=brightest",
)
setting_color_sleep = mod.setting("mode_indicator_color_sleep", str)
setting_color_dictation = mod.setting("mode_indicator_color_dictation", str)
setting_color_mixed = mod.setting("mode_indicator_color_mixed", str)
setting_color_command = mod.setting("mode_indicator_color_command", str)
setting_color_other = mod.setting("mode_indicator_color_other", str)
AndreasArvidsson marked this conversation as resolved.
Show resolved Hide resolved

setting_paths = {
s.path
for s in [
setting_show,
setting_size,
setting_x,
setting_y,
setting_color_alpha,
setting_color_gradient,
setting_color_sleep,
setting_color_dictation,
setting_color_mixed,
setting_color_command,
setting_color_other,
]
}


def get_mode_color() -> str:
if current_mode == "sleep":
return setting_color_sleep.get()
elif current_mode == "dictation":
return setting_color_dictation.get()
elif current_mode == "mixed":
return setting_color_mixed.get()
elif current_mode == "command":
return setting_color_command.get()
else:
return setting_color_other.get()


def get_alpha_color() -> str:
return f"{int(setting_color_alpha.get() * 255):02x}"


def get_gradient_color(color: str) -> str:
factor = setting_color_gradient.get()
# hex -> rgb
(r, g, b) = tuple(int(color[i : i + 2], 16) for i in (0, 2, 4))
# Darken rgb
r, g, b = int(r * factor), int(g * factor), int(b * factor)
# rgb -> hex
return f"{r:02x}{g:02x}{b:02x}"


def get_colors():
color_mode = get_mode_color()
color_gradient = get_gradient_color(color_mode)
color_alpha = get_alpha_color()
return f"{color_mode}{color_alpha}", f"{color_gradient}"


def on_draw(c: SkiaCanvas):
color_mode, color_gradient = get_colors()
x, y = c.rect.center.x, c.rect.center.y
radius = c.rect.height / 2 - 2

c.paint.shader = skia.Shader.radial_gradient(
(x, y), radius, [color_mode, color_gradient]
)

c.paint.imagefilter = ImageFilter.drop_shadow(1, 1, 1, 1, color_gradient)

c.paint.style = c.paint.Style.FILL
c.paint.color = color_mode
c.draw_circle(x, y, radius)


def move_indicator():
screen: Screen = ui.main_screen()
rect = screen.rect
AndreasArvidsson marked this conversation as resolved.
Show resolved Hide resolved
radius = setting_size.get() * screen.scale / 2

x = rect.left + min(
max(setting_x.get() * rect.width - radius, 0),
rect.width - 2 * radius,
)

y = rect.top + min(
max(setting_y.get() * rect.height - radius, 0),
rect.height - 2 * radius,
)

side = 2 * radius
canvas.move(x, y)
canvas.resize(side, side)


def show_indicator():
global canvas
canvas = Canvas.from_rect(Rect(0, 0, 0, 0))
canvas.register("draw", on_draw)


def hide_indicator():
global canvas
canvas.unregister("draw", on_draw)
canvas.close()
canvas = None


def update_indicator():
if setting_show.get():
if not canvas:
show_indicator()
move_indicator()
canvas.freeze()
elif canvas:
hide_indicator()


def on_update_contexts():
global current_mode
modes = scope.get("mode")
if "sleep" in modes:
mode = "sleep"
elif "dictation" in modes:
if "command" in modes:
mode = "mixed"
else:
mode = "dictation"
elif "command" in modes:
mode = "command"
else:
mode = "other"

if current_mode != mode:
current_mode = mode
update_indicator()


def on_update_settings(updated_settings: set[str]):
if setting_paths & updated_settings:
update_indicator()


def on_ready():
registry.register("update_contexts", on_update_contexts)
registry.register("update_settings", on_update_settings)
ui.register("screen_change", lambda _: update_indicator)


app.register("ready", on_ready)
23 changes: 23 additions & 0 deletions plugin/mode_indicator/mode_indicator.talon
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
settings():
# Don't show mode indicator by default
user.mode_indicator_show = 0
# 30pixels diameter
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're multiplying it by the scale factor, then these aren't necessarily pixels. For example, on my screen, this becomes a diameter of 120px.

Suggested change
# 30pixels diameter
# Diameter (in resolution independent points).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not sure that point is more clear to people.

user.mode_indicator_size = 30
AndreasArvidsson marked this conversation as resolved.
Show resolved Hide resolved
# Center horizontally
user.mode_indicator_x = 0.5
# Align top
user.mode_indicator_y = 0
# Slightly transparent
user.mode_indicator_color_alpha = 0.75
# Grey gradient
user.mode_indicator_color_gradient = 0.5
# Grey color for sleep mode
user.mode_indicator_color_sleep = "808080"
# Orchid color for dictation mode
user.mode_indicator_color_dictation = "da70d6"
AndreasArvidsson marked this conversation as resolved.
Show resolved Hide resolved
# OliveDrab color for mixed mode
user.mode_indicator_color_mixed = "6b8e23"
AndreasArvidsson marked this conversation as resolved.
Show resolved Hide resolved
# CornflowerBlue color for command mode
user.mode_indicator_color_command = "6495ed"
# GhostWhite color for other modes
user.mode_indicator_color_other = "f8f8ff"
AndreasArvidsson marked this conversation as resolved.
Show resolved Hide resolved