switch: Style switches with pure CSS

Drop hardcoded assets, have a handle actor instead, change its align to
move it.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2717>
This commit is contained in:
Daniel Ruiz de Alegría 2019-05-07 15:20:59 +02:00 committed by Florian Müllner
parent e75839bd5d
commit 259eaa9bbb
7 changed files with 63 additions and 33 deletions

View File

@ -10,10 +10,6 @@
<file>pad-osd.css</file>
<file>process-working-light.svg</file>
<file>process-working-dark.svg</file>
<file>toggle-off.svg</file>
<file>toggle-off-light.svg</file>
<file>toggle-on.svg</file>
<file>toggle-on-light.svg</file>
<file>workspace-placeholder.svg</file>
</gresource>
</gresources>

View File

@ -1,18 +1,40 @@
/* Switches */
// these are equal to the size of the SVG assets
$switch_height: 26px;
$switch_width: 46px;
$switch_handle_size: 20px;
.toggle-switch {
color: $fg_color;
height: $switch_height;
width: $switch_width;
background-size: contain;
background-image: if($variant == 'light', url("resource:///org/gnome/shell/theme/toggle-off-light.svg"),url("resource:///org/gnome/shell/theme/toggle-off.svg"));
&:checked {
background-image: if($variant == 'light', url("resource:///org/gnome/shell/theme/toggle-on-light.svg"),url("resource:///org/gnome/shell/theme/toggle-on.svg"));
border-radius: $forced_circular_radius;
transition-duration: 100ms;
color: $fg_color;
@if $contrast == 'high' {
background: transparentize(if($variant == 'light', black, white), .7);
} @else {
background: transparentize(if($variant == 'light', black, white), .85);
}
& StIcon {icon-size: $base_icon_size;}
StIcon {
icon-size: $base_icon_size;
}
.handle {
margin: 3px;
width: $switch_handle_size;
height: $switch_handle_size;
border-radius: $forced_circular_radius;
background: if($variant == 'light', white, mix(white, $bg_color, 80%));
box-shadow: 0 2px 4px transparentize(black, .8);
transition-duration: 100ms;
}
&:checked {
background: $selected_bg_color;
color: $selected_fg_color;
.handle {
background: white;
}
}
}

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="46" height="26"><g transform="matrix(-1 0 0 1 0 -291.18)"><rect width="46" height="26" x="-46" y="291.18" fill="#3081e3" rx="12.458" ry="13" style="fill:#c0bfbc;stroke:none;stroke-width:1;marker:none"/><rect width="20" height="20" x="-23" y="295.18" fill="#f8f7f7" rx="10" ry="10" style="fill:#000;fill-opacity:.2;stroke:none;stroke-width:1;marker:none"/><rect width="20" height="20" x="-23" y="294.18" fill="#f8f7f7" rx="10" ry="10" style="stroke:none;stroke-width:1;marker:none"/></g></svg>

Before

Width:  |  Height:  |  Size: 539 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="46" height="26"><g transform="matrix(-1 0 0 1 0 -291.18)"><rect width="46" height="26" x="-46" y="291.18" fill="#3081e3" rx="12.458" ry="13" style="fill:#fff;fill-opacity:.15;stroke:none;stroke-width:1;marker:none"/><rect width="20" height="20" x="-23" y="295.18" fill="#f8f7f7" rx="10" ry="10" style="fill:#000;fill-opacity:.2;stroke:none;stroke-width:1;marker:none"/><rect width="20" height="20" x="-23" y="294.18" fill="#f8f7f7" rx="10" ry="10" style="fill:#fff;fill-opacity:1;stroke:none;stroke-width:1;marker:none"/></g></svg>

Before

Width:  |  Height:  |  Size: 578 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="46" height="26"><g transform="translate(0 -291.18)"><rect width="46" height="26" y="291.18" fill="#3081e3" ry="13" style="fill:#3584e4;stroke:none;stroke-width:1;marker:none"/><rect width="20" height="20" x="23" y="295.18" fill="#f8f7f7" rx="10" ry="10" style="fill:#000;fill-opacity:.2;stroke:none;stroke-width:1;marker:none"/><rect width="20" height="20" x="23" y="294.18" fill="#f8f7f7" rx="10" ry="10" style="stroke:none;stroke-width:1;marker:none"/></g></svg>

Before

Width:  |  Height:  |  Size: 511 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="46" height="26"><g transform="translate(0 -291.18)"><rect width="46" height="26" y="291.18" fill="#3081e3" rx="12.458" ry="13" style="fill:#3584e4;stroke:none;stroke-width:1;marker:none"/><rect width="20" height="20" x="23" y="295.18" fill="#f8f7f7" rx="10" ry="10" style="fill:#000;fill-opacity:.2;stroke:none;stroke-width:1;marker:none"/><rect width="20" height="20" x="23" y="294.18" fill="#f8f7f7" rx="10" ry="10" style="fill:#fff;stroke:none;stroke-width:1;marker:none"/></g></svg>

Before

Width:  |  Height:  |  Size: 533 B

View File

@ -336,21 +336,24 @@ export const Switch = GObject.registerClass({
GObject.ParamFlags.READWRITE,
false),
},
}, class Switch extends St.Bin {
}, class Switch extends St.Widget {
_init(state) {
this._state = false;
super._init({
style_class: 'toggle-switch',
accessible_role: Atk.Role.CHECK_BOX,
});
const box = new St.BoxLayout({
x_expand: true,
y_expand: true,
constraints: new Clutter.BindConstraint({
source: this,
coordinate: Clutter.BindCoordinate.SIZE,
}),
});
super._init({
style_class: 'toggle-switch',
child: box,
accessible_role: Atk.Role.CHECK_BOX,
state,
});
this.add_child(box);
this._onIcon = new St.Icon({
icon_name: 'switch-on-symbolic',
@ -368,6 +371,20 @@ export const Switch = GObject.registerClass({
});
box.add_child(this._offIcon);
this._handle = new St.Widget({
style_class: 'handle',
y_align: Clutter.ActorAlign.CENTER,
x_align: Clutter.ActorAlign.START,
x_expand: true,
constraints: new Clutter.BindConstraint({
source: this,
coordinate: Clutter.BindCoordinate.SIZE,
}),
});
this.add_child(this._handle);
this.state = state;
this._a11ySettings = new Gio.Settings({
schema_id: 'org.gnome.desktop.a11y.interface',
});
@ -375,8 +392,6 @@ export const Switch = GObject.registerClass({
this._a11ySettings.connectObject('changed::show-status-shapes',
() => this._updateIconOpacity(),
this);
this.connect('notify::state',
() => this._updateIconOpacity());
this._updateIconOpacity();
}
@ -384,10 +399,8 @@ export const Switch = GObject.registerClass({
const activeOpacity = this._a11ySettings.get_boolean('show-status-shapes')
? 255. : 0.;
this._onIcon.opacity = this.state
? activeOpacity : 0.;
this._offIcon.opacity = this.state
? 0. : activeOpacity;
this._onIcon.opacity = activeOpacity;
this._offIcon.opacity = activeOpacity;
}
get state() {
@ -398,10 +411,13 @@ export const Switch = GObject.registerClass({
if (this._state === state)
return;
if (state)
if (state) {
this.add_style_pseudo_class('checked');
else
this._handle.x_align = Clutter.ActorAlign.END;
} else {
this.remove_style_pseudo_class('checked');
this._handle.x_align = Clutter.ActorAlign.START;
}
this._state = state;
this.notify('state');