mirror of https://github.com/GNOME/gimp.git
libgimp, libgimpbase, libgimpwidgets: new gimp_range_estimate_settings()
Similar code was used in 2 places basically (GimpLabelSpin and GimpProcedureDialog) so just make it an utils function. It's good anyway to have a generic function to estimate suitable increments and decimal places depending on a range. As a consequence also gimp_label_spin_new() now takes a gint digits (instead of guint), with -1 meaning we want digits computed from the range. Similarly gimp_prop_scale_entry_new() docs adds the -1 meaning too.
This commit is contained in:
parent
9ca18c37cd
commit
8d5008d76f
|
@ -85,12 +85,6 @@ static void gimp_procedure_dialog_load_defaults (GtkWidget *button,
|
|||
static void gimp_procedure_dialog_save_defaults (GtkWidget *button,
|
||||
GimpProcedureDialog *dialog);
|
||||
|
||||
static void gimp_procedure_dialog_estimate_increments (gdouble lower,
|
||||
gdouble upper,
|
||||
gdouble *step,
|
||||
gdouble *page,
|
||||
gint *digits);
|
||||
|
||||
static gboolean gimp_procedure_dialog_check_mnemonic (GimpProcedureDialog *dialog,
|
||||
GtkWidget *widget,
|
||||
const gchar *id,
|
||||
|
@ -456,7 +450,7 @@ gimp_procedure_dialog_get_widget (GimpProcedureDialog *dialog,
|
|||
minimum = pspecdouble->minimum;
|
||||
maximum = pspecdouble->maximum;
|
||||
}
|
||||
gimp_procedure_dialog_estimate_increments (minimum, maximum, &step, &page, &digits);
|
||||
gimp_range_estimate_settings (minimum, maximum, &step, &page, &digits);
|
||||
|
||||
if (widget_type == G_TYPE_NONE || widget_type == GIMP_TYPE_LABEL_SPIN)
|
||||
{
|
||||
|
@ -1186,98 +1180,6 @@ gimp_procedure_dialog_save_defaults (GtkWidget *button,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_procedure_dialog_estimate_increments:
|
||||
* @lower:
|
||||
* @upper:
|
||||
* @step:
|
||||
* @page:
|
||||
*
|
||||
* Though sometimes you might want to specify step and page increments
|
||||
* on widgets explicitly, sometimes you are fine with just anything
|
||||
* which doesn't give you absurd values. This procedure just tries to
|
||||
* return such sensible increment values.
|
||||
*/
|
||||
static void
|
||||
gimp_procedure_dialog_estimate_increments (gdouble lower,
|
||||
gdouble upper,
|
||||
gdouble *step,
|
||||
gdouble *page,
|
||||
gint *digits)
|
||||
{
|
||||
gdouble range;
|
||||
|
||||
g_return_if_fail (upper >= lower);
|
||||
g_return_if_fail (step || page || digits);
|
||||
|
||||
range = upper - lower;
|
||||
|
||||
if (range > 0 && range <= 1.0)
|
||||
{
|
||||
gdouble places = 10.0;
|
||||
|
||||
if (digits)
|
||||
*digits = 3;
|
||||
|
||||
/* Compute some acceptable step and page increments always in the
|
||||
* format `10**-X` where X is the rounded precision.
|
||||
* So for instance:
|
||||
* 0.8 will have increments 0.01 and 0.1.
|
||||
* 0.3 will have increments 0.001 and 0.01.
|
||||
* 0.06 will also have increments 0.001 and 0.01.
|
||||
*/
|
||||
while (range * places < 5.0)
|
||||
{
|
||||
places *= 10.0;
|
||||
if (digits)
|
||||
(*digits)++;
|
||||
}
|
||||
|
||||
|
||||
if (step)
|
||||
*step = 0.1 / places;
|
||||
if (page)
|
||||
*page = 1.0 / places;
|
||||
}
|
||||
else if (range <= 2.0)
|
||||
{
|
||||
if (step)
|
||||
*step = 0.01;
|
||||
if (page)
|
||||
*page = 0.1;
|
||||
|
||||
if (digits)
|
||||
*digits = 3;
|
||||
}
|
||||
else if (range <= 5.0)
|
||||
{
|
||||
if (step)
|
||||
*step = 0.1;
|
||||
if (page)
|
||||
*page = 1.0;
|
||||
if (digits)
|
||||
*digits = 2;
|
||||
}
|
||||
else if (range <= 40.0)
|
||||
{
|
||||
if (step)
|
||||
*step = 1.0;
|
||||
if (page)
|
||||
*page = 2.0;
|
||||
if (digits)
|
||||
*digits = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (step)
|
||||
*step = 1.0;
|
||||
if (page)
|
||||
*page = 10.0;
|
||||
if (digits)
|
||||
*digits = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_procedure_dialog_check_mnemonic (GimpProcedureDialog *dialog,
|
||||
GtkWidget *widget,
|
||||
|
|
|
@ -159,6 +159,7 @@ EXPORTS
|
|||
gimp_plug_in_directory_file
|
||||
gimp_precision_get_type
|
||||
gimp_progress_command_get_type
|
||||
gimp_range_estimate_settings
|
||||
gimp_rectangle_intersect
|
||||
gimp_rectangle_union
|
||||
gimp_repeat_mode_get_type
|
||||
|
|
|
@ -1521,6 +1521,109 @@ gimp_stack_trace_query (const gchar *prog_name)
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_range_estimate_settings:
|
||||
* @lower: the lower value.
|
||||
* @upper: the higher value.
|
||||
* @step: (out) (optional): the proposed step increment.
|
||||
* @page: (out) (optional): the proposed page increment.
|
||||
* @digits: (out) (optional): the proposed decimal places precision.
|
||||
*
|
||||
* This function proposes reasonable settings for increments and display
|
||||
* digits. These can be used for instance on #GtkRange or other widgets
|
||||
* using a #GtkAdjustment typically.
|
||||
* Note that it will never return @digits with value 0. If you know that
|
||||
* your input needs to display integer values, there is no need to set
|
||||
* @digits.
|
||||
*
|
||||
* There is no universal answer to the best increments and number of
|
||||
* decimal places. It often depends on context of what the value is
|
||||
* meant to represent. This function only tries to provide sensible
|
||||
* generic values which can be used when it doesn't matter too much or
|
||||
* for generated GUI for instance. If you know exactly how you want to
|
||||
* show and interact with a given range, you don't have to use this
|
||||
* function.
|
||||
*/
|
||||
void
|
||||
gimp_range_estimate_settings (gdouble lower,
|
||||
gdouble upper,
|
||||
gdouble *step,
|
||||
gdouble *page,
|
||||
gint *digits)
|
||||
{
|
||||
gdouble range;
|
||||
|
||||
g_return_if_fail (upper >= lower);
|
||||
g_return_if_fail (step || page || digits);
|
||||
|
||||
range = upper - lower;
|
||||
|
||||
if (range > 0 && range <= 1.0)
|
||||
{
|
||||
gdouble places = 10.0;
|
||||
|
||||
if (digits)
|
||||
*digits = 3;
|
||||
|
||||
/* Compute some acceptable step and page increments always in the
|
||||
* format `10**-X` where X is the rounded precision.
|
||||
* So for instance:
|
||||
* 0.8 will have increments 0.01 and 0.1.
|
||||
* 0.3 will have increments 0.001 and 0.01.
|
||||
* 0.06 will also have increments 0.001 and 0.01.
|
||||
*/
|
||||
while (range * places < 5.0)
|
||||
{
|
||||
places *= 10.0;
|
||||
if (digits)
|
||||
(*digits)++;
|
||||
}
|
||||
|
||||
|
||||
if (step)
|
||||
*step = 0.1 / places;
|
||||
if (page)
|
||||
*page = 1.0 / places;
|
||||
}
|
||||
else if (range <= 2.0)
|
||||
{
|
||||
if (step)
|
||||
*step = 0.01;
|
||||
if (page)
|
||||
*page = 0.1;
|
||||
|
||||
if (digits)
|
||||
*digits = 3;
|
||||
}
|
||||
else if (range <= 5.0)
|
||||
{
|
||||
if (step)
|
||||
*step = 0.1;
|
||||
if (page)
|
||||
*page = 1.0;
|
||||
if (digits)
|
||||
*digits = 2;
|
||||
}
|
||||
else if (range <= 40.0)
|
||||
{
|
||||
if (step)
|
||||
*step = 1.0;
|
||||
if (page)
|
||||
*page = 2.0;
|
||||
if (digits)
|
||||
*digits = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (step)
|
||||
*step = 1.0;
|
||||
if (page)
|
||||
*page = 10.0;
|
||||
if (digits)
|
||||
*digits = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Private functions. */
|
||||
|
||||
|
|
|
@ -82,6 +82,12 @@ gboolean gimp_stack_trace_print (const gchar *prog_na
|
|||
gchar **trace);
|
||||
void gimp_stack_trace_query (const gchar *prog_name);
|
||||
|
||||
void gimp_range_estimate_settings (gdouble lower,
|
||||
gdouble upper,
|
||||
gdouble *step,
|
||||
gdouble *page,
|
||||
gint *digits);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ typedef struct _GimpLabelSpinPrivate
|
|||
|
||||
GtkWidget *spinbutton;
|
||||
GtkAdjustment *spin_adjustment;
|
||||
|
||||
gint digits;
|
||||
} GimpLabelSpinPrivate;
|
||||
|
||||
static void gimp_label_spin_constructed (GObject *object);
|
||||
|
@ -78,8 +80,11 @@ static GtkWidget * gimp_label_spin_populate (GimpLabeled *spin,
|
|||
gint *width,
|
||||
gint *height);
|
||||
|
||||
static void gimp_label_spin_update_spin_width (GimpLabelSpin *spin);
|
||||
static void gimp_label_spin_update_increments (GimpLabelSpin *spin);
|
||||
static void gimp_label_spin_update_spin_width (GimpLabelSpin *spin,
|
||||
gdouble lower,
|
||||
gdouble upper,
|
||||
guint digits);
|
||||
static void gimp_label_spin_update_settings (GimpLabelSpin *spin);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GimpLabelSpin, gimp_label_spin, GIMP_TYPE_LABELED)
|
||||
|
||||
|
@ -151,15 +156,16 @@ gimp_label_spin_class_init (GimpLabelSpinClass *klass)
|
|||
/**
|
||||
* GimpLabelSpin:digits:
|
||||
*
|
||||
* The number of decimal places to display.
|
||||
* The number of decimal places to display. If -1, then the number is
|
||||
* estimated.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
g_object_class_install_property (object_class, PROP_DIGITS,
|
||||
g_param_spec_uint ("digits", NULL,
|
||||
"The number of decimal places to display",
|
||||
0, G_MAXUINT, 2,
|
||||
GIMP_PARAM_READWRITE));
|
||||
g_param_spec_int ("digits", NULL,
|
||||
"The number of decimal places to display",
|
||||
-1, G_MAXINT, -1,
|
||||
GIMP_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -195,8 +201,7 @@ gimp_label_spin_constructed (GObject *object)
|
|||
G_BINDING_BIDIRECTIONAL |
|
||||
G_BINDING_SYNC_CREATE);
|
||||
|
||||
gimp_label_spin_update_spin_width (spin);
|
||||
gimp_label_spin_update_increments (spin);
|
||||
gimp_label_spin_update_settings (spin);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -224,8 +229,7 @@ gimp_label_spin_set_property (GObject *object,
|
|||
g_value_get_double (value));
|
||||
if (priv->spinbutton)
|
||||
{
|
||||
gimp_label_spin_update_spin_width (spin);
|
||||
gimp_label_spin_update_increments (spin);
|
||||
gimp_label_spin_update_settings (spin);
|
||||
}
|
||||
break;
|
||||
case PROP_UPPER:
|
||||
|
@ -233,18 +237,14 @@ gimp_label_spin_set_property (GObject *object,
|
|||
g_value_get_double (value));
|
||||
if (priv->spinbutton)
|
||||
{
|
||||
gimp_label_spin_update_spin_width (spin);
|
||||
gimp_label_spin_update_increments (spin);
|
||||
gimp_label_spin_update_settings (spin);
|
||||
}
|
||||
break;
|
||||
case PROP_DIGITS:
|
||||
if (priv->spinbutton)
|
||||
{
|
||||
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (priv->spinbutton),
|
||||
g_value_get_uint (value));
|
||||
|
||||
gimp_label_spin_update_spin_width (spin);
|
||||
gimp_label_spin_update_increments (spin);
|
||||
priv->digits = g_value_get_int (value);
|
||||
gimp_label_spin_update_settings (spin);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -305,22 +305,16 @@ gimp_label_spin_populate (GimpLabeled *labeled,
|
|||
}
|
||||
|
||||
static void
|
||||
gimp_label_spin_update_spin_width (GimpLabelSpin *spin)
|
||||
gimp_label_spin_update_spin_width (GimpLabelSpin *spin,
|
||||
gdouble lower,
|
||||
gdouble upper,
|
||||
guint digits)
|
||||
{
|
||||
GimpLabelSpinPrivate *priv = gimp_label_spin_get_instance_private (spin);
|
||||
gint width = 0;
|
||||
gdouble lower;
|
||||
gdouble upper;
|
||||
gint digits;
|
||||
|
||||
g_return_if_fail (GIMP_IS_LABEL_SPIN (spin));
|
||||
|
||||
g_object_get (spin,
|
||||
"lower", &lower,
|
||||
"upper", &upper,
|
||||
"digits", &digits,
|
||||
NULL);
|
||||
|
||||
/* Necessary size to display the max/min integer values, with optional
|
||||
* negative sign.
|
||||
*/
|
||||
|
@ -337,11 +331,14 @@ gimp_label_spin_update_spin_width (GimpLabelSpin *spin)
|
|||
}
|
||||
|
||||
static void
|
||||
gimp_label_spin_update_increments (GimpLabelSpin *spin)
|
||||
gimp_label_spin_update_settings (GimpLabelSpin *spin)
|
||||
{
|
||||
gdouble lower;
|
||||
gdouble upper;
|
||||
gdouble range;
|
||||
GimpLabelSpinPrivate *priv = gimp_label_spin_get_instance_private (spin);
|
||||
gdouble lower;
|
||||
gdouble upper;
|
||||
gdouble step;
|
||||
gdouble page;
|
||||
gint digits = priv->digits;
|
||||
|
||||
g_return_if_fail (GIMP_IS_LABEL_SPIN (spin));
|
||||
|
||||
|
@ -352,46 +349,11 @@ gimp_label_spin_update_increments (GimpLabelSpin *spin)
|
|||
|
||||
g_return_if_fail (upper >= lower);
|
||||
|
||||
range = upper - lower;
|
||||
|
||||
if (range > 0 && range <= 1.0)
|
||||
{
|
||||
gdouble places = 10.0;
|
||||
gdouble step;
|
||||
gdouble page;
|
||||
|
||||
/* Compute some acceptable step and page increments always in the
|
||||
* format `10**-X` where X is the rounded precision.
|
||||
* So for instance:
|
||||
* 0.8 will have increments 0.01 and 0.1.
|
||||
* 0.3 will have increments 0.001 and 0.01.
|
||||
* 0.06 will also have increments 0.001 and 0.01.
|
||||
*/
|
||||
while (range * places < 5.0)
|
||||
places *= 10.0;
|
||||
|
||||
|
||||
step = 0.1 / places;
|
||||
page = 1.0 / places;
|
||||
|
||||
gimp_label_spin_set_increments (spin, step, page);
|
||||
}
|
||||
else if (range <= 2.0)
|
||||
{
|
||||
gimp_label_spin_set_increments (spin, 0.01, 0.1);
|
||||
}
|
||||
else if (range <= 5.0)
|
||||
{
|
||||
gimp_label_spin_set_increments (spin, 0.1, 1.0);
|
||||
}
|
||||
else if (range <= 40.0)
|
||||
{
|
||||
gimp_label_spin_set_increments (spin, 1.0, 2.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_label_spin_set_increments (spin, 1.0, 10.0);
|
||||
}
|
||||
gimp_range_estimate_settings (lower, upper, &step, &page,
|
||||
digits < 0 ? &digits: NULL);
|
||||
gimp_label_spin_set_increments (spin, step, page);
|
||||
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (priv->spinbutton), (guint) digits);
|
||||
gimp_label_spin_update_spin_width (spin, lower, upper, (guint) digits);
|
||||
}
|
||||
|
||||
|
||||
|
@ -406,6 +368,12 @@ gimp_label_spin_update_increments (GimpLabelSpin *spin)
|
|||
* @upper: The upper boundary.
|
||||
* @digits: The number of decimal digits.
|
||||
*
|
||||
* Suitable increment values are estimated based on the [@lower, @upper]
|
||||
* range.
|
||||
* If @digits is -1, then it will also be estimated based on the same
|
||||
* range. Digits estimation will always be at least 1, so if you want to
|
||||
* show integer values only, set 0 explicitly.
|
||||
*
|
||||
* Returns: (transfer full): The new #GimpLabelSpin widget.
|
||||
**/
|
||||
GtkWidget *
|
||||
|
@ -413,10 +381,13 @@ gimp_label_spin_new (const gchar *text,
|
|||
gdouble value,
|
||||
gdouble lower,
|
||||
gdouble upper,
|
||||
guint digits)
|
||||
gint digits)
|
||||
{
|
||||
GtkWidget *labeled;
|
||||
|
||||
g_return_val_if_fail (upper >= lower, NULL);
|
||||
g_return_val_if_fail (digits >= -1, NULL);
|
||||
|
||||
labeled = g_object_new (GIMP_TYPE_LABEL_SPIN,
|
||||
"label", text,
|
||||
"value", value,
|
||||
|
|
|
@ -55,7 +55,7 @@ GtkWidget * gimp_label_spin_new (const gchar *text,
|
|||
gdouble value,
|
||||
gdouble lower,
|
||||
gdouble upper,
|
||||
guint digits);
|
||||
gint digits);
|
||||
|
||||
void gimp_label_spin_set_value (GimpLabelSpin *spin,
|
||||
gdouble value);
|
||||
|
|
|
@ -1513,6 +1513,8 @@ gimp_prop_hscale_new (GObject *config,
|
|||
* @property_name: Name of integer or double property controlled by the scale.
|
||||
* @digits: Number of digits after decimal point to display. For
|
||||
* integer properties, this will be ignored (always 0).
|
||||
* If set to -1, a reasonable value will be
|
||||
* approximated depending on @property_name's range.
|
||||
* @limit_scale: %FALSE if the range of possible values of the
|
||||
* GtkHScale should be the same as of the GtkSpinButton.
|
||||
* @lower_limit: The scale's lower boundary if @scale_limits is %TRUE.
|
||||
|
|
Loading…
Reference in New Issue