* Lesser 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, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
#include "config.h"
+#include "gtkspinbutton.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <locale.h>
+#include "gtkadjustment.h"
#include "gtkbindings.h"
-#include "gtkspinbutton.h"
#include "gtkentryprivate.h"
+#include "gtkiconhelperprivate.h"
#include "gtkicontheme.h"
+#include "gtkintl.h"
#include "gtkmarshalers.h"
+#include "gtkorientable.h"
+#include "gtkorientableprivate.h"
+#include "gtkprivate.h"
#include "gtksettings.h"
#include "gtkstock.h"
-#include "gtkprivate.h"
-#include "gtkintl.h"
#include "gtktypebuiltins.h"
+#include "gtkwidgetpath.h"
+#include "gtkwidgetprivate.h"
#include "a11y/gtkspinbuttonaccessible.h"
gdouble climb_rate;
gdouble timer_step;
+ GtkOrientation orientation;
+
guint button : 2;
guint digits : 10;
guint need_timer : 1;
PROP_NUMERIC,
PROP_WRAP,
PROP_UPDATE_POLICY,
- PROP_VALUE
+ PROP_VALUE,
+ PROP_ORIENTATION
};
/* Signals */
static void gtk_spin_button_get_preferred_width (GtkWidget *widget,
gint *minimum,
gint *natural);
-
+static void gtk_spin_button_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural);
static void gtk_spin_button_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gint gtk_spin_button_draw (GtkWidget *widget,
gint *y,
gint *width,
gint *height);
+static void gtk_spin_button_get_frame_size (GtkEntry *entry,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height);
+static void gtk_spin_button_set_orientation (GtkSpinButton *spin_button,
+ GtkOrientation orientation);
static void gtk_spin_button_snap (GtkSpinButton *spin_button,
gdouble val);
static void gtk_spin_button_insert_text (GtkEditable *editable,
static gint gtk_spin_button_default_input (GtkSpinButton *spin_button,
gdouble *new_val);
-static gint gtk_spin_button_default_output (GtkSpinButton *spin_button);
+static void gtk_spin_button_default_output (GtkSpinButton *spin_button);
static guint spinbutton_signals[LAST_SIGNAL] = {0};
G_DEFINE_TYPE_WITH_CODE (GtkSpinButton, gtk_spin_button, GTK_TYPE_ENTRY,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL)
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
gtk_spin_button_editable_init))
widget_class->realize = gtk_spin_button_realize;
widget_class->unrealize = gtk_spin_button_unrealize;
widget_class->get_preferred_width = gtk_spin_button_get_preferred_width;
+ widget_class->get_preferred_height = gtk_spin_button_get_preferred_height;
widget_class->size_allocate = gtk_spin_button_size_allocate;
widget_class->draw = gtk_spin_button_draw;
widget_class->scroll_event = gtk_spin_button_scroll;
entry_class->activate = gtk_spin_button_activate;
entry_class->get_text_area_size = gtk_spin_button_get_text_area_size;
+ entry_class->get_frame_size = gtk_spin_button_get_frame_size;
class->input = NULL;
class->output = NULL;
0.0,
GTK_PARAM_READWRITE));
+ g_object_class_override_property (gobject_class,
+ PROP_ORIENTATION,
+ "orientation");
+
gtk_widget_class_install_style_property_parser (widget_class,
g_param_spec_enum ("shadow-type",
"Shadow Type",
case PROP_VALUE:
gtk_spin_button_set_value (spin_button, g_value_get_double (value));
break;
+ case PROP_ORIENTATION:
+ gtk_spin_button_set_orientation (spin_button, g_value_get_enum (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_VALUE:
g_value_set_double (value, gtk_adjustment_get_value (priv->adjustment));
break;
+ case PROP_ORIENTATION:
+ g_value_set_enum (value, priv->orientation);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
-static gint
-get_icon_size (void)
-{
- gint width, height, icon_size;
-
- gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
- icon_size = MAX (width, height);
-
- return icon_size;
-}
-
-static GdkPixbuf *
-create_one_pixbuf (GtkStyleContext *context,
- const gchar *icon_name)
-{
- GtkIconInfo *icon_info;
- GdkPixbuf *pix;
- gint size = get_icon_size ();
-
- icon_info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (),
- icon_name, size,
- GTK_ICON_LOOKUP_GENERIC_FALLBACK);
-
- if (icon_info != NULL)
- {
- pix = gtk_icon_info_load_symbolic_for_context (icon_info, context,
- NULL, NULL);
- gtk_icon_info_free (icon_info);
- }
- else
- {
- GtkIconSet *icon_set;
-
- icon_set = gtk_style_context_lookup_icon_set (context, GTK_STOCK_MISSING_IMAGE);
- pix = gtk_icon_set_render_icon_pixbuf (icon_set, context, size);
-
- g_warning ("Unable to fetch icon %s from the icon theme", icon_name);
- }
-
- return pix;
-}
-
static void
gtk_spin_button_init (GtkSpinButton *spin_button)
{
priv->wrap = FALSE;
priv->snap_to_ticks = FALSE;
+ priv->orientation = GTK_ORIENTATION_HORIZONTAL;
+
gtk_spin_button_set_adjustment (spin_button,
gtk_adjustment_new (0, 0, 0, 0, 0, 0));
context = gtk_widget_get_style_context (GTK_WIDGET (spin_button));
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SPINBUTTON);
+
+ gtk_widget_add_events (GTK_WIDGET (spin_button), GDK_SCROLL_MASK);
}
static void
GtkStyleContext *context,
GdkWindow *panel)
{
+ GtkSpinButtonPrivate *priv = spin_button->priv;
GtkWidget *widget = GTK_WIDGET (spin_button);
GtkWidgetPath *path, *siblings_path;
GtkTextDirection direction;
* have to emulate what gtk_container_get_path_for_child() would do
* for the button panels
*/
- path = gtk_widget_path_copy (gtk_widget_get_path (widget));
- direction = gtk_widget_get_direction (widget);
+ path = _gtk_widget_create_path (widget);
siblings_path = gtk_widget_path_new ();
- /* flip children order for RTL */
- if (direction == GTK_TEXT_DIR_RTL)
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
- up_pos = gtk_widget_path_append_type (siblings_path, GTK_TYPE_SPIN_BUTTON);
- down_pos = gtk_widget_path_append_type (siblings_path, GTK_TYPE_SPIN_BUTTON);
- gtk_widget_path_append_type (siblings_path, GTK_TYPE_ENTRY);
+ direction = gtk_widget_get_direction (widget);
+
+ /* flip children order for RTL */
+ if (direction == GTK_TEXT_DIR_RTL)
+ {
+ up_pos = gtk_widget_path_append_type (siblings_path, GTK_TYPE_SPIN_BUTTON);
+ down_pos = gtk_widget_path_append_type (siblings_path, GTK_TYPE_SPIN_BUTTON);
+ gtk_widget_path_append_type (siblings_path, GTK_TYPE_ENTRY);
+ }
+ else
+ {
+ gtk_widget_path_append_type (siblings_path, GTK_TYPE_ENTRY);
+ down_pos = gtk_widget_path_append_type (siblings_path, GTK_TYPE_SPIN_BUTTON);
+ up_pos = gtk_widget_path_append_type (siblings_path, GTK_TYPE_SPIN_BUTTON);
+ }
}
else
{
- gtk_widget_path_append_type (siblings_path, GTK_TYPE_ENTRY);
- down_pos = gtk_widget_path_append_type (siblings_path, GTK_TYPE_SPIN_BUTTON);
up_pos = gtk_widget_path_append_type (siblings_path, GTK_TYPE_SPIN_BUTTON);
+ gtk_widget_path_append_type (siblings_path, GTK_TYPE_ENTRY);
+ down_pos = gtk_widget_path_append_type (siblings_path, GTK_TYPE_SPIN_BUTTON);
}
gtk_widget_path_iter_add_class (siblings_path, up_pos, GTK_STYLE_CLASS_BUTTON);
gtk_widget_path_iter_add_class (siblings_path, up_pos, GTK_STYLE_CLASS_SPINBUTTON);
gtk_widget_path_iter_add_class (siblings_path, down_pos, GTK_STYLE_CLASS_SPINBUTTON);
- if (panel == spin_button->priv->down_panel)
- {
- gtk_widget_path_append_with_siblings (path, siblings_path, up_pos);
- gtk_widget_path_append_with_siblings (path, siblings_path, down_pos);
- }
+ if (panel == priv->down_panel)
+ gtk_widget_path_append_with_siblings (path, siblings_path, down_pos);
else
- {
- gtk_widget_path_append_with_siblings (path, siblings_path, down_pos);
- gtk_widget_path_append_with_siblings (path, siblings_path, up_pos);
- }
+ gtk_widget_path_append_with_siblings (path, siblings_path, up_pos);
gtk_style_context_set_path (context, path);
gtk_widget_path_unref (path);
GtkStateFlags state;
GtkSpinButtonPrivate *priv = spin_button->priv;
- if (gtk_spin_button_panel_at_limit (spin_button, panel))
- state = GTK_STATE_FLAG_INSENSITIVE;
+ state = gtk_widget_get_state_flags (GTK_WIDGET (spin_button));
+
+ state &= ~(GTK_STATE_FLAG_ACTIVE | GTK_STATE_FLAG_PRELIGHT);
+
+ if ((state & GTK_STATE_FLAG_INSENSITIVE) ||
+ gtk_spin_button_panel_at_limit (spin_button, panel) ||
+ !gtk_editable_get_editable (GTK_EDITABLE (spin_button)))
+ {
+ state |= GTK_STATE_FLAG_INSENSITIVE;
+ }
else
{
if (priv->click_child == panel)
- state = GTK_STATE_ACTIVE;
- else
- {
- if (priv->in_child == panel &&
- priv->click_child == NULL)
- state = GTK_STATE_FLAG_PRELIGHT;
- else
- state = gtk_widget_get_state_flags (GTK_WIDGET (spin_button));
- }
+ state |= GTK_STATE_FLAG_ACTIVE;
+ else if (priv->in_child == panel &&
+ priv->click_child == NULL)
+ state |= GTK_STATE_FLAG_PRELIGHT;
}
return state;
return context;
}
-static gint
-gtk_spin_button_panel_get_width (GtkSpinButton *spin_button,
- GdkWindow *panel)
+static void
+gtk_spin_button_panel_get_size (GtkSpinButton *spin_button,
+ GdkWindow *panel,
+ gint *width,
+ gint *height)
{
GtkBorder button_padding, button_border;
GtkStyleContext *context;
GtkStateFlags state;
+ gint icon_size, w, h;
+
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
+ icon_size = MAX (w, h);
context = gtk_spin_button_panel_get_context (spin_button, panel);
state = gtk_spin_button_panel_get_state (spin_button, panel);
g_object_unref (context);
- return get_icon_size () + button_padding.left + button_padding.right +
- button_border.left + button_border.right;
+ if (width)
+ *width = icon_size + button_padding.left + button_padding.right +
+ button_border.left + button_border.right;
+
+ if (height)
+ *height = icon_size + button_padding.top + button_padding.bottom +
+ button_border.top + button_border.bottom;
}
static void
GtkAllocation spin_allocation, down_allocation, up_allocation, allocation;
GtkRequisition requisition;
gint req_height;
- gint up_panel_width, down_panel_width;
+ gint down_panel_width, down_panel_height;
+ gint up_panel_width, up_panel_height;
GtkStyleContext *context;
- GtkBorder space;
+ GtkBorder border;
gtk_widget_get_allocation (widget, &spin_allocation);
gtk_widget_get_preferred_size (widget, &requisition, NULL);
context = gtk_widget_get_style_context (GTK_WIDGET (spin_button));
- gtk_style_context_get_border (context, GTK_STATE_NORMAL, &space);
+ gtk_style_context_get_border (context, GTK_STATE_FLAG_NORMAL, &border);
- req_height = requisition.height - gtk_widget_get_margin_top (widget) - gtk_widget_get_margin_bottom (widget);
- down_panel_width = gtk_spin_button_panel_get_width (spin_button, priv->down_panel);
- up_panel_width = gtk_spin_button_panel_get_width (spin_button, priv->up_panel);
+ gtk_spin_button_panel_get_size (spin_button, priv->down_panel, &down_panel_width, &down_panel_height);
+ gtk_spin_button_panel_get_size (spin_button, priv->up_panel, &up_panel_width, &up_panel_height);
- /* both panels have the same size, and they're as big as the entry allocation,
- * excluding margins
- */
- allocation.height = MIN (req_height, spin_allocation.height) - space.top - space.bottom;
- allocation.y = spin_allocation.y + space.top + (spin_allocation.height - req_height) / 2;
- down_allocation = up_allocation = allocation;
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ req_height = requisition.height - gtk_widget_get_margin_top (widget) - gtk_widget_get_margin_bottom (widget);
+
+ /* both panels have the same size, and they're as tall as the entry allocation,
+ * excluding margins
+ */
+ allocation.height = MIN (req_height, spin_allocation.height) - border.top - border.bottom;
+ allocation.y = spin_allocation.y + border.top + (spin_allocation.height - req_height) / 2;
+ down_allocation = up_allocation = allocation;
- down_allocation.width = down_panel_width;
- up_allocation.width = up_panel_width;
+ down_allocation.width = down_panel_width;
+ up_allocation.width = up_panel_width;
- /* invert x axis allocation for RTL */
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
- {
- up_allocation.x = spin_allocation.x + space.left;
- down_allocation.x = up_allocation.x + up_panel_width;
+ /* invert x axis allocation for RTL */
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+ {
+ up_allocation.x = spin_allocation.x + border.left;
+ down_allocation.x = up_allocation.x + up_panel_width;
+ }
+ else
+ {
+ up_allocation.x = spin_allocation.x + spin_allocation.width - up_panel_width - border.right;
+ down_allocation.x = up_allocation.x - down_panel_width;
+ }
}
else
{
- up_allocation.x = spin_allocation.x + spin_allocation.width - up_panel_width - space.right;
- down_allocation.x = up_allocation.x - down_panel_width;
+ /* both panels have the same size, and they're as wide as the entry allocation */
+ allocation.width = spin_allocation.width;
+ allocation.x = spin_allocation.x;
+ down_allocation = up_allocation = allocation;
+
+ down_allocation.height = down_panel_height;
+ up_allocation.height = up_panel_height;
+
+ up_allocation.y = spin_allocation.y;
+ down_allocation.y = spin_allocation.y + spin_allocation.height - down_allocation.height;
}
if (down_allocation_out)
GtkStateFlags state;
GtkWidget *widget;
gdouble width, height, x, y;
- GdkPixbuf *pix;
+ gint icon_width, icon_height;
+ GtkIconHelper *icon_helper;
widget = GTK_WIDGET (spin_button);
height = gdk_window_get_height (panel);
width = gdk_window_get_width (panel);
+ icon_helper = _gtk_icon_helper_new ();
+ _gtk_icon_helper_set_use_fallback (icon_helper, TRUE);
+
if (panel == priv->down_panel)
- pix = create_one_pixbuf (context, "list-remove-symbolic");
+ _gtk_icon_helper_set_icon_name (icon_helper, "list-remove-symbolic", GTK_ICON_SIZE_MENU);
else
- pix = create_one_pixbuf (context, "list-add-symbolic");
+ _gtk_icon_helper_set_icon_name (icon_helper, "list-add-symbolic", GTK_ICON_SIZE_MENU);
+
+ _gtk_icon_helper_get_size (icon_helper, context,
+ &icon_width, &icon_height);
gtk_render_background (context, cr,
0, 0, width, height);
gtk_render_frame (context, cr,
0, 0, width, height);
- x = floor ((width - gdk_pixbuf_get_width (pix)) / 2.0);
- y = floor ((height - gdk_pixbuf_get_height (pix)) / 2.0);
+ x = floor ((width - icon_width) / 2.0);
+ y = floor ((height - icon_height) / 2.0);
- gtk_render_icon (context, cr, pix,
- x, y);
+ _gtk_icon_helper_draw (icon_helper, context, cr,
+ x, y);
cairo_restore (cr);
- g_object_unref (pix);
+ g_object_unref (icon_helper);
g_object_unref (context);
}
priv->down_panel = gdk_window_new (gtk_widget_get_window (widget),
&attributes, attributes_mask);
- gdk_window_set_user_data (priv->down_panel, widget);
+ gtk_widget_register_window (widget, priv->down_panel);
/* create the right panel window */
attributes.x = up_allocation.x;
priv->up_panel = gdk_window_new (gtk_widget_get_window (widget),
&attributes, attributes_mask);
- gdk_window_set_user_data (priv->up_panel, widget);
+ gtk_widget_register_window (widget, priv->up_panel);
return_val = FALSE;
g_signal_emit (spin_button, spinbutton_signals[OUTPUT], 0, &return_val);
if (priv->down_panel)
{
- gdk_window_set_user_data (priv->down_panel, NULL);
+ gtk_widget_unregister_window (widget, priv->down_panel);
gdk_window_destroy (priv->down_panel);
priv->down_panel = NULL;
}
if (priv->up_panel)
{
- gdk_window_set_user_data (priv->up_panel, NULL);
+ gtk_widget_unregister_window (widget, priv->up_panel);
gdk_window_destroy (priv->up_panel);
priv->up_panel = NULL;
}
}
-static int
-compute_double_length (double val, int digits)
+static void
+gtk_spin_button_set_orientation (GtkSpinButton *spin,
+ GtkOrientation orientation)
{
- int a;
- int extra;
+ GtkEntry *entry = GTK_ENTRY (spin);
+ GtkSpinButtonPrivate *priv = spin->priv;
+
+ if (priv->orientation == orientation)
+ return;
+
+ priv->orientation = orientation;
+ _gtk_orientable_set_style_classes (GTK_ORIENTABLE (spin));
- a = 1;
- if (fabs (val) > 1.0)
- a = floor (log10 (fabs (val))) + 1;
+ /* change alignment if it's the default */
+ if (priv->orientation == GTK_ORIENTATION_VERTICAL &&
+ gtk_entry_get_alignment (entry) == 0.0)
+ gtk_entry_set_alignment (entry, 0.5);
+ else if (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
+ gtk_entry_get_alignment (entry) == 0.5)
+ gtk_entry_set_alignment (entry, 0.0);
+
+ g_object_notify (G_OBJECT (spin), "orientation");
+ gtk_widget_queue_resize (GTK_WIDGET (spin));
+}
+
+static gint
+measure_string_width (PangoLayout *layout,
+ const gchar *string)
+{
+ gint width;
- extra = 0;
+ pango_layout_set_text (layout, string, -1);
+ pango_layout_get_pixel_size (layout, &width, NULL);
- /* The dot: */
- if (digits > 0)
- extra++;
+ return width;
+}
- /* The sign: */
- if (val < 0)
- extra++;
+static gchar *
+gtk_spin_button_format_for_value (GtkSpinButton *spin_button,
+ gdouble value)
+{
+ GtkSpinButtonPrivate *priv = spin_button->priv;
+ gchar *buf = g_strdup_printf ("%0.*f", priv->digits, value);
- return a + digits + extra;
+ return buf;
}
static void
GtkSpinButtonPrivate *priv = spin_button->priv;
GtkEntry *entry = GTK_ENTRY (widget);
GtkStyleContext *style_context;
- gint up_panel_width, down_panel_width;
style_context = gtk_widget_get_style_context (widget);
- up_panel_width = gtk_spin_button_panel_get_width (spin_button, priv->up_panel);
- down_panel_width = gtk_spin_button_panel_get_width (spin_button, priv->down_panel);
GTK_WIDGET_CLASS (gtk_spin_button_parent_class)->get_preferred_width (widget, minimum, natural);
if (gtk_entry_get_width_chars (entry) < 0)
{
- PangoContext *context;
- const PangoFontDescription *font_desc;
- PangoFontMetrics *metrics;
- gint width;
- gint w;
- gint string_len;
- gint max_string_len;
- gint digit_width;
+ gint width, w;
gboolean interior_focus;
gint focus_width;
- gint xborder, yborder;
- GtkBorder inner_border;
+ GtkBorder borders;
+ PangoLayout *layout;
+ gchar *str;
gtk_style_context_get_style (style_context,
"interior-focus", &interior_focus,
"focus-line-width", &focus_width,
NULL);
- font_desc = gtk_style_context_get_font (style_context, GTK_STATE_FLAG_NORMAL);
-
- context = gtk_widget_get_pango_context (widget);
- metrics = pango_context_get_metrics (context, font_desc,
- pango_context_get_language (context));
- digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
- digit_width = PANGO_SCALE *
- ((digit_width + PANGO_SCALE - 1) / PANGO_SCALE);
-
- pango_font_metrics_unref (metrics);
+ layout = pango_layout_copy (gtk_entry_get_layout (entry));
/* Get max of MIN_SPIN_BUTTON_WIDTH, size of upper, size of lower */
width = MIN_SPIN_BUTTON_WIDTH;
- max_string_len = MAX (10, compute_double_length (1e9 * gtk_adjustment_get_step_increment (priv->adjustment),
- priv->digits));
- string_len = compute_double_length (gtk_adjustment_get_upper (priv->adjustment),
- priv->digits);
- w = PANGO_PIXELS (MIN (string_len, max_string_len) * digit_width);
- width = MAX (width, w);
- string_len = compute_double_length (gtk_adjustment_get_lower (priv->adjustment), priv->digits);
- w = PANGO_PIXELS (MIN (string_len, max_string_len) * digit_width);
+ str = gtk_spin_button_format_for_value (spin_button,
+ gtk_adjustment_get_upper (priv->adjustment));
+ w = measure_string_width (layout, str);
width = MAX (width, w);
+ g_free (str);
- _gtk_entry_get_borders (entry, &xborder, &yborder);
- _gtk_entry_effective_inner_border (entry, &inner_border);
+ str = gtk_spin_button_format_for_value (spin_button,
+ gtk_adjustment_get_lower (priv->adjustment));
+ w = measure_string_width (layout, str);
+ width = MAX (width, w);
+ g_free (str);
- width += xborder * 2 + inner_border.left + inner_border.right;
+ _gtk_entry_get_borders (entry, &borders);
+ width += borders.left + borders.right;
*minimum = width;
*natural = width;
+
+ g_object_unref (layout);
}
- *minimum += up_panel_width + down_panel_width;
- *natural += up_panel_width + down_panel_width;
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ gint down_panel_width;
+ gint up_panel_width;
+
+ gtk_spin_button_panel_get_size (spin_button, priv->down_panel, &down_panel_width, NULL);
+ gtk_spin_button_panel_get_size (spin_button, priv->up_panel, &up_panel_width, NULL);
+
+ *minimum += up_panel_width + down_panel_width;
+ *natural += up_panel_width + down_panel_width;
+ }
+}
+
+static void
+gtk_spin_button_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ GtkSpinButton *spin_button = GTK_SPIN_BUTTON (widget);
+ GtkSpinButtonPrivate *priv = spin_button->priv;
+
+ GTK_WIDGET_CLASS (gtk_spin_button_parent_class)->get_preferred_height (widget, minimum, natural);
+
+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ gint down_panel_height;
+ gint up_panel_height;
+
+ gtk_spin_button_panel_get_size (spin_button, priv->down_panel, NULL, &down_panel_height);
+ gtk_spin_button_panel_get_size (spin_button, priv->up_panel, NULL, &up_panel_height);
+
+ *minimum += up_panel_height + down_panel_height;
+ *natural += up_panel_height + down_panel_height;
+ }
}
static void
if (gtk_editable_get_editable (GTK_EDITABLE (widget))) {
gtk_spin_button_update (spin);
- if (event->button == 1)
+ if (event->button == GDK_BUTTON_PRIMARY)
start_spinning (spin, event->window, gtk_adjustment_get_step_increment (priv->adjustment));
- else if (event->button == 2)
+ else if (event->button == GDK_BUTTON_MIDDLE)
start_spinning (spin, event->window, gtk_adjustment_get_page_increment (priv->adjustment));
else
priv->click_child = event->window;
gtk_spin_button_stop_spinning (spin);
- if (event->button == 3)
+ if (event->button == GDK_BUTTON_SECONDARY)
{
gdouble diff;
GtkSpinButtonPrivate *priv = spin->priv;
gdouble old_value;
+ if (!gtk_editable_get_editable (GTK_EDITABLE (spin)))
+ {
+ gtk_widget_error_bell (GTK_WIDGET (spin));
+ return;
+ }
+
/* When the key binding is activated, there may be an outstanding
* value, so we first have to commit what is currently written in
* the spin buttons text entry. See #106574
old_value = gtk_adjustment_get_value (priv->adjustment);
- /* We don't test whether the entry is editable, since
- * this key binding conceptually corresponds to changing
- * the value with the buttons using the mouse, which
- * we allow for non-editable spin buttons.
- */
switch (scroll)
{
case GTK_SCROLL_STEP_BACKWARD:
GTK_ENTRY_CLASS (gtk_spin_button_parent_class)->activate (entry);
}
+static void
+gtk_spin_button_get_frame_size (GtkEntry *entry,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height)
+{
+ GtkSpinButtonPrivate *priv = GTK_SPIN_BUTTON (entry)->priv;
+ gint up_panel_width, up_panel_height;
+ gint down_panel_width, down_panel_height;
+
+ gtk_spin_button_panel_get_size (GTK_SPIN_BUTTON (entry), priv->up_panel, &up_panel_width, &up_panel_height);
+ gtk_spin_button_panel_get_size (GTK_SPIN_BUTTON (entry), priv->down_panel, &down_panel_width, &down_panel_height);
+
+ GTK_ENTRY_CLASS (gtk_spin_button_parent_class)->get_frame_size (entry, x, y, width, height);
+
+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ if (y)
+ *y += up_panel_height;
+
+ if (height)
+ *height -= up_panel_height + down_panel_height;
+ }
+}
+
static void
gtk_spin_button_get_text_area_size (GtkEntry *entry,
gint *x,
gint *height)
{
GtkSpinButtonPrivate *priv = GTK_SPIN_BUTTON (entry)->priv;
- gint up_panel_width, down_panel_width;
+ gint up_panel_width, up_panel_height;
+ gint down_panel_width, down_panel_height;
- up_panel_width = gtk_spin_button_panel_get_width (GTK_SPIN_BUTTON (entry), priv->up_panel);
- down_panel_width = gtk_spin_button_panel_get_width (GTK_SPIN_BUTTON (entry), priv->down_panel);
+ gtk_spin_button_panel_get_size (GTK_SPIN_BUTTON (entry), priv->up_panel, &up_panel_width, &up_panel_height);
+ gtk_spin_button_panel_get_size (GTK_SPIN_BUTTON (entry), priv->down_panel, &down_panel_width, &down_panel_height);
GTK_ENTRY_CLASS (gtk_spin_button_parent_class)->get_text_area_size (entry, x, y, width, height);
- if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
- if (x)
- *x += up_panel_width + down_panel_width;
+ if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
+ {
+ if (x)
+ *x += up_panel_width + down_panel_width;
+ }
+
+ if (width)
+ *width -= up_panel_width + down_panel_width;
}
+ else
+ {
+ if (y)
+ *y += up_panel_height;
- if (width)
- *width -= up_panel_width + down_panel_width;
+ if (height)
+ *height -= up_panel_height + down_panel_height;
+ }
}
static void
return FALSE;
}
-static gint
+static void
gtk_spin_button_default_output (GtkSpinButton *spin_button)
{
GtkSpinButtonPrivate *priv = spin_button->priv;
-
- gchar *buf = g_strdup_printf ("%0.*f", priv->digits, gtk_adjustment_get_value (priv->adjustment));
+ gchar *buf = gtk_spin_button_format_for_value (spin_button,
+ gtk_adjustment_get_value (priv->adjustment));
if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
+
g_free (buf);
- return FALSE;
}
* @policy: a #GtkSpinButtonUpdatePolicy value
*
* Sets the update behavior of a spin button.
- * This determines wether the spin button is always updated
+ * This determines whether the spin button is always updated
* or only when a valid value is set.
*/
void