+G_MODULE_EXPORT gboolean
+preview_window_delete_cb(
+ GtkWidget *widget,
+ GdkEvent *event,
+ signal_user_data_t *ud)
+{
+ live_preview_stop(ud);
+ gtk_widget_hide(widget);
+ return TRUE;
+}
+
+gboolean
+settings_window_delete_cb(
+ GtkWidget *widget,
+ GdkEvent *event,
+ signal_user_data_t *ud)
+{
+ gint signal_id;
+ gint handler_id = 0;
+
+ gtk_widget_hide(widget);
+ widget = GHB_WIDGET (ud->builder, "show_picture");
+
+ // I don't want deleting the settings window to also remove the
+ // preview window, but changing the toggle will do this, so temporarily
+ // ignore the toggled signal
+ signal_id = g_signal_lookup("toggled", GTK_TYPE_TOGGLE_TOOL_BUTTON);
+ if (signal_id > 0)
+ {
+ // Valid signal id found. This should always succeed.
+ handler_id = g_signal_handler_find((gpointer)widget, G_SIGNAL_MATCH_ID,
+ signal_id, 0, 0, 0, 0);
+ if (handler_id > 0)
+ {
+ // This should also always succeed
+ g_signal_handler_block ((gpointer)widget, handler_id);
+ }
+ }
+
+ gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(widget), FALSE);
+
+ if (handler_id > 0)
+ {
+ g_signal_handler_unblock ((gpointer)widget, handler_id);
+ }
+ return TRUE;
+}
+
+G_MODULE_EXPORT void
+preview_duration_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ g_debug("preview_duration_changed_cb ()");
+ ghb_live_reset(ud);
+ ghb_widget_to_setting (ud->settings, widget);
+ ghb_check_dependency(ud, widget);
+ const gchar *name = gtk_widget_get_name(widget);
+ ghb_pref_save(ud->settings, name);
+}
+
+static guint hud_timeout_id = 0;
+
+static gboolean
+hud_timeout(signal_user_data_t *ud)
+{
+ GtkWidget *widget;
+
+ g_debug("hud_timeout()");
+ widget = GHB_WIDGET(ud->builder, "preview_hud");
+ gtk_widget_hide(widget);
+ hud_timeout_id = 0;
+ return FALSE;
+}
+
+G_MODULE_EXPORT gboolean
+hud_enter_cb(
+ GtkWidget *widget,
+ GdkEventCrossing *event,
+ signal_user_data_t *ud)
+{
+ g_debug("hud_enter_cb()");
+ if (hud_timeout_id != 0)
+ {
+ GMainContext *mc;
+ GSource *source;
+
+ mc = g_main_context_default();
+ source = g_main_context_find_source_by_id(mc, hud_timeout_id);
+ if (source != NULL)
+ g_source_destroy(source);
+ }
+ widget = GHB_WIDGET(ud->builder, "preview_hud");
+ gtk_widget_show(widget);
+ hud_timeout_id = 0;
+ return FALSE;
+}
+
+G_MODULE_EXPORT gboolean
+preview_leave_cb(
+ GtkWidget *widget,
+ GdkEventCrossing *event,
+ signal_user_data_t *ud)
+{
+ g_debug("hud_leave_cb()");
+ if (hud_timeout_id != 0)
+ {
+ GMainContext *mc;
+ GSource *source;
+
+ mc = g_main_context_default();
+ source = g_main_context_find_source_by_id(mc, hud_timeout_id);
+ if (source != NULL)
+ g_source_destroy(source);
+ }
+ hud_timeout_id = g_timeout_add(300, (GSourceFunc)hud_timeout, ud);
+ return FALSE;
+}
+
+G_MODULE_EXPORT gboolean
+preview_motion_cb(
+ GtkWidget *widget,
+ GdkEventMotion *event,
+ signal_user_data_t *ud)
+{
+ //g_debug("hud_motion_cb %d", hud_timeout_id);
+ if (hud_timeout_id != 0)
+ {
+ GMainContext *mc;
+ GSource *source;
+
+ mc = g_main_context_default();
+ source = g_main_context_find_source_by_id(mc, hud_timeout_id);
+ if (source != NULL)
+ g_source_destroy(source);
+ }
+ widget = GHB_WIDGET(ud->builder, "preview_hud");
+ if (!GTK_WIDGET_VISIBLE(widget))
+ {
+ gtk_widget_show(widget);
+ }
+ hud_timeout_id = g_timeout_add_seconds(4, (GSourceFunc)hud_timeout, ud);
+ return FALSE;
+}
+
+GdkDrawable*
+ghb_curved_rect_mask(gint width, gint height, gint radius)
+{
+ GdkDrawable *shape;
+ cairo_t *cr;
+ double w, h;
+
+ if (!width || !height)
+ return NULL;
+
+ shape = (GdkDrawable *)gdk_pixmap_new (NULL, width, height, 1);
+
+ cr = gdk_cairo_create (shape);
+
+ w = width;
+ h = height;
+ if (radius > width / 2)
+ radius = width / 2;
+ if (radius > height / 2)
+ radius = height / 2;
+
+ // fill shape with black
+ cairo_save(cr);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_move_to (cr, 0, radius);
+ cairo_curve_to (cr, 0 , 0, 0 , 0, radius, 0);
+ cairo_line_to (cr, w - radius, 0);
+ cairo_curve_to (cr, w, 0, w, 0, w, radius);
+ cairo_line_to (cr, w , h - radius);
+ cairo_curve_to (cr, w, h, w, h, w - radius, h);
+ cairo_line_to (cr, 0 + radius, h);
+ cairo_curve_to (cr, 0, h, 0, h, 0, h - radius);
+
+ cairo_close_path(cr);
+
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_fill(cr);
+
+ cairo_destroy(cr);
+
+ return shape;
+}
+
+G_MODULE_EXPORT void
+preview_hud_size_alloc_cb(
+ GtkWidget *widget,
+ GtkAllocation *allocation,
+ signal_user_data_t *ud)
+{
+ GdkDrawable *shape;
+
+ //g_message("preview_hud_size_alloc_cb()");
+ if (GTK_WIDGET_VISIBLE(widget) && allocation->height > 50)
+ {
+ shape = ghb_curved_rect_mask(allocation->width,
+ allocation->height, allocation->height/4);
+ if (shape != NULL)
+ {
+ gtk_widget_shape_combine_mask(widget, shape, 0, 0);
+ gdk_pixmap_unref(shape);
+ }
+ }
+}
+
+G_MODULE_EXPORT gboolean
+preview_configure_cb(
+ GtkWidget *widget,
+ GdkEventConfigure *event,
+ signal_user_data_t *ud)
+{
+ gint x, y;
+
+ //g_message("preview_configure_cb()");
+ if (GTK_WIDGET_VISIBLE(widget))
+ {
+ gtk_window_get_position(GTK_WINDOW(widget), &x, &y);
+ ghb_settings_set_int(ud->settings, "preview_x", x);
+ ghb_settings_set_int(ud->settings, "preview_y", y);
+ ghb_pref_set(ud->settings, "preview_x");
+ ghb_pref_set(ud->settings, "preview_y");
+ ghb_prefs_store();
+ }
+ return FALSE;
+}
+
+G_MODULE_EXPORT gboolean
+settings_configure_cb(
+ GtkWidget *widget,
+ GdkEventConfigure *event,
+ signal_user_data_t *ud)
+{
+ gint x, y;
+
+ //g_message("settings_configure_cb()");
+ if (GTK_WIDGET_VISIBLE(widget))
+ {
+ gtk_window_get_position(GTK_WINDOW(widget), &x, &y);
+ ghb_settings_set_int(ud->settings, "settings_x", x);
+ ghb_settings_set_int(ud->settings, "settings_y", y);
+ ghb_pref_set(ud->settings, "settings_x");
+ ghb_pref_set(ud->settings, "settings_y");
+ ghb_prefs_store();
+ }
+ return FALSE;
+}
+