Refactor icons jammy (#108)

* chore: add icons and installation

* refactor: use the new battery icons

* refactor: use audio applet icons

* chore dependency cleanup

* chore: remove icons included in cosmic-icons package

* refactor: use icons for signal strength and fix handling of new connections

* fix: improve some logic for the networking applet

* chore: add cosmic-icons to Depends

* feat: use notifications icons

* chore: set bluetooth icon depending on state

* fix: set default font and text size

* feat (network): add airplane-mode message

* feat (battery): add display icons to the battery applet

* fix (battery): logic for selecting the battery icon & use new battery icons
This commit is contained in:
Ashley Wulber 2023-08-08 16:18:12 -04:00 committed by GitHub
parent 76ce8838b5
commit 3ad64df5f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
77 changed files with 653 additions and 615 deletions

View file

@ -120,7 +120,9 @@ impl CosmicAppletHelper {
resizable: None,
..Default::default()
}),
..cosmic::settings_with_flags(flags)
default_text_size: 18.0,
default_font: cosmic::font::FONT,
..Settings::with_flags(flags)
}
}

View file

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
<defs>
<filter id="alpha" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
<feColorMatrix type="matrix" in="SourceGraphic" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="mask0">
<g filter="url(#alpha)">
<rect x="0" y="0" width="16" height="16" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip1">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10818" clip-path="url(#clip1)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 123.503906 236 C 123.503906 268.863281 96.863281 295.503906 64 295.503906 C 31.136719 295.503906 4.496094 268.863281 4.496094 236 C 4.496094 203.136719 31.136719 176.496094 64 176.496094 C 96.863281 176.496094 123.503906 203.136719 123.503906 236 Z M 123.503906 236 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask1">
<g filter="url(#alpha)">
<rect x="0" y="0" width="16" height="16" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip2">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10821" clip-path="url(#clip2)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 29.195312 180.496094 L 98.804688 180.496094 C 103.609375 180.496094 107.503906 184.046875 107.503906 188.425781 L 107.503906 283.574219 C 107.503906 287.953125 103.609375 291.503906 98.804688 291.503906 L 29.195312 291.503906 C 24.390625 291.503906 20.496094 287.953125 20.496094 283.574219 L 20.496094 188.425781 C 20.496094 184.046875 24.390625 180.496094 29.195312 180.496094 Z M 29.195312 180.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask2">
<g filter="url(#alpha)">
<rect x="0" y="0" width="16" height="16" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip3">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10824" clip-path="url(#clip3)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 20.417969 184.496094 L 107.582031 184.496094 C 111.957031 184.496094 115.503906 188.042969 115.503906 192.417969 L 115.503906 279.582031 C 115.503906 283.957031 111.957031 287.503906 107.582031 287.503906 L 20.417969 287.503906 C 16.042969 287.503906 12.496094 283.957031 12.496094 279.582031 L 12.496094 192.417969 C 12.496094 188.042969 16.042969 184.496094 20.417969 184.496094 Z M 20.417969 184.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask3">
<g filter="url(#alpha)">
<rect x="0" y="0" width="16" height="16" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip4">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10827" clip-path="url(#clip4)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 16.425781 200.496094 L 111.574219 200.496094 C 115.953125 200.496094 119.503906 204.390625 119.503906 209.195312 L 119.503906 278.804688 C 119.503906 283.609375 115.953125 287.503906 111.574219 287.503906 L 16.425781 287.503906 C 12.046875 287.503906 8.496094 283.609375 8.496094 278.804688 L 8.496094 209.195312 C 8.496094 204.390625 12.046875 200.496094 16.425781 200.496094 Z M 16.425781 200.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
</defs>
<g id="surface10764">
<rect x="0" y="0" width="16" height="16" style="fill:rgb(94.117647%,94.117647%,94.117647%);fill-opacity:1;stroke:none;"/>
<use xlink:href="#surface10818" transform="matrix(1,0,0,1,-168,-16)" mask="url(#mask0)"/>
<use xlink:href="#surface10821" transform="matrix(1,0,0,1,-168,-16)" mask="url(#mask1)"/>
<use xlink:href="#surface10824" transform="matrix(1,0,0,1,-168,-16)" mask="url(#mask2)"/>
<use xlink:href="#surface10827" transform="matrix(1,0,0,1,-168,-16)" mask="url(#mask3)"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.3 KiB

View file

@ -1,147 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128px" height="128px" viewBox="0 0 128 128" version="1.1">
<defs>
<filter id="alpha" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
<feColorMatrix type="matrix" in="SourceGraphic" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="mask0">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip1">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10726" clip-path="url(#clip1)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 123.503906 236 C 123.503906 268.863281 96.863281 295.503906 64 295.503906 C 31.136719 295.503906 4.496094 268.863281 4.496094 236 C 4.496094 203.136719 31.136719 176.496094 64 176.496094 C 96.863281 176.496094 123.503906 203.136719 123.503906 236 Z M 123.503906 236 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask1">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip2">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10729" clip-path="url(#clip2)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 29.195312 180.496094 L 98.804688 180.496094 C 103.609375 180.496094 107.503906 184.046875 107.503906 188.425781 L 107.503906 283.574219 C 107.503906 287.953125 103.609375 291.503906 98.804688 291.503906 L 29.195312 291.503906 C 24.390625 291.503906 20.496094 287.953125 20.496094 283.574219 L 20.496094 188.425781 C 20.496094 184.046875 24.390625 180.496094 29.195312 180.496094 Z M 29.195312 180.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask2">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip3">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10732" clip-path="url(#clip3)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 20.417969 184.496094 L 107.582031 184.496094 C 111.957031 184.496094 115.503906 188.042969 115.503906 192.417969 L 115.503906 279.582031 C 115.503906 283.957031 111.957031 287.503906 107.582031 287.503906 L 20.417969 287.503906 C 16.042969 287.503906 12.496094 283.957031 12.496094 279.582031 L 12.496094 192.417969 C 12.496094 188.042969 16.042969 184.496094 20.417969 184.496094 Z M 20.417969 184.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask3">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip4">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10735" clip-path="url(#clip4)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 16.425781 200.496094 L 111.574219 200.496094 C 115.953125 200.496094 119.503906 204.390625 119.503906 209.195312 L 119.503906 278.804688 C 119.503906 283.609375 115.953125 287.503906 111.574219 287.503906 L 16.425781 287.503906 C 12.046875 287.503906 8.496094 283.609375 8.496094 278.804688 L 8.496094 209.195312 C 8.496094 204.390625 12.046875 200.496094 16.425781 200.496094 Z M 16.425781 200.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask5">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip7">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10726" clip-path="url(#clip7)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 123.503906 236 C 123.503906 268.863281 96.863281 295.503906 64 295.503906 C 31.136719 295.503906 4.496094 268.863281 4.496094 236 C 4.496094 203.136719 31.136719 176.496094 64 176.496094 C 96.863281 176.496094 123.503906 203.136719 123.503906 236 Z M 123.503906 236 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask6">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip8">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10729" clip-path="url(#clip8)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 29.195312 180.496094 L 98.804688 180.496094 C 103.609375 180.496094 107.503906 184.046875 107.503906 188.425781 L 107.503906 283.574219 C 107.503906 287.953125 103.609375 291.503906 98.804688 291.503906 L 29.195312 291.503906 C 24.390625 291.503906 20.496094 287.953125 20.496094 283.574219 L 20.496094 188.425781 C 20.496094 184.046875 24.390625 180.496094 29.195312 180.496094 Z M 29.195312 180.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask7">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip9">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10732" clip-path="url(#clip9)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 20.417969 184.496094 L 107.582031 184.496094 C 111.957031 184.496094 115.503906 188.042969 115.503906 192.417969 L 115.503906 279.582031 C 115.503906 283.957031 111.957031 287.503906 107.582031 287.503906 L 20.417969 287.503906 C 16.042969 287.503906 12.496094 283.957031 12.496094 279.582031 L 12.496094 192.417969 C 12.496094 188.042969 16.042969 184.496094 20.417969 184.496094 Z M 20.417969 184.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<mask id="mask8">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.1;stroke:none;"/>
</g>
</mask>
<clipPath id="clip10">
<rect x="0" y="0" width="192" height="152"/>
</clipPath>
<g id="surface10735" clip-path="url(#clip10)">
<path style="fill:none;stroke-width:0.99;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.99,0.99;stroke-miterlimit:4;" d="M 16.425781 200.496094 L 111.574219 200.496094 C 115.953125 200.496094 119.503906 204.390625 119.503906 209.195312 L 119.503906 278.804688 C 119.503906 283.609375 115.953125 287.503906 111.574219 287.503906 L 16.425781 287.503906 C 12.046875 287.503906 8.496094 283.609375 8.496094 278.804688 L 8.496094 209.195312 C 8.496094 204.390625 12.046875 200.496094 16.425781 200.496094 Z M 16.425781 200.496094 " transform="matrix(1,0,0,1,8,-156)"/>
</g>
<clipPath id="clip6">
<rect x="0" y="0" width="128" height="128"/>
</clipPath>
<g id="surface10750" clip-path="url(#clip6)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(94.117647%,94.117647%,94.117647%);fill-opacity:1;stroke:none;"/>
<use xlink:href="#surface10726" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask5)"/>
<use xlink:href="#surface10729" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask6)"/>
<use xlink:href="#surface10732" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask7)"/>
<use xlink:href="#surface10735" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask8)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(38.431373%,62.7451%,91.764706%);stroke-opacity:1;stroke-miterlimit:4;" d="M 0 289 L 128 289 " transform="matrix(1,0,0,1,0,-172)"/>
</g>
<clipPath id="clip5">
<rect x="0" y="0" width="128" height="128"/>
</clipPath>
<g id="surface10753" clip-path="url(#clip5)" filter="url(#alpha)">
<use xlink:href="#surface10750"/>
</g>
<mask id="mask4">
<use xlink:href="#surface10753"/>
</mask>
<mask id="mask9">
<g filter="url(#alpha)">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(0%,0%,0%);fill-opacity:0.8;stroke:none;"/>
</g>
</mask>
<linearGradient id="linear0" gradientUnits="userSpaceOnUse" x1="300" y1="235" x2="428" y2="235" gradientTransform="matrix(0.000000000000000023,0.37,-0.98462,0.00000000000000006,295.38501,-30.360001)">
<stop offset="0" style="stop-color:rgb(97.647059%,94.117647%,41.960785%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(96.078432%,76.078433%,6.666667%);stop-opacity:1;"/>
</linearGradient>
<clipPath id="clip12">
<rect x="0" y="0" width="128" height="128"/>
</clipPath>
<g id="surface10747" clip-path="url(#clip12)">
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear0);" d="M 128 80.640625 L 128 128 L 0 128 L 0 80.640625 Z M 128 80.640625 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 13.308594 80.640625 L 60.664062 128 L 81.878906 128 L 34.519531 80.640625 Z M 55.730469 80.640625 L 103.09375 128 L 124.308594 128 L 76.945312 80.640625 Z M 98.160156 80.640625 L 128 110.480469 L 128 89.269531 L 119.371094 80.640625 Z M 0 88.546875 L 0 109.761719 L 18.238281 128 L 39.453125 128 Z M 0 88.546875 "/>
</g>
<clipPath id="clip11">
<rect x="0" y="0" width="128" height="128"/>
</clipPath>
<g id="surface10752" clip-path="url(#clip11)">
<use xlink:href="#surface10747" mask="url(#mask9)"/>
</g>
</defs>
<g id="surface10672">
<rect x="0" y="0" width="128" height="128" style="fill:rgb(94.117647%,94.117647%,94.117647%);fill-opacity:1;stroke:none;"/>
<use xlink:href="#surface10726" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask0)"/>
<use xlink:href="#surface10729" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask1)"/>
<use xlink:href="#surface10732" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask2)"/>
<use xlink:href="#surface10735" transform="matrix(1,0,0,1,-8,-16)" mask="url(#mask3)"/>
<path style="fill:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(38.431373%,62.7451%,91.764706%);stroke-opacity:1;stroke-miterlimit:4;" d="M 0 289 L 128 289 " transform="matrix(1,0,0,1,0,-172)"/>
<use xlink:href="#surface10752" mask="url(#mask4)"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Before After
Before After

View file

@ -49,6 +49,7 @@ struct Audio {
pulse_state: PulseState,
applet_helper: CosmicAppletHelper,
icon_name: String,
input_icon_name: String,
theme: Theme,
popup: Option<window::Id>,
show_media_controls_in_top_panel: bool,
@ -56,6 +57,58 @@ struct Audio {
timeline: Timeline,
}
impl Audio {
fn update_output(&mut self, output: Option<DeviceInfo>) {
self.current_output = output;
self.apply_output_volume();
}
fn apply_output_volume(&mut self) {
let Some(output) = self.current_output.as_ref() else {
self.icon_name = "audio-volume-muted-symbolic".to_string();
return;
};
let volume = output.volume.avg();
let output_volume = VolumeLinear::from(volume).0;
if volume.is_muted() {
self.icon_name = "audio-volume-muted-symbolic".to_string();
} else if output_volume < 0.25 {
self.icon_name = "audio-volume-low-symbolic".to_string();
} else if output_volume < 0.5 {
self.icon_name = "audio-volume-medium-symbolic".to_string();
} else if output_volume < 0.75 {
self.icon_name = "audio-volume-high-symbolic".to_string();
} else {
self.icon_name = "audio-volume-overamplified-symbolic".to_string();
}
}
fn update_input(&mut self, input: Option<DeviceInfo>) {
self.current_input = input;
self.apply_input_volume();
}
fn apply_input_volume(&mut self) {
let Some(input) = self.current_input.as_ref() else {
self.input_icon_name = "microphone-sensitivity-muted-symbolic".to_string();
return;
};
let volume = input.volume.avg();
let input_volume = VolumeLinear::from(volume).0;
if volume.is_muted() {
self.input_icon_name = "microphone-sensitivity-muted-symbolic".to_string();
} else if input_volume < 0.33 {
self.input_icon_name = "microphone-sensitivity-low-symbolic".to_string();
} else if input_volume < 0.66 {
self.input_icon_name = "microphone-sensitivity-medium-symbolic".to_string();
} else {
self.input_icon_name = "microphone-sensitivity-high-symbolic".to_string();
}
}
}
#[derive(Debug, PartialEq, Eq)]
enum IsOpen {
None,
@ -96,6 +149,7 @@ impl Application for Audio {
outputs: vec![],
inputs: vec![],
icon_name: "audio-volume-high-symbolic".to_string(),
input_icon_name: "audio-input-microphone-symbolic".to_string(),
applet_helper,
theme,
..Default::default()
@ -165,6 +219,7 @@ impl Application for Audio {
o.volume
.set(o.volume.len(), VolumeLinear(vol / 100.0).into())
});
self.apply_output_volume();
if let PulseState::Connected(connection) = &mut self.pulse_state {
if let Some(device) = &self.current_output {
if let Some(name) = &device.name {
@ -181,6 +236,7 @@ impl Application for Audio {
i.volume
.set(i.volume.len(), VolumeLinear(vol / 100.0).into())
});
self.apply_input_volume();
if let PulseState::Connected(connection) = &mut self.pulse_state {
if let Some(device) = &self.current_input {
if let Some(name) = &device.name {
@ -256,10 +312,10 @@ impl Application for Audio {
.collect()
}
pulse::Message::SetDefaultSink(sink) => {
self.current_output = Some(sink);
self.update_output(Some(sink));
}
pulse::Message::SetDefaultSource(source) => {
self.current_input = Some(source)
self.update_input(Some(source));
}
pulse::Message::Disconnected => {
panic!("Subscriton error handling is bad. This should never happen.")
@ -325,7 +381,7 @@ impl Application for Audio {
} else {
column![
row![
icon("audio-volume-high-symbolic", 24).style(Svg::Symbolic),
icon(self.icon_name.as_str(), 24).style(Svg::Symbolic),
slider(0.0..=100.0, out_f64, Message::SetOutputVolume)
.width(Length::FillPortion(5)),
text(format!("{}%", out_f64.round()))
@ -337,7 +393,7 @@ impl Application for Audio {
.align_items(Alignment::Center)
.padding([8, 24]),
row![
icon("audio-input-microphone-symbolic", 24).style(Svg::Symbolic),
icon(self.input_icon_name.as_str(), 24).style(Svg::Symbolic),
slider(0.0..=100.0, in_f64, Message::SetInputVolume)
.width(Length::FillPortion(5)),
text(format!("{}%", in_f64.round()))

View file

@ -0,0 +1,12 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_412_3870)">
<path d="M0 0.00701904H16V16.007H0V0.00701904Z" fill="#808080" fill-opacity="0.01"/>
<path d="M2 0.00701904C0 0.00701904 0 2.00702 0 2.00702V11.007C0 11.007 0 13.007 2 13.007H14C14 13.007 16 13.007 16 11.007V2.00702C16 2.00702 16 0.00701904 14 0.00701904H2ZM2 2.00702H14V10.007H2V2.00702ZM3 15.007V16.004H13V15.007C13 14.007 12 14.007 12 14.007H3.978C3.978 14.007 3 14.007 3 15.007Z" fill="#232323"/>
<path d="M13 3.00702H3V9.00702H13V3.00702Z" fill="#232323"/>
</g>
<defs>
<clipPath id="clip0_412_3870">
<rect width="16" height="16" fill="white" transform="translate(0 0.00701904)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 745 B

View file

@ -0,0 +1,13 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_412_3869)">
<path d="M0 0.00701904H16V16.007H0V0.00701904Z" fill="#808080" fill-opacity="0.01"/>
<path d="M2 0.00701904C0 0.00701904 0 2.00702 0 2.00702V11.007C0 11.007 0 13.007 2 13.007H14C14 13.007 16 13.007 16 11.007V2.00702C16 2.00702 16 0.00701904 14 0.00701904H2ZM2 2.00702H14V10.007H2V2.00702ZM3 15.007V16.004H13V15.007C13 14.007 12 14.007 12 14.007H3.978C3.978 14.007 3 14.007 3 15.007Z" fill="#232323"/>
<path opacity="0.35" d="M13 3.00702H3V9.00702H13V3.00702Z" fill="#232323"/>
<path d="M13 7.00702H3V9.00702H13V7.00702Z" fill="#232323"/>
</g>
<defs>
<clipPath id="clip0_412_3869">
<rect width="16" height="16" fill="white" transform="translate(0 0.00701904)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 821 B

View file

@ -0,0 +1,13 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_412_3868)">
<path d="M0 0.00701904H16V16.007H0V0.00701904Z" fill="#808080" fill-opacity="0.01"/>
<path d="M2 0.00701904C0 0.00701904 0 2.00702 0 2.00702V11.007C0 11.007 0 13.007 2 13.007H14C14 13.007 16 13.007 16 11.007V2.00702C16 2.00702 16 0.00701904 14 0.00701904H2ZM2 2.00702H14V10.007H2V2.00702ZM3 15.007V16.004H13V15.007C13 14.007 12 14.007 12 14.007H3.978C3.978 14.007 3 14.007 3 15.007Z" fill="#232323"/>
<path opacity="0.35" d="M13 3.00702H3V9.00702H13V3.00702Z" fill="#232323"/>
<path d="M13 5.00702H3V9.00702H13V5.00702Z" fill="#232323"/>
</g>
<defs>
<clipPath id="clip0_412_3868">
<rect width="16" height="16" fill="white" transform="translate(0 0.00701904)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 821 B

View file

@ -0,0 +1,12 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_412_3867)">
<path d="M0 0.00701904H16V16.007H0V0.00701904Z" fill="#808080" fill-opacity="0.01"/>
<path d="M2 0.00701904C0 0.00701904 0 2.00702 0 2.00702V11.007C0 11.007 0 13.007 2 13.007H14C14 13.007 16 13.007 16 11.007V2.00702C16 2.00702 16 0.00701904 14 0.00701904H2ZM2 2.00702H14V10.007H2V2.00702ZM3 15.007V16.004H13V15.007C13 14.007 12 14.007 12 14.007H3.978C3.978 14.007 3 14.007 3 15.007Z" fill="#232323"/>
<path opacity="0.35" d="M13 8.00702H3V9.00702H13V8.00702Z" fill="#232323"/>
</g>
<defs>
<clipPath id="clip0_412_3867">
<rect width="16" height="16" fill="white" transform="translate(0 0.00701904)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 760 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 537 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 537 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#F44336"/>
<path d="M5 5H7V8H5V5Z" fill="#F44336"/>
<circle cx="6" cy="10" r="1" fill="#F44336"/>
</svg>

After

Width:  |  Height:  |  Size: 574 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#F44336"/>
<path d="M6 5H8V8H6V5Z" fill="#F44336"/>
<circle cx="7" cy="10" r="1" fill="#F44336"/>
</svg>

After

Width:  |  Height:  |  Size: 574 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L2 12Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 645 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L2 12Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 645 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L2 12Z" fill="#F44336"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#F44336"/>
</svg>

After

Width:  |  Height:  |  Size: 595 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L2 12Z" fill="#F44336"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#F44336"/>
</svg>

After

Width:  |  Height:  |  Size: 595 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect opacity="0.35" x="1" y="12" width="8" height="12" rx="1" transform="rotate(-90 1 12)" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 646 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect opacity="0.35" x="1" y="12" width="8" height="12" rx="1" transform="rotate(-90 1 12)" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 596 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H3L3 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 649 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H3L3 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 649 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H3L3 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 599 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H3L3 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 599 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H5L5 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 649 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H5L5 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 649 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H5L5 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 599 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H5L5 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 599 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L2 12Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 645 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L2 12Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 645 B

View file

@ -0,0 +1,6 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L2 12Z" fill="#F44336"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#F44336"/>
<path d="M5 5H7V8H5V5Z" fill="#F44336"/>
<circle cx="6" cy="10" r="1" fill="#F44336"/>
</svg>

After

Width:  |  Height:  |  Size: 682 B

View file

@ -0,0 +1,6 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L2 12Z" fill="#F44336"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#F44336"/>
<path d="M6 5H8V8H6V5Z" fill="#F44336"/>
<circle cx="7" cy="10" r="1" fill="#F44336"/>
</svg>

After

Width:  |  Height:  |  Size: 682 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H7L7 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 649 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H7L7 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 649 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H7L7 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 599 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H7L7 12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 599 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H9V12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 647 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H9V12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 647 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H9V12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 597 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4H9V12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 597 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L11 4V12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 650 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L11 4V12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 650 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L11 4V12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H10C10.5523 4 11 4.44772 11 5V11C11 11.5523 10.5523 12 10 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 600 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44772 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L11 4V12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 600 B

View file

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44771 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L12 4V12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
<path d="M9 7H7V5L5 9H7V11L9 7Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 650 B

View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.35" d="M2 12C1.44771 12 1 11.5523 1 11L1 5C1 4.44772 1.44772 4 2 4L12 4V12H2Z" fill="#232323"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 5C0 3.89543 0.895431 3 2 3H12C13.1046 3 14 3.89543 14 5V6L14.0018 6C15.1054 6 16 6.89543 16 8C16 9.10457 15.1054 10 14.0018 10L14 10V11C14 12.1046 13.1046 13 12 13H2C0.89543 13 0 12.1046 0 11V5ZM2 4H12C12.5523 4 13 4.44772 13 5V11C13 11.5523 12.5523 12 12 12H2C1.44772 12 1 11.5523 1 11V5C1 4.44772 1.44772 4 2 4Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 600 B

View file

@ -55,9 +55,11 @@ static MAX_CHARGE: Lazy<id::Toggler> = Lazy::new(id::Toggler::unique);
#[derive(Clone, Default)]
struct CosmicBatteryApplet {
icon_name: String,
display_icon_name: String,
theme: Theme,
charging_limit: bool,
battery_percent: f64,
on_battery: bool,
time_remaining: Duration,
kbd_brightness: f64,
screen_brightness: f64,
@ -71,11 +73,65 @@ struct CosmicBatteryApplet {
timeline: Timeline,
}
impl CosmicBatteryApplet {
fn update_battery(&mut self, mut percent: f64, on_battery: bool) {
percent = percent.clamp(0.0, 100.0);
self.on_battery = on_battery;
self.battery_percent = percent;
let battery_percent = if self.battery_percent > 95.0 && !self.charging_limit {
100
} else if self.battery_percent > 80.0 && !self.charging_limit {
90
} else if self.battery_percent > 65.0 {
80
} else if self.battery_percent > 35.0 {
50
} else if self.battery_percent > 20.0 {
35
} else if self.battery_percent > 14.0 {
20
} else if self.battery_percent > 9.0 {
10
} else if self.battery_percent > 5.0 {
5
} else {
0
};
let limited = if self.charging_limit { "limited-" } else { "" };
let charging = if on_battery { "" } else { "charging-" };
self.icon_name =
format!("cosmic-applet-battery-level-{battery_percent}-{limited}{charging}symbolic",);
}
fn update_display(&mut self, mut percent: f64) {
percent = percent.clamp(0.01, 1.0);
self.screen_brightness = percent;
let screen_brightness = if self.screen_brightness < 0.011 {
"off"
} else if self.screen_brightness < 0.333 {
"low"
} else if self.screen_brightness < 0.666 {
"medium"
} else {
"high"
}
.to_string();
self.display_icon_name =
format!("cosmic-applet-battery-display-brightness-{screen_brightness}-symbolic",);
}
fn set_charging_limit(&mut self, limit: bool) {
self.charging_limit = limit;
self.update_battery(self.battery_percent, self.on_battery);
}
}
#[derive(Debug, Clone)]
enum Message {
TogglePopup,
Update {
icon_name: String,
on_battery: bool,
percent: f64,
time_to_empty: i64,
},
@ -108,6 +164,7 @@ impl Application for CosmicBatteryApplet {
(
CosmicBatteryApplet {
icon_name: "battery-symbolic".to_string(),
display_icon_name: "display-brightness-symbolic".to_string(),
applet_helper,
theme,
..Default::default()
@ -130,14 +187,14 @@ impl Application for CosmicBatteryApplet {
}
}
Message::SetScreenBrightness(brightness) => {
self.screen_brightness = (brightness as f64 / 100.0).clamp(0.01, 1.0);
self.update_display((brightness as f64 / 100.0).clamp(0.01, 1.0));
if let Some(tx) = &self.screen_sender {
let _ = tx.send(ScreenBacklightRequest::Set(self.screen_brightness));
}
}
Message::SetChargingLimit(chain, enable) => {
self.timeline.set_chain(chain).start();
self.charging_limit = enable;
self.set_charging_limit(enable);
}
Message::OpenBatterySettings => {
// TODO Ashley
@ -179,12 +236,11 @@ impl Application for CosmicBatteryApplet {
}
}
Message::Update {
icon_name,
on_battery,
percent,
time_to_empty,
} => {
self.icon_name = icon_name;
self.battery_percent = percent;
self.update_battery(percent, on_battery);
self.time_remaining = Duration::from_secs(time_to_empty as u64);
}
Message::UpdateKbdBrightness(b) => {
@ -199,10 +255,10 @@ impl Application for CosmicBatteryApplet {
Message::InitScreenBacklight(tx, brightness) => {
let _ = tx.send(ScreenBacklightRequest::Get);
self.screen_sender = Some(tx);
self.screen_brightness = brightness;
self.update_display(brightness);
}
Message::UpdateScreenBrightness(b) => {
self.screen_brightness = b;
self.update_display(b);
}
Message::InitProfile(tx, profile) => {
self.power_profile_sender.replace(tx);
@ -236,20 +292,16 @@ impl Application for CosmicBatteryApplet {
.into()
} else {
let name = text(fl!("battery")).size(14);
let description = text(
if "battery-full-charging-symbolic" == self.icon_name
|| "battery-full-charged-symbolic" == self.icon_name
{
format!("{}%", self.battery_percent)
} else {
format!(
"{} {} ({:.0}%)",
format_duration(self.time_remaining),
fl!("until-empty"),
self.battery_percent
)
},
)
let description = text(if !self.on_battery {
format!("{}%", self.battery_percent)
} else {
format!(
"{} {} ({:.0}%)",
format_duration(self.time_remaining),
fl!("until-empty"),
self.battery_percent
)
})
.size(10);
self.applet_helper
.popup_container(
@ -342,7 +394,7 @@ impl Application for CosmicBatteryApplet {
.width(Length::Fill)
.padding([0, 12]),
row![
icon("display-brightness-symbolic", 24).style(Svg::Symbolic),
icon(self.display_icon_name.as_str(), 24).style(Svg::Symbolic),
slider(
1..=100,
(self.screen_brightness * 100.0) as i32,
@ -393,11 +445,11 @@ impl Application for CosmicBatteryApplet {
self.applet_helper.theme_subscription(0).map(Message::Theme),
device_subscription(0).map(
|DeviceDbusEvent::Update {
icon_name,
on_battery,
percent,
time_to_empty,
}| Message::Update {
icon_name,
on_battery,
percent,
time_to_empty,
},

View file

@ -168,19 +168,20 @@ pub fn device_subscription<I: 'static + Hash + Copy + Send + Sync + Debug>(
#[derive(Debug)]
pub enum State {
Ready,
Waiting(DeviceProxy<'static>),
Waiting(UPowerProxy<'static>, DeviceProxy<'static>),
Finished,
}
async fn display_device() -> zbus::Result<DeviceProxy<'static>> {
async fn display_device() -> zbus::Result<(UPowerProxy<'static>, DeviceProxy<'static>)> {
let connection = zbus::Connection::system().await?;
let upower = UPowerProxy::new(&connection).await?;
let upower: UPowerProxy<'_> = UPowerProxy::new(&connection).await?;
let device_path = upower.get_display_device().await?;
DeviceProxy::builder(&connection)
.path(device_path)?
.cache_properties(zbus::CacheProperties::Yes)
.build()
.await
.map(|dp| (upower, dp))
}
async fn start_listening(
@ -189,11 +190,11 @@ async fn start_listening(
) -> State {
match state {
State::Ready => {
if let Ok(device) = display_device().await {
if let Ok((upower, device)) = display_device().await {
_ = output
.send(DeviceDbusEvent::Update {
icon_name: device
.cached_icon_name()
on_battery: upower
.cached_on_battery()
.unwrap_or_default()
.unwrap_or_default(),
percent: device
@ -206,13 +207,13 @@ async fn start_listening(
.unwrap_or_default(),
})
.await;
return State::Waiting(device);
return State::Waiting(upower, device);
}
State::Finished
}
State::Waiting(device) => {
State::Waiting(upower, device) => {
let mut stream = futures::stream_select!(
device.receive_icon_name_changed().await.map(|_| ()),
upower.receive_on_battery_changed().await.map(|_| ()),
device.receive_percentage_changed().await.map(|_| ()),
device.receive_time_to_empty_changed().await.map(|_| ()),
);
@ -220,8 +221,8 @@ async fn start_listening(
Some(_) => {
_ = output
.send(DeviceDbusEvent::Update {
icon_name: device
.cached_icon_name()
on_battery: upower
.cached_on_battery()
.unwrap_or_default()
.unwrap_or_default(),
percent: device
@ -235,7 +236,7 @@ async fn start_listening(
})
.await;
State::Waiting(device)
State::Waiting(upower, device)
}
None => State::Finished,
}
@ -247,7 +248,7 @@ async fn start_listening(
#[derive(Debug, Clone)]
pub enum DeviceDbusEvent {
Update {
icon_name: String,
on_battery: bool,
percent: f64,
time_to_empty: i64,
},

View file

@ -0,0 +1,5 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Status Icons/bluetooth-active-symbolic">
<path id="Vector" d="M8.5 0.0200195C5.453 0.0200195 3 2.69602 3 6.02002V10.02C3 13.344 5.453 16.02 8.5 16.02C11.547 16.02 14 13.344 14 10.02V6.02002C14 2.69602 11.547 0.0200195 8.5 0.0200195V0.0200195ZM8.46 2.08202C8.52712 2.08097 8.59376 2.09344 8.65595 2.1187C8.71815 2.14395 8.77462 2.18147 8.822 2.22902L11.822 5.22902C11.8718 5.27866 11.9106 5.33825 11.9358 5.40389C11.961 5.46953 11.972 5.53975 11.9683 5.60996C11.9645 5.68017 11.946 5.7488 11.9139 5.81136C11.8818 5.87392 11.8368 5.929 11.782 5.97302L9.145 8.08302L11.781 10.192C11.8359 10.236 11.8809 10.291 11.9131 10.3535C11.9453 10.416 11.9639 10.4846 11.9678 10.5549C11.9717 10.6251 11.9607 10.6953 11.9356 10.761C11.9104 10.8267 11.8717 10.8863 11.822 10.936L8.822 13.936C8.75208 14.0057 8.66309 14.0532 8.56624 14.0724C8.4694 14.0916 8.36903 14.0817 8.27781 14.0439C8.18658 14.0062 8.10857 13.9422 8.05362 13.8602C7.99866 13.7782 7.96922 13.6817 7.969 13.583V9.02302L5.781 10.773C5.67714 10.851 5.54699 10.8856 5.4181 10.8693C5.28922 10.8531 5.17172 10.7873 5.09049 10.6859C5.00926 10.5845 4.97068 10.4555 4.9829 10.3262C4.99513 10.1969 5.05721 10.0774 5.156 9.99302L7.543 8.08302L5.156 6.17302C5.10245 6.13279 5.05753 6.08222 5.0239 6.02429C4.99028 5.96637 4.96863 5.90229 4.96025 5.83584C4.95187 5.76939 4.95692 5.70193 4.97511 5.63748C4.99329 5.57302 5.02425 5.51287 5.06613 5.4606C5.10801 5.40834 5.15996 5.36502 5.2189 5.33322C5.27785 5.30142 5.34258 5.28178 5.40926 5.27548C5.47593 5.26917 5.5432 5.27633 5.60706 5.29652C5.67092 5.31671 5.73007 5.34953 5.781 5.39302L7.969 7.14302V2.58302C7.96898 2.45179 8.02056 2.32581 8.11261 2.23226C8.20465 2.13872 8.32978 2.08512 8.461 2.08302L8.46 2.08202ZM8.97 3.79002V6.94302L10.722 5.54302L8.97 3.79002ZM8.97 9.22402V12.376L10.722 10.624L8.97 9.22402Z" fill="#232323"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,9 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Status Icons/bluetooth-disabled-symbolic">
<g id="Group">
<path id="Vector" d="M0 0H16V16H0V0Z" fill="#808080" fill-opacity="0.01"/>
<path id="Vector_2" d="M8.50011 0.019989C7.23211 0.019989 6.08412 0.504375 5.15612 1.2844L7.9691 4.0929V2.57978C7.96912 2.48109 7.99842 2.38464 8.0533 2.30257C8.10818 2.2205 8.18619 2.15648 8.27745 2.11865C8.36872 2.08083 8.46918 2.07086 8.56612 2.09C8.66306 2.10915 8.75212 2.15657 8.8221 2.22625L11.8221 5.2225C11.8719 5.27208 11.9107 5.33159 11.9359 5.39715C11.9611 5.46271 11.9721 5.53283 11.9684 5.60295C11.9646 5.67307 11.9461 5.74163 11.914 5.80411C11.8819 5.8666 11.837 5.9216 11.7821 5.96556L10.7051 6.82548L13.9951 10.1114C13.9951 10.0764 14.0001 10.0425 14.0001 10.0075V6.0125C14.0001 2.69265 11.5471 0.019989 8.50011 0.019989ZM4.18611 2.29214C3.40742 3.3761 2.99225 4.67843 3.00011 6.0125V10.0075C3.00011 13.3274 5.45311 16 8.50011 16C10.9611 16 13.0341 14.2552 13.7401 11.8352L9.60411 7.70539L9.14412 8.07194L11.7811 10.1793C11.836 10.2232 11.881 10.2781 11.9132 10.3406C11.9454 10.403 11.964 10.4716 11.9679 10.5417C11.9718 10.6118 11.9608 10.682 11.9357 10.7476C11.9105 10.8132 11.8718 10.8727 11.8221 10.9224L8.8221 13.9186C8.75218 13.9882 8.66321 14.0356 8.56636 14.0548C8.46952 14.074 8.36914 14.0641 8.27791 14.0264C8.18668 13.9887 8.10868 13.9248 8.05373 13.8429C7.99877 13.761 7.96932 13.6647 7.9691 13.5661V9.01175L5.78112 10.7596C5.26112 11.177 4.63512 10.396 5.15612 9.98054L7.54311 8.07292L5.37712 6.0125C4.81112 5.60202 5.25712 4.92385 5.78112 5.38627L7.9691 7.13409V6.07142L4.18611 2.29214ZM8.9691 3.78527V5.09166L9.99211 6.11437L10.7211 5.5351L8.9691 3.78527ZM8.9691 9.21151V12.3606L10.7211 10.6108L8.9691 9.21151Z" fill="#232323"/>
<path id="Vector_3" d="M14.8594 12.9524L3.55069 1.65775C3.16134 1.26888 2.53009 1.26887 2.14073 1.65773C1.75138 2.0466 1.75137 2.67709 2.14073 3.06595L13.4495 14.3606C13.8388 14.7495 14.4701 14.7495 14.8595 14.3606C15.2488 13.9717 15.2488 13.3413 14.8594 12.9524Z" fill="#232323"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -43,11 +43,21 @@ struct CosmicBluetoothApplet {
request_confirmation: Option<(BluerDevice, String, Sender<bool>)>,
}
impl CosmicBluetoothApplet {
fn update_icon(&mut self) {
self.icon_name = if self.bluer_state.bluetooth_enabled {
"cosmic-applet-bluetooth-active-symbolic"
} else {
"cosmic-applet-bluetooth-disabled-symbolic"
}
.to_string();
}
}
#[derive(Debug, Clone)]
enum Message {
TogglePopup,
ToggleVisibleDevices(bool),
Errored(String),
Ignore,
BluetoothEvent(BluerEvent),
Request(BluerRequest),
@ -118,7 +128,6 @@ impl Application for CosmicBluetoothApplet {
]);
}
}
Message::Errored(_) => todo!(),
Message::Ignore => {}
Message::ToggleVisibleDevices(enabled) => {
self.show_visible_devices = enabled;
@ -165,29 +174,19 @@ impl Application for CosmicBluetoothApplet {
}
// TODO handle agent events
BluerEvent::AgentEvent(event) => match event {
crate::bluetooth::BluerAgentEvent::DisplayPinCode(_d, _code) => {
// dbg!((d.name, code));
}
crate::bluetooth::BluerAgentEvent::DisplayPasskey(_d, _code) => {
// dbg!((d.name, code));
}
crate::bluetooth::BluerAgentEvent::DisplayPinCode(_d, _code) => {}
crate::bluetooth::BluerAgentEvent::DisplayPasskey(_d, _code) => {}
crate::bluetooth::BluerAgentEvent::RequestPinCode(_d) => {
// TODO anything to be done here?
// dbg!("request pin code", d.name);
}
crate::bluetooth::BluerAgentEvent::RequestPasskey(_d) => {
// TODO anything to be done here?
// dbg!("request passkey", d.name);
}
crate::bluetooth::BluerAgentEvent::RequestConfirmation(d, code, tx) => {
// dbg!("request confirmation", &d.name, &code);
self.request_confirmation.replace((d, code, tx));
// let _ = tx.send(false);
}
crate::bluetooth::BluerAgentEvent::RequestDeviceAuthorization(_d, _tx) => {
// TODO anything to be done here?
// dbg!("request device authorization", d.name);
// let_ = tx.send(false);
}
crate::bluetooth::BluerAgentEvent::RequestServiceAuthorization(
_d,
@ -276,6 +275,7 @@ impl Application for CosmicBluetoothApplet {
self.theme = t;
}
}
self.update_icon();
Command::none()
}
fn view(&self, id: window::Id) -> Element<Message> {

View file

@ -20,6 +20,8 @@ use cosmic::{
use cosmic_applet::{applet_button_theme, cosmic_panel_config::PanelAnchor, CosmicAppletHelper};
use zbus::Connection;
const ID: &str = "com.system76.CosmicAppletGraphics";
#[derive(Clone, Copy)]
enum GraphicsMode {
AppliedGraphicsMode(Graphics),
@ -198,17 +200,13 @@ impl Application for Window {
match self.applet_helper.anchor {
PanelAnchor::Left | PanelAnchor::Right => self
.applet_helper
.icon_button("input-gaming-symbolic")
.icon_button(ID)
.on_press(Message::TogglePopup)
.style(Button::Text)
.into(),
PanelAnchor::Top | PanelAnchor::Bottom => button(Button::Text)
.custom(vec![row![
icon(
"input-gaming-symbolic",
self.applet_helper.suggested_size().0,
)
.style(Svg::Symbolic),
icon(ID, self.applet_helper.suggested_size().0,).style(Svg::Symbolic),
text(match self.graphics_mode.map(|g| g.inner()) {
Some(Graphics::Integrated) => fl!("integrated"),
Some(Graphics::Nvidia) => fl!("nvidia"),

View file

@ -1,5 +1,7 @@
network = Network
airplane-mode = Airplane mode
airplane-mode-on = Airplane Mode is on
turn-off-airplane-mode = Turn on to enable Wi-Fi, Bluetooth and mobile broadband.
wifi = Wi-Fi
ipv4 = IPv4 Address
ipv6 = IPv6 Address

View file

@ -95,9 +95,28 @@ struct CosmicNetworkApplet {
new_connection: Option<NewConnectionState>,
conn: Option<Connection>,
timeline: Timeline,
toggle_wifi_ctr: u128,
}
fn wifi_icon(strength: u8) -> &'static str {
if strength < 25 {
"network-wireless-signal-weak-symbolic"
} else if strength < 50 {
"network-wireless-signal-ok-symbolic"
} else if strength < 75 {
"network-wireless-signal-good-symbolic"
} else {
"network-wireless-signal-excellent-symbolic"
}
}
impl CosmicNetworkApplet {
fn update_nm_state(&mut self, new_state: NetworkManagerState) {
self.update_togglers(&new_state);
self.nm_state = new_state;
self.update_icon_name();
}
fn update_icon_name(&mut self) {
self.icon_name = self
.nm_state
@ -105,11 +124,12 @@ impl CosmicNetworkApplet {
.iter()
.fold("network-offline-symbolic", |icon_name, conn| {
match (icon_name, conn) {
("network-offline-symbolic", ActiveConnectionInfo::WiFi { .. }) => {
"network-wireless-symbolic"
("network-offline-symbolic", ActiveConnectionInfo::WiFi { strength, .. }) => {
wifi_icon(*strength)
}
("network-offline-symbolic", ActiveConnectionInfo::Wired { .. })
| ("network-wireless-symbolic", ActiveConnectionInfo::Wired { .. }) => {
(_, ActiveConnectionInfo::Wired { .. })
if icon_name != "network-vpn-symbolic" =>
{
"network-wired-symbolic"
}
(_, ActiveConnectionInfo::Vpn { .. }) => "network-vpn-symbolic",
@ -121,7 +141,9 @@ impl CosmicNetworkApplet {
fn update_togglers(&mut self, state: &NetworkManagerState) {
let timeline = &mut self.timeline;
let mut changed = false;
if state.wifi_enabled != self.nm_state.wifi_enabled {
changed = true;
let chain = if state.wifi_enabled {
chain::Toggler::on(WIFI.clone(), 1.)
} else {
@ -131,6 +153,7 @@ impl CosmicNetworkApplet {
};
if state.airplane_mode != self.nm_state.airplane_mode {
changed = true;
let chain = if state.airplane_mode {
chain::Toggler::on(AIRPLANE_MODE.clone(), 1.)
} else {
@ -138,8 +161,9 @@ impl CosmicNetworkApplet {
};
timeline.set_chain(chain);
};
timeline.start();
if changed {
timeline.start();
}
}
}
@ -221,11 +245,14 @@ impl Application for CosmicNetworkApplet {
// Message::Errored(_) => todo!(),
Message::Ignore => {}
Message::ToggleAirplaneMode(enabled) => {
self.toggle_wifi_ctr += 1;
if let Some(tx) = self.nm_sender.as_mut() {
let _ = tx.unbounded_send(NetworkManagerRequest::SetAirplaneMode(enabled));
}
}
Message::ToggleWiFi(enabled) => {
self.toggle_wifi_ctr += 1;
if let Some(tx) = self.nm_sender.as_mut() {
let _ = tx.unbounded_send(NetworkManagerRequest::SetWiFi(enabled));
}
@ -237,20 +264,13 @@ impl Application for CosmicNetworkApplet {
state,
} => {
self.nm_sender.replace(sender);
self.update_togglers(&state);
self.nm_state = state;
self.update_icon_name();
self.update_nm_state(state);
self.conn = Some(conn);
}
NetworkManagerEvent::WiFiEnabled(state) => {
self.nm_state = state;
}
NetworkManagerEvent::WirelessAccessPoints(state) => {
self.nm_state = state;
}
NetworkManagerEvent::ActiveConns(state) => {
self.nm_state = state;
self.update_icon_name();
NetworkManagerEvent::WiFiEnabled(state)
| NetworkManagerEvent::WirelessAccessPoints(state)
| NetworkManagerEvent::ActiveConns(state) => {
self.update_nm_state(state);
}
NetworkManagerEvent::RequestResponse {
state,
@ -264,21 +284,19 @@ impl Application for CosmicNetworkApplet {
if self
.new_connection
.as_ref()
.map(|c| c.ssid() == ssid)
.map(|c| c.ssid() != ssid)
.unwrap_or_default()
{
self.new_connection = None;
}
}
if success {
self.update_togglers(&state);
} else {
if !success {
match req {
NetworkManagerRequest::Password(_, _) => {
if let Some(NewConnectionState::EnterPassword {
access_point,
..
}) = self.new_connection.as_ref()
if let Some(
NewConnectionState::EnterPassword { access_point, .. }
| NewConnectionState::Waiting(access_point),
) = self.new_connection.as_ref()
{
self.new_connection
.replace(NewConnectionState::Failure(access_point.clone()));
@ -287,8 +305,7 @@ impl Application for CosmicNetworkApplet {
_ => {}
}
}
self.nm_state = state;
self.update_icon_name();
self.update_nm_state(state);
}
},
Message::SelectWirelessAccessPoint(access_point) => {
@ -443,6 +460,7 @@ impl Application for CosmicNetworkApplet {
name,
ip_addresses,
state,
strength,
..
} => {
let mut ipv4 = Vec::with_capacity(ip_addresses.len());
@ -454,9 +472,7 @@ impl Application for CosmicNetworkApplet {
);
}
let mut btn_content = vec![
icon("network-wireless-symbolic", 24)
.style(Svg::Symbolic)
.into(),
icon(wifi_icon(*strength), 24).style(Svg::Symbolic).into(),
column![text(name).size(14), Column::with_children(ipv4)]
.width(Length::Fill)
.into(),
@ -493,43 +509,6 @@ impl Application for CosmicNetworkApplet {
}
};
}
for known in &self.nm_state.known_access_points {
let mut btn_content = vec![
icon("network-wireless-symbolic", 24)
.style(Svg::Symbolic)
.into(),
text(&known.ssid).size(14).width(Length::Fill).into(),
];
if known.working {
btn_content.push(
icon("process-working-symbolic", 24)
.style(Svg::Symbolic)
.into(),
);
}
let mut btn = button(Button::Secondary)
.custom(vec![Row::with_children(btn_content)
.align_items(Alignment::Center)
.spacing(8)
.into()])
.padding([8, 24])
.width(Length::Fill)
.style(button_style());
btn = match known.state {
DeviceState::Failed
| DeviceState::Unknown
| DeviceState::Unmanaged
| DeviceState::Disconnected
| DeviceState::NeedAuth => {
btn.on_press(Message::ActivateKnownWifi(known.ssid.clone()))
}
DeviceState::Activated => btn.on_press(Message::Disconnect(known.ssid.clone())),
_ => btn,
};
known_wifi = known_wifi.push(row![btn].align_items(Alignment::Center));
}
let mut content = column![
vpn_ethernet_col,
@ -561,38 +540,106 @@ impl Application for CosmicNetworkApplet {
)
.padding([0, 12]),
divider::horizontal::light(),
known_wifi,
]
.align_items(Alignment::Center)
.spacing(8)
.padding([8, 0]);
let dropdown_icon = if self.show_visible_networks {
"go-down-symbolic"
if self.nm_state.airplane_mode {
content = content.push(
column!(
icon("airplane-mode-symbolic", 48).style(Svg::Symbolic),
text(fl!("airplane-mode-on")).size(14),
text(fl!("turn-off-airplane-mode")).size(12)
)
.spacing(8)
.align_items(Alignment::Center)
.width(Length::Fill),
);
} else {
"go-next-symbolic"
};
let available_connections_btn = button(Button::Secondary)
.custom(
vec![
text(fl!("visible-wireless-networks"))
.size(14)
.width(Length::Fill)
.height(Length::Fixed(24.0))
.vertical_alignment(Vertical::Center)
.into(),
container(icon(dropdown_icon, 14).style(Svg::Symbolic))
.align_x(Horizontal::Center)
.align_y(Vertical::Center)
.width(Length::Fixed(24.0))
.height(Length::Fixed(24.0))
.into(),
]
.into(),
)
.padding([8, 24])
.style(button_style())
.on_press(Message::ToggleVisibleNetworks);
content = content.push(available_connections_btn);
for known in &self.nm_state.known_access_points {
let mut btn_content = Vec::with_capacity(2);
let ssid = text(&known.ssid).size(14).width(Length::Fill);
if known.working {
btn_content.push(
icon("network-wireless-acquiring-symbolic", 24)
.style(Svg::Symbolic)
.into(),
);
btn_content.push(ssid.into());
btn_content.push(
icon("process-working-symbolic", 24)
.style(Svg::Symbolic)
.into(),
);
} else if matches!(known.state, DeviceState::Unavailable) {
btn_content.push(
icon("network-wireless-disconnected-symbolic", 24)
.style(Svg::Symbolic)
.into(),
);
btn_content.push(ssid.into());
} else {
btn_content.push(
icon(wifi_icon(known.strength), 24)
.style(Svg::Symbolic)
.into(),
);
btn_content.push(ssid.into());
}
let mut btn = button(Button::Secondary)
.custom(vec![Row::with_children(btn_content)
.align_items(Alignment::Center)
.spacing(8)
.into()])
.padding([8, 24])
.width(Length::Fill)
.style(button_style());
btn = match known.state {
DeviceState::Failed
| DeviceState::Unknown
| DeviceState::Unmanaged
| DeviceState::Disconnected
| DeviceState::NeedAuth => {
btn.on_press(Message::ActivateKnownWifi(known.ssid.clone()))
}
DeviceState::Activated => {
btn.on_press(Message::Disconnect(known.ssid.clone()))
}
_ => btn,
};
known_wifi = known_wifi.push(row![btn].align_items(Alignment::Center));
}
content = content.push(known_wifi);
let dropdown_icon = if self.show_visible_networks {
"go-down-symbolic"
} else {
"go-next-symbolic"
};
let available_connections_btn = button(Button::Secondary)
.custom(
vec![
text(fl!("visible-wireless-networks"))
.size(14)
.width(Length::Fill)
.height(Length::Fixed(24.0))
.vertical_alignment(Vertical::Center)
.into(),
container(icon(dropdown_icon, 14).style(Svg::Symbolic))
.align_x(Horizontal::Center)
.align_y(Vertical::Center)
.width(Length::Fixed(24.0))
.height(Length::Fixed(24.0))
.into(),
]
.into(),
)
.padding([8, 24])
.style(button_style())
.on_press(Message::ToggleVisibleNetworks);
content = content.push(available_connections_btn);
}
if self.show_visible_networks {
if let Some(new_conn_state) = self.new_connection.as_ref() {
match new_conn_state {
@ -601,7 +648,8 @@ impl Application for CosmicNetworkApplet {
password,
} => {
let id = row![
icon("network-wireless-symbolic", 24).style(Svg::Symbolic),
icon("network-wireless-acquiring-symbolic", 24)
.style(Svg::Symbolic),
text(&access_point.ssid).size(14),
]
.align_items(Alignment::Center)
@ -638,7 +686,8 @@ impl Application for CosmicNetworkApplet {
}
NewConnectionState::Waiting(access_point) => {
let id = row![
icon("network-wireless-symbolic", 24).style(Svg::Symbolic),
icon("network-wireless-acquiring-symbolic", 24)
.style(Svg::Symbolic),
text(&access_point.ssid).size(14),
]
.align_items(Alignment::Center)
@ -654,7 +703,7 @@ impl Application for CosmicNetworkApplet {
}
NewConnectionState::Failure(access_point) => {
let id = row![
icon("network-wireless-symbolic", 24).style(Svg::Symbolic),
icon("network-wireless-error-symbolic", 24).style(Svg::Symbolic),
text(&access_point.ssid).size(14),
]
.align_items(Alignment::Center)
@ -701,7 +750,7 @@ impl Application for CosmicNetworkApplet {
}
let button = button(button_style())
.custom(vec![row![
icon("network-wireless-symbolic", 16).style(Svg::Symbolic),
icon(wifi_icon(ap.strength), 16).style(Svg::Symbolic),
text(&ap.ssid)
.size(14)
.height(Length::Fixed(24.0))
@ -736,9 +785,12 @@ impl Application for CosmicNetworkApplet {
self.applet_helper.theme_subscription(0).map(Message::Theme),
timeline,
network_sub,
active_conns_subscription(0, conn.clone()).map(Message::NetworkManagerEvent),
devices_subscription(0, conn.clone()).map(Message::NetworkManagerEvent),
wireless_enabled_subscription(0, conn.clone()).map(Message::NetworkManagerEvent),
active_conns_subscription(self.toggle_wifi_ctr, conn.clone())
.map(Message::NetworkManagerEvent),
devices_subscription(self.toggle_wifi_ctr, conn.clone())
.map(Message::NetworkManagerEvent),
wireless_enabled_subscription(self.toggle_wifi_ctr, conn.clone())
.map(Message::NetworkManagerEvent),
])
} else {
Subscription::batch(vec![timeline, network_sub])

View file

@ -18,6 +18,7 @@ pub fn active_conns_subscription<I: 'static + Hash + Copy + Send + Sync + Debug>
async move {
loop {
state = start_listening(state, &mut output).await;
_ = tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
}
}
})

View file

@ -56,6 +56,7 @@ pub async fn active_connections(
rsn_flags: access_point.rsn_flags().await?,
wpa_flags: access_point.wpa_flags().await?,
state,
strength: access_point.strength().await.unwrap_or_default(),
});
}
}
@ -98,6 +99,7 @@ pub enum ActiveConnectionInfo {
rsn_flags: ApSecurityFlags,
wpa_flags: ApSecurityFlags,
state: ActiveConnectionState,
strength: u8,
},
Vpn {
name: String,

View file

@ -18,6 +18,7 @@ pub fn devices_subscription<I: 'static + Hash + Copy + Send + Sync + Debug>(
async move {
loop {
state = start_listening(state, &mut output).await;
_ = tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
}
}
})

View file

@ -140,20 +140,31 @@ async fn start_listening(
.output()
.await
.is_ok();
let mut state = NetworkManagerState::new(&conn).await.unwrap_or_default();
state.airplane_mode = if success {
airplane_mode
} else {
!airplane_mode
};
if state.airplane_mode {
state.wifi_enabled = false;
}
_ = output
.send(NetworkManagerEvent::RequestResponse {
req: NetworkManagerRequest::SetAirplaneMode(airplane_mode),
success,
state: NetworkManagerState::new(&conn).await.unwrap_or_default(),
state,
})
.await;
}
Some(NetworkManagerRequest::SetWiFi(enabled)) => {
let success = network_manager.set_wireless_enabled(enabled).await.is_ok();
let mut state = NetworkManagerState::new(&conn).await.unwrap_or_default();
state.wifi_enabled = if success { enabled } else { !enabled };
let response = NetworkManagerEvent::RequestResponse {
req: NetworkManagerRequest::SetWiFi(enabled),
success,
state: NetworkManagerState::new(&conn).await.unwrap_or_default(),
state,
};
_ = output.send(response).await;
}
@ -198,7 +209,6 @@ async fn start_listening(
};
if let Some(s) = secrets.get_mut("802-11-wireless-security") {
s.insert("psk".into(), Value::Str(password.clone().into()).to_owned());
drop(s);
settings.extend(secrets.into_iter());
let settings: HashMap<_, _> = settings
.iter()
@ -519,14 +529,8 @@ impl NetworkManagerState {
.output()
.await?;
let airplane_mode = std::str::from_utf8(&airplaine_mode.stdout).unwrap_or_default();
let bluetooth_disabled = airplane_mode.contains("Soft blocked: yes");
if !network_manager.wireless_enabled().await.unwrap_or_default() {
_self.airplane_mode = bluetooth_disabled;
return Ok(_self);
} else {
_self.wifi_enabled = true;
};
_self.wifi_enabled = network_manager.wireless_enabled().await.unwrap_or_default();
_self.airplane_mode = airplane_mode.contains("Soft blocked: yes") && !_self.wifi_enabled;
let s = NetworkManagerSettings::new(&conn).await?;
_ = s.load_connections(&[]).await;

View file

@ -18,6 +18,7 @@ pub fn wireless_enabled_subscription<I: 'static + Hash + Copy + Send + Sync + De
async move {
loop {
state = start_listening(state, &mut output).await;
_ = tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
}
}
})

View file

@ -0,0 +1,15 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Status Icons/notification-disabled-symbolic" clip-path="url(#clip0_4614_124694)">
<g id="Group">
<path id="Vector" d="M0 0H16V16H0V0Z" fill="#808080" fill-opacity="0.01"/>
<path id="Vector_2" d="M12.5414 12.1343L2.69913 2.29205C2.30977 1.9027 1.6785 1.90271 1.28915 2.29206C0.899796 2.68141 0.899812 3.31266 1.28916 3.70202L11.1314 13.5442C11.5207 13.9336 12.152 13.9336 12.5413 13.5443C12.9307 13.1549 12.9307 12.5236 12.5414 12.1343Z" fill="#232323"/>
<path id="Vector_3" d="M3 3C1.892 3 1 3.892 1 5V10C1 11.108 1.892 12 3 12H12.41L3.41 3H3ZM5.39001 3L14.074 11.684C14.63 11.329 15 10.711 15 10V5C15 3.892 14.108 3 13 3H5.39001Z" fill="#232323"/>
<path id="Vector_4" d="M8 12L6 15L4 12H8Z" fill="#232323"/>
</g>
</g>
<defs>
<clipPath id="clip0_4614_124694">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 934 B

View file

@ -0,0 +1,13 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Status Icons/notification-new-symbolic" clip-path="url(#clip0_4614_124695)">
<path id="Vector" d="M0 0H16V16H0V0Z" fill="#808080" fill-opacity="0.01"/>
<path id="Vector_2" d="M7.23995 3C7.73568 3.7396 8.00087 4.60963 8.00195 5.5C8.00195 6.09095 7.88556 6.67611 7.65941 7.22208C7.43326 7.76804 7.1018 8.26412 6.68393 8.68198C6.26607 9.09984 5.76999 9.43131 5.22403 9.65746C4.67806 9.8836 4.0929 10 3.50195 10C2.61179 9.99951 1.74178 9.73502 1.00195 9.24V10C1.00195 11.108 1.89395 12 3.00195 12H13.002C14.11 12 15.002 11.108 15.002 10V5C15.002 3.892 14.11 3 13.002 3H7.23995Z" fill="#232323"/>
<path id="Vector_3" d="M12 12L10 15L8 12H12Z" fill="#232323"/>
<path id="Vector_4" d="M3.5 2C2.57174 2 1.6815 2.36875 1.02513 3.02513C0.368749 3.6815 0 4.57174 0 5.5C0 6.42826 0.368749 7.3185 1.02513 7.97487C1.6815 8.63125 2.57174 9 3.5 9C4.42826 9 5.3185 8.63125 5.97487 7.97487C6.63125 7.3185 7 6.42826 7 5.5C7 4.57174 6.63125 3.6815 5.97487 3.02513C5.3185 2.36875 4.42826 2 3.5 2ZM3 3H4V6H3V3ZM3 7H4V8H3V7Z" fill="#232323"/>
</g>
<defs>
<clipPath id="clip0_4614_124695">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,14 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Status Icons/notification-symbolic" clip-path="url(#clip0_4612_124293)">
<g id="Group">
<path id="Vector" d="M0 0L16 0V16H0L0 0Z" fill="#808080" fill-opacity="0.01"/>
<path id="Vector_2" d="M13 3H3C1.89543 3 1 3.89543 1 5V10C1 11.1046 1.89543 12 3 12H13C14.1046 12 15 11.1046 15 10V5C15 3.89543 14.1046 3 13 3Z" fill="#232323"/>
<path id="Vector_3" d="M12 12L10 15L8 12H12Z" fill="#232323"/>
</g>
</g>
<defs>
<clipPath id="clip0_4612_124293">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 617 B

View file

@ -70,6 +70,17 @@ impl Notifications {
self.timeline.start();
}
}
fn update_icon(&mut self) {
self.icon_name = if self.config.do_not_disturb {
"cosmic-applet-notification-disabled-symbolic"
} else if self.cards.is_empty() {
"cosmic-applet-notification-symbolic"
} else {
"cosmic-applet-notification-new-symbolic"
}
.to_string();
}
}
#[derive(Debug, Clone)]
@ -114,17 +125,15 @@ impl Application for Notifications {
})
})
.unwrap_or_default();
(
Notifications {
applet_helper,
theme,
icon_name: "notification-alert-symbolic".to_string(),
config_helper: helper,
config,
..Default::default()
},
Command::none(),
)
let mut _self = Notifications {
applet_helper,
theme,
config_helper: helper,
config,
..Default::default()
};
_self.update_icon();
(_self, Command::none())
}
fn title(&self) -> String {
@ -175,15 +184,13 @@ impl Application for Notifications {
match message {
Message::Theme(t) => {
self.theme = t;
Command::none()
}
Message::Frame(now) => {
self.timeline.now(now);
Command::none()
}
Message::TogglePopup => {
if let Some(p) = self.popup.take() {
destroy_popup(p)
return destroy_popup(p);
} else {
self.id_ctr += 1;
let new_id = window::Id(self.id_ctr);
@ -201,7 +208,7 @@ impl Application for Notifications {
.max_width(444.0)
.min_height(100.0)
.max_height(900.0);
get_popup(popup_settings)
return get_popup(popup_settings);
}
}
Message::DoNotDisturb(chain, b) => {
@ -212,11 +219,9 @@ impl Application for Notifications {
tracing::error!("{:?}", err);
}
}
Command::none()
}
Message::Settings => {
let _ = process::Command::new("cosmic-settings notifications").spawn();
Command::none()
}
Message::NotificationEvent(n) => {
if let Some(c) = self
@ -241,13 +246,10 @@ impl Application for Notifications {
fl!("show-more", HashMap::from_iter(vec![("more", "1")])),
));
}
Command::none()
}
Message::Ignore => Command::none(),
Message::Ignore => {}
Message::Config(config) => {
self.config = config;
Command::none()
}
Message::Dismissed(id) => {
info!("Dismissed {}", id);
@ -264,12 +266,10 @@ impl Application for Notifications {
}
});
}
Command::none()
}
Message::DbusEvent(e) => match e {
subscriptions::dbus::Output::Ready(tx) => {
self.dbus_sender.replace(tx);
Command::none()
}
subscriptions::dbus::Output::CloseEvent(id) => {
for c in &mut self.cards {
@ -280,8 +280,6 @@ impl Application for Notifications {
);
}
self.cards.retain(|c| !c.1.is_empty());
Command::none()
}
},
Message::ClearAll(app_name) => {
@ -303,8 +301,6 @@ impl Application for Notifications {
}
}
}
Command::none()
}
Message::CardsToggled(name, expanded) => {
let id = if let Some((id, _, n_expanded, _)) = self
@ -318,9 +314,10 @@ impl Application for Notifications {
return Command::none();
};
self.update_cards(id);
Command::none()
}
}
};
self.update_icon();
Command::none()
}
fn view(&self, id: window::Id) -> Element<Message> {
@ -346,7 +343,7 @@ impl Application for Notifications {
let notifications = if self.cards.is_empty() {
row![container(
column![
text_icon(&self.icon_name, 40),
text_icon("cosmic-applet-notification-symbolic", 40),
text(&fl!("no-notifications"))
]
.align_items(Alignment::Center)

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

View file

@ -1,99 +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"
id="Layer_1"
data-name="Layer 1"
width="210"
height="210"
viewBox="0 0 210 210"
version="1.1"
sodipodi:docname="pop_icon.svg"
inkscape:version="0.92+devel unknown">
<metadata
id="metadata25">
<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>Pop_icon</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs23" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
inkscape:document-rotation="0"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1376"
id="namedview21"
showgrid="false"
fit-margin-top="5"
fit-margin-left="5"
fit-margin-right="5"
fit-margin-bottom="5"
inkscape:zoom="4.249208"
inkscape:cx="42.52691"
inkscape:cy="89.544373"
inkscape:window-x="0"
inkscape:window-y="31"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<title
id="title2">Pop_icon</title>
<g
id="g18"
transform="matrix(0.21141649,0,0,0.21141649,5,4.7885835)">
<g
id="g8">
<circle
cx="473"
cy="474"
r="473"
style="fill:#48b9c7"
id="circle4" />
<rect
x="223"
y="726"
width="500"
height="76.959999"
rx="37"
ry="37"
style="fill:#ffffff"
id="rect6" />
</g>
<path
d="m 536,357 c -24,51 -64,92 -120,112 l 48,125 c 9,23 17,47 10,69 -7,22 -39,29 -62,5 -44,-47 -192,-343 -203,-365 -11,-22 -23,-40 -23,-62 1,-33 52,-67 77,-84 25,-17 74,-40 117,-41 43,-1 61,9 86,25 38,25 65,64 75,109 10,45 7,80 -5,105 M 423,301 c -9,-31 -28,-61 -53,-81 -5,-4 -11,-9 -18,-11 -46,-15 -26,62 -19,82 7,20 26,62 47,83 5,5 10,9 16,10 6,1 18,-5 23,-13 5,-8 6,-14 6,-22 a 128,128 0 0 0 -2,-48 z"
style="fill:#ffffff"
id="path10"
inkscape:connector-curvature="0" />
<g
id="g16">
<path
d="m 625,664 c -2,9 -7,17 -15,22 -8,5 -27,5 -38,-4 -11,-9 -13,-24 -10,-36 3,-12 13,-25 27,-29 29,-9 42,23 36,47 z"
style="fill:#ffffff"
id="path12"
inkscape:connector-curvature="0" />
<path
d="m 607,573 c -18,-7 -12,-103 5,-220 5,-32 13,-48 22,-56 9,-8 36,-12 52,-9 a 90,90 0 0 1 49,24 c 12,11 13,23 9,38 -4,15 -18,47 -29,70 l -28,53 c -54,96 -65,106 -80,100 z"
style="fill:#ffffff"
id="path14"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -1,99 +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"
id="Layer_1"
data-name="Layer 1"
width="210"
height="210"
viewBox="0 0 210 210"
version="1.1"
sodipodi:docname="pop_icon.svg"
inkscape:version="0.92+devel unknown">
<metadata
id="metadata25">
<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>Pop_icon</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs23" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
inkscape:document-rotation="0"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1376"
id="namedview21"
showgrid="false"
fit-margin-top="5"
fit-margin-left="5"
fit-margin-right="5"
fit-margin-bottom="5"
inkscape:zoom="4.249208"
inkscape:cx="42.52691"
inkscape:cy="89.544373"
inkscape:window-x="0"
inkscape:window-y="31"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<title
id="title2">Pop_icon</title>
<g
id="g18"
transform="matrix(0.21141649,0,0,0.21141649,5,4.7885835)">
<g
id="g8">
<circle
cx="473"
cy="474"
r="473"
style="fill:#48b9c7"
id="circle4" />
<rect
x="223"
y="726"
width="500"
height="76.959999"
rx="37"
ry="37"
style="fill:#ffffff"
id="rect6" />
</g>
<path
d="m 536,357 c -24,51 -64,92 -120,112 l 48,125 c 9,23 17,47 10,69 -7,22 -39,29 -62,5 -44,-47 -192,-343 -203,-365 -11,-22 -23,-40 -23,-62 1,-33 52,-67 77,-84 25,-17 74,-40 117,-41 43,-1 61,9 86,25 38,25 65,64 75,109 10,45 7,80 -5,105 M 423,301 c -9,-31 -28,-61 -53,-81 -5,-4 -11,-9 -18,-11 -46,-15 -26,62 -19,82 7,20 26,62 47,83 5,5 10,9 16,10 6,1 18,-5 23,-13 5,-8 6,-14 6,-22 a 128,128 0 0 0 -2,-48 z"
style="fill:#ffffff"
id="path10"
inkscape:connector-curvature="0" />
<g
id="g16">
<path
d="m 625,664 c -2,9 -7,17 -15,22 -8,5 -27,5 -38,-4 -11,-9 -13,-24 -10,-36 3,-12 13,-25 27,-29 29,-9 42,23 36,47 z"
style="fill:#ffffff"
id="path12"
inkscape:connector-curvature="0" />
<path
d="m 607,573 c -18,-7 -12,-103 5,-220 5,-32 13,-48 22,-56 9,-8 36,-12 52,-9 a 90,90 0 0 1 49,24 c 12,11 13,23 9,38 -4,15 -18,47 -29,70 l -28,53 c -54,96 -65,106 -80,100 z"
style="fill:#ffffff"
id="path14"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

1
debian/control vendored
View file

@ -19,6 +19,7 @@ Homepage: https://github.com/pop-os/cosmic-applets
Package: cosmic-applets
Architecture: amd64 arm64
Depends:
cosmic-icons,
${misc:Depends},
${shlibs:Depends}
Recommends:

View file

@ -10,7 +10,7 @@ cargo_args := vendor_args + ' ' + debug_args
sharedir := rootdir + prefix + '/share'
iconsdir := sharedir + '/icons/hicolor/scalable/apps'
iconsdir := sharedir + '/icons/hicolor'
bindir := rootdir + prefix + '/bin'
build: _extract_vendor
@ -24,8 +24,8 @@ build-debug *args:
# Compiles with release profile
build-release *args: (build-debug '--release' args)
_install_icon path:
install -Dm0644 {{path}} {{iconsdir}}/{{file_name(path)}}
_install_icons name:
find {{name}}/'data'/'icons' -type f -exec echo {} \; | rev | cut -d'/' -f-3 | rev | xargs -d '\n' -I {} install -Dm0644 {{name}}/'data'/'icons'/{} {{iconsdir}}/{}
_install_desktop path:
install -Dm0644 {{path}} {{sharedir}}/applications/{{file_name(path)}}
@ -33,7 +33,7 @@ _install_desktop path:
_install_bin name:
install -Dm0755 target/release/{{name}} {{bindir}}/{{name}}
_install id name: (_install_icon name + '/data/icons/' + id + '.svg') (_install_desktop name + '/data/' + id + '.desktop') (_install_bin name)
_install id name: (_install_icons name) (_install_desktop name + '/data/' + id + '.desktop') (_install_bin name)
_install_app_list: (_install 'com.system76.CosmicAppList' 'cosmic-app-list')
_install_audio: (_install 'com.system76.CosmicAppletAudio' 'cosmic-applet-audio')
@ -48,7 +48,7 @@ _install_time: (_install 'com.system76.CosmicAppletTime' 'cosmic-applet-time')
# TODO: Turn this into one configurable applet?
_install_panel_button: (_install_bin 'cosmic-panel-button')
_install_button id name: (_install_icon name + '/data/icons/' + id + '.svg') (_install_desktop name + '/data/' + id + '.desktop')
_install_button id name: (_install_icons name) (_install_desktop name + '/data/' + id + '.desktop')
_install_app_button: (_install_button 'com.system76.CosmicPanelAppButton' 'cosmic-panel-app-button')
_install_workspaces_button: (_install_button 'com.system76.CosmicPanelWorkspacesButton' 'cosmic-panel-workspaces-button')