Skip to content

Commit

Permalink
v3.1.0 upload.
Browse files Browse the repository at this point in the history
  • Loading branch information
definite-d authored Feb 18, 2024
1 parent 77711eb commit e34d37b
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 8 deletions.
27 changes: 27 additions & 0 deletions src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,32 @@

name = "psg_reskinner"
from .constants import HSL_INTERPOLATION, HUE_INTERPOLATION, RGB_INTERPOLATION
from .easings import (
EASE_CONSTANT,
EASE_IN_SINE,
EASE_OUT_SINE,
EASE_IN_OUT_SINE,
EASE_IN_QUAD,
EASE_OUT_QUAD,
EASE_IN_OUT_QUAD,
EASE_IN_CUBIC,
EASE_OUT_CUBIC,
EASE_IN_OUT_CUBIC,
EASE_IN_QUART,
EASE_OUT_QUART,
EASE_IN_OUT_QUART,
EASE_IN_QUINT,
EASE_OUT_QUINT,
EASE_IN_OUT_QUINT,
EASE_IN_EXPO,
EASE_OUT_EXPO,
EASE_IN_OUT_EXPO,
EASE_IN_CIRC,
EASE_OUT_CIRC,
EASE_IN_OUT_CIRC,
EASE_OUT_BOUNCE,
EASE_IN_BOUNCE,
EASE_IN_OUT_BOUNCE,
)
from .psg_reskinner import animated_reskin, reskin, toggle_transparency
from .version import __version__
6 changes: 6 additions & 0 deletions src/colorprocessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,12 @@ def menu_entry(
index: int,
configs: Dict[str, Union[str, Tuple[str, int]]],
):
configs = dict(
filter(
lambda item: item[0] in menu.entryconfigure(index).keys(),
configs.items(),
)
) # Filter the configs for menu entries that don't accept the full config dict. Fixes issue #11.
self.config(
configs,
lambda **cnf: menu.entryconfigure(index, cnf),
Expand Down
90 changes: 90 additions & 0 deletions src/easings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# PSG_Reskinner
#
# Enables changing the themes of your PySimpleGUI windows and elements
# instantaneously on the fly without the need for re-instantiating the window.
#
# MIT License
#
# Copyright (c) 2023 Divine Afam-Ifediogor
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from math import cos, sin, pi, sqrt, pow

# Easing functions adapted from https://easings.net

EASE_CONSTANT = lambda x: x
EASE_IN_SINE = lambda x: 1 - cos((x * pi) / 2)
EASE_OUT_SINE = lambda x: sin((x * pi) / 2)
EASE_IN_OUT_SINE = lambda x: -(cos(x * pi) - 1) / 2
EASE_IN_QUAD = lambda x: pow(x, 2)
EASE_OUT_QUAD = lambda x: 1 - (1 - x) * (1 - x)
EASE_IN_OUT_QUAD = lambda x: 2 * pow(x, 2) if x < 0.5 else 1 - pow(-2 * x + 2, 2) / 2
EASE_IN_CUBIC = lambda x: pow(x, 3)
EASE_OUT_CUBIC = lambda x: 1 - pow(1 - x, 3)
EASE_IN_OUT_CUBIC = lambda x: 4 * pow(x, 3) if x < 0.5 else 1 - pow(-2 * x + 2, 3) / 2
EASE_IN_QUART = lambda x: pow(x, 4)
EASE_OUT_QUART = lambda x: 1 - pow(1 - x, 4)
EASE_IN_OUT_QUART = lambda x: 8 * pow(x, 4) if x < 0.5 else 1 - pow(-2 * x + 2, 4) / 2
EASE_IN_QUINT = lambda x: pow(x, 5)
EASE_OUT_QUINT = lambda x: 1 - pow(1 - x, 5)
EASE_IN_OUT_QUINT = lambda x: 16 * pow(x, 5) if x < 0.5 else 1 - pow(-2 * x + 2, 5) / 2
EASE_IN_EXPO = lambda x: 0 if x == 0 else pow(2, 10 * x - 10)
EASE_OUT_EXPO = lambda x: 1 if x == 1 else 1 - pow(2, -10 * x)
EASE_IN_OUT_EXPO = (
lambda x: 0
if x == 0
else 1
if x == 1
else pow(2, 20 * x - 10) / 2
if x < 0.5
else (2 - pow(2, -20 * x + 10)) / 2
)
EASE_IN_CIRC = lambda x: 1 - sqrt(1 - pow(x, 2))
EASE_OUT_CIRC = lambda x: sqrt(1 - pow(x - 1, 2))
EASE_IN_OUT_CIRC = (
lambda x: (1 - sqrt(1 - pow(2 * x, 2))) / 2
if x < 0.5
else (sqrt(1 - pow(-2 * x + 2, 2)) + 1) / 2
)


def _ease_out_bounce(x):
n1 = 7.5625
d1 = 2.75
if x < 1 / d1:
return n1 * x * x
elif x < 2 / d1:
x -= 1.5
return n1 * (x / d1) * x + 0.75
elif x < 2.5 / d1:
x -= 2.25
return n1 * (x / d1) * x + 0.9375
else:
x -= 2.625
return n1 * (x / d1) * x + 0.984375


EASE_OUT_BOUNCE = lambda x: _ease_out_bounce(x) # For uniformity.
EASE_IN_BOUNCE = lambda x: 1 - _ease_out_bounce(1 - x)
EASE_IN_OUT_BOUNCE = (
lambda x: (1 - _ease_out_bounce(1 - 2 * x)) / 2
if x < 0.5
else (1 + _ease_out_bounce(2 * x - 1)) / 2
)
42 changes: 36 additions & 6 deletions src/psg_reskinner.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
WINDOW_THEME_MAP,
)
from .deprecation import deprecation_trigger
from .easings import EASE_CONSTANT
from .utilities import _lower_class_name
from .version import __version__

Expand Down Expand Up @@ -113,7 +114,6 @@ def reskin(
cp: ColorProcessor = kwargs.get("_color_processor")
old_theme = kwargs.get("_old_theme")
new_theme = kwargs.get("_new_theme")
styler = cp.styler
old_theme_dict = cp.old_theme_dict
new_theme_dict = cp.new_theme_dict

Expand Down Expand Up @@ -155,9 +155,9 @@ def reskin(

# TTK Scrollbars
if getattr(element, "vsb_style_name", False):
cp.scrollbar(element.vsb_style_name, "Vertical.TScrollbar")
cp.scrollbar(element.vsb_style_name, "Vertical.TScrollbar") # noqa
if getattr(element, "hsb_style_name", False):
cp.scrollbar(element.hsb_style_name, "Horizontal.TScrollbar")
cp.scrollbar(element.hsb_style_name, "Horizontal.TScrollbar") # noqa
if getattr(
element, "ttk_style_name", False
) and element.ttk_style_name.endswith("TScrollbar"):
Expand Down Expand Up @@ -238,7 +238,7 @@ def reskin(
},
)
if getattr(element, "TKMenu", False):
cp.recurse_menu(element.TKMenu)
cp.recurse_menu(element.TKMenu) # noqa
continue

elif el == "canvas":
Expand Down Expand Up @@ -395,7 +395,31 @@ def animated_reskin(
interpolation_mode: Union[
RGB_INTERPOLATION, HUE_INTERPOLATION, HSL_INTERPOLATION
] = RGB_INTERPOLATION,
easing_function: Callable[[float], float] = EASE_CONSTANT,
):
"""
Does the same as a regular reskin, but animates the effect over time.
First available from v2.2.0.
The `interpolation_mode` argument was added in v2.3.4.
The `easing_function` argument was added in v3.1.0.
:param duration_in_milliseconds: The duration of the animation in milliseconds.
:param interpolation_mode: Determines how interpolation is to be handled. May be `RGB_INTERPOLATION`,
`HUE_INTERPOLATION`, or `HSL_INTERPOLATION`.
:param easing_function: A callable acting as an easing function. Other available modes are prefixed with `EASE`.
:param window: The window to operate on.
:param new_theme: The theme to transition to.
:param theme_function: The theme change function from PySimpleGUI within your code. Required because of namespaces.
:param lf_table: The LOOK_AND_FEEL_TABLE from PySimpleGUI from within your code. The `new_theme` should be in there.
:param set_future: If set to True, the `new_theme` will be applied to all future windows.
:param element_filter: A callable of your choice that takes an element as its only parameter and returns True or
False. Elements that result in True will be reskinned, and others will be skipped.
:param reskin_background: If True, the background color of the window will be reskinned. Else, it won't.
:return:
"""
delta = timedelta(milliseconds=duration_in_milliseconds)
start_time = datetime.now()
end_time = start_time + delta
Expand All @@ -421,7 +445,7 @@ def animated_reskin(
old_theme_dict, new_theme_dict, styler, 0, interpolation_mode
)
while datetime.now() <= end_time:
cp.progress = round((datetime.now() - start_time) / delta, 4)
cp.progress = easing_function(round((datetime.now() - start_time) / delta, 4))
try:
reskin(
window,
Expand Down Expand Up @@ -492,7 +516,13 @@ def main():

right_click_menu = [
"",
[["Hi", ["Next Level", ["Deeper Level", ["a", "b", "c"]], "Hoho"]], "There"],
[
[
"Hi",
["Next Level", ["Deeper Level", "---", "as", ["a", "b", "c"]], "Hoho"],
],
"There",
],
]

window_layout = [
Expand Down
4 changes: 2 additions & 2 deletions src/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

__version__: str = "3.0.0"
__deprecation_condition__: bool = int(__version__.split(".")[1]) >= 1
__version__: str = "3.1.0"
__deprecation_condition__: bool = int(__version__.split(".")[1]) >= 2

0 comments on commit e34d37b

Please sign in to comment.