This commit is contained in:
liyaowhen
2024-07-14 22:55:41 -07:00
commit d4e7133248
39 changed files with 2351 additions and 0 deletions
+164
View File
@@ -0,0 +1,164 @@
namespace Song {
public class MainView : Adw.NavigationPage {
private Window window;
public Settings settings = new Settings("com.liyaowhen.Song.playlists");
public MainViewContent main_content;
public string current_playlist;
public MainView(Window _window) {
this.window = _window;
}
construct {
// make ui
var toolbar_view = new Adw.ToolbarView ();
var scrollable = new Gtk.ScrolledWindow();
main_content = new MainViewContent();
scrollable.set_child(main_content);
scrollable.hexpand = true;
scrollable.hexpand_set = true;
var action_bar = new MainViewActionBar (main_content);
var controls = new SongControls();
toolbar_view.add_top_bar (action_bar);
toolbar_view.set_content(scrollable);
toolbar_view.add_bottom_bar (controls);
this.child = toolbar_view;
this.title = "main_view";
}
}
public class MainViewActionBar : Gtk.Box {
private Gtk.ActionBar action_bar;
private MainViewContent main_view;
public MainViewActionBar (MainViewContent _main_view) {
this.main_view = _main_view;
}
construct {
orientation = Gtk.Orientation.HORIZONTAL;
action_bar = new Gtk.ActionBar();
action_bar.vexpand = true;
action_bar.hexpand = true;
append(action_bar);
}
public void new_music_popover_show() {
var popover = new NewMusicPopover();
popover.present(this);
}
}
public class MainViewContent : Gtk.Box {
private Settings settings = new Settings("com.liyaowhen.Song.playlists");
private Adw.NavigationView navigation_view;
public string current_playlist;
public MainViewContent() {
vexpand = true;
hexpand = true;
print("loading empty ui");
navigation_view = new Adw.NavigationView();
append(navigation_view);
navigation_view.vexpand = true;
navigation_view.hexpand = true;
}
construct {
SongController.main_view_content = this;
}
public void change_page(string playlist_name) {
print("change page called");
bool isKeyValid = false;
foreach (string key in settings.list_keys()){
if (key == playlist_name) {
print("valid playlist");
isKeyValid = true;
}
}
if (!isKeyValid) {
print("invalid playlist_name");
return;
}
current_playlist = playlist_name;
string[] songs = settings.get_strv(playlist_name);
print("\n playlist contains: \n" + songs[1]);
if (songs.length == 1) {
if (songs[0] == "") {empty_playlist_ui(playlist_name); return;}
else {
//
}
} else if (songs.length > 1) {
if (songs[1] != null) {
print("making a page with actual content");
playlist_ui(playlist_name);
}
}
}
private void empty_playlist_ui(string playlist_name) {
var empty_page = new Adw.StatusPage();
var parent_page = new Adw.NavigationPage(empty_page,"no songs added");
empty_page.set_title("Empty Playlist " + playlist_name);
empty_page.set_icon_name("edit-find-symbolic");
empty_page.set_description("Click the button on the top left to add songs in this playlist.");
navigation_view.push(parent_page);
}
private void playlist_ui(string playlist_name) {
var playlist_page = new Adw.StatusPage();
playlist_page.set_title(playlist_name);
playlist_page.set_icon_name("emblem-music-symbolic");
load_music(playlist_page, playlist_name);
var parent_page = new Adw.NavigationPage(playlist_page, playlist_name);
navigation_view.push(parent_page);
}
private void load_music(Adw.StatusPage page, string playlist_name) {
Adw.Clamp clamp = new Adw.Clamp();
Gtk.ListBox content = new Gtk.ListBox();
foreach (string i in settings.get_strv(playlist_name)) {
if (i != "") {
content.append(new MusicListRow(i));
}
}
clamp.child = content;
page.child = clamp;
content.hexpand = true;
}
/*private Gtk.WidgetPaintable playlist_cover(string playlist_name) {
Gtk.WidgetPaintable paintable = new Gtk.WidgetPaintable();
return paintable;
} */
}
}
+64
View File
@@ -0,0 +1,64 @@
namespace Song {
public class MusicListRow : Gtk.Box {
private Settings settings = new Settings("com.liyaowhen.Song.playlists");
public string song_name;
public MusicListRow (string _song_name) {
this.song_name = _song_name;
build_ui();
}
construct {
margin_bottom = 5;
margin_top = 5;
margin_start = 5;
margin_end = 5;
vexpand = true;
hexpand = true;
vexpand_set = true;
hexpand_set = true;
orientation = Gtk.Orientation.HORIZONTAL;
}
private void build_ui() {
var label = new Gtk.Label (song_name);
print(song_name + "making playlists song button");
label.hexpand = true;
append(label);
var play_button = new Gtk.Button.from_icon_name ("media-playback-start-symbolic");
play_button.hexpand = false;
play_button.add_css_class("flat");
play_button.clicked.connect(() => {
if (SongController.song_controls.current_song != song_name) {
SongController.song_controls.change_song(song_name);
play_button.icon_name = "media-playback-pause-symbolic";
Timeout.add(1, () => {
if (SongController.song_controls.current_song != song_name) {
// when another song is called to play, reset the button state
play_button.icon_name = "media-playback-start-symbolic";
return false;
}
return true;
});
} else if (SongController.song_controls.isPlaying) {
SongController.song_controls.pause();
play_button.icon_name = "media-playback-start-symbolic";
} else if (!SongController.song_controls.isPlaying) {
SongController.song_controls.play();
play_button.icon_name = "media-playback-pause-symbolic";
}
});
append(play_button);
spacing = 5;
}
}
}
+31
View File
@@ -0,0 +1,31 @@
namespace Song {
public class Playlist : Gtk.Button {
private Settings settings = new Settings ("com.liyaowhen.Song");
public signal void removal_mode();
public signal void exit_removal_mode();
private string playlist_name;
public Playlist (string _playlist_name) {
this.playlist_name = _playlist_name;
initialize();
}
construct {
hexpand = true;
clicked.connect(() => {
//assumes that main_view is already instanciated
SongController.main_view_content.change_page(playlist_name);
});
}
public void initialize() {
set_label(playlist_name);
}
}
}
+153
View File
@@ -0,0 +1,153 @@
namespace Song {
public class SideBar : Adw.NavigationPage {
private Settings settings = new Settings("com.liyaowhen.Song");
private Window window;
public SideBarContent side_bar_content;
public SideBarControls side_bar_controls;
public SideBar(Window _window) {
this.window = _window;
}
construct {
var toolbar_view = new Adw.ToolbarView();
var scroll_box = new Gtk.ScrolledWindow();
side_bar_content = new SideBarContent ();
side_bar_content.set_vexpand (true);
side_bar_content.set_hexpand (true);
scroll_box.child = side_bar_content;
side_bar_controls = new SideBarControls (side_bar_content);
side_bar_controls.set_hexpand (true);
toolbar_view.set_content(scroll_box);
toolbar_view.add_bottom_bar(side_bar_controls);
title = "Songs:";
this.child = toolbar_view;
}
}
public class SideBarContent : Gtk.Box {
private Settings settings = new Settings("com.liyaowhen.Song.playlists");
public List<Playlist> playlists;
private MainView main_view;
public SideBarContent() {
}
construct {
orientation = Gtk.Orientation.VERTICAL;
valign = Gtk.Align.START;
spacing = 5;
margin_bottom = 5;
margin_top = 5;
margin_start = 5;
margin_end = 5;
vexpand = true;
hexpand = true;
vexpand_set = true;
hexpand_set = true;
Playlist initial_playlist;
var playlist_names = settings.get_strv("playlists");
foreach (string _name in playlist_names) {
var playlist = new Playlist(_name);
if (_name == playlist_names[0]) {
initial_playlist = playlist;
}
playlists.append(playlist);
append(playlist);
}
print("sidbar requesting main_view_content switch to playlist of name:\n" + playlist_names[1]);
Timeout.add(1, () => {
if (SongController.main_view_content != null) {
SongController.main_view_content.change_page(playlist_names[0]);
return false;
}
return true;
}, 1);
SongController.sidebar_content = this;
//reconfigure_playlist_button_group(); DOES NOT WORK FOR SOME REASON
}
/*private void reconfigure_playlist_button_group() {
foreach (Playlist i in playlists) {
foreach (Playlist j in playlists) {
if (i != j) {
i.set_group(j);
}
}
}
}*/
}
public class SideBarControls : Gtk.Box {
private SideBarContent sidebar_content;
private Gtk.ActionBar action_bar;
public SideBarControls(SideBarContent _sidebar_content) {
this.sidebar_content = _sidebar_content;
}
construct {
action_bar = new Gtk.ActionBar();
action_bar.vexpand = true;
action_bar.hexpand = true;
append(action_bar);
this.orientation = Gtk.Orientation.HORIZONTAL;
this.add_css_class ("toolbar");
// make ui
var select_button = new Gtk.ToggleButton();
select_button.set_icon_name ("checkbox-symbolic");
var delete_button = new Gtk.Button();
delete_button.set_icon_name ("user-trash-symbolic");
var export_button = new Gtk.Button();
export_button.set_icon_name("document-save-symbolic");
var options_button = new Gtk.Button(); // TODO: change to Gtk.MenuButton
options_button.set_icon_name("open-menu-symbolic");
options_button.sensitive = true;
action_bar.pack_start(select_button);
//action_bar.set_center_widget(empty_spacer());
action_bar.pack_end(options_button);
// signals
}
private Gtk.Separator empty_spacer() {
var empty_spacer = new Gtk.Separator(Gtk.Orientation.VERTICAL);
empty_spacer.hexpand = true;
empty_spacer.add_css_class("spacer");
return empty_spacer;
}
}
}
+162
View File
@@ -0,0 +1,162 @@
using Gst;
namespace Song {
public class SongControls : Gtk.Box {
private Settings songs_list = new Settings("com.liyaowhen.Song.playlists");
private Settings settings = new Settings("com.liyaowhen.Song");
public Gtk.Scale progress_bar;
public Gtk.Adjustment progress_bar_adjustment;
private bool isDragging;
public bool isPlaying;
public string current_song;
public Gst.Element playbin;
public SongControls() {
playbin = Gst.ElementFactory.make("playbin", "player");
}
construct {
// Gstreamer stuff
isPlaying = false;
// UI
orientation = Gtk.Orientation.VERTICAL;
vexpand = false;
hexpand = true;
hexpand_set = true;
progress_bar_adjustment = new Gtk.Adjustment(0, 0, 1, 1, 1, 0);
progress_bar = new Gtk.Scale(Gtk.Orientation.HORIZONTAL, progress_bar_adjustment);
progress_bar.set_draw_value(false);
Timeout.add(1, () => {
if (playbin != null && isDragging != true) {
var position = (int64) 0;
var duration = (int64) 0;
// Query the current position and duration
if (playbin.query_position(Format.TIME, out position) &&
playbin.query_duration(Format.TIME, out duration)) {
progress_bar.set_range(0, (double) duration / Gst.SECOND);
progress_bar.set_value((double) position / Gst.SECOND);
}
}
//print("running");
return true;
});
uint timeout_id = 0;
progress_bar.change_value.connect((range) => {
if (timeout_id != 0) {
try {
Source.remove(timeout_id);
} catch (GLib.Error e) {
// the function above often complains
}
}
isDragging = true;
if (playbin != null) {
var seek_time = (int64)(progress_bar.get_value() * Gst.SECOND);
playbin.seek_simple(Format.TIME, SeekFlags.FLUSH | SeekFlags.KEY_UNIT, seek_time);
}
timeout_id = Timeout.add(50, () => {
isDragging = false;
return false;
});
}); // emitted when user (not program) changes the scale
progress_bar.value_changed.connect((range) => {
});
append(progress_bar);
// add controls to control the music
music_controls();
SongController.song_controls = this;
}
private void music_controls() {
var clamp = new Adw.Clamp();
var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
box.hexpand = true;
box.halign = Gtk.Align.CENTER;
box.margin_bottom = 10;
var play_button = new Gtk.Button.from_icon_name("media-playback-start-symbolic");
play_button.halign = Gtk.Align.CENTER;
Timeout.add(1, () => {
if (isPlaying == true) {
play_button.set_icon_name("media-playback-pause-symbolic");
} else {
play_button.set_icon_name("media-playback-start-symbolic");
}
return true;
});
play_button.clicked.connect(() => {
if (isPlaying) pause();
else play();
});
box.append(play_button);
play_button.clicked.connect(() => {
play_music();
});
clamp.child = box;
append(clamp);
}
private void play_music() {
if (current_song != null) {
}
}
public void play() {
playbin.set_state(Gst.State.PLAYING);
isPlaying = true;
}
public void pause() {
playbin.set_state(Gst.State.PAUSED);
isPlaying = false;
}
public void change_song(string song) {
print("song is now " + song + "\n");
current_song = song;
string file_path = "file://" + settings.get_string("song-folder") + "/" + current_song + ".mp3";
print("song full path is " + file_path);
playbin.set_state(Gst.State.NULL);
playbin.set_property("uri", file_path);
playbin.set_state(Gst.State.PLAYING);
isPlaying = true;
}
}
}