import { Palette, Slider, ComboBox } from "std-widgets.slint"; component Button { in-out property icon <=> img.source; in property wanted; in property enabled: false; callback clicked; VerticalLayout { alignment: center; spacing: 8px; img := Image { // What the actual fuck x: 7px; colorize: enabled ? Palette.foreground : Palette.foreground.darker(10%); width: 16px; height: 16px; horizontal-alignment: center; opacity: 1; } rect := Rectangle { touch := TouchArea { clicked => { if enabled { clicked() } } } border-radius: root.height / 2; border-width: 1px; border-color: Palette.border; background: enabled ? (touch.pressed ? Palette.control-background.darker(45%) : (touch.has-hover ? Palette.control-background.darker(35%) : Palette.control-background)) : Palette.control-background.darker(35%); animate background { duration: 166ms; } drop-shadow-blur: wanted ? pow(abs(mod(animation-tick() / 1s - 3, 6) - 3) / 3, 2) * 128.0 * 1px : 0px; drop-shadow-color: self.border-color; width: 32px; height: 32px; } } } export component MainWindow inherits Window { callback play; callback stop; callback next; callback refreshp; callback change_volume(float); callback text_edited; in-out property addr: address.text; in-out property mtitle: ""; in-out property malbum: ""; in-out property martist: ""; in-out property volume: svolume.value; in-out property start_enabled: false; in-out property playing: false; in-out property paused: false; in property cover: @image-url("../lonelyradio.png"); in property <[string]> playlists: ["All tracks"]; in property <[string]> supported_encoders: []; in-out property selected_playlist: selected.current-value; in-out property selected_encoder: encoder.current-index; property settings: false; title: "monoclient-s"; min-width: 448px; max-width: 448px * 3; preferred-width: 448px; height: main.height; animate background { duration: 166ms; } panels := HorizontalLayout { width: root.width * 2; x: settings ? -root.width : 0.0; height: main.height; animate x { easing: ease-in-out-expo; duration: 0.5s; } main := HorizontalLayout { width: root.width; height: rect.height + self.padding * 2; spacing: 16px; padding: 16px; rect := Rectangle { opacity: playing ? 1.0 : 0.0; animate opacity { duration: 0.25s; easing: ease-in-out; } clip: true; border-radius: 6px; animate background { duration: 166ms; } background: Palette.foreground; //width: 240px; height: img.height + 12px * 2 + 1.5rem * 3; max-width: parent.width; border-width: 0px; VerticalLayout { img := Image { vertical-alignment: top; source: cover; min-width: 240px; height: self.width; image-fit: contain; } VerticalLayout { padding: 12px; tartist := Text { color: Palette.background; vertical-alignment: center; height: 1.5rem; font-weight: 600; text: martist; overflow: elide; } talbum := Text { color: Palette.background; vertical-alignment: center; height: 1.5rem; text: malbum; overflow: elide; } ttitle := Text { color: Palette.background; vertical-alignment: center; height: 1.5rem; text: mtitle; overflow: elide; } } } } VerticalLayout { alignment: center; //max-width: 160px; spacing: 16px; VerticalLayout { spacing: 16px; HorizontalLayout { padding: 8px; alignment: center; spacing: 16px; //height: 96px; Button { icon: @image-url("icons/stop.svg"); enabled: playing && !paused; clicked => { stop() } } Button { icon: playing ? (paused ? @image-url("icons/play.svg") : @image-url("icons/pause.svg")) : @image-url("icons/random.svg"); enabled: start_enabled || playing; wanted: start_enabled && !playing; clicked => { play() } } Button { icon: @image-url("icons/next.svg"); enabled: playing && !paused; clicked => { next() } } } Rectangle { padding: 16px; clip: true; background: Palette.background; border-color: Palette.border; animate background, border-color { duration: 166ms; } border-width: 1px; border-radius: 4px; drop-shadow-blur: !start_enabled ? pow(abs(mod(animation-tick() / 1s - 3, 6) - 3) / 3, 2) * 128.0 * 1px : 0px; drop-shadow-color: Palette.border; VerticalLayout { alignment: center; padding: 8px; address := TextInput { text: ""; accepted => { self.clear_focus() } edited => { text_edited(); } } } } svolume := Slider { value: 255; maximum: 255; changed(f) => { change_volume(f) } } HorizontalLayout { alignment: center; Button { icon: @image-url("icons/gear.svg"); enabled: true; wanted: false; clicked => { settings = !settings; } } } } } } VerticalLayout { width: root.width; height: root.height; alignment: center; VerticalLayout { padding: 20px; spacing: 20px; HorizontalLayout { alignment: center; spacing: 8px; Text { horizontal-alignment: right; vertical-alignment: center; text: "Playlists"; } selected := ComboBox { model: playlists; current-index: 0; selected() => { self.clear_focus() } } } HorizontalLayout { alignment: center; spacing: 8px; Text { horizontal-alignment: right; vertical-alignment: center; text: "Encoder"; } encoder := ComboBox { model: supported_encoders; selected() => { self.clear_focus() } } } } HorizontalLayout { alignment: center; Button { icon: @image-url("icons/first.svg"); enabled: true; wanted: false; clicked => { settings = !settings; } } } } } }