Merge lp:~artem-anufrij/audience/playlist-rewrite into lp:~audience-members/audience/trunk

Proposed by Artem Anufrij
Status: Rejected
Rejected by: Danielle Foré
Proposed branch: lp:~artem-anufrij/audience/playlist-rewrite
Merge into: lp:~audience-members/audience/trunk
Diff against target: 1481 lines (+453/-511)
11 files modified
src/CMakeLists.txt (+2/-2)
src/Objects/Video.vala (+7/-2)
src/Widgets/BottomBar.vala (+28/-21)
src/Widgets/EpisodesPage.vala (+23/-5)
src/Widgets/LibraryPage.vala (+5/-4)
src/Widgets/PlayerPage.vala (+42/-82)
src/Widgets/Playlist.vala (+199/-196)
src/Widgets/PlaylistItem.vala (+66/-0)
src/Widgets/PlaylistPopover.vala (+0/-118)
src/Widgets/WelcomePage.vala (+41/-34)
src/Window.vala (+40/-47)
To merge this branch: bzr merge lp:~artem-anufrij/audience/playlist-rewrite
Reviewer Review Type Date Requested Status
Jeremy Wootten code, ui, function Needs Fixing
Review via email: mp+307248@code.launchpad.net

Description of the change

* Playlist redesign
* Bottom bar: Adden "Next" button
* Playlist: Added "Delete" button
* EpisodesView: Added "Play all" button

To post a comment you must log in.
680. By Artem Anufrij

no autohide for playlist

681. By Artem Anufrij

* save playlist
* restore playlist
* Welcome button: resume playlist
* Welcome button: replay playlist
* Welcome button: resume last video
* welcome button: replay last video

682. By Artem Anufrij

DnD on welcome screen

683. By Artem Anufrij

visiualisize playlist

Revision history for this message
Artem Anufrij (artem-anufrij) wrote :

Perhaps someone could check this branch.

Revision history for this message
Jeremy Wootten (jeremywootten) wrote :

Conflicts with trunk. I tested after merging and resolving conflicts.

Compilation warnings:
Bottom Bar: playlist_item.added not used.
PlayList::add_from_file - unhandled GLib.Error, misaligned lines

variable name instand_play should be "instant play".
some formatting issues (see inline)

UI:
Add and remove icons not consistent with other elementary apps - use + - buttons at bottom?
Use of trash icon misleading. User might think the original video will be trashed?
Playlist too narrow when empty - need empty message?

FUNCTION:
After adding file(s) they do not appear until playlist hidden/opened or app restarted.

review: Needs Fixing (code, ui, function)
Revision history for this message
Artem Anufrij (artem-anufrij) wrote :

@Jeremy: Dan said I should to break up to work on this branch. Thank you for your time...

Revision history for this message
Jeremy Wootten (jeremywootten) wrote :

Hi Artem.

Do you mean this branch is abandoned/rejected or just on hold? Or it needs
breaking up into smaller branches?

If so it should be marked as "in progress" or be withdrawn...

On 16 December 2016 at 16:40, Artem Anufrij <email address hidden> wrote:

> @Jeremy: Dan said I should to break up to work on this branch. Thank you
> for your time...
> --
> https://code.launchpad.net/~artem-anufrij/audience/
> playlist-rewrite/+merge/307248
> You are reviewing the proposed merge of lp:~artem-anufrij/audience/playlist-rewrite
> into lp:audience.
>

Revision history for this message
Danielle Foré (danrabbit) wrote :

We can probably resume trying to break up this branch into separate PRs on GitHub. Rejecting for now

Unmerged revisions

683. By Artem Anufrij

visiualisize playlist

682. By Artem Anufrij

DnD on welcome screen

681. By Artem Anufrij

* save playlist
* restore playlist
* Welcome button: resume playlist
* Welcome button: replay playlist
* Welcome button: resume last video
* welcome button: replay last video

680. By Artem Anufrij

no autohide for playlist

679. By Artem Anufrij

development

678. By Artem Anufrij

added missing file

677. By Artem Anufrij

begin playlist rewrite

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2016-09-26 20:52:11 +0000
+++ src/CMakeLists.txt 2016-09-30 22:31:06 +0000
@@ -50,11 +50,11 @@
50 DiskManager.vala50 DiskManager.vala
51 Window.vala51 Window.vala
52 Widgets/BottomBar.vala52 Widgets/BottomBar.vala
53 Widgets/Playlist.vala
54 Widgets/PlaylistItem.vala
53 Widgets/SettingsPopover.vala55 Widgets/SettingsPopover.vala
54 Widgets/PreviewPopover.vala56 Widgets/PreviewPopover.vala
55 Widgets/TimeWidget.vala57 Widgets/TimeWidget.vala
56 Widgets/Playlist.vala
57 Widgets/PlaylistPopover.vala
58 Widgets/WelcomePage.vala58 Widgets/WelcomePage.vala
59 Widgets/PlayerPage.vala59 Widgets/PlayerPage.vala
60 Widgets/LibraryPage.vala60 Widgets/LibraryPage.vala
6161
=== modified file 'src/Objects/Video.vala'
--- src/Objects/Video.vala 2016-09-27 20:26:37 +0000
+++ src/Objects/Video.vala 2016-09-30 22:31:06 +0000
@@ -27,7 +27,7 @@
27 public signal void thumbnail_changed ();27 public signal void thumbnail_changed ();
28 public signal void trashed ();28 public signal void trashed ();
2929
30 public File video_file { get; private set; }30 public File? video_file { get; private set; default = null;}
31 public string directory { get; construct set; }31 public string directory { get; construct set; }
32 public string file { get; construct set; }32 public string file { get; construct set; }
3333
@@ -55,10 +55,15 @@
55 manager = Audience.Services.LibraryManager.get_instance ();55 manager = Audience.Services.LibraryManager.get_instance ();
56 manager.thumbler.finished.connect (dbus_finished);56 manager.thumbler.finished.connect (dbus_finished);
5757
58 if (directory.has_prefix ("file:///")) {
59 video_file = File.new_for_uri (directory + "/" + file);
60 } else {
61 video_file = File.new_for_path (get_path ());
62 }
63
58 title = Audience.get_title (file);64 title = Audience.get_title (file);
5965
60 extract_metadata ();66 extract_metadata ();
61 video_file = File.new_for_path (this.get_path ());
6267
63 if (directory != Audience.settings.library_folder) {68 if (directory != Audience.settings.library_folder) {
64 container = Path.get_basename (directory);69 container = Path.get_basename (directory);
6570
=== modified file 'src/Widgets/BottomBar.vala'
--- src/Widgets/BottomBar.vala 2016-09-28 02:43:54 +0000
+++ src/Widgets/BottomBar.vala 2016-09-30 22:31:06 +0000
@@ -24,6 +24,7 @@
24 private const string PULSE_TYPE = "attention";24 private const string PULSE_TYPE = "attention";
2525
26 public signal void play_toggled ();26 public signal void play_toggled ();
27 public signal void playlist_clicked ();
27 public signal void unfullscreen ();28 public signal void unfullscreen ();
28 public signal void seeked (double val);29 public signal void seeked (double val);
2930
@@ -31,26 +32,27 @@
31 public bool hovered { get; set; default=false; }32 public bool hovered { get; set; default=false; }
32 public bool fullscreen { get; set; default=false; }33 public bool fullscreen { get; set; default=false; }
33 public SettingsPopover preferences_popover;34 public SettingsPopover preferences_popover;
34 public PlaylistPopover playlist_popover;
35 public TimeWidget time_widget;35 public TimeWidget time_widget;
36 public Audience.Widgets.Playlist playlist;
3637
37 private Gtk.Button play_button;38 private Gtk.Button play_button;
39 private Gtk.Button next_button;
38 private Gtk.Button preferences_button;40 private Gtk.Button preferences_button;
39 private Gtk.Button playlist_button;41 private Gtk.Button playlist_button;
40 private Gtk.Revealer unfullscreen_revealer;42 private Gtk.Revealer unfullscreen_revealer;
41 private uint hiding_timer = 0;43 private uint hiding_timer = 0;
42 private bool playlist_glowing = false;44 private bool playlist_glowing = false;
4345
44 public bool repeat {
45 get {
46 return playlist_popover.rep.active;
47 }
48 set {
49 playlist_popover.rep.active = value;
50 }
51 }
52
53 public BottomBar (ClutterGst.Playback playback) {46 public BottomBar (ClutterGst.Playback playback) {
47 playlist = Audience.Widgets.Playlist.get_instance ();
48 playlist.collection_changed.connect ((size) => { next_button.visible = size > 1; });
49 playlist.visibility_changed.connect ((visible) => {
50 if (visible) {
51 playlist_button.image = new Gtk.Image.from_icon_name ("pane-hide-symbolic", Gtk.IconSize.BUTTON);
52 } else {
53 playlist_button.image = new Gtk.Image.from_icon_name ("pane-show-symbolic", Gtk.IconSize.BUTTON);
54 }
55 });
54 this.events |= Gdk.EventMask.POINTER_MOTION_MASK;56 this.events |= Gdk.EventMask.POINTER_MOTION_MASK;
55 this.events |= Gdk.EventMask.LEAVE_NOTIFY_MASK;57 this.events |= Gdk.EventMask.LEAVE_NOTIFY_MASK;
56 this.events |= Gdk.EventMask.ENTER_NOTIFY_MASK;58 this.events |= Gdk.EventMask.ENTER_NOTIFY_MASK;
@@ -66,34 +68,36 @@
66 play_button.tooltip_text = _("Play");68 play_button.tooltip_text = _("Play");
67 play_button.clicked.connect (() => {play_toggled ();});69 play_button.clicked.connect (() => {play_toggled ();});
6870
69 playlist_button = new Gtk.Button.from_icon_name ("view-list-symbolic", Gtk.IconSize.BUTTON);71 next_button = new Gtk.Button.from_icon_name ("media-seek-forward-symbolic", Gtk.IconSize.BUTTON);
72 next_button.tooltip_text = _("Next");
73 next_button.clicked.connect (() => { playlist.next ();});
74
75 playlist_button = new Gtk.Button.from_icon_name ("pane-show-symbolic", Gtk.IconSize.BUTTON);
70 playlist_button.tooltip_text = _("Playlist");76 playlist_button.tooltip_text = _("Playlist");
71 playlist_button.clicked.connect (() => {playlist_popover.show_all (); playlist_popover.queue_resize ();});77 playlist_button.clicked.connect (() => { playlist.toggle_reveal_control (); });
7278
73 preferences_button = new Gtk.Button.from_icon_name ("open-menu-symbolic", Gtk.IconSize.BUTTON);79 preferences_button = new Gtk.Button.from_icon_name ("open-menu-symbolic", Gtk.IconSize.BUTTON);
74 preferences_button.tooltip_text = _("Settings");80 preferences_button.tooltip_text = _("Settings");
75 preferences_button.clicked.connect (() => {81 preferences_button.clicked.connect (() => {
76 preferences_popover.setup ();82 preferences_popover.setup ();
77 preferences_popover.show_all (); 83 preferences_popover.show_all ();
78 preferences_popover.queue_resize ();84 preferences_popover.queue_resize ();
79 });85 });
8086
81 time_widget = new TimeWidget (playback);87 time_widget = new TimeWidget (playback);
8288
83 playlist_popover = new PlaylistPopover ();89
84 playlist_popover.relative_to = playlist_button;
85 preferences_popover = new SettingsPopover (playback);90 preferences_popover = new SettingsPopover (playback);
86 preferences_popover.relative_to = preferences_button;91 preferences_popover.relative_to = preferences_button;
8792
88 main_actionbar.pack_start (play_button);93 main_actionbar.pack_start (play_button);
94 main_actionbar.pack_start (next_button);
89 main_actionbar.set_center_widget (time_widget);95 main_actionbar.set_center_widget (time_widget);
96 main_actionbar.pack_end (playlist_button);
90 main_actionbar.pack_end (preferences_button);97 main_actionbar.pack_end (preferences_button);
91 main_actionbar.pack_end (playlist_button);
92 add (main_actionbar);98 add (main_actionbar);
9399
94 playlist_popover.playlist.item_added.connect (() => {100
95 playlist_item_added ();
96 });
97101
98 notify["hovered"].connect (() => {102 notify["hovered"].connect (() => {
99 if (hovered == false) {103 if (hovered == false) {
@@ -131,6 +135,7 @@
131 });135 });
132136
133 show_all ();137 show_all ();
138 next_button.visible = playlist.size > 1;
134 }139 }
135140
136 private void playlist_item_added () {141 private void playlist_item_added () {
@@ -138,7 +143,7 @@
138 playlist_glowing = true;143 playlist_glowing = true;
139 playlist_button.get_child ().get_style_context ().add_class (PULSE_CLASS);144 playlist_button.get_child ().get_style_context ().add_class (PULSE_CLASS);
140 playlist_button.get_child ().get_style_context ().add_class (PULSE_TYPE);145 playlist_button.get_child ().get_style_context ().add_class (PULSE_TYPE);
141 146
142 Timeout.add (6000, () => {147 Timeout.add (6000, () => {
143 playlist_button.get_child ().get_style_context ().remove_class (PULSE_CLASS);148 playlist_button.get_child ().get_style_context ().remove_class (PULSE_CLASS);
144 playlist_button.get_child ().get_style_context ().remove_class (PULSE_TYPE);149 playlist_button.get_child ().get_style_context ().remove_class (PULSE_TYPE);
@@ -188,11 +193,13 @@
188 Source.remove (hiding_timer);193 Source.remove (hiding_timer);
189194
190 hiding_timer = GLib.Timeout.add (2000, () => {195 hiding_timer = GLib.Timeout.add (2000, () => {
191 if (hovered == true || preferences_popover.visible == true || playlist_popover.visible == true || playing == false) {196 if (hovered == true || preferences_popover.visible == true || playing == false) {
192 hiding_timer = 0;197 hiding_timer = 0;
193 return false;198 return false;
194 }199 }
200 playlist_button.image = new Gtk.Image.from_icon_name ("pane-show-symbolic", Gtk.IconSize.BUTTON);
195 set_reveal_child (false);201 set_reveal_child (false);
202 playlist.set_reveal_child (false);
196 unfullscreen_revealer.set_reveal_child (false);203 unfullscreen_revealer.set_reveal_child (false);
197 hiding_timer = 0;204 hiding_timer = 0;
198 return false;205 return false;
199206
=== modified file 'src/Widgets/EpisodesPage.vala'
--- src/Widgets/EpisodesPage.vala 2016-09-27 20:26:37 +0000
+++ src/Widgets/EpisodesPage.vala 2016-09-30 22:31:06 +0000
@@ -22,15 +22,18 @@
22namespace Audience {22namespace Audience {
23 public class EpisodesPage : Gtk.Grid {23 public class EpisodesPage : Gtk.Grid {
24 public Gtk.Image poster { get; set; }24 public Gtk.Image poster { get; set; }
25 Gtk.Button play_all;
25 Gtk.ScrolledWindow scrolled_window;26 Gtk.ScrolledWindow scrolled_window;
26 Gtk.FlowBox view_episodes;27 Gtk.FlowBox view_episodes;
27 Granite.Widgets.AlertView alert_view;28 Granite.Widgets.AlertView alert_view;
2829
29 public Audience.Services.LibraryManager manager;30 public Audience.Services.LibraryManager manager;
31 public Audience.Widgets.Playlist playlist;
3032
31 string query;33 string query;
3234
33 construct {35 construct {
36 playlist = Audience.Widgets.Playlist.get_instance ();
34 query = "";37 query = "";
3538
36 poster = new Gtk.Image ();39 poster = new Gtk.Image ();
@@ -39,6 +42,13 @@
39 poster.valign = Gtk.Align.START;42 poster.valign = Gtk.Align.START;
40 poster.get_style_context ().add_class ("card");43 poster.get_style_context ().add_class ("card");
4144
45 play_all = new Gtk.Button ();
46 play_all.margin_left = 24;
47 play_all.vexpand = true;
48 play_all.valign = Gtk.Align.START;
49 play_all.label = _("Play all");
50 play_all.clicked.connect (play_all_episodes);
51
42 view_episodes = new Gtk.FlowBox ();52 view_episodes = new Gtk.FlowBox ();
43 view_episodes.margin = 24;53 view_episodes.margin = 24;
44 view_episodes.homogeneous = true;54 view_episodes.homogeneous = true;
@@ -58,9 +68,10 @@
58 alert_view.hide ();68 alert_view.hide ();
5969
60 expand = true;70 expand = true;
61 attach (poster, 0, 1, 1, 1);71 attach (poster, 0, 0, 1, 1);
62 attach (scrolled_window, 1, 1, 1, 1);72 attach (play_all, 0, 1, 1 ,1);
63 attach (alert_view, 1, 1, 1, 1);73 attach (scrolled_window, 1, 0, 1, 2);
74 attach (alert_view, 1, 0, 1, 2);
6475
65 manager = Audience.Services.LibraryManager.get_instance ();76 manager = Audience.Services.LibraryManager.get_instance ();
66 manager.video_file_deleted.connect (remove_item_from_path);77 manager.video_file_deleted.connect (remove_item_from_path);
@@ -81,8 +92,7 @@
81 var selected = (item as Audience.LibraryItem);92 var selected = (item as Audience.LibraryItem);
82 var video = selected.episodes.first ();93 var video = selected.episodes.first ();
83 if (video.video_file.query_exists ()) {94 if (video.video_file.query_exists ()) {
84 bool from_beginning = video.video_file.get_uri () != settings.current_video;95 playlist.add_item (video);
85 App.get_instance ().mainwindow.play_file (video.video_file.get_uri (), from_beginning);
86 }96 }
87 }97 }
8898
@@ -153,6 +163,14 @@
153 return false;163 return false;
154 }164 }
155165
166 public void play_all_episodes () {
167 playlist.clear ();
168 view_episodes.forall ((item)=> {
169 playlist.add_item ((item as LibraryItem).episodes.first (), false);
170 });
171 playlist.play_playlist ();
172 }
173
156 public void show_alert (string primary_text, string secondary_text, string icon_name) {174 public void show_alert (string primary_text, string secondary_text, string icon_name) {
157 alert_view.no_show_all = false;175 alert_view.no_show_all = false;
158 alert_view.show_all ();176 alert_view.show_all ();
159177
=== modified file 'src/Widgets/LibraryPage.vala'
--- src/Widgets/LibraryPage.vala 2016-09-27 20:26:37 +0000
+++ src/Widgets/LibraryPage.vala 2016-09-30 22:31:06 +0000
@@ -27,6 +27,7 @@
2727
28 public Gtk.FlowBox view_movies;28 public Gtk.FlowBox view_movies;
29 public Audience.Services.LibraryManager manager;29 public Audience.Services.LibraryManager manager;
30 public Audience.Widgets.Playlist playlist;
30 public Gtk.ScrolledWindow scrolled_window;31 public Gtk.ScrolledWindow scrolled_window;
31 bool poster_initialized = false;32 bool poster_initialized = false;
32 string query;33 string query;
@@ -45,11 +46,12 @@
4546
46 construct {47 construct {
47 manager = Audience.Services.LibraryManager.get_instance ();48 manager = Audience.Services.LibraryManager.get_instance ();
4849 playlist = Audience.Widgets.Playlist.get_instance ();
49 query = "";50 query = "";
5051
51 scrolled_window = new Gtk.ScrolledWindow (null, null);52 scrolled_window = new Gtk.ScrolledWindow (null, null);
52 scrolled_window.expand = true;53 scrolled_window.height_request = 100;
54 scrolled_window.width_request = 100;
5355
54 view_movies = new Gtk.FlowBox ();56 view_movies = new Gtk.FlowBox ();
55 view_movies.margin = 24;57 view_movies.margin = 24;
@@ -88,8 +90,7 @@
88 var selected = (item as Audience.LibraryItem);90 var selected = (item as Audience.LibraryItem);
8991
90 if (selected.episodes.size == 1) {92 if (selected.episodes.size == 1) {
91 bool from_beginning = selected.episodes.first ().video_file.get_uri () != settings.current_video;93 playlist.add_item (selected.episodes.first ());
92 App.get_instance ().mainwindow.play_file (selected.episodes.first ().video_file.get_uri (), from_beginning);
93 } else {94 } else {
94 last_filter = query;95 last_filter = query;
95 show_episodes (selected);96 show_episodes (selected);
9697
=== modified file 'src/Widgets/PlayerPage.vala'
--- src/Widgets/PlayerPage.vala 2016-09-28 02:43:54 +0000
+++ src/Widgets/PlayerPage.vala 2016-09-30 22:31:06 +0000
@@ -11,29 +11,22 @@
11 public class PlayerPage : Gtk.EventBox {11 public class PlayerPage : Gtk.EventBox {
12 public signal void unfullscreen_clicked ();12 public signal void unfullscreen_clicked ();
13 public signal void ended ();13 public signal void ended ();
14 public signal void started (Audience.Objects.Video video);
1415
15 public GtkClutter.Embed clutter;16 public GtkClutter.Embed clutter;
16 private Clutter.Actor video_actor;17 private Clutter.Actor video_actor;
17 private Audience.Widgets.BottomBar bottom_bar;18 private Audience.Widgets.BottomBar bottom_bar;
19 private Audience.Widgets.Playlist playlist_bar;
18 private Clutter.Stage stage;20 private Clutter.Stage stage;
19 private Gtk.Revealer unfullscreen_bar;21 private Gtk.Revealer unfullscreen_bar;
20 private GtkClutter.Actor unfullscreen_actor;22 private GtkClutter.Actor unfullscreen_actor;
21 private GtkClutter.Actor bottom_actor;23 private GtkClutter.Actor bottom_actor;
24 private GtkClutter.Actor playlist_actor;
22 private GnomeMediaKeys mediakeys;25 private GnomeMediaKeys mediakeys;
23 private ClutterGst.Playback playback;26 private ClutterGst.Playback playback;
2427
25 private bool mouse_primary_down = false;28 private bool mouse_primary_down = false;
2629
27 public bool repeat {
28 get{
29 return bottom_bar.repeat;
30 }
31
32 set{
33 bottom_bar.repeat = value;
34 }
35 }
36
37 public bool playing {30 public bool playing {
38 get {31 get {
39 return playback.playing;32 return playback.playing;
@@ -101,8 +94,24 @@
101 bottom_bar.bind_property ("playing", playback, "playing", BindingFlags.BIDIRECTIONAL);94 bottom_bar.bind_property ("playing", playback, "playing", BindingFlags.BIDIRECTIONAL);
102 bottom_bar.unfullscreen.connect (() => unfullscreen_clicked ());95 bottom_bar.unfullscreen.connect (() => unfullscreen_clicked ());
10396
97 playlist_bar = Audience.Widgets.Playlist.get_instance ();
98 playlist_bar.play.connect ((video, progress) => { play_video (video, progress); });
99 playlist_bar.collection_changed.connect ((size) => {
100 if (size == 0 && playing) {
101 playing = false;
102 reset_played_uri ();
103 ended ();
104 }
105 });
106
104 unfullscreen_bar = bottom_bar.get_unfullscreen_button ();107 unfullscreen_bar = bottom_bar.get_unfullscreen_button ();
105108
109 playlist_actor = new GtkClutter.Actor.with_contents (playlist_bar);
110 playlist_actor.opacity = GLOBAL_OPACITY;
111 playlist_actor.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.HEIGHT, 0));
112 playlist_actor.add_constraint (new Clutter.AlignConstraint (stage, Clutter.AlignAxis.X_AXIS, 1));
113 stage.add_child (playlist_actor);
114
106 bottom_actor = new GtkClutter.Actor.with_contents (bottom_bar);115 bottom_actor = new GtkClutter.Actor.with_contents (bottom_bar);
107 bottom_actor.opacity = GLOBAL_OPACITY;116 bottom_actor.opacity = GLOBAL_OPACITY;
108 bottom_actor.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.WIDTH, 0));117 bottom_actor.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.WIDTH, 0));
@@ -117,17 +126,16 @@
117126
118 //media keys127 //media keys
119 try {128 try {
120 mediakeys = Bus.get_proxy_sync (BusType.SESSION,129 mediakeys = Bus.get_proxy_sync (BusType.SESSION, "org.gnome.SettingsDaemon", "/org/gnome/SettingsDaemon/MediaKeys");
121 "org.gnome.SettingsDaemon", "/org/gnome/SettingsDaemon/MediaKeys");
122 mediakeys.MediaPlayerKeyPressed.connect ((bus, app, key) => {130 mediakeys.MediaPlayerKeyPressed.connect ((bus, app, key) => {
123 if (app != "audience")131 if (app != "audience")
124 return;132 return;
125 switch (key) {133 switch (key) {
126 case "Previous":134 case "Previous":
127 get_playlist_widget ().previous ();135 playlist_bar.previous ();
128 break;136 break;
129 case "Next":137 case "Next":
130 get_playlist_widget ().next ();138 playlist_bar.next ();
131 break;139 break;
132 case "Play":140 case "Play":
133 playback.playing = !playback.playing;141 playback.playing = !playback.playing;
@@ -181,13 +189,11 @@
181 });189 });
182190
183 this.destroy.connect (() => {191 this.destroy.connect (() => {
184 // FIXME:should find better way to decide if its end of playlist192 if (playback.progress < 1) {
185 if (playback.progress > 0.99)193 settings.last_stopped = playback.progress;
194 } else {
186 settings.last_stopped = 0;195 settings.last_stopped = 0;
187 else196 }
188 settings.last_stopped = playback.progress;
189
190 get_playlist_widget ().save_playlist ();
191 Audience.Services.Inhibitor.get_instance ().uninhibit ();197 Audience.Services.Inhibitor.get_instance ().uninhibit ();
192 });198 });
193199
@@ -195,25 +201,13 @@
195 playback.eos.connect (() => {201 playback.eos.connect (() => {
196 Idle.add (() => {202 Idle.add (() => {
197 playback.progress = 0;203 playback.progress = 0;
198 if (!get_playlist_widget ().next ()) {204 if (!playlist_bar.next ()) {
199 if (repeat) {205 ended ();
200 play_file (get_playlist_widget ().get_first_item ().get_uri ());
201 playback.playing = true;
202 } else {
203 playback.playing = false;
204 settings.last_stopped = 0;
205 ended ();
206 }
207 }206 }
208 return false;207 return false;
209 });208 });
210 });209 });
211210
212 //playlist wants us to open a file
213 get_playlist_widget ().play.connect ((file) => {
214 this.play_file (file.get_uri ());
215 });
216
217 bottom_bar.notify["child-revealed"].connect (() => {211 bottom_bar.notify["child-revealed"].connect (() => {
218 if (bottom_bar.child_revealed == true) {212 if (bottom_bar.child_revealed == true) {
219 App.get_instance ().mainwindow.get_window ().set_cursor (null);213 App.get_instance ().mainwindow.get_window ().set_cursor (null);
@@ -230,6 +224,7 @@
230 Audience.Services.Inhibitor.get_instance ().inhibit ();224 Audience.Services.Inhibitor.get_instance ().inhibit ();
231 } else {225 } else {
232 Audience.Services.Inhibitor.get_instance ().uninhibit ();226 Audience.Services.Inhibitor.get_instance ().uninhibit ();
227 settings.last_stopped = playback.progress;
233 }228 }
234 });229 });
235230
@@ -237,24 +232,20 @@
237 show_all ();232 show_all ();
238 }233 }
239234
240 public void play_file (string uri, bool from_beginning = true) {235 private void play_video (Audience.Objects.Video video, double progress = 0) {
241 debug ("Opening %s", uri);236 string? uri = video.video_file.get_uri ();
242 get_playlist_widget ().set_current (uri);
243 playback.uri = uri;237 playback.uri = uri;
244238
245 string? sub_uri = get_subtitle_for_uri (uri);239 string? sub_uri = get_subtitle_for_uri (uri);
246 if (sub_uri != null && sub_uri != uri)240 if (sub_uri != null && sub_uri != uri) {
247 playback.set_subtitle_uri (sub_uri);241 playback.set_subtitle_uri (sub_uri);
248242 }
249 App.get_instance ().mainwindow.title = get_title (uri);243
250244 if (playback.progress != progress) {
251 if (from_beginning) {245 playback.progress = progress;
252 playback.progress = 0.0;246 }
253 } else {
254 playback.progress = settings.last_stopped;
255 }
256
257 playback.playing = !settings.playback_wait;247 playback.playing = !settings.playback_wait;
248
258 Gtk.RecentManager recent_manager = Gtk.RecentManager.get_default ();249 Gtk.RecentManager recent_manager = Gtk.RecentManager.get_default ();
259 recent_manager.add_item (uri);250 recent_manager.add_item (uri);
260251
@@ -262,53 +253,26 @@
262253
263 Audience.Services.Inhibitor.get_instance ().inhibit ();254 Audience.Services.Inhibitor.get_instance ().inhibit ();
264 settings.current_video = uri;255 settings.current_video = uri;
256
257 started (video);
265 }258 }
266259
267 public double get_progress () {260 public double get_progress () {
268 return playback.progress;261 return playback.progress;
269 }262 }
270263
271 public string get_played_uri () {
272 return playback.uri;
273 }
274
275 public void reset_played_uri () {264 public void reset_played_uri () {
276 playback.uri = "";265 playback.uri = "";
277 }266 }
278267
279 public void next () {
280 get_playlist_widget ().next ();
281 }
282
283 public void prev () {
284 get_playlist_widget ().next ();
285 }
286
287 public void resume_last_videos () {
288 play_file (settings.current_video);
289 playback.playing = false;
290 if (settings.resume_videos) {
291 playback.progress = settings.last_stopped;
292 } else {
293 playback.progress = 0.0;
294 }
295
296 playback.playing = !settings.playback_wait;
297 }
298
299 public void append_to_playlist (File file) {268 public void append_to_playlist (File file) {
300 if (playback.playing && is_subtitle (file.get_uri ())) {269 if (playback.playing && is_subtitle (file.get_uri ())) {
301 playback.set_subtitle_uri (file.get_uri ());270 playback.set_subtitle_uri (file.get_uri ());
302 } else {271 } else {
303 get_playlist_widget ().add_item (file);272 playlist_bar.add_from_file (file);
304 }273 }
305 }274 }
306275
307 public void play_first_in_playlist () {
308 var file = get_playlist_widget ().get_first_item ();
309 play_file (file.get_uri ());
310 }
311
312 public void reveal_control () {276 public void reveal_control () {
313 bottom_bar.reveal_control ();277 bottom_bar.reveal_control ();
314 }278 }
@@ -328,10 +292,6 @@
328 playback.progress = double.min (new_progress, 1.0);292 playback.progress = double.min (new_progress, 1.0);
329 }293 }
330294
331 public Widgets.Playlist get_playlist_widget () {
332 return bottom_bar.playlist_popover.playlist;
333 }
334
335 private string? get_subtitle_for_uri (string uri) {295 private string? get_subtitle_for_uri (string uri) {
336 string without_ext;296 string without_ext;
337 int last_dot = uri.last_index_of (".", 0);297 int last_dot = uri.last_index_of (".", 0);
@@ -365,7 +325,7 @@
365 public bool update_pointer_position (double y, int window_height) {325 public bool update_pointer_position (double y, int window_height) {
366 App.get_instance ().mainwindow.get_window ().set_cursor (null);326 App.get_instance ().mainwindow.get_window ().set_cursor (null);
367327
368 bottom_bar.reveal_control ();328 reveal_control ();
369329
370 return false;330 return false;
371 }331 }
372332
=== modified file 'src/Widgets/Playlist.vala'
--- src/Widgets/Playlist.vala 2016-08-19 16:27:45 +0000
+++ src/Widgets/Playlist.vala 2016-09-30 22:31:06 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-1// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
2/*-2/*-
3 * Copyright (c) 2013-2014 Audience Developers (http://launchpad.net/pantheon-chat)3 * Copyright (c) 2016-2016 elementary LLC.
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by6 * it under the terms of the GNU General Public License as published by
@@ -15,221 +15,224 @@
15 * You should have received a copy of the GNU General Public License15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *17 *
18 * Authored by: Tom Beckmann <tomjonabc@gmail.com>18 * Authored by: Artem Anufrij <artem.anufrij@live.de>
19 *
19 */20 */
2021
21namespace Audience.Widgets {22namespace Audience.Widgets {
22 public class Playlist : Gtk.TreeView {23 public class Playlist : Gtk.Revealer {
23 // the player is requested to play path24
24 public signal void play (File path);25 public signal void play (Audience.Objects.Video video, double process = 0);
25 public signal void item_added ();26 public signal void collection_changed (uint size);
2627 public signal void visibility_changed (bool visible);
27 private enum Columns {28
28 PLAYING,29 Gtk.Grid grid;
29 TITLE,30 Gtk.ScrolledWindow scrolled_window;
30 FILENAME,31 Gtk.ListBox listbox;
31 N_COLUMNS32 Gtk.ToggleButton repeat_button;
33
34 public uint size { get { return listbox.get_children ().length (); } }
35
36 static Playlist _instance = null;
37 public static Playlist get_instance () {
38 if (_instance == null) {
39 _instance = new Playlist ();
40 }
41 return _instance;
32 }42 }
3343
34 private int current = 0;44 private Playlist () {}
35 private Gtk.ListStore playlist;45
3646 construct {
37 public Playlist () {47 valign = Gtk.Align.FILL;
38 this.playlist = new Gtk.ListStore (Columns.N_COLUMNS, typeof (Icon), typeof (string), typeof (string));48 transition_type = Gtk.RevealerTransitionType.SLIDE_LEFT;
39 this.model = this.playlist;49
40 this.expand = true;50 grid = new Gtk.Grid ();
41 this.headers_visible = false;51 grid.expand = true;
42 this.activate_on_single_click = true;52 grid.valign = Gtk.Align.FILL;
43 this.can_focus = false;53 grid.halign = Gtk.Align.FILL;
44 get_selection ().mode = Gtk.SelectionMode.NONE;54 grid.orientation = Gtk.Orientation.VERTICAL;
4555 grid.margin_bottom = 28;
46 var text_render = new Gtk.CellRendererText ();56
47 text_render.ellipsize = Pango.EllipsizeMode.MIDDLE;57 scrolled_window = new Gtk.ScrolledWindow (null, null);
4858 scrolled_window.expand = true;
49 this.insert_column_with_attributes (-1, "Playing", new Gtk.CellRendererPixbuf (), "gicon", Columns.PLAYING);59 scrolled_window.set_policy (Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
50 this.insert_column_with_attributes (-1, "Title", text_render, "text", Columns.TITLE);60
51 this.set_tooltip_column (1);61
5262 listbox = new Gtk.ListBox ();
53 this.row_activated.connect ((path ,col) => {63 listbox.row_selected.connect ( play_selected );
54 Gtk.TreeIter iter;64 listbox.expand = true;
55 playlist.get_iter (out iter, path);65 listbox.valign = Gtk.Align.FILL;
56 string filename;66
57 playlist.get (iter, Columns.FILENAME, out filename);67 var toolbar = new Gtk.Toolbar ();
58 play (File.new_for_commandline_arg (filename));68 toolbar.get_style_context ().add_class (Gtk.STYLE_CLASS_INLINE_TOOLBAR);
59 });69 toolbar.icon_size = Gtk.IconSize.SMALL_TOOLBAR;
6070
61 this.reorderable = true;71 var add_button = new Gtk.ToolButton (new Gtk.Image.from_icon_name ("document-open-symbolic", Gtk.IconSize.BUTTON), null);
62 this.model.row_inserted.connect ((path, iter) => {72 add_button.tooltip_text = _("Add Video…");
63 Gtk.TreeIter it;73 add_button.clicked.connect (() => { App.get_instance ().mainwindow.run_open_file (false, false); });
64 playlist.get_iter (out it, path);74 toolbar.add (add_button);
65 Gdk.Pixbuf playing;75
66 playlist.get (it, Columns.PLAYING, out playing);76 var repeat_item = new Gtk.ToolItem ();
67 if (playing != null) //if playing is not null it's the current item77 repeat_item.halign = Gtk.Align.END;
68 this.current = int.parse (path.to_string ());78
69 });79 repeat_button = new Gtk.ToggleButton ();
7080 repeat_button.set_image (new Gtk.Image.from_icon_name ("media-playlist-no-repeat-symbolic", Gtk.IconSize.BUTTON));
71 // Automatically load from gsettings last_played_videos81 repeat_button.set_tooltip_text (_("Enable Repeat"));
82 repeat_button.toggled.connect (() => {
83 if (repeat_button.active) {
84 repeat_button.set_image (new Gtk.Image.from_icon_name ("media-playlist-repeat-symbolic", Gtk.IconSize.BUTTON));
85 repeat_button.set_tooltip_text (_("Disable Repeat"));
86 } else {
87 repeat_button.set_image (new Gtk.Image.from_icon_name ("media-playlist-no-repeat-symbolic", Gtk.IconSize.BUTTON));
88 repeat_button.set_tooltip_text (_("Enable Repeat"));
89 }
90 });
91
92 repeat_item.add (repeat_button);
93 toolbar.add (repeat_item);
94 scrolled_window.add (listbox);
95 grid.attach (scrolled_window, 0, 0, 1, 1);
96 grid.add (toolbar);
97 add (grid);
72 restore_playlist ();98 restore_playlist ();
73 }99 show_all ();
74100
75 ~Playlist () {101 destroy.connect (() =>{ save_playlist (); });
76 save_playlist ();102 }
77 }103
104 public void toggle_reveal_control () {
105 if (!child_revealed) {
106 show_all ();
107 }
108 set_reveal_child (!child_revealed);
109 visibility_changed (!child_revealed);
110 }
111
112 public void hide_reval_control () {
113 set_reveal_child (false);
114 visibility_changed (false);
115 }
116
117 public void add_item (Audience.Objects.Video video, bool instand_play = true) {
118 var new_item = new Audience.Widgets.PlaylistItem (video);
119 if (instand_play) {
120 clear ();
121 }
122 listbox.add (new_item);
123 if (instand_play) {
124 listbox.select_row (new_item);
125 }
126 collection_changed (size);
127 }
128
129 public void remove_item (Gtk.ListBoxRow row) {
130 if (row.is_selected ()) {
131 next ();
132 }
133 listbox.remove (row);
134 save_playlist ();
135 collection_changed (size);
136 }
137
138 public void clear () {
139 listbox.forall ((item)=> {
140 item.dispose ();
141 });
142 }
143
144 private void play_selected (Gtk.ListBoxRow? row) {
145 if (row != null) {
146 listbox.forall ((item) => {
147 (item as PlaylistItem).update_state ();
148 });
149 start_playing (((PlaylistItem)row).video);
150 }
151 }
152
153 private void start_playing (Audience.Objects.Video video) {
154 double progress = 0;
155 if (video.video_file.get_uri () == settings.current_video) {
156 progress = settings.last_stopped;
157 }
158 play (video, progress);
159 }
160
161 public void play_playlist () {
162 listbox.select_row (listbox.get_row_at_index(0));
163 }
78164
79 public bool next () {165 public bool next () {
80 Gtk.TreeIter iter;166 if (size > listbox.get_selected_row ().get_index () + 1) {
81 if (playlist.get_iter_from_string (out iter, (this.current + 1).to_string ())){167 var next_video = listbox.get_row_at_index (listbox.get_selected_row ().get_index () + 1);
82 string filename;168 listbox.select_row (next_video);
83 playlist.get (iter, Columns.FILENAME, out filename);169 return true;
84 current++;170 } else if (repeat_button.active && size > 0) {
85 play (File.new_for_commandline_arg (filename));171 if (size == 1) {
86 return true;172 listbox.select_row (null);
87 }173 }
88 current = 0;174 listbox.select_row (listbox.get_row_at_index (0));
89 return false;175 return true;
90 }176 }
91177 return false;
92 public void previous () {178 }
93 Gtk.TreeIter iter;179
94 if (playlist.get_iter_from_string (out iter, (this.current - 1).to_string ())){180 public bool previous () {
95 string filename;181 if (listbox.get_selected_row ().get_index () > 0) {
96 playlist.get (iter, Columns.FILENAME, out filename);182 var next_video = listbox.get_row_at_index (listbox.get_selected_row ().get_index () - 1);
97 current--;183 listbox.select_row (next_video);
98 play (File.new_for_commandline_arg (filename));184 return true;
99 }185 }
100 }186 return false;
101187 }
102 public void add_item (File path) {188
103 if (!path.query_exists ())189 public void resume () {
104 return;190 listbox.forall ((item) => {
105 var file_name = path.get_uri ();191 var video = (item as PlaylistItem).video;
106 bool exist = false;192 if (video.video_file.get_uri () == settings.current_video) {
107 Gtk.TreeIter iter;193 if (listbox.get_selected_row () != (item as PlaylistItem)) {
108194 listbox.select_row (item as PlaylistItem);
109 playlist.foreach ((model, path, iter) => {195 } else {
110 Value filename;196 start_playing (video);
111 playlist.get_value (iter, Columns.FILENAME, out filename);197 }
112 string name = filename.get_string ();198 return;
113 if (name == file_name)199 }
114 exist = true;200 });
115 return false;201
116 });202 play_playlist ();
117 if (exist)
118 return;
119
120 Icon? playing = null;
121 Gtk.TreeIter dummy;
122 if (!playlist.get_iter_first (out dummy)){
123 playing = new ThemedIcon ("media-playback-start-symbolic");
124 } else {
125 playing = null;
126 }
127
128 playlist.append (out iter);
129 playlist.set (iter, Columns.PLAYING, playing,
130 Columns.TITLE, Audience.get_title (path.get_basename ()),
131 Columns.FILENAME, path.get_uri ());
132 item_added ();
133 }
134
135 public void remove_item (File path) {
136 var file_name = path.get_uri ();
137
138 playlist.foreach ((model, path, iter) => {
139 Value filename;
140 playlist.get_value (iter, Columns.FILENAME, out filename);
141 string name = filename.get_string ();
142 if (name == file_name)
143 playlist.remove (iter);
144 return false;
145 });
146 }
147
148 public void clear_items () {
149 current = 0;
150 playlist.clear ();
151 }
152
153 public File? get_first_item () {
154 Gtk.TreeIter iter;
155 if (playlist.get_iter_first (out iter)){
156 string filename;
157 playlist.get (iter, Columns.FILENAME, out filename);
158 return File.new_for_commandline_arg (filename);
159 }
160 return null;
161 }
162
163 public int get_current () {
164 return current;
165 }
166
167 public void set_current (string current_file) {
168 int count = 0;
169 int current_played = 0;
170 playlist.foreach ((model, path, iter) => {
171 playlist.set (iter, Columns.PLAYING, null);
172 Value filename;
173 playlist.get_value (iter, Columns.FILENAME, out filename);
174 string name = filename.get_string ();
175 if (name == current_file)
176 current_played = count;
177 count++;
178 return false;
179 });
180
181 Gtk.TreeIter new_iter;
182 playlist.get_iter_from_string (out new_iter, current_played.to_string ());
183 playlist.set (new_iter, Columns.PLAYING, new ThemedIcon ("media-playback-start-symbolic"));
184
185 this.current = current_played;
186
187 }
188
189 public List<string> get_all_items () {
190 var list = new List<string> ();
191 playlist.foreach ((model, path, iter) => {
192 Value filename;
193 playlist.get_value (iter, Columns.FILENAME, out filename);
194 string name = filename.get_string ();
195 list.append (name);
196 return false;
197 });
198 return list.copy ();
199 }203 }
200204
201 public void save_playlist () {205 public void save_playlist () {
202 if (Audience.App.get_instance ().mainwindow.is_privacy_mode_enabled ()) {206 if (Audience.App.get_instance ().mainwindow.is_privacy_mode_enabled ()) {
203 return;207 return;
204 }208 }
205209 var list = new Gee.ArrayList<string> ();
206 var list = new List<string> ();210 listbox.forall ((item) => {
207 playlist.foreach ((model, path, iter) => {211 list.add ((item as PlaylistItem).video.video_file.get_uri ());
208 Value filename;
209 playlist.get_value (iter, Columns.FILENAME, out filename);
210 string name = filename.get_string ();
211 list.append (name);
212 return false;
213 });212 });
214213 settings.last_played_videos = list.to_array ();
215 uint i = 0;214 if (list.size == 0) {
216 var videos = new string[list.length ()];215 settings.current_video = "";
217 foreach (var filename in list) {216 settings.last_stopped = 0;
218 videos[i] = filename;
219 i++;
220 }217 }
221
222 settings.last_played_videos = videos;
223 }218 }
224219
225 private void restore_playlist () {220 private void restore_playlist () {
226 this.current = 0;221 foreach (var filename in settings.last_played_videos) {
227 /* foreach (var filename in settings.last_played_videos) { */222 add_from_uri (filename);
228 for (int i = 0;i<settings.last_played_videos.length;i++) {
229 if (settings.last_played_videos[i] == settings.current_video)
230 this.current = i;
231 add_item (File.new_for_uri (settings.last_played_videos[i]));
232 }223 }
233 }224 }
225
226 public void add_from_uri (string uri, bool instand_play = false) {
227 File file = File.new_for_uri (uri);
228 add_from_file (file);
229 }
230
231 public void add_from_file (File file, bool instand_play = false) {
232 if (file.query_exists () && file.get_path () != null) {
233 FileInfo file_info = file.query_info (FileAttribute.STANDARD_CONTENT_TYPE, 0);
234 add_item (new Audience.Objects.Video (Path.get_dirname (file.get_path ()) ,Path.get_basename (file.get_path ()),file_info.get_content_type ()), instand_play);
235 }
236 }
234 }237 }
235}238}
236239
=== added file 'src/Widgets/PlaylistItem.vala'
--- src/Widgets/PlaylistItem.vala 1970-01-01 00:00:00 +0000
+++ src/Widgets/PlaylistItem.vala 2016-09-30 22:31:06 +0000
@@ -0,0 +1,66 @@
1// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
2/*-
3 * Copyright (c) 2016-2016 elementary LLC.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authored by: Artem Anufrij <artem.anufrij@live.de>
19 *
20 */
21
22namespace Audience.Widgets {
23 public class PlaylistItem : Gtk.ListBoxRow {
24
25 public Audience.Objects.Video video { get; construct set; }
26 Gtk.Grid grid;
27 Gtk.Label title;
28 Gtk.Image image;
29 Gtk.Button delete_button;
30
31 public PlaylistItem (Audience.Objects.Video video) {
32 Object (video: video);
33 }
34
35 construct {
36 grid = new Gtk.Grid ();
37 title = new Gtk.Label (video.title);
38 title.expand = true;
39 title.halign = Gtk.Align.START;
40
41 image = new Gtk.Image.from_icon_name ("media-playback-start-symbolic", Gtk.IconSize.MENU);
42 image.margin_right = 4;
43
44 delete_button = new Gtk.Button.from_icon_name ("edit-delete-symbolic", Gtk.IconSize.BUTTON);
45 delete_button.tooltip_text = _("Remove from Playlist");
46 delete_button.relief = Gtk.ReliefStyle.NONE;
47 delete_button.clicked.connect (() => { Audience.Widgets.Playlist.get_instance ().remove_item (this); });
48
49 grid.margin = 4;
50 grid.attach (title, 1, 0, 1, 1);
51 grid.attach (delete_button, 2, 0, 1, 1);
52 add (grid);
53 }
54
55 public void update_state () {
56 if (is_selected () && image.parent != grid) {
57 grid.attach (image, 0, 0, 1, 1);
58 image.show ();
59 } else {
60 if (image.parent == grid) {
61 grid.remove (image);
62 }
63 }
64 }
65 }
66}
067
=== removed file 'src/Widgets/PlaylistPopover.vala'
--- src/Widgets/PlaylistPopover.vala 2016-07-29 05:02:48 +0000
+++ src/Widgets/PlaylistPopover.vala 1970-01-01 00:00:00 +0000
@@ -1,118 +0,0 @@
1// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
2/*-
3 * Copyright (c) 2013-2014 Audience Developers (http://launchpad.net/pantheon-chat)
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authored by: Corentin Noël <corentin@elementaryos.org>
19 */
20
21public class Audience.Widgets.PlaylistPopover : Gtk.Popover {
22 public Playlist playlist;
23 public Gtk.ToggleButton rep;
24 private Gtk.ScrolledWindow playlist_scrolled;
25 private Gtk.Button dvd;
26
27 public PlaylistPopover () {
28 opacity = GLOBAL_OPACITY;
29 var grid = new Gtk.Grid ();
30 grid.row_spacing = 6;
31 grid.column_spacing = 12;
32 grid.margin = 6;
33
34 var fil = new Gtk.Button.from_icon_name ("document-open-symbolic", Gtk.IconSize.BUTTON);
35 fil.set_tooltip_text (_("Open file"));
36 dvd = new Gtk.Button.from_icon_name ("media-optical-symbolic", Gtk.IconSize.BUTTON);
37 dvd.set_tooltip_text (_("Play from Disc"));
38
39 rep = new Gtk.ToggleButton ();
40 rep.set_image (new Gtk.Image.from_icon_name ("media-playlist-no-repeat-symbolic", Gtk.IconSize.BUTTON));
41 rep.set_tooltip_text (_("Enable Repeat"));
42
43 playlist_scrolled = new Gtk.ScrolledWindow (null, null);
44 playlist_scrolled.set_min_content_height (100);
45 playlist_scrolled.set_min_content_width (260);
46
47 playlist = new Playlist ();
48 playlist_scrolled.add (playlist);
49
50 fil.clicked.connect ( () => {
51 hide ();
52 App.get_instance ().mainwindow.run_open_file (false, false);
53 });
54
55 dvd.clicked.connect ( () => {
56 hide ();
57 App.get_instance ().mainwindow.run_open_dvd ();
58 });
59
60 rep.toggled.connect ( () => {
61 /* app.repeat = rep.active; */
62 if (rep.active) {
63 rep.set_image (new Gtk.Image.from_icon_name ("media-playlist-repeat-symbolic", Gtk.IconSize.BUTTON));
64 rep.set_tooltip_text (_("Disable Repeat"));
65 } else {
66 rep.set_image (new Gtk.Image.from_icon_name ("media-playlist-no-repeat-symbolic", Gtk.IconSize.BUTTON));
67 rep.set_tooltip_text (_("Enable Repeat"));
68 }
69 });
70
71 grid.attach (playlist_scrolled, 0, 0, 7, 1);
72 grid.attach (fil, 0, 1, 1, 1);
73 grid.attach (dvd, 1, 1, 1, 1);
74 grid.attach (rep, 6, 1, 1, 1);
75
76 add (grid);
77
78 var disk_manager = DiskManager.get_default ();
79 set_dvd_visibility (disk_manager.has_media_volumes ());
80 disk_manager.volume_found.connect ((vol) => {
81 set_dvd_visibility (disk_manager.has_media_volumes ());
82 });
83
84 disk_manager.volume_removed.connect ((vol) => {
85 set_dvd_visibility (disk_manager.has_media_volumes ());
86 });
87 }
88
89 private void set_dvd_visibility (bool visible) {
90 dvd.no_show_all = !visible;
91 dvd.visible = visible;
92 }
93
94 //Override because the Popover doesn't auto-rejust his size.
95 public override void get_preferred_height (out int minimum_height, out int natural_height) {
96 base.get_preferred_height (out minimum_height, out natural_height);
97 int p_minimum_height;
98 int p_natural_height;
99 var app = ((Audience.App) GLib.Application.get_default ());
100 playlist.get_preferred_height (out p_minimum_height, out p_natural_height);
101 int temp_minimum_height = minimum_height + p_minimum_height;
102 int r_minimum_height;
103 int r_natural_height;
104 relative_to.get_preferred_height (out r_minimum_height, out r_natural_height);
105 if (temp_minimum_height < app.mainwindow.get_window ().get_height () - r_minimum_height*2) {
106 minimum_height = temp_minimum_height;
107 } else {
108 minimum_height = app.mainwindow.get_window ().get_height () - r_minimum_height*2;
109 }
110
111 int temp_natural_height = natural_height + p_natural_height;
112 if (temp_natural_height < app.mainwindow.get_window ().get_height () - r_natural_height*2) {
113 natural_height = temp_natural_height;
114 } else {
115 natural_height = minimum_height;
116 }
117 }
118}
1190
=== modified file 'src/Widgets/WelcomePage.vala'
--- src/Widgets/WelcomePage.vala 2016-09-28 02:32:33 +0000
+++ src/Widgets/WelcomePage.vala 2016-09-30 22:31:06 +0000
@@ -2,27 +2,19 @@
2 public class WelcomePage : Granite.Widgets.Welcome {2 public class WelcomePage : Granite.Widgets.Welcome {
3 private DiskManager disk_manager;3 private DiskManager disk_manager;
4 private Services.LibraryManager library_manager;4 private Services.LibraryManager library_manager;
5 private Audience.Widgets.Playlist playlist;
6
5 public WelcomePage () {7 public WelcomePage () {
6 base (_("No Videos Open"), _("Select a source to begin playing."));8 base (_("No Videos Open"), _("Select a source to begin playing."));
7 }9 }
810
9 construct {11 construct {
12 playlist = Audience.Widgets.Playlist.get_instance ();
13 playlist.collection_changed.connect ((playlist_size) => { build_replay_button (playlist_size); });
10 append ("document-open", _("Open file"), _("Open a saved file."));14 append ("document-open", _("Open file"), _("Open a saved file."));
1115
12 var filename = settings.current_video;16 append ("media-playlist-repeat", _("Replay last video"), "");
13 var last_file = File.new_for_uri (filename);17 set_item_visible (1, false);
14 bool show_last_file = settings.current_video != "";
15 if (last_file.query_exists () == false) {
16 show_last_file = false;
17 }
18
19 if (settings.last_stopped == 0.0 || !settings.resume_videos) {
20 append ("media-playlist-repeat", _("Replay last video"), get_title (last_file.get_basename ()));
21 } else {
22 append ("media-playback-start", _("Resume last video"), get_title (last_file.get_basename ()));
23 }
24
25 set_item_visible (1, show_last_file);
2618
27 //look for dvd19 //look for dvd
28 disk_manager = DiskManager.get_default ();20 disk_manager = DiskManager.get_default ();
@@ -54,11 +46,10 @@
54 var window = App.get_instance ().mainwindow;46 var window = App.get_instance ().mainwindow;
55 switch (index) {47 switch (index) {
56 case 0:48 case 0:
57 // Open file49 window.run_open_file ();
58 window.run_open_file (true);
59 break;50 break;
60 case 1:51 case 1:
61 window.resume_last_videos ();52 playlist.resume ();
62 break;53 break;
63 case 2:54 case 2:
64 window.run_open_dvd ();55 window.run_open_dvd ();
@@ -67,30 +58,46 @@
67 window.show_library ();58 window.show_library ();
68 }59 }
69 });60 });
61
62 build_replay_button (playlist.size);
70 }63 }
7164
72 public void refresh () {65 private void build_replay_button (uint playlist_size) {
66 string current_video = settings.current_video;
67
73 var replay_button = get_button_from_index (1);68 var replay_button = get_button_from_index (1);
7469
75 var filename = settings.current_video;70 if (playlist_size > 1 && current_video != "") {
76 var last_file = File.new_for_uri (filename);71 // Resume Playlist;
7772 replay_button.title = _("Resume playlist");
78 if (settings.last_stopped == 0.0) {73 replay_button.icon.icon_name = ("media-playback-start");
74 replay_button.description = get_title (Path.get_basename (current_video));
75 set_item_visible (1, true);
76 replay_button.show_all ();
77 } else if (playlist_size > 1 && current_video == "") {
78 // Replay Playlist
79 replay_button.title = _("Start playing playlist");
80 replay_button.icon.icon_name = ("media-playback-start");
81 replay_button.description = _("All videos of current playlist");
82 set_item_visible (1, true);
83 replay_button.show_all ();
84 } else if (current_video != "" && settings.last_stopped > 0) {
85 // Resume Video
86 replay_button.title = _("Resume last video");
87 replay_button.icon.icon_name = ("media-playback-start");
88 replay_button.description = get_title (Path.get_basename (current_video));
89 set_item_visible (1, true);
90 replay_button.show_all ();
91 } else if (current_video != "" && settings.last_stopped == 0) {
92 // Replay Video
79 replay_button.title = _("Replay last video");93 replay_button.title = _("Replay last video");
80 replay_button.icon.icon_name = ("media-playlist-repeat");94 replay_button.icon.icon_name = ("media-playlist-repeat");
95 replay_button.description = get_title (Path.get_basename (current_video));
96 set_item_visible (1, true);
97 replay_button.show_all ();
81 } else {98 } else {
82 replay_button.title = _("Resume last video");99 set_item_visible (1, false);
83 replay_button.icon.icon_name = ("media-playback-start");100 }
84 }
85 replay_button.description = get_title (last_file.get_basename ());
86
87 bool show_last_file = settings.current_video != "";
88 if (last_file.query_exists () == false) {
89 show_last_file = false;
90 }
91
92 set_item_visible (1, show_last_file);
93 set_item_visible (2, disk_manager.has_media_volumes ());
94 }101 }
95 }102 }
96}103}
97104
=== modified file 'src/Window.vala'
--- src/Window.vala 2016-09-27 19:58:34 +0000
+++ src/Window.vala 2016-09-30 22:31:06 +0000
@@ -27,6 +27,7 @@
27 private PlayerPage player_page;27 private PlayerPage player_page;
28 private WelcomePage welcome_page;28 private WelcomePage welcome_page;
29 private LibraryPage library_page;29 private LibraryPage library_page;
30 private Audience.Widgets.Playlist playlist;
30 private EpisodesPage episodes_page;31 private EpisodesPage episodes_page;
31 private Granite.Widgets.AlertView alert_view;32 private Granite.Widgets.AlertView alert_view;
32 private Toast app_notification;33 private Toast app_notification;
@@ -42,9 +43,7 @@
4243
43 public signal void media_volumes_changed ();44 public signal void media_volumes_changed ();
4445
45 public Window () {46 public Window () {}
46
47 }
4847
49 construct {48 construct {
50 zeitgeist_manager = new ZeitgeistManager ();49 zeitgeist_manager = new ZeitgeistManager ();
@@ -78,6 +77,9 @@
7877
79 set_titlebar (header);78 set_titlebar (header);
8079
80 welcome_page = new WelcomePage ();
81 playlist = Audience.Widgets.Playlist.get_instance ();
82
81 library_page = LibraryPage.get_instance ();83 library_page = LibraryPage.get_instance ();
82 library_page.map.connect (() => {84 library_page.map.connect (() => {
83 search_entry.visible = true;85 search_entry.visible = true;
@@ -110,18 +112,12 @@
110 search_entry.text = "";112 search_entry.text = "";
111 });113 });
112114
113 welcome_page = new WelcomePage ();
114
115 player_page = new PlayerPage ();115 player_page = new PlayerPage ();
116 player_page.ended.connect (on_player_ended);116 player_page.ended.connect (on_player_ended);
117 player_page.unfullscreen_clicked.connect (() => {117 player_page.unfullscreen_clicked.connect (() => {
118 unfullscreen ();118 unfullscreen ();
119 });119 });
120120
121 player_page.notify["playing"].connect (() => {
122 set_keep_above (player_page.playing && settings.stay_on_top);
123 });
124
125 player_page.map.connect (() => {121 player_page.map.connect (() => {
126 app_notification.visible = false;122 app_notification.visible = false;
127 });123 });
@@ -130,6 +126,11 @@
130 app_notification.visible = true;126 app_notification.visible = true;
131 });127 });
132128
129 player_page.started.connect ((video) => {
130 this.title = video.title;
131 show_player ();
132 });
133
133 alert_view = new Granite.Widgets.AlertView ("", "", "");134 alert_view = new Granite.Widgets.AlertView ("", "", "");
134 alert_view.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL);135 alert_view.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL);
135 alert_view.set_vexpand (true);136 alert_view.set_vexpand (true);
@@ -154,7 +155,7 @@
154 app_notification.accept.connect (() => {155 app_notification.accept.connect (() => {
155 library_page.manager.undo_delete_item ();156 library_page.manager.undo_delete_item ();
156 if (main_stack.visible_child != episodes_page) {157 if (main_stack.visible_child != episodes_page) {
157 main_stack.set_visible_child (library_page);158 main_stack.visible_child = library_page;
158 }159 }
159 });160 });
160161
@@ -314,7 +315,7 @@
314 }315 }
315 } else if (main_stack.visible_child == welcome_page) {316 } else if (main_stack.visible_child == welcome_page) {
316 if (match_keycode (Gdk.Key.p, keycode) || match_keycode (Gdk.Key.space, keycode)) {317 if (match_keycode (Gdk.Key.p, keycode) || match_keycode (Gdk.Key.space, keycode)) {
317 resume_last_videos ();318 playlist.resume ();
318 return true;319 return true;
319 } else if (ctrl_pressed && match_keycode (Gdk.Key.o, keycode)) {320 } else if (ctrl_pressed && match_keycode (Gdk.Key.o, keycode)) {
320 run_open_file ();321 run_open_file ();
@@ -344,7 +345,7 @@
344345
345 public void open_files (File[] files, bool clear_playlist = false, bool force_play = true) {346 public void open_files (File[] files, bool clear_playlist = false, bool force_play = true) {
346 if (clear_playlist) {347 if (clear_playlist) {
347 player_page.get_playlist_widget ().clear_items ();348 playlist.clear ();
348 }349 }
349350
350 string[] videos = {};351 string[] videos = {};
@@ -365,15 +366,7 @@
365 }366 }
366367
367 if (force_play) {368 if (force_play) {
368 play_file (videos [0]);369 playlist.play_playlist ();
369 }
370 }
371
372 public void resume_last_videos () {
373 if (settings.current_video != "") {
374 play_file (settings.current_video, false);
375 } else {
376 run_open_file ();
377 }370 }
378 }371 }
379372
@@ -381,13 +374,6 @@
381 read_first_disk.begin ();374 read_first_disk.begin ();
382 }375 }
383376
384 public void show_library () {
385 navigation_button.label = navigation_button_welcomescreen;
386 navigation_button.show ();
387 main_stack.visible_child = library_page;
388 library_page.scrolled_window.grab_focus ();
389 }
390
391 public void run_open_file (bool clear_playlist = false, bool force_play = true) {377 public void run_open_file (bool clear_playlist = false, bool force_play = true) {
392 var file = new Gtk.FileChooserDialog (_("Open"), this, Gtk.FileChooserAction.OPEN,378 var file = new Gtk.FileChooserDialog (_("Open"), this, Gtk.FileChooserAction.OPEN,
393 _("_Cancel"), Gtk.ResponseType.CANCEL, _("_Open"), Gtk.ResponseType.ACCEPT);379 _("_Cancel"), Gtk.ResponseType.CANCEL, _("_Open"), Gtk.ResponseType.ACCEPT);
@@ -412,7 +398,7 @@
412 files += item;398 files += item;
413 }399 }
414400
415 open_files (files, clear_playlist, force_play);401 open_files (files, force_play);
416 settings.last_folder = file.get_current_folder ();402 settings.last_folder = file.get_current_folder ();
417 }403 }
418404
@@ -445,29 +431,37 @@
445 }431 }
446432
447 var root = volume.get_mount ().get_default_location ();433 var root = volume.get_mount ().get_default_location ();
448 play_file (root.get_uri ().replace ("file:///", "dvd:///"));434 //play_file (root.get_uri ().replace ("file:///", "dvd:///"));
449 }435 }
450436
451 private void on_player_ended () {437 private void on_player_ended () {
438 unfullscreen ();
452 navigate_back ();439 navigate_back ();
453 unfullscreen ();440 }
454 }441
455442
456 public void play_file (string uri, bool from_beginning = true) {443 public void show_library () {
444 navigation_button.label = navigation_button_welcomescreen;
445 navigation_button.show ();
446 main_stack.visible_child = library_page;
447 library_page.scrolled_window.grab_focus ();
448 }
449
450 public void show_player () {
457 search_entry.visible = false;451 search_entry.visible = false;
458 if (navigation_button.visible) {452 if (main_stack.visible_child != player_page) {
459 if (navigation_button.label == navigation_button_library) {453 if (navigation_button.visible) {
460 navigation_button.label = navigation_button_episodes;454 if (navigation_button.label == navigation_button_library) {
455 navigation_button.label = navigation_button_episodes;
456 } else {
457 navigation_button.label = navigation_button_library;
458 }
461 } else {459 } else {
462 navigation_button.label = navigation_button_library;460 navigation_button.show ();
461 navigation_button.label = navigation_button_welcomescreen;
463 }462 }
464 } else {463 main_stack.set_visible_child_full ("player", Gtk.StackTransitionType.SLIDE_LEFT);
465 navigation_button.show ();
466 navigation_button.label = navigation_button_welcomescreen;
467 }464 }
468
469 main_stack.set_visible_child_full ("player", Gtk.StackTransitionType.SLIDE_LEFT);
470 player_page.play_file (uri, from_beginning);
471 if (is_maximized) {465 if (is_maximized) {
472 fullscreen ();466 fullscreen ();
473 }467 }
@@ -475,8 +469,6 @@
475 if (settings.stay_on_top && !settings.playback_wait) {469 if (settings.stay_on_top && !settings.playback_wait) {
476 set_keep_above (true);470 set_keep_above (true);
477 }471 }
478
479 welcome_page.refresh ();
480 }472 }
481473
482 public void navigate_back () {474 public void navigate_back () {
@@ -502,7 +494,8 @@
502 main_stack.set_visible_child (welcome_page);494 main_stack.set_visible_child (welcome_page);
503 search_entry.visible = false;495 search_entry.visible = false;
504 }496 }
505 welcome_page.refresh ();497
498 playlist.hide_reval_control ();
506 }499 }
507500
508 public void hide_alert () {501 public void hide_alert () {

Subscribers

People subscribed via source and target branches