
because it confuses gtk-doc and breaks some links. Also change the "Index of new symbols in GIMP 2.x" sections to be what seems to be the modern standard (looked at the GLib and GTK+ docs), and update some other stuff.
532 lines
21 KiB
C
532 lines
21 KiB
C
/* LIBGIMP - The GIMP Library
|
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
|
*
|
|
* gimpscaleentry.c
|
|
* Copyright (C) 2000 Michael Natterer <mitch@gimp.org>
|
|
*
|
|
* This library is free software: you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <gegl.h>
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "libgimpcolor/gimpcolor.h"
|
|
#include "libgimpmath/gimpmath.h"
|
|
#include "libgimpbase/gimpbase.h"
|
|
|
|
#include "gimpwidgets.h"
|
|
|
|
|
|
static void gimp_scale_entry_unconstrained_adjustment_callback (GtkAdjustment *adjustment,
|
|
GtkAdjustment *other_adj);
|
|
static void gimp_scale_entry_exp_adjustment_callback (GtkAdjustment *adjustment,
|
|
GtkAdjustment *other_adj);
|
|
static void gimp_scale_entry_log_adjustment_callback (GtkAdjustment *adjustment,
|
|
GtkAdjustment *other_adj);
|
|
|
|
static GtkObject * gimp_scale_entry_new_internal (gboolean color_scale,
|
|
GtkTable *table,
|
|
gint column,
|
|
gint row,
|
|
const gchar *text,
|
|
gint scale_width,
|
|
gint spinbutton_width,
|
|
gdouble value,
|
|
gdouble lower,
|
|
gdouble upper,
|
|
gdouble step_increment,
|
|
gdouble page_increment,
|
|
guint digits,
|
|
gboolean constrain,
|
|
gdouble unconstrained_lower,
|
|
gdouble unconstrained_upper,
|
|
const gchar *tooltip,
|
|
const gchar *help_id);
|
|
|
|
|
|
static void
|
|
gimp_scale_entry_unconstrained_adjustment_callback (GtkAdjustment *adjustment,
|
|
GtkAdjustment *other_adj)
|
|
{
|
|
g_signal_handlers_block_by_func (other_adj,
|
|
gimp_scale_entry_unconstrained_adjustment_callback,
|
|
adjustment);
|
|
|
|
gtk_adjustment_set_value (other_adj, gtk_adjustment_get_value (adjustment));
|
|
|
|
g_signal_handlers_unblock_by_func (other_adj,
|
|
gimp_scale_entry_unconstrained_adjustment_callback,
|
|
adjustment);
|
|
}
|
|
|
|
static void
|
|
gimp_scale_entry_log_adjustment_callback (GtkAdjustment *adjustment,
|
|
GtkAdjustment *other_adj)
|
|
{
|
|
gdouble value;
|
|
|
|
g_signal_handlers_block_by_func (other_adj,
|
|
gimp_scale_entry_exp_adjustment_callback,
|
|
adjustment);
|
|
|
|
if (gtk_adjustment_get_lower (adjustment) <= 0.0)
|
|
value = log (gtk_adjustment_get_value (adjustment) -
|
|
gtk_adjustment_get_lower (adjustment) + 0.1);
|
|
else
|
|
value = log (gtk_adjustment_get_value (adjustment));
|
|
|
|
gtk_adjustment_set_value (other_adj, value);
|
|
|
|
g_signal_handlers_unblock_by_func (other_adj,
|
|
gimp_scale_entry_exp_adjustment_callback,
|
|
adjustment);
|
|
}
|
|
|
|
static void
|
|
gimp_scale_entry_exp_adjustment_callback (GtkAdjustment *adjustment,
|
|
GtkAdjustment *other_adj)
|
|
{
|
|
gdouble value;
|
|
|
|
g_signal_handlers_block_by_func (other_adj,
|
|
gimp_scale_entry_log_adjustment_callback,
|
|
adjustment);
|
|
|
|
value = exp (gtk_adjustment_get_value (adjustment));
|
|
if (gtk_adjustment_get_lower (other_adj) <= 0.0)
|
|
value += gtk_adjustment_get_lower (other_adj) - 0.1;
|
|
|
|
gtk_adjustment_set_value (other_adj, value);
|
|
|
|
g_signal_handlers_unblock_by_func (other_adj,
|
|
gimp_scale_entry_log_adjustment_callback,
|
|
adjustment);
|
|
}
|
|
|
|
static GtkObject *
|
|
gimp_scale_entry_new_internal (gboolean color_scale,
|
|
GtkTable *table,
|
|
gint column,
|
|
gint row,
|
|
const gchar *text,
|
|
gint scale_width,
|
|
gint spinbutton_width,
|
|
gdouble value,
|
|
gdouble lower,
|
|
gdouble upper,
|
|
gdouble step_increment,
|
|
gdouble page_increment,
|
|
guint digits,
|
|
gboolean constrain,
|
|
gdouble unconstrained_lower,
|
|
gdouble unconstrained_upper,
|
|
const gchar *tooltip,
|
|
const gchar *help_id)
|
|
{
|
|
GtkWidget *label;
|
|
GtkWidget *scale;
|
|
GtkWidget *spinbutton;
|
|
GtkAdjustment *adjustment;
|
|
GtkAdjustment *return_adj;
|
|
|
|
label = gtk_label_new_with_mnemonic (text);
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
gtk_table_attach (GTK_TABLE (table), label,
|
|
column, column + 1, row, row + 1,
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
gtk_widget_show (label);
|
|
|
|
if (! constrain &&
|
|
unconstrained_lower <= lower &&
|
|
unconstrained_upper >= upper)
|
|
{
|
|
GtkAdjustment *constrained_adj;
|
|
|
|
constrained_adj = (GtkAdjustment *)
|
|
gtk_adjustment_new (value, lower, upper,
|
|
step_increment, page_increment,
|
|
0.0);
|
|
|
|
adjustment = (GtkAdjustment *)
|
|
gtk_adjustment_new (value,
|
|
unconstrained_lower,
|
|
unconstrained_upper,
|
|
step_increment, page_increment, 0.0);
|
|
spinbutton = gtk_spin_button_new (adjustment, step_increment, digits);
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
|
|
|
g_signal_connect
|
|
(constrained_adj, "value-changed",
|
|
G_CALLBACK (gimp_scale_entry_unconstrained_adjustment_callback),
|
|
adjustment);
|
|
|
|
g_signal_connect
|
|
(adjustment, "value-changed",
|
|
G_CALLBACK (gimp_scale_entry_unconstrained_adjustment_callback),
|
|
constrained_adj);
|
|
|
|
return_adj = adjustment;
|
|
|
|
adjustment = constrained_adj;
|
|
}
|
|
else
|
|
{
|
|
adjustment = (GtkAdjustment *)
|
|
gtk_adjustment_new (value, lower, upper,
|
|
step_increment, page_increment, 0.0);
|
|
spinbutton = gtk_spin_button_new (adjustment, step_increment, digits);
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
|
|
|
return_adj = adjustment;
|
|
}
|
|
|
|
gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinbutton);
|
|
|
|
if (spinbutton_width > 0)
|
|
{
|
|
if (spinbutton_width < 17)
|
|
gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), spinbutton_width);
|
|
else
|
|
gtk_widget_set_size_request (spinbutton, spinbutton_width, -1);
|
|
}
|
|
|
|
if (color_scale)
|
|
{
|
|
scale = gimp_color_scale_new (GTK_ORIENTATION_HORIZONTAL,
|
|
GIMP_COLOR_SELECTOR_VALUE);
|
|
|
|
gtk_range_set_adjustment (GTK_RANGE (scale), adjustment);
|
|
}
|
|
else
|
|
{
|
|
scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
|
|
}
|
|
|
|
if (scale_width > 0)
|
|
gtk_widget_set_size_request (scale, scale_width, -1);
|
|
gtk_scale_set_digits (GTK_SCALE (scale), digits);
|
|
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
|
|
gtk_table_attach (GTK_TABLE (table), scale,
|
|
column + 1, column + 2, row, row + 1,
|
|
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
|
|
gtk_widget_show (scale);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), spinbutton,
|
|
column + 2, column + 3, row, row + 1,
|
|
GTK_FILL | GTK_SHRINK, GTK_SHRINK, 0, 0);
|
|
gtk_widget_show (spinbutton);
|
|
|
|
if (tooltip || help_id)
|
|
{
|
|
gimp_help_set_help_data (label, tooltip, help_id);
|
|
gimp_help_set_help_data (scale, tooltip, help_id);
|
|
gimp_help_set_help_data (spinbutton, tooltip, help_id);
|
|
}
|
|
|
|
g_object_set_data (G_OBJECT (return_adj), "label", label);
|
|
g_object_set_data (G_OBJECT (return_adj), "scale", scale);
|
|
g_object_set_data (G_OBJECT (return_adj), "spinbutton", spinbutton);
|
|
|
|
return GTK_OBJECT (return_adj);
|
|
}
|
|
|
|
/**
|
|
* gimp_scale_entry_new:
|
|
* @table: The #GtkTable the widgets will be attached to.
|
|
* @column: The column to start with.
|
|
* @row: The row to attach the widgets.
|
|
* @text: The text for the #GtkLabel which will appear
|
|
* left of the #GtkHScale.
|
|
* @scale_width: The minimum horizontal size of the #GtkHScale.
|
|
* @spinbutton_width: The minimum horizontal size of the #GtkSpinButton.
|
|
* @value: The initial value.
|
|
* @lower: The lower boundary.
|
|
* @upper: The upper boundary.
|
|
* @step_increment: The step increment.
|
|
* @page_increment: The page increment.
|
|
* @digits: The number of decimal digits.
|
|
* @constrain: %TRUE if the range of possible values of the
|
|
* #GtkSpinButton should be the same as of the #GtkHScale.
|
|
* @unconstrained_lower: The spinbutton's lower boundary
|
|
* if @constrain == %FALSE.
|
|
* @unconstrained_upper: The spinbutton's upper boundary
|
|
* if @constrain == %FALSE.
|
|
* @tooltip: A tooltip message for the scale and the spinbutton.
|
|
* @help_id: The widgets' help_id (see gimp_help_set_help_data()).
|
|
*
|
|
* This function creates a #GtkLabel, a #GtkHScale and a #GtkSpinButton and
|
|
* attaches them to a 3-column #GtkTable.
|
|
*
|
|
* Returns: The #GtkSpinButton's #GtkAdjustment.
|
|
**/
|
|
GtkObject *
|
|
gimp_scale_entry_new (GtkTable *table,
|
|
gint column,
|
|
gint row,
|
|
const gchar *text,
|
|
gint scale_width,
|
|
gint spinbutton_width,
|
|
gdouble value,
|
|
gdouble lower,
|
|
gdouble upper,
|
|
gdouble step_increment,
|
|
gdouble page_increment,
|
|
guint digits,
|
|
gboolean constrain,
|
|
gdouble unconstrained_lower,
|
|
gdouble unconstrained_upper,
|
|
const gchar *tooltip,
|
|
const gchar *help_id)
|
|
{
|
|
return gimp_scale_entry_new_internal (FALSE,
|
|
table, column, row,
|
|
text, scale_width, spinbutton_width,
|
|
value, lower, upper,
|
|
step_increment, page_increment,
|
|
digits,
|
|
constrain,
|
|
unconstrained_lower,
|
|
unconstrained_upper,
|
|
tooltip, help_id);
|
|
}
|
|
|
|
/**
|
|
* gimp_color_scale_entry_new:
|
|
* @table: The #GtkTable the widgets will be attached to.
|
|
* @column: The column to start with.
|
|
* @row: The row to attach the widgets.
|
|
* @text: The text for the #GtkLabel which will appear
|
|
* left of the #GtkHScale.
|
|
* @scale_width: The minimum horizontal size of the #GtkHScale.
|
|
* @spinbutton_width: The minimum horizontal size of the #GtkSpinButton.
|
|
* @value: The initial value.
|
|
* @lower: The lower boundary.
|
|
* @upper: The upper boundary.
|
|
* @step_increment: The step increment.
|
|
* @page_increment: The page increment.
|
|
* @digits: The number of decimal digits.
|
|
* @tooltip: A tooltip message for the scale and the spinbutton.
|
|
* @help_id: The widgets' help_id (see gimp_help_set_help_data()).
|
|
*
|
|
* This function creates a #GtkLabel, a #GimpColorScale and a
|
|
* #GtkSpinButton and attaches them to a 3-column #GtkTable.
|
|
*
|
|
* Returns: The #GtkSpinButton's #GtkAdjustment.
|
|
**/
|
|
GtkObject *
|
|
gimp_color_scale_entry_new (GtkTable *table,
|
|
gint column,
|
|
gint row,
|
|
const gchar *text,
|
|
gint scale_width,
|
|
gint spinbutton_width,
|
|
gdouble value,
|
|
gdouble lower,
|
|
gdouble upper,
|
|
gdouble step_increment,
|
|
gdouble page_increment,
|
|
guint digits,
|
|
const gchar *tooltip,
|
|
const gchar *help_id)
|
|
{
|
|
return gimp_scale_entry_new_internal (TRUE,
|
|
table, column, row,
|
|
text, scale_width, spinbutton_width,
|
|
value, lower, upper,
|
|
step_increment, page_increment,
|
|
digits,
|
|
TRUE, 0.0, 0.0,
|
|
tooltip, help_id);
|
|
}
|
|
|
|
/**
|
|
* gimp_scale_entry_set_logarithmic:
|
|
* @adjustment: a #GtkAdjustment as returned by gimp_scale_entry_new()
|
|
* @logarithmic: a boolean value to set or reset logarithmic behaviour
|
|
* of the scale widget
|
|
*
|
|
* Sets whether the scale_entry's scale widget will behave in a linear
|
|
* or logharithmic fashion. Useful when an entry has to attend large
|
|
* ranges, but smaller selections on that range require a finer
|
|
* adjustment.
|
|
*
|
|
* Since: 2.2
|
|
**/
|
|
void
|
|
gimp_scale_entry_set_logarithmic (GtkObject *adjustment,
|
|
gboolean logarithmic)
|
|
{
|
|
GtkAdjustment *adj;
|
|
GtkAdjustment *scale_adj;
|
|
|
|
g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
|
|
|
|
adj = GTK_ADJUSTMENT (adjustment);
|
|
scale_adj = GIMP_SCALE_ENTRY_SCALE_ADJ (adjustment);
|
|
|
|
if (logarithmic == gimp_scale_entry_get_logarithmic (adjustment))
|
|
return;
|
|
|
|
if (logarithmic)
|
|
{
|
|
gdouble correction;
|
|
gdouble log_value, log_lower, log_upper;
|
|
gdouble log_step_increment, log_page_increment;
|
|
|
|
correction = (gtk_adjustment_get_lower (scale_adj) > 0 ?
|
|
0 : 0.1 + - gtk_adjustment_get_lower (scale_adj));
|
|
|
|
log_value = log (gtk_adjustment_get_value (scale_adj) + correction);
|
|
log_lower = log (gtk_adjustment_get_lower (scale_adj) + correction);
|
|
log_upper = log (gtk_adjustment_get_upper (scale_adj) + correction);
|
|
log_step_increment =
|
|
(log_upper - log_lower) / ((gtk_adjustment_get_upper (scale_adj) -
|
|
gtk_adjustment_get_lower (scale_adj)) /
|
|
gtk_adjustment_get_step_increment (scale_adj));
|
|
log_page_increment =
|
|
(log_upper - log_lower) / ((gtk_adjustment_get_upper (scale_adj) -
|
|
gtk_adjustment_get_lower (scale_adj)) /
|
|
gtk_adjustment_get_page_increment (scale_adj));
|
|
|
|
if (scale_adj == adj)
|
|
{
|
|
GtkObject *new_adj;
|
|
|
|
new_adj = gtk_adjustment_new (gtk_adjustment_get_value (scale_adj),
|
|
gtk_adjustment_get_lower (scale_adj),
|
|
gtk_adjustment_get_upper (scale_adj),
|
|
gtk_adjustment_get_step_increment (scale_adj),
|
|
gtk_adjustment_get_page_increment (scale_adj),
|
|
0.0);
|
|
gtk_range_set_adjustment (GTK_RANGE (GIMP_SCALE_ENTRY_SCALE (adj)),
|
|
GTK_ADJUSTMENT (new_adj));
|
|
|
|
scale_adj = (GtkAdjustment *) new_adj;
|
|
}
|
|
else
|
|
{
|
|
g_signal_handlers_disconnect_by_func (adj,
|
|
gimp_scale_entry_unconstrained_adjustment_callback,
|
|
scale_adj);
|
|
|
|
g_signal_handlers_disconnect_by_func (scale_adj,
|
|
gimp_scale_entry_unconstrained_adjustment_callback,
|
|
adj);
|
|
}
|
|
|
|
gtk_adjustment_configure (scale_adj,
|
|
log_value, log_lower, log_upper,
|
|
log_step_increment, log_page_increment, 0.0);
|
|
|
|
g_signal_connect (scale_adj, "value-changed",
|
|
G_CALLBACK (gimp_scale_entry_exp_adjustment_callback),
|
|
adj);
|
|
|
|
g_signal_connect (adj, "value-changed",
|
|
G_CALLBACK (gimp_scale_entry_log_adjustment_callback),
|
|
scale_adj);
|
|
|
|
g_object_set_data (G_OBJECT (adjustment),
|
|
"logarithmic", GINT_TO_POINTER (TRUE));
|
|
}
|
|
else
|
|
{
|
|
gdouble lower, upper;
|
|
|
|
g_signal_handlers_disconnect_by_func (adj,
|
|
gimp_scale_entry_log_adjustment_callback,
|
|
scale_adj);
|
|
|
|
g_signal_handlers_disconnect_by_func (scale_adj,
|
|
gimp_scale_entry_exp_adjustment_callback,
|
|
adj);
|
|
|
|
lower = exp (gtk_adjustment_get_lower (scale_adj));
|
|
upper = exp (gtk_adjustment_get_upper (scale_adj));
|
|
|
|
if (gtk_adjustment_get_lower (adj) <= 0.0)
|
|
{
|
|
lower += - 0.1 + gtk_adjustment_get_lower (adj);
|
|
upper += - 0.1 + gtk_adjustment_get_lower (adj);
|
|
}
|
|
|
|
gtk_adjustment_configure (scale_adj,
|
|
gtk_adjustment_get_value (adj),
|
|
lower, upper,
|
|
gtk_adjustment_get_step_increment (adj),
|
|
gtk_adjustment_get_page_increment (adj),
|
|
0.0);
|
|
|
|
g_signal_connect (scale_adj, "value-changed",
|
|
G_CALLBACK (gimp_scale_entry_unconstrained_adjustment_callback),
|
|
adj);
|
|
|
|
g_signal_connect (adj, "value-changed",
|
|
G_CALLBACK (gimp_scale_entry_unconstrained_adjustment_callback),
|
|
scale_adj);
|
|
|
|
g_object_set_data (G_OBJECT (adjustment),
|
|
"logarithmic", GINT_TO_POINTER (FALSE));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* gimp_scale_entry_get_logarithmic:
|
|
* @adjustment: a #GtkAdjustment as returned by gimp_scale_entry_new()
|
|
*
|
|
* Return value: %TRUE if the the entry's scale widget will behave in
|
|
* logharithmic fashion, %FALSE for linear behaviour.
|
|
*
|
|
* Since: 2.2
|
|
**/
|
|
gboolean
|
|
gimp_scale_entry_get_logarithmic (GtkObject *adjustment)
|
|
{
|
|
return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (adjustment),
|
|
"logarithmic"));
|
|
}
|
|
|
|
/**
|
|
* gimp_scale_entry_set_sensitive:
|
|
* @adjustment: a #GtkAdjustment returned by gimp_scale_entry_new()
|
|
* @sensitive: a boolean value with the same semantics as the @sensitive
|
|
* parameter of gtk_widget_set_sensitive()
|
|
*
|
|
* Sets the sensitivity of the scale_entry's #GtkLabel, #GtkHScale and
|
|
* #GtkSpinButton.
|
|
**/
|
|
void
|
|
gimp_scale_entry_set_sensitive (GtkObject *adjustment,
|
|
gboolean sensitive)
|
|
{
|
|
GtkWidget *widget;
|
|
|
|
g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
|
|
|
|
widget = GIMP_SCALE_ENTRY_LABEL (adjustment);
|
|
if (widget)
|
|
gtk_widget_set_sensitive (widget, sensitive);
|
|
|
|
widget = GIMP_SCALE_ENTRY_SCALE (adjustment);
|
|
if (widget)
|
|
gtk_widget_set_sensitive (widget, sensitive);
|
|
|
|
widget = GIMP_SCALE_ENTRY_SPINBUTTON (adjustment);
|
|
if (widget)
|
|
gtk_widget_set_sensitive (widget, sensitive);
|
|
}
|