Re: [Gimp-developer] Problem refreshing GimpPreviewArea

Top Page

Reply to this message
Author: Sven Neumann
Date:  
To: Nicolás Serrano Martínez Santos
CC: gimp-developer
Subject: Re: [Gimp-developer] Problem refreshing GimpPreviewArea
Hi,

On Fri, 2008-05-09 at 11:45 +0200, Nicolás Serrano Martínez Santos
wrote:
> Please find attached a simple plugin which consist in a dialog showing
> a drawable. Where you can specify the width and height that will be
> shown.
>
>
> This dialog does not refresh the GimpPreviewArea every time you click
> the spin. am I missing something??


You need to redraw the preview-area everytime it's size changes. It
doesn't keep the buffer across size changes. I have attached a modified
version of your test code that does the right thing.


Sven

#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>

typedef struct{
gint x1,y1,width,height;
GimpDrawable *drawable; GtkWidget *preview, *frame;
} redraw_info;


gboolean dialog (GimpDrawable *drawable);
void change_width(GtkSpinButton *p, gpointer data);
void change_height(GtkSpinButton *p, gpointer data);
static void size_changed (GimpPreviewArea *preview,
GtkAllocation *allocation,
redraw_info *info);

/*****************************************/

static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);

GimpPlugInInfo PLUG_IN_INFO =
{
NULL,
NULL,
query,
run
};

MAIN()

static void query (void){
static GimpParamDef args[] = {
{ GIMP_PDB_INT32,"run-mode","Run mode"},
{ GIMP_PDB_IMAGE,"image","Input image"},
{ GIMP_PDB_DRAWABLE,"drawable","Input drawable" },
};

gimp_install_procedure (
"test",
"test",
"Help:",
"test-author",
"Copyright test-author",
"2008",
"test",
"GRAY",
GIMP_PLUGIN,
G_N_ELEMENTS (args), 0,
args, NULL);

gimp_plugin_menu_register ("test","<Image>/test");
}

static void
run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
GimpRunMode run_mode;
gint32 image; GimpDrawable *drawable;

/* Setting mandatory output values */
*nreturn_vals = 1;
*return_vals = values;

values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;

/* Getting run_mode - we won't display a dialog if
* we are in NONINTERACTIVE mode
*/
run_mode = param[0].data.d_int32;
image = param[1].data.d_image;
drawable = gimp_drawable_get(param[2].data.d_drawable);

gimp_tile_cache_ntiles (2 * (drawable->width /
gimp_tile_width () + 1));
switch (run_mode){
case GIMP_RUN_NONINTERACTIVE:
status = GIMP_PDB_CALLING_ERROR;
break;
case GIMP_RUN_INTERACTIVE:
dialog(drawable);
break;
     case GIMP_RUN_WITH_LAST_VALS:
/* Possibly retrieve data */
//gimp_get_data (GIDOC_TRANSCRIPTIONS_KEY_VALS, &vals);
break;
default:
break;
}
/******************** RUN SECTION ************************/
if (status == GIMP_PDB_SUCCESS)

values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
}

gboolean dialog (GimpDrawable *drawable) {
/* widget variables */
GtkWidget *dlg;
GtkWidget *main_vbox;
GtkWidget *frame;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *spin_width, *spin_height;
GtkWidget *preview;
gboolean run = FALSE;
redraw_info info;

gimp_ui_init ("test", TRUE);

dlg = gimp_dialog_new ("test", "test",
NULL, 0,
             gimp_standard_help_func, "test",

             GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
             GTK_STOCK_OK, GTK_RESPONSE_OK,

             NULL);

/* FIXME The window doesn't fit the scrowable zone... */
main_vbox = gtk_vbox_new (FALSE, 12);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dlg)->vbox), main_vbox);


frame = gimp_frame_new("Preview");
gtk_box_pack_start (GTK_BOX (main_vbox), frame,FALSE,FALSE, 0);

hbox = gtk_hbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (frame), hbox);

preview = gimp_preview_area_new();
gtk_box_pack_start (GTK_BOX (hbox), preview, FALSE, FALSE, 0);

g_signal_connect (preview, "size-allocate", G_CALLBACK (size_changed), &info);

info.x1 = 0; info.y1 = 0;
info.height = 100; info.width = 100;
info.drawable = drawable; info.preview = preview; info.frame = frame;

gtk_widget_set_size_request (GTK_WIDGET (preview),
info.width, info.height);

gtk_widget_show_all (frame);

hbox = gtk_hbox_new (FALSE, 12);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox,FALSE,FALSE, 0);
label = gtk_label_new("width");
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE,FALSE, 0);
spin_width = gtk_spin_button_new_with_range(100,
gimp_drawable_width(drawable->drawable_id),1);
g_signal_connect(G_OBJECT(spin_width),"value-changed",
G_CALLBACK(change_width),&info);
gtk_box_pack_start (GTK_BOX (hbox), spin_width, FALSE,FALSE, 0);
label = gtk_label_new("height");
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE,FALSE, 0);
spin_height = gtk_spin_button_new_with_range(100,
gimp_drawable_height(drawable->drawable_id),1);
g_signal_connect(G_OBJECT(spin_height),"value-changed",
G_CALLBACK(change_height),&info);
gtk_box_pack_start (GTK_BOX (hbox), spin_height, FALSE,FALSE, 0);

gtk_widget_show_all(hbox);

gtk_widget_show (main_vbox);
gtk_widget_show (dlg);

/* put an initial preview */
run = (gimp_dialog_run (GIMP_DIALOG (dlg)) == GTK_RESPONSE_OK);

gimp_displays_flush ();

gtk_widget_destroy (dlg);

return run;
}

void change_width(GtkSpinButton *p, gpointer data){
redraw_info *info = data;

info->width = gtk_spin_button_get_value(p);

gtk_widget_set_size_request((GtkWidget *) info->preview,
info->width,info->height);
}

void change_height(GtkSpinButton *p, gpointer data){
redraw_info *info = data;

info->height = gtk_spin_button_get_value(p);

gtk_widget_set_size_request (GTK_WIDGET (info->preview),
info->width, info->height);
}

static void
size_changed (GimpPreviewArea *preview,
GtkAllocation *allocation,
redraw_info *info)
{
GimpPixelRgn rgn_input; guchar *buf; gint i;

buf = g_newa (guchar, info->width);

gimp_pixel_rgn_init (&rgn_input,
info->drawable,
0,0,
info->width, info->height,
FALSE, FALSE);

for (i=0; i<info->height; i++)
{
gimp_pixel_rgn_get_row (&rgn_input,buf,0,i,info->width);
gimp_preview_area_draw (GIMP_PREVIEW_AREA(info->preview),
0, i,
info->width, 1,
GIMP_GRAY_IMAGE, buf, info->width);
}
}
_______________________________________________
Gimp-developer mailing list
Gimp-developer@???
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer