Hello, I fixed and improved a few thing in the IFS Compose plugin. I know I should use bugzilla. The reasons I write here are: The existing bugreports are 1.2, while I fixed it in 1.3 (except #82472 fix, which I also backported to 1.2), I'm not sure how to handle this. Some issues were just side effects of an underlying real problem (#82466, #82473). Bug #82470 I fixed as a side effect of a larger change. The other things are not in bugzilla at all (like Save/Load), I don't have separate patches for them, and don't like the perspective of creating a dozen of individual reports and separating the patches only for the sake of bugzillization of the whole thing. Please critize/check/apply the attached patch (against 1.3.11) and tell me what to do with: nor #82472 Flip button doesn't act on all selected objects (I attached the backport to this one) min #82466 Toggling between Simple/Full in IfsCompose changes preview min #82473 IfsCompose disable Undo/Redo button when nothing to be undo enh #82470 IfsCompose filter: location of 'New' and 'Delete' button not... and what to do generally in situations like this. IFS Compose changes: * implemented Save and Load * made Flip to act on all selected transformations, fixes #82472 * moved New/Delete from action area below other buttons, fixes #82470 * fixed Delete to be insensitive when num of transforms == 2 * Undo/Redo made insensitive when there's nothing to update, and avoided creation of bogus undo levels during color updates, fixes #82466, #82473, and other queer undo/redo behaviour * set alpha of all colors to 1.0 -- ifscompose ignores alpha anyway, and default value (122???) makes the color selection dialog pretty confusing * made Undo, Redo, Select All, Recompute Center menu items visible as buttons, so people who don't try right clicking in the design area know about them * changed confusing numeric frame title to "Transformation n" * changed the button layout to two centered groups (it looked approximately this way before too, but probably only incidentally) Thanks in advance, Yeti --- gimp-1.3.11.orig/plug-ins/ifscompose/ifscompose.c 2002-12-03 20:42:41.000000000 +0100 +++ gimp-1.3.11/plug-ins/ifscompose/ifscompose.c 2003-02-01 23:25:34.000000000 +0100 @@ -169,6 +169,12 @@ GtkWidget *stretch_button; gint stretch_handler; + GtkWidget *undo_button; + GtkWidget *undo_menu_item; + GtkWidget *redo_button; + GtkWidget *redo_menu_item; + GtkWidget *delete_button; + GtkWidget *preview; guchar *preview_data; gint preview_iterations; @@ -278,6 +284,10 @@ gpointer data); static void ifs_compose_delete_callback (GtkWidget *widget, gpointer data); +static void ifs_compose_load_callback (GtkWidget *widget, + gpointer data); +static void ifs_compose_save_callback (GtkWidget *widget, + gpointer data); static void ifs_compose_ok_callback (GtkWidget *widget, GtkWidget *window); @@ -300,6 +310,8 @@ static gint undo_num = 0; static gint undo_start = 0; +static gchar ifsfile_path[PATH_MAX] = { '\0' }; + /* num_elements = 0, signals not inited */ static IfsComposeVals ifsvals = { @@ -387,8 +399,6 @@ INIT_I18N_UI(); - /* kill (getpid(), 19); */ - /* Get the active drawable */ active_drawable = gimp_drawable_get (param[2].data.d_drawable); @@ -786,10 +796,10 @@ GIMP_STOCK_RESET, ifs_compose_defaults_callback, NULL, NULL, NULL, FALSE, FALSE, - GTK_STOCK_DELETE, ifs_compose_delete_callback, + GTK_STOCK_OPEN, ifs_compose_load_callback, NULL, NULL, NULL, FALSE, FALSE, - GTK_STOCK_NEW, ifs_compose_new_callback, + GTK_STOCK_SAVE, ifs_compose_save_callback, NULL, NULL, NULL, FALSE, FALSE, GTK_STOCK_CANCEL, gtk_widget_destroy, @@ -850,10 +860,10 @@ /* Iterations and preview options */ - hbox = gtk_hbox_new (FALSE, 4); + hbox = gtk_hbox_new (TRUE, 4); gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0); - alignment = gtk_alignment_new (1.0, 0.5, 0.5, 0.0); + alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); gtk_box_pack_start (GTK_BOX (hbox), alignment, TRUE, TRUE, 0); util_hbox = gtk_hbox_new (FALSE, 4); @@ -891,7 +901,7 @@ gtk_widget_show (alignment); gtk_widget_show (util_hbox); - alignment = gtk_alignment_new (1.0, 0.5, 0.5, 0.0); + alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); gtk_box_pack_start (GTK_BOX (hbox), alignment, TRUE, TRUE, 0); util_hbox = gtk_hbox_new (FALSE, 4); @@ -924,6 +934,70 @@ gtk_widget_show (alignment); gtk_widget_show (hbox); + /* second util row */ + hbox = gtk_hbox_new (TRUE, 4); + gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0); + + alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); + gtk_box_pack_start (GTK_BOX (hbox), alignment, TRUE, TRUE, 0); + + util_hbox = gtk_hbox_new (FALSE, 4); + gtk_container_add (GTK_CONTAINER (alignment), util_hbox); + + ifsD->undo_button = gtk_button_new_with_label(_("Undo")); + gtk_box_pack_start(GTK_BOX(util_hbox), ifsD->undo_button, + TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(ifsD->undo_button), "clicked", + G_CALLBACK(undo), NULL); + gtk_widget_set_sensitive(ifsD->undo_button, FALSE); + gtk_widget_show(ifsD->undo_button); + + ifsD->redo_button = gtk_button_new_with_label (_("Redo")); + gtk_box_pack_start (GTK_BOX (util_hbox), ifsD->redo_button, + TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(ifsD->redo_button), "clicked", + G_CALLBACK(redo), NULL); + gtk_widget_set_sensitive(ifsD->redo_button, FALSE); + gtk_widget_show(ifsD->redo_button); + + button = gtk_button_new_with_label (_("Select All")); + gtk_box_pack_start (GTK_BOX (util_hbox), button, + TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(design_area_select_all_callback), NULL); + gtk_widget_show (button); + + gtk_widget_show (alignment); + gtk_widget_show (util_hbox); + + alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); + gtk_box_pack_start (GTK_BOX (hbox), alignment, TRUE, TRUE, 0); + + util_hbox = gtk_hbox_new (FALSE, 4); + gtk_container_add (GTK_CONTAINER (alignment), util_hbox); + + ifsD->delete_button = gtk_button_new_with_label (_("Delete")); + g_signal_connect(G_OBJECT(ifsD->delete_button), "clicked", + G_CALLBACK(ifs_compose_delete_callback), NULL); + gtk_box_pack_start(GTK_BOX(util_hbox), ifsD->delete_button, TRUE, TRUE, 0); + gtk_widget_show(ifsD->delete_button); + + button = gtk_button_new_with_label(_("New")); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(ifs_compose_new_callback), NULL); + gtk_box_pack_start (GTK_BOX (util_hbox), button, TRUE, TRUE, 0); + gtk_widget_show (button); + + button = gtk_button_new_with_label (_("Recompute center")); + gtk_box_pack_start (GTK_BOX (util_hbox), button, TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(recompute_center_cb), NULL); + gtk_widget_show (button); + + gtk_widget_show (util_hbox); + gtk_widget_show (alignment); + gtk_widget_show (hbox); + /* The current transformation frame */ ifsD->current_frame = gtk_frame_new (NULL); @@ -1190,25 +1264,29 @@ 'R', GDK_MOD1_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - menu_item = gtk_menu_item_new_with_label (_("Undo")); - gtk_menu_shell_append (GTK_MENU_SHELL (ifsDesign->op_menu), menu_item); - gtk_widget_show (menu_item); - g_signal_connect (G_OBJECT (menu_item), "activate", - G_CALLBACK (undo), - NULL); - gtk_widget_add_accelerator (menu_item, + ifsD->undo_menu_item = gtk_menu_item_new_with_label(_("Undo")); + gtk_menu_shell_append(GTK_MENU_SHELL(ifsDesign->op_menu), + ifsD->undo_menu_item); + gtk_widget_set_sensitive(ifsD->undo_menu_item, FALSE); + gtk_widget_show(ifsD->undo_menu_item); + g_signal_connect(G_OBJECT(ifsD->undo_menu_item), "activate", + G_CALLBACK(undo), + NULL); + gtk_widget_add_accelerator(ifsD->undo_menu_item, "activate", accel_group, 'Z', GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - menu_item = gtk_menu_item_new_with_label(_("Redo")); - gtk_menu_shell_append (GTK_MENU_SHELL (ifsDesign->op_menu), menu_item); - gtk_widget_show(menu_item); - g_signal_connect (G_OBJECT (menu_item), "activate", + ifsD->redo_menu_item = gtk_menu_item_new_with_label(_("Redo")); + gtk_menu_shell_append (GTK_MENU_SHELL (ifsDesign->op_menu), + ifsD->redo_menu_item); + gtk_widget_set_sensitive(ifsD->redo_menu_item, FALSE); + gtk_widget_show(ifsD->redo_menu_item); + g_signal_connect (G_OBJECT (ifsD->redo_menu_item), "activate", G_CALLBACK (redo), NULL); - gtk_widget_add_accelerator(menu_item, + gtk_widget_add_accelerator(ifsD->redo_menu_item, "activate", accel_group, 'R', GDK_CONTROL_MASK, @@ -1415,7 +1493,7 @@ gint btot=0; gint gtot=0; gint mtot=0; - for (jj=0;jj<ifsvals.subdivide;jj++) + for (jj = 0; jj < ifsvals.subdivide; jj++) { ptr = data + 3 * (((j-band_y)*ifsvals.subdivide+jj)*ifsvals.subdivide*width + @@ -1424,7 +1502,7 @@ maskptr = mask + ((j-band_y)*ifsvals.subdivide+jj)*ifsvals.subdivide*width + i*ifsvals.subdivide; - for (ii=0;ii<ifsvals.subdivide;ii++) + for (ii = 0; ii < ifsvals.subdivide; ii++) { maskval = *maskptr++; mtot += maskval; @@ -1524,9 +1602,13 @@ static void set_current_element (gint index) { + gchar *frame_name = g_strdup_printf(_("Transformation %s"), + elements[index]->name); + ifsD->current_element = index; - gtk_frame_set_label(GTK_FRAME(ifsD->current_frame),elements[index]->name); + gtk_frame_set_label(GTK_FRAME(ifsD->current_frame),frame_name); + g_free(frame_name); update_values(); } @@ -1564,7 +1646,7 @@ widget->style->fg_gc[widget->state], cx, cy - 10, cx, cy + 10); - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) { aff_element_draw(elements[i], element_selected[i], widget->allocation.width, @@ -1593,10 +1675,10 @@ gdouble width = widget->allocation.width; gdouble height = widget->allocation.height; - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) aff_element_compute_trans(elements[i],width,height, ifsvals.center_x, ifsvals.center_y); - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) aff_element_compute_boundary(elements[i],width,height, elements, ifsvals.num_elements); @@ -1634,7 +1716,7 @@ ifsD->current_element = -1; /* Find out where the button press was */ - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) { if ( ipolygon_contains(elements[i]->click_boundary,event->x,event->y) ) { @@ -1652,7 +1734,7 @@ && ( (ifsD->current_element<0) || !element_selected[ifsD->current_element] )) { - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) element_selected[i] = 0; } @@ -1665,7 +1747,7 @@ ifsDesign->num_selected = 0; ifsDesign->op_xcenter = 0.0; ifsDesign->op_ycenter = 0.0; - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) { if (element_selected[i]) { @@ -1772,7 +1854,7 @@ } } - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) if (element_selected[i]) { if (ifsDesign->num_selected == ifsvals.num_elements) @@ -1784,7 +1866,7 @@ cx = ifsDesign->op_center_x * width; cy = ifsDesign->op_center_y * width; - aff2_apply(&trans,cx,cy,&cx,&cy); + aff2_apply(&trans, cx, cy, &cx, &cy); ifsvals.center_x = cx / width; ifsvals.center_y = cy / width; } @@ -1843,9 +1925,9 @@ new_index = (undo_start+undo_cur)%UNDO_LEVELS; /* remove any redo elements or the oldest element if necessary */ - for (j=new_index;to_delete>0;j=(j+1)%UNDO_LEVELS,to_delete--) + for (j = new_index; to_delete > 0; j = (j+1)%UNDO_LEVELS, to_delete--) { - for (i=0;i<undo_ring[j].ifsvals.num_elements;i++) + for (i = 0; i < undo_ring[j].ifsvals.num_elements; i++) if (undo_ring[j].elements[i]) aff_element_free(undo_ring[j].elements[i]); g_free(undo_ring[j].elements); @@ -1857,11 +1939,16 @@ undo_ring[new_index].element_selected = g_new(gint,ifsvals.num_elements); undo_ring[new_index].current_element = ifsD->current_element; - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) { undo_ring[new_index].elements[i] = NULL; undo_ring[new_index].element_selected[i] = element_selected[i]; } + + gtk_widget_set_sensitive(ifsD->undo_button, undo_cur >= 0); + gtk_widget_set_sensitive(ifsD->undo_menu_item, undo_cur >= 0); + gtk_widget_set_sensitive(ifsD->redo_button, undo_cur != undo_num-1); + gtk_widget_set_sensitive(ifsD->redo_menu_item, undo_cur != undo_num-1); } static void @@ -1910,7 +1997,7 @@ undo_ring[el].current_element = tcurrent; /* now swap back any unchanged elements */ - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) if (!elements[i]) { elements[i] = undo_ring[el].elements[i]; @@ -1936,6 +2023,11 @@ undo_exchange((undo_start+undo_cur)%UNDO_LEVELS); undo_cur--; } + + gtk_widget_set_sensitive(ifsD->undo_button, undo_cur >= 0); + gtk_widget_set_sensitive(ifsD->undo_menu_item, undo_cur >= 0); + gtk_widget_set_sensitive(ifsD->redo_button, undo_cur != undo_num-1); + gtk_widget_set_sensitive(ifsD->redo_menu_item, undo_cur != undo_num-1); } static void @@ -1946,6 +2038,11 @@ undo_cur++; undo_exchange((undo_start+undo_cur)%UNDO_LEVELS); } + + gtk_widget_set_sensitive(ifsD->undo_button, undo_cur >= 0); + gtk_widget_set_sensitive(ifsD->undo_menu_item, undo_cur >= 0); + gtk_widget_set_sensitive(ifsD->redo_button, undo_cur != undo_num-1); + gtk_widget_set_sensitive(ifsD->redo_menu_item, undo_cur != undo_num-1); } static void @@ -1954,7 +2051,7 @@ { gint i; - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) element_selected[i] = TRUE; design_area_redraw(); @@ -2002,6 +2099,7 @@ ColorMap *color_map = g_new (ColorMap,1); + gimp_rgb_set_alpha(data, 1.0); color_map->color = data; color_map->fixed_point = fixed_point; color_map->hbox = gtk_hbox_new (FALSE,2); @@ -2048,6 +2146,9 @@ color_map_color_changed_cb (GtkWidget *widget, ColorMap *color_map) { + if (ifsD->in_update) + return; + undo_begin (); undo_update (ifsD->current_element); @@ -2065,11 +2166,11 @@ color_map_update (ColorMap *color_map) { gimp_color_button_set_color (GIMP_COLOR_BUTTON (color_map->button), - color_map->color); + color_map->color); if (color_map->fixed_point) gimp_color_area_set_color (GIMP_COLOR_AREA (color_map->orig_preview), - color_map->color); + color_map->color); } static void @@ -2097,10 +2198,9 @@ cur->v.simple_color = GTK_TOGGLE_BUTTON(widget)->active; ifsD->current_vals.simple_color = cur->v.simple_color; if (cur->v.simple_color) - { - aff_element_compute_color_trans(cur); - val_changed_update(); - } + aff_element_compute_color_trans(cur); + + val_changed_update(); simple_color_set_sensitive(); } @@ -2364,7 +2464,7 @@ if (save_undo) undo_begin(); - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) { if (save_undo) undo_update(i); @@ -2378,7 +2478,7 @@ ifsvals.center_x = center_x/ifsvals.num_elements; ifsvals.center_y = center_y/ifsvals.num_elements; - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) { aff_element_decompose_trans(elements[i],&elements[i]->trans, 1,ifsvals.aspect_ratio, @@ -2387,7 +2487,7 @@ if (width > 1 && height > 1) { - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) aff_element_compute_trans(elements[i],width,height, ifsvals.center_x, ifsvals.center_y); design_area_redraw(); @@ -2414,8 +2514,29 @@ flip_check_button_callback (GtkWidget *widget, gpointer data) { - ifsD->current_vals.flip = GTK_TOGGLE_BUTTON(widget)->active; - val_changed_update (); + guint i; + gdouble width = ifsDesign->area->allocation.width; + gdouble height = ifsDesign->area->allocation.height; + gint active = GTK_TOGGLE_BUTTON(widget)->active; + + if (ifsD->in_update) + return; + + undo_begin(); + for (i = 0; i < ifsvals.num_elements; i++) { + if (element_selected[i]) { + undo_update(i); + elements[i]->v.flip = active; + aff_element_compute_trans(elements[i], width, height, + ifsvals.center_x, ifsvals.center_y); + } + } + + update_values(); + design_area_redraw(); + + if (ifsD->auto_preview) + ifs_compose_preview(); } static void @@ -2428,7 +2549,7 @@ ifsvals.aspect_ratio = (gdouble)ifsD->drawable_height/ifsD->drawable_width; - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) aff_element_free(elements[i]); count_for_naming = 0; @@ -2497,6 +2618,191 @@ design_area_redraw (); } +/* show a modal dialog */ +void +yeti_message_dialog(GtkMessageType type, GtkWindow *parent, + gchar *title, gchar *message) +{ + GtkWidget *dlg; + + dlg = gtk_message_dialog_new(parent, GTK_DIALOG_MODAL, + type, GTK_BUTTONS_OK, message); + if (title) + gtk_window_set_title(GTK_WINDOW(dlg), title); + gtk_window_set_wmclass(GTK_WINDOW(dlg), "message", "Gimp"); + gtk_dialog_run(GTK_DIALOG(dlg)); + gtk_widget_destroy(dlg); +} + +/* save an ifs file */ +static void +ifsfile_save(GtkWidget *widget, GtkWidget *file_select) +{ + gchar *str = ifsvals_stringify(&ifsvals, elements); + FILE *fh; + char *warning = NULL; + + strcpy(ifsfile_path, + gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_select))); + fh = fopen(ifsfile_path, "w"); + if (fh) { + fputs(str, fh); + fclose(fh); + } + else + warning = g_strdup_printf(_("Cannot save into file `%s'.\n" + "Check the path and permissions.\n"), + ifsfile_path); + + free(str); + if (warning) { + yeti_message_dialog(GTK_MESSAGE_ERROR, GTK_WINDOW(file_select), + "Save failed", warning); + g_free(warning); + } + gtk_widget_destroy(file_select); +} + +/* replace ifsvals and elements with specified new values + * recompute and update everything necessary */ +static void +ifsfile_replace_ifsvals(IfsComposeVals *new_ifsvals, + AffElement **new_elements) +{ + gdouble width = ifsDesign->area->allocation.width; + gdouble height = ifsDesign->area->allocation.height; + guint i; + + for (i = 0; i < ifsvals.num_elements; i++) + aff_element_free(elements[i]); + free(elements); + + ifsvals = *new_ifsvals; + elements = new_elements; + for (i = 0; i < ifsvals.num_elements; i++) { + aff_element_compute_trans(elements[i], width, height, + ifsvals.center_x, ifsvals.center_y); + aff_element_compute_color_trans(elements[i]); + } + + element_selected = g_realloc(element_selected, + ifsvals.num_elements * sizeof(gint)); + for (i = 0; i < ifsvals.num_elements; i++) + element_selected[i] = FALSE; + + if (ifsOptD) { + value_pair_update(ifsOptD->iterations_pair); + value_pair_update(ifsOptD->subdivide_pair); + value_pair_update(ifsOptD->radius_pair); + value_pair_update(ifsOptD->memory_pair); + } + + set_current_element(0); + element_selected[0] = TRUE; + recompute_center(FALSE); + + if (ifsD->selected_orig) + g_free(ifsD->selected_orig); + + ifsD->selected_orig = g_new(AffElement, ifsvals.num_elements); +} + +/* load an ifs file */ +static void +ifsfile_load(GtkWidget *widget, GtkWidget *file_select) +{ + FILE *fh; + guint size = 4096; + guint len, pos; + guchar *buffer; + AffElement **new_elements; + IfsComposeVals new_ifsvals; + gchar *warning = NULL; + + buffer = g_new(guchar, size); + strcpy(ifsfile_path, + gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_select))); + fh = fopen(ifsfile_path, "r"); + if (fh) { + pos = 0; + while ((len = fread(buffer + pos, 1, size - pos, fh)) == size-pos) { + pos = size; + size *= 2; + buffer = g_realloc(buffer, size); + } + fclose(fh); + + pos += len; + buffer[pos] = '\0'; + if (ifsvals_parse_string(buffer, &new_ifsvals, &new_elements)) { + guint i; + + undo_begin (); + for (i = 0; i < ifsvals.num_elements; i++) + undo_update(i); + + ifsfile_replace_ifsvals(&new_ifsvals, new_elements); + + if (ifsD->auto_preview) + ifs_compose_preview(); + + design_area_redraw(); + } + else + warning = g_strdup_printf(_("File `%s' doesn't seem to be " + "an IFS Compose file.\n"), ifsfile_path); + g_free(buffer); + } + else + warning = g_strdup_printf(_("Cannot open file `%s'.\n" + "Check the path and permissions.\n"), + ifsfile_path); + + if (warning) { + yeti_message_dialog(GTK_MESSAGE_ERROR, GTK_WINDOW(file_select), + _("Load failed"), warning); + g_free(warning); + } + + gtk_widget_destroy(file_select); +} + +static void +ifs_compose_save_callback(GtkWidget *widget, gpointer data) +{ + GtkWidget *file_select; + + file_select = gtk_file_selection_new(_("Save as IFS file")); + gimp_help_connect(file_select, gimp_standard_help_func, + "filters/ifscompose.html"); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_select), + ifsfile_path); + g_signal_connect (G_OBJECT(GTK_FILE_SELECTION(file_select)->ok_button), + "clicked", G_CALLBACK(ifsfile_save), file_select); + g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(file_select)->cancel_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + file_select); + gtk_widget_show(file_select); +} + +static void +ifs_compose_load_callback(GtkWidget *widget, gpointer data) +{ + GtkWidget *file_select; + + file_select = gtk_file_selection_new(_("Load IFS file")); + gimp_help_connect(file_select, gimp_standard_help_func, + "filters/ifscompose.html"); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_select), + ifsfile_path); + g_signal_connect (G_OBJECT(GTK_FILE_SELECTION(file_select)->ok_button), + "clicked", G_CALLBACK(ifsfile_load), file_select); + g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(file_select)->cancel_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + file_select); + gtk_widget_show(file_select); +} + static void ifs_compose_new_callback (GtkWidget *widget, gpointer data) @@ -2519,7 +2825,7 @@ element_selected = g_realloc (element_selected, ifsvals.num_elements * sizeof (gint)); - for (i=0;i<ifsvals.num_elements-1;i++) + for (i = 0; i < ifsvals.num_elements-1; i++) element_selected[i] = FALSE; element_selected[ifsvals.num_elements-1] = TRUE; @@ -2535,6 +2841,9 @@ if (ifsD->auto_preview) ifs_compose_preview (); + + if (ifsvals.num_elements > 2) + gtk_widget_set_sensitive(ifsD->delete_button, TRUE); } static void @@ -2543,8 +2852,6 @@ { gint i; gint new_current; - if (ifsvals.num_elements <= 2) - return; undo_begin(); undo_update(ifsD->current_element); @@ -2562,7 +2869,7 @@ ifsvals.num_elements--; - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) if (element_selected[i]) { new_current = i; @@ -2576,6 +2883,9 @@ if (ifsD->auto_preview) ifs_compose_preview (); + + if (ifsvals.num_elements == 2) + gtk_widget_set_sensitive(ifsD->delete_button, FALSE); } static gint @@ -2589,7 +2899,7 @@ if (iterations > ifsD->preview_iterations) iterations = ifsD->preview_iterations; - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) aff_element_compute_trans(elements[i], width, height, ifsvals.center_x, ifsvals.center_y); @@ -2597,7 +2907,7 @@ iterations,&ifsvals,0,height, ifsD->preview_data,NULL,NULL,TRUE); - for (i=0;i<ifsvals.num_elements;i++) + for (i = 0; i < ifsvals.num_elements; i++) aff_element_compute_trans(elements[i], ifsDesign->area->allocation.width, ifsDesign->area->allocation.height, @@ -2632,7 +2942,7 @@ gimp_rgb_get_uchar (&color, &rc, &gc, &bc); ptr = ifsD->preview_data; - for (i=0; i < width * height; i++) + for (i = 0; i < width * height; i++) { *ptr++ = rc; *ptr++ = gc; --- gimp-1.3.11.orig/plug-ins/ifscompose/ifscompose_storage.c 2002-05-14 01:30:03.000000000 +0200 +++ gimp-1.3.11/plug-ins/ifscompose/ifscompose_storage.c 2003-01-30 21:48:53.000000000 +0100 @@ -129,6 +129,8 @@ if (token != G_TOKEN_RIGHT_CURLY) return G_TOKEN_RIGHT_CURLY; + gimp_rgb_set_alpha(result, 1.0); + return G_TOKEN_NONE; }