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 GParamSpec *properties[PROP_PLAYERS + 1] = { NULL, };
40 : :
41 : : static void
42 : 2 : on_player_selected (GtkDropDown *dropdown,
43 : : GParamSpec *pspec,
44 : : ValentMediaWindow *self)
45 : : {
46 : 2 : ValentMediaPlayer *player = NULL;
47 : 2 : ValentResource *player_source = NULL;
48 : 2 : unsigned int n_items = 0;
49 : :
50 [ + - ]: 2 : g_assert (VALENT_IS_MEDIA_WINDOW (self));
51 : :
52 : 2 : player = gtk_drop_down_get_selected_item (self->media_player);
53 [ + + ]: 2 : if (player == NULL)
54 : : {
55 : 1 : gtk_widget_set_visible (GTK_WIDGET (self->media_player), FALSE);
56 : 1 : gtk_stack_set_visible_child_name (self->media_stack, "empty-state");
57 : 1 : return;
58 : : }
59 : :
60 : 1 : player_source = valent_resource_get_source (VALENT_RESOURCE (player));
61 [ - + ]: 1 : if (player_source == NULL)
62 : : return;
63 : :
64 : 0 : n_items = g_list_model_get_n_items (self->mixers);
65 [ # # ]: 0 : for (unsigned int i = 0; i < n_items; i++)
66 : : {
67 : 0 : g_autoptr (ValentMixerAdapter) item = NULL;
68 : 0 : ValentResource *item_source = NULL;
69 : :
70 : 0 : item = g_list_model_get_item (self->mixers, i);
71 : 0 : item_source = valent_resource_get_source (VALENT_RESOURCE (item));
72 [ # # ]: 0 : if (item_source == player_source)
73 : : {
74 : 0 : gtk_drop_down_set_selected (self->mixer_adapter, i);
75 : 0 : break;
76 : : }
77 : :
78 : : // TODO: this should only be reached for local players, whose direct
79 : : // source doesn't match the player. The hypothetical solution is
80 : : // `valent_object_get_ancestor (object, VALENT_TYPE_DATA_SOURCE)`
81 [ # # # # ]: 0 : if (!VALENT_IS_DEVICE (player_source) && !VALENT_IS_DEVICE (item_source))
82 : : {
83 : 0 : gtk_drop_down_set_selected (self->mixer_adapter, i);
84 : 0 : break;
85 : : }
86 : : }
87 : :
88 : 0 : gtk_widget_set_visible (GTK_WIDGET (self->media_player), TRUE);
89 : 0 : gtk_stack_set_visible_child_name (self->media_stack, "player");
90 : : }
91 : :
92 : : /*
93 : : * GObject
94 : : */
95 : : static void
96 : 1 : valent_media_window_finalize (GObject *object)
97 : : {
98 : 1 : ValentMediaWindow *self = VALENT_MEDIA_WINDOW (object);
99 : :
100 [ - + ]: 1 : g_clear_object (&self->mixers);
101 [ + - ]: 1 : g_clear_object (&self->players);
102 : :
103 : 1 : G_OBJECT_CLASS (valent_media_window_parent_class)->finalize (object);
104 : 1 : }
105 : :
106 : : static void
107 : 5 : valent_media_window_get_property (GObject *object,
108 : : guint prop_id,
109 : : GValue *value,
110 : : GParamSpec *pspec)
111 : : {
112 : 5 : ValentMediaWindow *self = VALENT_MEDIA_WINDOW (object);
113 : :
114 [ + + - ]: 5 : switch ((ValentMediaWindowProperty)prop_id)
115 : : {
116 : 2 : case PROP_MIXERS:
117 : 2 : g_value_set_object (value, self->mixers);
118 : 2 : break;
119 : :
120 : 3 : case PROP_PLAYERS:
121 : 3 : g_value_set_object (value, self->players);
122 : 3 : break;
123 : :
124 : 0 : default:
125 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
126 : : }
127 : 5 : }
128 : :
129 : : static void
130 : 2 : valent_media_window_set_property (GObject *object,
131 : : guint prop_id,
132 : : const GValue *value,
133 : : GParamSpec *pspec)
134 : : {
135 : 2 : ValentMediaWindow *self = VALENT_MEDIA_WINDOW (object);
136 : :
137 [ + + - ]: 2 : switch ((ValentMediaWindowProperty)prop_id)
138 : : {
139 : 1 : case PROP_MIXERS:
140 : 1 : self->mixers = g_value_dup_object (value);
141 : 1 : break;
142 : :
143 : 1 : case PROP_PLAYERS:
144 : 1 : self->players = g_value_dup_object (value);
145 : 1 : break;
146 : :
147 : 0 : default:
148 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
149 : : }
150 : 2 : }
151 : :
152 : : static void
153 : 1 : valent_media_window_class_init (ValentMediaWindowClass *klass)
154 : : {
155 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
156 : 1 : GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
157 : :
158 : 1 : object_class->finalize = valent_media_window_finalize;
159 : 1 : object_class->get_property = valent_media_window_get_property;
160 : 1 : object_class->set_property = valent_media_window_set_property;
161 : :
162 : 2 : properties [PROP_MIXERS] =
163 : 1 : g_param_spec_object ("mixers", NULL, NULL,
164 : : G_TYPE_LIST_MODEL,
165 : : (G_PARAM_READWRITE |
166 : : G_PARAM_CONSTRUCT_ONLY |
167 : : G_PARAM_STATIC_STRINGS));
168 : :
169 : 2 : properties [PROP_PLAYERS] =
170 : 1 : g_param_spec_object ("players", NULL, NULL,
171 : : G_TYPE_LIST_MODEL,
172 : : (G_PARAM_READWRITE |
173 : : G_PARAM_CONSTRUCT_ONLY |
174 : : G_PARAM_STATIC_STRINGS));
175 : :
176 : 1 : g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties);
177 : :
178 : 1 : gtk_widget_class_set_template_from_resource (widget_class, "/plugins/gnome/valent-media-window.ui");
179 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentMediaWindow, media_player);
180 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentMediaWindow, media_stack);
181 : 1 : gtk_widget_class_bind_template_child (widget_class, ValentMediaWindow, mixer_adapter);
182 : 1 : gtk_widget_class_bind_template_callback (widget_class, on_player_selected);
183 : 1 : }
184 : :
185 : : static void
186 : 1 : valent_media_window_init (ValentMediaWindow *self)
187 : : {
188 : 1 : gtk_widget_init_template (GTK_WIDGET (self));
189 : 1 : }
|