X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=gtk%2Fsrc%2Fpreview.c;h=3cbc9ee203092ec59fe1cddf2329f272c908b205;hb=9460d9624a5cf24126bc39605bc47d43330fcdf4;hp=d3bd475da890e7e15ead50b8fef35db52f52402a;hpb=8433fbca4f4b2dfdf139ca45c741f61bf529019e;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/gtk/src/preview.c b/gtk/src/preview.c index d3bd475d..3cbc9ee2 100644 --- a/gtk/src/preview.c +++ b/gtk/src/preview.c @@ -16,11 +16,18 @@ #include #include #include + +#if !defined(_WIN32) #include +#endif + +#if defined(_ENABLE_GST) #include #include #include #include +#endif + #include "settings.h" #include "presets.h" #include "callbacks.h" @@ -34,7 +41,10 @@ struct preview_s { +#if defined(_ENABLE_GST) GstElement *play; + gulong xid; +#endif gint64 len; gint64 pos; gboolean seek_lock; @@ -42,7 +52,6 @@ struct preview_s gint width; gint height; GtkWidget *view; - gulong xid; GdkPixbuf *pix; gint button_width; gint button_height; @@ -55,15 +64,19 @@ struct preview_s gchar *current; }; -static gboolean live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data); +#if defined(_ENABLE_GST) +G_MODULE_EXPORT gboolean live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data); static GstBusSyncReply create_window(GstBus *bus, GstMessage *msg, gpointer data); -gboolean preview_expose_cb(GtkWidget *widget, GdkEventExpose *event, +#endif + +G_MODULE_EXPORT gboolean preview_expose_cb(GtkWidget *widget, GdkEventExpose *event, signal_user_data_t *ud); void ghb_screen_par(signal_user_data_t *ud, gint *par_n, gint *par_d) { +#if defined(_ENABLE_GST) GValue disp_par = {0,}; GstElement *xover; GObjectClass *klass; @@ -72,7 +85,13 @@ ghb_screen_par(signal_user_data_t *ud, gint *par_n, gint *par_d) g_value_init(&disp_par, GST_TYPE_FRACTION); gst_value_set_fraction(&disp_par, 1, 1); g_object_get(ud->preview->play, "video-sink", &xover, NULL); + if (xover == NULL) + goto fail; + klass = G_OBJECT_GET_CLASS(xover); + if (klass == NULL) + goto fail; + pspec = g_object_class_find_property(klass, "pixel-aspect_ratio"); if (pspec) { @@ -91,6 +110,15 @@ ghb_screen_par(signal_user_data_t *ud, gint *par_n, gint *par_d) *par_n = gst_value_get_fraction_numerator(&disp_par); *par_d = gst_value_get_fraction_denominator(&disp_par); g_value_unset(&disp_par); + return; + +fail: + *par_n = 1; + *par_d = 1; +#else + *par_n = 1; + *par_d = 1; +#endif } void @@ -100,10 +128,12 @@ ghb_par_scale(signal_user_data_t *ud, gint *width, gint *height, gint par_n, gin gint64 num, den; ghb_screen_par(ud, &disp_par_n, &disp_par_d); + if (disp_par_n < 1) disp_par_n = 1; + if (disp_par_d < 1) disp_par_d = 1; num = par_n * disp_par_d; den = par_d * disp_par_n; - if (num > den) + if (par_n > par_d) *width = *width * num / den; else *height = *height * den / num; @@ -112,29 +142,57 @@ ghb_par_scale(signal_user_data_t *ud, gint *width, gint *height, gint par_n, gin void ghb_preview_init(signal_user_data_t *ud) { - GstBus *bus; - GstElement *xover; + GtkWidget *widget; ud->preview = g_malloc0(sizeof(preview_t)); ud->preview->view = GHB_WIDGET(ud->builder, "preview_image"); gtk_widget_realize(ud->preview->view); g_signal_connect(G_OBJECT(ud->preview->view), "expose_event", G_CALLBACK(preview_expose_cb), ud); - ud->preview->xid = GDK_DRAWABLE_XID(ud->preview->view->window); - ud->preview->play = gst_element_factory_make("playbin", "play"); ud->preview->pause = TRUE; ud->preview->encode_frame = -1; ud->preview->live_id = -1; + widget = GHB_WIDGET (ud->builder, "preview_button_image"); + gtk_widget_get_size_request(widget, &ud->preview->button_width, &ud->preview->button_height); + +#if defined(_ENABLE_GST) + GstBus *bus; + GstElement *xover; + +#if !defined(_WIN32) + ud->preview->xid = GDK_DRAWABLE_XID(ud->preview->view->window); +#else + ud->preview->xid = GDK_WINDOW_HWND(ud->preview->view->window); +#endif + ud->preview->play = gst_element_factory_make("playbin", "play"); //xover = gst_element_factory_make("xvimagesink", "xover"); + //xover = gst_element_factory_make("ximagesink", "xover"); xover = gst_element_factory_make("gconfvideosink", "xover"); + if (xover == NULL) + { + GtkWidget *widget = GHB_WIDGET(ud->builder, "live_preview_box"); + gtk_widget_hide (widget); + widget = GHB_WIDGET(ud->builder, "live_preview_duration_box"); + gtk_widget_hide (widget); + return; + } + g_object_set(G_OBJECT(ud->preview->play), "video-sink", xover, NULL); + g_object_set(ud->preview->play, "subtitle-font-desc", + "sans bold 20", NULL); //g_object_set(G_OBJECT(xover), "force-aspect-ratio", TRUE, NULL); bus = gst_pipeline_get_bus(GST_PIPELINE(ud->preview->play)); gst_bus_add_watch(bus, live_preview_cb, ud); gst_bus_set_sync_handler(bus, create_window, ud->preview); gst_object_unref(bus); +#else + widget = GHB_WIDGET(ud->builder, "live_preview_box"); + gtk_widget_hide (widget); + widget = GHB_WIDGET(ud->builder, "live_preview_duration_box"); + gtk_widget_hide (widget); +#endif } void @@ -147,6 +205,7 @@ ghb_preview_cleanup(signal_user_data_t *ud) } } +#if defined(_ENABLE_GST) static GstBusSyncReply create_window(GstBus *bus, GstMessage *msg, gpointer data) { @@ -158,8 +217,13 @@ create_window(GstBus *bus, GstMessage *msg, gpointer data) { if (!gst_structure_has_name(msg->structure, "prepare-xwindow-id")) return GST_BUS_PASS; +#if !defined(_WIN32) gst_x_overlay_set_xwindow_id( GST_X_OVERLAY(GST_MESSAGE_SRC(msg)), preview->xid); +#else + gst_directdraw_sink_set_window_id( + GST_X_OVERLAY(GST_MESSAGE_SRC(msg)), preview->xid); +#endif gst_message_unref(msg); return GST_BUS_DROP; } break; @@ -307,7 +371,7 @@ update_stream_info(signal_user_data_t *ud) g_list_free(vstreams); } -static gboolean +G_MODULE_EXPORT gboolean live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data) { signal_user_data_t *ud = (signal_user_data_t*)data; @@ -409,6 +473,7 @@ live_preview_pause(signal_user_data_t *ud) gst_element_set_state(ud->preview->play, GST_STATE_PAUSED); ud->preview->pause = TRUE; } +#endif void live_preview_stop(signal_user_data_t *ud) @@ -418,7 +483,9 @@ live_preview_stop(signal_user_data_t *ud) img = GTK_IMAGE(GHB_WIDGET(ud->builder, "live_preview_play_image")); gtk_image_set_from_stock(img, "gtk-media-play", GTK_ICON_SIZE_BUTTON); +#if defined(_ENABLE_GST) gst_element_set_state(ud->preview->play, GST_STATE_NULL); +#endif ud->preview->pause = TRUE; ud->preview->state = PREVIEW_STATE_IMAGE; @@ -452,7 +519,7 @@ ghb_live_reset(signal_user_data_t *ud) extern void hb_get_tempory_directory(hb_handle_t *h, char path[512]); -void +G_MODULE_EXPORT void live_preview_start_cb(GtkWidget *xwidget, signal_user_data_t *ud) { gchar *tmp_dir; @@ -468,10 +535,12 @@ live_preview_start_cb(GtkWidget *xwidget, signal_user_data_t *ud) if (ud->preview->encoded[frame] && g_file_test(name, G_FILE_TEST_IS_REGULAR)) { +#if defined(_ENABLE_GST) if (ud->preview->pause) live_preview_start(ud); else live_preview_pause(ud); +#endif } else { @@ -502,7 +571,9 @@ ghb_live_encode_done(signal_user_data_t *ud, gboolean success) gtk_progress_bar_set_text(GTK_PROGRESS_BAR(prog), "Done"); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(prog), 1); ud->preview->encoded[ud->preview->encode_frame] = TRUE; +#if defined(_ENABLE_GST) live_preview_start(ud); +#endif widget = GHB_WIDGET(ud->builder, "live_progress_box"); gtk_widget_hide (widget); widget = GHB_WIDGET(ud->builder, "live_preview_progress"); @@ -516,7 +587,8 @@ ghb_live_encode_done(signal_user_data_t *ud, gboolean success) } } -static gboolean +#if defined(_ENABLE_GST) +G_MODULE_EXPORT gboolean unlock_progress_cb(signal_user_data_t *ud) { ud->preview->progress_lock = FALSE; @@ -524,10 +596,12 @@ unlock_progress_cb(signal_user_data_t *ud) // so that it is not called again return FALSE; } +#endif void ghb_live_preview_progress(signal_user_data_t *ud) { +#if defined(_ENABLE_GST) GstFormat fmt = GST_FORMAT_TIME; gint64 len = -1, pos = -1; @@ -559,9 +633,11 @@ ghb_live_preview_progress(signal_user_data_t *ud) gtk_range_set_value(progress, percent); } g_idle_add((GSourceFunc)unlock_progress_cb, ud); +#endif } -static gboolean +#if defined(_ENABLE_GST) +G_MODULE_EXPORT gboolean unlock_seek_cb(signal_user_data_t *ud) { ud->preview->seek_lock = FALSE; @@ -569,10 +645,12 @@ unlock_seek_cb(signal_user_data_t *ud) // so that it is not called again return FALSE; } +#endif -void +G_MODULE_EXPORT void live_preview_seek_cb(GtkWidget *widget, signal_user_data_t *ud) { +#if defined(_ENABLE_GST) gdouble dval; gint64 pos; @@ -587,6 +665,7 @@ live_preview_seek_cb(GtkWidget *widget, signal_user_data_t *ud) GST_SEEK_TYPE_SET, pos, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); g_idle_add((GSourceFunc)unlock_seek_cb, ud); +#endif } void @@ -626,7 +705,7 @@ ghb_set_preview_image(signal_user_data_t *ud) ud->preview->pix = ghb_get_preview_image(titleindex, ud->preview->frame, - ud, TRUE, &width, &height); + ud, &width, &height); if (ud->preview->pix == NULL) return; preview_width = gdk_pixbuf_get_width(ud->preview->pix); preview_height = gdk_pixbuf_get_height(ud->preview->pix); @@ -648,9 +727,14 @@ ghb_set_preview_image(signal_user_data_t *ud) g_free(text); g_debug("preview %d x %d", preview_width, preview_height); - target_height = MIN(ud->preview->button_height, 128); + target_height = MIN(ud->preview->button_height, 200); height = target_height; width = preview_width * height / preview_height; + if (width > 400) + { + width = 400; + height = preview_height * width / preview_width; + } if ((height >= 16) && (width >= 16)) { @@ -666,13 +750,17 @@ ghb_set_preview_image(signal_user_data_t *ud) } } -static gboolean +#if defined(_ENABLE_GST) +G_MODULE_EXPORT gboolean delayed_expose_cb(signal_user_data_t *ud) { GstElement *vsink; GstXOverlay *xover; g_object_get(ud->preview->play, "video-sink", &vsink, NULL); + if (vsink == NULL) + return FALSE; + if (GST_IS_BIN(vsink)) xover = GST_X_OVERLAY(gst_bin_get_by_interface( GST_BIN(vsink), GST_TYPE_X_OVERLAY)); @@ -683,13 +771,15 @@ delayed_expose_cb(signal_user_data_t *ud) // so that it is not called again return FALSE; } +#endif -gboolean +G_MODULE_EXPORT gboolean preview_expose_cb( GtkWidget *widget, GdkEventExpose *event, signal_user_data_t *ud) { +#if defined(_ENABLE_GST) if (ud->preview->state == PREVIEW_STATE_LIVE) { if (GST_STATE(ud->preview->play) >= GST_STATE_PAUSED) @@ -712,6 +802,7 @@ preview_expose_cb( } return TRUE; } +#endif if (ud->preview->pix != NULL) { @@ -722,7 +813,7 @@ preview_expose_cb( return TRUE; } -void +G_MODULE_EXPORT void preview_button_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, signal_user_data_t *ud) { g_debug("allocate %d x %d", allocation->width, allocation->height); @@ -753,26 +844,39 @@ set_visible(GtkWidget *widget, gboolean visible) } } -G_MODULE_EXPORT void -preview_button_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) +void +ghb_preview_set_visible(signal_user_data_t *ud) { gint titleindex; + GtkWidget *widget; + gboolean settings_active; - g_debug("preview_button_clicked_cb()"); + settings_active = ghb_settings_get_boolean(ud->settings, "show_picture"); + widget = GHB_WIDGET (ud->builder, "preview_window"); titleindex = ghb_settings_combo_int(ud->settings, "title"); - if (titleindex >= 0) + if (settings_active && titleindex >= 0) { gint x, y; - GtkWidget *widget = GHB_WIDGET (ud->builder, "preview_window"); x = ghb_settings_get_int(ud->settings, "preview_x"); y = ghb_settings_get_int(ud->settings, "preview_y"); if (x >= 0 && y >= 0) gtk_window_move(GTK_WINDOW(widget), x, y); - set_visible(widget, gtk_toggle_button_get_active( - GTK_TOGGLE_BUTTON(xwidget))); + set_visible(widget, + ghb_settings_get_boolean(ud->settings, "show_preview")); } + else + { + set_visible(widget, FALSE); + } +} + +G_MODULE_EXPORT void +preview_button_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) +{ + g_debug("preview_button_clicked_cb()"); ghb_widget_to_setting (ud->settings, xwidget); - ghb_check_dependency(ud, xwidget); + ghb_preview_set_visible(ud); + ghb_check_dependency(ud, xwidget, NULL); const gchar *name = gtk_widget_get_name(xwidget); ghb_pref_save(ud->settings, name); } @@ -781,26 +885,22 @@ G_MODULE_EXPORT void picture_settings_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { GtkWidget *widget; - gboolean active; + gboolean active, hide_settings; gint x, y; g_debug("picture_settings_clicked_cb()"); + ghb_widget_to_setting (ud->settings, xwidget); + + hide_settings = ghb_settings_get_boolean(ud->settings, "hide_settings"); + + active = ghb_settings_get_boolean(ud->settings, "show_picture"); widget = GHB_WIDGET (ud->builder, "settings_window"); - active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(xwidget)); x = ghb_settings_get_int(ud->settings, "settings_x"); y = ghb_settings_get_int(ud->settings, "settings_y"); if (x >= 0 && y >= 0) gtk_window_move(GTK_WINDOW(widget), x, y); - set_visible(widget, active); - if (ghb_settings_get_boolean(ud->settings, "show_preview")) - { - widget = GHB_WIDGET (ud->builder, "preview_window"); - x = ghb_settings_get_int(ud->settings, "preview_x"); - y = ghb_settings_get_int(ud->settings, "preview_y"); - if (x >= 0 && y >= 0) - gtk_window_move(GTK_WINDOW(widget), x, y); - set_visible(widget, active); - } + set_visible(widget, active && !hide_settings); + ghb_preview_set_visible(ud); } G_MODULE_EXPORT void @@ -815,54 +915,78 @@ picture_settings_alt_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(toggle), !active); } +static gboolean +go_full(signal_user_data_t *ud) +{ + GtkWindow *window; + window = GTK_WINDOW(GHB_WIDGET (ud->builder, "preview_window")); + gtk_window_fullscreen(window); + ghb_set_preview_image(ud); + return FALSE; +} + G_MODULE_EXPORT void -picture_settings_alt2_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) +fullscreen_clicked_cb(GtkWidget *toggle, signal_user_data_t *ud) { - GtkWidget *toggle; gboolean active; - gint signal_id; - gint handler_id = 0; + GtkWindow *window; - g_debug("picture_settings_alt2_clicked_cb()"); - toggle = GHB_WIDGET (ud->builder, "show_picture"); - active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(toggle)); + g_debug("fullscreen_clicked_cb()"); + ghb_widget_to_setting (ud->settings, toggle); + ghb_check_dependency(ud, toggle, NULL); + const gchar *name = gtk_widget_get_name(toggle); + ghb_pref_save(ud->settings, name); + + window = GTK_WINDOW(GHB_WIDGET (ud->builder, "preview_window")); + active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)); if (active) { - // 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)toggle, - G_SIGNAL_MATCH_ID, - signal_id, 0, 0, 0, 0); - if (handler_id > 0) - { - // This should also always succeed - g_signal_handler_block ((gpointer)toggle, handler_id); - } - } + gtk_window_set_resizable(window, TRUE); + gtk_button_set_label(GTK_BUTTON(toggle), "Windowed"); + // Changing resizable property doesn't take effect immediately + // need to delay fullscreen till after this callback returns + // to mainloop + g_idle_add((GSourceFunc)go_full, ud); + } + else + { + gtk_window_unfullscreen(window); + gtk_window_set_resizable(window, FALSE); + gtk_button_set_label(GTK_BUTTON(toggle), "Fullscreen"); + ghb_set_preview_image(ud); } +} - GtkWidget *widget = GHB_WIDGET (ud->builder, "settings_window"); - gint x, y; +G_MODULE_EXPORT void +picture_settings_alt2_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) +{ + GtkWidget *toggle; + gboolean active; + GtkWidget *window; - x = ghb_settings_get_int(ud->settings, "settings_x"); - y = ghb_settings_get_int(ud->settings, "settings_y"); - if (x >= 0 && y >= 0) - gtk_window_move(GTK_WINDOW(widget), x, y); - set_visible(widget, !active); - gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(toggle), !active); + g_debug("picture_settings_alt2_clicked_cb()"); + ghb_widget_to_setting (ud->settings, xwidget); + active = ghb_settings_get_boolean(ud->settings, "hide_settings"); - if (handler_id > 0) + toggle = GHB_WIDGET (ud->builder, "hide_settings"); + window = GHB_WIDGET(ud->builder, "settings_window"); + if (!active) { - g_signal_handler_unblock ((gpointer)toggle, handler_id); + gtk_button_set_label(GTK_BUTTON(toggle), "Hide Settings"); + gtk_widget_set_tooltip_text(toggle, + "Hide the picture settings window while " + "leaving the preview visible."); + gtk_widget_show(window); + } + else + { + gtk_button_set_label(GTK_BUTTON(toggle), "Show Settings"); + gtk_widget_set_tooltip_text(toggle, "Show picture settings."); + gtk_widget_hide(window); } } -void +G_MODULE_EXPORT void preview_frame_value_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { if (ud->preview->live_id >= 0) @@ -874,61 +998,38 @@ preview_frame_value_changed_cb(GtkWidget *widget, signal_user_data_t *ud) ghb_set_preview_image(ud); } -gboolean +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); + widget = GHB_WIDGET (ud->builder, "show_picture"); + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(widget), FALSE); return TRUE; } -gboolean +G_MODULE_EXPORT 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); + live_preview_stop(ud); 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; } -void +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); + ghb_check_dependency(ud, widget, NULL); const gchar *name = gtk_widget_get_name(widget); ghb_pref_save(ud->settings, name); } @@ -940,6 +1041,7 @@ 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; @@ -952,6 +1054,7 @@ hud_enter_cb( GdkEventCrossing *event, signal_user_data_t *ud) { + g_debug("hud_enter_cb()"); if (hud_timeout_id != 0) { GMainContext *mc; @@ -974,6 +1077,7 @@ preview_leave_cb( GdkEventCrossing *event, signal_user_data_t *ud) { + g_debug("hud_leave_cb()"); if (hud_timeout_id != 0) { GMainContext *mc; @@ -994,6 +1098,7 @@ preview_motion_cb( GdkEventMotion *event, signal_user_data_t *ud) { + //g_debug("hud_motion_cb %d", hud_timeout_id); if (hud_timeout_id != 0) { GMainContext *mc; @@ -1004,30 +1109,83 @@ preview_motion_cb( if (source != NULL) g_source_destroy(source); } - else + widget = GHB_WIDGET(ud->builder, "preview_hud"); + if (!GTK_WIDGET_VISIBLE(widget)) { - GtkWidget *widget; - GdkWindow *parent, *win; - gint pw, ph, w, h, x, y; - - widget = GHB_WIDGET(ud->builder, "preview_image"); - parent = gtk_widget_get_window(widget); - widget = GHB_WIDGET(ud->builder, "preview_hud"); - win = gtk_widget_get_window(widget); gtk_widget_show(widget); - gdk_drawable_get_size(GDK_DRAWABLE(parent), &pw, &ph); - gdk_drawable_get_size(GDK_DRAWABLE(win), &w, &h); - x = pw/2 - w/2; - if (ph/4 > h/2) - y = ph - ph/4 - h/2; - else - y = ph - h; - gdk_window_move(win, x, y); } - hud_timeout_id = g_timeout_add_seconds(10, (GSourceFunc)hud_timeout, ud); + 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, @@ -1036,7 +1194,7 @@ preview_configure_cb( { gint x, y; - g_debug("preview_configure_cb()"); + //g_message("preview_configure_cb()"); if (GTK_WIDGET_VISIBLE(widget)) { gtk_window_get_position(GTK_WINDOW(widget), &x, &y); @@ -1057,7 +1215,7 @@ settings_configure_cb( { gint x, y; - g_debug("settings_configure_cb()"); + //g_message("settings_configure_cb()"); if (GTK_WIDGET_VISIBLE(widget)) { gtk_window_get_position(GTK_WINDOW(widget), &x, &y);