Commit 36ebcf61 authored by Benjamin Berg's avatar Benjamin Berg
Browse files

Improve UI with steps and cancellation possibility

Unfortunately, it seems that sometimes the pipeline stays alive when
cancelling.
parent d893c1dd
......@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib/gi18n.h>
#include "gnome-screencast-config.h"
#include "gnome-screencast-window.h"
#include "screencast-sink-list.h"
......@@ -43,9 +44,22 @@ struct _GnomeScreencastWindow
GCancellable *cancellable;
ScreencastSink *stream_sink;
/* Template widgets */
GtkStack *step_stack;
ScreencastSinkList *find_sink_list;
GtkListBox *connect_sink_list;
GtkLabel *connect_state_label;
GtkButton *connect_cancel;
GtkListBox *stream_sink_list;
GtkLabel *stream_state_label;
GtkButton *stream_cancel;
GtkListBox *error_sink_list;
GtkButton *error_return;
};
G_DEFINE_TYPE (GnomeScreencastWindow, gnome_screencast_window, GTK_TYPE_APPLICATION_WINDOW)
......@@ -90,11 +104,76 @@ sink_create_source_cb (GnomeScreencastWindow *self, ScreencastSink *sink)
return GST_ELEMENT (bin);
}
static void
remove_widget (GtkWidget *widget, gpointer user_data)
{
GtkContainer *container = GTK_CONTAINER (user_data);
gtk_container_remove (container, widget);
}
static void
sink_notify_state_cb (GnomeScreencastWindow *self, GParamSpec *pspec, ScreencastSink *sink)
{
ScreencastSinkState state;
g_object_get (sink, "state", &state, NULL);
g_debug ("Got state change notification from streaming sink to state %s",
g_enum_to_string (SCREENCAST_TYPE_SINK_STATE, state));
switch (state)
{
case SCREENCAST_SINK_STATE_WAIT_P2P:
gtk_label_set_text (self->connect_state_label,
_("Making P2P connection"));
break;
case SCREENCAST_SINK_STATE_WAIT_SOCKET:
gtk_label_set_text (self->connect_state_label,
_("Establishing connection to sink"));
break;
case SCREENCAST_SINK_STATE_WAIT_STREAMING:
gtk_label_set_text (self->connect_state_label,
_("Starting to stream"));
break;
case SCREENCAST_SINK_STATE_STREAMING:
gtk_container_foreach (GTK_CONTAINER (self->connect_sink_list), remove_widget, self->connect_sink_list);
gtk_container_foreach (GTK_CONTAINER (self->stream_sink_list), remove_widget, self->stream_sink_list);
gtk_container_foreach (GTK_CONTAINER (self->error_sink_list), remove_widget, self->error_sink_list);
gtk_container_add (GTK_CONTAINER (self->stream_sink_list),
GTK_WIDGET (screencast_sink_row_new (self->stream_sink)));
gtk_stack_set_visible_child_name (self->step_stack, "stream");
break;
case SCREENCAST_SINK_STATE_ERROR:
gtk_container_foreach (GTK_CONTAINER (self->stream_sink_list), remove_widget, self->stream_sink_list);
gtk_container_foreach (GTK_CONTAINER (self->connect_sink_list), remove_widget, self->connect_sink_list);
gtk_container_foreach (GTK_CONTAINER (self->error_sink_list), remove_widget, self->error_sink_list);
gtk_container_add (GTK_CONTAINER (self->error_sink_list),
GTK_WIDGET (screencast_sink_row_new (self->stream_sink)));
gtk_stack_set_visible_child_name (self->step_stack, "error");
case SCREENCAST_SINK_STATE_DISCONNECTED:
gtk_container_foreach (GTK_CONTAINER (self->stream_sink_list), remove_widget, self->stream_sink_list);
gtk_container_foreach (GTK_CONTAINER (self->connect_sink_list), remove_widget, self->connect_sink_list);
gtk_container_foreach (GTK_CONTAINER (self->error_sink_list), remove_widget, self->error_sink_list);
gtk_stack_set_visible_child_name (self->step_stack, "find");
g_signal_handlers_disconnect_by_data (self->stream_sink, self);
g_clear_object (&self->stream_sink);
break;
}
}
static void
find_sink_list_row_activated_cb (GnomeScreencastWindow *self, ScreencastSinkRow *row, ScreencastSinkList *sink_list)
{
ScreencastSink *sink;
g_autoptr(ScreencastSink) streaming_sink = NULL;
#if HAVE_SCREENCAST_PORTAL
if (!self->portal)
......@@ -107,20 +186,28 @@ find_sink_list_row_activated_cb (GnomeScreencastWindow *self, ScreencastSinkRow
g_assert (SCREENCAST_IS_SINK_ROW (row));
sink = screencast_sink_row_get_sink (row);
streaming_sink = screencast_sink_start_stream (sink);
self->stream_sink = screencast_sink_start_stream (sink);
if (streaming_sink)
if (!self->stream_sink)
{
g_signal_connect_object (streaming_sink,
"create-source",
(GCallback) sink_create_source_cb,
self,
G_CONNECT_SWAPPED);
g_warning ("ScreencastWindow: Could not start streaming!");
}
/* XXX: leak streaming_sink intentionally for now */
g_steal_pointer (&streaming_sink);
g_signal_connect_object (self->stream_sink,
"create-source",
(GCallback) sink_create_source_cb,
self,
G_CONNECT_SWAPPED);
g_signal_connect_object (self->stream_sink,
"notify::state",
(GCallback) sink_notify_state_cb,
self,
G_CONNECT_SWAPPED);
gtk_stack_set_visible_child_name (self->step_stack, "connect");
gtk_container_add (GTK_CONTAINER (self->connect_sink_list),
GTK_WIDGET (screencast_sink_row_new (self->stream_sink)));
}
static void
......@@ -147,6 +234,14 @@ gnome_screencast_window_class_init (GnomeScreencastWindowClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/screencast/gnome-screencast-window.ui");
gtk_widget_class_bind_template_child (widget_class, GnomeScreencastWindow, step_stack);
gtk_widget_class_bind_template_child (widget_class, GnomeScreencastWindow, find_sink_list);
gtk_widget_class_bind_template_child (widget_class, GnomeScreencastWindow, connect_sink_list);
gtk_widget_class_bind_template_child (widget_class, GnomeScreencastWindow, connect_state_label);
gtk_widget_class_bind_template_child (widget_class, GnomeScreencastWindow, connect_cancel);
gtk_widget_class_bind_template_child (widget_class, GnomeScreencastWindow, stream_sink_list);
gtk_widget_class_bind_template_child (widget_class, GnomeScreencastWindow, stream_state_label);
gtk_widget_class_bind_template_child (widget_class, GnomeScreencastWindow, stream_cancel);
gtk_widget_class_bind_template_child (widget_class, GnomeScreencastWindow, error_sink_list);
gtk_widget_class_bind_template_child (widget_class, GnomeScreencastWindow, error_return);
}
#if HAVE_SCREENCAST_PORTAL
......@@ -178,6 +273,15 @@ screencast_portal_init_async_cb (GObject *source_object,
}
#endif
static void
stream_stop_clicked_cb (GnomeScreencastWindow *self)
{
if (!self->stream_sink)
return;
screencast_sink_stop_stream (self->stream_sink);
}
static void
gnome_screencast_window_init (GnomeScreencastWindow *self)
{
......@@ -207,6 +311,26 @@ gnome_screencast_window_init (GnomeScreencastWindow *self)
self->cancellable = g_cancellable_new ();
/* All of these buttons just stop the stream, which will return us
* to the DISCONNECTED state and the selection page. */
g_signal_connect_object (self->connect_cancel,
"clicked",
(GCallback) stream_stop_clicked_cb,
self,
G_CONNECT_SWAPPED);
g_signal_connect_object (self->stream_cancel,
"clicked",
(GCallback) stream_stop_clicked_cb,
self,
G_CONNECT_SWAPPED);
g_signal_connect_object (self->error_return,
"clicked",
(GCallback) stream_stop_clicked_cb,
self,
G_CONNECT_SWAPPED);
#if HAVE_SCREENCAST_PORTAL
portal = screencast_portal_new ();
g_async_initable_init_async (G_ASYNC_INITABLE (portal),
......
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment