From 91c277705747fb03219fee77e399f2b6afdba7cc Mon Sep 17 00:00:00 2001 From: Andreas Frisch Date: Wed, 27 Apr 2016 13:05:29 +0200 Subject: [PATCH] use templated signals --- Makefile | 4 +- photobooth.c | 197 ++++++++++++++++++++++++++++-------------------- photobooth.css | 15 +++- photobooth.h | 2 + photobooth.ui | 46 +++++++++-- photoboothwin.c | 9 ++- photoboothwin.h | 1 + 7 files changed, 178 insertions(+), 96 deletions(-) diff --git a/Makefile b/Makefile index 560347b..cb31381 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC ?= gcc PKGCONFIG = $(shell which pkg-config) -CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0 gstreamer-1.0 gstreamer-video-1.0 libgphoto2) -LIBS = $(shell $(PKGCONFIG) --libs gtk+-3.0 gstreamer-1.0 gstreamer-video-1.0 libgphoto2) +CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0 gstreamer-1.0 gstreamer-video-1.0 libgphoto2) -Wl,--export-dynamic -rdynamic +LIBS = $(shell $(PKGCONFIG) --libs gtk+-3.0 gstreamer-1.0 gstreamer-video-1.0 libgphoto2 gmodule-export-2.0) GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0) GLIB_COMPILE_SCHEMAS = $(shell $(PKGCONFIG) --variable=glib_compile_schemas gio-2.0) diff --git a/photobooth.c b/photobooth.c index cdaadd3..46d9ce9 100644 --- a/photobooth.c +++ b/photobooth.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "photobooth.h" #include "photoboothwin.h" @@ -65,8 +64,9 @@ static void photo_booth_get_property (GObject *object, guint prop_id, GValue *va static void photo_booth_dispose (GObject *object); static void photo_booth_finalize (GObject *object); PhotoBooth *photo_booth_new (void); -static void photo_booth_clicked (GtkWidget *button, GdkEventButton *event, PhotoBooth *pb); static GdkRectangle photo_boot_monitor_geo (PhotoBooth *pb); +void photo_booth_background_clicked (GtkWidget *widget, GdkEventButton *event, PhotoBoothWindow *win); +void photo_booth_button_yes_clicked (GtkButton *button, PhotoBoothWindow *win); /* general private functions */ static void photo_booth_quit_signal (PhotoBooth *pb); @@ -76,6 +76,7 @@ static gboolean photo_booth_preview (PhotoBooth *pb); static void photo_booth_snapshot_start (PhotoBooth *pb); static gboolean photo_booth_snapshot_prepare (PhotoBooth *pb); static gboolean photo_booth_snapshot_taken (PhotoBooth *pb); +static void photo_booth_print (PhotoBooth *pb); /* libgphoto2 */ static gboolean photo_booth_cam_init (CameraInfo **cam_info); @@ -569,7 +570,7 @@ static gboolean photo_booth_setup_gstreamer (PhotoBooth *pb) g_object_get (pb->video_sink, "widget", &drawing_area, NULL); photo_booth_window_add_drawing_area (priv->win, drawing_area); - g_signal_connect (G_OBJECT (drawing_area), "button-press-event", G_CALLBACK (photo_booth_clicked), pb); +// g_signal_connect (G_OBJECT (drawing_area), "button-press-event", G_CALLBACK (photo_booth_clicked), pb); g_object_unref (drawing_area); gst_element_set_state (pb->pipeline, GST_STATE_PLAYING); @@ -688,6 +689,89 @@ static gboolean photo_booth_preview (PhotoBooth *pb) return FALSE; } +void photo_booth_background_clicked (GtkWidget *widget, GdkEventButton *event, PhotoBoothWindow *win) +{ + PhotoBooth *pb = PHOTO_BOOTH_FROM_WINDOW (win); + GST_DEBUG_OBJECT (widget, "photo_booth_background_clicked state=%d", pb->state); + + switch (pb->state) { + case PB_STATE_PREVIEW: + { + photo_booth_snapshot_start (pb); + break; + } + case PB_STATE_TAKING_PHOTO: + GST_WARNING_OBJECT (pb, "BUSY TAKING A PHOTO, IGNORE CLICK"); + break; + case PB_STATE_ASKING: + photo_booth_preview (pb); + break; + default: + break; + } +} + +static void photo_booth_snapshot_start (PhotoBooth *pb) +{ + PhotoBoothPrivate *priv; + gchar* uri; + guint delay = 1; + + priv = photo_booth_get_instance_private (pb); + photo_booth_window_start_countdown (priv->win, priv->countdown); + if (priv->countdown > 1) + delay = (priv->countdown*1000)-100; + GST_INFO_OBJECT (pb, "started countdown of %d seconds, start taking photo in %d ms", priv->countdown, delay); + g_timeout_add (delay, (GSourceFunc) photo_booth_snapshot_prepare, pb); + uri = g_filename_to_uri (DEFAULT_AUDIOFILE_COUNTDOWN, NULL, NULL); + GST_INFO_OBJECT (pb, "audio uri: %s", uri); + g_object_set (priv->audio_playbin, "uri", uri, NULL); + g_free (uri); + gst_element_set_state (GST_ELEMENT_PARENT (priv->audio_playbin), GST_STATE_PLAYING); +} + +static gboolean photo_booth_snapshot_prepare (PhotoBooth *pb) +{ + PhotoBoothPrivate *priv; + GstPad *pad; + gboolean ret; + + GST_INFO_OBJECT (pb, "SNAPSHOT!"); + GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (pb->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "photo_booth_pre_snapshot.dot"); + + if (!pb->cam_info) + return FALSE; + pb->state = PB_STATE_TAKING_PHOTO; + + priv = photo_booth_get_instance_private (pb); + photo_booth_window_set_spinner (priv->win, TRUE); + + gst_element_set_state (priv->audio_playbin, GST_STATE_READY); + + SEND_COMMAND (pb, CONTROL_PHOTO); + + gst_element_set_state (pb->video_bin, GST_STATE_READY); + GST_DEBUG_OBJECT (pb, "photo_booth_preview! halt video_bin..."); + pad = gst_element_get_static_pad (pb->video_bin, "src"); + pb->video_block_id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM, _gst_video_probecb, pb, NULL); + gst_object_unref (pad); + gst_element_unlink (pb->video_bin, pb->pixoverlay); + + if (pb->photo_block_id) + { + GST_DEBUG_OBJECT (pb, "photo_booth_preview! unblock photo_bin..."); + pad = gst_element_get_static_pad (pb->photo_bin, "src"); + gst_pad_remove_probe (pad, pb->photo_block_id); + gst_object_unref (pad); + } + + ret = gst_element_link (pb->photo_bin, pb->pixoverlay); + GST_DEBUG_OBJECT (pb, "linking %" GST_PTR_FORMAT " ! %" GST_PTR_FORMAT " ret=%i", pb->photo_bin, pb->pixoverlay, ret); + gst_element_set_state (pb->photo_bin, GST_STATE_PLAYING); + + return FALSE; +} + extern int camera_auto_focus (Camera *list, GPContext *context, int onoff); static gboolean photo_booth_focus (CameraInfo *cam_info) @@ -762,90 +846,16 @@ static gboolean photo_booth_take_photo (CameraInfo *cam_info) return TRUE; } -static void photo_booth_clicked (GtkWidget *widget, GdkEventButton *event, PhotoBooth *pb) -{ - GST_DEBUG_OBJECT (pb, "photo_booth_clicked state=%d", pb->state); - switch (pb->state) { - case PB_STATE_PREVIEW: - { - photo_booth_snapshot_start (pb); - break; - } - case PB_STATE_TAKING_PHOTO: - GST_WARNING_OBJECT (pb, "BUSY TAKING A PHOTO, IGNORE CLICK"); - break; - case PB_STATE_ASKING: - photo_booth_preview (pb); - break; - default: - break; - } -} - -static void photo_booth_snapshot_start (PhotoBooth *pb) -{ - PhotoBoothPrivate *priv = photo_booth_get_instance_private (pb); - photo_booth_window_start_countdown (priv->win, priv->countdown); - guint delay = priv->countdown > 1 ? (priv->countdown*1000)-100 : 1; - GST_INFO_OBJECT (pb, "started countdown of %d seconds, start taking photo in %d ms", priv->countdown, delay); - g_timeout_add (delay, (GSourceFunc) photo_booth_snapshot_prepare, pb); - gchar* uri = g_filename_to_uri (DEFAULT_AUDIOFILE_COUNTDOWN, NULL, NULL); - GST_INFO_OBJECT (pb, "audio uri: %s", uri); - g_object_set (priv->audio_playbin, "uri", uri, NULL); - g_free (uri); - gst_element_set_state (GST_ELEMENT_PARENT (priv->audio_playbin), GST_STATE_PLAYING); -} - -static gboolean photo_booth_snapshot_prepare (PhotoBooth *pb) -{ - PhotoBoothPrivate *priv; - GstPad *pad; - gboolean ret; - - GST_INFO_OBJECT (pb, "SNAPSHOT!"); - GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (pb->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "photo_booth_pre_snapshot.dot"); - - if (!pb->cam_info) - return FALSE; - pb->state = PB_STATE_TAKING_PHOTO; - - priv = photo_booth_get_instance_private (pb); - photo_booth_window_set_spinner (priv->win, TRUE); - - gst_element_set_state (priv->audio_playbin, GST_STATE_READY); - - SEND_COMMAND (pb, CONTROL_PHOTO); - - gst_element_set_state (pb->video_bin, GST_STATE_READY); - GST_DEBUG_OBJECT (pb, "photo_booth_preview! halt video_bin..."); - pad = gst_element_get_static_pad (pb->video_bin, "src"); - pb->video_block_id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM, _gst_video_probecb, pb, NULL); - gst_object_unref (pad); - gst_element_unlink (pb->video_bin, pb->pixoverlay); - - if (pb->photo_block_id) - { - GST_DEBUG_OBJECT (pb, "photo_booth_preview! unblock photo_bin..."); - pad = gst_element_get_static_pad (pb->photo_bin, "src"); - gst_pad_remove_probe (pad, pb->photo_block_id); - gst_object_unref (pad); - } - - ret = gst_element_link (pb->photo_bin, pb->pixoverlay); - GST_DEBUG_OBJECT (pb, "linking %" GST_PTR_FORMAT " ! %" GST_PTR_FORMAT " ret=%i", pb->photo_bin, pb->pixoverlay, ret); - gst_element_set_state (pb->photo_bin, GST_STATE_PLAYING); - - return FALSE; -} - static gboolean photo_booth_snapshot_taken (PhotoBooth *pb) { - GST_INFO_OBJECT (pb, "photo_booth_snapshot_taken size=%lu", pb->cam_info->size); - - GstElement *appsrc = gst_bin_get_by_name (GST_BIN (pb->photo_bin), "photo-appsrc"); + PhotoBoothPrivate *priv; + GstElement *appsrc; GstBuffer *buffer; GstFlowReturn flowret; + GST_INFO_OBJECT (pb, "photo_booth_snapshot_taken size=%lu", pb->cam_info->size); + + appsrc = gst_bin_get_by_name (GST_BIN (pb->photo_bin), "photo-appsrc"); buffer = gst_buffer_new_wrapped (pb->cam_info->data, pb->cam_info->size); g_signal_emit_by_name (appsrc, "push-buffer", buffer, &flowret); @@ -854,12 +864,35 @@ static gboolean photo_booth_snapshot_taken (PhotoBooth *pb) gst_object_unref (appsrc); GST_INFO_OBJECT (pb, "photo_booth_snapshot now waiting for user input... PB_STATE_ASKING"); + priv = photo_booth_get_instance_private (pb); + GST_INFO_OBJECT (priv->win->button_yes, "priv->win->button_yes showing...."); + gtk_widget_show (GTK_WIDGET (priv->win->button_yes)); + pb->state = PB_STATE_TAKING_PHOTO; + SEND_COMMAND (pb, CONTROL_PAUSE); pb->state = PB_STATE_ASKING; return FALSE; } +void photo_booth_button_yes_clicked (GtkButton *button, PhotoBoothWindow *win) +{ + PhotoBooth *pb = PHOTO_BOOTH_FROM_WINDOW (win); + GST_DEBUG_OBJECT (pb, "on_button_yes_clicked"); + if (pb->state == PB_STATE_ASKING) + { + photo_booth_print (pb); + } +} + +static void photo_booth_print (PhotoBooth *pb) +{ + PhotoBoothPrivate *priv; + GST_DEBUG_OBJECT (pb, "!!!PRINT!!!"); + priv = photo_booth_get_instance_private (pb); + gtk_widget_hide (GTK_WIDGET (priv->win->button_yes)); +} + PhotoBooth *photo_booth_new (void) { return g_object_new (PHOTO_BOOTH_TYPE, diff --git a/photobooth.css b/photobooth.css index b83fc3c..e2be7d7 100644 --- a/photobooth.css +++ b/photobooth.css @@ -3,8 +3,17 @@ } .countdown_label { - color: white; + color: rgba (150, 200, 200, 255); + text-shadow: 10px 10px #000000 font-weight: bold; - font-size: 60px; - padding: 0 0 0 0; + font-size: 80px; + padding: 0 0 0 0; +} + +.button_yes { + color: rgba (0, 0, 110, 255); + background: rgba (168, 233, 255, 200); + font-weight: bold; + font-size: 80px; + padding: 20px 20px 20px 20px; } diff --git a/photobooth.h b/photobooth.h index d93b3a7..2bff11f 100644 --- a/photobooth.h +++ b/photobooth.h @@ -79,11 +79,13 @@ typedef enum PB_STATE_PRINTING } PhotoboothState; + #define PHOTO_BOOTH_TYPE (photo_booth_get_type ()) #define PHOTO_BOOTH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),PHOTO_BOOTH_TYPE,PhotoBooth)) #define PHOTO_BOOTH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PHOTO_BOOTH_TYPE,PhotoBoothClass)) #define IS_PHOTO_BOOTH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),PHOTO_BOOTH_TYPE)) #define IS_PHOTO_BOOTH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PHOTO_BOOTH_TYPE)) +#define PHOTO_BOOTH_FROM_WINDOW(win) (PHOTO_BOOTH (gtk_window_get_application (GTK_WINDOW (win)))) typedef struct _PhotoBooth PhotoBooth; typedef struct _PhotoBoothClass PhotoBoothClass; diff --git a/photobooth.ui b/photobooth.ui index 690fa9a..30ea9ce 100644 --- a/photobooth.ui +++ b/photobooth.ui @@ -11,11 +11,15 @@ True False + GDK_BUTTON_PRESS_MASK + + + + 400 300 - False False 0.9 center @@ -33,7 +37,7 @@ - -1 + 1 @@ -45,15 +49,47 @@ 0.8 center center - True - True + False + False True - 1 + 2 + + + + + True + False + + + Ausdrucken! + 300 + 200 + True + False + 10 + 10 + + + + + 130 + 104 + + + + + + True + 2