Merge lp:~tintou/audience/clutter-gst-3-bis into lp:~audience-members/audience/trunk
- clutter-gst-3-bis
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Danielle Foré | ||||
Approved revision: | 578 | ||||
Merged at revision: | 577 | ||||
Proposed branch: | lp:~tintou/audience/clutter-gst-3-bis | ||||
Merge into: | lp:~audience-members/audience/trunk | ||||
Diff against target: |
2736 lines (+742/-1378) 16 files modified
data/org.pantheon.audience.gschema.xml (+0/-5) src/Audience.vala (+17/-308) src/CMakeLists.txt (+12/-2) src/DiskManager.vala (+21/-12) src/Settings.vala (+0/-1) src/Utils.vala (+4/-18) src/Widgets/BottomBar.vala (+21/-30) src/Widgets/PlayerPage.vala (+168/-286) src/Widgets/Playlist.vala (+1/-1) src/Widgets/PlaylistPopover.vala (+12/-15) src/Widgets/PreviewPopover.vala (+53/-59) src/Widgets/SettingsPopover.vala (+35/-69) src/Widgets/TimeWidget.vala (+42/-29) src/Widgets/VideoPlayer.vala (+0/-491) src/Widgets/WelcomePage.vala (+38/-52) src/Window.vala (+318/-0) |
||||
To merge this branch: | bzr merge lp:~tintou/audience/clutter-gst-3-bis | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cody Garver | Pending | ||
Nathan Dyer | Pending | ||
Review via email: mp+289499@code.launchpad.net |
This proposal supersedes a proposal from 2016-01-02.
Commit message
Port to clutter-gst-3.0
Description of the change
Nathan Dyer (nathandyer) wrote : Posted in a previous version of this proposal | # |
Cody Garver (codygarver) wrote : Posted in a previous version of this proposal | # |
Needs trunk merged in and conflicts resolved
Corentin Noël (tintou) wrote : | # |
Merged with trunk.
Cody Garver (codygarver) wrote : | # |
Still has a lot of regressions like:
* Black bars at the bottom and top when starting video windowed
* Black bars left and right after leaving fullscreen
* Cursor disappears for a while when mousing over video
* Can no longer grab and drag window around by the playback area
Cody Garver (codygarver) wrote : | # |
* Subtitles aren't shown in the menu
- 577. By Corentin Noël
-
Fixed some misbehavior with DVDs
Corentin Noël (tintou) wrote : | # |
I fixed the grab&drag window but there is nothing I can do for the black bars, there is a bug with the compositor that triggers misbehaviours when I force the window ratio.
I couldn't reproduce subtitles not showing
Danielle Foré (danrabbit) wrote : | # |
Hm I'm getting crashes when the preview popopver appears. It's doing like weird chasing the cursor (vertically) stuff as well. Not sure if this is related. Also the popover contains pillarboxing (black bars on the sides), so it might not be the window manager's fault after all ;p
- 578. By Corentin Noël
-
Fixed popover size request
Corentin Noël (tintou) wrote : | # |
I fixed the popover preview not being correctly resized, I applied the size to the popover instead of the widget itself. It's still the windows manager fault for the app itself :P
Preview Diff
1 | === modified file 'data/org.pantheon.audience.gschema.xml' |
2 | --- data/org.pantheon.audience.gschema.xml 2015-05-16 10:36:21 +0000 |
3 | +++ data/org.pantheon.audience.gschema.xml 2016-03-20 01:32:19 +0000 |
4 | @@ -49,10 +49,5 @@ |
5 | <summary>Cause the audience window to stay on top by default when it's playing</summary> |
6 | <description>Set the option to keep the audience window above all other windows by default when audience is currently playing</description> |
7 | </key> |
8 | - <key name="show-window-decoration" type="b"> |
9 | - <default>true</default> |
10 | - <summary>Don't show the window decorations</summary> |
11 | - <description>Hide the window decorations. You can close the window with escape</description> |
12 | - </key> |
13 | </schema> |
14 | </schemalist> |
15 | |
16 | === modified file 'src/Audience.vala' |
17 | --- src/Audience.vala 2016-02-23 04:26:42 +0000 |
18 | +++ src/Audience.vala 2016-03-20 01:32:19 +0000 |
19 | @@ -19,21 +19,9 @@ |
20 | * Artem Anufrij <artem.anufrij@live.de> |
21 | */ |
22 | |
23 | -/* |
24 | -[CCode (cname="gst_navigation_query_parse_commands_length")] |
25 | -public extern bool gst_navigation_query_parse_commands_length (Gst.Query q, out uint n); |
26 | -[CCode (cname="gst_navigation_query_parse_commands_nth")] |
27 | -public extern bool gst_navigation_query_parse_commands_nth (Gst.Query q, uint n, out Gst.NavigationCommand cmd); |
28 | -*/ |
29 | namespace Audience { |
30 | |
31 | - public enum Page { |
32 | - WELCOME, |
33 | - PLAYER |
34 | - } |
35 | - |
36 | public Audience.Settings settings; //global space for easier access... |
37 | - |
38 | public class App : Granite.Application { |
39 | |
40 | /** |
41 | @@ -50,8 +38,11 @@ |
42 | public const string ABOUT_STOCK = N_("About Audience"); |
43 | /// TRANSLATORS: This is the shortcut used to view information about the application itself when its displayed name is the localized equivalent of "Videos". |
44 | public const string ABOUT_GENERIC = N_("About Videos"); |
45 | - public const string ABOUT_TRANSLATORS = N_("translator-credits"); |
46 | - |
47 | + public const string ABOUT_TRANSLATORS = N_("translator-credits"); |
48 | + |
49 | + public Window mainwindow; |
50 | + public GLib.VolumeMonitor monitor; |
51 | + |
52 | construct { |
53 | program_name = "Audience"; |
54 | exec_name = "audience"; |
55 | @@ -81,318 +72,36 @@ |
56 | about_license_type = Gtk.License.GPL_3_0; |
57 | } |
58 | |
59 | - private ZeitgeistManager zeitgeist_manager; |
60 | - private Gtk.HeaderBar header; |
61 | - |
62 | - public Gtk.Window mainwindow; |
63 | - |
64 | - private Page _page; |
65 | - public Page page { |
66 | - get { |
67 | - return _page; |
68 | - } |
69 | - set { |
70 | - switch (value) { |
71 | - case Page.PLAYER: |
72 | - if (page == Page.PLAYER) |
73 | - break; |
74 | - |
75 | - if (mainwindow.get_child()!=null) |
76 | - mainwindow.get_child().destroy (); |
77 | - |
78 | - var new_widget = new PlayerPage (); |
79 | - new_widget.ended.connect (on_player_ended); |
80 | - mainwindow.add (new_widget); |
81 | - mainwindow.show_all (); |
82 | - |
83 | - _page = Page.PLAYER; |
84 | - break; |
85 | - case Page.WELCOME: |
86 | - var pl = mainwindow.get_child () as PlayerPage; |
87 | - if (pl!=null) { |
88 | - pl.ended.disconnect (on_player_ended); |
89 | - pl.destroy (); |
90 | - } |
91 | - |
92 | - var new_widget = new WelcomePage (); |
93 | - mainwindow.add (new_widget); |
94 | - mainwindow.show_all (); |
95 | - |
96 | - _page = Page.WELCOME; |
97 | - break; |
98 | - } |
99 | - } |
100 | - } |
101 | - |
102 | - private static App app; // global App instance |
103 | - public DiskManager disk_manager; |
104 | - |
105 | - public GLib.VolumeMonitor monitor; |
106 | - |
107 | - public signal void media_volumes_changed (); |
108 | - |
109 | public App () { |
110 | - |
111 | Gtk.Settings.get_default ().gtk_application_prefer_dark_theme = true; |
112 | this.flags |= GLib.ApplicationFlags.HANDLES_OPEN; |
113 | - |
114 | - zeitgeist_manager = new ZeitgeistManager (); |
115 | + settings = new Settings (); |
116 | + set_default (); |
117 | } |
118 | |
119 | + private static App app; // global App instance |
120 | public static App get_instance () { |
121 | if (app == null) |
122 | app = new App (); |
123 | return app; |
124 | } |
125 | |
126 | - void build () { |
127 | - settings = new Settings (); |
128 | - if (is_privacy_mode_enabled ()) { |
129 | - clear_video_settings (); |
130 | - } |
131 | - |
132 | - mainwindow = new Gtk.Window (); |
133 | - |
134 | - if (settings.last_folder == "-1") |
135 | - settings.last_folder = Environment.get_home_dir (); |
136 | - |
137 | - header = new Gtk.HeaderBar (); |
138 | - header.set_show_close_button (true); |
139 | - header.get_style_context ().add_class ("compact"); |
140 | - |
141 | - disk_manager = DiskManager.get_default (); |
142 | - |
143 | - disk_manager.volume_found.connect ((vol) => { |
144 | - media_volumes_changed (); |
145 | - }); |
146 | - |
147 | - disk_manager.volume_removed.connect ((vol) => { |
148 | - media_volumes_changed (); |
149 | - }); |
150 | - |
151 | - page = Page.WELCOME; |
152 | - |
153 | - mainwindow.set_application (this); |
154 | - mainwindow.set_titlebar (header); |
155 | - mainwindow.window_position = Gtk.WindowPosition.CENTER; |
156 | - mainwindow.gravity = Gdk.Gravity.CENTER; |
157 | - mainwindow.show_all (); |
158 | - if (!settings.show_window_decoration) |
159 | - mainwindow.decorated = false; |
160 | - set_window_title (program_name); |
161 | - |
162 | - mainwindow.key_press_event.connect (on_key_press_event); |
163 | - |
164 | - mainwindow.destroy.connect (() => { |
165 | - if (is_privacy_mode_enabled ()) { |
166 | - clear_video_settings (); |
167 | - } |
168 | - }); |
169 | - |
170 | - setup_drag_n_drop (); |
171 | - } |
172 | - |
173 | - public bool has_media_volumes () { |
174 | - return disk_manager.has_media_volumes (); |
175 | - } |
176 | - |
177 | - private async void read_first_disk () { |
178 | - if (disk_manager.get_volumes ().length () <= 0) |
179 | - return; |
180 | - var volume = disk_manager.get_volumes ().nth_data (0); |
181 | - if (volume.can_mount () == true && volume.get_mount ().can_unmount () == false) { |
182 | - try { |
183 | - yield volume.mount (MountMountFlags.NONE, null); |
184 | - } catch (Error e) { |
185 | - critical (e.message); |
186 | - } |
187 | - } |
188 | - |
189 | - page = Page.PLAYER; |
190 | - var root = volume.get_mount ().get_default_location (); |
191 | - play_file (root.get_uri (), true); |
192 | - } |
193 | - |
194 | - public void set_content_size (double width, double height, double content_height){ |
195 | - var geom = Gdk.Geometry (); |
196 | - |
197 | - if (width == 0 |
198 | - && height == 0 |
199 | - && content_height == 0) { |
200 | - geom.min_aspect = geom.max_aspect = 0; |
201 | - } else { |
202 | - double width_offset = mainwindow.get_allocated_width () - width; |
203 | - double height_offset = mainwindow.get_allocated_height () - content_height; |
204 | - |
205 | - debug ("Width: %f, Height: %f, Offset: %f )\n", width, height, content_height); |
206 | - |
207 | - geom.min_aspect = geom.max_aspect = (width + width_offset) / (height + height_offset); |
208 | - } |
209 | - |
210 | - mainwindow.set_geometry_hints (mainwindow, geom, Gdk.WindowHints.ASPECT); |
211 | - } |
212 | - |
213 | - private void on_player_ended () { |
214 | - page = Page.WELCOME; |
215 | - } |
216 | - |
217 | - public bool on_key_press_event (Gdk.EventKey e) { |
218 | - switch (e.keyval) { |
219 | - case Gdk.Key.o: |
220 | - App.get_instance ().run_open_file (); |
221 | - break; |
222 | - case Gdk.Key.q: |
223 | - App.get_instance ().mainwindow.destroy (); |
224 | - break; |
225 | - default: |
226 | - break; |
227 | - } |
228 | - return false; |
229 | - } |
230 | - |
231 | - private inline void clear_video_settings () { |
232 | - settings.last_stopped = 0; |
233 | - settings.last_played_videos = null; |
234 | - settings.current_video = ""; |
235 | - settings.last_folder = ""; |
236 | - } |
237 | - |
238 | - public void run_open_file () { |
239 | - var file = new Gtk.FileChooserDialog (_("Open"), mainwindow, Gtk.FileChooserAction.OPEN, |
240 | - _("_Cancel"), Gtk.ResponseType.CANCEL, _("_Open"), Gtk.ResponseType.ACCEPT); |
241 | - file.set_transient_for (mainwindow); |
242 | - file.select_multiple = true; |
243 | - |
244 | - var all_files_filter = new Gtk.FileFilter (); |
245 | - all_files_filter.set_filter_name (_("All files")); |
246 | - all_files_filter.add_pattern ("*"); |
247 | - |
248 | - var video_filter = new Gtk.FileFilter (); |
249 | - video_filter.set_filter_name (_("Video files")); |
250 | - video_filter.add_mime_type ("video/*"); |
251 | - |
252 | - file.add_filter (video_filter); |
253 | - file.add_filter (all_files_filter); |
254 | - |
255 | - file.set_current_folder (settings.last_folder); |
256 | - if (file.run () == Gtk.ResponseType.ACCEPT) { |
257 | - if (page == Page.WELCOME) |
258 | - clear_video_settings (); |
259 | - |
260 | - File[] files = {}; |
261 | - foreach (File item in file.get_files ()) { |
262 | - files += item; |
263 | - } |
264 | - |
265 | - open (files, ""); |
266 | - settings.last_folder = file.get_current_folder (); |
267 | - } |
268 | - |
269 | - file.destroy (); |
270 | - } |
271 | - |
272 | - public void run_open_dvd () { |
273 | - read_first_disk.begin (); |
274 | - } |
275 | - |
276 | - /*DnD*/ |
277 | - private void setup_drag_n_drop () { |
278 | - Gtk.TargetEntry uris = {"text/uri-list", 0, 0}; |
279 | - Gtk.drag_dest_set (mainwindow, Gtk.DestDefaults.ALL, {uris}, Gdk.DragAction.MOVE); |
280 | - mainwindow.drag_data_received.connect ( (ctx, x, y, sel, info, time) => { |
281 | - page = Page.PLAYER; |
282 | - File[] files = {}; |
283 | - foreach (var uri in sel.get_uris ()) { |
284 | - var file = File.new_for_uri (uri); |
285 | - files += file; |
286 | - } |
287 | - open (files,""); |
288 | - }); |
289 | - } |
290 | - |
291 | - public void resume_last_videos () { |
292 | - page = Page.PLAYER; |
293 | - |
294 | - var player = mainwindow.get_child () as PlayerPage; |
295 | - player.resume_last_videos (); |
296 | - } |
297 | - |
298 | - public void set_window_title (string title) { |
299 | - mainwindow.title = title; |
300 | - } |
301 | - |
302 | - /* |
303 | - make sure we are in player page and play file |
304 | - */ |
305 | - internal void play_file (string uri, bool dont_modify = false) { |
306 | - if (page != Page.PLAYER) |
307 | - page = Page.PLAYER; |
308 | - |
309 | - PlayerPage player_page = mainwindow.get_child() as PlayerPage; |
310 | - player_page.play_file (uri); |
311 | - |
312 | - } |
313 | - |
314 | public override void activate () { |
315 | if (mainwindow == null) { |
316 | - build (); |
317 | + if (settings.last_folder == "-1") { |
318 | + settings.last_folder = Environment.get_user_special_dir (GLib.UserDirectory.VIDEOS); |
319 | + } |
320 | + |
321 | + mainwindow = new Window (); |
322 | + mainwindow.application = this; |
323 | + mainwindow.title = program_name; |
324 | } |
325 | } |
326 | |
327 | //the application was requested to open some files |
328 | public override void open (File[] files, string hint) { |
329 | - if (mainwindow == null) |
330 | - build (); |
331 | - |
332 | - if (page != Page.PLAYER) |
333 | - clear_video_settings (); |
334 | - |
335 | - page = Page.PLAYER; |
336 | - var player_page = (mainwindow.get_child () as PlayerPage); |
337 | - string[] videos = {}; |
338 | - foreach (var file in files) { |
339 | - |
340 | - if (file.query_file_type (0) == FileType.DIRECTORY) { |
341 | - Audience.recurse_over_dir (file, (file_ret) => { |
342 | - player_page.append_to_playlist (file); |
343 | - videos += file_ret.get_uri (); |
344 | - }); |
345 | - } else if (player_page.video_player.playing && |
346 | - PlayerPage.is_subtitle (file.get_uri ())) { |
347 | - message ("is subtitle"); |
348 | - player_page.video_player.set_subtitle_uri (file.get_uri ()); |
349 | - } else { |
350 | - player_page.append_to_playlist (file); |
351 | - videos += file.get_uri (); |
352 | - } |
353 | - } |
354 | - |
355 | - if (videos.length == 0) |
356 | - return; |
357 | - |
358 | - // notification when adding video to playlist |
359 | - if (!player_page.video_player.playing // we are paused |
360 | - && (mainwindow.get_window ().get_state () & Gdk.WindowState.FOCUSED) == 0) { |
361 | - if (videos.length == 1) |
362 | - show_notification (_("Video added to playlist"), get_title (videos[0])); |
363 | - else |
364 | - show_notification (_("%i videos added to playlist").printf (videos.length), ""); |
365 | - } |
366 | - |
367 | - play_file (videos [0]); |
368 | - |
369 | - |
370 | - } |
371 | - |
372 | - internal bool is_privacy_mode_enabled () { |
373 | - var privacy_settings = new GLib.Settings ("org.gnome.desktop.privacy"); |
374 | - bool privacy_mode = !privacy_settings.get_boolean ("remember-recent-files") || !privacy_settings.get_boolean ("remember-app-usage"); |
375 | - |
376 | - if (privacy_mode) { |
377 | - return true; |
378 | - } |
379 | - |
380 | - return zeitgeist_manager.app_into_blacklist (exec_name); |
381 | + activate (); |
382 | + mainwindow.open_files (files); |
383 | } |
384 | |
385 | } |
386 | |
387 | === modified file 'src/CMakeLists.txt' |
388 | --- src/CMakeLists.txt 2015-10-27 18:43:49 +0000 |
389 | +++ src/CMakeLists.txt 2016-03-20 01:32:19 +0000 |
390 | @@ -11,7 +11,16 @@ |
391 | # pkgconfig, real C code |
392 | find_package (PkgConfig) |
393 | |
394 | -set (PKG_DEPS granite>=0.3.0 clutter-gtk-1.0 gstreamer-1.0 gstreamer-pbutils-1.0 gstreamer-video-1.0 gstreamer-tag-1.0) |
395 | +set (PKG_DEPS |
396 | + granite>=0.3.0 |
397 | + clutter-gtk-1.0 |
398 | + gstreamer-1.0 |
399 | + gstreamer-pbutils-1.0 |
400 | + gstreamer-video-1.0 |
401 | + gstreamer-tag-1.0 |
402 | + clutter-gst-3.0 |
403 | +) |
404 | + |
405 | set (VALA_DEPS |
406 | granite>=0.3.0 |
407 | clutter-gtk-1.0 |
408 | @@ -20,6 +29,7 @@ |
409 | gstreamer-pbutils-1.0 |
410 | gstreamer-video-1.0 |
411 | gstreamer-tag-1.0 |
412 | + clutter-gst-3.0 |
413 | ) |
414 | |
415 | pkg_check_modules (DEPS REQUIRED ${PKG_DEPS}) |
416 | @@ -57,13 +67,13 @@ |
417 | Settings.vala |
418 | Utils.vala |
419 | DiskManager.vala |
420 | + Window.vala |
421 | Widgets/BottomBar.vala |
422 | Widgets/SettingsPopover.vala |
423 | Widgets/PreviewPopover.vala |
424 | Widgets/TimeWidget.vala |
425 | Widgets/Playlist.vala |
426 | Widgets/PlaylistPopover.vala |
427 | - Widgets/VideoPlayer.vala |
428 | Widgets/WelcomePage.vala |
429 | Widgets/PlayerPage.vala |
430 | PACKAGES |
431 | |
432 | === modified file 'src/DiskManager.vala' |
433 | --- src/DiskManager.vala 2015-06-07 13:27:10 +0000 |
434 | +++ src/DiskManager.vala 2016-03-20 01:32:19 +0000 |
435 | @@ -32,11 +32,18 @@ |
436 | } |
437 | |
438 | private GLib.VolumeMonitor monitor; |
439 | - private List<Volume> volumes; |
440 | + private Gee.TreeSet<Volume> volumes; |
441 | |
442 | private DiskManager () { |
443 | + |
444 | + } |
445 | + |
446 | + construct { |
447 | monitor = GLib.VolumeMonitor.get (); |
448 | - volumes = monitor.get_volumes (); |
449 | + volumes = new Gee.TreeSet<Volume> (); |
450 | + monitor.get_volumes ().foreach ((volume) => { |
451 | + volumes.add (volume); |
452 | + }); |
453 | |
454 | monitor.drive_changed.connect ((drive) => { |
455 | debug ("Drive changed: %s\n", drive.get_name ()); |
456 | @@ -71,30 +78,32 @@ |
457 | monitor.volume_removed.connect ((volume) => { |
458 | volumes.remove (volume); |
459 | volume_removed (volume); |
460 | - debug ("Volume removed: %s"+volumes.length ().to_string (), volume.get_name ()); |
461 | + debug ("Volume removed: %s", volume.get_name ()); |
462 | }); |
463 | } |
464 | |
465 | - public GLib.List<Volume> get_volumes () { |
466 | - return volumes.copy (); |
467 | + public Gee.TreeSet<Volume> get_volumes () { |
468 | + return volumes; |
469 | } |
470 | |
471 | - public GLib.List<Volume> get_media_volumes () { |
472 | - GLib.List<Volume> returnValue = new GLib.List<Volume> (); |
473 | + public Gee.TreeSet<Volume> get_media_volumes () { |
474 | + var return_value = new Gee.TreeSet<Volume> (); |
475 | foreach (Volume volume in volumes) { |
476 | - if (has_dvd_media (volume)) |
477 | - returnValue.append (volume); |
478 | + if (has_dvd_media (volume)) { |
479 | + return_value.add (volume); |
480 | + } |
481 | } |
482 | - return returnValue; |
483 | + |
484 | + return return_value; |
485 | } |
486 | |
487 | public bool has_media_volumes () { |
488 | - return (get_media_volumes ().length () > 0); |
489 | + return (get_media_volumes ().size > 0); |
490 | } |
491 | |
492 | private void check_for_volume (Volume volume) { |
493 | if (has_dvd_media (volume)) { |
494 | - volumes.append (volume); |
495 | + volumes.add (volume); |
496 | volume_found (volume); |
497 | } |
498 | } |
499 | |
500 | === modified file 'src/Settings.vala' |
501 | --- src/Settings.vala 2015-05-16 10:13:38 +0000 |
502 | +++ src/Settings.vala 2016-03-20 01:32:19 +0000 |
503 | @@ -28,7 +28,6 @@ |
504 | public string last_folder {get; set;} |
505 | public bool playback_wait {get; set;} |
506 | public bool stay_on_top {get; set;} |
507 | - public bool show_window_decoration {get; set;} |
508 | public string subtitle_font {get; set; } |
509 | |
510 | public Settings () { |
511 | |
512 | === modified file 'src/Utils.vala' |
513 | --- src/Utils.vala 2015-06-06 14:08:15 +0000 |
514 | +++ src/Utils.vala 2016-03-20 01:32:19 +0000 |
515 | @@ -68,18 +68,9 @@ |
516 | } |
517 | |
518 | public static string get_basename (string filename) { |
519 | - uint end = 0; |
520 | - for (uint start=filename.length; start != 0; start--) { |
521 | - if (filename[start] == '/') { |
522 | - start ++; |
523 | - return filename.substring (start, end - start); |
524 | - } |
525 | - |
526 | - if (filename[start] == '.' && end == 0) |
527 | - end = start; |
528 | - } |
529 | - |
530 | - return filename.substring (0, end); |
531 | + var name = Path.get_basename (filename); |
532 | + |
533 | + return name.split (".", 2)[0]; |
534 | } |
535 | |
536 | public static string seconds_to_time (int seconds) { |
537 | @@ -103,8 +94,7 @@ |
538 | } |
539 | |
540 | public static bool has_dvd () { |
541 | - var disk_manager = DiskManager.get_default (); |
542 | - return disk_manager.get_volumes ().length () > 0; |
543 | + return !DiskManager.get_default ().get_volumes ().is_empty; |
544 | } |
545 | |
546 | public static bool file_exists (string uri) { |
547 | @@ -153,8 +143,4 @@ |
548 | } |
549 | #endif |
550 | } |
551 | - |
552 | - private bool modifier_is_pressed (Gdk.EventKey event, Gdk.ModifierType modifier) { |
553 | - return (event.state & modifier) == modifier; |
554 | - } |
555 | } |
556 | |
557 | === modified file 'src/Widgets/BottomBar.vala' |
558 | --- src/Widgets/BottomBar.vala 2015-11-30 06:29:31 +0000 |
559 | +++ src/Widgets/BottomBar.vala 2016-03-20 01:32:19 +0000 |
560 | @@ -24,22 +24,19 @@ |
561 | public signal void unfullscreen (); |
562 | public signal void seeked (double val); |
563 | |
564 | + public bool playing { get; set; default=false; } |
565 | public bool hovered { get; set; default=false; } |
566 | public bool fullscreen { get; set; default=false; } |
567 | public SettingsPopover preferences_popover; |
568 | public PlaylistPopover playlist_popover; |
569 | public TimeWidget time_widget; |
570 | |
571 | - private Widgets.VideoPlayer player; |
572 | private Gtk.Button play_button; |
573 | private Gtk.Button preferences_button; |
574 | private Gtk.Revealer unfullscreen_revealer; |
575 | - private bool is_playing = false; |
576 | private uint hiding_timer = 0; |
577 | |
578 | - public BottomBar (Widgets.VideoPlayer player) { |
579 | - this.player = player; |
580 | - |
581 | + public BottomBar (ClutterGst.Playback playback) { |
582 | this.events |= Gdk.EventMask.POINTER_MOTION_MASK; |
583 | this.events |= Gdk.EventMask.LEAVE_NOTIFY_MASK; |
584 | this.events |= Gdk.EventMask.ENTER_NOTIFY_MASK; |
585 | @@ -63,12 +60,11 @@ |
586 | preferences_button.tooltip_text = _("Settings"); |
587 | preferences_button.clicked.connect (() => {preferences_popover.show_all (); preferences_popover.queue_resize ();}); |
588 | |
589 | - time_widget = new TimeWidget (); |
590 | - time_widget.seeked.connect ((val) => {seeked (val);}); |
591 | + time_widget = new TimeWidget (playback); |
592 | |
593 | playlist_popover = new PlaylistPopover (); |
594 | playlist_popover.relative_to = playlist_button; |
595 | - preferences_popover = new SettingsPopover (player); |
596 | + preferences_popover = new SettingsPopover (playback); |
597 | preferences_popover.relative_to = preferences_button; |
598 | |
599 | main_actionbar.pack_start (play_button); |
600 | @@ -96,13 +92,25 @@ |
601 | } |
602 | }); |
603 | |
604 | + play_button.clicked.connect (() => { |
605 | + playing = !playing; |
606 | + }); |
607 | + |
608 | + notify["playing"].connect (() => { |
609 | + if (playing == true) { |
610 | + ((Gtk.Image) play_button.image).icon_name = "media-playback-pause-symbolic"; |
611 | + play_button.tooltip_text = _("Pause"); |
612 | + reveal_control (); |
613 | + } else { |
614 | + ((Gtk.Image) play_button.image).icon_name = "media-playback-start-symbolic"; |
615 | + play_button.tooltip_text = _("Play"); |
616 | + set_reveal_child (true); |
617 | + } |
618 | + }); |
619 | + |
620 | show_all (); |
621 | } |
622 | |
623 | - public void set_preview_uri (string uri) { |
624 | - time_widget.set_preview_uri (uri); |
625 | - } |
626 | - |
627 | public bool get_repeat () { |
628 | return playlist_popover.rep.active; |
629 | } |
630 | @@ -123,19 +131,6 @@ |
631 | return unfullscreen_revealer; |
632 | } |
633 | |
634 | - public void toggle_play_pause () { |
635 | - is_playing = !is_playing; |
636 | - if (is_playing == true) { |
637 | - play_button.image = new Gtk.Image.from_icon_name ("media-playback-pause-symbolic", Gtk.IconSize.BUTTON); |
638 | - play_button.tooltip_text = _("Pause"); |
639 | - reveal_control (); |
640 | - } else { |
641 | - play_button.image = new Gtk.Image.from_icon_name ("media-playback-start-symbolic", Gtk.IconSize.BUTTON); |
642 | - play_button.tooltip_text = _("Play"); |
643 | - set_reveal_child (true); |
644 | - } |
645 | - } |
646 | - |
647 | private new void set_reveal_child (bool reveal) { |
648 | base.set_reveal_child (reveal); |
649 | if (reveal == true && fullscreen == true) { |
650 | @@ -156,10 +151,6 @@ |
651 | } |
652 | } |
653 | |
654 | - public void set_progression_time (double current_time, double total_time) { |
655 | - time_widget.set_progression_time (current_time, total_time); |
656 | - } |
657 | - |
658 | public void reveal_control () { |
659 | if (child_revealed == false) |
660 | set_reveal_child (true); |
661 | @@ -168,7 +159,7 @@ |
662 | Source.remove (hiding_timer); |
663 | |
664 | hiding_timer = GLib.Timeout.add (2000, () => { |
665 | - if (hovered == true || preferences_popover.visible == true || playlist_popover.visible == true || is_playing == false) { |
666 | + if (hovered == true || preferences_popover.visible == true || playlist_popover.visible == true || playing == false) { |
667 | hiding_timer = 0; |
668 | return false; |
669 | } |
670 | |
671 | === modified file 'src/Widgets/PlayerPage.vala' |
672 | --- src/Widgets/PlayerPage.vala 2016-02-23 04:31:53 +0000 |
673 | +++ src/Widgets/PlayerPage.vala 2016-03-20 01:32:19 +0000 |
674 | @@ -7,21 +7,25 @@ |
675 | "ass", |
676 | "asc" |
677 | }; |
678 | - public class PlayerPage : Gtk.Bin { |
679 | - public GtkClutter.Embed clutter; |
680 | - public Audience.Widgets.VideoPlayer video_player; |
681 | + |
682 | + public class PlayerPage : Gtk.EventBox { |
683 | + public signal void unfullscreen_clicked (); |
684 | + public signal void ended (); |
685 | + |
686 | + public GtkClutter.Embed clutter; |
687 | + private Clutter.Actor video_actor; |
688 | private Audience.Widgets.BottomBar bottom_bar; |
689 | private Clutter.Stage stage; |
690 | private Gtk.Revealer unfullscreen_bar; |
691 | private GtkClutter.Actor unfullscreen_actor; |
692 | private GtkClutter.Actor bottom_actor; |
693 | - private GnomeMediaKeys mediakeys; |
694 | + private GnomeMediaKeys mediakeys; |
695 | + private ClutterGst.Playback playback; |
696 | |
697 | public GnomeSessionManager session_manager; |
698 | uint32 inhibit_cookie; |
699 | |
700 | private bool mouse_primary_down = false; |
701 | - private bool fullscreened = false; |
702 | |
703 | public bool repeat { |
704 | get{ |
705 | @@ -33,29 +37,75 @@ |
706 | } |
707 | } |
708 | |
709 | - public signal void ended (); |
710 | + public bool playing { |
711 | + get { |
712 | + return playback.playing; |
713 | + } |
714 | + set { |
715 | + if (playback.playing == value) |
716 | + return; |
717 | + |
718 | + playback.playing = value; |
719 | + } |
720 | + } |
721 | + |
722 | + private bool _fullscreened = false; |
723 | + public bool fullscreened { |
724 | + get { |
725 | + return _fullscreened; |
726 | + } |
727 | + set { |
728 | + _fullscreened = value; |
729 | + bottom_bar.fullscreen = value; |
730 | + } |
731 | + } |
732 | |
733 | public PlayerPage () { |
734 | - video_player = new Widgets.VideoPlayer(); |
735 | - video_player.notify["playing"].connect (() => { |
736 | - bottom_bar.toggle_play_pause (); |
737 | - inhibit_session (video_player.playing); |
738 | + } |
739 | + |
740 | + construct { |
741 | + events |= Gdk.EventMask.POINTER_MOTION_MASK; |
742 | + events |= Gdk.EventMask.KEY_PRESS_MASK; |
743 | + events |= Gdk.EventMask.KEY_RELEASE_MASK; |
744 | + playback = new ClutterGst.Playback (); |
745 | + playback.set_seek_flags (ClutterGst.SeekFlags.ACCURATE); |
746 | + playback.notify["playing"].connect (() => { |
747 | + inhibit_session (playback.playing); |
748 | }); |
749 | |
750 | clutter = new GtkClutter.Embed (); |
751 | stage = (Clutter.Stage)clutter.get_stage (); |
752 | stage.background_color = {0, 0, 0, 0}; |
753 | |
754 | - video_player.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.WIDTH, 0)); |
755 | - video_player.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.HEIGHT, 0)); |
756 | - |
757 | - stage.add_child (video_player); |
758 | - |
759 | - bottom_bar = new Widgets.BottomBar (video_player); |
760 | - bottom_bar.play_toggled.connect (() => { video_player.playing = !video_player.playing; }); |
761 | - bottom_bar.seeked.connect ((val) => { video_player.progress = val; }); |
762 | - bottom_bar.unfullscreen.connect (()=>{set_fullscreen (false);}); |
763 | - bottom_bar.set_repeat (false); |
764 | + video_actor = new Clutter.Actor (); |
765 | + var aspect_ratio = ClutterGst.Aspectratio.@new (); |
766 | + ((ClutterGst.Aspectratio) aspect_ratio).paint_borders = false; |
767 | + ((ClutterGst.Content) aspect_ratio).player = playback; |
768 | + /* Commented because of a bug in the compositor |
769 | + ((ClutterGst.Content) aspect_ratio).size_change.connect ((width, height) => { |
770 | + double aspect = ((double) width)/((double) height); |
771 | + var geometry = Gdk.Geometry (); |
772 | + geometry.min_aspect = aspect; |
773 | + geometry.max_aspect = aspect; |
774 | + ((Gtk.Window) get_toplevel ()).set_geometry_hints (get_toplevel (), geometry, Gdk.WindowHints.ASPECT); |
775 | + }); |
776 | + */ |
777 | + video_actor.content = aspect_ratio; |
778 | + |
779 | + video_actor.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.WIDTH, 0)); |
780 | + video_actor.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.HEIGHT, 0)); |
781 | + |
782 | + Signal.connect (clutter, "button-press-event", (GLib.Callback) navigation_event, this); |
783 | + Signal.connect (clutter, "button-release-event", (GLib.Callback) navigation_event, this); |
784 | + Signal.connect (clutter, "key-press-event", (GLib.Callback) navigation_event, this); |
785 | + Signal.connect (clutter, "key-release-event", (GLib.Callback) navigation_event, this); |
786 | + Signal.connect (clutter, "motion-notify-event", (GLib.Callback) navigation_event, this); |
787 | + |
788 | + stage.add_child (video_actor); |
789 | + |
790 | + bottom_bar = new Widgets.BottomBar (playback); |
791 | + bottom_bar.bind_property ("playing", playback, "playing", BindingFlags.BIDIRECTIONAL); |
792 | + bottom_bar.unfullscreen.connect (() => unfullscreen_clicked ()); |
793 | |
794 | unfullscreen_bar = bottom_bar.get_unfullscreen_button (); |
795 | |
796 | @@ -71,12 +121,6 @@ |
797 | unfullscreen_actor.add_constraint (new Clutter.AlignConstraint (stage, Clutter.AlignAxis.Y_AXIS, 0)); |
798 | stage.add_child (unfullscreen_actor); |
799 | |
800 | - this.size_allocate.connect (on_size_allocate); |
801 | - App.get_instance ().mainwindow.key_press_event.connect (on_key_press_event); |
802 | - App.get_instance ().mainwindow.window_state_event.connect (on_window_state_event); |
803 | - if (App.get_instance ().mainwindow.is_maximized) |
804 | - set_fullscreen (true); |
805 | - |
806 | //media keys |
807 | try { |
808 | mediakeys = Bus.get_proxy_sync (BusType.SESSION, |
809 | @@ -92,7 +136,7 @@ |
810 | get_playlist_widget ().next (); |
811 | break; |
812 | case "Play": |
813 | - video_player.playing = !video_player.playing; |
814 | + playback.playing = !playback.playing; |
815 | break; |
816 | default: |
817 | break; |
818 | @@ -104,7 +148,7 @@ |
819 | warning (e.message); |
820 | } |
821 | |
822 | - App.get_instance ().mainwindow.motion_notify_event.connect ((event) => { |
823 | + this.motion_notify_event.connect ((event) => { |
824 | if (mouse_primary_down && settings.move_window) { |
825 | mouse_primary_down = false; |
826 | App.get_instance ().mainwindow.begin_move_drag (Gdk.BUTTON_PRIMARY, |
827 | @@ -117,13 +161,6 @@ |
828 | }); |
829 | |
830 | this.button_press_event.connect ((event) => { |
831 | - if (event.button == Gdk.BUTTON_PRIMARY |
832 | - && event.type == Gdk.EventType.2BUTTON_PRESS) // double left click |
833 | - set_fullscreen(!fullscreened); |
834 | - |
835 | - if (event.button == Gdk.BUTTON_SECONDARY) // right click |
836 | - bottom_bar.play_toggled (); |
837 | - |
838 | if (event.button == Gdk.BUTTON_PRIMARY) |
839 | mouse_primary_down = true; |
840 | |
841 | @@ -151,31 +188,25 @@ |
842 | |
843 | this.destroy.connect (() => { |
844 | // FIXME:should find better way to decide if its end of playlist |
845 | - if (video_player.progress > 0.99) |
846 | + if (playback.progress > 0.99) |
847 | settings.last_stopped = 0; |
848 | else |
849 | - settings.last_stopped = video_player.progress; |
850 | + settings.last_stopped = playback.progress; |
851 | |
852 | get_playlist_widget ().save_playlist (); |
853 | }); |
854 | |
855 | - /*events*/ |
856 | - video_player.text_tags_changed.connect (bottom_bar.preferences_popover.setup_text); |
857 | - video_player.audio_tags_changed.connect (bottom_bar.preferences_popover.setup_audio); |
858 | - video_player.progression_changed.connect ((current_time, total_time) => { |
859 | - bottom_bar.set_progression_time (current_time, total_time); |
860 | - }); |
861 | - |
862 | //end |
863 | - video_player.ended.connect (() => { |
864 | + playback.eos.connect (() => { |
865 | Idle.add (() => { |
866 | - video_player.progress = 0; |
867 | + playback.progress = 0; |
868 | if (!get_playlist_widget ().next ()) { |
869 | if (repeat) { |
870 | play_file (get_playlist_widget ().get_first_item ().get_uri ()); |
871 | - video_player.playing = true; |
872 | + playback.playing = true; |
873 | } else { |
874 | - video_player.playing = false; |
875 | + playback.playing = false; |
876 | + settings.last_stopped = 0; |
877 | ended (); |
878 | } |
879 | } |
880 | @@ -183,26 +214,6 @@ |
881 | }); |
882 | }); |
883 | |
884 | - video_player.error.connect (() => { |
885 | - App.get_instance ().page = Page.WELCOME; |
886 | - }); |
887 | - |
888 | - video_player.plugin_install_done.connect (() => { |
889 | - App.get_instance ().page = Page.PLAYER; |
890 | - }); |
891 | - |
892 | - video_player.notify["playing"].connect (() => { |
893 | - App.get_instance ().mainwindow.set_keep_above (video_player.playing && settings.stay_on_top); |
894 | - }); |
895 | - |
896 | - bottom_bar.time_widget.slider_motion_event.connect ((event) => { |
897 | - int x, y; |
898 | - bottom_bar.translate_coordinates (App.get_instance ().mainwindow, (int)event.x, (int)event.y, out x, out y); |
899 | - Gtk.Allocation allocation; |
900 | - clutter.get_allocation (out allocation); |
901 | - update_pointer_position (y, allocation.height); |
902 | - }); |
903 | - |
904 | //playlist wants us to open a file |
905 | get_playlist_widget ().play.connect ((file) => { |
906 | this.play_file (file.get_uri ()); |
907 | @@ -212,56 +223,35 @@ |
908 | if (bottom_bar.child_revealed == true) { |
909 | App.get_instance ().mainwindow.get_window ().set_cursor (null); |
910 | } else { |
911 | - App.get_instance ().mainwindow.get_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.BLANK_CURSOR)); |
912 | + var window = App.get_instance ().mainwindow.get_window (); |
913 | + var display = window.get_display (); |
914 | + var cursor = new Gdk.Cursor.for_display (display, Gdk.CursorType.BLANK_CURSOR); |
915 | + window.set_cursor (cursor); |
916 | } |
917 | }); |
918 | |
919 | add (clutter); |
920 | - |
921 | show_all (); |
922 | - |
923 | - } |
924 | - |
925 | - ~PlayerPage () { |
926 | - video_player.playing = false; |
927 | - |
928 | - App.get_instance ().set_content_size (0, 0, 0); |
929 | - this.size_allocate.disconnect (on_size_allocate); |
930 | - App.get_instance ().mainwindow.window_state_event.disconnect (on_window_state_event); |
931 | - App.get_instance ().mainwindow.key_press_event.disconnect (on_key_press_event); |
932 | - if (App.get_instance ().mainwindow.get_window () != null) |
933 | - App.get_instance ().mainwindow.get_window ().set_cursor (null); |
934 | - |
935 | - App.get_instance ().mainwindow.unfullscreen (); |
936 | - if (fullscreened) |
937 | - App.get_instance ().mainwindow.maximize (); |
938 | - |
939 | - video_player.text_tags_changed.disconnect (bottom_bar.preferences_popover.setup_text); |
940 | - video_player.audio_tags_changed.disconnect (bottom_bar.preferences_popover.setup_audio); |
941 | } |
942 | |
943 | public void play_file (string uri, bool from_beginning = true) { |
944 | debug ("Opening %s", uri); |
945 | - video_player.uri = uri; |
946 | get_playlist_widget ().set_current (uri); |
947 | - bottom_bar.set_preview_uri (uri); |
948 | + playback.uri = uri; |
949 | |
950 | string? sub_uri = get_subtitle_for_uri (uri); |
951 | - if (sub_uri != null) |
952 | - video_player.set_subtitle_uri (sub_uri); |
953 | - |
954 | - App.get_instance ().set_window_title (get_title (uri)); |
955 | - video_player.relayout (); |
956 | - |
957 | - int target_width, target_height, center_x, center_y; |
958 | - get_target_size (out target_width, out target_height, out center_x, out center_y); |
959 | - get_window ().move_resize (center_x, center_y, target_width, target_height); |
960 | - |
961 | - update_aspect_ratio (); |
962 | - video_player.playing = !settings.playback_wait; |
963 | - if (from_beginning) |
964 | - video_player.progress = 0.0; |
965 | - |
966 | + if (sub_uri != null && sub_uri != uri) |
967 | + playback.set_subtitle_uri (sub_uri); |
968 | + |
969 | + App.get_instance ().mainwindow.title = get_title (uri); |
970 | + |
971 | + if (from_beginning) { |
972 | + playback.progress = 0.0; |
973 | + } else { |
974 | + playback.progress = settings.last_stopped; |
975 | + } |
976 | + |
977 | + playback.playing = !settings.playback_wait; |
978 | Gtk.RecentManager recent_manager = Gtk.RecentManager.get_default (); |
979 | recent_manager.add_item (uri); |
980 | |
981 | @@ -270,6 +260,10 @@ |
982 | bottom_bar.preferences_popover.setup_audio (); |
983 | } |
984 | |
985 | + public string get_played_uri () { |
986 | + return playback.uri; |
987 | + } |
988 | + |
989 | public void next () { |
990 | get_playlist_widget ().next (); |
991 | } |
992 | @@ -280,26 +274,46 @@ |
993 | |
994 | public void resume_last_videos () { |
995 | play_file (settings.current_video); |
996 | - video_player.playing = false; |
997 | - Idle.add (() => { |
998 | - if (settings.resume_videos) |
999 | - video_player.progress = settings.last_stopped; |
1000 | - else |
1001 | - video_player.progress = 0.0; |
1002 | + playback.playing = false; |
1003 | + if (settings.resume_videos) { |
1004 | + playback.progress = settings.last_stopped; |
1005 | + } else { |
1006 | + playback.progress = 0.0; |
1007 | + } |
1008 | |
1009 | - return false; |
1010 | - }); |
1011 | - video_player.playing = !settings.playback_wait; |
1012 | + playback.playing = !settings.playback_wait; |
1013 | } |
1014 | |
1015 | public void append_to_playlist (File file) { |
1016 | - get_playlist_widget ().add_item (file); |
1017 | + if (playback.playing && is_subtitle (file.get_uri ())) { |
1018 | + playback.set_subtitle_uri (file.get_uri ()); |
1019 | + } else { |
1020 | + get_playlist_widget ().add_item (file); |
1021 | + } |
1022 | } |
1023 | |
1024 | public void play_first_in_playlist () { |
1025 | var file = get_playlist_widget ().get_first_item (); |
1026 | play_file (file.get_uri ()); |
1027 | - video_player.progress = 0.0; |
1028 | + } |
1029 | + |
1030 | + public void reveal_control () { |
1031 | + bottom_bar.reveal_control (); |
1032 | + } |
1033 | + |
1034 | + public void next_audio () { |
1035 | + bottom_bar.preferences_popover.next_audio (); |
1036 | + } |
1037 | + |
1038 | + public void next_text () { |
1039 | + bottom_bar.preferences_popover.next_text (); |
1040 | + } |
1041 | + |
1042 | + public void seek_jump_seconds (int seconds) { |
1043 | + var duration = playback.duration; |
1044 | + var progress = playback.progress; |
1045 | + var new_progress = ((duration * progress) + (double)seconds)/duration; |
1046 | + playback.progress = double.min (new_progress, 1.0); |
1047 | } |
1048 | |
1049 | private Widgets.Playlist get_playlist_widget () { |
1050 | @@ -324,7 +338,7 @@ |
1051 | return null; |
1052 | } |
1053 | |
1054 | - public static bool is_subtitle (string uri) { |
1055 | + private bool is_subtitle (string uri) { |
1056 | if (uri.length < 4 || uri.get_char (uri.length-4) != '.') |
1057 | return false; |
1058 | |
1059 | @@ -344,174 +358,42 @@ |
1060 | return false; |
1061 | } |
1062 | |
1063 | - private void get_target_size (out int target_width, out int target_height, |
1064 | - out int center_x, out int center_y) { |
1065 | - Gdk.Rectangle monitor; |
1066 | - var screen = Gdk.Screen.get_default (); |
1067 | - screen.get_monitor_geometry (screen.get_monitor_at_window (get_window ()), |
1068 | - out monitor); |
1069 | - |
1070 | - if (monitor.width > video_player.video_width |
1071 | - && monitor.height > video_player.video_height) { |
1072 | - target_width = (int) video_player.video_width; |
1073 | - target_height = (int) video_player.video_height; |
1074 | - } else { |
1075 | - target_width = (int)(monitor.width * 0.9); |
1076 | - target_height = (int)((double) video_player.video_height / video_player.video_width * target_width); |
1077 | - } |
1078 | - center_x = monitor.width / 2 - target_width /2 + monitor.x; |
1079 | - center_y = monitor.height / 2 - target_height /2 + monitor.y; |
1080 | - } |
1081 | - |
1082 | - private bool on_key_press_event (Gdk.EventKey e) { |
1083 | - switch (e.keyval) { |
1084 | - case Gdk.Key.p: |
1085 | - case Gdk.Key.space: |
1086 | - video_player.playing = !video_player.playing; |
1087 | - break; |
1088 | - case Gdk.Key.Escape: |
1089 | - if (fullscreened) { |
1090 | - set_fullscreen (false); |
1091 | - } else { |
1092 | - App.get_instance ().mainwindow.destroy (); |
1093 | - } |
1094 | - return true; |
1095 | - case Gdk.Key.Down: |
1096 | - if (modifier_is_pressed (e, Gdk.ModifierType.SHIFT_MASK)) { |
1097 | - video_player.seek_jump_seconds (-5); // 5 secs |
1098 | - } else { |
1099 | - video_player.seek_jump_seconds (-60); // 1 min |
1100 | - } |
1101 | - bottom_bar.reveal_control (); |
1102 | - break; |
1103 | - case Gdk.Key.Left: |
1104 | - if (modifier_is_pressed (e, Gdk.ModifierType.SHIFT_MASK)) { |
1105 | - video_player.seek_jump_seconds (-1); // 1 sec |
1106 | - } else { |
1107 | - video_player.seek_jump_seconds (-10); // 10 secs |
1108 | - } |
1109 | - bottom_bar.reveal_control (); |
1110 | - break; |
1111 | - case Gdk.Key.Right: |
1112 | - if (modifier_is_pressed (e, Gdk.ModifierType.SHIFT_MASK)) { |
1113 | - video_player.seek_jump_seconds (1); // 1 sec |
1114 | - } else { |
1115 | - video_player.seek_jump_seconds (10); // 10 secs |
1116 | - } |
1117 | - bottom_bar.reveal_control (); |
1118 | - break; |
1119 | - case Gdk.Key.Up: |
1120 | - if (modifier_is_pressed (e, Gdk.ModifierType.SHIFT_MASK)) { |
1121 | - video_player.seek_jump_seconds (5); // 5 secs |
1122 | - } else { |
1123 | - video_player.seek_jump_seconds (60); // 1 min |
1124 | - } |
1125 | - bottom_bar.reveal_control (); |
1126 | - break; |
1127 | - case Gdk.Key.Page_Down: |
1128 | - video_player.seek_jump_seconds (-600); // 10 mins |
1129 | - bottom_bar.reveal_control (); |
1130 | - break; |
1131 | - case Gdk.Key.Page_Up: |
1132 | - video_player.seek_jump_seconds (600); // 10 mins |
1133 | - bottom_bar.reveal_control (); |
1134 | - break; |
1135 | - case Gdk.Key.a: |
1136 | - bottom_bar.preferences_popover.next_audio (); |
1137 | - break; |
1138 | - case Gdk.Key.s: |
1139 | - bottom_bar.preferences_popover.next_text (); |
1140 | - break; |
1141 | - case Gdk.Key.f: |
1142 | - if (fullscreened) |
1143 | - set_fullscreen (false); |
1144 | - else |
1145 | - set_fullscreen (true); |
1146 | - |
1147 | - break; |
1148 | - default: |
1149 | - break; |
1150 | - } |
1151 | - |
1152 | - return false; |
1153 | - } |
1154 | - |
1155 | - private bool on_window_state_event (Gdk.EventWindowState e){ |
1156 | - switch (e.changed_mask){ |
1157 | - case Gdk.WindowState.FULLSCREEN: |
1158 | - fullscreened= ((e.new_window_state & Gdk.WindowState.FULLSCREEN)!=0); |
1159 | - break; |
1160 | - case Gdk.WindowState.MAXIMIZED: |
1161 | - bool currently_maximixed = ((e.new_window_state & Gdk.WindowState.MAXIMIZED)!=0); |
1162 | - set_fullscreen (currently_maximixed); |
1163 | - break; |
1164 | - } |
1165 | - return false; |
1166 | - } |
1167 | - |
1168 | - private void set_fullscreen (bool full){ |
1169 | - fullscreened = full; |
1170 | - if (full) { |
1171 | - App.get_instance ().mainwindow.fullscreen (); |
1172 | - } else { |
1173 | - // unfullscreen shoulnd't be call from elsewhere other than here |
1174 | - App.get_instance ().mainwindow.maximize (); |
1175 | - App.get_instance ().mainwindow.unfullscreen (); |
1176 | - } |
1177 | - bottom_bar.fullscreen = full; |
1178 | - } |
1179 | - |
1180 | - private uint update_aspect_ratio_timeout = 0; |
1181 | - private bool update_aspect_ratio_locked = false; |
1182 | - private int prev_width = 0; |
1183 | - private int prev_height = 0; |
1184 | - private int old_h = -1; |
1185 | - private int old_w = -1; |
1186 | - /** |
1187 | - * Updates the window's aspect ratio locking if enabled. |
1188 | - * Return type is just there to make it compatible with Idle.add() |
1189 | - */ |
1190 | - private bool update_aspect_ratio () { |
1191 | - if (!settings.keep_aspect |
1192 | - || video_player.video_width < 1 |
1193 | - || video_player.height < 1 |
1194 | - || !clutter.visible) |
1195 | - return false; |
1196 | - |
1197 | - if (update_aspect_ratio_timeout != 0) |
1198 | - Source.remove (update_aspect_ratio_timeout); |
1199 | - |
1200 | - update_aspect_ratio_timeout = Timeout.add (200, () => { |
1201 | - Gtk.Allocation a; |
1202 | - clutter.get_allocation (out a); |
1203 | - debug ("%i %i %i,%i\n", a.x, a.y, (this.get_allocated_width () - this.clutter.get_allocated_width ()) / 2, (this.get_allocated_height () - this.clutter.get_allocated_height ()) / 2); |
1204 | - |
1205 | - double width, height; |
1206 | - width = clutter.get_allocated_width (); |
1207 | - height = width * video_player.video_height / (double) video_player.video_width; |
1208 | - |
1209 | - App.get_instance ().set_content_size (width, height,clutter.get_allocated_height ()); |
1210 | - |
1211 | - prev_width = this.get_allocated_width (); |
1212 | - prev_height = this.get_allocated_height (); |
1213 | - |
1214 | - update_aspect_ratio_timeout = 0; |
1215 | - |
1216 | - return false; |
1217 | - }); |
1218 | - |
1219 | - return false; |
1220 | - } |
1221 | - private void on_size_allocate (Gtk.Allocation alloc) { |
1222 | - if (alloc.width != old_w || alloc.height != old_h) { |
1223 | - if (video_player.relayout ()) { |
1224 | - old_w = alloc.width; |
1225 | - old_h = alloc.height; |
1226 | - } |
1227 | - } |
1228 | - |
1229 | - if (prev_width != this.get_allocated_width () || prev_height != this.get_allocated_height ()) |
1230 | - Idle.add (update_aspect_ratio); |
1231 | + [CCode (instance_pos = -1)] |
1232 | + private bool navigation_event (GtkClutter.Embed embed, Clutter.Event event) { |
1233 | + var video_sink = playback.get_video_sink (); |
1234 | + var frame = video_sink.get_frame (); |
1235 | + |
1236 | + if (frame == null) |
1237 | + return true; |
1238 | + |
1239 | + float x, y; |
1240 | + event.get_coords (out x, out y); |
1241 | + // Transform event coordinates into the actor's coordinates |
1242 | + video_actor.transform_stage_point (x, y, out x, out y); |
1243 | + float actor_width, actor_height; |
1244 | + video_actor.get_size (out actor_width, out actor_height); |
1245 | + |
1246 | + /* Convert event's coordinates into the frame's coordinates. */ |
1247 | + x = x * frame.resolution.width / actor_width; |
1248 | + y = y * frame.resolution.height / actor_height; |
1249 | + |
1250 | + switch (event.type) { |
1251 | + case Clutter.EventType.MOTION: |
1252 | + ((Gst.Video.Navigation) video_sink).send_mouse_event ("mouse-move", 0, x, y); |
1253 | + break; |
1254 | + case Clutter.EventType.BUTTON_PRESS: |
1255 | + ((Gst.Video.Navigation) video_sink).send_mouse_event ("mouse-button-press", (int)event.button.button, x, y); |
1256 | + break; |
1257 | + case Clutter.EventType.KEY_PRESS: |
1258 | + warning (X.keysym_to_string (event.key.keyval)); |
1259 | + ((Gst.Video.Navigation) video_sink).send_key_event ("key-press", X.keysym_to_string (event.key.keyval)); |
1260 | + break; |
1261 | + case Clutter.EventType.KEY_RELEASE: |
1262 | + ((Gst.Video.Navigation) video_sink).send_key_event ("key-release", X.keysym_to_string (event.key.keyval)); |
1263 | + break; |
1264 | + } |
1265 | + |
1266 | + return false; |
1267 | } |
1268 | |
1269 | X.Display dpy; |
1270 | |
1271 | === modified file 'src/Widgets/Playlist.vala' |
1272 | --- src/Widgets/Playlist.vala 2015-10-26 18:28:19 +0000 |
1273 | +++ src/Widgets/Playlist.vala 2016-03-20 01:32:19 +0000 |
1274 | @@ -197,7 +197,7 @@ |
1275 | } |
1276 | |
1277 | public void save_playlist () { |
1278 | - if (Audience.App.get_instance ().is_privacy_mode_enabled ()) { |
1279 | + if (Audience.App.get_instance ().mainwindow.is_privacy_mode_enabled ()) { |
1280 | return; |
1281 | } |
1282 | |
1283 | |
1284 | === modified file 'src/Widgets/PlaylistPopover.vala' |
1285 | --- src/Widgets/PlaylistPopover.vala 2015-06-08 05:53:03 +0000 |
1286 | +++ src/Widgets/PlaylistPopover.vala 2016-03-20 01:32:19 +0000 |
1287 | @@ -35,8 +35,6 @@ |
1288 | fil.set_tooltip_text (_("Open file")); |
1289 | dvd = new Gtk.Button.from_icon_name ("media-optical-symbolic", Gtk.IconSize.BUTTON); |
1290 | dvd.set_tooltip_text (_("Play from Disc")); |
1291 | - dvd.no_show_all = true; |
1292 | - set_dvd_visibility (App.get_instance ().has_media_volumes ()); |
1293 | |
1294 | rep = new Gtk.ToggleButton (); |
1295 | rep.set_image (new Gtk.Image.from_icon_name ("media-playlist-no-repeat-symbolic", Gtk.IconSize.BUTTON)); |
1296 | @@ -45,19 +43,18 @@ |
1297 | playlist_scrolled = new Gtk.ScrolledWindow (null, null); |
1298 | playlist_scrolled.set_min_content_height (100); |
1299 | playlist_scrolled.set_min_content_width (260); |
1300 | - var app = ((Audience.App) GLib.Application.get_default ()); |
1301 | |
1302 | playlist = new Playlist (); |
1303 | playlist_scrolled.add (playlist); |
1304 | |
1305 | fil.clicked.connect ( () => { |
1306 | hide (); |
1307 | - app.run_open_file (); |
1308 | + App.get_instance ().mainwindow.run_open_file (); |
1309 | }); |
1310 | |
1311 | dvd.clicked.connect ( () => { |
1312 | hide (); |
1313 | - app.run_open_dvd (); |
1314 | + App.get_instance ().mainwindow.run_open_dvd (); |
1315 | }); |
1316 | |
1317 | rep.toggled.connect ( () => { |
1318 | @@ -78,19 +75,19 @@ |
1319 | |
1320 | add (grid); |
1321 | |
1322 | - App.get_instance ().media_volumes_changed.connect (on_media_volumes_changed); |
1323 | - } |
1324 | - |
1325 | - ~PlaylistPopover () { |
1326 | - App.get_instance ().media_volumes_changed.disconnect (on_media_volumes_changed); |
1327 | - } |
1328 | - |
1329 | - private void on_media_volumes_changed () { |
1330 | - set_dvd_visibility (App.get_instance ().has_media_volumes ()); |
1331 | + var disk_manager = DiskManager.get_default (); |
1332 | + set_dvd_visibility (disk_manager.has_media_volumes ()); |
1333 | + disk_manager.volume_found.connect ((vol) => { |
1334 | + set_dvd_visibility (disk_manager.has_media_volumes ()); |
1335 | + }); |
1336 | + |
1337 | + disk_manager.volume_removed.connect ((vol) => { |
1338 | + set_dvd_visibility (disk_manager.has_media_volumes ()); |
1339 | + }); |
1340 | } |
1341 | |
1342 | private void set_dvd_visibility (bool visible) { |
1343 | - dvd.no_show_all = true; |
1344 | + dvd.no_show_all = !visible; |
1345 | dvd.visible = visible; |
1346 | } |
1347 | |
1348 | |
1349 | === modified file 'src/Widgets/PreviewPopover.vala' |
1350 | --- src/Widgets/PreviewPopover.vala 2015-06-07 13:27:10 +0000 |
1351 | +++ src/Widgets/PreviewPopover.vala 2016-03-20 01:32:19 +0000 |
1352 | @@ -19,85 +19,79 @@ |
1353 | */ |
1354 | |
1355 | public class Audience.Widgets.PreviewPopover : Gtk.Popover { |
1356 | - public Clutter.Actor preview_actor; |
1357 | - dynamic Gst.Element preview_playbin; |
1358 | - Clutter.Texture video; |
1359 | - double ratio = 0; |
1360 | + private enum PlayFlags { |
1361 | + VIDEO = (1 << 0), |
1362 | + AUDIO = (1 << 1), |
1363 | + TEXT = (1 << 2), |
1364 | + VIS = (1 << 3), |
1365 | + SOFT_VOLUME = (1 << 4), |
1366 | + NATIVE_AUDIO = (1 << 5), |
1367 | + NATIVE_VIDEO = (1 << 6), |
1368 | + DOWNLOAD = (1 << 7), |
1369 | + BUFFERING = (1 << 8), |
1370 | + DEINTERLACE = (1 << 9), |
1371 | + SOFT_COLORBALANCE = (1 << 10) |
1372 | + } |
1373 | + |
1374 | + ClutterGst.Playback playback; |
1375 | + GtkClutter.Embed clutter; |
1376 | uint? timer_id = null; |
1377 | - public PreviewPopover () { |
1378 | + |
1379 | + public PreviewPopover (ClutterGst.Playback main_playback) { |
1380 | opacity = GLOBAL_OPACITY; |
1381 | can_focus = false; |
1382 | sensitive = false; |
1383 | modal = false; |
1384 | |
1385 | - // connect gstreamer stuff |
1386 | - preview_playbin = Gst.ElementFactory.make ("playbin", "play"); |
1387 | - preview_playbin.get_bus ().add_signal_watch (); |
1388 | - preview_playbin.get_bus ().message.connect ((msg) => { |
1389 | - switch (msg.type) { |
1390 | - case Gst.MessageType.STATE_CHANGED: |
1391 | - break; |
1392 | - case Gst.MessageType.ASYNC_DONE: |
1393 | - break; |
1394 | - } |
1395 | + playback = new ClutterGst.Playback (); |
1396 | + playback.ready.connect (() => { |
1397 | + unowned Gst.Element pipeline = playback.get_pipeline (); |
1398 | + int flags; |
1399 | + pipeline.get ("flags", out flags); |
1400 | + flags &= ~PlayFlags.TEXT; //disable subtitle |
1401 | + flags &= ~PlayFlags.AUDIO; //disable audio sink |
1402 | + pipeline.set ("flags", flags); |
1403 | }); |
1404 | - video = new Clutter.Texture (); |
1405 | |
1406 | - dynamic Gst.Element video_sink = Gst.ElementFactory.make ("cluttersink", "source"); |
1407 | - video_sink.texture = video; |
1408 | - preview_playbin.video_sink = video_sink; |
1409 | - var clutter = new GtkClutter.Embed (); |
1410 | - clutter.margin = 6; |
1411 | + playback.set_seek_flags (ClutterGst.SeekFlags.ACCURATE); |
1412 | + playback.uri = main_playback.uri; |
1413 | + playback.playing = false; |
1414 | + clutter = new GtkClutter.Embed (); |
1415 | + clutter.margin = 3; |
1416 | var stage = (Clutter.Stage)clutter.get_stage (); |
1417 | stage.background_color = {0, 0, 0, 0}; |
1418 | - stage.use_alpha = true; |
1419 | - |
1420 | - video.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.WIDTH, 0)); |
1421 | - video.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.HEIGHT, 0)); |
1422 | - |
1423 | - stage.add_child (video); |
1424 | + |
1425 | + var video_actor = new Clutter.Actor (); |
1426 | + var aspect_ratio = ClutterGst.Aspectratio.@new (); |
1427 | + ((ClutterGst.Aspectratio) aspect_ratio).paint_borders = false; |
1428 | + ((ClutterGst.Content) aspect_ratio).player = playback; |
1429 | + video_actor.content = aspect_ratio; |
1430 | + ((ClutterGst.Content) aspect_ratio).size_change.connect ((width, height) => { |
1431 | + clutter.set_size_request (200, (int)(((double) (height*200))/((double) width))); |
1432 | + }); |
1433 | + |
1434 | + video_actor.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.WIDTH, 0)); |
1435 | + video_actor.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.HEIGHT, 0)); |
1436 | + |
1437 | + stage.add_child (video_actor); |
1438 | add (clutter); |
1439 | - //show_all (); |
1440 | + |
1441 | closed.connect (() => { |
1442 | - preview_playbin.set_state (Gst.State.PAUSED); |
1443 | + playback.playing = false; |
1444 | cancel_loop_timer (); |
1445 | }); |
1446 | } |
1447 | + |
1448 | ~PreviewPopover () { |
1449 | - preview_playbin.set_state (Gst.State.NULL); |
1450 | - } |
1451 | - |
1452 | - public void set_preview_uri (string uri) { |
1453 | - preview_playbin.set_state (Gst.State.READY); |
1454 | - preview_playbin.uri = uri; |
1455 | - int flags; |
1456 | - preview_playbin.get ("flags", out flags); |
1457 | - flags &= ~PlayFlags.TEXT; //disable subtitle |
1458 | - flags &= ~PlayFlags.AUDIO; //disable audio sink |
1459 | - preview_playbin.set ("flags", flags); |
1460 | - |
1461 | - try { |
1462 | - var info = new Gst.PbUtils.Discoverer (10 * Gst.SECOND).discover_uri (uri); |
1463 | - var video = info.get_video_streams (); |
1464 | - if (video != null && video.data != null) { |
1465 | - var video_info = (Gst.PbUtils.DiscovererVideoInfo)video.data; |
1466 | - uint video_width = video_info.get_width (); |
1467 | - uint video_height = video_info.get_height (); |
1468 | - ratio = ((double) video_height) / ((double) video_width); |
1469 | - set_size_request (200, (int) (ratio*200)); |
1470 | - } |
1471 | - } catch (Error e) { |
1472 | - warning (e.message); |
1473 | - return; |
1474 | - } |
1475 | + playback.playing = false; |
1476 | + cancel_loop_timer (); |
1477 | } |
1478 | |
1479 | public void set_preview_progress (double progress) { |
1480 | cancel_loop_timer (); |
1481 | - int64 length; |
1482 | - preview_playbin.query_duration (Gst.Format.TIME, out length); |
1483 | - preview_playbin.seek_simple (Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE, (int64)(double.max (progress, 0.0) * length)); |
1484 | - preview_playbin.set_state (Gst.State.PLAYING); |
1485 | + playback.progress = progress; |
1486 | + playback.playing = true; |
1487 | + |
1488 | timer_id = Timeout.add_seconds (5, () => { |
1489 | set_preview_progress (progress); |
1490 | return false; |
1491 | |
1492 | === modified file 'src/Widgets/SettingsPopover.vala' |
1493 | --- src/Widgets/SettingsPopover.vala 2015-06-14 07:02:09 +0000 |
1494 | +++ src/Widgets/SettingsPopover.vala 2016-03-20 01:32:19 +0000 |
1495 | @@ -22,14 +22,14 @@ |
1496 | private Gtk.ComboBoxText languages; |
1497 | private Gtk.ComboBoxText subtitles; |
1498 | private Gtk.FileChooserButton external_subtitle_file; |
1499 | - private Widgets.VideoPlayer player; |
1500 | + private ClutterGst.Playback playback; |
1501 | |
1502 | - public SettingsPopover (Widgets.VideoPlayer player) { |
1503 | + public SettingsPopover (ClutterGst.Playback playback) { |
1504 | + this.playback = playback; |
1505 | opacity = GLOBAL_OPACITY; |
1506 | |
1507 | languages = new Gtk.ComboBoxText (); |
1508 | subtitles = new Gtk.ComboBoxText (); |
1509 | - this.player = player; |
1510 | |
1511 | var all_files_filter = new Gtk.FileFilter (); |
1512 | all_files_filter.set_filter_name (_("All files")); |
1513 | @@ -68,118 +68,84 @@ |
1514 | setupgrid.column_spacing = 12; |
1515 | |
1516 | external_subtitle_file.file_set.connect (() => { |
1517 | - player.set_subtitle_uri (external_subtitle_file.get_uri ()); |
1518 | + playback.set_subtitle_uri (external_subtitle_file.get_uri ()); |
1519 | }); |
1520 | |
1521 | - player.external_subtitle_changed.connect ((uri) => { |
1522 | - external_subtitle_file.select_uri (uri); |
1523 | + playback.notify["subtitle_uri"].connect (() => { |
1524 | + external_subtitle_file.select_uri (playback.subtitle_uri); |
1525 | }); |
1526 | |
1527 | subtitles.changed.connect (() => { |
1528 | - if (subtitles.active_id == null) |
1529 | - return; |
1530 | - |
1531 | - var id = int.parse (subtitles.active_id); |
1532 | - player.current_text = id; |
1533 | + if (subtitles.active <= -1) |
1534 | + return; |
1535 | + |
1536 | + if (subtitles.active_id == "none") { |
1537 | + playback.subtitle_track = -1; |
1538 | + return; |
1539 | + } |
1540 | + |
1541 | + playback.subtitle_track = subtitles.active; |
1542 | }); |
1543 | |
1544 | languages.changed.connect ( () => { //place it here to not get problems |
1545 | - if (languages.active_id == null) |
1546 | + if (languages.active <= -1 || languages.active_id == "def") |
1547 | return; |
1548 | |
1549 | - player.current_audio = int.parse (languages.active_id); |
1550 | + playback.audio_stream = languages.active; |
1551 | }); |
1552 | |
1553 | add (setupgrid); |
1554 | } |
1555 | |
1556 | public void setup_text () { |
1557 | - subtitles.sensitive = false; |
1558 | if (subtitles.model.iter_n_children (null) > 0) |
1559 | subtitles.remove_all (); |
1560 | |
1561 | - int n_text; |
1562 | - player.playbin.get ("n-text", out n_text); |
1563 | - for (var i=0; i<n_text; i++) { |
1564 | - Gst.TagList tags = null; |
1565 | - Signal.emit_by_name (player.playbin, "get-text-tags", i, out tags); |
1566 | - if (tags == null) |
1567 | - continue; |
1568 | - |
1569 | - string desc; |
1570 | - string readable = null; |
1571 | - tags.get_string (Gst.Tags.LANGUAGE_CODE, out desc); |
1572 | - if (desc == null) |
1573 | - tags.get_string (Gst.Tags.CODEC, out desc); |
1574 | - |
1575 | - if (desc != null) { |
1576 | - readable = Gst.Tag.get_language_name (desc); |
1577 | - var language = Gst.Tag.get_language_name (desc); |
1578 | - subtitles.append (i.to_string (), language == null ? desc : language); |
1579 | - subtitles.sensitive = true; |
1580 | - } |
1581 | - } |
1582 | - |
1583 | - subtitles.append ("-1", _("None")); |
1584 | - subtitles.active_id = player.current_text.to_string (); |
1585 | + playback.get_subtitle_tracks ().foreach ((lang) => { |
1586 | + subtitles.append (lang, lang); |
1587 | + }); |
1588 | + |
1589 | + subtitles.append ("none", _("None")); |
1590 | + subtitles.active = playback.subtitle_track; |
1591 | + subtitles.sensitive = subtitles.model.iter_n_children (null) > 1; |
1592 | } |
1593 | |
1594 | public void setup_audio () { |
1595 | - languages.sensitive = false; |
1596 | if (languages.model.iter_n_children (null) > 0) |
1597 | languages.remove_all (); |
1598 | |
1599 | - int n_audio; |
1600 | - player.playbin.get ("n-audio", out n_audio); |
1601 | - for (var i=0; i<n_audio; i++) { |
1602 | - Gst.TagList tags = null; |
1603 | - Signal.emit_by_name (player.playbin, "get-audio-tags", i, out tags); |
1604 | - if (tags == null) |
1605 | - continue; |
1606 | - |
1607 | - string desc; |
1608 | - string readable = null; |
1609 | - tags.get_string (Gst.Tags.LANGUAGE_CODE, out desc); |
1610 | - if (desc == null) |
1611 | - tags.get_string (Gst.Tags.CODEC, out desc); |
1612 | - |
1613 | - if (desc != null) { |
1614 | - readable = Gst.Tag.get_language_name (desc); |
1615 | - languages.append (i.to_string (), readable == null ? desc : readable); |
1616 | - } |
1617 | - } |
1618 | - |
1619 | - var audio_items = languages.model.iter_n_children (null); |
1620 | - if (audio_items <= 0) { |
1621 | + playback.get_audio_streams ().foreach ((lang) => { |
1622 | + languages.append (lang, lang); |
1623 | + }); |
1624 | + |
1625 | + languages.sensitive = languages.model.iter_n_children (null) > 0; |
1626 | + if (!languages.sensitive) { |
1627 | languages.append ("def", _("Default")); |
1628 | languages.active = 0; |
1629 | } else { |
1630 | - if (audio_items != 1) |
1631 | - languages.sensitive = true; |
1632 | - |
1633 | - languages.active_id = player.current_audio.to_string (); |
1634 | + languages.active = playback.subtitle_track; |
1635 | } |
1636 | } |
1637 | |
1638 | public void next_audio () { |
1639 | - int current = int.parse (languages.active_id); |
1640 | + int current = languages.active; |
1641 | if (current < languages.model.iter_n_children (null) - 1) { |
1642 | current++; |
1643 | } else { |
1644 | current = 0; |
1645 | } |
1646 | |
1647 | - languages.active_id = current.to_string (); |
1648 | + languages.active = current; |
1649 | } |
1650 | |
1651 | public void next_text () { |
1652 | - int current = int.parse (subtitles.active_id); |
1653 | + int current = subtitles.active; |
1654 | if (current < subtitles.model.iter_n_children (null)) { |
1655 | current++; |
1656 | } else { |
1657 | current = 0; |
1658 | } |
1659 | |
1660 | - subtitles.active_id = current.to_string (); |
1661 | + subtitles.active = current; |
1662 | } |
1663 | } |
1664 | |
1665 | === modified file 'src/Widgets/TimeWidget.vala' |
1666 | --- src/Widgets/TimeWidget.vala 2014-11-30 22:46:15 +0000 |
1667 | +++ src/Widgets/TimeWidget.vala 2016-03-20 01:32:19 +0000 |
1668 | @@ -20,25 +20,39 @@ |
1669 | */ |
1670 | |
1671 | public class Audience.Widgets.TimeWidget : Gtk.Grid { |
1672 | - public signal void slider_motion_event (Gdk.EventMotion event); |
1673 | - |
1674 | + unowned ClutterGst.Playback main_playback; |
1675 | public Gtk.Label progression_label; |
1676 | public Gtk.Label time_label; |
1677 | public Gtk.Scale scale; |
1678 | - public signal void seeked (double val); |
1679 | private Audience.Widgets.PreviewPopover preview_popover; |
1680 | - private bool is_seeking = false; |
1681 | private bool released = true; |
1682 | private uint timeout_id = 0; |
1683 | private int original = 0; |
1684 | |
1685 | - public TimeWidget () { |
1686 | + public TimeWidget (ClutterGst.Playback main_playback) { |
1687 | + this.main_playback = main_playback; |
1688 | orientation = Gtk.Orientation.HORIZONTAL; |
1689 | column_spacing = 12; |
1690 | halign = Gtk.Align.CENTER; |
1691 | progression_label = new Gtk.Label (""); |
1692 | time_label = new Gtk.Label (""); |
1693 | |
1694 | + main_playback.notify["progress"].connect (progress_callback); |
1695 | + |
1696 | + main_playback.notify["duration"].connect (() => { |
1697 | + if (preview_popover != null) { |
1698 | + preview_popover.destroy (); |
1699 | + } |
1700 | + time_label.label = seconds_to_time ((int) main_playback.duration); |
1701 | + progress_callback (); |
1702 | + // Don't allow to change the time if there is none. |
1703 | + sensitive = (main_playback.duration != 0); |
1704 | + if (sensitive) { |
1705 | + preview_popover = new Audience.Widgets.PreviewPopover (main_playback); |
1706 | + preview_popover.relative_to = this; |
1707 | + } |
1708 | + }); |
1709 | + |
1710 | scale = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL, 0, 1, 0.1); |
1711 | scale.expand = true; |
1712 | scale.draw_value = false; |
1713 | @@ -47,8 +61,8 @@ |
1714 | scale.events |= Gdk.EventMask.LEAVE_NOTIFY_MASK; |
1715 | scale.events |= Gdk.EventMask.ENTER_NOTIFY_MASK; |
1716 | scale.button_press_event.connect ((event) => { |
1717 | - is_seeking = true; |
1718 | released = false; |
1719 | + main_playback.notify["progress"].disconnect (progress_callback); |
1720 | |
1721 | if (timeout_id != 0) |
1722 | Source.remove (timeout_id); |
1723 | @@ -56,9 +70,8 @@ |
1724 | timeout_id = Timeout.add (300, () => { |
1725 | if (released == false) |
1726 | return true; |
1727 | - seeked (scale.get_value ()); |
1728 | - is_seeking = false; |
1729 | |
1730 | + main_playback.progress = scale.get_value (); |
1731 | timeout_id = 0; |
1732 | |
1733 | return false; |
1734 | @@ -68,12 +81,20 @@ |
1735 | }); |
1736 | |
1737 | scale.enter_notify_event.connect ((event) => { |
1738 | - preview_popover.show_all (); |
1739 | + if (event.detail != Gdk.NotifyType.INFERIOR && event.detail != Gdk.NotifyType.NONLINEAR) { |
1740 | + preview_popover.show_all (); |
1741 | + return false; |
1742 | + } |
1743 | + |
1744 | return false; |
1745 | }); |
1746 | |
1747 | scale.leave_notify_event.connect ((event) => { |
1748 | - preview_popover.hide (); |
1749 | + if (event.detail != Gdk.NotifyType.INFERIOR && event.detail != Gdk.NotifyType.NONLINEAR) { |
1750 | + preview_popover.hide (); |
1751 | + return false; |
1752 | + } |
1753 | + |
1754 | return false; |
1755 | }); |
1756 | |
1757 | @@ -87,25 +108,20 @@ |
1758 | pointing.x = (int)(event.x) - event.window.get_width ()/2 - distance/2; |
1759 | preview_popover.set_pointing_to ((Gdk.Rectangle)pointing); |
1760 | preview_popover.set_preview_progress (((double)event.x)/((double)event.window.get_width ())); |
1761 | - |
1762 | - slider_motion_event (event); |
1763 | - |
1764 | - return false; |
1765 | - }); |
1766 | - |
1767 | - scale.button_release_event.connect ((event) => {released = true; return false;}); |
1768 | - preview_popover = new Audience.Widgets.PreviewPopover (); |
1769 | - preview_popover.relative_to = this; |
1770 | + return false; |
1771 | + }); |
1772 | + |
1773 | + scale.button_release_event.connect ((event) => { |
1774 | + released = true; |
1775 | + main_playback.notify["progress"].connect (progress_callback); |
1776 | + return false; |
1777 | + }); |
1778 | |
1779 | add (progression_label); |
1780 | add (scale); |
1781 | add (time_label); |
1782 | } |
1783 | |
1784 | - public void set_preview_uri (string uri) { |
1785 | - preview_popover.set_preview_uri (uri); |
1786 | - } |
1787 | - |
1788 | public override void get_preferred_width (out int minimum_width, out int natural_width) { |
1789 | base.get_preferred_width (out minimum_width, out natural_width); |
1790 | |
1791 | @@ -117,11 +133,8 @@ |
1792 | } |
1793 | } |
1794 | |
1795 | - public void set_progression_time (double current_time, double total_time) { |
1796 | - if (is_seeking == true) |
1797 | - return; |
1798 | - scale.set_value (current_time/total_time); |
1799 | - progression_label.label = seconds_to_time ((int)(current_time / 1000000000)); |
1800 | - time_label.label = seconds_to_time ((int)((total_time - current_time) / 1000000000)); |
1801 | + private void progress_callback () { |
1802 | + scale.set_value (main_playback.progress); |
1803 | + progression_label.label = seconds_to_time ((int) (main_playback.duration * main_playback.progress)); |
1804 | } |
1805 | } |
1806 | |
1807 | === removed file 'src/Widgets/VideoPlayer.vala' |
1808 | --- src/Widgets/VideoPlayer.vala 2016-02-23 04:31:53 +0000 |
1809 | +++ src/Widgets/VideoPlayer.vala 1970-01-01 00:00:00 +0000 |
1810 | @@ -1,491 +0,0 @@ |
1811 | -// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- |
1812 | -/*- |
1813 | - * Copyright (c) 2013-2014 Audience Developers (http://launchpad.net/pantheon-chat) |
1814 | - * |
1815 | - * This program is free software: you can redistribute it and/or modify |
1816 | - * it under the terms of the GNU General Public License as published by |
1817 | - * the Free Software Foundation, either version 3 of the License, or |
1818 | - * (at your option) any later version. |
1819 | - |
1820 | - * This program is distributed in the hope that it will be useful, |
1821 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1822 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1823 | - * GNU General Public License for more details. |
1824 | - |
1825 | - * You should have received a copy of the GNU General Public License |
1826 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1827 | - * |
1828 | - * Authored by: Tom Beckmann <tomjonabc@gmail.com> |
1829 | - * Corentin Noël <corentin@elementaryos.org> |
1830 | - */ |
1831 | - |
1832 | -using Clutter; |
1833 | - |
1834 | -enum PlayFlags { |
1835 | - VIDEO = (1 << 0), |
1836 | - AUDIO = (1 << 1), |
1837 | - TEXT = (1 << 2), |
1838 | - VIS = (1 << 3), |
1839 | - SOFT_VOLUME = (1 << 4), |
1840 | - NATIVE_AUDIO = (1 << 5), |
1841 | - NATIVE_VIDEO = (1 << 6), |
1842 | - DOWNLOAD = (1 << 7), |
1843 | - BUFFERING = (1 << 8), |
1844 | - DEINTERLACE = (1 << 9), |
1845 | - SOFT_COLORBALANCE = (1 << 10) |
1846 | -} |
1847 | - |
1848 | -/* use internal function while |
1849 | - * https://bugzilla.gnome.org/show_bug.cgi?id=754567 |
1850 | - * isn't fixed |
1851 | - */ |
1852 | -[CCode (cprefix = "Gst", gir_namespace="GstVideo", gir_version="1.0", lower_case_cprefix="gst_video_", cheader_filename = "gst/video/video.h")] |
1853 | -namespace GstVideo { |
1854 | - [CCode (cheader_filename = "gst/video/video.h")] |
1855 | - public static extern bool calculate_display_ratio (out uint dar_n, out uint dar_d, uint video_width, uint video_height, uint video_par_n, uint video_par_d, uint display_par_n, uint display_par_d); |
1856 | -} |
1857 | - |
1858 | -namespace Audience.Widgets { |
1859 | - public class VideoPlayer : Actor { |
1860 | - |
1861 | - bool _playing; |
1862 | - public bool playing { |
1863 | - get { |
1864 | - return _playing; |
1865 | - } |
1866 | - set { |
1867 | - if (value == playing) |
1868 | - return; |
1869 | - |
1870 | - playbin.set_state (value ? Gst.State.PLAYING : Gst.State.PAUSED); |
1871 | - _playing = value; |
1872 | - } |
1873 | - } |
1874 | - |
1875 | - public double progress { |
1876 | - get { |
1877 | - int64 length, prog; |
1878 | - playbin.query_duration (Gst.Format.TIME, out length); |
1879 | - playbin.query_position (Gst.Format.TIME, out prog); |
1880 | - if (length == 0) |
1881 | - return 0; |
1882 | - |
1883 | - return prog / (double)length; |
1884 | - } |
1885 | - set { |
1886 | - int64 length; |
1887 | - playbin.query_duration (Gst.Format.TIME, out length); |
1888 | - playbin.seek_simple (Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE, (int64)(double.max (value, 0.0) * length)); |
1889 | - } |
1890 | - } |
1891 | - |
1892 | - public double volume { |
1893 | - get { |
1894 | - return playbin.volume; |
1895 | - } |
1896 | - set { |
1897 | - playbin.volume = value; |
1898 | - } |
1899 | - } |
1900 | - |
1901 | - public string uri { |
1902 | - owned get { |
1903 | - return playbin.current_uri; |
1904 | - } |
1905 | - set { |
1906 | - if (value == (string)playbin.uri) |
1907 | - return; |
1908 | - |
1909 | - playbin.get_bus ().set_flushing (true); |
1910 | - playing = false; |
1911 | - playbin.set_state (Gst.State.READY); |
1912 | - playbin.suburi = null; |
1913 | - subtitle_uri = null; |
1914 | - playbin.get_bus ().set_flushing (false); |
1915 | - playbin.uri = value; |
1916 | - volume = 1.0; |
1917 | - |
1918 | - relayout (); |
1919 | - playing = false; |
1920 | - |
1921 | - // this has to be done after setting uri playbin, if not codec checking will fail |
1922 | - try { |
1923 | - var info = new Gst.PbUtils.Discoverer (10 * Gst.SECOND).discover_uri (value); |
1924 | - var video = info.get_video_streams (); |
1925 | - if (video != null && video.data != null) { |
1926 | - var video_info = (Gst.PbUtils.DiscovererVideoInfo)video.data; |
1927 | - uint w, h; |
1928 | - get_media_size (video_info, out w, out h); |
1929 | - video_width = w; |
1930 | - video_height = h; |
1931 | - } |
1932 | - } catch (Error e) { |
1933 | - warning (e.message); |
1934 | - return; |
1935 | - } |
1936 | - } |
1937 | - } |
1938 | - |
1939 | - public int current_audio { |
1940 | - get { |
1941 | - return playbin.current_audio; |
1942 | - } |
1943 | - set { |
1944 | - playbin.current_audio = value; |
1945 | - } |
1946 | - } |
1947 | - |
1948 | - string? subtitle_uri = null; |
1949 | - |
1950 | - // currently used text stream. Set to -1 to disable subtitles |
1951 | - public int current_text { |
1952 | - get { |
1953 | - return playbin.current_text; |
1954 | - } |
1955 | - set { |
1956 | - if (value == current_text) |
1957 | - return; |
1958 | - |
1959 | - int flags; |
1960 | - playbin.get ("flags", out flags); |
1961 | - |
1962 | - var disable = value < 0; |
1963 | - if (disable) |
1964 | - playbin.current_text = -1; |
1965 | - |
1966 | - check_text_layer (!disable); |
1967 | - if (!disable) { |
1968 | - playbin.current_text = value; |
1969 | - } |
1970 | - } |
1971 | - } |
1972 | - |
1973 | - private string _subtitle_font; |
1974 | - public string subtitle_font { |
1975 | - get { |
1976 | - return _subtitle_font; |
1977 | - } |
1978 | - set { |
1979 | - _subtitle_font = value; |
1980 | - playbin.set ("subtitle-font-desc", _subtitle_font); |
1981 | - } |
1982 | - } |
1983 | - |
1984 | - public dynamic Gst.Element playbin; |
1985 | - Clutter.Texture video; |
1986 | - |
1987 | - public uint video_width { get; private set; } |
1988 | - public uint video_height { get; private set; } |
1989 | - |
1990 | - public signal void ended (); |
1991 | - public signal void toggle_side_pane (bool show); |
1992 | - public signal void text_tags_changed (); |
1993 | - public signal void audio_tags_changed (); |
1994 | - public signal void error (); |
1995 | - public signal void plugin_install_done (); |
1996 | - public signal void progression_changed (double current_time, double total_time); |
1997 | - public signal void external_subtitle_changed (string? uri); |
1998 | - |
1999 | - public VideoPlayer () { |
2000 | - video = new Clutter.Texture (); |
2001 | - playbin = Gst.ElementFactory.make ("playbin", "playbin"); |
2002 | - build (); |
2003 | - |
2004 | - playbin.text_tags_changed.connect ((el) => { |
2005 | - var structure = new Gst.Structure.empty ("tags-changed"); |
2006 | - structure.set_value ("type", "text"); |
2007 | - el.post_message (new Gst.Message.application (el, (owned) structure)); |
2008 | - }); |
2009 | - |
2010 | - playbin.audio_tags_changed.connect ((el) => { |
2011 | - var structure = new Gst.Structure.empty ("tags-changed"); |
2012 | - structure.set_value ("type", "audio"); |
2013 | - el.post_message (new Gst.Message.application (el, (owned) structure)); |
2014 | - }); |
2015 | - |
2016 | - Timeout.add (100, () => { |
2017 | - int64 length, prog; |
2018 | - playbin.query_position (Gst.Format.TIME, out prog); |
2019 | - playbin.query_duration (Gst.Format.TIME, out length); |
2020 | - if (length == 0) |
2021 | - return true; |
2022 | - |
2023 | - progression_changed ((double)prog, (double)length); |
2024 | - return true; |
2025 | - }); |
2026 | - |
2027 | - playbin.get_bus ().add_signal_watch (); |
2028 | - playbin.get_bus ().message.connect (watch); |
2029 | - } |
2030 | - |
2031 | - ~VideoPlayer () { |
2032 | - playbin.set_state (Gst.State.NULL); |
2033 | - playbin.get_bus ().message.disconnect (watch); |
2034 | - message ("video player destroyed"); |
2035 | - } |
2036 | - |
2037 | - public void build (){ |
2038 | - |
2039 | - if (video.get_parent ()!=null) |
2040 | - remove_child (video); |
2041 | - dynamic Gst.Element video_sink = Gst.ElementFactory.make ("cluttersink", "source"); |
2042 | - video_sink.texture = video; |
2043 | - playbin.video_sink = video_sink; |
2044 | - add_child(video); |
2045 | - update_subtitle_font (); |
2046 | - settings.changed.connect (() => { |
2047 | - update_subtitle_font (); |
2048 | - }); |
2049 | - } |
2050 | - |
2051 | - void watch (Gst.Message msg) { |
2052 | - |
2053 | - switch (msg.type) { |
2054 | - case Gst.MessageType.APPLICATION: |
2055 | - if (msg.get_structure ().get_name () == "tags-changed") { |
2056 | - if (msg.get_structure ().get_string ("type") == "text") |
2057 | - text_tags_changed (); |
2058 | - else |
2059 | - audio_tags_changed (); |
2060 | - } |
2061 | - break; |
2062 | - case Gst.MessageType.ERROR: |
2063 | - GLib.Error e; string detail; |
2064 | - msg.parse_error (out e, out detail); |
2065 | - playbin.set_state (Gst.State.NULL); |
2066 | - |
2067 | - warning (detail); |
2068 | - |
2069 | - show_error (e.message); |
2070 | - break; |
2071 | - case Gst.MessageType.EOS: |
2072 | - Idle.add (()=>{ |
2073 | - ended (); |
2074 | - return false; |
2075 | - }); |
2076 | - break; |
2077 | - case Gst.MessageType.ELEMENT: |
2078 | - if (msg.get_structure () == null) |
2079 | - break; |
2080 | - |
2081 | - if (Gst.PbUtils.is_missing_plugin_message (msg)) { |
2082 | - error (); |
2083 | - playbin.set_state (Gst.State.NULL); |
2084 | - |
2085 | - handle_missing_plugin (msg); |
2086 | - /*TODO } else { //may be navigation command |
2087 | - var nav_msg = Gst.Navigation.message_get_type (msg); |
2088 | - |
2089 | - if (nav_msg == Gst.NavigationMessageType.COMMANDS_CHANGED) { |
2090 | - var q = Gst.Navigation.query_new_commands (); |
2091 | - pipeline.query (q); |
2092 | - |
2093 | - uint n; |
2094 | - gst_navigation_query_parse_commands_length (q, out n); |
2095 | - for (var i=0;i<n;i++) { |
2096 | - Gst.NavigationCommand cmd; |
2097 | - gst_navigation_query_parse_commands_nth (q, 0, out cmd); |
2098 | - debug ("Got command: %i", (int)cmd); |
2099 | - } |
2100 | - }*/ |
2101 | - } |
2102 | - break; |
2103 | - default: |
2104 | - break; |
2105 | - } |
2106 | - } |
2107 | - |
2108 | - public void set_subtitle_uri (string? uri) { |
2109 | - subtitle_uri = uri; |
2110 | - if (!check_text_layer (subtitle_uri != null)) { |
2111 | - apply_subtitles (); |
2112 | - external_subtitle_changed (uri); |
2113 | - }; |
2114 | - } |
2115 | - |
2116 | - // checks whether text layer has to be enabled |
2117 | - // returns if apply_subtitles has been called |
2118 | - bool check_text_layer (bool enable) { |
2119 | - int flags; |
2120 | - playbin.get ("flags", out flags); |
2121 | - |
2122 | - if (!enable && (flags & PlayFlags.TEXT) > 0) { |
2123 | - flags &= ~PlayFlags.TEXT; |
2124 | - playbin.set ("flags", flags); |
2125 | - } else if (enable && (flags & PlayFlags.TEXT) < 1) { |
2126 | - flags |= PlayFlags.TEXT; |
2127 | - playbin.set ("flags", flags); |
2128 | - apply_subtitles (); |
2129 | - return true; |
2130 | - } |
2131 | - |
2132 | - return false; |
2133 | - } |
2134 | - |
2135 | - // ported from totem bvw widget set_subtitle_uri |
2136 | - void apply_subtitles () { |
2137 | - int64 time; |
2138 | - playbin.query_position (Gst.Format.TIME, out time); |
2139 | - |
2140 | - playbin.get_state (null, null, Gst.CLOCK_TIME_NONE); |
2141 | - |
2142 | - Gst.State current; |
2143 | - playbin.get_state (out current, null, Gst.CLOCK_TIME_NONE); |
2144 | - if (current > Gst.State.READY) { |
2145 | - playbin.set_state (Gst.State.READY); |
2146 | - playbin.get_state (null, null, Gst.CLOCK_TIME_NONE); |
2147 | - } |
2148 | - |
2149 | - playbin.suburi = subtitle_uri; |
2150 | - if (current > Gst.State.READY) { |
2151 | - playbin.set_state (current); |
2152 | - playbin.get_state (null, null, Gst.CLOCK_TIME_NONE); |
2153 | - } |
2154 | - |
2155 | - playbin.set_state (Gst.State.PAUSED); |
2156 | - playbin.seek (1.0, Gst.Format.TIME, |
2157 | - Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE, |
2158 | - Gst.SeekType.SET, time, |
2159 | - Gst.SeekType.NONE, (int64)Gst.CLOCK_TIME_NONE); |
2160 | - |
2161 | - if (current > Gst.State.READY) { |
2162 | - playbin.set_state (current); |
2163 | - playbin.get_state (null, null, Gst.CLOCK_TIME_NONE); |
2164 | - } |
2165 | - } |
2166 | - |
2167 | - public bool relayout () { |
2168 | - if (video_width < 1 || video_height < 1 || uri == null) |
2169 | - return false; |
2170 | - |
2171 | - var stage = get_stage (); |
2172 | - var aspect = stage.width / video_width < stage.height / video_height ? |
2173 | - stage.width / video_width : stage.height / video_height; |
2174 | - video.width = video_width * aspect; |
2175 | - video.height = video_height * aspect; |
2176 | - video.x = (stage.width - video.width) / 2; |
2177 | - video.y = (stage.height - video.height) / 2; |
2178 | - |
2179 | - return true; |
2180 | - } |
2181 | - |
2182 | - void show_error (string? message=null) { |
2183 | - var dlg = new Gtk.Dialog.with_buttons (_("Error"), null, Gtk.DialogFlags.MODAL, _("_OK"), Gtk.ResponseType.OK); |
2184 | - var grid = new Gtk.Grid (); |
2185 | - var err = new Gtk.Image.from_icon_name ("dialog-error", Gtk.IconSize.DIALOG); |
2186 | - err.margin_right = 12; |
2187 | - |
2188 | - var err_label = new Gtk.Label (""); |
2189 | - err_label.set_markup ("<b>%s</b>".printf (_("Oops! Audience can't play this file!"))); |
2190 | - |
2191 | - grid.margin = 12; |
2192 | - grid.attach (err, 0, 0, 1, 1); |
2193 | - grid.attach (err_label, 1, 0, 1, 1); |
2194 | - if (message != null) |
2195 | - grid.attach (new Gtk.Label (message), 1, 1, 1, 2); |
2196 | - |
2197 | - error (); |
2198 | - ((Gtk.Box)dlg.get_content_area ()).add (grid); |
2199 | - dlg.show_all (); |
2200 | - dlg.run (); |
2201 | - dlg.destroy (); |
2202 | - } |
2203 | - |
2204 | - void handle_missing_plugin (Gst.Message msg) { |
2205 | - var detail = Gst.PbUtils.missing_plugin_message_get_description (msg); |
2206 | - var dlg = new Gtk.Dialog.with_buttons ("Missing plugin", null, Gtk.DialogFlags.MODAL); |
2207 | - var grid = new Gtk.Grid (); |
2208 | - var err = new Gtk.Image.from_icon_name ("dialog-error", Gtk.IconSize.DIALOG); |
2209 | - var phrase = new Gtk.Label (_("Some media files need extra software to be played. Audience can install this software automatically.")); |
2210 | - |
2211 | - err.margin_right = 12; |
2212 | - |
2213 | - var err_label = new Gtk.Label (""); |
2214 | - err_label.set_markup ("<b>%s</b>".printf (_("Audience needs %s to play this file.").printf (detail))); |
2215 | - |
2216 | - grid.margin = 12; |
2217 | - grid.attach (err, 0, 0, 1, 1); |
2218 | - grid.attach (err_label, 1, 0, 1, 1); |
2219 | - grid.attach (phrase, 1, 1, 1, 2); |
2220 | - |
2221 | - dlg.add_button (_("Don't install"), 1); |
2222 | - dlg.add_button (_("Install")+" "+detail, 0); |
2223 | - |
2224 | - (dlg.get_content_area () as Gtk.Container).add (grid); |
2225 | - dlg.show_all (); |
2226 | - if (dlg.run () == 0) { |
2227 | - var installer = Gst.PbUtils.missing_plugin_message_get_installer_detail (msg); |
2228 | - var context = new Gst.PbUtils.InstallPluginsContext (); |
2229 | - Gst.PbUtils.install_plugins_async ({installer}, context, () => { //finished |
2230 | - debug ("Finished plugin install"); |
2231 | - Gst.update_registry (); |
2232 | - plugin_install_done (); |
2233 | - playing = true; |
2234 | - }); |
2235 | - } |
2236 | - |
2237 | - dlg.destroy (); |
2238 | - } |
2239 | - |
2240 | - public void seek_jump_seconds (int seconds) { |
2241 | - int64 position; |
2242 | - playbin.query_position (Gst.Format.TIME, out position); |
2243 | - |
2244 | - var gst_seconds = 1000000000 * (int64)seconds; |
2245 | - var new_position = position + gst_seconds; |
2246 | - |
2247 | - if (new_position < 0) { |
2248 | - playbin.seek_simple (Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE, int64.max (new_position, 1)); |
2249 | - return; |
2250 | - } |
2251 | - |
2252 | - playbin.seek_simple (Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE, new_position); |
2253 | - } |
2254 | - |
2255 | - |
2256 | - |
2257 | - private void get_media_size (Gst.PbUtils.DiscovererVideoInfo video_info, out uint video_width, out uint video_height) { |
2258 | - var video_w = video_info.get_width (); |
2259 | - var video_h = video_info.get_height (); |
2260 | - var video_par_n = video_info.get_par_num (); |
2261 | - var video_par_d = video_info.get_par_denom (); |
2262 | - if (video_par_n == 0 || video_par_d == 0) { |
2263 | - debug ("width and/or height 0, assumming 1/1"); |
2264 | - video_par_n = 1; |
2265 | - video_par_d = 1; |
2266 | - } |
2267 | - debug ("video PAR %u/%u", video_par_n, video_par_d); |
2268 | - |
2269 | - uint num; |
2270 | - uint den; |
2271 | - if (!GstVideo.calculate_display_ratio (out num, out den, video_w, video_h, video_par_n, video_par_d, 1, 1)) { |
2272 | - warning ("overflow calculating display ratio"); |
2273 | - num = 1; |
2274 | - den = 1; |
2275 | - } |
2276 | - debug ("calculated scale ratio %u / %u for %ux%u", num, den, video_w, video_h); |
2277 | - |
2278 | - if (video_w % num == 0) { |
2279 | - debug ("keeping video width"); |
2280 | - video_width = video_w; |
2281 | - video_height = (uint) Gst.Util.uint64_scale (video_w, den, num); |
2282 | - } else { |
2283 | - debug ("keeping video height"); |
2284 | - video_width = (uint) Gst.Util.uint64_scale (video_h, num, den); |
2285 | - video_height = video_h; |
2286 | - } |
2287 | - debug ("scaling to %ux%u", video_width, video_height); |
2288 | - } |
2289 | - |
2290 | - void update_subtitle_font () { |
2291 | - debug ("Updating subtitle font"); |
2292 | - var font = settings.subtitle_font; |
2293 | - |
2294 | - if (font == "") { |
2295 | - var gnome_settings = new GLib.Settings ("org.gnome.desktop.interface"); |
2296 | - font = gnome_settings.get_string ("font-name"); |
2297 | - } |
2298 | - subtitle_font = font; |
2299 | - } |
2300 | - } |
2301 | -} |
2302 | |
2303 | === modified file 'src/Widgets/WelcomePage.vala' |
2304 | --- src/Widgets/WelcomePage.vala 2015-06-15 08:29:35 +0000 |
2305 | +++ src/Widgets/WelcomePage.vala 2016-03-20 01:32:19 +0000 |
2306 | @@ -1,10 +1,12 @@ |
2307 | namespace Audience { |
2308 | public class WelcomePage : Granite.Widgets.Welcome { |
2309 | + private DiskManager disk_manager; |
2310 | public WelcomePage () { |
2311 | base (_("No Videos Open"), _("Select a source to begin playing.")); |
2312 | - this.append ("document-open", _("Open file"), _("Open a saved file.")); |
2313 | + } |
2314 | |
2315 | - this.set_size_request (350, 300); |
2316 | + construct { |
2317 | + append ("document-open", _("Open file"), _("Open a saved file.")); |
2318 | |
2319 | var filename = settings.current_video; |
2320 | var last_file = File.new_for_uri (filename); |
2321 | @@ -13,58 +15,42 @@ |
2322 | show_last_file = false; |
2323 | } |
2324 | |
2325 | - if (settings.last_stopped == 0.0 || !settings.resume_videos) |
2326 | - this.append ("media-playlist-repeat", _("Replay last video"), get_title (last_file.get_basename ())); |
2327 | - else |
2328 | - this.append ("media-playback-start", _("Resume last video"), get_title (last_file.get_basename ())); |
2329 | - this.set_item_visible (1, show_last_file); |
2330 | + if (settings.last_stopped == 0.0 || !settings.resume_videos) { |
2331 | + append ("media-playlist-repeat", _("Replay last video"), get_title (last_file.get_basename ())); |
2332 | + } else { |
2333 | + append ("media-playback-start", _("Resume last video"), get_title (last_file.get_basename ())); |
2334 | + } |
2335 | + |
2336 | + set_item_visible (1, show_last_file); |
2337 | |
2338 | //look for dvd |
2339 | - this.append ("media-cdrom", _("Play from Disc"), _("Watch a DVD or open a file from disc")); |
2340 | - this.set_item_visible (2, App.get_instance ().has_media_volumes ()); |
2341 | - App.get_instance ().media_volumes_changed.connect (() => { |
2342 | - this.set_item_visible (2, App.get_instance ().has_media_volumes ()); |
2343 | - }); |
2344 | - |
2345 | - //handle welcome |
2346 | - this.activated.connect (on_activate); |
2347 | - |
2348 | - App.get_instance ().set_window_title (App.get_instance ().program_name); |
2349 | - // FIXME : dont know why but cant move this to Audience.vala |
2350 | - App.get_instance ().mainwindow.set_default_size (960, 640); |
2351 | - |
2352 | - App.get_instance ().mainwindow.key_press_event.connect (on_key_press_event); |
2353 | - |
2354 | - } |
2355 | - ~WelcomePage () { |
2356 | - this.activated.disconnect (on_activate); |
2357 | - App.get_instance ().mainwindow.key_press_event.disconnect (on_key_press_event); |
2358 | - } |
2359 | - private void on_activate (int index) { |
2360 | - switch (index) { |
2361 | - case 0: |
2362 | - // Open file |
2363 | - App.get_instance ().run_open_file (); |
2364 | - break; |
2365 | - case 1: |
2366 | - App.get_instance ().resume_last_videos (); |
2367 | - break; |
2368 | - case 2: |
2369 | - App.get_instance ().run_open_dvd (); |
2370 | - break; |
2371 | - } |
2372 | - } |
2373 | - private bool on_key_press_event (Gdk.EventKey e) { |
2374 | - switch (e.keyval) { |
2375 | - case Gdk.Key.p: |
2376 | - case Gdk.Key.space: |
2377 | - App.get_instance ().resume_last_videos (); |
2378 | - break; |
2379 | - default: |
2380 | - break; |
2381 | - } |
2382 | - |
2383 | - return false; |
2384 | + disk_manager = DiskManager.get_default (); |
2385 | + disk_manager.volume_found.connect ((vol) => { |
2386 | + set_item_visible (2, disk_manager.has_media_volumes ()); |
2387 | + }); |
2388 | + |
2389 | + disk_manager.volume_removed.connect ((vol) => { |
2390 | + set_item_visible (2, disk_manager.has_media_volumes ()); |
2391 | + }); |
2392 | + |
2393 | + append ("media-cdrom", _("Play from Disc"), _("Watch a DVD or open a file from disc")); |
2394 | + set_item_visible (2, disk_manager.has_media_volumes ()); |
2395 | + |
2396 | + activated.connect ((index) => { |
2397 | + var window = App.get_instance ().mainwindow; |
2398 | + switch (index) { |
2399 | + case 0: |
2400 | + // Open file |
2401 | + window.run_open_file (); |
2402 | + break; |
2403 | + case 1: |
2404 | + window.resume_last_videos (); |
2405 | + break; |
2406 | + case 2: |
2407 | + window.run_open_dvd (); |
2408 | + break; |
2409 | + } |
2410 | + }); |
2411 | } |
2412 | } |
2413 | } |
2414 | |
2415 | === added file 'src/Window.vala' |
2416 | --- src/Window.vala 1970-01-01 00:00:00 +0000 |
2417 | +++ src/Window.vala 2016-03-20 01:32:19 +0000 |
2418 | @@ -0,0 +1,318 @@ |
2419 | +// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- |
2420 | +/*- |
2421 | + * Copyright (c) 2013-2016 elementary LLC. |
2422 | + * |
2423 | + * This program is free software: you can redistribute it and/or modify |
2424 | + * it under the terms of the GNU General Public License as published by |
2425 | + * the Free Software Foundation, either version 3 of the License, or |
2426 | + * (at your option) any later version. |
2427 | + |
2428 | + * This program is distributed in the hope that it will be useful, |
2429 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2430 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2431 | + * GNU General Public License for more details. |
2432 | + |
2433 | + * You should have received a copy of the GNU General Public License |
2434 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2435 | + * |
2436 | + * Authored by: Tom Beckmann <tomjonabc@gmail.com> |
2437 | + * Cody Garver <cody@elementaryos.org> |
2438 | + * Artem Anufrij <artem.anufrij@live.de> |
2439 | + * Corentin Noël <corentin@elementary.io> |
2440 | + */ |
2441 | + |
2442 | +public class Audience.Window : Gtk.Window { |
2443 | + private Gtk.Stack main_stack; |
2444 | + private Gtk.HeaderBar header; |
2445 | + private PlayerPage player_page; |
2446 | + private WelcomePage welcome_page; |
2447 | + private ZeitgeistManager zeitgeist_manager; |
2448 | + |
2449 | + public signal void media_volumes_changed (); |
2450 | + |
2451 | + public Window () { |
2452 | + |
2453 | + } |
2454 | + |
2455 | + construct { |
2456 | + zeitgeist_manager = new ZeitgeistManager (); |
2457 | + window_position = Gtk.WindowPosition.CENTER; |
2458 | + gravity = Gdk.Gravity.CENTER; |
2459 | + set_default_geometry (1000, 680); |
2460 | + |
2461 | + header = new Gtk.HeaderBar (); |
2462 | + header.set_show_close_button (true); |
2463 | + header.get_style_context ().add_class ("compact"); |
2464 | + set_titlebar (header); |
2465 | + |
2466 | + welcome_page = new WelcomePage (); |
2467 | + |
2468 | + player_page = new PlayerPage (); |
2469 | + player_page.ended.connect (on_player_ended); |
2470 | + player_page.unfullscreen_clicked.connect (() => { |
2471 | + unfullscreen (); |
2472 | + }); |
2473 | + |
2474 | + player_page.notify["playing"].connect (() => { |
2475 | + set_keep_above (player_page.playing && settings.stay_on_top); |
2476 | + }); |
2477 | + |
2478 | + main_stack = new Gtk.Stack (); |
2479 | + main_stack.add (welcome_page); |
2480 | + main_stack.add (player_page); |
2481 | + |
2482 | + add (main_stack); |
2483 | + show_all (); |
2484 | + main_stack.set_visible_child (welcome_page); |
2485 | + |
2486 | + Gtk.TargetEntry uris = {"text/uri-list", 0, 0}; |
2487 | + Gtk.drag_dest_set (this, Gtk.DestDefaults.ALL, {uris}, Gdk.DragAction.MOVE); |
2488 | + drag_data_received.connect ((ctx, x, y, sel, info, time) => { |
2489 | + File[] files = {}; |
2490 | + foreach (var uri in sel.get_uris ()) { |
2491 | + var file = File.new_for_uri (uri); |
2492 | + files += file; |
2493 | + } |
2494 | + |
2495 | + open_files (files); |
2496 | + }); |
2497 | + |
2498 | + player_page.button_press_event.connect ((event) => { |
2499 | + // double left click |
2500 | + if (event.button == Gdk.BUTTON_PRIMARY && event.type == Gdk.EventType.2BUTTON_PRESS) { |
2501 | + if (player_page.fullscreened) { |
2502 | + unfullscreen (); |
2503 | + } else { |
2504 | + fullscreen (); |
2505 | + } |
2506 | + } |
2507 | + |
2508 | + // right click |
2509 | + if (event.button == Gdk.BUTTON_SECONDARY) { |
2510 | + player_page.playing = !player_page.playing; |
2511 | + } |
2512 | + return false; |
2513 | + }); |
2514 | + } |
2515 | + |
2516 | + public override bool key_press_event (Gdk.EventKey e) { |
2517 | + switch (e.keyval) { |
2518 | + case Gdk.Key.o: |
2519 | + run_open_file (); |
2520 | + return true; |
2521 | + case Gdk.Key.p: |
2522 | + case Gdk.Key.space: |
2523 | + resume_last_videos (); |
2524 | + return true; |
2525 | + case Gdk.Key.q: |
2526 | + destroy (); |
2527 | + return true; |
2528 | + } |
2529 | + |
2530 | + if (main_stack.get_visible_child () == player_page) { |
2531 | + switch (e.keyval) { |
2532 | + case Gdk.Key.p: |
2533 | + case Gdk.Key.space: |
2534 | + player_page.playing = !player_page.playing; |
2535 | + break; |
2536 | + case Gdk.Key.Escape: |
2537 | + if (player_page.fullscreened) { |
2538 | + unfullscreen (); |
2539 | + } else { |
2540 | + destroy (); |
2541 | + } |
2542 | + |
2543 | + return true; |
2544 | + case Gdk.Key.Down: |
2545 | + if (Gdk.ModifierType.SHIFT_MASK in e.state) { |
2546 | + player_page.seek_jump_seconds (-5); // 5 secs |
2547 | + } else { |
2548 | + player_page.seek_jump_seconds (-60); // 1 min |
2549 | + } |
2550 | + |
2551 | + player_page.reveal_control (); |
2552 | + break; |
2553 | + case Gdk.Key.Left: |
2554 | + if (Gdk.ModifierType.SHIFT_MASK in e.state) { |
2555 | + player_page.seek_jump_seconds (-1); // 1 sec |
2556 | + } else { |
2557 | + player_page.seek_jump_seconds (-10); // 10 secs |
2558 | + } |
2559 | + |
2560 | + player_page.reveal_control (); |
2561 | + break; |
2562 | + case Gdk.Key.Right: |
2563 | + if (Gdk.ModifierType.SHIFT_MASK in e.state) { |
2564 | + player_page.seek_jump_seconds (1); // 1 sec |
2565 | + } else { |
2566 | + player_page.seek_jump_seconds (10); // 10 secs |
2567 | + } |
2568 | + |
2569 | + player_page.reveal_control (); |
2570 | + break; |
2571 | + case Gdk.Key.Up: |
2572 | + if (Gdk.ModifierType.SHIFT_MASK in e.state) { |
2573 | + player_page.seek_jump_seconds (5); // 5 secs |
2574 | + } else { |
2575 | + player_page.seek_jump_seconds (60); // 1 min |
2576 | + } |
2577 | + |
2578 | + player_page.reveal_control (); |
2579 | + break; |
2580 | + case Gdk.Key.Page_Down: |
2581 | + player_page.seek_jump_seconds (-600); // 10 mins |
2582 | + player_page.reveal_control (); |
2583 | + break; |
2584 | + case Gdk.Key.Page_Up: |
2585 | + player_page.seek_jump_seconds (600); // 10 mins |
2586 | + player_page.reveal_control (); |
2587 | + break; |
2588 | + case Gdk.Key.a: |
2589 | + player_page.next_audio (); |
2590 | + break; |
2591 | + case Gdk.Key.s: |
2592 | + player_page.next_text (); |
2593 | + break; |
2594 | + case Gdk.Key.f: |
2595 | + if (player_page.fullscreened) { |
2596 | + unfullscreen (); |
2597 | + } else { |
2598 | + fullscreen (); |
2599 | + } |
2600 | + |
2601 | + break; |
2602 | + default: |
2603 | + break; |
2604 | + } |
2605 | + } |
2606 | + |
2607 | + return false; |
2608 | + } |
2609 | + |
2610 | + public override bool window_state_event (Gdk.EventWindowState e) { |
2611 | + if (Gdk.WindowState.FULLSCREEN in e.changed_mask) { |
2612 | + player_page.fullscreened = Gdk.WindowState.FULLSCREEN in e.new_window_state; |
2613 | + header.visible = !player_page.fullscreened; |
2614 | + } |
2615 | + |
2616 | + if (Gdk.WindowState.MAXIMIZED in e.changed_mask) { |
2617 | + bool currently_maximixed = Gdk.WindowState.MAXIMIZED in e.new_window_state; |
2618 | + if (main_stack.get_visible_child () == player_page && currently_maximixed) { |
2619 | + fullscreen (); |
2620 | + } |
2621 | + } |
2622 | + |
2623 | + return false; |
2624 | + } |
2625 | + |
2626 | + public void open_files (File[] files) { |
2627 | + string[] videos = {}; |
2628 | + foreach (var file in files) { |
2629 | + if (file.query_file_type (0) == FileType.DIRECTORY) { |
2630 | + Audience.recurse_over_dir (file, (file_ret) => { |
2631 | + player_page.append_to_playlist (file); |
2632 | + videos += file_ret.get_uri (); |
2633 | + }); |
2634 | + } else { |
2635 | + player_page.append_to_playlist (file); |
2636 | + videos += file.get_uri (); |
2637 | + } |
2638 | + } |
2639 | + |
2640 | + |
2641 | + if (videos.length == 0) { |
2642 | + return; |
2643 | + } |
2644 | + |
2645 | + // notification when adding video to playlist |
2646 | + if (!player_page.playing && (Gdk.WindowState.FOCUSED in get_window ().get_state ())) { |
2647 | + var text = ngettext (_("%u Video added to Playlist"), _("%u Videos added to Playlist"), videos.length).printf (videos.length); |
2648 | + show_notification (text, (videos.length == 1) ? Audience.get_title (videos[0]) : ""); |
2649 | + } |
2650 | + |
2651 | + play_file (videos [0]); |
2652 | + } |
2653 | + |
2654 | + public void resume_last_videos () { |
2655 | + play_file (settings.current_video, false); |
2656 | + } |
2657 | + |
2658 | + public void run_open_dvd () { |
2659 | + read_first_disk.begin (); |
2660 | + } |
2661 | + |
2662 | + public void run_open_file () { |
2663 | + var file = new Gtk.FileChooserDialog (_("Open"), this, Gtk.FileChooserAction.OPEN, |
2664 | + _("_Cancel"), Gtk.ResponseType.CANCEL, _("_Open"), Gtk.ResponseType.ACCEPT); |
2665 | + file.set_transient_for (this); |
2666 | + file.select_multiple = true; |
2667 | + |
2668 | + var all_files_filter = new Gtk.FileFilter (); |
2669 | + all_files_filter.set_filter_name (_("All files")); |
2670 | + all_files_filter.add_pattern ("*"); |
2671 | + |
2672 | + var video_filter = new Gtk.FileFilter (); |
2673 | + video_filter.set_filter_name (_("Video files")); |
2674 | + video_filter.add_mime_type ("video/*"); |
2675 | + |
2676 | + file.add_filter (video_filter); |
2677 | + file.add_filter (all_files_filter); |
2678 | + |
2679 | + file.set_current_folder (settings.last_folder); |
2680 | + if (file.run () == Gtk.ResponseType.ACCEPT) { |
2681 | + File[] files = {}; |
2682 | + foreach (File item in file.get_files ()) { |
2683 | + files += item; |
2684 | + } |
2685 | + |
2686 | + open_files (files); |
2687 | + settings.last_folder = file.get_current_folder (); |
2688 | + } |
2689 | + |
2690 | + file.destroy (); |
2691 | + } |
2692 | + |
2693 | + public bool is_privacy_mode_enabled () { |
2694 | + var privacy_settings = new GLib.Settings ("org.gnome.desktop.privacy"); |
2695 | + bool privacy_mode = !privacy_settings.get_boolean ("remember-recent-files") || !privacy_settings.get_boolean ("remember-app-usage"); |
2696 | + |
2697 | + if (privacy_mode) { |
2698 | + return true; |
2699 | + } |
2700 | + |
2701 | + return zeitgeist_manager.app_into_blacklist (Audience.App.get_instance ().exec_name); |
2702 | + } |
2703 | + |
2704 | + private async void read_first_disk () { |
2705 | + var disk_manager = DiskManager.get_default (); |
2706 | + if (disk_manager.get_volumes ().is_empty) |
2707 | + return; |
2708 | + |
2709 | + var volume = disk_manager.get_volumes ().first (); |
2710 | + if (volume.can_mount () == true && volume.get_mount ().can_unmount () == false) { |
2711 | + try { |
2712 | + yield volume.mount (MountMountFlags.NONE, null); |
2713 | + } catch (Error e) { |
2714 | + critical (e.message); |
2715 | + } |
2716 | + } |
2717 | + |
2718 | + var root = volume.get_mount ().get_default_location (); |
2719 | + play_file (root.get_uri ().replace ("file:///", "dvd:///")); |
2720 | + } |
2721 | + |
2722 | + private void on_player_ended () { |
2723 | + main_stack.set_visible_child (welcome_page); |
2724 | + title = App.get_instance ().program_name; |
2725 | + get_window ().set_cursor (null); |
2726 | + unfullscreen (); |
2727 | + } |
2728 | + |
2729 | + private void play_file (string uri, bool from_beginning = true) { |
2730 | + main_stack.set_visible_child (player_page); |
2731 | + player_page.play_file (uri, from_beginning); |
2732 | + if (is_maximized) { |
2733 | + fullscreen (); |
2734 | + } |
2735 | + } |
2736 | +} |
The clutter embed is working as expected, but it appears that there are a lot of regressions here. Window resizing is broken, videos have vertical bars on both sides, and the cursor disappears when over the title bar.