/* application.vala * * Copyright 2024 Erica Z * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * * SPDX-License-Identifier: AGPL-3.0-or-later */ Gst.Element playbin; Wavelet.Subsonic public_api; public class Wavelet.Application : Adw.Application { public Application () { Object ( application_id: "eu.callcc.Wavelet", flags: ApplicationFlags.DEFAULT_FLAGS ); } construct { ActionEntry[] action_entries = { { "about", this.on_about_action }, { "preferences", this.on_preferences_action }, { "quit", this.quit } }; this.add_action_entries (action_entries, this); this.set_accels_for_action ("app.quit", {"q"}); } public override void activate () { base.activate (); // FIXME edit back if issues var win = this.active_window ?? new Wavelet.Window (this); var win = new Wavelet.Window (this); win.present (); playbin = Gst.ElementFactory.make ("playbin3", null); assert (playbin != null); win.notify["volume"].connect ((s, p) => { // gst docs: Volume sliders should usually use a cubic volume. ((Gst.Audio.StreamVolume) playbin).set_volume (Gst.Audio.StreamVolumeFormat.CUBIC, win.volume); }); win.mute.clicked.connect (() => { var vol = (Gst.Audio.StreamVolume) playbin; if (vol.get_mute ()) { win.show_unmute (); vol.set_mute (false); } else { win.show_mute (); vol.set_mute (true); } }); Timeout.add (100, () => { int64 position_ns; if (playbin.query_position (Gst.Format.TIME, out position_ns)) { win.play_position_ms = (int) (position_ns / 1000000); } return Source.CONTINUE; }); playbin.get_bus ().add_watch (Priority.DEFAULT, (bus, message) => { switch (message.type) { case Gst.MessageType.ASYNC_DONE: win.play_position.sensitive = true; int64 duration_ns; if (playbin.query_duration (Gst.Format.TIME, out duration_ns)) { win.play_position_ms = 0; win.play_duration_ms = (int) (duration_ns / 1000000); } else { warning ("could not query playbin duration after ASYNC_DONE"); } break; default: break; } return true; }); win.setup.connected.connect ((api) => { public_api = api; win.shuffle_all_tracks.sensitive = true; win.shuffle_all_tracks.activated.connect (() => { win.shuffle_all_tracks.sensitive = false; win.play_queue.clear (); api.get_random_songs.begin (null, (song) => { win.play_queue.queue (song); }, (obj, res) => { try { api.get_random_songs.end (res); } catch (Error e) { error ("could not get random songs: %s", e.message); } win.shuffle_all_tracks.sensitive = true; }); }); win.play_queue.play_now.connect ((song) => { win.play_position.sensitive = false; playbin.set_state (Gst.State.READY); playbin.set ("uri", api.stream_uri (song.id)); playbin.set_state (Gst.State.PLAYING); win.song = song; }); }); win.setup.load (); } private void on_about_action () { string[] developers = { "Erica Z" }; var about = new Adw.AboutDialog () { application_name = "wavelet", application_icon = "eu.callcc.Wavelet", developer_name = "Erica Z", translator_credits = _("translator-credits"), version = "0.1.0", developers = developers, copyright = "© 2024 Erica Z", }; about.present (this.active_window); } private void on_preferences_action () { message ("app.preferences action activated"); } }