/* * STORE FRAME MANAGER */ #include "../lib/version.h" #include "filename.h" #include "base_frame_manager.h" #include "store_frame_manager.h" #include "stdio.h" #include "interface.h" #include "ops_buttons.h" #include "general.h" #include "actionarea.h" #include "fileops.h" #include #include #include #include "tools.h" #include "rect_selectP.h" #include "menus.h" #include "../lib/wire/iodebug.h" #include "../lib/wire/wirebuffer.h" #include "../lib/wire/enums.h" #include "plug_in.h" #include "undo.h" #include "../lib/wire/wirebuffer.h" #include "../lib/wire/enums.h" #include "plug_in.h" #include "spline.h" #include "layer_pvt.h" #include "buttons/play_forward.xpm" #include "buttons/play_forward_is.xpm" #include "buttons/play_backwards.xpm" #include "buttons/play_backwards_is.xpm" #include "buttons/forward.xpm" #include "buttons/forward_is.xpm" #include "buttons/backwards.xpm" #include "buttons/backwards_is.xpm" #include "buttons/stop.xpm" #include "buttons/stop_is.xpm" extern GSList *display_list; extern int initial_frames_loaded; extern Tool *active_tool; extern GSList *display_list; extern int initial_frames_loaded; typedef gint (*CallbackAction) (GtkWidget *, gpointer); #define STORE_LIST_WIDTH 200 #define STORE_LIST_HEIGHT 150 #define BUTTON_EVENT_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | \ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK #define NORMAL 0 #define SELECTED 1 #define INSENSITIVE 2 static gint TYPE_TO_ADD; static gint sfm_onionskin (GtkWidget *, gpointer); static gint sfm_onionskin_on (GtkWidget *, gpointer); static gint sfm_onionskin_fgbg (GtkWidget *, gpointer); static gint sfm_auto_save (GtkWidget *, gpointer); static gint sfm_set_aofi (GtkWidget *, gpointer); static gint sfm_aofi (GtkWidget *, gpointer); static void sfm_unset_aofi (GDisplay *); static void sfm_play_backwards_callback (GtkWidget *, gpointer); static void sfm_play_forward_callback (GtkWidget *, gpointer); static void sfm_flip_backwards_callback (GtkWidget *, gpointer); static void sfm_flip_forward_callback (GtkWidget *, gpointer); static void sfm_stop_callback (GtkWidget *, gpointer); static void sfm_store_clear (GDisplay*); static store* sfm_store_create (GDisplay*, GImage*, int, int, int); static void sfm_store_select (GtkCList *, gint, gint, GdkEventButton *, gpointer); static void sfm_store_unselect (GtkCList *, gint, gint, GdkEventButton *, gpointer); static void sfm_store_set_option (GtkCList *, gint, gpointer); static void sfm_store_set_op (GDisplay *, gint, gint); static void sfm_store_make_cur (GDisplay *, int); static void sfm_store_add_create_dialog (GDisplay *disp); static void sfm_store_change_frame_create_dialog (GDisplay *disp); static gint sfm_adv_backwards_callback (GtkWidget *, gpointer); static gint sfm_adv_forward_callback (GtkWidget *, gpointer); /* static MenuItem sfm_store_entries[] = { {"/Store/Add", 0, 0, sfm_store_add, NULL, NULL, NULL}, {"/Store/Delete", 0, 0, sfm_store_delete, NULL, NULL, NULL}, {"/Store/Raise", 0, 0, sfm_store_raise, NULL, NULL, NULL}, {"/Store/Lower", 0, 0, sfm_store_lower, NULL, NULL, NULL}, {"/Store/Save", 0, 0, sfm_store_save, NULL, NULL, NULL}, {"/Store/Save All", 0, 0, sfm_store_save_all, NULL, NULL, NULL}, {"/Store/Revert", 0, 0, sfm_store_revert, NULL, NULL, NULL}, {"/Store/Change Frame", 0, 0, sfm_store_change_frame, NULL, NULL, NULL}, {"/Dir/Recent Src", 0, 0, sfm_store_recent_src, NULL, NULL, NULL}, {"/Dir/Recent Dest", 0, 0, sfm_store_recent_dest, NULL, NULL, NULL}, {"/Dir/Load Smart", 0, 0, sfm_store_load_smart, NULL, NULL, NULL}, { NULL, 0, 0, NULL, NULL, NULL, NULL }, }; */ static gint sfm_check (GDisplay *disp) { if (!disp->bfm) return 1; if (!disp->bfm->sfm) return 1; return 0; } static gint sfm_delete_callback (GtkWidget *w, GdkEvent *e, gpointer data) { store_frame_manager *sfm = ((GDisplay*)data)->bfm->sfm; bfm_onionskin_rm ((GDisplay*)data); sfm_store_clear ((GDisplay*)data); if (GTK_WIDGET_VISIBLE (sfm->shell)) gtk_widget_hide (sfm->shell); return TRUE; } void sfm_create_gui (GDisplay *disp) { GtkWidget *check_button, *button, *hbox, *flip_box, *scrolled_window, *utilbox, *slider, *menubar, *event_box, *label, *vbox; GtkTooltips *tooltip; char tmp[256]; char *check_names[3] = { "Auto Save", "Set AofI", "AofI" }; CallbackAction check_callbacks[3] = { sfm_auto_save, sfm_set_aofi, sfm_aofi }; OpsButton flip_button[] = { { play_backwards_xpm, play_backwards_is_xpm, sfm_play_backwards_callback, "Play Backwards", NULL, NULL, NULL, NULL, NULL, NULL }, { backwards_xpm, backwards_is_xpm, sfm_flip_backwards_callback, "Flip Backward", NULL, NULL, NULL, NULL, NULL, NULL }, { stop_xpm, stop_is_xpm, sfm_stop_callback, "Stop", NULL, NULL, NULL, NULL, NULL, NULL }, { forward_xpm, forward_is_xpm, sfm_flip_forward_callback, "Flip Forward", NULL, NULL, NULL, NULL, NULL, NULL }, { play_forward_xpm, play_forward_is_xpm, sfm_play_forward_callback, "Play Forward", NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, 0, 0, NULL, NULL, NULL, NULL } }; gchar *store_col_name[6] = {"RO", "Adv", "F", "Bg", "*", "Filename"}; if (disp->gimage->filename == NULL){ g_message ("You need to have saved the filename out first, also it should probably be of the form FILE.0001.EXT"); return; } disp->bfm->sfm->accel_group = gtk_accel_group_new (); /* the shell */ disp->bfm->sfm->shell = gtk_dialog_new (); gtk_window_set_wmclass (GTK_WINDOW (disp->bfm->sfm->shell), "sfm", PROGRAM_NAME); gtk_window_set_policy (GTK_WINDOW (disp->bfm->sfm->shell), FALSE, TRUE, FALSE); sprintf (tmp, "Flipbook for %s", disp->gimage->filename); gtk_window_set_title (GTK_WINDOW (disp->bfm->sfm->shell), tmp); /* gtk_window_set_transient_for (GTK_WINDOW (disp->bfm->sfm->shell), GTK_WINDOW (disp->shell)); */ /* handle the wm close signal */ gtk_signal_connect (GTK_OBJECT (disp->bfm->sfm->shell), "delete_event", GTK_SIGNAL_FUNC (sfm_delete_callback), disp); /* pull down menu */ #if 0 menubar = build_menu (sfm_store_entries, disp->bfm->sfm->accel_group); #endif menus_get_sfm_store_menu (&menubar, &disp->bfm->sfm->accel_group, disp); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (disp->bfm->sfm->shell)->vbox), menubar, FALSE, FALSE, 0); gtk_widget_reparent (menubar, GTK_WIDGET (GTK_DIALOG (disp->bfm->sfm->shell)->vbox)); gtk_widget_show (menubar); /* gtk_window_add_accel_group (GTK_DIALOG (disp->shell), disp->bfm->sfm->accel_group); */ /* check buttons */ hbox = gtk_hbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (hbox), 1); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (disp->bfm->sfm->shell)->vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); disp->bfm->sfm->autosave = check_button = gtk_check_button_new_with_label (check_names[0]); gtk_signal_connect (GTK_OBJECT (check_button), "clicked", (GtkSignalFunc) check_callbacks[0], disp); gtk_box_pack_start (GTK_BOX (hbox), check_button, FALSE, FALSE, 0); gtk_widget_show (check_button); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, check_button, "Saves all stores not marked RO before removing them from list", NULL); check_button = gtk_check_button_new_with_label (check_names[1]); gtk_signal_connect (GTK_OBJECT (check_button), "clicked", (GtkSignalFunc) check_callbacks[1], disp); gtk_box_pack_start (GTK_BOX (hbox), check_button, FALSE, FALSE, 0); gtk_widget_show (check_button); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, check_button, "Sets the area of interest", NULL); disp->bfm->sfm->aofi = check_button = gtk_check_button_new_with_label (check_names[2]); gtk_signal_connect (GTK_OBJECT (check_button), "clicked", (GtkSignalFunc) check_callbacks[2], disp); gtk_box_pack_start (GTK_BOX (hbox), check_button, FALSE, FALSE, 0); gtk_widget_show (check_button); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, check_button, "Enable area of interest", NULL); /* advance */ button = gtk_button_new_with_label ("<"); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) sfm_adv_backwards_callback, disp); gtk_widget_show (button); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, button, "Loads a new frame (current frame number - step size) into each store marked A.", NULL); disp->bfm->sfm->num_to_adv = gtk_spin_button_new ( GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 100, 1, 1, 0)), 1.0, 0); gtk_box_pack_start (GTK_BOX (hbox), disp->bfm->sfm->num_to_adv, FALSE, FALSE, 2); gtk_widget_show (disp->bfm->sfm->num_to_adv); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, disp->bfm->sfm->num_to_adv, "Step size", NULL); button = gtk_button_new_with_label (">"); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) sfm_adv_forward_callback, disp); gtk_widget_show (button); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, button, "Loads a new frame (current frame number + step size) into each store marked A.", NULL); /* store window */ scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_widget_set_usize (scrolled_window, 200, 150); gtk_box_pack_start(GTK_BOX (GTK_DIALOG (disp->bfm->sfm->shell)->vbox), scrolled_window, TRUE, TRUE, 0); event_box = gtk_event_box_new (); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_window), event_box); gtk_widget_show (event_box); disp->bfm->sfm->store_list = gtk_clist_new_with_titles( 6, store_col_name); gtk_clist_set_column_justification (GTK_CLIST(disp->bfm->sfm->store_list), 0, GTK_JUSTIFY_LEFT); gtk_clist_set_column_justification (GTK_CLIST(disp->bfm->sfm->store_list), 1, GTK_JUSTIFY_LEFT); gtk_clist_set_column_justification (GTK_CLIST(disp->bfm->sfm->store_list), 2, GTK_JUSTIFY_LEFT); gtk_clist_set_column_justification (GTK_CLIST(disp->bfm->sfm->store_list), 3, GTK_JUSTIFY_LEFT); gtk_clist_set_column_justification (GTK_CLIST(disp->bfm->sfm->store_list), 4, GTK_JUSTIFY_LEFT); gtk_clist_set_column_justification (GTK_CLIST(disp->bfm->sfm->store_list), 5, GTK_JUSTIFY_LEFT); gtk_clist_column_title_active (GTK_CLIST(disp->bfm->sfm->store_list), 0); gtk_clist_column_title_active (GTK_CLIST(disp->bfm->sfm->store_list), 1); gtk_clist_column_title_active (GTK_CLIST(disp->bfm->sfm->store_list), 2); gtk_clist_column_title_active (GTK_CLIST(disp->bfm->sfm->store_list), 3); gtk_clist_set_column_width (GTK_CLIST(disp->bfm->sfm->store_list), 0, 20); gtk_clist_set_column_width (GTK_CLIST(disp->bfm->sfm->store_list), 1, 30); gtk_clist_set_column_width (GTK_CLIST(disp->bfm->sfm->store_list), 2, 10); gtk_clist_set_column_width (GTK_CLIST(disp->bfm->sfm->store_list), 3, 20); gtk_clist_set_column_width (GTK_CLIST(disp->bfm->sfm->store_list), 4, 10); gtk_clist_set_column_width (GTK_CLIST(disp->bfm->sfm->store_list), 5, strlen (prune_pathname (disp->gimage->filename))*10); gtk_signal_connect(GTK_OBJECT(disp->bfm->sfm->store_list), "select_row", GTK_SIGNAL_FUNC(sfm_store_select), disp); gtk_signal_connect(GTK_OBJECT(disp->bfm->sfm->store_list), "unselect_row", GTK_SIGNAL_FUNC(sfm_store_unselect), disp); gtk_signal_connect(GTK_OBJECT(disp->bfm->sfm->store_list), "click-column", GTK_SIGNAL_FUNC(sfm_store_set_option), disp); gtk_clist_set_selection_mode (GTK_CLIST(disp->bfm->sfm->store_list), GTK_SELECTION_BROWSE); /* It isn't necessary to shadow the border, but it looks nice :) */ gtk_clist_set_shadow_type (GTK_CLIST(disp->bfm->sfm->store_list), GTK_SHADOW_OUT); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, event_box, "RO - read only. This store will not be saved\n" "A - advance. This store is affected by the advance controls\n" "F - flip. This store is affected by the flip book controls\n" "Bg - background. This is the src in a clone and the bg in the onionskin\n" "* - modified. This store has been modified", NULL); /* Add the CList widget to the vertical box and show it. */ gtk_container_add(GTK_CONTAINER(event_box), disp->bfm->sfm->store_list); gtk_widget_show(disp->bfm->sfm->store_list); gtk_widget_show (scrolled_window); /* flip buttons */ flip_box = ops_button_box_new2 (disp->bfm->sfm->shell, tool_tips, flip_button, disp); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (disp->bfm->sfm->shell)->vbox), flip_box, FALSE, FALSE, 0); gtk_widget_show (flip_box); /* onion skinning */ hbox = gtk_hbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (hbox), 1); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (disp->bfm->sfm->shell)->vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); disp->bfm->sfm->onionskin = gtk_check_button_new_with_label ("onionskin"); gtk_signal_connect (GTK_OBJECT (disp->bfm->sfm->onionskin), "clicked", (GtkSignalFunc) sfm_onionskin_on, disp); gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (disp->bfm->sfm->onionskin), FALSE, FALSE, 0); gtk_widget_show (GTK_WIDGET (disp->bfm->sfm->onionskin)); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, disp->bfm->sfm->onionskin, "Checked when onionskining is on", NULL); utilbox = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (hbox), utilbox, TRUE, TRUE, 0); gtk_widget_show (utilbox); disp->bfm->sfm->onionskin_val = (GtkWidget*) gtk_adjustment_new (1.0, 0.0, 1.0, .1, .1, 0.0); slider = gtk_hscale_new (GTK_ADJUSTMENT (disp->bfm->sfm->onionskin_val)); gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DISCONTINUOUS); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_RIGHT); gtk_box_pack_start (GTK_BOX (utilbox), slider, TRUE, TRUE, 0); gtk_signal_connect (GTK_OBJECT (disp->bfm->sfm->onionskin_val), "value_changed", (GtkSignalFunc) sfm_onionskin, disp); gtk_widget_show (slider); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, slider, "Sets the opacity for onion skinning.\n" "LMB to drag slider\n" "MMB to jump", NULL); button = gtk_button_new_with_label ("Bg/Fg"); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) sfm_onionskin_fgbg, disp); gtk_widget_show (button); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, button, "Flips between the fg and bg store", NULL); /* src & dest labels */ hbox = gtk_hbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (hbox), 1); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (disp->bfm->sfm->shell)->vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); vbox = gtk_vbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (vbox), 1); gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); gtk_widget_show (vbox); label = gtk_label_new ("SRC DIR"); gtk_box_pack_start(GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_widget_show (label); label = gtk_label_new ("DEST DIR"); gtk_box_pack_start(GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_widget_show (label); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_ALWAYS, GTK_POLICY_NEVER); gtk_box_pack_start(GTK_BOX (hbox), scrolled_window, TRUE, TRUE, 0); gtk_widget_show (scrolled_window); hbox = gtk_vbox_new (FALSE, 1); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_window), hbox); gtk_container_border_width (GTK_CONTAINER (hbox), 1); gtk_widget_show (hbox); event_box = gtk_event_box_new (); gtk_box_pack_start (GTK_BOX (hbox), event_box, FALSE, FALSE, 0); gtk_widget_show (event_box); disp->bfm->sfm->src_dir = gtk_label_new ("SRC DIR"); gtk_label_set_justify (GTK_LABEL(disp->bfm->sfm->src_dir), GTK_JUSTIFY_LEFT); gtk_container_add (GTK_CONTAINER (event_box), disp->bfm->sfm->src_dir); gtk_widget_show (disp->bfm->sfm->src_dir); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, event_box, "Src dir and file name", NULL); event_box = gtk_event_box_new (); gtk_box_pack_start (GTK_BOX (hbox), event_box, FALSE, FALSE, 0); gtk_widget_show (event_box); disp->bfm->sfm->dest_dir = gtk_label_new ("DEST DIR"); gtk_label_set_justify (GTK_LABEL(disp->bfm->sfm->dest_dir), GTK_JUSTIFY_LEFT); gtk_container_add (GTK_CONTAINER(event_box), disp->bfm->sfm->dest_dir); gtk_widget_show (disp->bfm->sfm->dest_dir); tooltip = gtk_tooltips_new (); gtk_tooltips_set_tip (tooltip, event_box, "Dest dir and file name", NULL); /* add store */ sfm_store_add_image (disp->gimage, disp, 0, 1, 0); bfm_set_fg (disp, disp->gimage); sfm_unset_aofi (disp); sfm_store_make_cur(disp, 0); gtk_widget_show (disp->bfm->sfm->shell); } /* * FLIP BOOK CONTROLS */ static gint sfm_backwards (store_frame_manager *fm) { gint row = fm->fg - 1 < 0 ? g_slist_length (fm->stores)-1 : fm->fg - 1; while (!((store*)g_slist_nth (fm->stores, row)->data)->flip && row != fm->fg) { row = row - 1 < 0 ? g_slist_length (fm->stores) - 1: row - 1; } gtk_clist_select_row (GTK_CLIST(fm->store_list), row, 5); return TRUE; } static void sfm_play_backwards_callback (GtkWidget *w, gpointer data) { sfm_play_backwards ((GDisplay*) data); } void sfm_play_backwards (GDisplay* gdisplay) { store_frame_manager *fm; gint row=0; if (sfm_check (gdisplay)) return; bfm_onionskin_rm (gdisplay); if (!gdisplay || row == -1) return; fm = gdisplay->bfm->sfm; if (!fm->play) { fm->play = gtk_timeout_add (100, (GtkFunction) sfm_backwards, fm); } } static gint sfm_forward (store_frame_manager *fm) { gint row = fm->fg + 1 == g_slist_length (fm->stores) ? 0 : fm->fg + 1; while (!((store*)g_slist_nth (fm->stores, row)->data)->flip && row != fm->fg) { row = row + 1 == g_slist_length (fm->stores) ? 0 : row + 1; } gtk_clist_select_row (GTK_CLIST(fm->store_list), row, 5); return TRUE; } static void sfm_play_forward_callback (GtkWidget *w, gpointer data) { sfm_play_forward((GDisplay*) data); } void sfm_play_forward (GDisplay* gdisplay) { store_frame_manager *fm; gint row=0; if (sfm_check (gdisplay)) return; bfm_onionskin_rm (gdisplay); if (!gdisplay || row == -1) return; fm = gdisplay->bfm->sfm; if (!fm->play) { fm->play = gtk_timeout_add (100, (GtkFunction) sfm_forward, fm); } } static void sfm_flip_backwards_callback (GtkWidget *w, gpointer data) { sfm_flip_backwards ((GDisplay*) data); } void sfm_flip_backwards (GDisplay* gdisplay) { store_frame_manager *fm; gint row=0; if (sfm_check (gdisplay)) { return; } bfm_onionskin_rm (gdisplay); if (!gdisplay || row == -1) return; fm = gdisplay->bfm->sfm; row = fm->fg - 1 < 0 ? g_slist_length (fm->stores)-1 : fm->fg - 1; while (!((store*)g_slist_nth (fm->stores, row)->data)->flip && row != fm->fg) { row = row - 1 < 0 ? g_slist_length (fm->stores) - 1: row - 1; } gtk_clist_select_row (GTK_CLIST(fm->store_list), row, 5); } static void sfm_flip_forward_callback (GtkWidget *w, gpointer data) { sfm_flip_forward ((GDisplay*) data); } void sfm_flip_forward (GDisplay* gdisplay) { store_frame_manager *fm; gint row=0; if (sfm_check (gdisplay)) { return; } bfm_onionskin_rm (gdisplay); if (!gdisplay || row == -1) return; fm = gdisplay->bfm->sfm; row = fm->fg + 1 == g_slist_length (fm->stores) ? 0 : fm->fg + 1; while (!((store*)g_slist_nth (fm->stores, row)->data)->flip && row != fm->fg) { row = row + 1 == g_slist_length (fm->stores) ? 0 : row + 1; } gtk_clist_select_row (GTK_CLIST(fm->store_list), row, 5); } static void sfm_stop_callback (GtkWidget *w, gpointer data) { sfm_stop ((GDisplay*) data); } void sfm_stop (GDisplay* gdisplay) { store_frame_manager *fm; if (sfm_check (gdisplay)) return; fm = gdisplay->bfm->sfm; bfm_onionskin_rm (gdisplay); if (fm->play) { gtk_timeout_remove (fm->play); fm->play = 0; } } /* * ADVANCE */ static gint sfm_adv_backwards_callback (GtkWidget *w, gpointer data) { return sfm_adv_backwards ((GDisplay*)data); } gint sfm_adv_backwards (GDisplay *disp) { store_frame_manager *fm; gint num_to_adv; gint row=0, cur_frame, new_frame, flag=0, frame; char* temp_path = 0; char* temp_name; GImage *gimage=NULL; GSList *list=NULL, *l=NULL; store *item, *i; if (sfm_check (disp)) { return 1; } fm = disp->bfm->sfm; num_to_adv = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(fm->num_to_adv)); bfm_onionskin_rm (disp); list = fm->stores; while (list) { flag = 0; item = (store*) list->data; cur_frame = filename_get_frame_number (item->gimage->filename); new_frame = cur_frame - num_to_adv; if (item->advance && !item->special) { l = fm->stores; while (l && !flag) { i = (store*) l->data; if (!i->special) { frame = filename_get_frame_number (i->gimage->filename); if (frame == new_frame) { item->new_gimage = i->gimage; i->gimage->ref_count++; if (item->bg) bfm_set_bg (disp, item->new_gimage); i->remove = 0; gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 5, prune_filename (item->new_gimage->filename)); if (i->gimage->dirty) gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, "*"); else gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, ""); flag = 1; } l = g_slist_next (l); } } } if (!flag && item->advance) { /* load frame from disk */ if (fm->load_smart) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->dest_dir, disp->bfm->dest_name, new_frame); } else { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, new_frame); } if (item->fg) { temp_name = prune_filename(temp_path); if (file_load (temp_path, temp_name, disp)) { gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 5, temp_name); gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, ""); disp->ID = disp->gimage->ID; item->new_gimage = disp->gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); } else if (fm->load_smart) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, new_frame); temp_name = prune_filename(temp_path); if (file_load (temp_path, temp_name, disp)) { gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 5, temp_name); gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, ""); disp->ID = disp->gimage->ID; item->new_gimage = disp->gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); } else { item->new_gimage = item->gimage; item->remove = 0; if (item->bg) bfm_set_bg (disp, item->new_gimage); } } else { item->new_gimage = item->gimage; item->remove = 0; if (item->bg) bfm_set_bg (disp, item->new_gimage); } } else { temp_name = prune_filename(temp_path); if ((gimage = file_load_without_display (temp_path, temp_name, disp))) { item->new_gimage = gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 5, temp_name); gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, ""); } else if (fm->load_smart) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, new_frame); temp_name = prune_filename(temp_path); if ((gimage = file_load_without_display (temp_path, temp_name, disp))) { item->new_gimage = gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 5, temp_name); gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, ""); } else { item->new_gimage = item->gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); item->remove = 0; } } else { item->new_gimage = item->gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); item->remove = 0; } } } list = g_slist_next (list); row ++; } /* save stores and delete images */ list = fm->stores; while (list) { item = (store*) list->data; if (item->advance) { if (!item->readonly && item->gimage->dirty && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(fm->autosave))) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->dest_dir, disp->bfm->dest_name, filename_get_frame_number(item->gimage->filename) ); file_save (item->gimage->ID, temp_path, prune_filename(temp_path)); } if (item->remove) { gimage_delete (item->gimage); } item->gimage = item->new_gimage; if (item->fg) sfm_store_make_cur (disp, fm->fg); item->new_gimage = NULL; item->remove = 1; } list = g_slist_next (list); } if (temp_path) free(temp_path); return 1; } static gint sfm_adv_forward_callback (GtkWidget *w, gpointer data) { return sfm_adv_forward ((GDisplay*)data); } gint sfm_adv_forward (GDisplay* disp) { store_frame_manager *fm; gint num_to_adv; gint row=0, cur_frame, new_frame, flag=0, frame; char* temp_path = 0; char* temp_name; GImage *gimage=NULL; GSList *list=NULL, *l=NULL; store *item, *i; if (sfm_check (disp)) { return 1; } fm = disp->bfm->sfm; num_to_adv = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(fm->num_to_adv)); bfm_onionskin_rm (disp); list = fm->stores; while (list) { flag = 0; item = (store*) list->data; cur_frame = filename_get_frame_number (item->gimage->filename); new_frame = cur_frame + num_to_adv; if (item->advance && !item->special) { l = fm->stores; while (l && !flag) { i = (store*) l->data; if (!i->special) { frame = filename_get_frame_number (i->gimage->filename); if (frame == new_frame) { item->new_gimage = i->gimage; i->gimage->ref_count++; i->remove = 0; gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 5, prune_filename (item->new_gimage->filename)); if (i->gimage->dirty) gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, "*"); else gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, ""); if (item->bg) bfm_set_bg (disp, item->new_gimage); flag = 1; } l = g_slist_next (l); } } } if (!flag && item->advance) { /* load frame from disk */ if (fm->load_smart) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->dest_dir, disp->bfm->dest_name, new_frame); } else { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, new_frame); } if (item->fg) { temp_name = prune_filename(temp_path); if (file_load (temp_path, temp_name, disp)) { gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 5, temp_name); gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, ""); disp->ID = disp->gimage->ID; item->new_gimage = disp->gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); } else if (fm->load_smart) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, new_frame); temp_name = prune_filename(temp_path); if (file_load (temp_path, temp_name, disp)) { gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 5, temp_name); gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, ""); disp->ID = disp->gimage->ID; item->new_gimage = disp->gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); } else { item->new_gimage = item->gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); item->remove = 0; } } else { item->new_gimage = item->gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); item->remove = 0; } } else { temp_name = prune_filename(temp_path); if ((gimage = file_load_without_display (temp_path, temp_name, disp))) { item->new_gimage = gimage; gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 5, temp_name); gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, ""); } else if (fm->load_smart) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, new_frame); temp_name = prune_filename(temp_path); if ((gimage = file_load_without_display (temp_path, temp_name, disp))) { item->new_gimage = gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 5, temp_name); gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 4, ""); } else { item->new_gimage = item->gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); item->remove = 0; } } else { item->new_gimage = item->gimage; if (item->bg) bfm_set_bg (disp, item->new_gimage); item->remove = 0; } } } list = g_slist_next (list); row ++; } /* save stores and delete images */ list = fm->stores; while (list) { item = (store*) list->data; if (item->advance) { if (!item->readonly && item->gimage->dirty && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(fm->autosave))) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->dest_dir, disp->bfm->dest_name, filename_get_frame_number(item->gimage->filename) ); file_save (item->gimage->ID, temp_path, prune_filename(temp_path)); } if (item->remove) { gimage_delete (item->gimage); } item->gimage = item->new_gimage; if (item->fg) sfm_store_make_cur (disp, fm->fg); item->new_gimage = NULL; item->remove = 1; } list = g_slist_next (list); } if (temp_path) free(temp_path); return 1; } /* * ONION SKIN */ static char onionskin_off = 1; static gint sfm_onionskin (GtkWidget *w, gpointer data) { store_frame_manager *fm = ((GDisplay*) data)->bfm->sfm; if (fm->bg == -1 || fm->bg == fm->fg) { e_printf ("ERROR: you must select a bg\n"); if (((GtkAdjustment*)fm->onionskin_val)->value != 1) gtk_adjustment_set_value (GTK_ADJUSTMENT(((GDisplay*)data)->bfm->sfm->onionskin_val), 1); return 1; } if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(((GDisplay*)data)->bfm->sfm->onionskin)) && onionskin_off) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(((GDisplay*)data)->bfm->sfm->onionskin), TRUE); bfm_onionskin_display (((GDisplay*) data), ((GtkAdjustment*)fm->onionskin_val)->value, fm->s_x, fm->s_y, fm->e_x, fm->e_y); return 1; } static gint sfm_onionskin_on (GtkWidget *w, gpointer data) { store_frame_manager *fm = ((GDisplay*) data)->bfm->sfm; if (fm->bg == -1 || fm->bg == fm->fg) { e_printf ("ERROR: you must select a bg\n"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(((GDisplay*)data)->bfm->sfm->onionskin), FALSE); return 1; } if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(((GDisplay*)data)->bfm->sfm->onionskin))) { onionskin_off = 1; /* rm onionskin */ if (GTK_ADJUSTMENT(((GDisplay*)data)->bfm->sfm->onionskin_val)->value != 1) { gtk_adjustment_set_value (GTK_ADJUSTMENT(((GDisplay*)data)->bfm->sfm->onionskin_val), 1); } bfm_onionskin_rm ((GDisplay*)data); } else { onionskin_off = 0; /* set onionskin */ bfm_onionskin_display (((GDisplay*) data), ((GtkAdjustment*)fm->onionskin_val)->value, fm->s_x, fm->s_y, fm->e_x, fm->e_y); } return 1; } static gint sfm_onionskin_fgbg (GtkWidget *w, gpointer data) { store_frame_manager *fm = ((GDisplay*) data)->bfm->sfm; if (fm->bg == -1 || fm->bg == fm->fg) { e_printf ("ERROR: you must select a bg\n"); return 1; } if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(((GDisplay*)data)->bfm->sfm->onionskin))) { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(((GDisplay*)data)->bfm->sfm->onionskin), TRUE); /* bfm_onionskin_display (((GDisplay*) data), ((GtkAdjustment*)fm->onionskin_val)->value, fm->s_x, fm->s_y, fm->e_x, fm->e_y); */ } if (((GtkAdjustment*)((GDisplay*)data)->bfm->sfm->onionskin_val)->value) gtk_adjustment_set_value (GTK_ADJUSTMENT(((GDisplay*)data)->bfm->sfm->onionskin_val), 0); else gtk_adjustment_set_value (GTK_ADJUSTMENT(((GDisplay*)data)->bfm->sfm->onionskin_val), 1); return 1; } void sfm_onionskin_set_offset (GDisplay* disp, int x, int y) { layer_translate2 (disp->bfm->bg->active_layer, -x, -y, disp->bfm->sfm->s_x, disp->bfm->sfm->s_y, disp->bfm->sfm->e_x, disp->bfm->sfm->e_y); } void sfm_onionskin_rm (GDisplay* disp) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(disp->bfm->sfm->onionskin))) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(disp->bfm->sfm->onionskin), FALSE); } /* * STORE */ static void sfm_store_clear (GDisplay* disp) { store_frame_manager *fm; store *item; gint l; fm = disp->bfm->sfm; l = g_slist_length(fm->stores); while (l > 0) { item = (store*)g_slist_nth(fm->stores, 0)->data; if (strcmp(item->gimage->filename, disp->gimage->filename) != 0) gimage_delete(item->gimage); fm->stores = g_slist_remove (fm->stores, (g_slist_nth (fm->stores, 0))->data); l = g_slist_length(fm->stores); } g_free(disp->bfm->sfm); g_free(disp->bfm); disp->bfm=NULL; } void sfm_store_add (GtkWidget *w, gpointer data) { bfm_onionskin_rm((GDisplay *)data); sfm_store_add_create_dialog ((GDisplay *)data); } static void sfm_store_remove (GDisplay *disp) { store_frame_manager *fm = disp->bfm->sfm; store *item = (store*) (g_slist_nth (fm->stores, fm->fg)); gint new_fg, i; gint l = g_slist_length (fm->stores); bfm_onionskin_rm (disp); if (item->gimage->dirty) { } new_fg = fm->fg < l-1 ? fm->fg : fm->fg - 1; if (fm->fg == fm->bg) { fm->bg = new_fg; gtk_clist_set_text (GTK_CLIST (fm->store_list), fm->bg, 3, "Bg"); } gtk_clist_remove (GTK_CLIST(fm->store_list), fm->fg); fm->stores = g_slist_remove (fm->stores, (g_slist_nth (fm->stores, fm->fg))->data); gtk_clist_select_row (GTK_CLIST(fm->store_list), new_fg, 5); for (i=0; istores, i)))->bg) fm->bg = i; } } void sfm_store_delete (GtkWidget *w, gpointer data) { store_frame_manager *fm = ((GDisplay *)data)->bfm->sfm; gint l = g_slist_length (fm->stores); bfm_onionskin_rm ((GDisplay*)data); if (l == 1) { e_printf ("ERROR: cannot rm last store\n"); return; } sfm_store_remove ((GDisplay *)data); } void sfm_store_raise (GtkWidget *w, gpointer data) { store_frame_manager *fm = ((GDisplay *)data)->bfm->sfm; store *item; bfm_onionskin_rm ((GDisplay*)data); if (!fm->fg) return; gtk_clist_swap_rows (GTK_CLIST(fm->store_list), fm->fg-1, fm->fg); item = (store*) g_slist_nth (fm->stores, fm->fg)->data; fm->stores = g_slist_remove (fm->stores, item); fm->stores = g_slist_insert (fm->stores, item, fm->fg-1); fm->bg = fm->bg == fm->fg ? fm->fg - 1 : fm->bg == fm->fg - 1 ? fm->fg : fm->bg; fm->fg --; } void sfm_store_lower (GtkWidget *w, gpointer data) { store_frame_manager *fm = ((GDisplay *)data)->bfm->sfm; store *item; gint l = g_slist_length (fm->stores); bfm_onionskin_rm ((GDisplay*)data); if (fm->fg == l-1) return; gtk_clist_swap_rows (GTK_CLIST(fm->store_list), fm->fg+1, fm->fg); item = (store*) g_slist_nth (fm->stores, fm->fg)->data; fm->stores = g_slist_remove (fm->stores, item); fm->stores = g_slist_insert (fm->stores, item, fm->fg+1); fm->bg = fm->bg == fm->fg ? fm->fg + 1 : fm->bg == fm->fg + 1 ? fm->fg : fm->bg; fm->fg ++; } void sfm_store_save (GtkWidget *w, gpointer data) { store_frame_manager *fm = ((GDisplay *)data)->bfm->sfm; char* temp_path; store *item = (store*) g_slist_nth (fm->stores, fm->fg)->data; bfm_onionskin_rm ((GDisplay*)data); if (item->readonly) { e_printf ("ERROR: trying to save a readonly file \n"); return; } temp_path = filename_build_path( ((GDisplay *)data)->bfm->dest_dir, ((GDisplay *)data)->bfm->dest_name, filename_get_frame_number(item->gimage->filename) ); if (file_save (item->gimage->ID, temp_path, prune_filename(temp_path))) gtk_clist_set_text (GTK_CLIST (fm->store_list), fm->fg, 4, ""); free(temp_path); } void sfm_store_save_all (GtkWidget *w, gpointer data) { store_frame_manager *fm = ((GDisplay *)data)->bfm->sfm; store *item; gint i, l = g_slist_length (fm->stores); char* temp_path; bfm_onionskin_rm ((GDisplay*)data); for (i=0; istores, i))->data; if (!item->readonly) { temp_path = filename_build_path( ((GDisplay *)data)->bfm->dest_dir, ((GDisplay *)data)->bfm->dest_name, filename_get_frame_number(item->gimage->filename) ); file_save (item->gimage->ID, temp_path, prune_filename(temp_path)); if (file_save (item->gimage->ID, temp_path, prune_filename(temp_path))) gtk_clist_set_text (GTK_CLIST (fm->store_list), i, 4, ""); free(temp_path); } } } void sfm_store_revert (GtkWidget *w, gpointer data) { store_frame_manager *fm = ((GDisplay *)data)->bfm->sfm; store *item = (store*) (g_slist_nth (fm->stores, fm->fg))->data; if (file_load (item->gimage->filename, prune_filename (item->gimage->filename), (GDisplay *)data)) { ((GDisplay *)data)->ID = ((GDisplay *)data)->gimage->ID; item->gimage = ((GDisplay *)data)->gimage; sfm_store_make_cur (((GDisplay *)data), fm->fg); gtk_clist_set_text (GTK_CLIST (fm->store_list), fm->fg, 5, prune_filename (item->gimage->filename)); gtk_clist_set_text (GTK_CLIST (fm->store_list), fm->fg, 4, ""); } } void sfm_store_change_frame (GtkWidget *w, gpointer data) { store_frame_manager *fm = ((GDisplay *)data)->bfm->sfm; store *item = (store*) (g_slist_nth (fm->stores, fm->fg))->data; char* temp_path; bfm_onionskin_rm ((GDisplay*)data); if (item->gimage->dirty && !item->readonly) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(fm->autosave))) { temp_path = filename_build_path( ((GDisplay *)data)->bfm->dest_dir, ((GDisplay *)data)->bfm->dest_name, filename_get_frame_number(item->gimage->filename) ); file_save (item->gimage->ID, temp_path, prune_filename(temp_path)); free(temp_path); } else d_printf ("WARNING: you just lost your changes to the file\n"); } sfm_store_change_frame_create_dialog (((GDisplay *)data)); } void sfm_set_dir_src (GDisplay *disp) { char* temp; store_frame_manager *fm = disp->bfm->sfm; temp = filename_build_label(disp->bfm->src_dir, disp->bfm->src_name); gtk_label_set_text(GTK_LABEL (fm->src_dir), temp); free(temp); } void sfm_store_recent_src (GtkWidget *w, gpointer data) { } void sfm_set_dir_dest (GDisplay *disp) { char* temp; store_frame_manager *fm = disp->bfm->sfm; temp = filename_build_label(disp->bfm->dest_dir, disp->bfm->dest_name); gtk_label_set_text(GTK_LABEL (fm->dest_dir), temp); free(temp); } void sfm_store_recent_dest (GtkWidget *w, gpointer data) { bfm_onionskin_rm ((GDisplay*)data); } void sfm_store_load_smart (GtkWidget *w, gpointer data) { GDisplay *display; display=(GDisplay *)data; ((GDisplay *)data)->bfm->sfm->load_smart = ((GDisplay *)data)->bfm->sfm->load_smart ? 0 : 1; bfm_onionskin_rm ((GDisplay*)data); } static store* sfm_store_create (GDisplay* disp, GImage* img, int active, int num, int readonly) { store *new_store; store_frame_manager *fm = disp->bfm->sfm; new_store = (store*) g_malloc (sizeof (store)); new_store->readonly = readonly ? 1 : 0; new_store->advance = 1; new_store->flip = 1; new_store->bg = 0; new_store->gimage = img; new_store->special = 0; new_store->remove = 1; if (readonly) gtk_clist_set_text (GTK_CLIST (fm->store_list), num, 0, "RO"); else gtk_clist_set_text (GTK_CLIST (fm->store_list), num, 0, ""); gtk_clist_set_text (GTK_CLIST (fm->store_list), num, 1, "A"); gtk_clist_set_text (GTK_CLIST (fm->store_list), num, 2, "F"); gtk_clist_set_text (GTK_CLIST (fm->store_list), num, 3, ""); if (img->dirty) gtk_clist_set_text (GTK_CLIST (fm->store_list), num, 4, "*"); else gtk_clist_set_text (GTK_CLIST (fm->store_list), num, 4, ""); gtk_clist_set_text (GTK_CLIST (fm->store_list), num, 5, prune_filename (img->filename)); if (active) gtk_clist_select_row (GTK_CLIST (fm->store_list), num, 5); if (!g_slist_length (fm->stores)) { bfm_set_dir_src (disp, img->filename); bfm_set_dir_dest (disp, img->filename); sfm_set_dir_src (disp); sfm_set_dir_dest (disp); } return new_store; } static void sfm_store_make_cur (GDisplay *gdisplay, int row) { store *item; store_frame_manager *fm; char tmp[256]; SplineTool *spline_tool=NULL; if (row == -1) return; fm = gdisplay->bfm->sfm; fm->fg = row; if (g_slist_length (fm->stores) <= row) return; item = (store*)(g_slist_nth (fm->stores, row)->data); item->fg = 1; /* shut down any spline tools associated with the current display's gimage. */ /* added 21December2004 - twh */ if(active_tool->type==SPLINE) { if(active_tool->private) { spline_tool=(SplineTool*)active_tool->private; if(spline_tool->active_spline && spline_tool->active_spline->drawn) spline_control(active_tool, PAUSE, gdisplay); } } /* display the new store */ gdisplay->gimage = item->gimage; gdisplay->ID = item->gimage->ID; gdisplays_update_title (gdisplay->gimage->ID); gdisplay_add_update_area (gdisplay, fm->s_x, fm->s_y, fm->e_x, fm->e_y); #if 0 if (active_tool->type == CLONE) clone_flip_image (); #endif bfm_set_fg (gdisplay, ((store*)(g_slist_nth (fm->stores, fm->fg)->data))->gimage); sprintf (tmp, "Flipbook for %s", gdisplay->gimage->filename); gtk_window_set_title (GTK_WINDOW (gdisplay->bfm->sfm->shell), tmp); /* restart any spline tools associated with the current display's new gimage. */ /* added 21December2004 - twh */ if(active_tool->type==SPLINE) { if(item->gimage->active_layer->sl.spline_tool) { spline_tool=(SplineTool*)item->gimage->active_layer->sl.spline_tool; active_tool->private=spline_tool; if(spline_tool->active_spline && !spline_tool->active_spline->drawn) spline_control(active_tool, RESUME, gdisplay); } } gdisplays_flush (); } static void sfm_store_select (GtkCList *w, gint row, gint col, GdkEventButton *event, gpointer client_pointer) { GDisplay *gdisplay = (GDisplay*) client_pointer; bfm_onionskin_rm (gdisplay); if (!gdisplay || row == -1) return; if (col != 5 && col != -1) { sfm_store_set_op (gdisplay, row, col); gtk_clist_select_row (GTK_CLIST (gdisplay->bfm->sfm->store_list), gdisplay->bfm->sfm->fg, 5); return; } sfm_store_make_cur (gdisplay, row); } static void sfm_store_unselect (GtkCList *w, gint row, gint col, GdkEventButton *event, gpointer client_pointer) { GDisplay *gdisplay = (GDisplay*) client_pointer; store_frame_manager *fm; bfm_onionskin_rm (gdisplay); if (!gdisplay) return; fm = gdisplay->bfm->sfm; /* gtk_clist_select_row (GTK_CLIST(fm->store_list), fm->fg, 0); */ if (col == 5) { ((store*)g_slist_nth (fm->stores, fm->fg)->data)->fg = 0; fm->fg = -1; } } void sfm_dirty (GDisplay* disp) { if (disp->gimage->dirty) gtk_clist_set_text (GTK_CLIST (disp->bfm->sfm->store_list), disp->bfm->sfm->fg, 4, "*"); else gtk_clist_set_text (GTK_CLIST (disp->bfm->sfm->store_list), disp->bfm->sfm->fg, 4, ""); } GDisplay * sfm_load_image_into_fm (GDisplay* disp, GImage *img) { store_frame_manager *fm = disp->bfm->sfm; char *text[6]={NULL, NULL, NULL, NULL, NULL, NULL}; store *new_store; gtk_clist_insert (GTK_CLIST (fm->store_list), fm->fg+1, text); new_store = sfm_store_create (disp, img, 0, fm->fg+1, 1); new_store->special = 1; fm->stores = g_slist_insert (fm->stores, new_store, fm->fg+1); return disp; } void sfm_set_bg (GDisplay *gdisplay) { store_frame_manager *fm; store *item; fm = gdisplay->bfm->sfm; item = (store*) (g_slist_nth (fm->stores, fm->fg))->data; gtk_clist_set_text (GTK_CLIST (fm->store_list), fm->fg, 3, "Bg"); fm->bg = fm->fg; } static void sfm_store_set_op (GDisplay *gdisplay, gint row, gint col) { store_frame_manager *fm; store *item; fm = gdisplay->bfm->sfm; if(-1 == row) return; item = (store*) g_slist_nth (fm->stores, row)->data; switch (col) { case 0: item->readonly = item->readonly ? 0 : 1; if (item->readonly) gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 0, "RO"); else gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 0, ""); break; case 1: item->advance = item->advance ? 0 : 1; if (item->advance) gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 1, "A"); else gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 1, ""); break; case 2: item->flip = item->flip ? 0 : 1; if (item->flip) gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 2, "F"); else gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 2, ""); break; case 3: if (fm->bg != -1 && fm->bg != row /*fm->fg*/) { ((store*) g_slist_nth (fm->stores, fm->bg)->data)->bg = 0; gtk_clist_set_text (GTK_CLIST (fm->store_list), fm->bg, 3, ""); fm->bg = -1; bfm_set_bg (gdisplay, 0); } item->bg = item->bg ? 0 : 1; if (item->bg) { gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 3, "Bg"); fm->bg = row; bfm_set_bg (gdisplay, ((store*)(g_slist_nth (fm->stores, fm->bg)->data))->gimage); } else { gtk_clist_set_text (GTK_CLIST (fm->store_list), row, 3, ""); fm->bg = -1; bfm_set_bg (gdisplay, 0); } break; default: break; } } static void sfm_store_set_option (GtkCList *w, gint col, gpointer client_pointer) { GDisplay *gdisplay = (GDisplay*) client_pointer; bfm_onionskin_rm (gdisplay); if (!gdisplay) return; sfm_store_set_op (gdisplay, gdisplay->bfm->sfm->fg, col); } void sfm_store_add_image (GImage *gimage, GDisplay *disp, int row, int fg, int readonly) { store_frame_manager *fm = disp->bfm->sfm; char *text[6]={NULL, NULL, NULL, NULL, NULL, NULL}; store *new_store; if (row<0) return; gtk_clist_insert (GTK_CLIST (fm->store_list), row, text); new_store = sfm_store_create (disp, gimage, fg, row, readonly); fm->stores = g_slist_insert (fm->stores, new_store, row); } /* * */ static gint sfm_auto_save (GtkWidget *w, gpointer data) { bfm_onionskin_rm ((GDisplay*)data); return 1; } static ToolType tool=-1; static gint sfm_set_aofi (GtkWidget *w, gpointer data) { GDisplay *disp; disp = (GDisplay*)data; bfm_onionskin_rm (disp); if (tool == -1) { if (disp->select) disp->select->hidden = FALSE; tool = active_tool->type; tools_select (RECT_SELECT); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(((GDisplay*)data)->bfm->sfm->aofi), TRUE); } else { tools_select (tool); tool = -1; selection_invis (disp->select); selection_layer_invis (disp->select); disp->select->hidden = disp->select->hidden ? FALSE : TRUE; selection_start (disp->select, TRUE); gdisplays_flush (); } return 1; } void sfm_setting_aofi(GDisplay *disp) { RectSelect * rect_sel; double scale; gint s_x, s_y, e_x, e_y; store_frame_manager *fm; bfm_onionskin_rm (disp); if (tool == -1) return; if (active_tool->type == RECT_SELECT) { /* get position */ rect_sel = (RectSelect *) active_tool->private; s_x = MIN (rect_sel->x, rect_sel->x + rect_sel->w); s_y = MIN (rect_sel->y, rect_sel->y + rect_sel->h); e_x = MAX (rect_sel->x, rect_sel->x + rect_sel->w) - s_x; e_y = MAX (rect_sel->y, rect_sel->y + rect_sel->h) - s_y; if ((!s_x && !s_y && !e_x && !e_y) || (!rect_sel->w && !rect_sel->h)) { scale = ((double) SCALESRC (disp) / (double)SCALEDEST (disp)); s_x = 0; s_y = 0; e_x = disp->disp_width*scale; e_y = disp->disp_height*scale; } fm = disp->bfm->sfm; fm->s_x = fm->sx = s_x; fm->s_y = fm->sy = s_y; fm->e_x = fm->ex = e_x; fm->e_y = fm->ey = e_y; } } static gint sfm_aofi (GtkWidget *w, gpointer data) { store_frame_manager *fm = ((GDisplay*)data)->bfm->sfm; bfm_onionskin_rm ((GDisplay*)data); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(fm->aofi))) { fm->s_x = fm->sx; fm->s_y = fm->sy; fm->e_x = fm->ex; fm->e_y = fm->ey; } else { sfm_unset_aofi ((GDisplay*)data); } return 1; } static void sfm_unset_aofi (GDisplay *disp) { store_frame_manager *fm = disp->bfm->sfm; double scale; bfm_onionskin_rm (disp); scale = ((double) SCALESRC (disp) / (double)SCALEDEST (disp)); fm->s_x = 0; fm->s_y = 0; fm->e_x = disp->disp_width*scale; fm->e_y = disp->disp_height*scale; } /* * ADD STORE */ static void sfm_store_add_stores (GDisplay* disp) { gint row, f, i; GImage *gimage; store_frame_manager *fm = disp->bfm->sfm; gint num_to_add = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(fm->num_to_add)); store *item; char* temp_path = 0; row = fm->fg; item = (store*) g_slist_nth (fm->stores, row)->data; switch (TYPE_TO_ADD) { case 1: f = filename_get_frame_number(item->gimage->filename); for (i=0; iload_smart) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->dest_dir, disp->bfm->dest_name, f-(i+1)); } else { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, f-(i+1)); } /* find the current */ if (temp_path ==NULL) { g_message("Frame numbers can not be negative."); } if ((temp_path!=NULL)&&(gimage=file_load_without_display (temp_path, prune_filename(temp_path), disp))) { sfm_store_add_image (gimage, disp, row+(i+1), 0, fm->readonly); } else if (fm->load_smart) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, f-(i+1)); if ((gimage=file_load_without_display (temp_path, prune_filename(temp_path), disp))) { sfm_store_add_image (gimage, disp, row+(i+1), 0, fm->readonly); } } } break; case 0: f = filename_get_frame_number(item->gimage->filename); for (i=0; iload_smart) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->dest_dir, disp->bfm->dest_name, f+(i+1)); } else { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, f+(i+1)); } /* find the current */ if (temp_path ==NULL) { g_message("Frame numbers can not be negative."); } if ((temp_path!=NULL)&&(gimage=file_load_without_display (temp_path, prune_filename(temp_path), disp))) { sfm_store_add_image (gimage, disp, row+(i+1), 0, fm->readonly); } else if (fm->load_smart) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, f+(i+1)); if ((gimage=file_load_without_display (temp_path, prune_filename(temp_path), disp))) { sfm_store_add_image (gimage, disp, row+(i+1), 0, fm->readonly); } } } break; case 2: gimage = item->gimage; for (i=0; ireadonly); } break; } if (temp_path) free(temp_path); } static void sfm_store_add_dialog_ok (GtkWidget *w, gpointer client_data) { store_frame_manager *fm = ((GDisplay*) client_data)->bfm->sfm; if (fm) { if (GTK_WIDGET_VISIBLE (fm->add_dialog)) { gtk_widget_hide (fm->add_dialog); sfm_store_add_stores ((GDisplay*) client_data); } } } static gint sfm_store_add_dialog_delete (GtkWidget *w, GdkEvent *e, gpointer data) { store_frame_manager *fm = ((GDisplay*) data)->bfm->sfm; if (fm) { if (GTK_WIDGET_VISIBLE (fm->add_dialog)) { gtk_widget_hide (fm->add_dialog); } } return TRUE; } static void sfm_store_add_readonly (GtkWidget *w, gpointer client_data) { store_frame_manager *fm = ((GDisplay*) client_data)->bfm->sfm; fm->readonly = fm->readonly ? 0 : 1; } static void frame_manager_add_dialog_option (GtkWidget *w, gpointer client_data) { TYPE_TO_ADD = (int) client_data; } static void sfm_store_add_create_dialog (GDisplay *disp) { store_frame_manager *fm = disp->bfm->sfm; int i; GtkWidget *hbox, *radio_button, *label, *check_button; GSList *group = NULL; char *options[3] = { "Load next frames", "Load prev frames", "Load copies of cur frame" }; static ActionAreaItem offset_action_items[1] = { { "Ok", sfm_store_add_dialog_ok, NULL, NULL }, }; if (!fm) return; if (!fm->add_dialog) { fm->add_dialog = gtk_dialog_new (); gtk_object_ref(GTK_OBJECT(fm->add_dialog)); gtk_window_set_wmclass (GTK_WINDOW (fm->add_dialog), "Store Option", PROGRAM_NAME); gtk_window_set_policy (GTK_WINDOW (fm->add_dialog), FALSE, FALSE, FALSE); gtk_window_set_title (GTK_WINDOW (fm->add_dialog), "New Store Option"); gtk_signal_connect (GTK_OBJECT (fm->add_dialog), "delete_event", GTK_SIGNAL_FUNC (sfm_store_add_dialog_delete), disp); #if 0 gtk_widget_set_uposition(fm->add_dialog, generic_window_x, generic_window_y); layout_connect_window_position(fm->add_dialog, &generic_window_x, &generic_window_y); minimize_register(fm->add_dialog); #endif hbox = gtk_hbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (hbox), 1); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (fm->add_dialog)->vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); /* readonly */ check_button = gtk_check_button_new_with_label ("readonly"); gtk_signal_connect (GTK_OBJECT (check_button), "clicked", (GtkSignalFunc) sfm_store_add_readonly, disp); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (fm->add_dialog)->vbox), check_button, FALSE, FALSE, 0); gtk_widget_show (check_button); /* num of store */ label = gtk_label_new ("Add"); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3); gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); gtk_widget_show (label); disp->bfm->sfm->num_to_add = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new (1, 1, 100, 1, 1, 0)), 1.0, 0); gtk_box_pack_start (GTK_BOX (hbox), disp->bfm->sfm->num_to_add, FALSE, FALSE, 2); gtk_widget_show (disp->bfm->sfm->num_to_add); label = gtk_label_new ("stores"); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 4); gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); gtk_widget_show (label); /* radio buttons */ for (i = 0; i < 3; i++) { radio_button = gtk_radio_button_new_with_label (group, options[i]); group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button)); gtk_signal_connect (GTK_OBJECT (radio_button), "toggled", (GtkSignalFunc) frame_manager_add_dialog_option, (void *)((long) i)); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (fm->add_dialog)->vbox), radio_button, FALSE, FALSE, 0); gtk_widget_show (radio_button); } offset_action_items[0].user_data = disp; build_action_area (GTK_DIALOG (fm->add_dialog), offset_action_items, 1, 0); gtk_widget_show (fm->add_dialog); } else { if (!GTK_WIDGET_VISIBLE (fm->add_dialog)) { gtk_widget_show (fm->add_dialog); } } } void sfm_slide_show (GtkWidget *w, gpointer data) { GDisplay *display=NULL; GtkWidget *window; static gint win_x, win_y, win_w, win_h, win_d; display = gdisplay_active(); window = display->shell; if(display) { static int rulers_visible = 0; display->slide_show = display->slide_show ? 0 : 1; if(display->slide_show) { if(GTK_WIDGET_VISIBLE(display->hrule)) rulers_visible = 1; gdk_window_get_geometry(window->window, &win_x, &win_y, &win_w, &win_h, &win_d); gtk_widget_hide(display->menubar); gtk_widget_hide(display->hsb); gtk_widget_hide(display->vsb); gtk_widget_hide(display->hrule); gtk_widget_hide(display->vrule); gdk_window_move_resize (window->window, -50, -75, gdk_screen_width()+92, gdk_screen_height()+105); gtk_window_set_default_size (GTK_WINDOW (window), gdk_screen_width()+92, gdk_screen_height()+105); gtk_widget_set_usize (GTK_WIDGET(window), gdk_screen_width()+92, gdk_screen_height()+105); } else { gdk_window_move_resize (window->window, win_x, win_y, win_w, win_h); gtk_window_set_default_size (GTK_WINDOW (window), win_w, win_h); gtk_widget_set_usize (GTK_WIDGET(window), win_w, win_h); gtk_widget_show(display->menubar); gtk_widget_show(display->hsb); gtk_widget_show(display->vsb); if(rulers_visible) { gtk_widget_show(display->hrule); gtk_widget_show(display->vrule); } } gdisplays_flush(); } } /* * CHANGE FRAME NUMBER */ static void sfm_store_change_frame_to (GDisplay* disp) { char* temp_path = 0; char* temp_name; store_frame_manager *fm = disp->bfm->sfm; store *item = (store*) (g_slist_nth (fm->stores, fm->fg)->data); int new_frame = atoi (gtk_editable_get_chars (GTK_EDITABLE(fm->change_to), 0, -1)); if (fm->load_smart) temp_path = filename_build_path( disp->bfm->dest_dir, disp->bfm->dest_name, new_frame); else temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, new_frame); temp_name = prune_filename(temp_path); if (file_load (temp_path, temp_name, disp)) { disp->ID = disp->gimage->ID; item->gimage = disp->gimage; sfm_store_make_cur (disp, fm->fg); gtk_clist_set_text (GTK_CLIST (disp->bfm->sfm->store_list), disp->bfm->sfm->fg, 5, temp_name); } else if (fm->load_smart) { if (temp_path) free(temp_path); temp_path = filename_build_path( disp->bfm->src_dir, disp->bfm->src_name, new_frame); temp_name = prune_filename(temp_path); if (file_load (temp_path, temp_name, disp)) { disp->ID = disp->gimage->ID; item->gimage = disp->gimage; sfm_store_make_cur (disp, fm->fg); gtk_clist_set_text (GTK_CLIST (disp->bfm->sfm->store_list), disp->bfm->sfm->fg, 5, temp_name); } } if (temp_path) free(temp_path); } static void sfm_store_change_frame_dialog_ok (GtkWidget *w, gpointer client_data) { store_frame_manager *fm = ((GDisplay*) client_data)->bfm->sfm; if (fm) { if (GTK_WIDGET_VISIBLE (fm->chg_frame_dialog)) { gtk_widget_hide (fm->chg_frame_dialog); sfm_store_change_frame_to ((GDisplay*) client_data); } } } void sfm_filter_apply (GtkWidget *w, gpointer data) { Argument *args; GDisplay *display=(GDisplay*)data; int i; gint start_frame; bfm_onionskin_rm ((GDisplay*)data); start_frame=display->bfm->sfm->fg; if (wire_buffer->last_plug_in) { /* construct the procedures arguments */ args = g_new (Argument, wire_buffer->last_plug_in->num_args); memset (args, 0, (sizeof (Argument) * wire_buffer->last_plug_in->num_args)); /* initialize the argument types */ for (i = 0; i < wire_buffer->last_plug_in->num_args; i++) args[i].arg_type = wire_buffer->last_plug_in->args[i].arg_type; sfm_flip_forward(display); while(start_frame != display->bfm->sfm->fg) { /* initialize the first 3 plug-in arguments */ args[0].value.pdb_int = RUN_WITH_LAST_VALS; args[1].value.pdb_int = display->gimage->ID; args[2].value.pdb_int = drawable_ID (gimage_active_drawable (display->gimage)); /* run the plug-in procedure */ plug_in_run (wire_buffer->last_plug_in, args, FALSE, TRUE); /* advance to the next store */ sfm_flip_forward(display); } g_free (args); } } static gint sfm_store_change_frame_dialog_delete (GtkWidget *w, GdkEvent *e, gpointer data) { store_frame_manager *fm = ((GDisplay*) data)->bfm->sfm; if (fm) { if (GTK_WIDGET_VISIBLE (fm->chg_frame_dialog)) { gtk_widget_hide (fm->chg_frame_dialog); } } return TRUE; } static void sfm_store_change_frame_create_dialog (GDisplay *disp) { store_frame_manager *fm = disp->bfm->sfm; GtkWidget *hbox, *label; char *temp; store *item = (store*) (g_slist_nth (fm->stores, fm->fg)->data); static ActionAreaItem offset_action_items[1] = { { "Ok", sfm_store_change_frame_dialog_ok, NULL, NULL }, }; if (!fm) return; if (!fm->chg_frame_dialog) { fm->chg_frame_dialog = gtk_dialog_new (); gtk_object_ref(GTK_OBJECT(fm->chg_frame_dialog)); gtk_window_set_wmclass (GTK_WINDOW (fm->chg_frame_dialog), "Store Option", PROGRAM_NAME); gtk_window_set_policy (GTK_WINDOW (fm->chg_frame_dialog), FALSE, FALSE, FALSE); gtk_window_set_title (GTK_WINDOW (fm->chg_frame_dialog), "New Store Option"); gtk_signal_connect (GTK_OBJECT (fm->chg_frame_dialog), "delete_event", GTK_SIGNAL_FUNC (sfm_store_change_frame_dialog_delete), disp); #if 0 gtk_widget_set_uposition(fm->add_dialog, generic_window_x, generic_window_y); layout_connect_window_position(fm->add_dialog, &generic_window_x, &generic_window_y); minimize_register(fm->add_dialog); #endif hbox = gtk_hbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (hbox), 1); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (fm->chg_frame_dialog)->vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); temp = filename_get_pre(item->gimage->filename); label = gtk_label_new (temp); free(temp); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 4); gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); gtk_widget_show (label); fm->change_to = gtk_entry_new (); temp = filename_get_frame(item->gimage->filename); gtk_entry_set_text (GTK_ENTRY (fm->change_to), temp); free(temp); gtk_box_pack_start (GTK_BOX (hbox), fm->change_to, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (fm->change_to), "activate", (GtkSignalFunc) sfm_store_change_frame_dialog_ok, disp); gtk_widget_show (fm->change_to); temp = filename_get_post(item->gimage->filename); label = gtk_label_new (temp); free(temp); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 4); gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); gtk_widget_show (label); offset_action_items[0].user_data = disp; build_action_area (GTK_DIALOG (fm->chg_frame_dialog), offset_action_items, 1, 0); gtk_widget_show (fm->chg_frame_dialog); } else { if (!GTK_WIDGET_VISIBLE (fm->chg_frame_dialog)) { gtk_widget_show (fm->chg_frame_dialog); } } } void sfm_dialog_create () { GDisplay *display; GImage *gimage; char* temp_path = 0; gint row, f, i; store_frame_manager *fm; store *item; if(display_list != NULL) { display=(GDisplay *)display_list->data; bfm_create_sfm(display); fm = display->bfm->sfm; row = fm->fg; item = (store*) g_slist_nth (fm->stores, row)->data; bfm_onionskin_rm(display); f = filename_get_frame_number(item->gimage->filename); for (i=0; i<(initial_frames_loaded-1); i++) { if (temp_path) { free(temp_path); } temp_path = filename_build_path(display->bfm->src_dir, display->bfm->src_name, f+(i+1)); /* find the current */ if ((gimage=file_load_without_display (temp_path, prune_filename(temp_path), display))) { sfm_store_add_image (gimage, display, row+(i+1), 0, fm->readonly); } } } else { printf("No gdisplays available.\n"); printf("Starting CinePaint without Frame Manger.\n"); printf("You may manually create a Frame Manager once you have loaded an image.\n"); } }