fixed bug where exiting youtube search mode makes it unusable.

This commit is contained in:
liyaowhen
2024-08-06 15:42:35 -07:00
parent e0c8fa374b
commit 8ad6f38f01
8 changed files with 182 additions and 44 deletions
+28
View File
@@ -0,0 +1,28 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "custom",
"name": "Custom launch",
"targetCreateCommands": [
"target create ${workspaceFolder}/<program>"
],
"processCreateCommands": [
"settings set target.run-args value1 value2 value3",
"process launch"
]
},
{
"type": "lldb",
"request": "launch",
"name": "Debug",
"program": "${workspaceFolder}/<executable file>",
"args": [],
"cwd": "${workspaceFolder}"
}
]
}
+4
View File
@@ -33,6 +33,10 @@ namespace Song {
public signal void request_search(string query); public signal void request_search(string query);
public YtSearchBar yt_search_bar; public YtSearchBar yt_search_bar;
public signal void start_drag();
public signal void end_drag();
public bool isDragging = false;
public static SignalHub get_instance () { public static SignalHub get_instance () {
if (instance == null) { if (instance == null) {
instance = new SignalHub(); instance = new SignalHub();
+1 -1
View File
@@ -111,7 +111,7 @@ namespace Song {
PlaylistItem _item = new PlaylistItem(); PlaylistItem _item = new PlaylistItem();
var _item_object = items_object.get_object_member(item); var _item_object = items_object.get_object_member(item);
_item.item_type = _item_object.get_int_member("item_type"); _item.item_type = _item_object.get_int_member("item_type");
_item.name = _item_object.get_string_member("name"); _item.name = item;
_item.file = _item_object.get_string_member("file"); _item.file = _item_object.get_string_member("file");
if (_item_object.has_member("picture")) { if (_item_object.has_member("picture")) {
_item.picture = _item_object.get_string_member("picture"); _item.picture = _item_object.get_string_member("picture");
+19 -7
View File
@@ -242,12 +242,13 @@ namespace Song {
} }
private void search_ui() { private void search_ui() {
var yt_search_list = new YtSearchView(); if (yt_search_page == null) {
var yt_search_list_container = new Gtk.ScrolledWindow(); var yt_search_list = YtSearchView.get_instance();
yt_search_list_container.vexpand = true; var yt_search_list_container = new Gtk.ScrolledWindow();
yt_search_list_container.set_child(yt_search_list); yt_search_list_container.vexpand = true;
yt_search_page = new Adw.NavigationPage(yt_search_list_container, "Searching..."); yt_search_list_container.set_child(yt_search_list);
yt_search_page = new Adw.NavigationPage(yt_search_list_container, "Searching...");
}
navigation_view.push(yt_search_page); navigation_view.push(yt_search_page);
} }
@@ -260,7 +261,18 @@ namespace Song {
} }
}*/ }*/
playlist.items.foreach((item) => { playlist.items.foreach((item) => {
content.append(new MusicListRow(item)); MusicListRow i = new MusicListRow(item);
content.append(i);
});
var config = Config.get_instance();
config.config_changed.connect(() => {
content.remove_all();
playlist.items.foreach((item) => {
MusicListRow i = new MusicListRow(item);
content.append(i);
});
}); });
clamp.child = content; clamp.child = content;
page.child = clamp; page.child = clamp;
+1
View File
@@ -124,6 +124,7 @@ namespace Song {
config.config_changed.connect(() => { config.config_changed.connect(() => {
foreach (PlaylistButton e in playlist_buttons) { foreach (PlaylistButton e in playlist_buttons) {
print("\n" + e.playlist.name + "eee"); print("\n" + e.playlist.name + "eee");
remove(e);
e.destroy(); e.destroy();
} }
if (config.playlists != null) { if (config.playlists != null) {
+34 -9
View File
@@ -11,6 +11,7 @@ namespace Song {
public Gtk.Adjustment progress_bar_adjustment; public Gtk.Adjustment progress_bar_adjustment;
private bool isDragging; private bool isDragging;
private Gtk.Button progress_bar_controller; private Gtk.Button progress_bar_controller;
private uint? seekTimeout = null;
private string item_directory = Path.build_path("/", Environment.get_user_config_dir(), "com.liyaowhen.Song"); private string item_directory = Path.build_path("/", Environment.get_user_config_dir(), "com.liyaowhen.Song");
@@ -20,10 +21,12 @@ namespace Song {
public Gst.Element playbin; public Gst.Element playbin;
public SongControls() { public SongControls() {
playbin = Gst.ElementFactory.make("playbin", "player");
} }
construct { construct {
playbin = Gst.ElementFactory.make("playbin", "player");
// Gstreamer stuff // Gstreamer stuff
isPlaying = false; isPlaying = false;
// UI // UI
@@ -37,21 +40,25 @@ namespace Song {
progress_bar.set_draw_value(false); progress_bar.set_draw_value(false);
var signal_hub = SignalHub.get_instance();
Timeout.add(500, () => { Timeout.add(500, () => {
if (playbin != null && isPlaying) { if (playbin != null && isPlaying) {
var position = (int64) 0; var position = (int64) 0;
var duration = (int64) 0; var duration = (int64) 0;
playbin.set_state(Gst.State.PLAYING); //playbin.set_state(Gst.State.PLAYING);
// Query the current position and duration // Query the current position and duration
if (playbin.query_position(Format.TIME, out position) && if (playbin.query_position(Format.TIME, out position) &&
playbin.query_duration(Format.TIME, out duration)) { playbin.query_duration(Format.TIME, out duration)) {
progress_bar.set_range(0, (double) duration / Gst.SECOND); progress_bar.set_range(0, (double) duration / Gst.SECOND);
progress_bar.set_value((double) position / Gst.SECOND); progress_bar.set_value((double) position / Gst.SECOND);
print("working");
} }
print(position.to_string() + "\n" + duration.to_string() + "\n");
} else { } else {
} }
@@ -60,17 +67,34 @@ namespace Song {
return true; return true;
}); });
progress_bar.change_value.connect((range) => {
progress_bar.adjust_bounds.connect((range) => {
if (playbin != null) { if (playbin != null) {
var seek_time = (int64)(progress_bar.get_value() * Gst.SECOND); //var seek_time = (int64)(progress_bar.get_value() * Gst.SECOND);
playbin.seek_simple(Format.TIME, SeekFlags.FLUSH | SeekFlags.KEY_UNIT, seek_time); //playbin.seek_simple(Format.TIME, SeekFlags.FLUSH | SeekFlags.TRICKMODE_FORWARD_PREDICTED, seek_time);
isPlaying = false;
print("seeking");
if (seekTimeout != null) {
if (seekTimeout > 0) {
GLib.Source.remove(seekTimeout);
}
}
seekTimeout = Timeout.add(200, () => {
if (playbin != null) {
int64 seek_time = (int64)(progress_bar.get_value() * Gst.SECOND);
playbin.seek_simple(Format.TIME, SeekFlags.FLUSH | SeekFlags.KEY_UNIT, seek_time);
}
return false; // Remove the timeout
});
} }
});
// emitted when user (not program) changes the scale
}); // emitted when user (not program) changes the scale signal_hub.end_drag.connect(() => {
isPlaying = true;
});
append(progress_bar); append(progress_bar);
@@ -143,6 +167,7 @@ namespace Song {
print("song full path is " + file_path); print("song full path is " + file_path);
playbin.set_state(Gst.State.NULL); playbin.set_state(Gst.State.NULL);
playbin.set_property("uri", File.new_for_path(file_path).get_uri()); playbin.set_property("uri", File.new_for_path(file_path).get_uri());
playbin.set_start_time(0);
playbin.set_state(Gst.State.PLAYING); playbin.set_state(Gst.State.PLAYING);
isPlaying = true; isPlaying = true;
+78 -24
View File
@@ -113,18 +113,32 @@ namespace Song {
private YtSearchViewStates state = YtSearchViewStates.IDLE; private YtSearchViewStates state = YtSearchViewStates.IDLE;
private Cancellable active_search_query;
private Gee.HashSet<YtSearchItem> results = new Gee.HashSet<YtSearchItem>(); private Gee.HashSet<YtSearchItem> results = new Gee.HashSet<YtSearchItem>();
private Gee.HashSet<Gtk.Widget> result_widgets = new Gee.HashSet<Gtk.Widget>(); private Gee.HashSet<Gtk.Widget> result_widgets = new Gee.HashSet<Gtk.Widget>();
private Gtk.FlowBox flow_box = new Gtk.FlowBox();
private Subprocess? search_process = null; private Subprocess? search_process = null;
private static YtSearchView? search_view = null;
public static YtSearchView get_instance() {
if (search_view == null) {
search_view = new YtSearchView();
}
return search_view;
}
private YtSearchView () {
}
construct { construct {
orientation = Gtk.Orientation.VERTICAL; orientation = Gtk.Orientation.VERTICAL;
append(flow_box); spacing = 15;
flow_box.set_max_children_per_line(4);
append(new Gtk.Label("Youtube Search"));
instanciate_signals(); instanciate_signals();
@@ -165,6 +179,9 @@ namespace Song {
} }
private async void search(string query) { private async void search(string query) {
if (query == "" | query.length == 0) return;
//label.label = query; //label.label = query;
string temp_file = Path.build_path("/", Environment.get_tmp_dir(), "yt_search_tmp.json"); string temp_file = Path.build_path("/", Environment.get_tmp_dir(), "yt_search_tmp.json");
@@ -244,7 +261,6 @@ namespace Song {
//GLib.IOChannel stdout_channel = new IOChannel.unix_new(std_out); //GLib.IOChannel stdout_channel = new IOChannel.unix_new(std_out);
StringBuilder output_buffer = new StringBuilder();
/*stdout_channel.add_watch(IOCondition.IN | IOCondition.HUP, (i, c) => { /*stdout_channel.add_watch(IOCondition.IN | IOCondition.HUP, (i, c) => {
if (c == IOCondition.HUP) { if (c == IOCondition.HUP) {
@@ -376,6 +392,7 @@ namespace Song {
search_item.thumbnail_url = item.get_string_member("image"); search_item.thumbnail_url = item.get_string_member("image");
} }
results.add(search_item); results.add(search_item);
}); });
@@ -439,12 +456,13 @@ namespace Song {
} }
result_widgets.clear(); result_widgets.clear();
results.foreach((result) => { results.foreach((result) => {
var label = new Gtk.Label(result.title); /*var label = new Gtk.Label(result.title);
var link = new Gtk.LinkButton(result.url); var link = new Gtk.LinkButton(result.url);
var thumbnail = new Gtk.Picture(); var thumbnail = new Gtk.Picture();
thumbnail.vexpand = true; thumbnail.vexpand = true;
thumbnail.vexpand_set = true; thumbnail.vexpand_set = true;
thumbnail.can_shrink = false; //thumbnail.can_shrink = false;
thumbnail.content_fit = Gtk.ContentFit.COVER;
load_url_to_image.begin(thumbnail, result.thumbnail_url); load_url_to_image.begin(thumbnail, result.thumbnail_url);
var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 5); var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 5);
var options_box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5); var options_box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
@@ -452,8 +470,17 @@ namespace Song {
var overlay = new Gtk.Overlay(); var overlay = new Gtk.Overlay();
overlay.set_child(thumbnail); overlay.set_child(thumbnail);
overlay.add_overlay(options_box); overlay.add_overlay(options_box);
append(overlay); var frame = new Gtk.AspectFrame(0.5f, 0.5f, 16/9, false);
result_widgets.add(overlay); frame.set_child(overlay);
frame.halign = Gtk.Align.START;*/
var thumbnail = new Gtk.Picture();
thumbnail.vexpand = true;
thumbnail.vexpand_set = true;
load_url_to_image.begin(thumbnail, result.thumbnail_url);
var row = new YtSearchItemWidget(thumbnail, result);
append(row);
result_widgets.add(row);
print("search_item added");
return true; return true;
}); });
} }
@@ -481,24 +508,51 @@ namespace Song {
public string thumbnail_url = ""; public string thumbnail_url = "";
} }
public class ExpandableImage : Gtk.DrawingArea { public class YtSearchItemWidget : Gtk.Box {
public Gdk.Pixbuf? pixbuf = null; private Gtk.Picture picture;
private YtSearchItem result;
public ExpandableImage () { public YtSearchItemWidget (Gtk.Picture picture, YtSearchItem result) {
var frame = new Gtk.Frame(null); this.picture = picture;
this.result = result;
this.set_draw_func((drawing_area, cairo_context, i) => { initialize();
if (pixbuf != null) {
Gdk.cairo_set_source_pixbuf(cairo_context, pixbuf, 0, 0);
} else {
cairo_context.set_source_rgb(200, 200, 200);
}
cairo_context.paint();
});
queue_draw();
} }
private void initialize() {
orientation = Gtk.Orientation.VERTICAL;
hexpand = true;
vexpand = false;
var overlay = new Gtk.Overlay();
picture.halign = Gtk.Align.START;
overlay.set_child(picture);
var label = new Gtk.Label(result.title);
label.valign = Gtk.Align.START;
label.halign = Gtk.Align.START;
label.add_css_class("title-4");
var attributes = new Pango.AttrList();
attributes.insert(Pango.attr_background_new(15, 15, 15));
label.set_attributes(attributes);
label.overflow = Gtk.Overflow.HIDDEN;
var add_button = new Gtk.Button.from_icon_name("folder-download-symbolic");
add_button.valign = Gtk.Align.END;
add_button.halign = Gtk.Align.END;
overlay.add_overlay(label);
overlay.add_overlay(add_button);
var aspect_ratio_box = new Gtk.AspectFrame(0.5f, 0.5f, 16/9, true);
aspect_ratio_box.set_child(overlay);
append(aspect_ratio_box);
set_size_request(100, 200);
}
} }
} }
+14
View File
@@ -97,10 +97,24 @@ namespace Song {
_content.add_controller(click_monitor); _content.add_controller(click_monitor);
click_monitor.set_propagation_phase(Gtk.PropagationPhase.CAPTURE); click_monitor.set_propagation_phase(Gtk.PropagationPhase.CAPTURE);
var drag_monitor = new Gtk.GestureDrag();
_content.add_controller(drag_monitor);
drag_monitor.set_propagation_phase(Gtk.PropagationPhase.CAPTURE);
var signal_hub = SignalHub.get_instance(); var signal_hub = SignalHub.get_instance();
click_monitor.begin.connect(() => { click_monitor.begin.connect(() => {
signal_hub.mouse_clicked(); signal_hub.mouse_clicked();
}); });
drag_monitor.drag_begin.connect(() => {
signal_hub.start_drag();
signal_hub.isDragging = true;
});
drag_monitor.drag_end.connect(() => {
signal_hub.end_drag();
signal_hub.isDragging = false;
});
} }
public void new_music_popover_show() { public void new_music_popover_show() {