GtkWidget* webx_dialog_new (gint image_ID, gint drawable_ID) { WebxDialog *dlg; GtkWidget *splitter; GtkWidget *tbscroll; GtkWidget *toolbox; GtkWidget *format_table; GtkWidget *left_box; GtkWidget *preview_box; GtkWidget *box; GtkWidget *vbox; GtkWidget *frame; GtkWidget *separator; GtkWidget *target; GtkWidget *radio; GtkWidget *notebook; GtkWidget *label; GSList *group; GSList *target_list; GSList *radio_list; gint bg_width; gint bg_height; gint align; gint row; webx_prefs_load (&webx_prefs); dlg = g_object_new (WEBX_TYPE_DIALOG, "title", (gchar*)_("Save for Web"), "role", (gchar*)PLUG_IN_BINARY, "modal", (GtkDialogFlags)GTK_DIALOG_MODAL, "help-func", (GimpHelpFunc)gimp_standard_help_func, "help-id", (gchar*)PLUG_IN_PROC, NULL); gimp_dialog_add_buttons (GIMP_DIALOG (dlg), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); gtk_dialog_set_alternative_button_order (GTK_DIALOG (dlg), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gimp_window_set_transient (GTK_WINDOW (dlg)); if (webx_prefs.dlg_width && webx_prefs.dlg_height) { gtk_window_set_default_size (GTK_WINDOW (dlg), webx_prefs.dlg_width, webx_prefs.dlg_height); } else { gtk_window_set_default_size (GTK_WINDOW (dlg), 728, 480); } if (webx_prefs.dlg_x && webx_prefs.dlg_y) { gtk_window_move (GTK_WINDOW (dlg), webx_prefs.dlg_x, webx_prefs.dlg_y); } g_signal_connect (dlg, "response", G_CALLBACK (webx_dialog_response), NULL); g_signal_connect (dlg, "destroy", G_CALLBACK (gtk_main_quit), NULL); dlg->pipeline = webx_pipeline_new (image_ID, drawable_ID); g_signal_connect_swapped (dlg->pipeline, "invalidated", G_CALLBACK (webx_dialog_reset), dlg); g_signal_connect_swapped (dlg->pipeline, "output-changed", G_CALLBACK (webx_dialog_update), dlg); g_object_ref_sink (dlg->pipeline); bg_width = gimp_image_width (image_ID); bg_height = gimp_image_height (image_ID); splitter = gtk_hpaned_new (); dlg->splitter = splitter; gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), GTK_WIDGET (splitter), TRUE, TRUE, 0); gtk_widget_show (GTK_WIDGET (splitter)); left_box = gtk_vbox_new (FALSE, 0); gtk_paned_pack1 (GTK_PANED (splitter), GTK_WIDGET (left_box), FALSE, FALSE); gtk_widget_show (left_box); frame = gtk_frame_new (NULL); gtk_box_pack_start (GTK_BOX (left_box), frame, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (frame), 4); gtk_widget_show (frame); notebook = gtk_notebook_new (); gtk_box_pack_start (GTK_BOX (left_box), notebook, TRUE, TRUE, 0); gtk_widget_show (notebook); tbscroll = gtk_scrolled_window_new (NULL, NULL); label = gtk_image_new_from_stock (GIMP_STOCK_IMAGE, GTK_ICON_SIZE_MENU); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), tbscroll, label); gtk_container_set_border_width (GTK_CONTAINER (tbscroll), 4); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (tbscroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show (GTK_WIDGET (tbscroll)); toolbox = gtk_vbox_new (FALSE, 0); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (tbscroll), GTK_WIDGET (toolbox)); gtk_container_set_border_width (GTK_CONTAINER (toolbox), 4); gtk_widget_show (GTK_WIDGET (toolbox)); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (frame), vbox); gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); gtk_widget_show (vbox); format_table = gtk_table_new (3, 2, TRUE); gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (format_table), FALSE, FALSE, 0); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 8); box = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (box), FALSE, FALSE, 0); gtk_widget_show (GTK_WIDGET (box)); dlg->file_size_label = gtk_label_new (""); gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (dlg->file_size_label), FALSE, FALSE, 0); target = webx_jpeg_target_new (); dlg->target_list = g_slist_append (dlg->target_list, target); radio = gtk_radio_button_new_with_label (NULL, _("JPEG")); dlg->radio_list = g_slist_append (dlg->radio_list, radio); group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)); target = NULL; dlg->target_list = g_slist_append (dlg->target_list, target); radio = gtk_radio_button_new_with_label (group, _("JPEG 2000")); dlg->radio_list = g_slist_append (dlg->radio_list, radio); group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)); target = webx_png8_target_new (); dlg->target_list = g_slist_append (dlg->target_list, target); radio = gtk_radio_button_new_with_label (group, _("PNG-8")); dlg->radio_list = g_slist_append (dlg->radio_list, radio); group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)); target = webx_png24_target_new (); dlg->target_list = g_slist_append (dlg->target_list, target); radio = gtk_radio_button_new_with_label (group, _("PNG-24")); dlg->radio_list = g_slist_append (dlg->radio_list, radio); group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)); target = webx_gif_target_new (); dlg->target_list = g_slist_append (dlg->target_list, target); radio = gtk_radio_button_new_with_label (group, _("GIF")); dlg->radio_list = g_slist_append (dlg->radio_list, radio); group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)); align = 0; row = 0; for (target_list = dlg->target_list, radio_list = dlg->radio_list; target_list && radio_list; target_list = target_list->next, radio_list = radio_list->next) { gtk_table_attach (GTK_TABLE (format_table), GTK_WIDGET (radio_list->data), align, align+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); g_signal_connect (radio_list->data, "toggled", G_CALLBACK (webx_dialog_format_changed), dlg); gtk_widget_show (GTK_WIDGET (radio_list->data)); if (target_list->data) { gtk_box_pack_start (GTK_BOX (toolbox), GTK_WIDGET (target_list->data), FALSE, FALSE, 0); g_signal_connect (target_list->data, "target-changed", G_CALLBACK (webx_dialog_target_changed), dlg); } else { gtk_widget_set_sensitive (GTK_WIDGET (radio_list->data), FALSE); } align ^= 1; if (! align) row++; } gtk_widget_show_all (GTK_WIDGET (format_table)); dlg->target = NULL; tbscroll = gtk_scrolled_window_new (NULL, NULL); label = gtk_image_new_from_stock (GIMP_STOCK_RESIZE, GTK_ICON_SIZE_MENU); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), tbscroll, label); gtk_container_set_border_width (GTK_CONTAINER (tbscroll), 4); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (tbscroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (tbscroll), GTK_SHADOW_NONE); gtk_widget_show (GTK_WIDGET (tbscroll)); toolbox = gtk_vbox_new (FALSE, 0); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (tbscroll), GTK_WIDGET (toolbox)); gtk_container_set_border_width (GTK_CONTAINER (toolbox), 4); gtk_widget_show (GTK_WIDGET (toolbox)); dlg->resize = webx_resize_widget_new (bg_width, bg_height); gtk_box_pack_start (GTK_BOX (toolbox), dlg->resize, FALSE, FALSE, 0); g_signal_connect (WEBX_RESIZE_WIDGET (dlg->resize), "resized", G_CALLBACK (webx_dialog_target_resized), dlg); webx_resize_widget_set_default_size (WEBX_RESIZE_WIDGET (dlg->resize), bg_width, bg_height); gtk_widget_show (dlg->resize); dlg->crop = webx_crop_widget_new (bg_width, bg_height); gtk_box_pack_start (GTK_BOX (toolbox), dlg->crop, FALSE, FALSE, 0); g_signal_connect (WEBX_CROP_WIDGET (dlg->crop), "crop-changed", G_CALLBACK (webx_dialog_crop_changed), dlg); gtk_widget_show (dlg->crop); preview_box = gtk_vbox_new (TRUE, 0); gtk_paned_pack2 (GTK_PANED (splitter), GTK_WIDGET (preview_box), TRUE, FALSE); gtk_widget_show (GTK_WIDGET (preview_box)); dlg->preview = webx_preview_new (bg_width, bg_height); gtk_box_pack_start (GTK_BOX (preview_box), dlg->preview, TRUE, TRUE, 0); g_signal_connect (WEBX_PREVIEW (dlg->preview), "crop-changed", G_CALLBACK (webx_dialog_crop_changed), dlg); gtk_widget_show (GTK_WIDGET (dlg->preview)); dlg->progress_bar = gimp_progress_bar_new (); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), dlg->progress_bar, FALSE, FALSE, 0); if (webx_prefs.dlg_splitpos) { gtk_paned_set_position (GTK_PANED (splitter), webx_prefs.dlg_splitpos); } return GTK_WIDGET (dlg); }
GimpPDBStatusType script_fu_interface (SFScript *script, gint start_arg) { GtkWidget *dialog; GtkWidget *menu; GtkWidget *vbox; GtkWidget *vbox2; GtkSizeGroup *group; GSList *list; gchar *title; gint i; static gboolean gtk_initted = FALSE; /* Simply return if there is already an interface. This is an * ugly workaround for the fact that we can not process two * scripts at a time. */ if (sf_interface != NULL) { gchar *message = g_strdup_printf ("%s\n\n%s", _("Script-Fu cannot process two scripts " "at the same time."), _("You are already running the \"%s\" script.")); g_message (message, sf_interface->title); g_free (message); return GIMP_PDB_CANCEL; } g_return_val_if_fail (script != NULL, FALSE); if (!gtk_initted) { INIT_I18N(); gimp_ui_init ("script-fu", TRUE); gtk_initted = TRUE; } sf_status = GIMP_PDB_SUCCESS; sf_interface = g_slice_new0 (SFInterface); sf_interface->widgets = g_new0 (GtkWidget *, script->n_args); sf_interface->title = script_fu_script_get_title (script); title = g_strdup_printf (_("Script-Fu: %s"), sf_interface->title); sf_interface->dialog = dialog = gimp_dialog_new (title, "script-fu", NULL, 0, gimp_standard_help_func, script->name, GIMP_STOCK_RESET, RESPONSE_RESET, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); g_free (title); gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), RESPONSE_RESET, GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gimp_window_set_transient (GTK_WINDOW (dialog)); g_signal_connect (dialog, "response", G_CALLBACK (script_fu_response), script); g_signal_connect_swapped (dialog, "destroy", G_CALLBACK (script_fu_interface_quit), script); gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); vbox = gtk_vbox_new (FALSE, 12); gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), vbox, TRUE, TRUE, 0); gtk_widget_show (vbox); /* The argument table */ sf_interface->table = gtk_table_new (script->n_args - start_arg, 3, FALSE); gtk_table_set_col_spacings (GTK_TABLE (sf_interface->table), 6); gtk_table_set_row_spacings (GTK_TABLE (sf_interface->table), 6); gtk_box_pack_start (GTK_BOX (vbox), sf_interface->table, FALSE, FALSE, 0); gtk_widget_show (sf_interface->table); group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); for (i = start_arg; i < script->n_args; i++) { GtkWidget *widget = NULL; GtkObject *adj; gchar *label_text; gfloat label_yalign = 0.5; gint *ID_ptr = NULL; gint row = i; gboolean left_align = FALSE; SFArg *arg = &script->args[i]; row -= start_arg; /* we add a colon after the label; * some languages want an extra space here */ label_text = g_strdup_printf (_("%s:"), gettext (arg->label)); switch (arg->type) { case SF_IMAGE: case SF_DRAWABLE: case SF_LAYER: case SF_CHANNEL: case SF_VECTORS: switch (arg->type) { case SF_IMAGE: widget = gimp_image_combo_box_new (NULL, NULL); ID_ptr = &arg->value.sfa_image; break; case SF_DRAWABLE: widget = gimp_drawable_combo_box_new (NULL, NULL); ID_ptr = &arg->value.sfa_drawable; break; case SF_LAYER: widget = gimp_layer_combo_box_new (NULL, NULL); ID_ptr = &arg->value.sfa_layer; break; case SF_CHANNEL: widget = gimp_channel_combo_box_new (NULL, NULL); ID_ptr = &arg->value.sfa_channel; break; case SF_VECTORS: widget = gimp_vectors_combo_box_new (NULL, NULL); ID_ptr = &arg->value.sfa_vectors; break; default: menu = NULL; break; } gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (widget), *ID_ptr, G_CALLBACK (gimp_int_combo_box_get_active), ID_ptr); break; case SF_COLOR: left_align = TRUE; widget = gimp_color_button_new (_("Script-Fu Color Selection"), COLOR_SAMPLE_WIDTH, COLOR_SAMPLE_HEIGHT, &arg->value.sfa_color, GIMP_COLOR_AREA_FLAT); gimp_color_button_set_update (GIMP_COLOR_BUTTON (widget), TRUE); g_signal_connect (widget, "color-changed", G_CALLBACK (gimp_color_button_get_color), &arg->value.sfa_color); break; case SF_TOGGLE: g_free (label_text); label_text = NULL; widget = gtk_check_button_new_with_mnemonic (gettext (arg->label)); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), arg->value.sfa_toggle); g_signal_connect (widget, "toggled", G_CALLBACK (gimp_toggle_button_update), &arg->value.sfa_toggle); break; case SF_VALUE: case SF_STRING: widget = gtk_entry_new (); gtk_widget_set_size_request (widget, TEXT_WIDTH, -1); gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE); gtk_entry_set_text (GTK_ENTRY (widget), arg->value.sfa_value); break; case SF_TEXT: { GtkWidget *view; GtkTextBuffer *buffer; widget = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_set_size_request (widget, TEXT_WIDTH, -1); view = gtk_text_view_new (); gtk_container_add (GTK_CONTAINER (widget), view); gtk_widget_show (view); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); gtk_text_view_set_editable (GTK_TEXT_VIEW (view), TRUE); gtk_text_buffer_set_text (buffer, arg->value.sfa_value, -1); label_yalign = 0.0; } break; case SF_ADJUSTMENT: switch (arg->default_value.sfa_adjustment.type) { case SF_SLIDER: arg->value.sfa_adjustment.adj = (GtkAdjustment *) gimp_scale_entry_new (GTK_TABLE (sf_interface->table), 0, row, label_text, SLIDER_WIDTH, -1, arg->value.sfa_adjustment.value, arg->default_value.sfa_adjustment.lower, arg->default_value.sfa_adjustment.upper, arg->default_value.sfa_adjustment.step, arg->default_value.sfa_adjustment.page, arg->default_value.sfa_adjustment.digits, TRUE, 0.0, 0.0, NULL, NULL); gtk_entry_set_activates_default (GIMP_SCALE_ENTRY_SPINBUTTON (arg->value.sfa_adjustment.adj), TRUE); break; default: g_warning ("unexpected adjustment type: %d", arg->default_value.sfa_adjustment.type); /* fallthrough */ case SF_SPINNER: left_align = TRUE; widget = gimp_spin_button_new (&adj, arg->value.sfa_adjustment.value, arg->default_value.sfa_adjustment.lower, arg->default_value.sfa_adjustment.upper, arg->default_value.sfa_adjustment.step, arg->default_value.sfa_adjustment.page, 0, 0, arg->default_value.sfa_adjustment.digits); gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE); arg->value.sfa_adjustment.adj = GTK_ADJUSTMENT (adj); break; } g_signal_connect (arg->value.sfa_adjustment.adj, "value-changed", G_CALLBACK (gimp_double_adjustment_update), &arg->value.sfa_adjustment.value); break; case SF_FILENAME: case SF_DIRNAME: if (arg->type == SF_FILENAME) widget = gtk_file_chooser_button_new (_("Script-Fu File Selection"), GTK_FILE_CHOOSER_ACTION_OPEN); else widget = gtk_file_chooser_button_new (_("Script-Fu Folder Selection"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); if (arg->value.sfa_file.filename) gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), arg->value.sfa_file.filename); g_signal_connect (widget, "selection-changed", G_CALLBACK (script_fu_file_callback), &arg->value.sfa_file); break; case SF_FONT: widget = gimp_font_select_button_new (_("Script-Fu Font Selection"), arg->value.sfa_font); g_signal_connect_swapped (widget, "font-set", G_CALLBACK (script_fu_font_callback), &arg->value.sfa_font); break; case SF_PALETTE: widget = gimp_palette_select_button_new (_("Script-Fu Palette Selection"), arg->value.sfa_palette); g_signal_connect_swapped (widget, "palette-set", G_CALLBACK (script_fu_palette_callback), &arg->value.sfa_palette); break; case SF_PATTERN: left_align = TRUE; widget = gimp_pattern_select_button_new (_("Script-Fu Pattern Selection"), arg->value.sfa_pattern); g_signal_connect_swapped (widget, "pattern-set", G_CALLBACK (script_fu_pattern_callback), &arg->value.sfa_pattern); break; case SF_GRADIENT: left_align = TRUE; widget = gimp_gradient_select_button_new (_("Script-Fu Gradient Selection"), arg->value.sfa_gradient); g_signal_connect_swapped (widget, "gradient-set", G_CALLBACK (script_fu_gradient_callback), &arg->value.sfa_gradient); break; case SF_BRUSH: left_align = TRUE; widget = gimp_brush_select_button_new (_("Script-Fu Brush Selection"), arg->value.sfa_brush.name, arg->value.sfa_brush.opacity, arg->value.sfa_brush.spacing, arg->value.sfa_brush.paint_mode); g_signal_connect_swapped (widget, "brush-set", G_CALLBACK (script_fu_brush_callback), &arg->value.sfa_brush); break; case SF_OPTION: #if GTK_CHECK_VERSION (2, 24, 0) widget = gtk_combo_box_text_new (); #else widget = gtk_combo_box_new_text (); #endif for (list = arg->default_value.sfa_option.list; list; list = g_slist_next (list)) { #if GTK_CHECK_VERSION (2, 24, 0) gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), gettext (list->data)); #else gtk_combo_box_append_text (GTK_COMBO_BOX (widget), gettext (list->data)); #endif } gtk_combo_box_set_active (GTK_COMBO_BOX (widget), arg->value.sfa_option.history); g_signal_connect (widget, "changed", G_CALLBACK (script_fu_combo_callback), &arg->value.sfa_option); break; case SF_ENUM: widget = gimp_enum_combo_box_new (g_type_from_name (arg->default_value.sfa_enum.type_name)); gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (widget), arg->value.sfa_enum.history); g_signal_connect (widget, "changed", G_CALLBACK (gimp_int_combo_box_get_active), &arg->value.sfa_enum.history); break; case SF_DISPLAY: break; } if (widget) { if (label_text) { gimp_table_attach_aligned (GTK_TABLE (sf_interface->table), 0, row, label_text, 0.0, label_yalign, widget, 2, left_align); g_free (label_text); } else { gtk_table_attach (GTK_TABLE (sf_interface->table), widget, 0, 3, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show (widget); } if (left_align) gtk_size_group_add_widget (group, widget); } sf_interface->widgets[i] = widget; } g_object_unref (group); /* the script progress bar */ vbox2 = gtk_vbox_new (FALSE, 6); gtk_box_pack_end (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0); gtk_widget_show (vbox2); sf_interface->progress_bar = gimp_progress_bar_new (); gtk_box_pack_start (GTK_BOX (vbox2), sf_interface->progress_bar, FALSE, FALSE, 0); gtk_widget_show (sf_interface->progress_bar); sf_interface->progress_label = gtk_label_new (NULL); gtk_misc_set_alignment (GTK_MISC (sf_interface->progress_label), 0.0, 0.5); gtk_label_set_ellipsize (GTK_LABEL (sf_interface->progress_label), PANGO_ELLIPSIZE_MIDDLE); gimp_label_set_attributes (GTK_LABEL (sf_interface->progress_label), PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC, -1); gtk_box_pack_start (GTK_BOX (vbox2), sf_interface->progress_label, FALSE, FALSE, 0); gtk_widget_show (sf_interface->progress_label); gtk_widget_show (dialog); gtk_main (); return sf_status; }