1 | /* Video Player |
2 | * #Keywords: GtkVideo, GtkMediaStream, GtkMediaFile, GdkPaintable |
3 | * #Keywords: GtkMediaControls |
4 | * |
5 | * This is a simple video player using just GTK widgets. |
6 | */ |
7 | |
8 | #include <gtk/gtk.h> |
9 | |
10 | static GtkWidget *window = NULL; |
11 | |
12 | static void |
13 | open_dialog_response_cb (GtkNativeDialog *dialog, |
14 | int response, |
15 | GtkWidget *video) |
16 | { |
17 | gtk_native_dialog_hide (self: dialog); |
18 | |
19 | if (response == GTK_RESPONSE_ACCEPT) |
20 | { |
21 | GFile *file; |
22 | |
23 | file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); |
24 | gtk_video_set_file (self: GTK_VIDEO (ptr: video), file); |
25 | g_object_unref (object: file); |
26 | } |
27 | |
28 | gtk_native_dialog_destroy (self: dialog); |
29 | } |
30 | |
31 | static void |
32 | open_clicked_cb (GtkWidget *button, |
33 | GtkWidget *video) |
34 | { |
35 | GtkFileChooserNative *dialog; |
36 | GtkFileFilter *filter; |
37 | |
38 | dialog = gtk_file_chooser_native_new (title: "Select a video" , |
39 | GTK_WINDOW (gtk_widget_get_root (button)), |
40 | action: GTK_FILE_CHOOSER_ACTION_OPEN, |
41 | accept_label: "_Open" , |
42 | cancel_label: "_Cancel" ); |
43 | |
44 | filter = gtk_file_filter_new (); |
45 | gtk_file_filter_add_pattern (filter, pattern: "*" ); |
46 | gtk_file_filter_set_name (filter, name: "All Files" ); |
47 | gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); |
48 | g_object_unref (object: filter); |
49 | |
50 | filter = gtk_file_filter_new (); |
51 | gtk_file_filter_add_mime_type (filter, mime_type: "image/*" ); |
52 | gtk_file_filter_set_name (filter, name: "Images" ); |
53 | gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); |
54 | g_object_unref (object: filter); |
55 | |
56 | filter = gtk_file_filter_new (); |
57 | gtk_file_filter_add_mime_type (filter, mime_type: "video/*" ); |
58 | gtk_file_filter_set_name (filter, name: "Video" ); |
59 | gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); |
60 | |
61 | gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter); |
62 | g_object_unref (object: filter); |
63 | |
64 | gtk_native_dialog_set_modal (self: GTK_NATIVE_DIALOG (ptr: dialog), TRUE); |
65 | g_signal_connect (dialog, "response" , G_CALLBACK (open_dialog_response_cb), video); |
66 | gtk_native_dialog_show (self: GTK_NATIVE_DIALOG (ptr: dialog)); |
67 | } |
68 | |
69 | static void |
70 | logo_clicked_cb (GtkWidget *button, |
71 | gpointer video) |
72 | { |
73 | GFile *file; |
74 | |
75 | file = g_file_new_for_uri (uri: "resource:///images/gtk-logo.webm" ); |
76 | gtk_video_set_file (self: GTK_VIDEO (ptr: video), file); |
77 | g_object_unref (object: file); |
78 | } |
79 | |
80 | static void |
81 | bbb_clicked_cb (GtkWidget *button, |
82 | gpointer video) |
83 | { |
84 | GFile *file; |
85 | |
86 | file = g_file_new_for_uri (uri: "https://download.blender.org/peach/trailer/trailer_400p.ogg" ); |
87 | gtk_video_set_file (self: GTK_VIDEO (ptr: video), file); |
88 | g_object_unref (object: file); |
89 | } |
90 | |
91 | static void |
92 | fullscreen_clicked_cb (GtkWidget *button, |
93 | gpointer unused) |
94 | { |
95 | GtkWidget *widget_window = GTK_WIDGET (gtk_widget_get_root (button)); |
96 | |
97 | gtk_window_fullscreen (GTK_WINDOW (widget_window)); |
98 | } |
99 | |
100 | static gboolean |
101 | toggle_fullscreen (GtkWidget *widget, |
102 | GVariant *args, |
103 | gpointer data) |
104 | { |
105 | GdkSurface *surface; |
106 | GdkToplevelState state; |
107 | |
108 | surface = gtk_native_get_surface (self: GTK_NATIVE (ptr: widget)); |
109 | state = gdk_toplevel_get_state (toplevel: GDK_TOPLEVEL (ptr: surface)); |
110 | |
111 | if (state & GDK_TOPLEVEL_STATE_FULLSCREEN) |
112 | gtk_window_unfullscreen (GTK_WINDOW (widget)); |
113 | else |
114 | gtk_window_fullscreen (GTK_WINDOW (widget)); |
115 | |
116 | return TRUE; |
117 | } |
118 | |
119 | GtkWidget * |
120 | do_video_player (GtkWidget *do_widget) |
121 | { |
122 | GtkWidget *title; |
123 | GtkWidget *video; |
124 | GtkWidget *button; |
125 | GtkWidget *image; |
126 | GtkWidget *fullscreen_button; |
127 | GtkEventController *controller; |
128 | |
129 | if (!window) |
130 | { |
131 | window = gtk_window_new (); |
132 | gtk_window_set_display (GTK_WINDOW (window), |
133 | display: gtk_widget_get_display (widget: do_widget)); |
134 | gtk_window_set_title (GTK_WINDOW (window), title: "Video Player" ); |
135 | gtk_window_set_default_size (GTK_WINDOW (window), width: 600, height: 400); |
136 | g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window); |
137 | |
138 | video = gtk_video_new (); |
139 | gtk_video_set_autoplay (self: GTK_VIDEO (ptr: video), TRUE); |
140 | gtk_window_set_child (GTK_WINDOW (window), child: video); |
141 | |
142 | title = gtk_header_bar_new (); |
143 | gtk_window_set_titlebar (GTK_WINDOW (window), titlebar: title); |
144 | |
145 | button = gtk_button_new_with_mnemonic (label: "_Open" ); |
146 | g_signal_connect (button, "clicked" , G_CALLBACK (open_clicked_cb), video); |
147 | gtk_header_bar_pack_start (GTK_HEADER_BAR (title), child: button); |
148 | |
149 | button = gtk_button_new (); |
150 | image = gtk_image_new_from_resource (resource_path: "/cursors/images/gtk_logo_cursor.png" ); |
151 | gtk_image_set_pixel_size (GTK_IMAGE (image), pixel_size: 24); |
152 | gtk_button_set_child (GTK_BUTTON (button), child: image); |
153 | g_signal_connect (button, "clicked" , G_CALLBACK (logo_clicked_cb), video); |
154 | gtk_header_bar_pack_start (GTK_HEADER_BAR (title), child: button); |
155 | |
156 | button = gtk_button_new (); |
157 | image = gtk_image_new_from_resource (resource_path: "/video-player/bbb.png" ); |
158 | gtk_image_set_pixel_size (GTK_IMAGE (image), pixel_size: 24); |
159 | gtk_button_set_child (GTK_BUTTON (button), child: image); |
160 | g_signal_connect (button, "clicked" , G_CALLBACK (bbb_clicked_cb), video); |
161 | gtk_header_bar_pack_start (GTK_HEADER_BAR (title), child: button); |
162 | |
163 | fullscreen_button = gtk_button_new_from_icon_name (icon_name: "view-fullscreen-symbolic" ); |
164 | g_signal_connect (fullscreen_button, "clicked" , G_CALLBACK (fullscreen_clicked_cb), NULL); |
165 | gtk_header_bar_pack_end (GTK_HEADER_BAR (title), child: fullscreen_button); |
166 | |
167 | controller = gtk_shortcut_controller_new (); |
168 | gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller), |
169 | scope: GTK_SHORTCUT_SCOPE_GLOBAL); |
170 | gtk_widget_add_controller (widget: window, controller); |
171 | gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), |
172 | shortcut: gtk_shortcut_new (trigger: gtk_keyval_trigger_new (GDK_KEY_F11, modifiers: 0), |
173 | action: gtk_callback_action_new (callback: toggle_fullscreen, NULL, NULL))); |
174 | } |
175 | |
176 | if (!gtk_widget_get_visible (widget: window)) |
177 | gtk_widget_show (widget: window); |
178 | else |
179 | gtk_window_destroy (GTK_WINDOW (window)); |
180 | |
181 | return window; |
182 | } |
183 | |