forked from AuroraMiddleware/gtk
applied refactored patch from maemo-gtk that replaces the INNER_BORDER
2006-03-10 Michael Natterer <mitch@gimp.org> * gtk/gtkentry.[ch]: applied refactored patch from maemo-gtk that replaces the INNER_BORDER define by an "inner-border" style property of type GtkBorder. Additionally, add an "inner-border" object property plus API which allows to override any theme border, to allow pixel-perfect positioning of entries for inline editing. Fixes bug #333922. * gtk/gtk.symbols: add the new public functions.
This commit is contained in:
parent
9c7e7a546e
commit
1d2bcff97d
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
||||
2006-03-10 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* gtk/gtkentry.[ch]: applied refactored patch from maemo-gtk that
|
||||
replaces the INNER_BORDER define by an "inner-border" style
|
||||
property of type GtkBorder. Additionally, add an "inner-border"
|
||||
object property plus API which allows to override any theme
|
||||
border, to allow pixel-perfect positioning of entries for inline
|
||||
editing. Fixes bug #333922.
|
||||
|
||||
* gtk/gtk.symbols: add the new public functions.
|
||||
|
||||
2006-03-09 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_class_init): Replace the
|
||||
|
@ -1,3 +1,14 @@
|
||||
2006-03-10 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* gtk/gtkentry.[ch]: applied refactored patch from maemo-gtk that
|
||||
replaces the INNER_BORDER define by an "inner-border" style
|
||||
property of type GtkBorder. Additionally, add an "inner-border"
|
||||
object property plus API which allows to override any theme
|
||||
border, to allow pixel-perfect positioning of entries for inline
|
||||
editing. Fixes bug #333922.
|
||||
|
||||
* gtk/gtk.symbols: add the new public functions.
|
||||
|
||||
2006-03-09 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_class_init): Replace the
|
||||
|
@ -1146,6 +1146,7 @@ gtk_entry_get_activates_default
|
||||
gtk_entry_get_alignment
|
||||
gtk_entry_get_completion
|
||||
gtk_entry_get_has_frame
|
||||
gtk_entry_get_inner_border
|
||||
gtk_entry_get_invisible_char
|
||||
gtk_entry_get_layout
|
||||
gtk_entry_get_layout_offsets
|
||||
@ -1168,6 +1169,7 @@ gtk_entry_set_activates_default
|
||||
gtk_entry_set_alignment
|
||||
gtk_entry_set_completion
|
||||
gtk_entry_set_has_frame
|
||||
gtk_entry_set_inner_border
|
||||
gtk_entry_set_invisible_char
|
||||
gtk_entry_set_max_length
|
||||
gtk_entry_set_text
|
||||
|
186
gtk/gtkentry.c
186
gtk/gtkentry.c
@ -61,7 +61,6 @@
|
||||
|
||||
#define MIN_ENTRY_WIDTH 150
|
||||
#define DRAW_TIMEOUT 20
|
||||
#define INNER_BORDER 2
|
||||
#define COMPLETION_TIMEOUT 300
|
||||
|
||||
/* Initial size of buffer, in bytes */
|
||||
@ -70,6 +69,9 @@
|
||||
/* Maximum size of text buffer, in bytes */
|
||||
#define MAX_SIZE G_MAXUSHORT
|
||||
|
||||
static const GtkBorder default_inner_border = { 2, 2, 2, 2 };
|
||||
static GQuark quark_inner_border = 0;
|
||||
|
||||
typedef struct _GtkEntryPrivate GtkEntryPrivate;
|
||||
|
||||
#define GTK_ENTRY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ENTRY, GtkEntryPrivate))
|
||||
@ -102,6 +104,7 @@ enum {
|
||||
PROP_MAX_LENGTH,
|
||||
PROP_VISIBILITY,
|
||||
PROP_HAS_FRAME,
|
||||
PROP_INNER_BORDER,
|
||||
PROP_INVISIBLE_CHAR,
|
||||
PROP_ACTIVATES_DEFAULT,
|
||||
PROP_WIDTH_CHARS,
|
||||
@ -124,14 +127,14 @@ static void gtk_entry_class_init (GtkEntryClass *klass);
|
||||
static void gtk_entry_editable_init (GtkEditableClass *iface);
|
||||
static void gtk_entry_cell_editable_init (GtkCellEditableIface *iface);
|
||||
static void gtk_entry_init (GtkEntry *entry);
|
||||
static void gtk_entry_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_entry_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_entry_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_entry_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_entry_finalize (GObject *object);
|
||||
static void gtk_entry_destroy (GtkObject *object);
|
||||
|
||||
@ -330,6 +333,8 @@ static void get_widget_window_size (GtkEntry *entry,
|
||||
gint *y,
|
||||
gint *width,
|
||||
gint *height);
|
||||
static void get_inner_border (GtkEntry *entry,
|
||||
GtkBorder *border);
|
||||
|
||||
/* Completion */
|
||||
static gint gtk_entry_completion_timeout (gpointer data);
|
||||
@ -485,6 +490,8 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
class->toggle_overwrite = gtk_entry_toggle_overwrite;
|
||||
class->activate = gtk_entry_real_activate;
|
||||
|
||||
quark_inner_border = g_quark_from_static_string ("gtk-entry-inner-border");
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_CURSOR_POSITION,
|
||||
g_param_spec_int ("cursor-position",
|
||||
@ -538,6 +545,14 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
TRUE,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_INNER_BORDER,
|
||||
g_param_spec_boxed ("inner-border",
|
||||
P_("Inner Border"),
|
||||
P_("Border between text and frame. Overrides the inner-border style propety"),
|
||||
GTK_TYPE_BORDER,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_INVISIBLE_CHAR,
|
||||
g_param_spec_unichar ("invisible-char",
|
||||
@ -867,7 +882,21 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KP_Insert, 0,
|
||||
"toggle_overwrite", 0);
|
||||
|
||||
gtk_settings_install_property (g_param_spec_boolean ("gtk-entry-select-on-focus",
|
||||
/**
|
||||
* GtkEntry:inner-border:
|
||||
*
|
||||
* Sets the text area's border between the text and the frame
|
||||
*
|
||||
* Since: 2.10
|
||||
*/
|
||||
gtk_widget_class_install_style_property (widget_class,
|
||||
g_param_spec_boxed ("inner-border",
|
||||
P_("Inner Border"),
|
||||
P_("Border between text and frame."),
|
||||
GTK_TYPE_BORDER,
|
||||
GTK_PARAM_READABLE));
|
||||
|
||||
gtk_settings_install_property (g_param_spec_boolean ("gtk-entry-select-on-focus",
|
||||
P_("Select on focus"),
|
||||
P_("Whether to select the contents of an entry when it is focused"),
|
||||
TRUE,
|
||||
@ -944,6 +973,10 @@ gtk_entry_set_property (GObject *object,
|
||||
gtk_entry_set_has_frame (entry, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_INNER_BORDER:
|
||||
gtk_entry_set_inner_border (entry, g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_INVISIBLE_CHAR:
|
||||
gtk_entry_set_invisible_char (entry, g_value_get_uint (value));
|
||||
break;
|
||||
@ -1004,6 +1037,9 @@ gtk_entry_get_property (GObject *object,
|
||||
case PROP_HAS_FRAME:
|
||||
g_value_set_boolean (value, entry->has_frame);
|
||||
break;
|
||||
case PROP_INNER_BORDER:
|
||||
g_value_set_boxed (value, gtk_entry_get_inner_border (entry));
|
||||
break;
|
||||
case PROP_INVISIBLE_CHAR:
|
||||
g_value_set_uint (value, entry->invisible_char);
|
||||
break;
|
||||
@ -1273,6 +1309,7 @@ gtk_entry_size_request (GtkWidget *widget,
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
PangoFontMetrics *metrics;
|
||||
gint xborder, yborder;
|
||||
GtkBorder inner_border;
|
||||
PangoContext *context;
|
||||
|
||||
gtk_widget_ensure_style (widget);
|
||||
@ -1285,22 +1322,20 @@ gtk_entry_size_request (GtkWidget *widget,
|
||||
entry->descent = pango_font_metrics_get_descent (metrics);
|
||||
|
||||
_gtk_entry_get_borders (entry, &xborder, &yborder);
|
||||
|
||||
xborder += INNER_BORDER;
|
||||
yborder += INNER_BORDER;
|
||||
|
||||
get_inner_border (entry, &inner_border);
|
||||
|
||||
if (entry->width_chars < 0)
|
||||
requisition->width = MIN_ENTRY_WIDTH + xborder * 2;
|
||||
requisition->width = MIN_ENTRY_WIDTH + xborder * 2 + inner_border.left + inner_border.right;
|
||||
else
|
||||
{
|
||||
gint char_width = pango_font_metrics_get_approximate_char_width (metrics);
|
||||
gint digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
|
||||
gint char_pixels = (MAX (char_width, digit_width) + PANGO_SCALE - 1) / PANGO_SCALE;
|
||||
|
||||
requisition->width = char_pixels * entry->width_chars + xborder * 2;
|
||||
requisition->width = char_pixels * entry->width_chars + xborder * 2 + inner_border.left + inner_border.right;
|
||||
}
|
||||
|
||||
requisition->height = PANGO_PIXELS (entry->ascent + entry->descent) + yborder * 2;
|
||||
requisition->height = PANGO_PIXELS (entry->ascent + entry->descent) + yborder * 2 + inner_border.top + inner_border.bottom;
|
||||
|
||||
pango_font_metrics_unref (metrics);
|
||||
}
|
||||
@ -1368,6 +1403,32 @@ get_widget_window_size (GtkEntry *entry,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_inner_border (GtkEntry *entry,
|
||||
GtkBorder *border)
|
||||
{
|
||||
GtkBorder *tmp_border;
|
||||
|
||||
tmp_border = g_object_get_qdata (G_OBJECT (entry), quark_inner_border);
|
||||
|
||||
if (tmp_border)
|
||||
{
|
||||
*border = *tmp_border;
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_style_get (GTK_WIDGET (entry), "inner-border", &tmp_border, NULL);
|
||||
|
||||
if (tmp_border)
|
||||
{
|
||||
*border = *tmp_border;
|
||||
g_free (tmp_border);
|
||||
return;
|
||||
}
|
||||
|
||||
*border = default_inner_border;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
@ -3151,15 +3212,17 @@ get_layout_position (GtkEntry *entry,
|
||||
PangoLayout *layout;
|
||||
PangoRectangle logical_rect;
|
||||
gint area_width, area_height;
|
||||
GtkBorder inner_border;
|
||||
gint y_pos;
|
||||
PangoLayoutLine *line;
|
||||
|
||||
layout = gtk_entry_ensure_layout (entry, TRUE);
|
||||
|
||||
get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
|
||||
|
||||
area_height = PANGO_SCALE * (area_height - 2 * INNER_BORDER);
|
||||
|
||||
get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
|
||||
get_inner_border (entry, &inner_border);
|
||||
|
||||
area_height = PANGO_SCALE * (area_height - inner_border.top - inner_border.bottom);
|
||||
|
||||
line = pango_layout_get_lines (layout)->data;
|
||||
pango_layout_line_get_extents (line, NULL, &logical_rect);
|
||||
|
||||
@ -3175,10 +3238,10 @@ get_layout_position (GtkEntry *entry,
|
||||
else if (y_pos + logical_rect.height > area_height)
|
||||
y_pos = area_height - logical_rect.height;
|
||||
|
||||
y_pos = INNER_BORDER + y_pos / PANGO_SCALE;
|
||||
y_pos = inner_border.top + y_pos / PANGO_SCALE;
|
||||
|
||||
if (x)
|
||||
*x = INNER_BORDER - entry->scroll_offset;
|
||||
*x = inner_border.left - entry->scroll_offset;
|
||||
|
||||
if (y)
|
||||
*y = y_pos;
|
||||
@ -3215,6 +3278,7 @@ gtk_entry_draw_text (GtkEntry *entry)
|
||||
gint n_ranges, i;
|
||||
PangoRectangle logical_rect;
|
||||
GdkColor *selection_color, *text_color;
|
||||
GtkBorder inner_border;
|
||||
|
||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||
gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
|
||||
@ -3230,9 +3294,11 @@ gtk_entry_draw_text (GtkEntry *entry)
|
||||
text_color = &widget->style->text [GTK_STATE_ACTIVE];
|
||||
}
|
||||
|
||||
get_inner_border (entry, &inner_border);
|
||||
|
||||
for (i = 0; i < n_ranges; ++i)
|
||||
cairo_rectangle (cr,
|
||||
INNER_BORDER - entry->scroll_offset + ranges[2 * i],
|
||||
inner_border.left - entry->scroll_offset + ranges[2 * i],
|
||||
y,
|
||||
ranges[2 * i + 1],
|
||||
logical_rect.height);
|
||||
@ -3286,7 +3352,8 @@ gtk_entry_draw_cursor (GtkEntry *entry,
|
||||
GdkRectangle cursor_location;
|
||||
gboolean split_cursor;
|
||||
|
||||
gint xoffset = INNER_BORDER - entry->scroll_offset;
|
||||
GtkBorder inner_border;
|
||||
gint xoffset;
|
||||
gint strong_x, weak_x;
|
||||
gint text_area_height;
|
||||
PangoDirection dir1 = PANGO_DIRECTION_NEUTRAL;
|
||||
@ -3294,6 +3361,10 @@ gtk_entry_draw_cursor (GtkEntry *entry,
|
||||
gint x1 = 0;
|
||||
gint x2 = 0;
|
||||
|
||||
get_inner_border (entry, &inner_border);
|
||||
|
||||
xoffset = inner_border.left - entry->scroll_offset;
|
||||
|
||||
gdk_drawable_get_size (entry->text_area, NULL, &text_area_height);
|
||||
|
||||
gtk_entry_get_cursor_locations (entry, type, &strong_x, &weak_x);
|
||||
@ -3323,9 +3394,9 @@ gtk_entry_draw_cursor (GtkEntry *entry,
|
||||
}
|
||||
|
||||
cursor_location.x = xoffset + x1;
|
||||
cursor_location.y = INNER_BORDER;
|
||||
cursor_location.y = inner_border.top;
|
||||
cursor_location.width = 0;
|
||||
cursor_location.height = text_area_height - 2 * INNER_BORDER ;
|
||||
cursor_location.height = text_area_height - inner_border.top - inner_border.bottom;
|
||||
|
||||
draw_insertion_cursor (entry,
|
||||
&cursor_location, TRUE, dir1,
|
||||
@ -3451,6 +3522,7 @@ gtk_entry_adjust_scroll (GtkEntry *entry)
|
||||
GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
|
||||
gint min_offset, max_offset;
|
||||
gint text_area_width, text_width;
|
||||
GtkBorder inner_border;
|
||||
gint strong_x, weak_x;
|
||||
gint strong_xoffset, weak_xoffset;
|
||||
gfloat xalign;
|
||||
@ -3460,9 +3532,11 @@ gtk_entry_adjust_scroll (GtkEntry *entry)
|
||||
|
||||
if (!GTK_WIDGET_REALIZED (entry))
|
||||
return;
|
||||
|
||||
|
||||
get_inner_border (entry, &inner_border);
|
||||
|
||||
gdk_drawable_get_size (entry->text_area, &text_area_width, NULL);
|
||||
text_area_width -= 2 * INNER_BORDER;
|
||||
text_area_width -= inner_border.left + inner_border.right;
|
||||
if (text_area_width < 0)
|
||||
text_area_width = 0;
|
||||
|
||||
@ -4315,6 +4389,58 @@ gtk_entry_get_has_frame (GtkEntry *entry)
|
||||
return entry->has_frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_set_inner_border:
|
||||
* @entry: a #GtkEntry
|
||||
* @border: a #GtkBorder, or %NULL
|
||||
*
|
||||
* Sets %entry's inner-border property to %border, or clears it if %NULL
|
||||
* is passed. The inner-border is the area around the entry's text, but
|
||||
* inside its frame.
|
||||
*
|
||||
* If set, this property overrides the inner-border style property.
|
||||
* Overriding the style-provided border is useful when you want to do
|
||||
* in-place editing of some text in a canvas or list widget, where
|
||||
* pixel-exact positioning of the entry is important.
|
||||
*
|
||||
* Since: 2.10
|
||||
**/
|
||||
void
|
||||
gtk_entry_set_inner_border (GtkEntry *entry,
|
||||
const GtkBorder *border)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY (entry));
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (entry));
|
||||
|
||||
if (border)
|
||||
g_object_set_qdata_full (G_OBJECT (entry), quark_inner_border,
|
||||
gtk_border_copy (border),
|
||||
(GDestroyNotify) gtk_border_free);
|
||||
else
|
||||
g_object_set_qdata (G_OBJECT (entry), quark_inner_border, NULL);
|
||||
|
||||
g_object_notify (G_OBJECT (entry), "inner-border");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_get_inner_border:
|
||||
* @entry: a #GtkEntry
|
||||
*
|
||||
* This function returns the entry's inner-border property. See
|
||||
* gtk_entry_set_inner_border() for more information.
|
||||
*
|
||||
* Return value: the entry's #GtkBorder, or %NULL if none was set.
|
||||
*
|
||||
* Since: 2.10
|
||||
**/
|
||||
G_CONST_RETURN GtkBorder *
|
||||
gtk_entry_get_inner_border (GtkEntry *entry)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
|
||||
|
||||
return g_object_get_qdata (G_OBJECT (entry), quark_inner_border);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_get_layout:
|
||||
@ -4878,7 +5004,7 @@ gtk_entry_drag_data_received (GtkWidget *widget,
|
||||
GtkEditable *editable = GTK_EDITABLE (widget);
|
||||
gchar *str;
|
||||
|
||||
str = gtk_selection_data_get_text (selection_data);
|
||||
str = (gchar *) gtk_selection_data_get_text (selection_data);
|
||||
|
||||
if (str && entry->editable)
|
||||
{
|
||||
|
@ -152,6 +152,9 @@ gunichar gtk_entry_get_invisible_char (GtkEntry *entry);
|
||||
void gtk_entry_set_has_frame (GtkEntry *entry,
|
||||
gboolean setting);
|
||||
gboolean gtk_entry_get_has_frame (GtkEntry *entry);
|
||||
void gtk_entry_set_inner_border (GtkEntry *entry,
|
||||
const GtkBorder *border);
|
||||
G_CONST_RETURN GtkBorder* gtk_entry_get_inner_border (GtkEntry *entry);
|
||||
/* text is truncated if needed */
|
||||
void gtk_entry_set_max_length (GtkEntry *entry,
|
||||
gint max);
|
||||
|
Loading…
Reference in New Issue
Block a user