Merge lp:~artem-anufrij/audience/playlist-rewrite into lp:~audience-members/audience/trunk
- playlist-rewrite
- Merge into trunk
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 | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jeremy Wootten | code, ui, function | Needs Fixing | |
Review via email: mp+307248@code.launchpad.net |
Commit message
Description of the change
* Playlist redesign
* Bottom bar: Adden "Next" button
* Playlist: Added "Delete" button
* EpisodesView: Added "Play all" button
- 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
Artem Anufrij (artem-anufrij) wrote : | # |
Jeremy Wootten (jeremywootten) wrote : | # |
Conflicts with trunk. I tested after merging and resolving conflicts.
Compilation warnings:
Bottom Bar: playlist_item.added not used.
PlayList:
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.
Artem Anufrij (artem-anufrij) wrote : | # |
@Jeremy: Dan said I should to break up to work on this branch. Thank you for your time...
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:/
> playlist-
> You are reviewing the proposed merge of lp:~artem-anufrij/audience/playlist-rewrite
> into lp:audience.
>
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
1 | === modified file 'src/CMakeLists.txt' | |||
2 | --- src/CMakeLists.txt 2016-09-26 20:52:11 +0000 | |||
3 | +++ src/CMakeLists.txt 2016-09-30 22:31:06 +0000 | |||
4 | @@ -50,11 +50,11 @@ | |||
5 | 50 | DiskManager.vala | 50 | DiskManager.vala |
6 | 51 | Window.vala | 51 | Window.vala |
7 | 52 | Widgets/BottomBar.vala | 52 | Widgets/BottomBar.vala |
8 | 53 | Widgets/Playlist.vala | ||
9 | 54 | Widgets/PlaylistItem.vala | ||
10 | 53 | Widgets/SettingsPopover.vala | 55 | Widgets/SettingsPopover.vala |
11 | 54 | Widgets/PreviewPopover.vala | 56 | Widgets/PreviewPopover.vala |
12 | 55 | Widgets/TimeWidget.vala | 57 | Widgets/TimeWidget.vala |
13 | 56 | Widgets/Playlist.vala | ||
14 | 57 | Widgets/PlaylistPopover.vala | ||
15 | 58 | Widgets/WelcomePage.vala | 58 | Widgets/WelcomePage.vala |
16 | 59 | Widgets/PlayerPage.vala | 59 | Widgets/PlayerPage.vala |
17 | 60 | Widgets/LibraryPage.vala | 60 | Widgets/LibraryPage.vala |
18 | 61 | 61 | ||
19 | === modified file 'src/Objects/Video.vala' | |||
20 | --- src/Objects/Video.vala 2016-09-27 20:26:37 +0000 | |||
21 | +++ src/Objects/Video.vala 2016-09-30 22:31:06 +0000 | |||
22 | @@ -27,7 +27,7 @@ | |||
23 | 27 | public signal void thumbnail_changed (); | 27 | public signal void thumbnail_changed (); |
24 | 28 | public signal void trashed (); | 28 | public signal void trashed (); |
25 | 29 | 29 | ||
27 | 30 | public File video_file { get; private set; } | 30 | public File? video_file { get; private set; default = null;} |
28 | 31 | public string directory { get; construct set; } | 31 | public string directory { get; construct set; } |
29 | 32 | public string file { get; construct set; } | 32 | public string file { get; construct set; } |
30 | 33 | 33 | ||
31 | @@ -55,10 +55,15 @@ | |||
32 | 55 | manager = Audience.Services.LibraryManager.get_instance (); | 55 | manager = Audience.Services.LibraryManager.get_instance (); |
33 | 56 | manager.thumbler.finished.connect (dbus_finished); | 56 | manager.thumbler.finished.connect (dbus_finished); |
34 | 57 | 57 | ||
35 | 58 | if (directory.has_prefix ("file:///")) { | ||
36 | 59 | video_file = File.new_for_uri (directory + "/" + file); | ||
37 | 60 | } else { | ||
38 | 61 | video_file = File.new_for_path (get_path ()); | ||
39 | 62 | } | ||
40 | 63 | |||
41 | 58 | title = Audience.get_title (file); | 64 | title = Audience.get_title (file); |
42 | 59 | 65 | ||
43 | 60 | extract_metadata (); | 66 | extract_metadata (); |
44 | 61 | video_file = File.new_for_path (this.get_path ()); | ||
45 | 62 | 67 | ||
46 | 63 | if (directory != Audience.settings.library_folder) { | 68 | if (directory != Audience.settings.library_folder) { |
47 | 64 | container = Path.get_basename (directory); | 69 | container = Path.get_basename (directory); |
48 | 65 | 70 | ||
49 | === modified file 'src/Widgets/BottomBar.vala' | |||
50 | --- src/Widgets/BottomBar.vala 2016-09-28 02:43:54 +0000 | |||
51 | +++ src/Widgets/BottomBar.vala 2016-09-30 22:31:06 +0000 | |||
52 | @@ -24,6 +24,7 @@ | |||
53 | 24 | private const string PULSE_TYPE = "attention"; | 24 | private const string PULSE_TYPE = "attention"; |
54 | 25 | 25 | ||
55 | 26 | public signal void play_toggled (); | 26 | public signal void play_toggled (); |
56 | 27 | public signal void playlist_clicked (); | ||
57 | 27 | public signal void unfullscreen (); | 28 | public signal void unfullscreen (); |
58 | 28 | public signal void seeked (double val); | 29 | public signal void seeked (double val); |
59 | 29 | 30 | ||
60 | @@ -31,26 +32,27 @@ | |||
61 | 31 | public bool hovered { get; set; default=false; } | 32 | public bool hovered { get; set; default=false; } |
62 | 32 | public bool fullscreen { get; set; default=false; } | 33 | public bool fullscreen { get; set; default=false; } |
63 | 33 | public SettingsPopover preferences_popover; | 34 | public SettingsPopover preferences_popover; |
64 | 34 | public PlaylistPopover playlist_popover; | ||
65 | 35 | public TimeWidget time_widget; | 35 | public TimeWidget time_widget; |
66 | 36 | public Audience.Widgets.Playlist playlist; | ||
67 | 36 | 37 | ||
68 | 37 | private Gtk.Button play_button; | 38 | private Gtk.Button play_button; |
69 | 39 | private Gtk.Button next_button; | ||
70 | 38 | private Gtk.Button preferences_button; | 40 | private Gtk.Button preferences_button; |
71 | 39 | private Gtk.Button playlist_button; | 41 | private Gtk.Button playlist_button; |
72 | 40 | private Gtk.Revealer unfullscreen_revealer; | 42 | private Gtk.Revealer unfullscreen_revealer; |
73 | 41 | private uint hiding_timer = 0; | 43 | private uint hiding_timer = 0; |
74 | 42 | private bool playlist_glowing = false; | 44 | private bool playlist_glowing = false; |
75 | 43 | 45 | ||
76 | 44 | public bool repeat { | ||
77 | 45 | get { | ||
78 | 46 | return playlist_popover.rep.active; | ||
79 | 47 | } | ||
80 | 48 | set { | ||
81 | 49 | playlist_popover.rep.active = value; | ||
82 | 50 | } | ||
83 | 51 | } | ||
84 | 52 | |||
85 | 53 | public BottomBar (ClutterGst.Playback playback) { | 46 | public BottomBar (ClutterGst.Playback playback) { |
86 | 47 | playlist = Audience.Widgets.Playlist.get_instance (); | ||
87 | 48 | playlist.collection_changed.connect ((size) => { next_button.visible = size > 1; }); | ||
88 | 49 | playlist.visibility_changed.connect ((visible) => { | ||
89 | 50 | if (visible) { | ||
90 | 51 | playlist_button.image = new Gtk.Image.from_icon_name ("pane-hide-symbolic", Gtk.IconSize.BUTTON); | ||
91 | 52 | } else { | ||
92 | 53 | playlist_button.image = new Gtk.Image.from_icon_name ("pane-show-symbolic", Gtk.IconSize.BUTTON); | ||
93 | 54 | } | ||
94 | 55 | }); | ||
95 | 54 | this.events |= Gdk.EventMask.POINTER_MOTION_MASK; | 56 | this.events |= Gdk.EventMask.POINTER_MOTION_MASK; |
96 | 55 | this.events |= Gdk.EventMask.LEAVE_NOTIFY_MASK; | 57 | this.events |= Gdk.EventMask.LEAVE_NOTIFY_MASK; |
97 | 56 | this.events |= Gdk.EventMask.ENTER_NOTIFY_MASK; | 58 | this.events |= Gdk.EventMask.ENTER_NOTIFY_MASK; |
98 | @@ -66,34 +68,36 @@ | |||
99 | 66 | play_button.tooltip_text = _("Play"); | 68 | play_button.tooltip_text = _("Play"); |
100 | 67 | play_button.clicked.connect (() => {play_toggled ();}); | 69 | play_button.clicked.connect (() => {play_toggled ();}); |
101 | 68 | 70 | ||
103 | 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); |
104 | 72 | next_button.tooltip_text = _("Next"); | ||
105 | 73 | next_button.clicked.connect (() => { playlist.next ();}); | ||
106 | 74 | |||
107 | 75 | playlist_button = new Gtk.Button.from_icon_name ("pane-show-symbolic", Gtk.IconSize.BUTTON); | ||
108 | 70 | playlist_button.tooltip_text = _("Playlist"); | 76 | playlist_button.tooltip_text = _("Playlist"); |
110 | 71 | playlist_button.clicked.connect (() => {playlist_popover.show_all (); playlist_popover.queue_resize ();}); | 77 | playlist_button.clicked.connect (() => { playlist.toggle_reveal_control (); }); |
111 | 72 | 78 | ||
112 | 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); |
113 | 74 | preferences_button.tooltip_text = _("Settings"); | 80 | preferences_button.tooltip_text = _("Settings"); |
114 | 75 | preferences_button.clicked.connect (() => { | 81 | preferences_button.clicked.connect (() => { |
115 | 76 | preferences_popover.setup (); | 82 | preferences_popover.setup (); |
117 | 77 | preferences_popover.show_all (); | 83 | preferences_popover.show_all (); |
118 | 78 | preferences_popover.queue_resize (); | 84 | preferences_popover.queue_resize (); |
119 | 79 | }); | 85 | }); |
120 | 80 | 86 | ||
121 | 81 | time_widget = new TimeWidget (playback); | 87 | time_widget = new TimeWidget (playback); |
122 | 82 | 88 | ||
125 | 83 | playlist_popover = new PlaylistPopover (); | 89 | |
124 | 84 | playlist_popover.relative_to = playlist_button; | ||
126 | 85 | preferences_popover = new SettingsPopover (playback); | 90 | preferences_popover = new SettingsPopover (playback); |
127 | 86 | preferences_popover.relative_to = preferences_button; | 91 | preferences_popover.relative_to = preferences_button; |
128 | 87 | 92 | ||
129 | 88 | main_actionbar.pack_start (play_button); | 93 | main_actionbar.pack_start (play_button); |
130 | 94 | main_actionbar.pack_start (next_button); | ||
131 | 89 | main_actionbar.set_center_widget (time_widget); | 95 | main_actionbar.set_center_widget (time_widget); |
132 | 96 | main_actionbar.pack_end (playlist_button); | ||
133 | 90 | main_actionbar.pack_end (preferences_button); | 97 | main_actionbar.pack_end (preferences_button); |
134 | 91 | main_actionbar.pack_end (playlist_button); | ||
135 | 92 | add (main_actionbar); | 98 | add (main_actionbar); |
136 | 93 | 99 | ||
140 | 94 | playlist_popover.playlist.item_added.connect (() => { | 100 | |
138 | 95 | playlist_item_added (); | ||
139 | 96 | }); | ||
141 | 97 | 101 | ||
142 | 98 | notify["hovered"].connect (() => { | 102 | notify["hovered"].connect (() => { |
143 | 99 | if (hovered == false) { | 103 | if (hovered == false) { |
144 | @@ -131,6 +135,7 @@ | |||
145 | 131 | }); | 135 | }); |
146 | 132 | 136 | ||
147 | 133 | show_all (); | 137 | show_all (); |
148 | 138 | next_button.visible = playlist.size > 1; | ||
149 | 134 | } | 139 | } |
150 | 135 | 140 | ||
151 | 136 | private void playlist_item_added () { | 141 | private void playlist_item_added () { |
152 | @@ -138,7 +143,7 @@ | |||
153 | 138 | playlist_glowing = true; | 143 | playlist_glowing = true; |
154 | 139 | playlist_button.get_child ().get_style_context ().add_class (PULSE_CLASS); | 144 | playlist_button.get_child ().get_style_context ().add_class (PULSE_CLASS); |
155 | 140 | playlist_button.get_child ().get_style_context ().add_class (PULSE_TYPE); | 145 | playlist_button.get_child ().get_style_context ().add_class (PULSE_TYPE); |
157 | 141 | 146 | ||
158 | 142 | Timeout.add (6000, () => { | 147 | Timeout.add (6000, () => { |
159 | 143 | playlist_button.get_child ().get_style_context ().remove_class (PULSE_CLASS); | 148 | playlist_button.get_child ().get_style_context ().remove_class (PULSE_CLASS); |
160 | 144 | playlist_button.get_child ().get_style_context ().remove_class (PULSE_TYPE); | 149 | playlist_button.get_child ().get_style_context ().remove_class (PULSE_TYPE); |
161 | @@ -188,11 +193,13 @@ | |||
162 | 188 | Source.remove (hiding_timer); | 193 | Source.remove (hiding_timer); |
163 | 189 | 194 | ||
164 | 190 | hiding_timer = GLib.Timeout.add (2000, () => { | 195 | hiding_timer = GLib.Timeout.add (2000, () => { |
166 | 191 | if (hovered == true || preferences_popover.visible == true || playlist_popover.visible == true || playing == false) { | 196 | if (hovered == true || preferences_popover.visible == true || playing == false) { |
167 | 192 | hiding_timer = 0; | 197 | hiding_timer = 0; |
168 | 193 | return false; | 198 | return false; |
169 | 194 | } | 199 | } |
170 | 200 | playlist_button.image = new Gtk.Image.from_icon_name ("pane-show-symbolic", Gtk.IconSize.BUTTON); | ||
171 | 195 | set_reveal_child (false); | 201 | set_reveal_child (false); |
172 | 202 | playlist.set_reveal_child (false); | ||
173 | 196 | unfullscreen_revealer.set_reveal_child (false); | 203 | unfullscreen_revealer.set_reveal_child (false); |
174 | 197 | hiding_timer = 0; | 204 | hiding_timer = 0; |
175 | 198 | return false; | 205 | return false; |
176 | 199 | 206 | ||
177 | === modified file 'src/Widgets/EpisodesPage.vala' | |||
178 | --- src/Widgets/EpisodesPage.vala 2016-09-27 20:26:37 +0000 | |||
179 | +++ src/Widgets/EpisodesPage.vala 2016-09-30 22:31:06 +0000 | |||
180 | @@ -22,15 +22,18 @@ | |||
181 | 22 | namespace Audience { | 22 | namespace Audience { |
182 | 23 | public class EpisodesPage : Gtk.Grid { | 23 | public class EpisodesPage : Gtk.Grid { |
183 | 24 | public Gtk.Image poster { get; set; } | 24 | public Gtk.Image poster { get; set; } |
184 | 25 | Gtk.Button play_all; | ||
185 | 25 | Gtk.ScrolledWindow scrolled_window; | 26 | Gtk.ScrolledWindow scrolled_window; |
186 | 26 | Gtk.FlowBox view_episodes; | 27 | Gtk.FlowBox view_episodes; |
187 | 27 | Granite.Widgets.AlertView alert_view; | 28 | Granite.Widgets.AlertView alert_view; |
188 | 28 | 29 | ||
189 | 29 | public Audience.Services.LibraryManager manager; | 30 | public Audience.Services.LibraryManager manager; |
190 | 31 | public Audience.Widgets.Playlist playlist; | ||
191 | 30 | 32 | ||
192 | 31 | string query; | 33 | string query; |
193 | 32 | 34 | ||
194 | 33 | construct { | 35 | construct { |
195 | 36 | playlist = Audience.Widgets.Playlist.get_instance (); | ||
196 | 34 | query = ""; | 37 | query = ""; |
197 | 35 | 38 | ||
198 | 36 | poster = new Gtk.Image (); | 39 | poster = new Gtk.Image (); |
199 | @@ -39,6 +42,13 @@ | |||
200 | 39 | poster.valign = Gtk.Align.START; | 42 | poster.valign = Gtk.Align.START; |
201 | 40 | poster.get_style_context ().add_class ("card"); | 43 | poster.get_style_context ().add_class ("card"); |
202 | 41 | 44 | ||
203 | 45 | play_all = new Gtk.Button (); | ||
204 | 46 | play_all.margin_left = 24; | ||
205 | 47 | play_all.vexpand = true; | ||
206 | 48 | play_all.valign = Gtk.Align.START; | ||
207 | 49 | play_all.label = _("Play all"); | ||
208 | 50 | play_all.clicked.connect (play_all_episodes); | ||
209 | 51 | |||
210 | 42 | view_episodes = new Gtk.FlowBox (); | 52 | view_episodes = new Gtk.FlowBox (); |
211 | 43 | view_episodes.margin = 24; | 53 | view_episodes.margin = 24; |
212 | 44 | view_episodes.homogeneous = true; | 54 | view_episodes.homogeneous = true; |
213 | @@ -58,9 +68,10 @@ | |||
214 | 58 | alert_view.hide (); | 68 | alert_view.hide (); |
215 | 59 | 69 | ||
216 | 60 | expand = true; | 70 | expand = true; |
220 | 61 | attach (poster, 0, 1, 1, 1); | 71 | attach (poster, 0, 0, 1, 1); |
221 | 62 | attach (scrolled_window, 1, 1, 1, 1); | 72 | attach (play_all, 0, 1, 1 ,1); |
222 | 63 | attach (alert_view, 1, 1, 1, 1); | 73 | attach (scrolled_window, 1, 0, 1, 2); |
223 | 74 | attach (alert_view, 1, 0, 1, 2); | ||
224 | 64 | 75 | ||
225 | 65 | manager = Audience.Services.LibraryManager.get_instance (); | 76 | manager = Audience.Services.LibraryManager.get_instance (); |
226 | 66 | manager.video_file_deleted.connect (remove_item_from_path); | 77 | manager.video_file_deleted.connect (remove_item_from_path); |
227 | @@ -81,8 +92,7 @@ | |||
228 | 81 | var selected = (item as Audience.LibraryItem); | 92 | var selected = (item as Audience.LibraryItem); |
229 | 82 | var video = selected.episodes.first (); | 93 | var video = selected.episodes.first (); |
230 | 83 | if (video.video_file.query_exists ()) { | 94 | if (video.video_file.query_exists ()) { |
233 | 84 | bool from_beginning = video.video_file.get_uri () != settings.current_video; | 95 | playlist.add_item (video); |
232 | 85 | App.get_instance ().mainwindow.play_file (video.video_file.get_uri (), from_beginning); | ||
234 | 86 | } | 96 | } |
235 | 87 | } | 97 | } |
236 | 88 | 98 | ||
237 | @@ -153,6 +163,14 @@ | |||
238 | 153 | return false; | 163 | return false; |
239 | 154 | } | 164 | } |
240 | 155 | 165 | ||
241 | 166 | public void play_all_episodes () { | ||
242 | 167 | playlist.clear (); | ||
243 | 168 | view_episodes.forall ((item)=> { | ||
244 | 169 | playlist.add_item ((item as LibraryItem).episodes.first (), false); | ||
245 | 170 | }); | ||
246 | 171 | playlist.play_playlist (); | ||
247 | 172 | } | ||
248 | 173 | |||
249 | 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) { |
250 | 157 | alert_view.no_show_all = false; | 175 | alert_view.no_show_all = false; |
251 | 158 | alert_view.show_all (); | 176 | alert_view.show_all (); |
252 | 159 | 177 | ||
253 | === modified file 'src/Widgets/LibraryPage.vala' | |||
254 | --- src/Widgets/LibraryPage.vala 2016-09-27 20:26:37 +0000 | |||
255 | +++ src/Widgets/LibraryPage.vala 2016-09-30 22:31:06 +0000 | |||
256 | @@ -27,6 +27,7 @@ | |||
257 | 27 | 27 | ||
258 | 28 | public Gtk.FlowBox view_movies; | 28 | public Gtk.FlowBox view_movies; |
259 | 29 | public Audience.Services.LibraryManager manager; | 29 | public Audience.Services.LibraryManager manager; |
260 | 30 | public Audience.Widgets.Playlist playlist; | ||
261 | 30 | public Gtk.ScrolledWindow scrolled_window; | 31 | public Gtk.ScrolledWindow scrolled_window; |
262 | 31 | bool poster_initialized = false; | 32 | bool poster_initialized = false; |
263 | 32 | string query; | 33 | string query; |
264 | @@ -45,11 +46,12 @@ | |||
265 | 45 | 46 | ||
266 | 46 | construct { | 47 | construct { |
267 | 47 | manager = Audience.Services.LibraryManager.get_instance (); | 48 | manager = Audience.Services.LibraryManager.get_instance (); |
269 | 48 | 49 | playlist = Audience.Widgets.Playlist.get_instance (); | |
270 | 49 | query = ""; | 50 | query = ""; |
271 | 50 | 51 | ||
272 | 51 | scrolled_window = new Gtk.ScrolledWindow (null, null); | 52 | scrolled_window = new Gtk.ScrolledWindow (null, null); |
274 | 52 | scrolled_window.expand = true; | 53 | scrolled_window.height_request = 100; |
275 | 54 | scrolled_window.width_request = 100; | ||
276 | 53 | 55 | ||
277 | 54 | view_movies = new Gtk.FlowBox (); | 56 | view_movies = new Gtk.FlowBox (); |
278 | 55 | view_movies.margin = 24; | 57 | view_movies.margin = 24; |
279 | @@ -88,8 +90,7 @@ | |||
280 | 88 | var selected = (item as Audience.LibraryItem); | 90 | var selected = (item as Audience.LibraryItem); |
281 | 89 | 91 | ||
282 | 90 | if (selected.episodes.size == 1) { | 92 | if (selected.episodes.size == 1) { |
285 | 91 | bool from_beginning = selected.episodes.first ().video_file.get_uri () != settings.current_video; | 93 | playlist.add_item (selected.episodes.first ()); |
284 | 92 | App.get_instance ().mainwindow.play_file (selected.episodes.first ().video_file.get_uri (), from_beginning); | ||
286 | 93 | } else { | 94 | } else { |
287 | 94 | last_filter = query; | 95 | last_filter = query; |
288 | 95 | show_episodes (selected); | 96 | show_episodes (selected); |
289 | 96 | 97 | ||
290 | === modified file 'src/Widgets/PlayerPage.vala' | |||
291 | --- src/Widgets/PlayerPage.vala 2016-09-28 02:43:54 +0000 | |||
292 | +++ src/Widgets/PlayerPage.vala 2016-09-30 22:31:06 +0000 | |||
293 | @@ -11,29 +11,22 @@ | |||
294 | 11 | public class PlayerPage : Gtk.EventBox { | 11 | public class PlayerPage : Gtk.EventBox { |
295 | 12 | public signal void unfullscreen_clicked (); | 12 | public signal void unfullscreen_clicked (); |
296 | 13 | public signal void ended (); | 13 | public signal void ended (); |
297 | 14 | public signal void started (Audience.Objects.Video video); | ||
298 | 14 | 15 | ||
299 | 15 | public GtkClutter.Embed clutter; | 16 | public GtkClutter.Embed clutter; |
300 | 16 | private Clutter.Actor video_actor; | 17 | private Clutter.Actor video_actor; |
301 | 17 | private Audience.Widgets.BottomBar bottom_bar; | 18 | private Audience.Widgets.BottomBar bottom_bar; |
302 | 19 | private Audience.Widgets.Playlist playlist_bar; | ||
303 | 18 | private Clutter.Stage stage; | 20 | private Clutter.Stage stage; |
304 | 19 | private Gtk.Revealer unfullscreen_bar; | 21 | private Gtk.Revealer unfullscreen_bar; |
305 | 20 | private GtkClutter.Actor unfullscreen_actor; | 22 | private GtkClutter.Actor unfullscreen_actor; |
306 | 21 | private GtkClutter.Actor bottom_actor; | 23 | private GtkClutter.Actor bottom_actor; |
307 | 24 | private GtkClutter.Actor playlist_actor; | ||
308 | 22 | private GnomeMediaKeys mediakeys; | 25 | private GnomeMediaKeys mediakeys; |
309 | 23 | private ClutterGst.Playback playback; | 26 | private ClutterGst.Playback playback; |
310 | 24 | 27 | ||
311 | 25 | private bool mouse_primary_down = false; | 28 | private bool mouse_primary_down = false; |
312 | 26 | 29 | ||
313 | 27 | public bool repeat { | ||
314 | 28 | get{ | ||
315 | 29 | return bottom_bar.repeat; | ||
316 | 30 | } | ||
317 | 31 | |||
318 | 32 | set{ | ||
319 | 33 | bottom_bar.repeat = value; | ||
320 | 34 | } | ||
321 | 35 | } | ||
322 | 36 | |||
323 | 37 | public bool playing { | 30 | public bool playing { |
324 | 38 | get { | 31 | get { |
325 | 39 | return playback.playing; | 32 | return playback.playing; |
326 | @@ -101,8 +94,24 @@ | |||
327 | 101 | bottom_bar.bind_property ("playing", playback, "playing", BindingFlags.BIDIRECTIONAL); | 94 | bottom_bar.bind_property ("playing", playback, "playing", BindingFlags.BIDIRECTIONAL); |
328 | 102 | bottom_bar.unfullscreen.connect (() => unfullscreen_clicked ()); | 95 | bottom_bar.unfullscreen.connect (() => unfullscreen_clicked ()); |
329 | 103 | 96 | ||
330 | 97 | playlist_bar = Audience.Widgets.Playlist.get_instance (); | ||
331 | 98 | playlist_bar.play.connect ((video, progress) => { play_video (video, progress); }); | ||
332 | 99 | playlist_bar.collection_changed.connect ((size) => { | ||
333 | 100 | if (size == 0 && playing) { | ||
334 | 101 | playing = false; | ||
335 | 102 | reset_played_uri (); | ||
336 | 103 | ended (); | ||
337 | 104 | } | ||
338 | 105 | }); | ||
339 | 106 | |||
340 | 104 | unfullscreen_bar = bottom_bar.get_unfullscreen_button (); | 107 | unfullscreen_bar = bottom_bar.get_unfullscreen_button (); |
341 | 105 | 108 | ||
342 | 109 | playlist_actor = new GtkClutter.Actor.with_contents (playlist_bar); | ||
343 | 110 | playlist_actor.opacity = GLOBAL_OPACITY; | ||
344 | 111 | playlist_actor.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.HEIGHT, 0)); | ||
345 | 112 | playlist_actor.add_constraint (new Clutter.AlignConstraint (stage, Clutter.AlignAxis.X_AXIS, 1)); | ||
346 | 113 | stage.add_child (playlist_actor); | ||
347 | 114 | |||
348 | 106 | bottom_actor = new GtkClutter.Actor.with_contents (bottom_bar); | 115 | bottom_actor = new GtkClutter.Actor.with_contents (bottom_bar); |
349 | 107 | bottom_actor.opacity = GLOBAL_OPACITY; | 116 | bottom_actor.opacity = GLOBAL_OPACITY; |
350 | 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)); |
351 | @@ -117,17 +126,16 @@ | |||
352 | 117 | 126 | ||
353 | 118 | //media keys | 127 | //media keys |
354 | 119 | try { | 128 | try { |
357 | 120 | mediakeys = Bus.get_proxy_sync (BusType.SESSION, | 129 | mediakeys = Bus.get_proxy_sync (BusType.SESSION, "org.gnome.SettingsDaemon", "/org/gnome/SettingsDaemon/MediaKeys"); |
356 | 121 | "org.gnome.SettingsDaemon", "/org/gnome/SettingsDaemon/MediaKeys"); | ||
358 | 122 | mediakeys.MediaPlayerKeyPressed.connect ((bus, app, key) => { | 130 | mediakeys.MediaPlayerKeyPressed.connect ((bus, app, key) => { |
359 | 123 | if (app != "audience") | 131 | if (app != "audience") |
360 | 124 | return; | 132 | return; |
361 | 125 | switch (key) { | 133 | switch (key) { |
362 | 126 | case "Previous": | 134 | case "Previous": |
364 | 127 | get_playlist_widget ().previous (); | 135 | playlist_bar.previous (); |
365 | 128 | break; | 136 | break; |
366 | 129 | case "Next": | 137 | case "Next": |
368 | 130 | get_playlist_widget ().next (); | 138 | playlist_bar.next (); |
369 | 131 | break; | 139 | break; |
370 | 132 | case "Play": | 140 | case "Play": |
371 | 133 | playback.playing = !playback.playing; | 141 | playback.playing = !playback.playing; |
372 | @@ -181,13 +189,11 @@ | |||
373 | 181 | }); | 189 | }); |
374 | 182 | 190 | ||
375 | 183 | this.destroy.connect (() => { | 191 | this.destroy.connect (() => { |
378 | 184 | // FIXME:should find better way to decide if its end of playlist | 192 | if (playback.progress < 1) { |
379 | 185 | if (playback.progress > 0.99) | 193 | settings.last_stopped = playback.progress; |
380 | 194 | } else { | ||
381 | 186 | settings.last_stopped = 0; | 195 | settings.last_stopped = 0; |
386 | 187 | else | 196 | } |
383 | 188 | settings.last_stopped = playback.progress; | ||
384 | 189 | |||
385 | 190 | get_playlist_widget ().save_playlist (); | ||
387 | 191 | Audience.Services.Inhibitor.get_instance ().uninhibit (); | 197 | Audience.Services.Inhibitor.get_instance ().uninhibit (); |
388 | 192 | }); | 198 | }); |
389 | 193 | 199 | ||
390 | @@ -195,25 +201,13 @@ | |||
391 | 195 | playback.eos.connect (() => { | 201 | playback.eos.connect (() => { |
392 | 196 | Idle.add (() => { | 202 | Idle.add (() => { |
393 | 197 | playback.progress = 0; | 203 | playback.progress = 0; |
403 | 198 | if (!get_playlist_widget ().next ()) { | 204 | if (!playlist_bar.next ()) { |
404 | 199 | if (repeat) { | 205 | ended (); |
396 | 200 | play_file (get_playlist_widget ().get_first_item ().get_uri ()); | ||
397 | 201 | playback.playing = true; | ||
398 | 202 | } else { | ||
399 | 203 | playback.playing = false; | ||
400 | 204 | settings.last_stopped = 0; | ||
401 | 205 | ended (); | ||
402 | 206 | } | ||
405 | 207 | } | 206 | } |
406 | 208 | return false; | 207 | return false; |
407 | 209 | }); | 208 | }); |
408 | 210 | }); | 209 | }); |
409 | 211 | 210 | ||
410 | 212 | //playlist wants us to open a file | ||
411 | 213 | get_playlist_widget ().play.connect ((file) => { | ||
412 | 214 | this.play_file (file.get_uri ()); | ||
413 | 215 | }); | ||
414 | 216 | |||
415 | 217 | bottom_bar.notify["child-revealed"].connect (() => { | 211 | bottom_bar.notify["child-revealed"].connect (() => { |
416 | 218 | if (bottom_bar.child_revealed == true) { | 212 | if (bottom_bar.child_revealed == true) { |
417 | 219 | App.get_instance ().mainwindow.get_window ().set_cursor (null); | 213 | App.get_instance ().mainwindow.get_window ().set_cursor (null); |
418 | @@ -230,6 +224,7 @@ | |||
419 | 230 | Audience.Services.Inhibitor.get_instance ().inhibit (); | 224 | Audience.Services.Inhibitor.get_instance ().inhibit (); |
420 | 231 | } else { | 225 | } else { |
421 | 232 | Audience.Services.Inhibitor.get_instance ().uninhibit (); | 226 | Audience.Services.Inhibitor.get_instance ().uninhibit (); |
422 | 227 | settings.last_stopped = playback.progress; | ||
423 | 233 | } | 228 | } |
424 | 234 | }); | 229 | }); |
425 | 235 | 230 | ||
426 | @@ -237,24 +232,20 @@ | |||
427 | 237 | show_all (); | 232 | show_all (); |
428 | 238 | } | 233 | } |
429 | 239 | 234 | ||
433 | 240 | public void play_file (string uri, bool from_beginning = true) { | 235 | private void play_video (Audience.Objects.Video video, double progress = 0) { |
434 | 241 | debug ("Opening %s", uri); | 236 | string? uri = video.video_file.get_uri (); |
432 | 242 | get_playlist_widget ().set_current (uri); | ||
435 | 243 | playback.uri = uri; | 237 | playback.uri = uri; |
436 | 244 | 238 | ||
437 | 245 | string? sub_uri = get_subtitle_for_uri (uri); | 239 | string? sub_uri = get_subtitle_for_uri (uri); |
439 | 246 | if (sub_uri != null && sub_uri != uri) | 240 | if (sub_uri != null && sub_uri != uri) { |
440 | 247 | playback.set_subtitle_uri (sub_uri); | 241 | playback.set_subtitle_uri (sub_uri); |
450 | 248 | 242 | } | |
451 | 249 | App.get_instance ().mainwindow.title = get_title (uri); | 243 | |
452 | 250 | 244 | if (playback.progress != progress) { | |
453 | 251 | if (from_beginning) { | 245 | playback.progress = progress; |
454 | 252 | playback.progress = 0.0; | 246 | } |
446 | 253 | } else { | ||
447 | 254 | playback.progress = settings.last_stopped; | ||
448 | 255 | } | ||
449 | 256 | |||
455 | 257 | playback.playing = !settings.playback_wait; | 247 | playback.playing = !settings.playback_wait; |
456 | 248 | |||
457 | 258 | Gtk.RecentManager recent_manager = Gtk.RecentManager.get_default (); | 249 | Gtk.RecentManager recent_manager = Gtk.RecentManager.get_default (); |
458 | 259 | recent_manager.add_item (uri); | 250 | recent_manager.add_item (uri); |
459 | 260 | 251 | ||
460 | @@ -262,53 +253,26 @@ | |||
461 | 262 | 253 | ||
462 | 263 | Audience.Services.Inhibitor.get_instance ().inhibit (); | 254 | Audience.Services.Inhibitor.get_instance ().inhibit (); |
463 | 264 | settings.current_video = uri; | 255 | settings.current_video = uri; |
464 | 256 | |||
465 | 257 | started (video); | ||
466 | 265 | } | 258 | } |
467 | 266 | 259 | ||
468 | 267 | public double get_progress () { | 260 | public double get_progress () { |
469 | 268 | return playback.progress; | 261 | return playback.progress; |
470 | 269 | } | 262 | } |
471 | 270 | 263 | ||
472 | 271 | public string get_played_uri () { | ||
473 | 272 | return playback.uri; | ||
474 | 273 | } | ||
475 | 274 | |||
476 | 275 | public void reset_played_uri () { | 264 | public void reset_played_uri () { |
477 | 276 | playback.uri = ""; | 265 | playback.uri = ""; |
478 | 277 | } | 266 | } |
479 | 278 | 267 | ||
480 | 279 | public void next () { | ||
481 | 280 | get_playlist_widget ().next (); | ||
482 | 281 | } | ||
483 | 282 | |||
484 | 283 | public void prev () { | ||
485 | 284 | get_playlist_widget ().next (); | ||
486 | 285 | } | ||
487 | 286 | |||
488 | 287 | public void resume_last_videos () { | ||
489 | 288 | play_file (settings.current_video); | ||
490 | 289 | playback.playing = false; | ||
491 | 290 | if (settings.resume_videos) { | ||
492 | 291 | playback.progress = settings.last_stopped; | ||
493 | 292 | } else { | ||
494 | 293 | playback.progress = 0.0; | ||
495 | 294 | } | ||
496 | 295 | |||
497 | 296 | playback.playing = !settings.playback_wait; | ||
498 | 297 | } | ||
499 | 298 | |||
500 | 299 | public void append_to_playlist (File file) { | 268 | public void append_to_playlist (File file) { |
501 | 300 | if (playback.playing && is_subtitle (file.get_uri ())) { | 269 | if (playback.playing && is_subtitle (file.get_uri ())) { |
502 | 301 | playback.set_subtitle_uri (file.get_uri ()); | 270 | playback.set_subtitle_uri (file.get_uri ()); |
503 | 302 | } else { | 271 | } else { |
505 | 303 | get_playlist_widget ().add_item (file); | 272 | playlist_bar.add_from_file (file); |
506 | 304 | } | 273 | } |
507 | 305 | } | 274 | } |
508 | 306 | 275 | ||
509 | 307 | public void play_first_in_playlist () { | ||
510 | 308 | var file = get_playlist_widget ().get_first_item (); | ||
511 | 309 | play_file (file.get_uri ()); | ||
512 | 310 | } | ||
513 | 311 | |||
514 | 312 | public void reveal_control () { | 276 | public void reveal_control () { |
515 | 313 | bottom_bar.reveal_control (); | 277 | bottom_bar.reveal_control (); |
516 | 314 | } | 278 | } |
517 | @@ -328,10 +292,6 @@ | |||
518 | 328 | playback.progress = double.min (new_progress, 1.0); | 292 | playback.progress = double.min (new_progress, 1.0); |
519 | 329 | } | 293 | } |
520 | 330 | 294 | ||
521 | 331 | public Widgets.Playlist get_playlist_widget () { | ||
522 | 332 | return bottom_bar.playlist_popover.playlist; | ||
523 | 333 | } | ||
524 | 334 | |||
525 | 335 | private string? get_subtitle_for_uri (string uri) { | 295 | private string? get_subtitle_for_uri (string uri) { |
526 | 336 | string without_ext; | 296 | string without_ext; |
527 | 337 | int last_dot = uri.last_index_of (".", 0); | 297 | int last_dot = uri.last_index_of (".", 0); |
528 | @@ -365,7 +325,7 @@ | |||
529 | 365 | public bool update_pointer_position (double y, int window_height) { | 325 | public bool update_pointer_position (double y, int window_height) { |
530 | 366 | App.get_instance ().mainwindow.get_window ().set_cursor (null); | 326 | App.get_instance ().mainwindow.get_window ().set_cursor (null); |
531 | 367 | 327 | ||
533 | 368 | bottom_bar.reveal_control (); | 328 | reveal_control (); |
534 | 369 | 329 | ||
535 | 370 | return false; | 330 | return false; |
536 | 371 | } | 331 | } |
537 | 372 | 332 | ||
538 | === modified file 'src/Widgets/Playlist.vala' | |||
539 | --- src/Widgets/Playlist.vala 2016-08-19 16:27:45 +0000 | |||
540 | +++ src/Widgets/Playlist.vala 2016-09-30 22:31:06 +0000 | |||
541 | @@ -1,6 +1,6 @@ | |||
542 | 1 | // -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- | 1 | // -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- |
543 | 2 | /*- | 2 | /*- |
545 | 3 | * Copyright (c) 2013-2014 Audience Developers (http://launchpad.net/pantheon-chat) | 3 | * Copyright (c) 2016-2016 elementary LLC. |
546 | 4 | * | 4 | * |
547 | 5 | * This program is free software: you can redistribute it and/or modify | 5 | * This program is free software: you can redistribute it and/or modify |
548 | 6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
549 | @@ -15,221 +15,224 @@ | |||
550 | 15 | * You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
551 | 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/>. |
552 | 17 | * | 17 | * |
554 | 18 | * Authored by: Tom Beckmann <tomjonabc@gmail.com> | 18 | * Authored by: Artem Anufrij <artem.anufrij@live.de> |
555 | 19 | * | ||
556 | 19 | */ | 20 | */ |
557 | 20 | 21 | ||
558 | 21 | namespace Audience.Widgets { | 22 | namespace Audience.Widgets { |
569 | 22 | public class Playlist : Gtk.TreeView { | 23 | public class Playlist : Gtk.Revealer { |
570 | 23 | // the player is requested to play path | 24 | |
571 | 24 | public signal void play (File path); | 25 | public signal void play (Audience.Objects.Video video, double process = 0); |
572 | 25 | public signal void item_added (); | 26 | public signal void collection_changed (uint size); |
573 | 26 | 27 | public signal void visibility_changed (bool visible); | |
574 | 27 | private enum Columns { | 28 | |
575 | 28 | PLAYING, | 29 | Gtk.Grid grid; |
576 | 29 | TITLE, | 30 | Gtk.ScrolledWindow scrolled_window; |
577 | 30 | FILENAME, | 31 | Gtk.ListBox listbox; |
578 | 31 | N_COLUMNS | 32 | Gtk.ToggleButton repeat_button; |
579 | 33 | |||
580 | 34 | public uint size { get { return listbox.get_children ().length (); } } | ||
581 | 35 | |||
582 | 36 | static Playlist _instance = null; | ||
583 | 37 | public static Playlist get_instance () { | ||
584 | 38 | if (_instance == null) { | ||
585 | 39 | _instance = new Playlist (); | ||
586 | 40 | } | ||
587 | 41 | return _instance; | ||
588 | 32 | } | 42 | } |
589 | 33 | 43 | ||
628 | 34 | private int current = 0; | 44 | private Playlist () {} |
629 | 35 | private Gtk.ListStore playlist; | 45 | |
630 | 36 | 46 | construct { | |
631 | 37 | public Playlist () { | 47 | valign = Gtk.Align.FILL; |
632 | 38 | this.playlist = new Gtk.ListStore (Columns.N_COLUMNS, typeof (Icon), typeof (string), typeof (string)); | 48 | transition_type = Gtk.RevealerTransitionType.SLIDE_LEFT; |
633 | 39 | this.model = this.playlist; | 49 | |
634 | 40 | this.expand = true; | 50 | grid = new Gtk.Grid (); |
635 | 41 | this.headers_visible = false; | 51 | grid.expand = true; |
636 | 42 | this.activate_on_single_click = true; | 52 | grid.valign = Gtk.Align.FILL; |
637 | 43 | this.can_focus = false; | 53 | grid.halign = Gtk.Align.FILL; |
638 | 44 | get_selection ().mode = Gtk.SelectionMode.NONE; | 54 | grid.orientation = Gtk.Orientation.VERTICAL; |
639 | 45 | 55 | grid.margin_bottom = 28; | |
640 | 46 | var text_render = new Gtk.CellRendererText (); | 56 | |
641 | 47 | text_render.ellipsize = Pango.EllipsizeMode.MIDDLE; | 57 | scrolled_window = new Gtk.ScrolledWindow (null, null); |
642 | 48 | 58 | scrolled_window.expand = true; | |
643 | 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); |
644 | 50 | this.insert_column_with_attributes (-1, "Title", text_render, "text", Columns.TITLE); | 60 | |
645 | 51 | this.set_tooltip_column (1); | 61 | |
646 | 52 | 62 | listbox = new Gtk.ListBox (); | |
647 | 53 | this.row_activated.connect ((path ,col) => { | 63 | listbox.row_selected.connect ( play_selected ); |
648 | 54 | Gtk.TreeIter iter; | 64 | listbox.expand = true; |
649 | 55 | playlist.get_iter (out iter, path); | 65 | listbox.valign = Gtk.Align.FILL; |
650 | 56 | string filename; | 66 | |
651 | 57 | playlist.get (iter, Columns.FILENAME, out filename); | 67 | var toolbar = new Gtk.Toolbar (); |
652 | 58 | play (File.new_for_commandline_arg (filename)); | 68 | toolbar.get_style_context ().add_class (Gtk.STYLE_CLASS_INLINE_TOOLBAR); |
653 | 59 | }); | 69 | toolbar.icon_size = Gtk.IconSize.SMALL_TOOLBAR; |
654 | 60 | 70 | ||
655 | 61 | this.reorderable = true; | 71 | var add_button = new Gtk.ToolButton (new Gtk.Image.from_icon_name ("document-open-symbolic", Gtk.IconSize.BUTTON), null); |
656 | 62 | this.model.row_inserted.connect ((path, iter) => { | 72 | add_button.tooltip_text = _("Add Video…"); |
657 | 63 | Gtk.TreeIter it; | 73 | add_button.clicked.connect (() => { App.get_instance ().mainwindow.run_open_file (false, false); }); |
658 | 64 | playlist.get_iter (out it, path); | 74 | toolbar.add (add_button); |
659 | 65 | Gdk.Pixbuf playing; | 75 | |
660 | 66 | playlist.get (it, Columns.PLAYING, out playing); | 76 | var repeat_item = new Gtk.ToolItem (); |
661 | 67 | if (playing != null) //if playing is not null it's the current item | 77 | repeat_item.halign = Gtk.Align.END; |
662 | 68 | this.current = int.parse (path.to_string ()); | 78 | |
663 | 69 | }); | 79 | repeat_button = new Gtk.ToggleButton (); |
664 | 70 | 80 | repeat_button.set_image (new Gtk.Image.from_icon_name ("media-playlist-no-repeat-symbolic", Gtk.IconSize.BUTTON)); | |
665 | 71 | // Automatically load from gsettings last_played_videos | 81 | repeat_button.set_tooltip_text (_("Enable Repeat")); |
666 | 82 | repeat_button.toggled.connect (() => { | ||
667 | 83 | if (repeat_button.active) { | ||
668 | 84 | repeat_button.set_image (new Gtk.Image.from_icon_name ("media-playlist-repeat-symbolic", Gtk.IconSize.BUTTON)); | ||
669 | 85 | repeat_button.set_tooltip_text (_("Disable Repeat")); | ||
670 | 86 | } else { | ||
671 | 87 | repeat_button.set_image (new Gtk.Image.from_icon_name ("media-playlist-no-repeat-symbolic", Gtk.IconSize.BUTTON)); | ||
672 | 88 | repeat_button.set_tooltip_text (_("Enable Repeat")); | ||
673 | 89 | } | ||
674 | 90 | }); | ||
675 | 91 | |||
676 | 92 | repeat_item.add (repeat_button); | ||
677 | 93 | toolbar.add (repeat_item); | ||
678 | 94 | scrolled_window.add (listbox); | ||
679 | 95 | grid.attach (scrolled_window, 0, 0, 1, 1); | ||
680 | 96 | grid.add (toolbar); | ||
681 | 97 | add (grid); | ||
682 | 72 | restore_playlist (); | 98 | restore_playlist (); |
688 | 73 | } | 99 | show_all (); |
689 | 74 | 100 | ||
690 | 75 | ~Playlist () { | 101 | destroy.connect (() =>{ save_playlist (); }); |
691 | 76 | save_playlist (); | 102 | } |
692 | 77 | } | 103 | |
693 | 104 | public void toggle_reveal_control () { | ||
694 | 105 | if (!child_revealed) { | ||
695 | 106 | show_all (); | ||
696 | 107 | } | ||
697 | 108 | set_reveal_child (!child_revealed); | ||
698 | 109 | visibility_changed (!child_revealed); | ||
699 | 110 | } | ||
700 | 111 | |||
701 | 112 | public void hide_reval_control () { | ||
702 | 113 | set_reveal_child (false); | ||
703 | 114 | visibility_changed (false); | ||
704 | 115 | } | ||
705 | 116 | |||
706 | 117 | public void add_item (Audience.Objects.Video video, bool instand_play = true) { | ||
707 | 118 | var new_item = new Audience.Widgets.PlaylistItem (video); | ||
708 | 119 | if (instand_play) { | ||
709 | 120 | clear (); | ||
710 | 121 | } | ||
711 | 122 | listbox.add (new_item); | ||
712 | 123 | if (instand_play) { | ||
713 | 124 | listbox.select_row (new_item); | ||
714 | 125 | } | ||
715 | 126 | collection_changed (size); | ||
716 | 127 | } | ||
717 | 128 | |||
718 | 129 | public void remove_item (Gtk.ListBoxRow row) { | ||
719 | 130 | if (row.is_selected ()) { | ||
720 | 131 | next (); | ||
721 | 132 | } | ||
722 | 133 | listbox.remove (row); | ||
723 | 134 | save_playlist (); | ||
724 | 135 | collection_changed (size); | ||
725 | 136 | } | ||
726 | 137 | |||
727 | 138 | public void clear () { | ||
728 | 139 | listbox.forall ((item)=> { | ||
729 | 140 | item.dispose (); | ||
730 | 141 | }); | ||
731 | 142 | } | ||
732 | 143 | |||
733 | 144 | private void play_selected (Gtk.ListBoxRow? row) { | ||
734 | 145 | if (row != null) { | ||
735 | 146 | listbox.forall ((item) => { | ||
736 | 147 | (item as PlaylistItem).update_state (); | ||
737 | 148 | }); | ||
738 | 149 | start_playing (((PlaylistItem)row).video); | ||
739 | 150 | } | ||
740 | 151 | } | ||
741 | 152 | |||
742 | 153 | private void start_playing (Audience.Objects.Video video) { | ||
743 | 154 | double progress = 0; | ||
744 | 155 | if (video.video_file.get_uri () == settings.current_video) { | ||
745 | 156 | progress = settings.last_stopped; | ||
746 | 157 | } | ||
747 | 158 | play (video, progress); | ||
748 | 159 | } | ||
749 | 160 | |||
750 | 161 | public void play_playlist () { | ||
751 | 162 | listbox.select_row (listbox.get_row_at_index(0)); | ||
752 | 163 | } | ||
753 | 78 | 164 | ||
754 | 79 | public bool next () { | 165 | public bool next () { |
874 | 80 | Gtk.TreeIter iter; | 166 | if (size > listbox.get_selected_row ().get_index () + 1) { |
875 | 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); |
876 | 82 | string filename; | 168 | listbox.select_row (next_video); |
877 | 83 | playlist.get (iter, Columns.FILENAME, out filename); | 169 | return true; |
878 | 84 | current++; | 170 | } else if (repeat_button.active && size > 0) { |
879 | 85 | play (File.new_for_commandline_arg (filename)); | 171 | if (size == 1) { |
880 | 86 | return true; | 172 | listbox.select_row (null); |
881 | 87 | } | 173 | } |
882 | 88 | current = 0; | 174 | listbox.select_row (listbox.get_row_at_index (0)); |
883 | 89 | return false; | 175 | return true; |
884 | 90 | } | 176 | } |
885 | 91 | 177 | return false; | |
886 | 92 | public void previous () { | 178 | } |
887 | 93 | Gtk.TreeIter iter; | 179 | |
888 | 94 | if (playlist.get_iter_from_string (out iter, (this.current - 1).to_string ())){ | 180 | public bool previous () { |
889 | 95 | string filename; | 181 | if (listbox.get_selected_row ().get_index () > 0) { |
890 | 96 | playlist.get (iter, Columns.FILENAME, out filename); | 182 | var next_video = listbox.get_row_at_index (listbox.get_selected_row ().get_index () - 1); |
891 | 97 | current--; | 183 | listbox.select_row (next_video); |
892 | 98 | play (File.new_for_commandline_arg (filename)); | 184 | return true; |
893 | 99 | } | 185 | } |
894 | 100 | } | 186 | return false; |
895 | 101 | 187 | } | |
896 | 102 | public void add_item (File path) { | 188 | |
897 | 103 | if (!path.query_exists ()) | 189 | public void resume () { |
898 | 104 | return; | 190 | listbox.forall ((item) => { |
899 | 105 | var file_name = path.get_uri (); | 191 | var video = (item as PlaylistItem).video; |
900 | 106 | bool exist = false; | 192 | if (video.video_file.get_uri () == settings.current_video) { |
901 | 107 | Gtk.TreeIter iter; | 193 | if (listbox.get_selected_row () != (item as PlaylistItem)) { |
902 | 108 | 194 | listbox.select_row (item as PlaylistItem); | |
903 | 109 | playlist.foreach ((model, path, iter) => { | 195 | } else { |
904 | 110 | Value filename; | 196 | start_playing (video); |
905 | 111 | playlist.get_value (iter, Columns.FILENAME, out filename); | 197 | } |
906 | 112 | string name = filename.get_string (); | 198 | return; |
907 | 113 | if (name == file_name) | 199 | } |
908 | 114 | exist = true; | 200 | }); |
909 | 115 | return false; | 201 | |
910 | 116 | }); | 202 | play_playlist (); |
792 | 117 | if (exist) | ||
793 | 118 | return; | ||
794 | 119 | |||
795 | 120 | Icon? playing = null; | ||
796 | 121 | Gtk.TreeIter dummy; | ||
797 | 122 | if (!playlist.get_iter_first (out dummy)){ | ||
798 | 123 | playing = new ThemedIcon ("media-playback-start-symbolic"); | ||
799 | 124 | } else { | ||
800 | 125 | playing = null; | ||
801 | 126 | } | ||
802 | 127 | |||
803 | 128 | playlist.append (out iter); | ||
804 | 129 | playlist.set (iter, Columns.PLAYING, playing, | ||
805 | 130 | Columns.TITLE, Audience.get_title (path.get_basename ()), | ||
806 | 131 | Columns.FILENAME, path.get_uri ()); | ||
807 | 132 | item_added (); | ||
808 | 133 | } | ||
809 | 134 | |||
810 | 135 | public void remove_item (File path) { | ||
811 | 136 | var file_name = path.get_uri (); | ||
812 | 137 | |||
813 | 138 | playlist.foreach ((model, path, iter) => { | ||
814 | 139 | Value filename; | ||
815 | 140 | playlist.get_value (iter, Columns.FILENAME, out filename); | ||
816 | 141 | string name = filename.get_string (); | ||
817 | 142 | if (name == file_name) | ||
818 | 143 | playlist.remove (iter); | ||
819 | 144 | return false; | ||
820 | 145 | }); | ||
821 | 146 | } | ||
822 | 147 | |||
823 | 148 | public void clear_items () { | ||
824 | 149 | current = 0; | ||
825 | 150 | playlist.clear (); | ||
826 | 151 | } | ||
827 | 152 | |||
828 | 153 | public File? get_first_item () { | ||
829 | 154 | Gtk.TreeIter iter; | ||
830 | 155 | if (playlist.get_iter_first (out iter)){ | ||
831 | 156 | string filename; | ||
832 | 157 | playlist.get (iter, Columns.FILENAME, out filename); | ||
833 | 158 | return File.new_for_commandline_arg (filename); | ||
834 | 159 | } | ||
835 | 160 | return null; | ||
836 | 161 | } | ||
837 | 162 | |||
838 | 163 | public int get_current () { | ||
839 | 164 | return current; | ||
840 | 165 | } | ||
841 | 166 | |||
842 | 167 | public void set_current (string current_file) { | ||
843 | 168 | int count = 0; | ||
844 | 169 | int current_played = 0; | ||
845 | 170 | playlist.foreach ((model, path, iter) => { | ||
846 | 171 | playlist.set (iter, Columns.PLAYING, null); | ||
847 | 172 | Value filename; | ||
848 | 173 | playlist.get_value (iter, Columns.FILENAME, out filename); | ||
849 | 174 | string name = filename.get_string (); | ||
850 | 175 | if (name == current_file) | ||
851 | 176 | current_played = count; | ||
852 | 177 | count++; | ||
853 | 178 | return false; | ||
854 | 179 | }); | ||
855 | 180 | |||
856 | 181 | Gtk.TreeIter new_iter; | ||
857 | 182 | playlist.get_iter_from_string (out new_iter, current_played.to_string ()); | ||
858 | 183 | playlist.set (new_iter, Columns.PLAYING, new ThemedIcon ("media-playback-start-symbolic")); | ||
859 | 184 | |||
860 | 185 | this.current = current_played; | ||
861 | 186 | |||
862 | 187 | } | ||
863 | 188 | |||
864 | 189 | public List<string> get_all_items () { | ||
865 | 190 | var list = new List<string> (); | ||
866 | 191 | playlist.foreach ((model, path, iter) => { | ||
867 | 192 | Value filename; | ||
868 | 193 | playlist.get_value (iter, Columns.FILENAME, out filename); | ||
869 | 194 | string name = filename.get_string (); | ||
870 | 195 | list.append (name); | ||
871 | 196 | return false; | ||
872 | 197 | }); | ||
873 | 198 | return list.copy (); | ||
911 | 199 | } | 203 | } |
912 | 200 | 204 | ||
913 | 201 | public void save_playlist () { | 205 | public void save_playlist () { |
914 | 202 | if (Audience.App.get_instance ().mainwindow.is_privacy_mode_enabled ()) { | 206 | if (Audience.App.get_instance ().mainwindow.is_privacy_mode_enabled ()) { |
915 | 203 | return; | 207 | return; |
916 | 204 | } | 208 | } |
925 | 205 | 209 | var list = new Gee.ArrayList<string> (); | |
926 | 206 | var list = new List<string> (); | 210 | listbox.forall ((item) => { |
927 | 207 | playlist.foreach ((model, path, iter) => { | 211 | list.add ((item as PlaylistItem).video.video_file.get_uri ()); |
920 | 208 | Value filename; | ||
921 | 209 | playlist.get_value (iter, Columns.FILENAME, out filename); | ||
922 | 210 | string name = filename.get_string (); | ||
923 | 211 | list.append (name); | ||
924 | 212 | return false; | ||
928 | 213 | }); | 212 | }); |
935 | 214 | 213 | settings.last_played_videos = list.to_array (); | |
936 | 215 | uint i = 0; | 214 | if (list.size == 0) { |
937 | 216 | var videos = new string[list.length ()]; | 215 | settings.current_video = ""; |
938 | 217 | foreach (var filename in list) { | 216 | settings.last_stopped = 0; |
933 | 218 | videos[i] = filename; | ||
934 | 219 | i++; | ||
939 | 220 | } | 217 | } |
940 | 221 | |||
941 | 222 | settings.last_played_videos = videos; | ||
942 | 223 | } | 218 | } |
943 | 224 | 219 | ||
944 | 225 | private void restore_playlist () { | 220 | private void restore_playlist () { |
951 | 226 | this.current = 0; | 221 | foreach (var filename in settings.last_played_videos) { |
952 | 227 | /* foreach (var filename in settings.last_played_videos) { */ | 222 | add_from_uri (filename); |
947 | 228 | for (int i = 0;i<settings.last_played_videos.length;i++) { | ||
948 | 229 | if (settings.last_played_videos[i] == settings.current_video) | ||
949 | 230 | this.current = i; | ||
950 | 231 | add_item (File.new_for_uri (settings.last_played_videos[i])); | ||
953 | 232 | } | 223 | } |
954 | 233 | } | 224 | } |
955 | 225 | |||
956 | 226 | public void add_from_uri (string uri, bool instand_play = false) { | ||
957 | 227 | File file = File.new_for_uri (uri); | ||
958 | 228 | add_from_file (file); | ||
959 | 229 | } | ||
960 | 230 | |||
961 | 231 | public void add_from_file (File file, bool instand_play = false) { | ||
962 | 232 | if (file.query_exists () && file.get_path () != null) { | ||
963 | 233 | FileInfo file_info = file.query_info (FileAttribute.STANDARD_CONTENT_TYPE, 0); | ||
964 | 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); | ||
965 | 235 | } | ||
966 | 236 | } | ||
967 | 234 | } | 237 | } |
968 | 235 | } | 238 | } |
969 | 236 | 239 | ||
970 | === added file 'src/Widgets/PlaylistItem.vala' | |||
971 | --- src/Widgets/PlaylistItem.vala 1970-01-01 00:00:00 +0000 | |||
972 | +++ src/Widgets/PlaylistItem.vala 2016-09-30 22:31:06 +0000 | |||
973 | @@ -0,0 +1,66 @@ | |||
974 | 1 | // -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- | ||
975 | 2 | /*- | ||
976 | 3 | * Copyright (c) 2016-2016 elementary LLC. | ||
977 | 4 | * | ||
978 | 5 | * This program is free software: you can redistribute it and/or modify | ||
979 | 6 | * it under the terms of the GNU General Public License as published by | ||
980 | 7 | * the Free Software Foundation, either version 3 of the License, or | ||
981 | 8 | * (at your option) any later version. | ||
982 | 9 | |||
983 | 10 | * This program is distributed in the hope that it will be useful, | ||
984 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
985 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
986 | 13 | * GNU General Public License for more details. | ||
987 | 14 | |||
988 | 15 | * You should have received a copy of the GNU General Public License | ||
989 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
990 | 17 | * | ||
991 | 18 | * Authored by: Artem Anufrij <artem.anufrij@live.de> | ||
992 | 19 | * | ||
993 | 20 | */ | ||
994 | 21 | |||
995 | 22 | namespace Audience.Widgets { | ||
996 | 23 | public class PlaylistItem : Gtk.ListBoxRow { | ||
997 | 24 | |||
998 | 25 | public Audience.Objects.Video video { get; construct set; } | ||
999 | 26 | Gtk.Grid grid; | ||
1000 | 27 | Gtk.Label title; | ||
1001 | 28 | Gtk.Image image; | ||
1002 | 29 | Gtk.Button delete_button; | ||
1003 | 30 | |||
1004 | 31 | public PlaylistItem (Audience.Objects.Video video) { | ||
1005 | 32 | Object (video: video); | ||
1006 | 33 | } | ||
1007 | 34 | |||
1008 | 35 | construct { | ||
1009 | 36 | grid = new Gtk.Grid (); | ||
1010 | 37 | title = new Gtk.Label (video.title); | ||
1011 | 38 | title.expand = true; | ||
1012 | 39 | title.halign = Gtk.Align.START; | ||
1013 | 40 | |||
1014 | 41 | image = new Gtk.Image.from_icon_name ("media-playback-start-symbolic", Gtk.IconSize.MENU); | ||
1015 | 42 | image.margin_right = 4; | ||
1016 | 43 | |||
1017 | 44 | delete_button = new Gtk.Button.from_icon_name ("edit-delete-symbolic", Gtk.IconSize.BUTTON); | ||
1018 | 45 | delete_button.tooltip_text = _("Remove from Playlist"); | ||
1019 | 46 | delete_button.relief = Gtk.ReliefStyle.NONE; | ||
1020 | 47 | delete_button.clicked.connect (() => { Audience.Widgets.Playlist.get_instance ().remove_item (this); }); | ||
1021 | 48 | |||
1022 | 49 | grid.margin = 4; | ||
1023 | 50 | grid.attach (title, 1, 0, 1, 1); | ||
1024 | 51 | grid.attach (delete_button, 2, 0, 1, 1); | ||
1025 | 52 | add (grid); | ||
1026 | 53 | } | ||
1027 | 54 | |||
1028 | 55 | public void update_state () { | ||
1029 | 56 | if (is_selected () && image.parent != grid) { | ||
1030 | 57 | grid.attach (image, 0, 0, 1, 1); | ||
1031 | 58 | image.show (); | ||
1032 | 59 | } else { | ||
1033 | 60 | if (image.parent == grid) { | ||
1034 | 61 | grid.remove (image); | ||
1035 | 62 | } | ||
1036 | 63 | } | ||
1037 | 64 | } | ||
1038 | 65 | } | ||
1039 | 66 | } | ||
1040 | 0 | 67 | ||
1041 | === removed file 'src/Widgets/PlaylistPopover.vala' | |||
1042 | --- src/Widgets/PlaylistPopover.vala 2016-07-29 05:02:48 +0000 | |||
1043 | +++ src/Widgets/PlaylistPopover.vala 1970-01-01 00:00:00 +0000 | |||
1044 | @@ -1,118 +0,0 @@ | |||
1045 | 1 | // -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- | ||
1046 | 2 | /*- | ||
1047 | 3 | * Copyright (c) 2013-2014 Audience Developers (http://launchpad.net/pantheon-chat) | ||
1048 | 4 | * | ||
1049 | 5 | * This program is free software: you can redistribute it and/or modify | ||
1050 | 6 | * it under the terms of the GNU General Public License as published by | ||
1051 | 7 | * the Free Software Foundation, either version 3 of the License, or | ||
1052 | 8 | * (at your option) any later version. | ||
1053 | 9 | |||
1054 | 10 | * This program is distributed in the hope that it will be useful, | ||
1055 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1056 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1057 | 13 | * GNU General Public License for more details. | ||
1058 | 14 | |||
1059 | 15 | * You should have received a copy of the GNU General Public License | ||
1060 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1061 | 17 | * | ||
1062 | 18 | * Authored by: Corentin Noël <corentin@elementaryos.org> | ||
1063 | 19 | */ | ||
1064 | 20 | |||
1065 | 21 | public class Audience.Widgets.PlaylistPopover : Gtk.Popover { | ||
1066 | 22 | public Playlist playlist; | ||
1067 | 23 | public Gtk.ToggleButton rep; | ||
1068 | 24 | private Gtk.ScrolledWindow playlist_scrolled; | ||
1069 | 25 | private Gtk.Button dvd; | ||
1070 | 26 | |||
1071 | 27 | public PlaylistPopover () { | ||
1072 | 28 | opacity = GLOBAL_OPACITY; | ||
1073 | 29 | var grid = new Gtk.Grid (); | ||
1074 | 30 | grid.row_spacing = 6; | ||
1075 | 31 | grid.column_spacing = 12; | ||
1076 | 32 | grid.margin = 6; | ||
1077 | 33 | |||
1078 | 34 | var fil = new Gtk.Button.from_icon_name ("document-open-symbolic", Gtk.IconSize.BUTTON); | ||
1079 | 35 | fil.set_tooltip_text (_("Open file")); | ||
1080 | 36 | dvd = new Gtk.Button.from_icon_name ("media-optical-symbolic", Gtk.IconSize.BUTTON); | ||
1081 | 37 | dvd.set_tooltip_text (_("Play from Disc")); | ||
1082 | 38 | |||
1083 | 39 | rep = new Gtk.ToggleButton (); | ||
1084 | 40 | rep.set_image (new Gtk.Image.from_icon_name ("media-playlist-no-repeat-symbolic", Gtk.IconSize.BUTTON)); | ||
1085 | 41 | rep.set_tooltip_text (_("Enable Repeat")); | ||
1086 | 42 | |||
1087 | 43 | playlist_scrolled = new Gtk.ScrolledWindow (null, null); | ||
1088 | 44 | playlist_scrolled.set_min_content_height (100); | ||
1089 | 45 | playlist_scrolled.set_min_content_width (260); | ||
1090 | 46 | |||
1091 | 47 | playlist = new Playlist (); | ||
1092 | 48 | playlist_scrolled.add (playlist); | ||
1093 | 49 | |||
1094 | 50 | fil.clicked.connect ( () => { | ||
1095 | 51 | hide (); | ||
1096 | 52 | App.get_instance ().mainwindow.run_open_file (false, false); | ||
1097 | 53 | }); | ||
1098 | 54 | |||
1099 | 55 | dvd.clicked.connect ( () => { | ||
1100 | 56 | hide (); | ||
1101 | 57 | App.get_instance ().mainwindow.run_open_dvd (); | ||
1102 | 58 | }); | ||
1103 | 59 | |||
1104 | 60 | rep.toggled.connect ( () => { | ||
1105 | 61 | /* app.repeat = rep.active; */ | ||
1106 | 62 | if (rep.active) { | ||
1107 | 63 | rep.set_image (new Gtk.Image.from_icon_name ("media-playlist-repeat-symbolic", Gtk.IconSize.BUTTON)); | ||
1108 | 64 | rep.set_tooltip_text (_("Disable Repeat")); | ||
1109 | 65 | } else { | ||
1110 | 66 | rep.set_image (new Gtk.Image.from_icon_name ("media-playlist-no-repeat-symbolic", Gtk.IconSize.BUTTON)); | ||
1111 | 67 | rep.set_tooltip_text (_("Enable Repeat")); | ||
1112 | 68 | } | ||
1113 | 69 | }); | ||
1114 | 70 | |||
1115 | 71 | grid.attach (playlist_scrolled, 0, 0, 7, 1); | ||
1116 | 72 | grid.attach (fil, 0, 1, 1, 1); | ||
1117 | 73 | grid.attach (dvd, 1, 1, 1, 1); | ||
1118 | 74 | grid.attach (rep, 6, 1, 1, 1); | ||
1119 | 75 | |||
1120 | 76 | add (grid); | ||
1121 | 77 | |||
1122 | 78 | var disk_manager = DiskManager.get_default (); | ||
1123 | 79 | set_dvd_visibility (disk_manager.has_media_volumes ()); | ||
1124 | 80 | disk_manager.volume_found.connect ((vol) => { | ||
1125 | 81 | set_dvd_visibility (disk_manager.has_media_volumes ()); | ||
1126 | 82 | }); | ||
1127 | 83 | |||
1128 | 84 | disk_manager.volume_removed.connect ((vol) => { | ||
1129 | 85 | set_dvd_visibility (disk_manager.has_media_volumes ()); | ||
1130 | 86 | }); | ||
1131 | 87 | } | ||
1132 | 88 | |||
1133 | 89 | private void set_dvd_visibility (bool visible) { | ||
1134 | 90 | dvd.no_show_all = !visible; | ||
1135 | 91 | dvd.visible = visible; | ||
1136 | 92 | } | ||
1137 | 93 | |||
1138 | 94 | //Override because the Popover doesn't auto-rejust his size. | ||
1139 | 95 | public override void get_preferred_height (out int minimum_height, out int natural_height) { | ||
1140 | 96 | base.get_preferred_height (out minimum_height, out natural_height); | ||
1141 | 97 | int p_minimum_height; | ||
1142 | 98 | int p_natural_height; | ||
1143 | 99 | var app = ((Audience.App) GLib.Application.get_default ()); | ||
1144 | 100 | playlist.get_preferred_height (out p_minimum_height, out p_natural_height); | ||
1145 | 101 | int temp_minimum_height = minimum_height + p_minimum_height; | ||
1146 | 102 | int r_minimum_height; | ||
1147 | 103 | int r_natural_height; | ||
1148 | 104 | relative_to.get_preferred_height (out r_minimum_height, out r_natural_height); | ||
1149 | 105 | if (temp_minimum_height < app.mainwindow.get_window ().get_height () - r_minimum_height*2) { | ||
1150 | 106 | minimum_height = temp_minimum_height; | ||
1151 | 107 | } else { | ||
1152 | 108 | minimum_height = app.mainwindow.get_window ().get_height () - r_minimum_height*2; | ||
1153 | 109 | } | ||
1154 | 110 | |||
1155 | 111 | int temp_natural_height = natural_height + p_natural_height; | ||
1156 | 112 | if (temp_natural_height < app.mainwindow.get_window ().get_height () - r_natural_height*2) { | ||
1157 | 113 | natural_height = temp_natural_height; | ||
1158 | 114 | } else { | ||
1159 | 115 | natural_height = minimum_height; | ||
1160 | 116 | } | ||
1161 | 117 | } | ||
1162 | 118 | } | ||
1163 | 119 | 0 | ||
1164 | === modified file 'src/Widgets/WelcomePage.vala' | |||
1165 | --- src/Widgets/WelcomePage.vala 2016-09-28 02:32:33 +0000 | |||
1166 | +++ src/Widgets/WelcomePage.vala 2016-09-30 22:31:06 +0000 | |||
1167 | @@ -2,27 +2,19 @@ | |||
1168 | 2 | public class WelcomePage : Granite.Widgets.Welcome { | 2 | public class WelcomePage : Granite.Widgets.Welcome { |
1169 | 3 | private DiskManager disk_manager; | 3 | private DiskManager disk_manager; |
1170 | 4 | private Services.LibraryManager library_manager; | 4 | private Services.LibraryManager library_manager; |
1171 | 5 | private Audience.Widgets.Playlist playlist; | ||
1172 | 6 | |||
1173 | 5 | public WelcomePage () { | 7 | public WelcomePage () { |
1174 | 6 | base (_("No Videos Open"), _("Select a source to begin playing.")); | 8 | base (_("No Videos Open"), _("Select a source to begin playing.")); |
1175 | 7 | } | 9 | } |
1176 | 8 | 10 | ||
1177 | 9 | construct { | 11 | construct { |
1178 | 12 | playlist = Audience.Widgets.Playlist.get_instance (); | ||
1179 | 13 | playlist.collection_changed.connect ((playlist_size) => { build_replay_button (playlist_size); }); | ||
1180 | 10 | append ("document-open", _("Open file"), _("Open a saved file.")); | 14 | append ("document-open", _("Open file"), _("Open a saved file.")); |
1181 | 11 | 15 | ||
1196 | 12 | var filename = settings.current_video; | 16 | append ("media-playlist-repeat", _("Replay last video"), ""); |
1197 | 13 | var last_file = File.new_for_uri (filename); | 17 | set_item_visible (1, false); |
1184 | 14 | bool show_last_file = settings.current_video != ""; | ||
1185 | 15 | if (last_file.query_exists () == false) { | ||
1186 | 16 | show_last_file = false; | ||
1187 | 17 | } | ||
1188 | 18 | |||
1189 | 19 | if (settings.last_stopped == 0.0 || !settings.resume_videos) { | ||
1190 | 20 | append ("media-playlist-repeat", _("Replay last video"), get_title (last_file.get_basename ())); | ||
1191 | 21 | } else { | ||
1192 | 22 | append ("media-playback-start", _("Resume last video"), get_title (last_file.get_basename ())); | ||
1193 | 23 | } | ||
1194 | 24 | |||
1195 | 25 | set_item_visible (1, show_last_file); | ||
1198 | 26 | 18 | ||
1199 | 27 | //look for dvd | 19 | //look for dvd |
1200 | 28 | disk_manager = DiskManager.get_default (); | 20 | disk_manager = DiskManager.get_default (); |
1201 | @@ -54,11 +46,10 @@ | |||
1202 | 54 | var window = App.get_instance ().mainwindow; | 46 | var window = App.get_instance ().mainwindow; |
1203 | 55 | switch (index) { | 47 | switch (index) { |
1204 | 56 | case 0: | 48 | case 0: |
1207 | 57 | // Open file | 49 | window.run_open_file (); |
1206 | 58 | window.run_open_file (true); | ||
1208 | 59 | break; | 50 | break; |
1209 | 60 | case 1: | 51 | case 1: |
1211 | 61 | window.resume_last_videos (); | 52 | playlist.resume (); |
1212 | 62 | break; | 53 | break; |
1213 | 63 | case 2: | 54 | case 2: |
1214 | 64 | window.run_open_dvd (); | 55 | window.run_open_dvd (); |
1215 | @@ -67,30 +58,46 @@ | |||
1216 | 67 | window.show_library (); | 58 | window.show_library (); |
1217 | 68 | } | 59 | } |
1218 | 69 | }); | 60 | }); |
1219 | 61 | |||
1220 | 62 | build_replay_button (playlist.size); | ||
1221 | 70 | } | 63 | } |
1222 | 71 | 64 | ||
1224 | 72 | public void refresh () { | 65 | private void build_replay_button (uint playlist_size) { |
1225 | 66 | string current_video = settings.current_video; | ||
1226 | 67 | |||
1227 | 73 | var replay_button = get_button_from_index (1); | 68 | var replay_button = get_button_from_index (1); |
1228 | 74 | 69 | ||
1233 | 75 | var filename = settings.current_video; | 70 | if (playlist_size > 1 && current_video != "") { |
1234 | 76 | var last_file = File.new_for_uri (filename); | 71 | // Resume Playlist; |
1235 | 77 | 72 | replay_button.title = _("Resume playlist"); | |
1236 | 78 | if (settings.last_stopped == 0.0) { | 73 | replay_button.icon.icon_name = ("media-playback-start"); |
1237 | 74 | replay_button.description = get_title (Path.get_basename (current_video)); | ||
1238 | 75 | set_item_visible (1, true); | ||
1239 | 76 | replay_button.show_all (); | ||
1240 | 77 | } else if (playlist_size > 1 && current_video == "") { | ||
1241 | 78 | // Replay Playlist | ||
1242 | 79 | replay_button.title = _("Start playing playlist"); | ||
1243 | 80 | replay_button.icon.icon_name = ("media-playback-start"); | ||
1244 | 81 | replay_button.description = _("All videos of current playlist"); | ||
1245 | 82 | set_item_visible (1, true); | ||
1246 | 83 | replay_button.show_all (); | ||
1247 | 84 | } else if (current_video != "" && settings.last_stopped > 0) { | ||
1248 | 85 | // Resume Video | ||
1249 | 86 | replay_button.title = _("Resume last video"); | ||
1250 | 87 | replay_button.icon.icon_name = ("media-playback-start"); | ||
1251 | 88 | replay_button.description = get_title (Path.get_basename (current_video)); | ||
1252 | 89 | set_item_visible (1, true); | ||
1253 | 90 | replay_button.show_all (); | ||
1254 | 91 | } else if (current_video != "" && settings.last_stopped == 0) { | ||
1255 | 92 | // Replay Video | ||
1256 | 79 | replay_button.title = _("Replay last video"); | 93 | replay_button.title = _("Replay last video"); |
1257 | 80 | replay_button.icon.icon_name = ("media-playlist-repeat"); | 94 | replay_button.icon.icon_name = ("media-playlist-repeat"); |
1258 | 95 | replay_button.description = get_title (Path.get_basename (current_video)); | ||
1259 | 96 | set_item_visible (1, true); | ||
1260 | 97 | replay_button.show_all (); | ||
1261 | 81 | } else { | 98 | } else { |
1274 | 82 | replay_button.title = _("Resume last video"); | 99 | set_item_visible (1, false); |
1275 | 83 | replay_button.icon.icon_name = ("media-playback-start"); | 100 | } |
1264 | 84 | } | ||
1265 | 85 | replay_button.description = get_title (last_file.get_basename ()); | ||
1266 | 86 | |||
1267 | 87 | bool show_last_file = settings.current_video != ""; | ||
1268 | 88 | if (last_file.query_exists () == false) { | ||
1269 | 89 | show_last_file = false; | ||
1270 | 90 | } | ||
1271 | 91 | |||
1272 | 92 | set_item_visible (1, show_last_file); | ||
1273 | 93 | set_item_visible (2, disk_manager.has_media_volumes ()); | ||
1276 | 94 | } | 101 | } |
1277 | 95 | } | 102 | } |
1278 | 96 | } | 103 | } |
1279 | 97 | 104 | ||
1280 | === modified file 'src/Window.vala' | |||
1281 | --- src/Window.vala 2016-09-27 19:58:34 +0000 | |||
1282 | +++ src/Window.vala 2016-09-30 22:31:06 +0000 | |||
1283 | @@ -27,6 +27,7 @@ | |||
1284 | 27 | private PlayerPage player_page; | 27 | private PlayerPage player_page; |
1285 | 28 | private WelcomePage welcome_page; | 28 | private WelcomePage welcome_page; |
1286 | 29 | private LibraryPage library_page; | 29 | private LibraryPage library_page; |
1287 | 30 | private Audience.Widgets.Playlist playlist; | ||
1288 | 30 | private EpisodesPage episodes_page; | 31 | private EpisodesPage episodes_page; |
1289 | 31 | private Granite.Widgets.AlertView alert_view; | 32 | private Granite.Widgets.AlertView alert_view; |
1290 | 32 | private Toast app_notification; | 33 | private Toast app_notification; |
1291 | @@ -42,9 +43,7 @@ | |||
1292 | 42 | 43 | ||
1293 | 43 | public signal void media_volumes_changed (); | 44 | public signal void media_volumes_changed (); |
1294 | 44 | 45 | ||
1298 | 45 | public Window () { | 46 | public Window () {} |
1296 | 46 | |||
1297 | 47 | } | ||
1299 | 48 | 47 | ||
1300 | 49 | construct { | 48 | construct { |
1301 | 50 | zeitgeist_manager = new ZeitgeistManager (); | 49 | zeitgeist_manager = new ZeitgeistManager (); |
1302 | @@ -78,6 +77,9 @@ | |||
1303 | 78 | 77 | ||
1304 | 79 | set_titlebar (header); | 78 | set_titlebar (header); |
1305 | 80 | 79 | ||
1306 | 80 | welcome_page = new WelcomePage (); | ||
1307 | 81 | playlist = Audience.Widgets.Playlist.get_instance (); | ||
1308 | 82 | |||
1309 | 81 | library_page = LibraryPage.get_instance (); | 83 | library_page = LibraryPage.get_instance (); |
1310 | 82 | library_page.map.connect (() => { | 84 | library_page.map.connect (() => { |
1311 | 83 | search_entry.visible = true; | 85 | search_entry.visible = true; |
1312 | @@ -110,18 +112,12 @@ | |||
1313 | 110 | search_entry.text = ""; | 112 | search_entry.text = ""; |
1314 | 111 | }); | 113 | }); |
1315 | 112 | 114 | ||
1316 | 113 | welcome_page = new WelcomePage (); | ||
1317 | 114 | |||
1318 | 115 | player_page = new PlayerPage (); | 115 | player_page = new PlayerPage (); |
1319 | 116 | player_page.ended.connect (on_player_ended); | 116 | player_page.ended.connect (on_player_ended); |
1320 | 117 | player_page.unfullscreen_clicked.connect (() => { | 117 | player_page.unfullscreen_clicked.connect (() => { |
1321 | 118 | unfullscreen (); | 118 | unfullscreen (); |
1322 | 119 | }); | 119 | }); |
1323 | 120 | 120 | ||
1324 | 121 | player_page.notify["playing"].connect (() => { | ||
1325 | 122 | set_keep_above (player_page.playing && settings.stay_on_top); | ||
1326 | 123 | }); | ||
1327 | 124 | |||
1328 | 125 | player_page.map.connect (() => { | 121 | player_page.map.connect (() => { |
1329 | 126 | app_notification.visible = false; | 122 | app_notification.visible = false; |
1330 | 127 | }); | 123 | }); |
1331 | @@ -130,6 +126,11 @@ | |||
1332 | 130 | app_notification.visible = true; | 126 | app_notification.visible = true; |
1333 | 131 | }); | 127 | }); |
1334 | 132 | 128 | ||
1335 | 129 | player_page.started.connect ((video) => { | ||
1336 | 130 | this.title = video.title; | ||
1337 | 131 | show_player (); | ||
1338 | 132 | }); | ||
1339 | 133 | |||
1340 | 133 | alert_view = new Granite.Widgets.AlertView ("", "", ""); | 134 | alert_view = new Granite.Widgets.AlertView ("", "", ""); |
1341 | 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); |
1342 | 135 | alert_view.set_vexpand (true); | 136 | alert_view.set_vexpand (true); |
1343 | @@ -154,7 +155,7 @@ | |||
1344 | 154 | app_notification.accept.connect (() => { | 155 | app_notification.accept.connect (() => { |
1345 | 155 | library_page.manager.undo_delete_item (); | 156 | library_page.manager.undo_delete_item (); |
1346 | 156 | if (main_stack.visible_child != episodes_page) { | 157 | if (main_stack.visible_child != episodes_page) { |
1348 | 157 | main_stack.set_visible_child (library_page); | 158 | main_stack.visible_child = library_page; |
1349 | 158 | } | 159 | } |
1350 | 159 | }); | 160 | }); |
1351 | 160 | 161 | ||
1352 | @@ -314,7 +315,7 @@ | |||
1353 | 314 | } | 315 | } |
1354 | 315 | } else if (main_stack.visible_child == welcome_page) { | 316 | } else if (main_stack.visible_child == welcome_page) { |
1355 | 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)) { |
1357 | 317 | resume_last_videos (); | 318 | playlist.resume (); |
1358 | 318 | return true; | 319 | return true; |
1359 | 319 | } else if (ctrl_pressed && match_keycode (Gdk.Key.o, keycode)) { | 320 | } else if (ctrl_pressed && match_keycode (Gdk.Key.o, keycode)) { |
1360 | 320 | run_open_file (); | 321 | run_open_file (); |
1361 | @@ -344,7 +345,7 @@ | |||
1362 | 344 | 345 | ||
1363 | 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) { |
1364 | 346 | if (clear_playlist) { | 347 | if (clear_playlist) { |
1366 | 347 | player_page.get_playlist_widget ().clear_items (); | 348 | playlist.clear (); |
1367 | 348 | } | 349 | } |
1368 | 349 | 350 | ||
1369 | 350 | string[] videos = {}; | 351 | string[] videos = {}; |
1370 | @@ -365,15 +366,7 @@ | |||
1371 | 365 | } | 366 | } |
1372 | 366 | 367 | ||
1373 | 367 | if (force_play) { | 368 | if (force_play) { |
1383 | 368 | play_file (videos [0]); | 369 | playlist.play_playlist (); |
1375 | 369 | } | ||
1376 | 370 | } | ||
1377 | 371 | |||
1378 | 372 | public void resume_last_videos () { | ||
1379 | 373 | if (settings.current_video != "") { | ||
1380 | 374 | play_file (settings.current_video, false); | ||
1381 | 375 | } else { | ||
1382 | 376 | run_open_file (); | ||
1384 | 377 | } | 370 | } |
1385 | 378 | } | 371 | } |
1386 | 379 | 372 | ||
1387 | @@ -381,13 +374,6 @@ | |||
1388 | 381 | read_first_disk.begin (); | 374 | read_first_disk.begin (); |
1389 | 382 | } | 375 | } |
1390 | 383 | 376 | ||
1391 | 384 | public void show_library () { | ||
1392 | 385 | navigation_button.label = navigation_button_welcomescreen; | ||
1393 | 386 | navigation_button.show (); | ||
1394 | 387 | main_stack.visible_child = library_page; | ||
1395 | 388 | library_page.scrolled_window.grab_focus (); | ||
1396 | 389 | } | ||
1397 | 390 | |||
1398 | 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) { |
1399 | 392 | var file = new Gtk.FileChooserDialog (_("Open"), this, Gtk.FileChooserAction.OPEN, | 378 | var file = new Gtk.FileChooserDialog (_("Open"), this, Gtk.FileChooserAction.OPEN, |
1400 | 393 | _("_Cancel"), Gtk.ResponseType.CANCEL, _("_Open"), Gtk.ResponseType.ACCEPT); | 379 | _("_Cancel"), Gtk.ResponseType.CANCEL, _("_Open"), Gtk.ResponseType.ACCEPT); |
1401 | @@ -412,7 +398,7 @@ | |||
1402 | 412 | files += item; | 398 | files += item; |
1403 | 413 | } | 399 | } |
1404 | 414 | 400 | ||
1406 | 415 | open_files (files, clear_playlist, force_play); | 401 | open_files (files, force_play); |
1407 | 416 | settings.last_folder = file.get_current_folder (); | 402 | settings.last_folder = file.get_current_folder (); |
1408 | 417 | } | 403 | } |
1409 | 418 | 404 | ||
1410 | @@ -445,29 +431,37 @@ | |||
1411 | 445 | } | 431 | } |
1412 | 446 | 432 | ||
1413 | 447 | var root = volume.get_mount ().get_default_location (); | 433 | var root = volume.get_mount ().get_default_location (); |
1415 | 448 | play_file (root.get_uri ().replace ("file:///", "dvd:///")); | 434 | //play_file (root.get_uri ().replace ("file:///", "dvd:///")); |
1416 | 449 | } | 435 | } |
1417 | 450 | 436 | ||
1418 | 451 | private void on_player_ended () { | 437 | private void on_player_ended () { |
1419 | 438 | unfullscreen (); | ||
1420 | 452 | navigate_back (); | 439 | navigate_back (); |
1425 | 453 | unfullscreen (); | 440 | } |
1426 | 454 | } | 441 | |
1427 | 455 | 442 | ||
1428 | 456 | public void play_file (string uri, bool from_beginning = true) { | 443 | public void show_library () { |
1429 | 444 | navigation_button.label = navigation_button_welcomescreen; | ||
1430 | 445 | navigation_button.show (); | ||
1431 | 446 | main_stack.visible_child = library_page; | ||
1432 | 447 | library_page.scrolled_window.grab_focus (); | ||
1433 | 448 | } | ||
1434 | 449 | |||
1435 | 450 | public void show_player () { | ||
1436 | 457 | search_entry.visible = false; | 451 | search_entry.visible = false; |
1440 | 458 | if (navigation_button.visible) { | 452 | if (main_stack.visible_child != player_page) { |
1441 | 459 | if (navigation_button.label == navigation_button_library) { | 453 | if (navigation_button.visible) { |
1442 | 460 | navigation_button.label = navigation_button_episodes; | 454 | if (navigation_button.label == navigation_button_library) { |
1443 | 455 | navigation_button.label = navigation_button_episodes; | ||
1444 | 456 | } else { | ||
1445 | 457 | navigation_button.label = navigation_button_library; | ||
1446 | 458 | } | ||
1447 | 461 | } else { | 459 | } else { |
1449 | 462 | navigation_button.label = navigation_button_library; | 460 | navigation_button.show (); |
1450 | 461 | navigation_button.label = navigation_button_welcomescreen; | ||
1451 | 463 | } | 462 | } |
1455 | 464 | } else { | 463 | main_stack.set_visible_child_full ("player", Gtk.StackTransitionType.SLIDE_LEFT); |
1453 | 465 | navigation_button.show (); | ||
1454 | 466 | navigation_button.label = navigation_button_welcomescreen; | ||
1456 | 467 | } | 464 | } |
1457 | 468 | |||
1458 | 469 | main_stack.set_visible_child_full ("player", Gtk.StackTransitionType.SLIDE_LEFT); | ||
1459 | 470 | player_page.play_file (uri, from_beginning); | ||
1460 | 471 | if (is_maximized) { | 465 | if (is_maximized) { |
1461 | 472 | fullscreen (); | 466 | fullscreen (); |
1462 | 473 | } | 467 | } |
1463 | @@ -475,8 +469,6 @@ | |||
1464 | 475 | if (settings.stay_on_top && !settings.playback_wait) { | 469 | if (settings.stay_on_top && !settings.playback_wait) { |
1465 | 476 | set_keep_above (true); | 470 | set_keep_above (true); |
1466 | 477 | } | 471 | } |
1467 | 478 | |||
1468 | 479 | welcome_page.refresh (); | ||
1469 | 480 | } | 472 | } |
1470 | 481 | 473 | ||
1471 | 482 | public void navigate_back () { | 474 | public void navigate_back () { |
1472 | @@ -502,7 +494,8 @@ | |||
1473 | 502 | main_stack.set_visible_child (welcome_page); | 494 | main_stack.set_visible_child (welcome_page); |
1474 | 503 | search_entry.visible = false; | 495 | search_entry.visible = false; |
1475 | 504 | } | 496 | } |
1477 | 505 | welcome_page.refresh (); | 497 | |
1478 | 498 | playlist.hide_reval_control (); | ||
1479 | 506 | } | 499 | } |
1480 | 507 | 500 | ||
1481 | 508 | public void hide_alert () { | 501 | public void hide_alert () { |
Perhaps someone could check this branch.