Commit 7e7caf2a authored by Artem Grinev's avatar Artem Grinev Committed by Nate Graham
Browse files

gtk3, gtk4: Blue ocean checkboxes

This MR adds a Blue Ocean-styled checkboxes and radio buttons. 
They follow Adwaita's approach to draw box in CSS and provide the image itself in a SVG. This allows us to control coloring of the box more precisely and also add an check/uncheck animation.

CCBUG: 443919
parent 9cae70a5
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="14"
height="14"
viewBox="0 0 14 14"
fill="none"
version="1.1"
id="svg27"
sodipodi:docname="bullet-symbolic.svg"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs7" />
<sodipodi:namedview
id="namedview5"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="15.789112"
inkscape:cx="6.618485"
inkscape:cy="5.5417936"
inkscape:window-width="1320"
inkscape:window-height="707"
inkscape:window-x="46"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="svg27" />
<g
filter="url(#filter0_d_735_2307)"
id="g4278"
transform="translate(-0.30520703,-0.06685129)" />
<circle
class="fg"
cx="7"
cy="7"
fill="#08293a"
id="circle4274"
style="stroke-width:0.999997"
r="3" />
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
version="1.1"
id="svg27"
sodipodi:docname="checkmark-symbolic.svg"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs7" />
<sodipodi:namedview
id="namedview5"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
showgrid="true"
inkscape:zoom="44.636117"
inkscape:cx="10.227144"
inkscape:cy="7.0458638"
inkscape:window-width="1320"
inkscape:window-height="707"
inkscape:window-x="46"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="g1325"
showguides="true"
inkscape:guide-bbox="true" />
<g
id="g1325">
<path
class="fg"
d="M 13.586,3.5430001 7,10.129 3.414,6.5429998 2,7.9569998 7,12.957 15,4.9569999 Z"
fill="#000000"
id="path7"
sodipodi:nodetypes="ccccccc" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="14"
height="14"
viewBox="0 0 14 14"
fill="none"
version="1.1"
id="svg27"
sodipodi:docname="dash-symbolic.svg"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs7" />
<sodipodi:namedview
id="namedview5"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="51.012703"
inkscape:cx="7.4981323"
inkscape:cy="6.6846095"
inkscape:window-width="1920"
inkscape:window-height="1053"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg27" />
<path
class="fg"
id="path1172"
style="color:#000000;fill:#000000;stroke-width:0.999664;-inkscape-stroke:none"
d="M 2 6 L 2 8 L 4 8 L 4 6 L 2 6 z M 6 6 L 6 8 L 8 8 L 8 6 L 6 6 z M 10 6 L 10 8 L 12 8 L 12 6 L 10 6 z " />
</svg>
......@@ -18,65 +18,122 @@ radiobutton.text-button {
margin-right: 4px;
}
}
&:active check,
&:active radio {
-gtk-icon-transform: translate(1px, 1px);
}
}
check,
radio {
transition: 0.1s;
margin: 0 4px;
&:only-child {
margin: 0;
}
min-height: 18px;
min-width: 18px;
min-height: 14px;
min-width: 14px;
//border: none;
animation: none;
background-color: transparent;
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus"),
success gtk("@borders"),
warning gtk("@theme_button_background_normal");
-gtk-icon-shadow: 1px 1px rgba(35, 38, 41, 0.2);
animation-timing-function: $ease-out-quad;
background-color: gtk("@theme_base_color");
border: 1px solid gtkalpha(
gtk("@theme_button_foreground_normal"),
0.333
);
-gtk-icon-shadow: none;
-gtk-icon-palette: fg gtk("@theme_fg_color");
&:hover {
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus"),
success gtk("@theme_button_decoration_focus"),
warning gtk("@theme_button_background_normal");
border: 1px solid gtk("@theme_button_decoration_hover");
}
&:disabled {
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus_insensitive"),
success gtk("@insensitive_borders"),
warning gtk("@theme_button_background_insensitive");
background-color: gtkalpha(
gtk("@theme_base_color"),
0.03
);
border-color: gtkalpha(
gtk("@theme_button_foreground_normal"),
0.222
);
}
&:focus {
border-color: gtk("@theme_button_decoration_focus");
}
&:indeterminate,
&:checked {
border-color: gtk("@theme_button_decoration_hover");
background-color: gtkalpha(
gtk("@theme_button_decoration_hover"),
0.333
);
&:backdrop {
background-color: gtkalpha(
gtk("@theme_button_decoration_hover"),
0.03
);
border-color: gtkalpha(
gtk("@theme_button_decoration_hover"),
0.3
);
}
&:disabled {
background-color: gtkalpha(
gtk("@theme_button_foreground_normal"),
0.03
);
border-color: gtkalpha(
gtk("@theme_button_decoration_hover"),
0.3
);
-gtk-icon-palette: fg gtk("@insensitive_fg_color");
-gtk-icon-effect: none;
}
}
&:indeterminate {
-gtk-icon-source: -gtk-recolor(url("../assets/dash-symbolic.svg"));
}
menu menuitem & {
margin: 0; // this is a workaround for a menu check/radio size allocation issue
min-height: 18px;
min-width: 18px;
min-height: 14px;
min-width: 14px;
background-color: transparent;
box-shadow: none;
-gtk-icon-shadow: none;
animation: none;
}
}
@each $type in ("check", "radio") {
#{$type} {
-gtk-icon-source: -gtk-recolor(
url("../assets/breeze-#{$type}-unchecked-symbolic.svg")
);
@each $state in ("checked", "indeterminate") {
&:#{$state} {
-gtk-icon-source: -gtk-recolor(
url("../assets/breeze-#{$type}-#{$state}-symbolic.svg")
);
}
}
check{
border-radius: $r;
&:checked {
-gtk-icon-source: -gtk-recolor(url("../assets/checkmark-symbolic.svg"));
}
}
radio {
border-radius: 50%;
&:checked {
-gtk-icon-source: -gtk-recolor(url("../assets/bullet-symbolic.svg"));
}
}
radio:not(:indeterminate):not(:checked):active:not(:backdrop) { -gtk-icon-transform: scale(0); }
check:not(:indeterminate):not(:checked):active:not(:backdrop) { -gtk-icon-transform: translate(-4px, 3px) scale(0) }
radio,
check {
&:active { -gtk-icon-transform: scale(0, 1); }
&:checked:not(:backdrop), &:indeterminate:not(:backdrop) {
-gtk-icon-transform: unset;
}
}
......@@ -177,9 +177,6 @@ menuitem {
}
check,
radio {
min-height: 18px;
min-width: 18px;
&:dir(ltr) {
margin-right: 6px;
}
......@@ -187,10 +184,6 @@ menuitem {
margin-left: 6px;
}
}
&:active check,
&:active radio {
-gtk-icon-transform: translate(1px, 1px);
}
}
/***************
* Popovers *
......@@ -216,41 +209,6 @@ modelbutton.flat,
@extend %undecorated_button;
color: gtk("@theme_unfocused_fg_color");
}
check,
radio {
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus"),
success gtk("@borders"),
warning gtk("@theme_button_background_normal");
-gtk-icon-shadow: 1px 1px rgba(35, 38, 41, 0.2);
&:hover {
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus"),
success gtk("@theme_button_decoration_focus"),
warning gtk("@theme_button_background_normal");
}
&:disabled {
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus_insensitive"),
success gtk("@insensitive_borders"),
warning gtk("@theme_button_background_insensitive");
}
}
@each $type in ("check", "radio") {
#{$type} {
-gtk-icon-source: -gtk-recolor(
url("../assets/breeze-#{$type}-unchecked-symbolic.svg")
);
@each $state in ("checked", "indeterminate") {
&:#{$state} {
-gtk-icon-source: -gtk-recolor(
url("../assets/breeze-#{$type}-#{$state}-symbolic.svg")
);
}
}
}
}
// FIXME: remove the following when the checks/radios rewrite lands
check:last-child,
......@@ -262,10 +220,7 @@ modelbutton.flat,
radio:first-child {
margin-left: 0px;
}
&:active check,
&:active radio {
-gtk-icon-transform: translate(1px, 1px);
}
}
modelbutton.flat arrow {
......
......@@ -18,65 +18,121 @@ radiobutton.text-button {
margin-right: 4px;
}
}
&:active check,
&:active radio {
-gtk-icon-transform: translate(1px, 1px);
}
}
check,
radio {
transition: 0.1s;
margin: 0 4px;
&:only-child {
margin: 0;
}
min-height: 18px;
min-width: 18px;
min-height: 14px;
min-width: 14px;
//border: none;
animation: none;
background-color: transparent;
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus"),
success gtk("@borders"),
warning gtk("@theme_button_background_normal");
-gtk-icon-shadow: 1px 1px rgba(35, 38, 41, 0.2);
animation-timing-function: $ease-out-quad;
background-color: gtk("@theme_base_color");
border: 1px solid gtkalpha(
gtk("@theme_button_foreground_normal"),
0.333
);
-gtk-icon-shadow: none;
-gtk-icon-palette: fg gtk("@theme_fg_color");
&:hover {
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus"),
success gtk("@theme_button_decoration_focus"),
warning gtk("@theme_button_background_normal");
border: 1px solid gtk("@theme_button_decoration_hover");
}
&:disabled {
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus_insensitive"),
success gtk("@insensitive_borders"),
warning gtk("@theme_button_background_insensitive");
background-color: gtkalpha(
gtk("@theme_base_color"),
0.03
);
border-color: gtkalpha(
gtk("@theme_button_foreground_normal"),
0.222
);
}
&:focus {
border-color: gtk("@theme_button_decoration_focus");
}
&:indeterminate,
&:checked {
border-color: gtk("@theme_button_decoration_hover");
background-color: gtkalpha(
gtk("@theme_button_decoration_hover"),
0.333
);
&:backdrop {
background-color: gtkalpha(
gtk("@theme_button_decoration_hover"),
0.03
);
border-color: gtkalpha(
gtk("@theme_button_decoration_hover"),
0.3
);
}
&:disabled {
background-color: gtkalpha(
gtk("@theme_button_foreground_normal"),
0.03
);
border-color: gtkalpha(
gtk("@theme_button_decoration_hover"),
0.3
);
-gtk-icon-palette: fg gtk("@insensitive_fg_color");
}
}
&:indeterminate {
-gtk-icon-source: -gtk-recolor(url("../assets/dash-symbolic.svg"));
}
menu menuitem & {
margin: 0; // this is a workaround for a menu check/radio size allocation issue
min-height: 18px;
min-width: 18px;
min-height: 14px;
min-width: 14px;
background-color: transparent;
box-shadow: none;
-gtk-icon-shadow: none;
animation: none;
}
}
@each $type in ("check", "radio") {
#{$type} {
-gtk-icon-source: -gtk-recolor(
url("../assets/breeze-#{$type}-unchecked-symbolic.svg")
);
@each $state in ("checked", "indeterminate") {
&:#{$state} {
-gtk-icon-source: -gtk-recolor(
url("../assets/breeze-#{$type}-#{$state}-symbolic.svg")
);
}
}
check{
border-radius: $r;
&:checked {
-gtk-icon-source: -gtk-recolor(url("../assets/checkmark-symbolic.svg"));
}
}
radio {
border-radius: 50%;
&:checked {
-gtk-icon-source: -gtk-recolor(url("../assets/bullet-symbolic.svg"));
}
}
radio:not(:indeterminate):not(:checked):active:not(:backdrop) { -gtk-icon-transform: scale(0); }
check:not(:indeterminate):not(:checked):active:not(:backdrop) { -gtk-icon-transform: translate(-4px, 3px) scale(0) }
radio,
check {
&:active { -gtk-icon-transform: scale(0, 1); }
&:checked:not(:backdrop), &:indeterminate:not(:backdrop) {
-gtk-icon-transform: unset;
}
}
......@@ -181,9 +181,6 @@ menuitem {
}
check,
radio {
min-height: 18px;
min-width: 18px;
&:dir(ltr) {
margin-right: 6px;
}
......@@ -191,10 +188,6 @@ menuitem {
margin-left: 6px;
}
}
&:active check,
&:active radio {
-gtk-icon-transform: translate(1px, 1px);
}
}
/***************
* Popovers *
......@@ -222,41 +215,6 @@ modelbutton.flat,
@extend %undecorated_button;
color: gtk("@theme_unfocused_fg_color");
}
check,
radio {
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus"),
success gtk("@borders"),
warning gtk("@theme_button_background_normal");
-gtk-icon-shadow: 1px 1px rgba(35, 38, 41, 0.2);
&:hover {
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus"),
success gtk("@theme_button_decoration_focus"),
warning gtk("@theme_button_background_normal");
}
&:disabled {
-gtk-icon-palette: error
gtk("@theme_button_decoration_focus_insensitive"),
success gtk("@insensitive_borders"),
warning gtk("@theme_button_background_insensitive");
}
}
@each $type in ("check", "radio") {
#{$type} {
-gtk-icon-source: -gtk-recolor(
url("../assets/breeze-#{$type}-unchecked-symbolic.svg")
);
@each $state in ("checked", "indeterminate") {
&:#{$state} {
-gtk-icon-source: -gtk-recolor(
url("../assets/breeze-#{$type}-#{$state}-symbolic.svg")
);
}
}
}
}
// FIXME: remove the following when the checks/radios rewrite lands
check:last-child,
......@@ -268,10 +226,6 @@ modelbutton.flat,
radio:first-child {
margin-left: 0px;
}
&:active check,
&:active radio {
-gtk-icon-transform: translate(1px, 1px);
}
}
modelbutton.flat arrow {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment