Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-media-window"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <adwaita.h>
9 : : #include <glib/gi18n-lib.h>
10 : : #include <gtk/gtk.h>
11 : : #include <valent.h>
12 : :
13 : : #include "valent-media-remote.h"
14 : : #include "valent-mixer-remote.h"
15 : : #include "valent-ui-utils-private.h"
16 : :
17 : : #include "valent-media-window.h"
18 : :
19 : : struct _ValentMediaWindow
20 : : {
21 : : AdwWindow parent_instance;
22 : :
23 : : GListModel *mixers;
24 : : GListModel *players;
25 : :
26 : : /* template */
27 : : GtkDropDown *media_player;
28 : : GtkStack *media_stack;
29 : : GtkDropDown *mixer_adapter;
30 : : };
31 : :
32 [ + + + - ]: 37 : G_DEFINE_FINAL_TYPE (ValentMediaWindow, valent_media_window, ADW_TYPE_WINDOW)
33 : :
34 : : typedef enum {
35 : : PROP_MIXERS = 1,
36 : : PROP_PLAYERS,
37 : : } ValentMediaWindowProperty;
38 : :
39 : : static char *
40 : 6 : _valent_mixer_adapter_get_name (GtkListItem *item)
41 : : {
42 : 12 : g_autoptr (PeasPluginInfo) plugin_info = NULL;
43 : 6 : ValentExtension *extension = NULL;
44 : 6 : ValentObject *parent = NULL;
45 : :
46 : 6 : extension = gtk_list_item_get_item (item);
47 [ + + ]: 6 : if (extension == NULL)
48 : : return NULL;
49 : :
50 : 2 : g_object_get (extension, "plugin-info", &plugin_info, NULL);
51 [ + - ]: 2 : if (plugin_info != NULL)
52 [ - + ]: 4 : return g_strdup (peas_plugin_info_get_name (plugin_info));
53 : :
54 : 0 : parent = valent_object_get_parent (VALENT_OBJECT (extension));
55 [ # # ]: 0 : if (VALENT_IS_DEVICE (parent))
56 [ # # ]: 0 : return g_strdup (valent_device_get_name (VALENT_DEVICE (parent)));
57 : :
58 [ - - + + ]: 6 : return g_strdup (valent_object_get_iri (VALENT_OBJECT (extension)));
59 : : }
60 : :
61 : : static GParamSpec *properties[PROP_PLAYERS + 1] = { NULL, };
62 : :
63 : : static void
64 : 2 : on_player_selected (GtkDropDown *dropdown,
65 : : GParamSpec *pspec,
66 : : ValentMediaWindow *self)
67 : : {
68 : 2 : ValentMediaPlayer *player = NULL;
69 : 2 : ValentObject *player_parent = NULL;
70 : 2 : unsigned int n_items = 0;
71 : :
72 [ - + ]: 2 : g_assert (VALENT_IS_MEDIA_WINDOW (self));
73 : :
74 : 2 : player = gtk_drop_down_get_selected_item (self->media_player);
75 [ + + ]: 2 : if (player == NULL)
76 : : {
77 : 1 : gtk_widget_set_visible (GTK_WIDGET (self->media_player), FALSE);
78 : 1 : gtk_stack_set_visible_child_name (self->media_stack, "empty-state");
79 : 1 : return;
80 : : }
81 : :
82 : 1 : player_parent = valent_object_get_parent (VALENT_OBJECT (player));
83 [ + - ]: 1 : if (player_parent == NULL)
84 : : return;
85 : :
86 : 1 : n_items = g_list_model_get_n_items (self->mixers);
87 [ + - ]: 1 : for (unsigned int i = 0; i < n_items; i++)
88 : : {
89 : 0 : g_autoptr (ValentMixerAdapter) item = NULL;
90 : 1 : ValentObject *item_parent = NULL;
91 : :
92 : 1 : item = g_list_model_get_item (self->mixers, i);
93 : 1 : item_parent = valent_object_get_parent (VALENT_OBJECT (item));
94 [ - + ]: 1 : if (item_parent == player_parent)
95 : : {
96 : 0 : gtk_drop_down_set_selected (self->mixer_adapter, i);
97 : 0 : break;
98 : : }
99 : :
100 : : // TODO: this should only be reached for local players, whose direct
101 : : // source doesn't match the player. The hypothetical solution is
102 : : // `valent_object_get_ancestor (object, VALENT_TYPE_DATA_SOURCE)`
103 [ + - + - ]: 1 : if (!VALENT_IS_DEVICE (player_parent) && !VALENT_IS_DEVICE (item_parent))
104 : : {
105 : 1 : gtk_drop_down_set_selected (self->mixer_adapter, i);
106 : 1 : break;
107 : : }
108 : : }
109 : :
110 : 1 : gtk_widget_set_visible (GTK_WIDGET (self->media_player), TRUE);
111 : 1 : gtk_stack_set_visible_child_name (self->media_stack, "player");
112 : : }
113 : :
114 : : /*
115 : : * GObject
116 : : */
117 : : static void
118 : 1 : valent_media_window_finalize (GObject *object)
119 : : {
120 : 1 : ValentMediaWindow *self = VALENT_MEDIA_WINDOW (object);
121 : :
122 [ + - ]: 1 : g_clear_object (&self->mixers);
123 [ + - ]: 1 : g_clear_object (&self->players);
124 : :
125 : 1 : G_OBJECT_CLASS (valent_media_window_parent_class)->finalize (object);
126 : 1 : }
127 : :
128 : : static void
129 : 6 : valent_media_window_get_property (GObject *object,
130 : : guint prop_id,
131 : : GValue *value,
132 : : GParamSpec *pspec)
133 : : {
134 : 6 : ValentMediaWindow *self = VALENT_MEDIA_WINDOW (object);
135 : :
136 [ + + - ]: 6 : switch ((ValentMediaWindowProperty)prop_id)
137 : : {
138 : 3 : case PROP_MIXERS:
139 : 3 : g_value_set_object (value, self->mixers);
140 : 3 : break;
141 : :
142 : 3 : case PROP_PLAYERS:
143 : 3 : g_value_set_object (value, self->players);
144 : 3 : break;
145 : :
146 : 0 : default:
147 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
148 : : }
149 : 6 : }
150 : :
151 : : static void
152 : 2 : valent_media_window_set_property (GObject *object,
153 : : guint prop_id,
154 : : const GValue *value,
155 : : GParamSpec *pspec)
156 : : {
157 : 2 : ValentMediaWindow *self = VALENT_MEDIA_WINDOW (object);
158 : :
159 [ + + - ]: 2 : switch ((ValentMediaWindowProperty)prop_id)
160 : : {
161 : 1 : case PROP_MIXERS:
162 : 1 : self->mixers = g_value_dup_object (value);
163 : 1 : break;
164 : :
165 : 1 : case PROP_PLAYERS:
166 : 1 : self->players = g_value_dup_object (value);
167 : 1 : break;
168 : :
169 : 0 : default:
170 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
171 : : }
172 : 2 : }
173 : :
174 : : static void
175 : 1 : valent_media_window_class_init (ValentMediaWindowClass *klass)
176 : : {
177 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
178 : 1 : GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
179 : :
180 : 1 : object_class->finalize = valent_media_window_finalize;
181 : 1 : object_class->get_property = valent_media_window_get_property;
182 : 1 : object_class->set_property = valent_media_window_set_property;
183 : :
184 : 2 : properties [PROP_MIXERS] =
185 : 1 : g_param_spec_object ("mixers", NULL, NULL,
186 : : G_TYPE_LIST_MODEL,
187 : : (G_PARAM_READWRITE |
188 : : G_PARAM_CONSTRUCT_ONLY |
189 : : G_PARAM_STATIC_STRINGS));
190 : :
191 : 2 : properties [PROP_PLAYERS] =
192 : 1 : g_param_spec_object ("players", NULL, NULL,
193 : : G_TYPE_LIST_MODEL,
194 : : (G_PARAM_READWRITE |
195 : : G_PARAM_CONSTRUCT_ONLY |
196 : : G_PARAM_STATIC_STRINGS));
197 : :
198 : 1 : g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties);
199 : :
200 : 1 : gtk_widget_class_set_template_from_resource (widget_class, "/plugins/gnome/valent-media-window.ui");
201 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentMediaWindow, media_player);
202 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentMediaWindow, media_stack);
203 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentMediaWindow, mixer_adapter);
204 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_player_selected);
205 : 1 : gtk_widget_class_bind_template_callback (widget_class, _valent_mixer_adapter_get_name);
206 : 1 : }
207 : :
208 : : static void
209 : 1 : valent_media_window_init (ValentMediaWindow *self)
210 : : {
211 : 1 : gtk_widget_init_template (GTK_WIDGET (self));
212 : 1 : }
|