Make mdi icons for Qt themeable (#2078)
* Fix create_vars_from_map not creating vars with default definition * Add white and black to vars * Replace some hard-coded SVGs with mdi equivalents * Implement function to dynamically adjust SVG icon color * Use new svg function to make Qt stylesheet icons respond to theme changes * Use svg function for sidebar tool icons * Create copy for each new color instead of modifying source file * Fix check fails * Add custom checkbox style for #2079 * Add example of how to generate svgs during build (dae) * Create arbitrary color variants for each icon with Bazel * Remove unused label (dae)
This commit is contained in:
parent
e109c62aa9
commit
bff76727fe
|
@ -2,7 +2,6 @@ load("@rules_python//python:defs.bzl", "py_library")
|
|||
load("@py_deps//:requirements.bzl", "requirement")
|
||||
load("@rules_python//python:packaging.bzl", "py_package", "py_wheel")
|
||||
load("//:defs.bzl", "anki_version")
|
||||
|
||||
load("//ts:copy.bzl", "copy_files_into_group")
|
||||
load("//ts:compile_sass.bzl", "compile_sass")
|
||||
|
||||
|
@ -31,13 +30,22 @@ genrule(
|
|||
srcs = [
|
||||
"_vars.css",
|
||||
],
|
||||
outs = ["colors.py", "props.py"],
|
||||
outs = [
|
||||
"colors.py",
|
||||
"props.py",
|
||||
],
|
||||
cmd = "$(location //qt:extract_sass_vars) $(SRCS) $(OUTS)",
|
||||
tools = [
|
||||
"//qt:extract_sass_vars",
|
||||
],
|
||||
)
|
||||
|
||||
py_library(
|
||||
name = "colors",
|
||||
srcs = [":colors.py"],
|
||||
visibility = ["//qt:__subpackages__"],
|
||||
)
|
||||
|
||||
_py_srcs = glob(
|
||||
[
|
||||
"**/*.py",
|
||||
|
|
|
@ -20,8 +20,16 @@ class SidebarTool(Enum):
|
|||
|
||||
class SidebarToolbar(QToolBar):
|
||||
_tools: tuple[tuple[SidebarTool, str, Callable[[], str]], ...] = (
|
||||
(SidebarTool.SEARCH, "icons:magnifying_glass.svg", tr.actions_search),
|
||||
(SidebarTool.SELECT, "icons:select.svg", tr.actions_select),
|
||||
(
|
||||
SidebarTool.SEARCH,
|
||||
"mdi:magnify",
|
||||
tr.actions_search,
|
||||
),
|
||||
(
|
||||
SidebarTool.SELECT,
|
||||
"mdi:selection-drag",
|
||||
tr.actions_select,
|
||||
),
|
||||
)
|
||||
|
||||
def __init__(self, sidebar: aqt.browser.sidebar.SidebarTreeView) -> None:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
load("//ts:vendor.bzl", "copy_mdi_icons")
|
||||
load("color_svg.bzl", "color_svg")
|
||||
|
||||
copy_mdi_icons(
|
||||
name = "mdi-icons",
|
||||
|
@ -33,6 +34,19 @@ copy_mdi_icons(
|
|||
# tags
|
||||
"tag-outline.svg",
|
||||
"tag-off-outline.svg",
|
||||
],
|
||||
)
|
||||
|
||||
copy_mdi_icons(
|
||||
name = "mdi-themed",
|
||||
icons = [
|
||||
# sidebar tools
|
||||
"magnify.svg",
|
||||
"selection-drag.svg",
|
||||
|
||||
# QComboBox arrows
|
||||
"chevron-up.svg",
|
||||
"chevron-down.svg",
|
||||
|
||||
# QHeaderView arrows
|
||||
"menu-up.svg",
|
||||
|
@ -41,12 +55,73 @@ copy_mdi_icons(
|
|||
# drag handle
|
||||
"drag-vertical.svg",
|
||||
"drag-horizontal.svg",
|
||||
|
||||
# checkbox
|
||||
"check.svg",
|
||||
"minus-thick.svg",
|
||||
],
|
||||
)
|
||||
|
||||
py_binary(
|
||||
name = "color_svg",
|
||||
srcs = [
|
||||
"color_svg.py",
|
||||
"//qt/aqt:colors",
|
||||
],
|
||||
imports = ["."],
|
||||
visibility = [":__subpackages__"],
|
||||
)
|
||||
|
||||
color_svg(
|
||||
name = "magnify",
|
||||
)
|
||||
color_svg(
|
||||
name = "selection-drag",
|
||||
)
|
||||
color_svg(
|
||||
name = "chevron-up",
|
||||
extra_colors = ["FG_DISABLED"],
|
||||
)
|
||||
color_svg(
|
||||
name = "chevron-down",
|
||||
extra_colors = ["FG_DISABLED"],
|
||||
)
|
||||
color_svg(
|
||||
name = "menu-up",
|
||||
)
|
||||
color_svg(
|
||||
name = "menu-down",
|
||||
)
|
||||
color_svg(
|
||||
name = "drag-vertical",
|
||||
extra_colors = ["FG_SUBTLE"],
|
||||
)
|
||||
color_svg(
|
||||
name = "drag-horizontal",
|
||||
extra_colors = ["FG_SUBTLE"],
|
||||
)
|
||||
color_svg(
|
||||
name = "check",
|
||||
)
|
||||
color_svg(
|
||||
name = "minus-thick",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "icons",
|
||||
srcs = ["mdi-icons"] + glob([
|
||||
srcs = [
|
||||
"mdi-icons",
|
||||
"magnify",
|
||||
"selection-drag",
|
||||
"chevron-up",
|
||||
"chevron-down",
|
||||
"menu-up",
|
||||
"menu-down",
|
||||
"drag-vertical",
|
||||
"drag-horizontal",
|
||||
"check",
|
||||
"minus-thick",
|
||||
] + glob([
|
||||
"*.svg",
|
||||
"*.png",
|
||||
]),
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#f4f4f4" d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 157 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#f4f4f4" d="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 159 B |
|
@ -0,0 +1,30 @@
|
|||
def color_svg(name, extra_colors = [], visibility = ["//qt:__submodules__"]):
|
||||
native.genrule(
|
||||
name = name,
|
||||
srcs = ["mdi-themed"],
|
||||
outs = [
|
||||
name + "-light.svg",
|
||||
] + [
|
||||
# additional light colors
|
||||
"{}{}{}".format(
|
||||
name,
|
||||
"-{}".format(color),
|
||||
"-light.svg"
|
||||
) for color in extra_colors
|
||||
] + [
|
||||
name + "-dark.svg",
|
||||
] + [
|
||||
# additional dark colors
|
||||
"{}{}{}".format(
|
||||
name,
|
||||
"-{}".format(color),
|
||||
"-dark.svg"
|
||||
) for color in extra_colors
|
||||
],
|
||||
cmd = "$(location color_svg) {}.svg {} $(OUTS) $(SRCS)".format(
|
||||
name, ":".join(["FG"] + extra_colors)
|
||||
),
|
||||
tools = [
|
||||
"color_svg",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,47 @@
|
|||
# Copyright: Ankitects Pty Ltd and contributors
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from qt.aqt import colors
|
||||
|
||||
input_filename = sys.argv[1]
|
||||
input_name = input_filename.replace(".svg", "")
|
||||
color_names = sys.argv[2].split(":")
|
||||
|
||||
# two files created for each additional color
|
||||
offset = len(color_names) * 2
|
||||
svg_paths = sys.argv[3 : 3 + offset]
|
||||
|
||||
# as we've received a group of files, we need to manually join the path
|
||||
input_folder = Path(sys.argv[4]).parent
|
||||
input_svg = input_folder / input_filename
|
||||
|
||||
with open(input_svg, "r") as f:
|
||||
svg_data = f.read()
|
||||
|
||||
for color_name in color_names:
|
||||
color = getattr(colors, color_name)
|
||||
light_svg = dark_svg = ""
|
||||
|
||||
if color_name == "FG":
|
||||
prefix = input_name
|
||||
else:
|
||||
prefix = f"{input_name}-{color_name}"
|
||||
|
||||
for path in svg_paths:
|
||||
if f"{prefix}-light.svg" in path:
|
||||
light_svg = path
|
||||
elif f"{prefix}-dark.svg" in path:
|
||||
dark_svg = path
|
||||
|
||||
for (idx, filename) in enumerate((light_svg, dark_svg)):
|
||||
data = svg_data
|
||||
if "fill" in data:
|
||||
data = re.sub(r"fill=\"#.+?\"", f'fill="{color[idx]}"', data)
|
||||
else:
|
||||
data = re.sub(r"<svg", f'<svg fill="{color[idx]}"', data, 1)
|
||||
with open(filename, "w") as f:
|
||||
f.write(data)
|
|
@ -1,84 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64"
|
||||
height="64"
|
||||
viewBox="0 0 16.933333 16.933334"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="1.0.2-2 (e86c870879, 2021-01-15)"
|
||||
sodipodi:docname="magnifying_glass.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="10.039334"
|
||||
inkscape:cy="35.645602"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
gridtolerance="10000"
|
||||
objecttolerance="51"
|
||||
guidetolerance="51"
|
||||
inkscape:snap-global="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid833" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<circle
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38115;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
id="path835"
|
||||
cx="5.5429349"
|
||||
cy="5.5176048"
|
||||
r="4.7567849" />
|
||||
<g
|
||||
id="path837"
|
||||
style="opacity:1"
|
||||
transform="translate(0.280633,0.25724692)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.1866;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
|
||||
d="m 9.270412,9.1682417 5.763677,5.8797903"
|
||||
id="path3348" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.997025;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
|
||||
d="M 8.519367,8.5427531 C 7.9111727,9.1535363 7.8640343,9.5551464 8.1618931,9.8774543 l 5.8029559,6.2792797 c 0.603423,0.638261 1.591613,0.648031 2.206659,0.0218 0.614172,-0.625577 0.623586,-1.648878 0.02103,-2.286493 0,0 -6.025394,-5.3742675 -6.3649177,-5.6724746 C 9.4880962,7.9213592 9.1275613,7.9319698 8.519367,8.5427531 Z"
|
||||
id="path3350"
|
||||
sodipodi:nodetypes="zzccczz" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 5.3 KiB |
|
@ -1,168 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64"
|
||||
height="64"
|
||||
viewBox="0 0 16.933333 16.933334"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="1.0.2-2 (e86c870879, 2021-01-15)"
|
||||
sodipodi:docname="select.svg">
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
effect="powermask"
|
||||
id="path-effect4000"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
uri="#mask-powermask-path-effect4000"
|
||||
invert="false"
|
||||
hide_mask="false"
|
||||
background="true"
|
||||
background_color="#ffffffff" />
|
||||
<inkscape:path-effect
|
||||
effect="powermask"
|
||||
id="path-effect3981"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
uri="#mask-powermask-path-effect3981"
|
||||
invert="false"
|
||||
hide_mask="false"
|
||||
background="true"
|
||||
background_color="#ffffffff" />
|
||||
<inkscape:path-effect
|
||||
effect="powermask"
|
||||
id="path-effect3966"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
uri="#mask-powermask-path-effect3966"
|
||||
invert="false"
|
||||
hide_mask="false"
|
||||
background="true"
|
||||
background_color="#ffffffff" />
|
||||
<inkscape:path-effect
|
||||
effect="powermask"
|
||||
id="path-effect2895"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
uri="#mask-powermask-path-effect2895"
|
||||
invert="false"
|
||||
hide_mask="false"
|
||||
background="true"
|
||||
background_color="#ffffffff" />
|
||||
<linearGradient
|
||||
id="linearGradient866"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#838799;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop864" />
|
||||
</linearGradient>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Arrow1Lstart"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="scale(0.8) translate(12.5,0)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path2747" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 8.466667 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="16.933333 : 8.466667 : 1"
|
||||
inkscape:persp3d-origin="8.4666665 : 5.6444447 : 1"
|
||||
id="perspective2694" />
|
||||
<filter
|
||||
id="mask-powermask-path-effect4000_inverse"
|
||||
inkscape:label="filtermask-powermask-path-effect4000"
|
||||
style="color-interpolation-filters:sRGB"
|
||||
height="100"
|
||||
width="100"
|
||||
x="-50"
|
||||
y="-50">
|
||||
<feColorMatrix
|
||||
id="mask-powermask-path-effect4000_primitive1"
|
||||
values="1"
|
||||
type="saturate"
|
||||
result="fbSourceGraphic" />
|
||||
<feColorMatrix
|
||||
id="mask-powermask-path-effect4000_primitive2"
|
||||
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
|
||||
in="fbSourceGraphic" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="9.1371454"
|
||||
inkscape:cx="33.803843"
|
||||
inkscape:cy="32.605832"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer2"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid833" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Back"
|
||||
style="display:inline;opacity:0.997">
|
||||
<path
|
||||
id="rect2692"
|
||||
transform="translate(0.26458378,0.26458346)"
|
||||
mask="none"
|
||||
d="m 7.4083329,10.847917 -6.87916626,0 V 0.52916664 H 14.022917 l 0,5.29166656"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.165;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2.33,2.33;stroke-dashoffset:8.621;stroke-opacity:1;paint-order:normal"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="Front"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="opacity:1;fill:#000000;fill-opacity:0.997319;stroke:#000000;stroke-width:0.535;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 10.433094,5.9254024 v 8.8238546 l 2.129895,-1.217083 1.217083,3.042708 1.521355,-0.608542 -1.217083,-3.042708 h 2.434166 z"
|
||||
id="path2710"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 5.3 KiB |
|
@ -100,19 +100,19 @@ QComboBox:!editable:pressed {{
|
|||
|
||||
|
||||
def splitter_styles(tm: ThemeManager, buf: str) -> str:
|
||||
buf += """
|
||||
buf += f"""
|
||||
QSplitter::handle,
|
||||
QMainWindow::separator {
|
||||
QMainWindow::separator {{
|
||||
height: 16px;
|
||||
}
|
||||
}}
|
||||
QSplitter::handle:vertical,
|
||||
QMainWindow::separator:horizontal {
|
||||
image: url(icons:drag-horizontal.svg);
|
||||
}
|
||||
QMainWindow::separator:horizontal {{
|
||||
image: url({tm.themed_icon("mdi:drag-horizontal-FG_SUBTLE")});
|
||||
}}
|
||||
QSplitter::handle:horizontal,
|
||||
QMainWindow::separator:vertical {
|
||||
image: url(icons:drag-vertical.svg);
|
||||
}
|
||||
QMainWindow::separator:vertical {{
|
||||
image: url({tm.themed_icon("mdi:drag-vertical-FG_SUBTLE")});
|
||||
}}
|
||||
"""
|
||||
return buf
|
||||
|
||||
|
@ -156,21 +156,21 @@ QComboBox::drop-down {{
|
|||
border-bottom-right-radius: {tm.var(props.BORDER_RADIUS)};
|
||||
}}
|
||||
QComboBox::down-arrow {{
|
||||
image: url(icons:chevron-down.svg);
|
||||
image: url({tm.themed_icon("mdi:chevron-down")});
|
||||
}}
|
||||
QComboBox::drop-down {{
|
||||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_PRIMARY_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_PRIMARY_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_GRADIENT_END)
|
||||
)
|
||||
};
|
||||
}}
|
||||
QComboBox::drop-down:hover {{
|
||||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_END)
|
||||
)
|
||||
};
|
||||
}}
|
||||
|
@ -288,10 +288,10 @@ QHeaderView::down-arrow {{
|
|||
height: 20px;
|
||||
}}
|
||||
QHeaderView::up-arrow {{
|
||||
image: url(icons:menu-up.svg);
|
||||
image: url({tm.themed_icon("mdi:menu-up")});
|
||||
}}
|
||||
QHeaderView::down-arrow {{
|
||||
image: url(icons:menu-down.svg);
|
||||
image: url({tm.themed_icon("mdi:menu-down")});
|
||||
}}
|
||||
"""
|
||||
return buf
|
||||
|
@ -306,8 +306,8 @@ QSpinBox::down-button {{
|
|||
border: 1px solid {tm.var(colors.BUTTON_BORDER)};
|
||||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_PRIMARY_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_PRIMARY_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_GRADIENT_END)
|
||||
)
|
||||
};
|
||||
}}
|
||||
|
@ -316,8 +316,8 @@ QSpinBox::down-button:pressed {{
|
|||
border: 1px solid {tm.var(colors.BUTTON_PRESSED_BORDER)};
|
||||
background: {
|
||||
button_pressed_gradient(
|
||||
tm.var(colors.BUTTON_PRIMARY_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_PRIMARY_GRADIENT_END),
|
||||
tm.var(colors.BUTTON_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_GRADIENT_END),
|
||||
tm.var(colors.BUTTON_PRESSED_SHADOW)
|
||||
)
|
||||
}
|
||||
|
@ -326,8 +326,8 @@ QSpinBox::up-button:hover,
|
|||
QSpinBox::down-button:hover {{
|
||||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_PRIMARY_HOVER_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_END)
|
||||
)
|
||||
};
|
||||
}}
|
||||
|
@ -342,10 +342,10 @@ QSpinBox::down-button {{
|
|||
border-bottom-right-radius: {tm.var(props.BORDER_RADIUS)};
|
||||
}}
|
||||
QSpinBox::up-arrow {{
|
||||
image: url(icons:chevron-up.svg);
|
||||
image: url({tm.themed_icon("mdi:chevron-up")});
|
||||
}}
|
||||
QSpinBox::down-arrow {{
|
||||
image: url(icons:chevron-down.svg);
|
||||
image: url({tm.themed_icon("mdi:chevron-down")});
|
||||
}}
|
||||
QSpinBox::up-arrow,
|
||||
QSpinBox::down-arrow,
|
||||
|
@ -363,12 +363,45 @@ QSpinBox::down-arrow:hover {{
|
|||
}}
|
||||
QSpinBox::up-button:disabled, QSpinBox::up-button:off,
|
||||
QSpinBox::down-button:disabled, QSpinBox::down-button:off {{
|
||||
background: {tm.var(colors.BUTTON_PRIMARY_DISABLED)};
|
||||
background: {tm.var(colors.BUTTON_DISABLED)};
|
||||
}}
|
||||
QSpinBox::up-arrow:off,
|
||||
QSpinBox::down-arrow:off {{
|
||||
image: url({tm.themed_icon("mdi:chevron-down-FG_DISABLED")});
|
||||
}}
|
||||
"""
|
||||
return buf
|
||||
|
||||
|
||||
def checkbox_styles(tm: ThemeManager, buf: str) -> str:
|
||||
buf += f"""
|
||||
QCheckBox {{
|
||||
spacing: 8px;
|
||||
margin: 2px 0;
|
||||
}}
|
||||
QCheckBox::indicator {{
|
||||
border: 1px solid {tm.var(colors.BUTTON_BORDER)};
|
||||
border-radius: {tm.var(props.BORDER_RADIUS)};
|
||||
background: {tm.var(colors.CANVAS_INSET)};
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}}
|
||||
QCheckBox::indicator:hover,
|
||||
QCheckBox::indicator:checked:hover {{
|
||||
border: 2px solid {tm.var(colors.BORDER_STRONG)};
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}}
|
||||
QCheckBox::indicator:checked {{
|
||||
image: url({tm.themed_icon("mdi:check")});
|
||||
}}
|
||||
QCheckBox::indicator:indeterminate {{
|
||||
image: url({tm.themed_icon("mdi:minus-thick")});
|
||||
}}
|
||||
"""
|
||||
return buf
|
||||
|
||||
|
||||
def scrollbar_styles(tm: ThemeManager, buf: str) -> str:
|
||||
buf += f"""
|
||||
QAbstractScrollArea::corner {{
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import subprocess
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable, List, Tuple
|
||||
|
@ -81,8 +83,21 @@ class ThemeManager:
|
|||
|
||||
night_mode = property(get_night_mode, set_night_mode)
|
||||
|
||||
def themed_icon(self, path: str) -> str:
|
||||
"Fetch themed version of svg."
|
||||
from aqt.utils import aqt_data_folder
|
||||
|
||||
if m := re.match(r"(?:mdi:)(.+)$", path):
|
||||
name = m.group(1)
|
||||
else:
|
||||
return path
|
||||
|
||||
filename = f"{name}-{'dark' if self.night_mode else 'light'}.svg"
|
||||
|
||||
return os.path.join(aqt_data_folder(), "qt", "icons", filename)
|
||||
|
||||
def icon_from_resources(self, path: str | ColoredIcon) -> QIcon:
|
||||
"Fetch icon from Qt resources, and invert if in night mode."
|
||||
"Fetch icon from Qt resources."
|
||||
if self.night_mode:
|
||||
cache = self._icon_cache_light
|
||||
else:
|
||||
|
@ -99,11 +114,14 @@ class ThemeManager:
|
|||
|
||||
if isinstance(path, str):
|
||||
# default black/white
|
||||
icon = QIcon(path)
|
||||
if self.night_mode:
|
||||
img = icon.pixmap(self._icon_size, self._icon_size).toImage()
|
||||
img.invertPixels()
|
||||
icon = QIcon(QPixmap(img))
|
||||
if "mdi:" in path:
|
||||
icon = QIcon(self.themed_icon(path))
|
||||
else:
|
||||
icon = QIcon(path)
|
||||
if self.night_mode:
|
||||
img = icon.pixmap(self._icon_size, self._icon_size).toImage()
|
||||
img.invertPixels()
|
||||
icon = QIcon(QPixmap(img))
|
||||
else:
|
||||
# specified colours
|
||||
icon = QIcon(path.path)
|
||||
|
@ -193,6 +211,7 @@ class ThemeManager:
|
|||
if not is_mac:
|
||||
from aqt.stylesheets import (
|
||||
button_styles,
|
||||
checkbox_styles,
|
||||
combobox_styles,
|
||||
general_styles,
|
||||
scrollbar_styles,
|
||||
|
@ -210,6 +229,7 @@ class ThemeManager:
|
|||
tabwidget_styles(self, buf),
|
||||
table_styles(self, buf),
|
||||
spinbox_styles(self, buf),
|
||||
checkbox_styles(self, buf),
|
||||
scrollbar_styles(self, buf),
|
||||
]
|
||||
)
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
);
|
||||
}
|
||||
}
|
||||
@else if $key == "default" {
|
||||
@return map.set($output, $name, map.get($map, $key));
|
||||
}
|
||||
}
|
||||
@return $output;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,12 @@ $vars: (
|
|||
),
|
||||
),
|
||||
colors: (
|
||||
white: (
|
||||
default: white,
|
||||
),
|
||||
black: (
|
||||
default: black,
|
||||
),
|
||||
fg: (
|
||||
default: (
|
||||
light: palette(darkgray, 9),
|
||||
|
@ -28,8 +34,8 @@ $vars: (
|
|||
dark: palette(lightgray, 3),
|
||||
),
|
||||
disabled: (
|
||||
light: palette(darkgray, 3),
|
||||
dark: palette(lightgray, 6),
|
||||
light: palette(darkgray, 2),
|
||||
dark: palette(lightgray, 8),
|
||||
),
|
||||
faint: (
|
||||
light: palette(lightgray, 7),
|
||||
|
@ -67,6 +73,10 @@ $vars: (
|
|||
light: palette(lightgray, 5),
|
||||
dark: palette(darkgray, 4),
|
||||
),
|
||||
strong: (
|
||||
light: palette(lightgray, 9),
|
||||
dark: palette(darkgray, 1),
|
||||
),
|
||||
focus: (
|
||||
light: palette(blue, 5),
|
||||
dark: palette(blue, 5),
|
||||
|
@ -91,6 +101,10 @@ $vars: (
|
|||
dark: palette(darkgray, 9),
|
||||
),
|
||||
),
|
||||
disabled: (
|
||||
light: color.scale(palette(lightgray, 5), $alpha: -50%),
|
||||
dark: color.scale(palette(darkgray, 3), $alpha: -50%),
|
||||
),
|
||||
gradient: (
|
||||
start: (
|
||||
light: white,
|
||||
|
|
Loading…
Reference in New Issue