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@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer

Reply via email to