Esempio n. 1
0
static double
qof_gobject_double_getter (gpointer data, QofParam *getter)
{
    GObject *gob = data;
    double fval;

    GParamSpec *gps = getter->param_userdata;

    /* Note that the return type must actually be of type
     * getter->param_type but we just follow the hard-coded
     * mapping below ... */
    if (G_IS_PARAM_SPEC_FLOAT(gps))
    {
        GValue gval = {G_TYPE_INVALID};
        g_value_init (&gval, G_TYPE_FLOAT);
        g_object_get_property (gob, getter->param_name, &gval);

        fval = g_value_get_float (&gval);
        return fval;
    }
    else if (G_IS_PARAM_SPEC_DOUBLE(gps))
    {
        GValue gval = {G_TYPE_INVALID};
        g_value_init (&gval, G_TYPE_DOUBLE);
        g_object_get_property (gob, getter->param_name, &gval);

        fval = g_value_get_double (&gval);
        return fval;
    }

    PWARN ("unhandled parameter type %s for paramter %s",
           G_PARAM_SPEC_TYPE_NAME(gps), getter->param_name);
    return 0.0;
}
Esempio n. 2
0
File: json.c Progetto: GNOME/gegl
static GParamSpec *
copy_param_spec(GParamSpec *in, const gchar *name) {

  const gchar * blurb = g_param_spec_get_blurb(in);
  GParamSpec *out = NULL;

  GParamFlags flags = G_PARAM_READWRITE;

  // TODO: handle more things
  if (G_IS_PARAM_SPEC_FLOAT(in)) {
    GParamSpecFloat *f = G_PARAM_SPEC_FLOAT(in);
    out = g_param_spec_double(name, name, blurb, f->minimum, f->maximum, f->default_value, flags);
  } else if (G_IS_PARAM_SPEC_DOUBLE(in)) {
    GParamSpecDouble *d = G_PARAM_SPEC_DOUBLE(in);
    out = g_param_spec_double(name, name, blurb, d->minimum, d->maximum, d->default_value, flags);
  } else if (G_IS_PARAM_SPEC_INT(in)) {
    GParamSpecInt *i = G_PARAM_SPEC_INT(in);
    out = g_param_spec_int(name, name, blurb, i->minimum, i->maximum, i->default_value, flags);
  } else if (G_IS_PARAM_SPEC_UINT(in)) {
    GParamSpecUInt *u = G_PARAM_SPEC_UINT(in);
    out = g_param_spec_int(name, name, blurb, u->minimum, u->maximum, u->default_value, flags);
  } else if (G_IS_PARAM_SPEC_LONG(in)) {
    GParamSpecLong *l = G_PARAM_SPEC_LONG(in);
    out = g_param_spec_int(name, name, blurb, l->minimum, l->maximum, l->default_value, flags);
  } else if (GEGL_IS_PARAM_SPEC_COLOR(in)) {
    GeglColor *default_value = gegl_param_spec_color_get_default(in);
    out = gegl_param_spec_color(name, name, blurb, default_value, flags);
  } else {
    g_critical("json: Unknown param spec type for property %s", g_param_spec_get_nick(in));
  }
  return out;
}
Esempio n. 3
0
gboolean
stetic_param_spec_get_default (GParamSpec *pspec, GValue *value)
{
	g_value_init (value, pspec->value_type);

	if (G_IS_PARAM_SPEC_CHAR (pspec))
		g_value_set_char (value, G_PARAM_SPEC_CHAR (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_UCHAR (pspec))
		g_value_set_uchar (value, G_PARAM_SPEC_UCHAR (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_INT (pspec))
		g_value_set_int (value, G_PARAM_SPEC_INT (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_UINT (pspec))
		g_value_set_uint (value, G_PARAM_SPEC_UINT (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_LONG (pspec))
		g_value_set_long (value, G_PARAM_SPEC_LONG (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_ULONG (pspec))
		g_value_set_ulong (value, G_PARAM_SPEC_ULONG (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_INT64 (pspec))
		g_value_set_int64 (value, G_PARAM_SPEC_INT64 (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_UINT64 (pspec))
		g_value_set_uint64 (value, G_PARAM_SPEC_UINT64 (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_FLOAT (pspec))
		g_value_set_float (value, G_PARAM_SPEC_FLOAT (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
		g_value_set_double (value, G_PARAM_SPEC_DOUBLE (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
		g_value_set_boolean (value, G_PARAM_SPEC_BOOLEAN (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_UNICHAR (pspec))
		g_value_set_uint (value, G_PARAM_SPEC_UNICHAR (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_STRING (pspec))
		g_value_set_static_string (value, G_PARAM_SPEC_STRING (pspec)->default_value);
	else
		return FALSE;
	return TRUE;
}
Esempio n. 4
0
gboolean
stetic_param_spec_get_maximum (GParamSpec *pspec, GValue *value)
{
	g_value_init (value, pspec->value_type);

	if (G_IS_PARAM_SPEC_CHAR (pspec))
		g_value_set_char (value, G_PARAM_SPEC_CHAR (pspec)->maximum);
	else if (G_IS_PARAM_SPEC_UCHAR (pspec))
		g_value_set_uchar (value, G_PARAM_SPEC_UCHAR (pspec)->maximum);
	else if (G_IS_PARAM_SPEC_INT (pspec))
		g_value_set_int (value, G_PARAM_SPEC_INT (pspec)->maximum);
	else if (G_IS_PARAM_SPEC_UINT (pspec))
		g_value_set_uint (value, G_PARAM_SPEC_UINT (pspec)->maximum);
	else if (G_IS_PARAM_SPEC_LONG (pspec))
		g_value_set_long (value, G_PARAM_SPEC_LONG (pspec)->maximum);
	else if (G_IS_PARAM_SPEC_ULONG (pspec))
		g_value_set_ulong (value, G_PARAM_SPEC_ULONG (pspec)->maximum);
	else if (G_IS_PARAM_SPEC_INT64 (pspec))
		g_value_set_int64 (value, G_PARAM_SPEC_INT64 (pspec)->maximum);
	else if (G_IS_PARAM_SPEC_UINT64 (pspec))
		g_value_set_uint64 (value, G_PARAM_SPEC_UINT64 (pspec)->maximum);
	else if (G_IS_PARAM_SPEC_FLOAT (pspec))
		g_value_set_float (value, G_PARAM_SPEC_FLOAT (pspec)->maximum);
	else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
		g_value_set_double (value, G_PARAM_SPEC_DOUBLE (pspec)->maximum);
	else
		return FALSE;
	return TRUE;
}
Esempio n. 5
0
qreal QtCamZoom::defaultValue() {
  GParamSpec *p = d_ptr->paramSpec();

  if (p && G_IS_PARAM_SPEC_FLOAT(p)) {
    return G_PARAM_SPEC_FLOAT(p)->default_value;
  }

  return 1.0;
}
Esempio n. 6
0
qreal QtCamZoom::minimumValue() {
  GParamSpec *p = d_ptr->paramSpec();

  if (p && G_IS_PARAM_SPEC_FLOAT(p)) {
    return G_PARAM_SPEC_FLOAT(p)->minimum;
  }

  return 1.0;
}
Esempio n. 7
0
GtkWidget *
gimp_prop_table_new (GObject              *config,
                     GType                 owner_type,
                     GimpContext          *context,
                     GimpCreatePickerFunc  create_picker_func,
                     gpointer              picker_creator)
{
  GtkWidget     *table;
  GtkSizeGroup  *size_group;
  GParamSpec   **param_specs;
  guint          n_param_specs;
  gint           i;
  gint           row = 0;
  GParamSpec    *last_pspec = NULL;
  GtkAdjustment *last_x_adj = NULL;
  gint           last_x_row = 0;

  g_return_val_if_fail (G_IS_OBJECT (config), NULL);
  g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);

  param_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config),
                                                &n_param_specs);

  size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);

  table = gtk_table_new (3, 1, FALSE);
  gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  gtk_table_set_row_spacings (GTK_TABLE (table), 2);

  for (i = 0; i < n_param_specs; i++)
    {
      GParamSpec  *pspec  = param_specs[i];
      GtkWidget   *widget = NULL;
      const gchar *label  = NULL;

      /*  ignore properties of parent classes of owner_type  */
      if (! g_type_is_a (pspec->owner_type, owner_type))
        continue;

      if (G_IS_PARAM_SPEC_STRING (pspec))
        {
          static GQuark multiline_quark = 0;

          if (! multiline_quark)
            multiline_quark = g_quark_from_static_string ("multiline");

          if (GIMP_IS_PARAM_SPEC_CONFIG_PATH (pspec))
            {
              widget = gimp_prop_file_chooser_button_new (config,
                                                          pspec->name,
                                                          g_param_spec_get_nick (pspec),
                                                          GTK_FILE_CHOOSER_ACTION_OPEN);
            }
          else if (g_param_spec_get_qdata (pspec, multiline_quark))
            {
              GtkTextBuffer *buffer;
              GtkWidget     *view;

              buffer = gimp_prop_text_buffer_new (config, pspec->name, -1);
              view = gtk_text_view_new_with_buffer (buffer);

              widget = gtk_scrolled_window_new (NULL, NULL);
              gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget),
                                                   GTK_SHADOW_IN);
              gtk_container_add (GTK_CONTAINER (widget), view);
              gtk_widget_show (view);
            }
          else
            {
              widget = gimp_prop_entry_new (config, pspec->name, -1);
            }

          label  = g_param_spec_get_nick (pspec);
        }
      else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
        {
          widget = gimp_prop_check_button_new (config, pspec->name,
                                               g_param_spec_get_nick (pspec));
        }
      else if (G_IS_PARAM_SPEC_ENUM (pspec))
        {
          widget = gimp_prop_enum_combo_box_new (config, pspec->name, 0, 0);
          gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (widget),
                                        g_param_spec_get_nick (pspec));
        }
      else if (GEGL_IS_PARAM_SPEC_SEED (pspec))
        {
          GtkAdjustment *adj;
          GtkWidget     *scale;
          GtkWidget     *button;

          widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

          scale = gimp_prop_spin_scale_new (config, pspec->name,
                                            g_param_spec_get_nick (pspec),
                                            1.0, 10.0, 0);
          gtk_box_pack_start (GTK_BOX (widget), scale, TRUE, TRUE, 0);
          gtk_widget_show (scale);

          button = gtk_button_new_with_label (_("New Seed"));
          gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
          gtk_widget_show (button);

          adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (scale));

          g_signal_connect (button, "clicked",
                            G_CALLBACK (gimp_prop_table_new_seed_clicked),
                            adj);
        }
      else if (G_IS_PARAM_SPEC_INT (pspec)   ||
               G_IS_PARAM_SPEC_UINT (pspec)  ||
               G_IS_PARAM_SPEC_FLOAT (pspec) ||
               G_IS_PARAM_SPEC_DOUBLE (pspec))
        {
          GtkAdjustment *adj;
          gdouble        value;
          gdouble        lower;
          gdouble        upper;
          gdouble        step   = 1.0;
          gdouble        page   = 10.0;
          gint           digits = (G_IS_PARAM_SPEC_FLOAT (pspec) ||
                                   G_IS_PARAM_SPEC_DOUBLE (pspec)) ? 2 : 0;

          if (GEGL_IS_PARAM_SPEC_DOUBLE (pspec))
            {
              GeglParamSpecDouble *gspec = GEGL_PARAM_SPEC_DOUBLE (pspec);

              lower = gspec->ui_minimum;
              upper = gspec->ui_maximum;
            }
          else if (GEGL_IS_PARAM_SPEC_INT (pspec))
            {
              GeglParamSpecInt *gspec = GEGL_PARAM_SPEC_INT (pspec);

              lower = gspec->ui_minimum;
              upper = gspec->ui_maximum;
            }
          else
            {
              _gimp_prop_widgets_get_numeric_values (config, pspec,
                                                     &value, &lower, &upper,
                                                     G_STRFUNC);
            }

          if ((upper - lower < 10.0) &&
              (G_IS_PARAM_SPEC_FLOAT (pspec) ||
               G_IS_PARAM_SPEC_DOUBLE (pspec)))
            {
              step   = 0.1;
              page   = 1.0;
              digits = 3;
            }

          widget = gimp_prop_spin_scale_new (config, pspec->name,
                                             g_param_spec_get_nick (pspec),
                                             step, page, digits);

          adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget));

          if (g_str_has_suffix (pspec->name, "x") ||
              g_str_has_suffix (pspec->name, "width"))
            {
              last_pspec = pspec;
              last_x_adj = adj;
              last_x_row = row;
            }
          else if ((g_str_has_suffix (pspec->name, "y") ||
                    g_str_has_suffix (pspec->name, "height")) &&
                   last_pspec != NULL &&
                   last_x_adj != NULL &&
                   last_x_row == row - 1)
            {
              GtkWidget *chain = gimp_chain_button_new (GIMP_CHAIN_RIGHT);

              gtk_table_attach (GTK_TABLE (table), chain,
                                3, 4, last_x_row, row + 1,
                                GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL,
                                0, 0);
              gtk_widget_show (chain);

              if (gtk_adjustment_get_value (last_x_adj) ==
                  gtk_adjustment_get_value (adj))
                {
                  GBinding *binding;

                  gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (chain), TRUE);

                  binding = g_object_bind_property (last_x_adj, "value",
                                                    adj,        "value",
                                                    G_BINDING_BIDIRECTIONAL);

                  g_object_set_data (G_OBJECT (chain), "binding", binding);
                }

              g_signal_connect (chain, "toggled",
                                G_CALLBACK (gimp_prop_table_chain_toggled),
                                last_x_adj);

              g_object_set_data (G_OBJECT (last_x_adj), "y-adjustment", adj);

              if (create_picker_func)
                {
                  GtkWidget *button;
                  gchar     *pspec_name;

                  pspec_name = g_strconcat (last_pspec->name, ":",
                                            pspec->name, NULL);

                  button = create_picker_func (picker_creator,
                                               pspec_name,
                                               GIMP_STOCK_CURSOR,
                                               _("Pick coordinates from the image"));
                  gtk_table_attach (GTK_TABLE (table), button,
                                    4, 5, last_x_row, row + 1,
                                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL,
                                    0, 0);
                  gtk_widget_show (button);

                  g_object_weak_ref (G_OBJECT (button),
                                     (GWeakNotify) g_free, pspec_name);
                }
            }
        }
      else if (GIMP_IS_PARAM_SPEC_RGB (pspec))
        {
          GtkWidget *button;

          widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

          button = gimp_prop_color_button_new (config, pspec->name,
                                               g_param_spec_get_nick (pspec),
                                               128, 24,
                                               GIMP_COLOR_AREA_SMALL_CHECKS);
          gimp_color_button_set_update (GIMP_COLOR_BUTTON (button), TRUE);
          gimp_color_panel_set_context (GIMP_COLOR_PANEL (button), context);
          gtk_box_pack_start (GTK_BOX (widget), button, TRUE, TRUE, 0);
          gtk_widget_show (button);

          if (create_picker_func)
            {
              button = create_picker_func (picker_creator,
                                           pspec->name,
                                           GIMP_STOCK_COLOR_PICKER_GRAY,
                                           _("Pick color from the image"));
              gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
              gtk_widget_show (button);
            }

          label = g_param_spec_get_nick (pspec);
        }
      else
        {
          g_warning ("%s: not supported: %s (%s)\n", G_STRFUNC,
                     g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name);
        }

      if (widget)
        {
          if (label)
            {
              gimp_table_attach_aligned (GTK_TABLE (table), 0, row,
                                         label, 0.0, 0.5,
                                         widget, 2, FALSE);
            }
          else
            {
              gtk_table_attach_defaults (GTK_TABLE (table), widget,
                                         0, 3, row, row + 1);
              gtk_widget_show (widget);
            }

          row++;
        }
    }

  g_object_unref (size_group);

  g_free (param_specs);

  return table;
}
Esempio n. 8
0
GtkWidget *
gimp_prop_widget_new_from_pspec (GObject               *config,
                                 GParamSpec            *pspec,
                                 GimpContext           *context,
                                 GimpCreatePickerFunc   create_picker_func,
                                 gpointer               picker_creator,
                                 const gchar          **label)
{
  GtkWidget *widget = NULL;

  g_return_val_if_fail (G_IS_OBJECT (config), NULL);
  g_return_val_if_fail (pspec != NULL, NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (label != NULL, NULL);

  *label = NULL;

  if (GEGL_IS_PARAM_SPEC_SEED (pspec))
    {
      GtkAdjustment *adj;
      GtkWidget     *spin;
      GtkWidget     *button;

      widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

      spin = gimp_prop_spin_button_new (config, pspec->name,
                                        1.0, 10.0, 0);
      gtk_box_pack_start (GTK_BOX (widget), spin, TRUE, TRUE, 0);
      gtk_widget_show (spin);

      button = gtk_button_new_with_label (_("New Seed"));
      gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
      gtk_widget_show (button);

      adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));

      g_signal_connect (button, "clicked",
                        G_CALLBACK (gimp_prop_widget_new_seed_clicked),
                        adj);

      *label = g_param_spec_get_nick (pspec);
    }
  else if (G_IS_PARAM_SPEC_INT (pspec)   ||
           G_IS_PARAM_SPEC_UINT (pspec)  ||
           G_IS_PARAM_SPEC_FLOAT (pspec) ||
           G_IS_PARAM_SPEC_DOUBLE (pspec))
    {
      gdouble lower;
      gdouble upper;
      gdouble step;
      gdouble page;
      gint    digits;

      if (GEGL_IS_PARAM_SPEC_DOUBLE (pspec))
        {
          GeglParamSpecDouble *gspec = GEGL_PARAM_SPEC_DOUBLE (pspec);

          lower  = gspec->ui_minimum;
          upper  = gspec->ui_maximum;
          step   = gspec->ui_step_small;
          page   = gspec->ui_step_big;
          digits = gspec->ui_digits;
        }
      else if (GEGL_IS_PARAM_SPEC_INT (pspec))
        {
          GeglParamSpecInt *gspec = GEGL_PARAM_SPEC_INT (pspec);

          lower  = gspec->ui_minimum;
          upper  = gspec->ui_maximum;
          step   = gspec->ui_step_small;
          page   = gspec->ui_step_big;
          digits = 0;
        }
      else
        {
          gdouble value;

          _gimp_prop_widgets_get_numeric_values (config, pspec,
                                                 &value, &lower, &upper,
                                                 G_STRFUNC);

          if ((upper - lower <= 1.0) &&
              (G_IS_PARAM_SPEC_FLOAT (pspec) ||
               G_IS_PARAM_SPEC_DOUBLE (pspec)))
            {
              step   = 0.01;
              page   = 0.1;
              digits = 4;
            }
          else if ((upper - lower <= 10.0) &&
                   (G_IS_PARAM_SPEC_FLOAT (pspec) ||
                    G_IS_PARAM_SPEC_DOUBLE (pspec)))
            {
              step   = 0.1;
              page   = 1.0;
              digits = 3;
            }
          else
            {
              step   = 1.0;
              page   = 10.0;
              digits = (G_IS_PARAM_SPEC_FLOAT (pspec) ||
                        G_IS_PARAM_SPEC_DOUBLE (pspec)) ? 2 : 0;
            }
        }

      widget = gimp_prop_spin_scale_new (config, pspec->name, NULL,
                                         step, page, digits);

      if (HAS_KEY (pspec, "unit", "degree") &&
          (upper - lower) == 360.0)
        {
          GtkWidget *hbox;
          GtkWidget *dial;

          gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (widget), TRUE);

          hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

          gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
          gtk_widget_show (widget);

          dial = gimp_prop_angle_dial_new (config, pspec->name);
          gtk_box_pack_start (GTK_BOX (hbox), dial, FALSE, FALSE, 0);
          gtk_widget_show (dial);

          widget = hbox;
        }
      else if (HAS_KEY (pspec, "unit", "kelvin"))
        {
          GtkWidget *hbox;
          GtkWidget *button;

          hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

          gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
          gtk_widget_show (widget);

          button = gimp_prop_kelvin_presets_new (config, pspec->name);
          gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
          gtk_widget_show (button);

          widget = hbox;
        }
    }
  else if (G_IS_PARAM_SPEC_STRING (pspec))
    {
      static GQuark multiline_quark = 0;

      if (! multiline_quark)
        multiline_quark = g_quark_from_static_string ("multiline");

      if (GIMP_IS_PARAM_SPEC_CONFIG_PATH (pspec))
        {
          widget =
            gimp_prop_file_chooser_button_new (config, pspec->name,
                                               g_param_spec_get_nick (pspec),
                                               GTK_FILE_CHOOSER_ACTION_OPEN);
        }
      else if (g_param_spec_get_qdata (pspec, multiline_quark))
        {
          GtkTextBuffer *buffer;
          GtkWidget     *view;

          buffer = gimp_prop_text_buffer_new (config, pspec->name, -1);
          view = gtk_text_view_new_with_buffer (buffer);
          g_object_unref (buffer);

          widget = gtk_scrolled_window_new (NULL, NULL);
          gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget),
                                               GTK_SHADOW_IN);
          gtk_container_add (GTK_CONTAINER (widget), view);
          gtk_widget_show (view);
        }
      else
        {
          widget = gimp_prop_entry_new (config, pspec->name, -1);
        }

      *label = g_param_spec_get_nick (pspec);
    }
  else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
    {
      widget = gimp_prop_check_button_new (config, pspec->name,
                                           g_param_spec_get_nick (pspec));
    }
  else if (G_IS_PARAM_SPEC_ENUM (pspec))
    {
      widget = gimp_prop_enum_combo_box_new (config, pspec->name, 0, 0);
      gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (widget),
                                    g_param_spec_get_nick (pspec));
    }
  else if (GIMP_IS_PARAM_SPEC_RGB (pspec))
    {
      GtkWidget *button;

      widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

      button = gimp_prop_color_button_new (config, pspec->name,
                                           g_param_spec_get_nick (pspec),
                                           128, 24,
                                           GIMP_COLOR_AREA_SMALL_CHECKS);
      gimp_color_button_set_update (GIMP_COLOR_BUTTON (button), TRUE);
      gimp_color_panel_set_context (GIMP_COLOR_PANEL (button), context);
      gtk_box_pack_start (GTK_BOX (widget), button, TRUE, TRUE, 0);
      gtk_widget_show (button);

      if (create_picker_func)
        {
          button = create_picker_func (picker_creator,
                                       pspec->name,
                                       GIMP_STOCK_COLOR_PICKER_GRAY,
                                       _("Pick color from the image"));
          gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
          gtk_widget_show (button);
        }

      *label = g_param_spec_get_nick (pspec);
    }
  else
    {
      g_warning ("%s: not supported: %s (%s)\n", G_STRFUNC,
                 g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name);
    }

  return widget;
}
/* XXX Historical note, originally I tried (ab)using override properties
 *     in ESourceCamel, which redirected to the equivalent CamelSettings
 *     property.  Seemed to work at first, and I was proud of my clever
 *     hack, but it turns out g_object_class_list_properties() excludes
 *     override properties.  So the ESourceCamel properties were being
 *     skipped in source_load_from_key_file() (e-source.c). */
static GParamSpec *
param_spec_clone (GParamSpec *pspec)
{
	GParamSpec *clone;
	GParamFlags flags;
	const gchar *name, *nick, *blurb;

	name = g_param_spec_get_name (pspec);
	nick = g_param_spec_get_nick (pspec);
	blurb = g_param_spec_get_blurb (pspec);
	flags = (pspec->flags & ~(G_PARAM_STATIC_STRINGS));

	if (G_IS_PARAM_SPEC_BOOLEAN (pspec)) {
		GParamSpecBoolean *pspec_boolean = G_PARAM_SPEC_BOOLEAN (pspec);

		clone = g_param_spec_boolean (name, nick, blurb,
			pspec_boolean->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_CHAR (pspec)) {
		GParamSpecChar *pspec_char = G_PARAM_SPEC_CHAR (pspec);

		clone = g_param_spec_char (name, nick, blurb,
			pspec_char->minimum,
			pspec_char->maximum,
			pspec_char->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_UCHAR (pspec)) {
		GParamSpecUChar *pspec_uchar = G_PARAM_SPEC_UCHAR (pspec);

		clone = g_param_spec_uchar (name, nick, blurb,
			pspec_uchar->minimum,
			pspec_uchar->maximum,
			pspec_uchar->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_INT (pspec)) {
		GParamSpecInt *pspec_int = G_PARAM_SPEC_INT (pspec);

		clone = g_param_spec_int (name, nick, blurb,
			pspec_int->minimum,
			pspec_int->maximum,
			pspec_int->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_UINT (pspec)) {
		GParamSpecUInt *pspec_uint = G_PARAM_SPEC_UINT (pspec);

		clone = g_param_spec_uint (name, nick, blurb,
			pspec_uint->minimum,
			pspec_uint->maximum,
			pspec_uint->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_LONG (pspec)) {
		GParamSpecLong *pspec_long = G_PARAM_SPEC_LONG (pspec);

		clone = g_param_spec_long (name, nick, blurb,
			pspec_long->minimum,
			pspec_long->maximum,
			pspec_long->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_ULONG (pspec)) {
		GParamSpecULong *pspec_ulong = G_PARAM_SPEC_ULONG (pspec);

		clone = g_param_spec_ulong (name, nick, blurb,
			pspec_ulong->minimum,
			pspec_ulong->maximum,
			pspec_ulong->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_INT64 (pspec)) {
		GParamSpecInt64 *pspec_int64 = G_PARAM_SPEC_INT64 (pspec);

		clone = g_param_spec_int64 (name, nick, blurb,
			pspec_int64->minimum,
			pspec_int64->maximum,
			pspec_int64->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_UINT64 (pspec)) {
		GParamSpecUInt64 *pspec_uint64 = G_PARAM_SPEC_UINT64 (pspec);

		clone = g_param_spec_uint64 (name, nick, blurb,
			pspec_uint64->minimum,
			pspec_uint64->maximum,
			pspec_uint64->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_FLOAT (pspec)) {
		GParamSpecFloat *pspec_float = G_PARAM_SPEC_FLOAT (pspec);

		clone = g_param_spec_float (name, nick, blurb,
			pspec_float->minimum,
			pspec_float->maximum,
			pspec_float->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_DOUBLE (pspec)) {
		GParamSpecDouble *pspec_double = G_PARAM_SPEC_DOUBLE (pspec);

		clone = g_param_spec_double (name, nick, blurb,
			pspec_double->minimum,
			pspec_double->maximum,
			pspec_double->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_ENUM (pspec)) {
		GParamSpecEnum *pspec_enum = G_PARAM_SPEC_ENUM (pspec);

		clone = g_param_spec_enum (name, nick, blurb,
			pspec->value_type,
			pspec_enum->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_FLAGS (pspec)) {
		GParamSpecFlags *pspec_flags = G_PARAM_SPEC_FLAGS (pspec);

		clone = g_param_spec_flags (name, nick, blurb,
			pspec->value_type,
			pspec_flags->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_STRING (pspec)) {
		GParamSpecString *pspec_string = G_PARAM_SPEC_STRING (pspec);

		clone = g_param_spec_string (name, nick, blurb,
			pspec_string->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_PARAM (pspec)) {
		clone = g_param_spec_param (name, nick, blurb,
			pspec->value_type,
			flags);
	} else if (G_IS_PARAM_SPEC_BOXED (pspec)) {
		clone = g_param_spec_boxed (name, nick, blurb,
			pspec->value_type,
			flags);
	} else if (G_IS_PARAM_SPEC_POINTER (pspec)) {
		clone = g_param_spec_pointer (name, nick, blurb, flags);
	} else if (G_IS_PARAM_SPEC_OBJECT (pspec)) {
		clone = g_param_spec_object (name, nick, blurb,
			pspec->value_type,
			flags);
	} else if (G_IS_PARAM_SPEC_UNICHAR (pspec)) {
		GParamSpecUnichar *pspec_unichar = G_PARAM_SPEC_UNICHAR (pspec);

		clone = g_param_spec_unichar (name, nick, blurb,
			pspec_unichar->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_GTYPE (pspec)) {
		GParamSpecGType *pspec_gtype = G_PARAM_SPEC_GTYPE (pspec);

		clone = g_param_spec_gtype (name, nick, blurb,
			pspec_gtype->is_a_type,
			flags);
	} else if (G_IS_PARAM_SPEC_VARIANT (pspec)) {
		GParamSpecVariant *pspec_variant = G_PARAM_SPEC_VARIANT (pspec);

		clone = g_param_spec_variant (name, nick, blurb,
			pspec_variant->type,
			pspec_variant->default_value,
			flags);
	} else {
		g_warn_if_reached ();
	}

	return clone;
}
Esempio n. 10
0
/* --- test functions --- */
static void
pspec_select_value (GParamSpec *pspec,
                    GValue     *value,
                    double      dvalue)
{
  /* generate a value suitable for pspec */
  if (G_IS_PARAM_SPEC_CHAR (pspec))
    ASSIGN_VALUE (g_value_set_char, value, GParamSpecChar*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_UCHAR (pspec))
    ASSIGN_VALUE (g_value_set_uchar, value, GParamSpecUChar*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_INT (pspec))
    ASSIGN_VALUE (g_value_set_int, value, GParamSpecInt*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_UINT (pspec))
    ASSIGN_VALUE (g_value_set_uint, value, GParamSpecUInt*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_LONG (pspec))
    ASSIGN_VALUE (g_value_set_long, value, GParamSpecLong*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_ULONG (pspec))
    ASSIGN_VALUE (g_value_set_ulong, value, GParamSpecULong*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_INT64 (pspec))
    ASSIGN_VALUE (g_value_set_int64, value, GParamSpecInt64*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_UINT64 (pspec))
    ASSIGN_VALUE (g_value_set_uint64, value, GParamSpecUInt64*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_FLOAT (pspec))
    ASSIGN_VALUE (g_value_set_float, value, GParamSpecFloat*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
    ASSIGN_VALUE (g_value_set_double, value, GParamSpecDouble*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
    g_value_set_boolean (value, SELECT_VALUE (dvalue, ((GParamSpecBoolean*) pspec)->default_value, FALSE, TRUE));
  else if (G_IS_PARAM_SPEC_UNICHAR (pspec))
    g_value_set_uint (value, SELECT_VALUE (dvalue, ((GParamSpecUnichar*) pspec)->default_value, FALSE, TRUE));
  else if (G_IS_PARAM_SPEC_GTYPE (pspec))
    g_value_set_gtype (value, SELECT_VALUE ((int) dvalue, ((GParamSpecGType*) pspec)->is_a_type, 0, GTK_TYPE_WIDGET));
  else if (G_IS_PARAM_SPEC_STRING (pspec))
    {
      GParamSpecString *sspec = (GParamSpecString*) pspec;
      if (dvalue >= +2)
        g_value_set_string (value, sspec->default_value);
      if (dvalue > 0 && sspec->cset_first && sspec->cset_nth)
        g_value_take_string (value, g_strdup_printf ("%c%c", sspec->cset_first[0], sspec->cset_nth[0]));
      else /* if (sspec->ensure_non_null) */
        g_value_set_string (value, "");
    }
  else if (G_IS_PARAM_SPEC_ENUM (pspec))
    {
      GParamSpecEnum *espec = (GParamSpecEnum*) pspec;
      if (dvalue >= +2)
        g_value_set_enum (value, espec->default_value);
      if (dvalue >= 0 && dvalue <= 1)
        g_value_set_enum (value, espec->enum_class->values[(int) ((espec->enum_class->n_values - 1) * dvalue)].value);
      else if (dvalue <= -1)
        g_value_set_enum (value, espec->enum_class->values[g_test_rand_int_range (0, espec->enum_class->n_values)].value);
    }
  else if (G_IS_PARAM_SPEC_FLAGS (pspec))
    {
      GParamSpecFlags *fspec = (GParamSpecFlags*) pspec;
      if (dvalue >= +2)
        g_value_set_flags (value, fspec->default_value);
      if (dvalue >= 0 && dvalue <= 1)
        g_value_set_flags (value, fspec->flags_class->values[(int) ((fspec->flags_class->n_values - 1) * dvalue)].value);
      else if (dvalue <= -1)
        g_value_set_flags (value, fspec->flags_class->values[g_test_rand_int_range (0, fspec->flags_class->n_values)].value);
    }
  /* unimplemented:
   * G_IS_PARAM_SPEC_PARAM
   * G_IS_PARAM_SPEC_BOXED
   * G_IS_PARAM_SPEC_POINTER
   * G_IS_PARAM_SPEC_VALUE_ARRAY
   * G_IS_PARAM_SPEC_OBJECT
   */
}
Esempio n. 11
0
GParamSpec *
gimp_param_spec_duplicate (GParamSpec *pspec)
{
  GParamSpec  *copy = NULL;
  GParamFlags  flags;

  g_return_val_if_fail (pspec != NULL, NULL);

  flags = pspec->flags | GIMP_CONFIG_PARAM_SERIALIZE;

  if (G_IS_PARAM_SPEC_STRING (pspec))
    {
      GParamSpecString *spec = G_PARAM_SPEC_STRING (pspec);

      if (GEGL_IS_PARAM_SPEC_FILE_PATH (pspec))
        {
          copy = gimp_param_spec_config_path (pspec->name,
                                              g_param_spec_get_nick (pspec),
                                              g_param_spec_get_blurb (pspec),
                                              GIMP_CONFIG_PATH_FILE,
                                              spec->default_value,
                                              flags);
        }
      else
        {
          static GQuark multiline_quark = 0;

          if (! multiline_quark)
            multiline_quark = g_quark_from_static_string ("multiline");

          copy = g_param_spec_string (pspec->name,
                                      g_param_spec_get_nick (pspec),
                                      g_param_spec_get_blurb (pspec),
                                      spec->default_value,
                                      flags);

          if (GEGL_IS_PARAM_SPEC_MULTILINE (pspec))
            {
              g_param_spec_set_qdata (copy, multiline_quark,
                                      GINT_TO_POINTER (TRUE));
            }
        }
    }
  else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
    {
      GParamSpecBoolean *spec = G_PARAM_SPEC_BOOLEAN (pspec);

      copy = g_param_spec_boolean (pspec->name,
                                   g_param_spec_get_nick (pspec),
                                   g_param_spec_get_blurb (pspec),
                                   spec->default_value,
                                   flags);
    }
  else if (G_IS_PARAM_SPEC_ENUM (pspec))
    {
      GParamSpecEnum *spec = G_PARAM_SPEC_ENUM (pspec);

      copy = g_param_spec_enum (pspec->name,
                                g_param_spec_get_nick (pspec),
                                g_param_spec_get_blurb (pspec),
                                G_TYPE_FROM_CLASS (spec->enum_class),
                                spec->default_value,
                                flags);
    }
  else if (GEGL_IS_PARAM_SPEC_DOUBLE (pspec))
    {
      GeglParamSpecDouble *gspec = GEGL_PARAM_SPEC_DOUBLE (pspec);
      GParamSpecDouble    *spec = G_PARAM_SPEC_DOUBLE (pspec);

      copy = gegl_param_spec_double (pspec->name,
                                     g_param_spec_get_nick (pspec),
                                     g_param_spec_get_blurb (pspec),
                                     spec->minimum,
                                     spec->maximum,
                                     spec->default_value,
                                     gspec->ui_minimum,
                                     gspec->ui_maximum,
                                     gspec->ui_gamma,
                                     flags);
    }
  else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
    {
      GParamSpecDouble *spec = G_PARAM_SPEC_DOUBLE (pspec);

      copy = g_param_spec_double (pspec->name,
                                  g_param_spec_get_nick (pspec),
                                  g_param_spec_get_blurb (pspec),
                                  spec->minimum,
                                  spec->maximum,
                                  spec->default_value,
                                  flags);
    }
  else if (G_IS_PARAM_SPEC_FLOAT (pspec))
    {
      GParamSpecFloat *spec = G_PARAM_SPEC_FLOAT (pspec);

      copy = g_param_spec_float (pspec->name,
                                 g_param_spec_get_nick (pspec),
                                 g_param_spec_get_blurb (pspec),
                                 spec->minimum,
                                 spec->maximum,
                                 spec->default_value,
                                 flags);
    }
  else if (GEGL_IS_PARAM_SPEC_INT (pspec))
    {
      GeglParamSpecInt *gspec = GEGL_PARAM_SPEC_INT (pspec);
      GParamSpecInt    *spec  = G_PARAM_SPEC_INT (pspec);

      copy = gegl_param_spec_int (pspec->name,
                                  g_param_spec_get_nick (pspec),
                                  g_param_spec_get_blurb (pspec),
                                  spec->minimum,
                                  spec->maximum,
                                  spec->default_value,
                                  gspec->ui_minimum,
                                  gspec->ui_maximum,
                                  gspec->ui_gamma,
                                  flags);
    }
  else if (GEGL_IS_PARAM_SPEC_SEED (pspec))
    {
      copy = gegl_param_spec_seed (pspec->name,
                                   g_param_spec_get_nick (pspec),
                                   g_param_spec_get_blurb (pspec),
                                   pspec->flags |
                                   GIMP_CONFIG_PARAM_SERIALIZE);
    }
  else if (G_IS_PARAM_SPEC_INT (pspec))
    {
      GParamSpecInt *spec = G_PARAM_SPEC_INT (pspec);

      copy = g_param_spec_int (pspec->name,
                               g_param_spec_get_nick (pspec),
                               g_param_spec_get_blurb (pspec),
                               spec->minimum,
                               spec->maximum,
                               spec->default_value,
                               flags);
    }
  else if (G_IS_PARAM_SPEC_UINT (pspec))
    {
      GParamSpecUInt *spec = G_PARAM_SPEC_UINT (pspec);

      copy = g_param_spec_uint (pspec->name,
                                g_param_spec_get_nick (pspec),
                                g_param_spec_get_blurb (pspec),
                                spec->minimum,
                                spec->maximum,
                                spec->default_value,
                                flags);
    }
  else if (GIMP_IS_PARAM_SPEC_RGB (pspec))
    {
      GValue  value = G_VALUE_INIT;
      GimpRGB color;

      g_value_init (&value, GIMP_TYPE_RGB);
      g_param_value_set_default (pspec, &value);
      gimp_value_get_rgb (&value, &color);
      g_value_unset (&value);

      copy = gimp_param_spec_rgb (pspec->name,
                                  g_param_spec_get_nick (pspec),
                                  g_param_spec_get_blurb (pspec),
                                  gimp_param_spec_rgb_has_alpha (pspec),
                                  &color,
                                  flags);
    }
  else if (GEGL_IS_PARAM_SPEC_COLOR (pspec))
    {
      GeglColor *gegl_color;
      GimpRGB    gimp_color;
      gdouble    r = 0.0;
      gdouble    g = 0.0;
      gdouble    b = 0.0;
      gdouble    a = 1.0;
      GValue     value = { 0, };

      g_value_init (&value, GEGL_TYPE_COLOR);
      g_param_value_set_default (pspec, &value);

      gegl_color = g_value_get_object (&value);
      if (gegl_color)
        gegl_color_get_rgba (gegl_color, &r, &g, &b, &a);

      gimp_rgba_set (&gimp_color, r, g, b, a);

      g_value_unset (&value);

      copy = gimp_param_spec_rgb (pspec->name,
                                  g_param_spec_get_nick (pspec),
                                  g_param_spec_get_blurb (pspec),
                                  TRUE,
                                  &gimp_color,
                                  flags);
    }
  else if (G_IS_PARAM_SPEC_OBJECT (pspec) ||
           G_IS_PARAM_SPEC_POINTER (pspec))
    {
      /*  silently ignore object properties  */
    }
  else
    {
      g_warning ("%s: not supported: %s (%s)\n", G_STRFUNC,
                 g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name);
    }

  if (copy)
    {
      GQuark      quark = g_quark_from_static_string ("gegl-property-keys");
      GHashTable *keys  = g_param_spec_get_qdata (pspec, quark);

      if (keys)
        g_param_spec_set_qdata (copy, quark, g_hash_table_ref (keys));
    }

  return copy;
}
Esempio n. 12
0
void
qof_gobject_register (QofType e_type, GObjectClass *obclass)
{
    int i;
    int j;
    QofParam *qof_param_list, *qpar;
    QofObject *class_def;
    GParamSpec **prop_list, *gparam;
    guint n_props;

    /* Get the GObject properties, convert to QOF properties */
    prop_list = g_object_class_list_properties (obclass, &n_props);

    qof_param_list = g_new0 (QofParam, n_props);
    paramList = g_slist_prepend (paramList, qof_param_list);

    PINFO ("object %s has %d props", e_type, n_props);
    j = 0;
    for (i = 0; i < n_props; i++)
    {
        gparam = prop_list[i];
        qpar = &qof_param_list[j];

        PINFO ("param %d %s is type %s",
               i, gparam->name, G_PARAM_SPEC_TYPE_NAME(gparam));

        qpar->param_name = g_param_spec_get_name (gparam);
        qpar->param_getfcn = (QofAccessFunc)qof_gobject_getter;
        qpar->param_setfcn = NULL;
        qpar->param_userdata = gparam;
        if ((G_IS_PARAM_SPEC_INT(gparam))  ||
                (G_IS_PARAM_SPEC_UINT(gparam)) ||
                (G_IS_PARAM_SPEC_ENUM(gparam)) ||
                (G_IS_PARAM_SPEC_FLAGS(gparam)))
        {
            qpar->param_type = QOF_TYPE_INT32;
            j++;
        }
        else if ((G_IS_PARAM_SPEC_INT64(gparam)) ||
                 (G_IS_PARAM_SPEC_UINT64(gparam)))
        {
            qpar->param_type = QOF_TYPE_INT64;
            j++;
        }
        else if (G_IS_PARAM_SPEC_BOOLEAN(gparam))
        {
            qpar->param_type = QOF_TYPE_BOOLEAN;
            j++;
        }
        else if (G_IS_PARAM_SPEC_STRING(gparam))
        {
            qpar->param_type = QOF_TYPE_STRING;
            j++;
        }
        else if ((G_IS_PARAM_SPEC_POINTER(gparam)) ||
                 (G_IS_PARAM_SPEC_OBJECT(gparam)))
        {
            /* No-op, silently ignore.  Someday we should handle this ...  */
        }
        else if ((G_IS_PARAM_SPEC_FLOAT(gparam)) ||
                 (G_IS_PARAM_SPEC_DOUBLE(gparam)))
        {
            qpar->param_getfcn = (QofAccessFunc) qof_gobject_double_getter;
            qpar->param_type = QOF_TYPE_DOUBLE;
            j++;
        }
        else if (G_IS_PARAM_SPEC_CHAR(gparam))
        {
            qpar->param_type = QOF_TYPE_CHAR;
            j++;
        }
        else
        {
            PWARN ("Unknown/unhandled parameter type %s on %s:%s\n",
                   G_PARAM_SPEC_TYPE_NAME(gparam), e_type, qpar->param_name);
        }
    }

    /* NULL-terminated list! */
    qof_param_list[j].param_type = NULL;

    qof_class_register (e_type, NULL, qof_param_list);

    /* ------------------------------------------------------ */
    /* Now do the class itself */
    class_def = g_new0 (QofObject, 1);
    classList = g_slist_prepend (classList, class_def);

    class_def->interface_version = QOF_OBJECT_VERSION;
    class_def->e_type = e_type;
    /* We could let the user specify a "nick" here, but
     * the actual class name seems reasonable, e.g. for debugging. */
    class_def->type_label = G_OBJECT_CLASS_NAME (obclass);
    class_def->create = NULL;
    class_def->book_begin = NULL;
    class_def->book_end = NULL;
    class_def->is_dirty = NULL;
    class_def->mark_clean = NULL;
    class_def->foreach = qof_gobject_foreach;
    class_def->printable = NULL;
    class_def->version_cmp = NULL;

    qof_object_register (class_def);
}
Esempio n. 13
0
/**
 * gwy_adjustment_new_for_property:
 * @object: (transfer none):
 *          An object.
 * @propname: Name of property to create adjustment for.  The property must be
 *            of integral or double type.
 *
 * Creates a new adjustment with ranges, default and current value given by
 * the property of an object.
 *
 * Changes to the property value are reflected by changes in the adjustment
 * value and vice versa.  The adjustment does not take a reference to @object.
 * If @object ceases to exist before the adjustment does the adjustment will
 * remain configured the same way, just the value will not be synchronised with
 * anything.
 *
 * You can limit the adjustment range further than what is permitted by the
 * property after the construction.  Extending it is not allowed.
 *
 * Returns: A newly created adjustment.
 **/
GwyAdjustment*
gwy_adjustment_new_for_property(GObject *object,
                                const gchar *propname)
{
    GwyAdjustment *adj = gwy_adjustment_new();
    g_return_val_if_fail(G_IS_OBJECT(object), adj);
    Adjustment *priv = adj->priv;

    g_return_val_if_fail(propname, adj);
    GObjectClass *klass = G_OBJECT_GET_CLASS(object);
    GParamSpec *property = g_object_class_find_property(klass, propname);
    g_return_val_if_fail(property, adj);

    gdouble lower, upper, defaultval;
    gboolean is_integral = TRUE;

    // Try the types by descending probability.
    if (G_IS_PARAM_SPEC_DOUBLE(property)) {
        GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE(property);
        lower = pspec->minimum;
        upper = pspec->maximum;
        defaultval = pspec->default_value;
        is_integral = FALSE;
    }
    else if (G_IS_PARAM_SPEC_UINT(property)) {
        GParamSpecUInt *pspec = G_PARAM_SPEC_UINT(property);
        lower = pspec->minimum;
        upper = pspec->maximum;
        defaultval = pspec->default_value;
    }
    else if (G_IS_PARAM_SPEC_INT(property)) {
        GParamSpecInt *pspec = G_PARAM_SPEC_INT(property);
        lower = pspec->minimum;
        upper = pspec->maximum;
        defaultval = pspec->default_value;
    }
    else if (G_IS_PARAM_SPEC_LONG(property)) {
        GParamSpecLong *pspec = G_PARAM_SPEC_LONG(property);
        lower = pspec->minimum;
        upper = pspec->maximum;
        defaultval = pspec->default_value;
    }
    else if (G_IS_PARAM_SPEC_ULONG(property)) {
        GParamSpecULong *pspec = G_PARAM_SPEC_ULONG(property);
        lower = pspec->minimum;
        upper = pspec->maximum;
        defaultval = pspec->default_value;
    }
    else if (G_IS_PARAM_SPEC_FLOAT(property)) {
        GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT(property);
        lower = pspec->minimum;
        upper = pspec->maximum;
        defaultval = pspec->default_value;
        is_integral = FALSE;
    }
    else {
        g_critical("Cannot create adjustment for value type %s.",
                   g_type_name(property->value_type));
        return adj;
    }

    // Construct a harmless value for the gtk_adjustment_configure() call.
    gdouble step_increment, page_increment, value;
    // XXX: This needs more elaboration.
    if (is_integral) {
        value = gwy_round(0.5*(lower + upper));
        step_increment = 1.0;
        page_increment = MIN(upper - lower, 10.0);
    }
    else {
        value = 0.5*(lower + upper);
        step_increment = MAX((upper - lower)/100000.0, fabs(lower));
        step_increment = gwy_powi(10.0, gwy_round(log10(step_increment)));
        page_increment = sqrt(step_increment*(upper - lower));
        page_increment = gwy_powi(10.0, gwy_round(log10(page_increment)));
    }

    gtk_adjustment_configure(GTK_ADJUSTMENT(adj),
                             value, lower, upper,
                             step_increment, page_increment, 0.0);
    priv->defaultval = defaultval;
    // This takes care of value synchronisation from the property to us.
    priv->binding = g_object_bind_property(object, propname,
                                           adj, "value",
                                           G_BINDING_BIDIRECTIONAL
                                           | G_BINDING_SYNC_CREATE);
    g_object_add_weak_pointer(G_OBJECT(priv->binding),
                              (gpointer*)&priv->binding);

    return adj;
}