Compare commits

...

6 Commits

Author SHA1 Message Date
Matthias Clasen
da63af060a wip: entry gadget conversion
This is not working fully yet. The text is always placed at the
very left, ignoring margin and padding, and sometimes overlaps
the icon.
2015-12-15 22:12:45 -05:00
Matthias Clasen
47f90506fd notebook: Some more gadgetization
Remove manual CSS padding handling, and convert
the toplevel size request functions to use the main gadget.
2015-12-15 22:12:45 -05:00
Matthias Clasen
29a826e0af notebook: Initial gadget setup
This commit just creates gadgets instead of nodes.
They are not used for size allocation or drawing yet.
2015-12-15 22:12:45 -05:00
Matthias Clasen
e18c194f6c frame: Convert to gadgets
As part of this conversion, remove the hardcoded padding around
the label.

Unfortunately, we cannot use the main gadget for drawing the frame
decoration, since we want to draw a custom border instead of the
stock css border that gadgets insist on drawing for us. Therefore,
add an extra css node with name decoration and use it just for
rendering the frame.
2015-12-15 22:12:45 -05:00
Matthias Clasen
1003a84e36 searchbar: Convert to gadgets 2015-12-15 22:12:45 -05:00
Matthias Clasen
84dd777340 3.19.5 2015-12-15 22:01:46 -05:00
9 changed files with 1308 additions and 887 deletions

View File

@@ -10,7 +10,7 @@
m4_define([gtk_major_version], [3])
m4_define([gtk_minor_version], [19])
m4_define([gtk_micro_version], [4])
m4_define([gtk_micro_version], [5])
m4_define([gtk_interface_age], [0])
m4_define([gtk_binary_age],
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])

View File

@@ -70,6 +70,7 @@
#include "gtktoolbar.h"
#include "gtkmagnifierprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkcsscustomgadgetprivate.h"
#include "a11y/gtkentryaccessible.h"
@@ -204,6 +205,7 @@ struct _GtkEntryPrivate
GtkGesture *drag_gesture;
GtkGesture *multipress_gesture;
GtkCssGadget *gadget;
GtkCssNode *selection_node;
GtkCssNode *progress_node;
@@ -278,7 +280,6 @@ struct _EntryIconInfo
GtkCssGadget *gadget;
GdkEventSequence *current_sequence;
GdkDevice *device;
GtkCssNode *css_node;
};
struct _GtkEntryPasswordHint
@@ -693,6 +694,27 @@ static void buffer_connect_signals (GtkEntry *entry);
static void buffer_disconnect_signals (GtkEntry *entry);
static GtkEntryBuffer *get_buffer (GtkEntry *entry);
static void gtk_entry_get_content_size (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline,
gpointer data);
static void gtk_entry_allocate_contents (GtkCssGadget *gadget,
const GtkAllocation *allocation,
gint baseline,
GtkAllocation *out_clip,
gpointer data);
static gboolean gtk_entry_render_contents (GtkCssGadget *gadget,
cairo_t *cr,
gint x,
gint y,
gint width,
gint height,
gpointer data);
G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET,
G_ADD_PRIVATE (GtkEntry)
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
@@ -2672,6 +2694,7 @@ static void
gtk_entry_init (GtkEntry *entry)
{
GtkEntryPrivate *priv;
GtkCssNode *widget_node;
entry->priv = gtk_entry_get_instance_private (entry);
priv = entry->priv;
@@ -2726,6 +2749,15 @@ gtk_entry_init (GtkEntry *entry)
G_CALLBACK (gtk_entry_multipress_gesture_pressed), entry);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->multipress_gesture), 0);
gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (priv->multipress_gesture), TRUE);
widget_node = gtk_widget_get_css_node (GTK_WIDGET (entry));
priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
GTK_WIDGET (entry),
gtk_entry_get_content_size,
gtk_entry_allocate_contents,
gtk_entry_render_contents,
NULL,
NULL);
}
static void
@@ -2770,8 +2802,7 @@ static gint
get_icon_width (GtkEntry *entry,
GtkEntryIconPosition icon_pos)
{
GtkEntryPrivate *priv = entry->priv;
EntryIconInfo *icon_info = priv->icons[icon_pos];
EntryIconInfo *icon_info = entry->priv->icons[icon_pos];
gint width;
if (!icon_info)
@@ -2922,19 +2953,16 @@ gtk_entry_finalize (GObject *object)
for (i = 0; i < MAX_ICONS; i++)
{
if ((icon_info = priv->icons[i]) != NULL)
{
if (icon_info->target_list != NULL)
{
gtk_target_list_unref (icon_info->target_list);
icon_info->target_list = NULL;
}
icon_info = priv->icons[i];
if (icon_info == NULL)
continue;
g_clear_object (&icon_info->gadget);
if (icon_info->target_list != NULL)
gtk_target_list_unref (icon_info->target_list);
g_slice_free (EntryIconInfo, icon_info);
priv->icons[i] = NULL;
}
g_clear_object (&icon_info->gadget);
g_slice_free (EntryIconInfo, icon_info);
}
if (priv->cached_layout)
@@ -2965,6 +2993,8 @@ gtk_entry_finalize (GObject *object)
if (priv->attrs)
pango_attr_list_unref (priv->attrs);
g_clear_object (&priv->gadget);
G_OBJECT_CLASS (gtk_entry_parent_class)->finalize (object);
}
@@ -3226,7 +3256,9 @@ update_node_ordering (GtkEntry *entry)
icon_info = priv->icons[icon_pos];
if (icon_info)
{
GtkCssNode *node = gtk_css_gadget_get_node (icon_info->gadget);
GtkCssNode *node;
node = gtk_css_gadget_get_node (icon_info->gadget);
parent = gtk_css_node_get_parent (node);
sibling = gtk_css_node_get_first_child (parent);
if (node != sibling)
@@ -3249,7 +3281,6 @@ construct_icon_info (GtkWidget *widget,
priv->icons[icon_pos] = icon_info;
widget_node = get_entry_node (widget);
icon_info->gadget = gtk_icon_helper_new_named ("image", widget);
_gtk_icon_helper_set_force_scale_pixbuf (GTK_ICON_HELPER (icon_info->gadget), TRUE);
gtk_css_node_set_parent (gtk_css_gadget_get_node (icon_info->gadget), widget_node);
@@ -3434,74 +3465,28 @@ gtk_entry_unrealize (GtkWidget *widget)
}
}
void
_gtk_entry_get_borders (GtkEntry *entry,
GtkBorder *border_out)
{
GtkWidget *widget = GTK_WIDGET (entry);
GtkBorder padding, border;
GtkStyleContext *context;
GtkStateFlags state;
context = gtk_widget_get_style_context (widget);
state = gtk_style_context_get_state (context);
gtk_style_context_get_padding (context, state, &padding);
gtk_style_context_get_border (context, state, &border);
border_out->top = padding.top + border.top;
border_out->bottom = padding.bottom + border.bottom;
border_out->left = padding.left + border.left;
border_out->right = padding.right + border.right;
}
static void
gtk_entry_get_preferred_width (GtkWidget *widget,
gint *minimum,
gint *natural)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = entry->priv;
PangoFontMetrics *metrics;
GtkBorder borders;
PangoContext *context;
gint icon_width, i;
gint min, nat;
gint char_width;
gint digit_width;
gint char_pixels;
gtk_css_gadget_get_preferred_size (GTK_ENTRY (widget)->priv->gadget,
GTK_ORIENTATION_HORIZONTAL,
-1,
minimum, natural,
NULL, NULL);
}
_gtk_entry_get_borders (entry, &borders);
context = gtk_widget_get_pango_context (widget);
metrics = pango_context_get_metrics (context,
pango_context_get_font_description (context),
pango_context_get_language (context));
char_width = pango_font_metrics_get_approximate_char_width (metrics);
digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
char_pixels = (MAX (char_width, digit_width) + PANGO_SCALE - 1) / PANGO_SCALE;
pango_font_metrics_unref (metrics);
if (priv->width_chars < 0)
min = MIN_ENTRY_WIDTH + borders.left + borders.right;
else
min = char_pixels * priv->width_chars + borders.left + borders.right;
if (priv->max_width_chars < 0)
nat = MIN_ENTRY_WIDTH + borders.left + borders.right;
else
nat = char_pixels * priv->max_width_chars + borders.left + borders.right;
icon_width = 0;
for (i = 0; i < MAX_ICONS; i++)
icon_width += get_icon_width (entry, i);
min = MAX (min, icon_width);
nat = MAX (min, nat);
*minimum = min;
*natural = nat;
static void
gtk_entry_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
{
gtk_css_gadget_get_preferred_size (GTK_ENTRY (widget)->priv->gadget,
GTK_ORIENTATION_VERTICAL,
-1,
minimum, natural,
NULL, NULL);
}
static void
@@ -3512,74 +3497,117 @@ gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = entry->priv;
PangoFontMetrics *metrics;
GtkBorder borders;
PangoContext *context;
gint height, baseline;
PangoLayout *layout;
int icon_min, icon_nat;
layout = gtk_entry_ensure_layout (entry, TRUE);
context = gtk_widget_get_pango_context (widget);
metrics = pango_context_get_metrics (context,
pango_context_get_font_description (context),
pango_context_get_language (context));
priv->ascent = pango_font_metrics_get_ascent (metrics);
priv->descent = pango_font_metrics_get_descent (metrics);
pango_font_metrics_unref (metrics);
_gtk_entry_get_borders (entry, &borders);
pango_layout_get_pixel_size (layout, NULL, &height);
height = MAX (height, PANGO_PIXELS (priv->ascent + priv->descent));
height += borders.top + borders.bottom;
baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
baseline += borders.top;
*minimum = height;
*natural = height;
if (minimum_baseline)
*minimum_baseline = baseline;
if (natural_baseline)
*natural_baseline = baseline;
if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
{
gtk_css_gadget_get_preferred_size (priv->icons[GTK_ENTRY_ICON_PRIMARY]->gadget,
GTK_ORIENTATION_VERTICAL,
-1,
&icon_min, &icon_nat,
NULL, NULL);
*minimum = MAX (*minimum, icon_min);
*natural = MAX (*natural, icon_nat);
}
if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
{
gtk_css_gadget_get_preferred_size (priv->icons[GTK_ENTRY_ICON_SECONDARY]->gadget,
GTK_ORIENTATION_VERTICAL,
-1,
&icon_min, &icon_nat,
NULL, NULL);
*minimum = MAX (*minimum, icon_min);
*natural = MAX (*natural, icon_nat);
}
gtk_css_gadget_get_preferred_size (GTK_ENTRY (widget)->priv->gadget,
GTK_ORIENTATION_VERTICAL,
width,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
gtk_entry_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
gtk_entry_get_content_size (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline,
gpointer unused)
{
gtk_entry_get_preferred_height_and_baseline_for_width (widget,
-1,
minimum,
natural,
NULL, NULL);
GtkWidget *widget;
GtkEntry *entry;
GtkEntryPrivate *priv;
PangoContext *context;
PangoFontMetrics *metrics;
widget = gtk_css_gadget_get_owner (gadget);
entry = GTK_ENTRY (widget);
priv = entry->priv;
context = gtk_widget_get_pango_context (widget);
metrics = pango_context_get_metrics (context,
pango_context_get_font_description (context),
pango_context_get_language (context));
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
gint icon_width, i;
gint min, nat;
gint char_width;
gint digit_width;
gint char_pixels;
char_width = pango_font_metrics_get_approximate_char_width (metrics);
digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
char_pixels = (MAX (char_width, digit_width) + PANGO_SCALE - 1) / PANGO_SCALE;
if (priv->width_chars < 0)
min = MIN_ENTRY_WIDTH;
else
min = char_pixels * priv->width_chars;
if (priv->max_width_chars < 0)
nat = MIN_ENTRY_WIDTH;
else
nat = char_pixels * priv->max_width_chars;
icon_width = 0;
for (i = 0; i < MAX_ICONS; i++)
icon_width += get_icon_width (entry, i);
min = MAX (min, icon_width);
nat = MAX (min, nat);
*minimum = min;
*natural = nat;
}
else
{
gint height, baseline;
gint icon_height, i;
PangoLayout *layout;
layout = gtk_entry_ensure_layout (entry, TRUE);
priv->ascent = pango_font_metrics_get_ascent (metrics);
priv->descent = pango_font_metrics_get_descent (metrics);
pango_layout_get_pixel_size (layout, NULL, &height);
height = MAX (height, PANGO_PIXELS (priv->ascent + priv->descent));
baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
icon_height = 0;
for (i = 0; i < MAX_ICONS; i++)
{
EntryIconInfo *icon_info = priv->icons[i];
gint h;
if (!icon_info)
continue;
gtk_css_gadget_get_preferred_size (icon_info->gadget,
GTK_ORIENTATION_VERTICAL,
-1,
NULL, &h,
NULL, NULL);
icon_height = MAX (icon_height, h);
}
*minimum = MAX (height, icon_height);
*natural = MAX (height, icon_height);
if (icon_height > height)
baseline += (icon_height - height) / 2;
if (minimum_baseline)
*minimum_baseline = baseline;
if (natural_baseline)
*natural_baseline = baseline;
}
pango_font_metrics_unref (metrics);
}
static void
@@ -3645,12 +3673,10 @@ gtk_entry_get_text_area_size (GtkEntry *entry,
GtkAllocation allocation;
gint req_height, unused;
gint frame_height;
GtkBorder borders;
gtk_entry_get_preferred_height_and_baseline_for_width (widget, -1, &req_height, &unused, NULL, NULL);
gtk_widget_get_allocation (widget, &allocation);
_gtk_entry_get_borders (entry, &borders);
if (gtk_widget_get_realized (widget))
get_frame_size (entry, TRUE, NULL, NULL, NULL, &frame_height);
@@ -3658,16 +3684,16 @@ gtk_entry_get_text_area_size (GtkEntry *entry,
frame_height = req_height;
if (x)
*x = borders.left;
*x = 0;
if (y)
*y = floor ((frame_height - req_height) / 2) + borders.top;
*y = floor ((frame_height - req_height) / 2);
if (width)
*width = allocation.width - borders.left - borders.right;
*width = allocation.width;
if (height)
*height = req_height - borders.top - borders.bottom;
*height = req_height;
}
static void
@@ -3697,9 +3723,9 @@ gtk_entry_get_frame_size (GtkEntry *entry,
{
GtkAllocation allocation;
GtkWidget *widget = GTK_WIDGET (entry);
gint req_height, req_baseline, unused;
gint req_height, req_baseline, unused, unused2;
gtk_entry_get_preferred_height_and_baseline_for_width (widget, -1, &req_height, &unused, &req_baseline, &unused);
gtk_entry_get_preferred_height_and_baseline_for_width (widget, -1, &req_height, &unused, &req_baseline, &unused2);
gtk_widget_get_allocation (widget, &allocation);
@@ -3751,12 +3777,13 @@ gtk_entry_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkEntry *entry = GTK_ENTRY (widget);
GdkRectangle clip;
gtk_widget_set_allocation (widget, allocation);
if (gtk_widget_get_realized (widget))
{
GtkEntryCompletion* completion;
GtkEntryCompletion *completion;
place_windows (entry);
gtk_entry_recompute (entry);
@@ -3766,7 +3793,70 @@ gtk_entry_size_allocate (GtkWidget *widget,
_gtk_entry_completion_resize_popup (completion);
}
_gtk_widget_set_simple_clip (widget, NULL);
gtk_css_gadget_allocate (entry->priv->gadget,
allocation,
gtk_widget_get_allocated_baseline (widget),
&clip);
gtk_widget_set_clip (widget, &clip);
}
static void
gtk_entry_allocate_contents (GtkCssGadget *gadget,
const GtkAllocation *allocation,
gint baseline,
GtkAllocation *out_clip,
gpointer data)
{
GtkWidget *widget;
GtkEntryPrivate *priv;
gint i;
widget = gtk_css_gadget_get_owner (gadget);
priv = GTK_ENTRY (widget)->priv;
out_clip->x = 0;
out_clip->y = 0;
out_clip->width = 0;
out_clip->height = 0;
for (i = 0; i < MAX_ICONS; i++)
{
EntryIconInfo *icon_info = priv->icons[i];
GtkAllocation icon_alloc;
GdkRectangle clip;
gint dummy, width, height;
if (!icon_info)
continue;
gtk_css_gadget_get_preferred_size (icon_info->gadget,
GTK_ORIENTATION_HORIZONTAL,
-1,
&dummy, &width,
NULL, NULL);
gtk_css_gadget_get_preferred_size (icon_info->gadget,
GTK_ORIENTATION_VERTICAL,
-1,
&dummy, &height,
NULL, NULL);
if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL && i == GTK_ENTRY_ICON_PRIMARY) ||
(gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR && i == GTK_ENTRY_ICON_SECONDARY))
icon_alloc.x = allocation->x + allocation->width - width;
else
icon_alloc.x = allocation->x;
icon_alloc.y = allocation->y + (allocation->height - height) / 2;
icon_alloc.width = width;
icon_alloc.height = height;
gtk_css_gadget_allocate (icon_info->gadget,
&icon_alloc,
baseline,
&clip);
gdk_rectangle_union (out_clip, &clip, out_clip);
}
}
static gboolean
@@ -3809,13 +3899,7 @@ gtk_entry_draw_frame (GtkWidget *widget,
if (GTK_IS_SPIN_BUTTON (widget) &&
gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_VERTICAL)
{
GtkBorder borders;
gtk_entry_get_text_area_size (GTK_ENTRY (widget), NULL, &y, NULL, &height);
_gtk_entry_get_borders (GTK_ENTRY (widget), &borders);
y -= borders.top;
height += borders.top + borders.bottom;
}
gtk_render_background (context, cr, x, y, width, height);
@@ -3835,12 +3919,8 @@ get_progress_area (GtkWidget *widget,
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *private = entry->priv;
GtkStyleContext *context;
GtkBorder border, entry_borders;
gint frame_width, text_area_width, text_area_height;
context = gtk_widget_get_style_context (widget);
_gtk_entry_get_borders (entry, &entry_borders);
get_text_area_size (entry,
x, y,
&text_area_width, &text_area_height);
@@ -3848,10 +3928,8 @@ get_progress_area (GtkWidget *widget,
NULL, NULL,
&frame_width, NULL);
*x -= entry_borders.left;
*y -= entry_borders.top;
*width = text_area_width + entry_borders.left + entry_borders.right;
*height = text_area_height + entry_borders.top + entry_borders.bottom;
*width = text_area_width;
*height = text_area_height;
/* if the text area got resized by a subclass, subtract the left/right
* border width, so that the progress bar won't extend over the resized
@@ -3859,34 +3937,8 @@ get_progress_area (GtkWidget *widget,
*/
if (frame_width > *width)
{
gtk_style_context_get_border (context,
gtk_style_context_get_state (context),
&border);
if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
{
*x = (frame_width - *width) + border.left;
*width -= border.left;
}
else
{
*width -= border.right;
}
}
if (private->progress_node)
{
GtkBorder margin;
gtk_style_context_save_to_node (context, private->progress_node);
gtk_style_context_get_margin (context,
gtk_style_context_get_state (context),
&margin);
gtk_style_context_restore (context);
*x += margin.left;
*y += margin.top;
*width -= margin.left + margin.right;
*height -= margin.top + margin.bottom;
*x = (frame_width - *width);
}
if (private->progress_pulse_mode)
@@ -3939,15 +3991,34 @@ gtk_entry_draw_progress (GtkWidget *widget,
gtk_style_context_restore (context);
}
static gint
static gboolean
gtk_entry_draw (GtkWidget *widget,
cairo_t *cr)
{
GtkEntry *entry = GTK_ENTRY (widget);
gtk_css_gadget_draw (GTK_ENTRY (widget)->priv->gadget, cr);
return FALSE;
}
static gboolean
gtk_entry_render_contents (GtkCssGadget *gadget,
cairo_t *cr,
gint x,
gint y,
gint width,
gint height,
gpointer data)
{
GtkWidget *widget;
GtkEntry *entry;
GtkStyleContext *context;
GtkEntryPrivate *priv = entry->priv;
GtkEntryPrivate *priv;
int i;
widget = gtk_css_gadget_get_owner (gadget);
entry = GTK_ENTRY (widget);
priv = entry->priv;
if (gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
{
context = gtk_widget_get_style_context (widget);
@@ -3955,6 +4026,15 @@ gtk_entry_draw (GtkWidget *widget,
/* Draw entry_bg, shadow, progress and focus */
gtk_entry_draw_frame (widget, context, cr);
/* Draw icons */
for (i = 0; i < MAX_ICONS; i++)
{
EntryIconInfo *icon_info = priv->icons[i];
if (icon_info != NULL)
gtk_css_gadget_draw (icon_info->gadget, cr);
}
/* Draw text and cursor */
cairo_save (cr);
@@ -6528,7 +6608,7 @@ gtk_entry_draw_text (GtkEntry *entry,
progress_width, progress_height);
cairo_clip (cr);
cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
draw_text_with_color (entry, cr, &text_color);
cairo_restore (cr);
@@ -7039,7 +7119,6 @@ gtk_entry_move_adjustments (GtkEntry *entry)
GtkAdjustment *adjustment;
PangoContext *context;
PangoFontMetrics *metrics;
GtkBorder borders;
gint x, layout_x;
gint char_width;
@@ -7052,8 +7131,7 @@ gtk_entry_move_adjustments (GtkEntry *entry)
/* Cursor/char position, layout offset, border width, and widget allocation */
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &x, NULL);
get_layout_position (entry, &layout_x, NULL);
_gtk_entry_get_borders (entry, &borders);
x += allocation.x + layout_x + borders.left;
x += allocation.x + layout_x;
/* Approximate width of a char, so user can see what is ahead/behind */
context = gtk_widget_get_pango_context (widget);
@@ -9567,7 +9645,6 @@ popup_position_func (GtkMenu *menu,
GdkScreen *screen;
GtkRequisition menu_req;
GdkRectangle monitor;
GtkBorder borders;
gint monitor_num, strong_x, height;
g_return_if_fail (gtk_widget_get_realized (widget));
@@ -9585,9 +9662,8 @@ popup_position_func (GtkMenu *menu,
&menu_req, NULL);
height = gdk_window_get_height (priv->text_area);
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL);
_gtk_entry_get_borders (entry, &borders);
*x += borders.left + strong_x - priv->scroll_offset;
*x += 0 + strong_x - priv->scroll_offset;
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
*x -= menu_req.width;

View File

@@ -31,6 +31,13 @@
#include "gtkintl.h"
#include "gtkbuildable.h"
#include "gtkwidgetpath.h"
#include "gtkcssnodeprivate.h"
#include "gtkcsscustomgadgetprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkcontainerprivate.h"
#include "gtkstylecontextprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtklabel.h"
#include "a11y/gtkframeaccessible.h"
@@ -79,6 +86,9 @@ struct _GtkFramePrivate
/* Properties */
GtkWidget *label_widget;
GtkCssGadget *gadget;
GtkCssGadget *border_gadget;
gint16 shadow_type;
gfloat label_xalign;
gfloat label_yalign;
@@ -100,6 +110,7 @@ enum {
static GParamSpec *frame_props[LAST_PROP];
static void gtk_frame_finalize (GObject *object);
static void gtk_frame_set_property (GObject *object,
guint param_id,
const GValue *value,
@@ -145,6 +156,34 @@ static void gtk_frame_get_preferred_width_for_height(GtkWidget *layout
gint width,
gint *minimum_height,
gint *natural_height);
static void gtk_frame_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state);
static void gtk_frame_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum_size,
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline,
gpointer data);
static void gtk_frame_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer data);
static void gtk_frame_allocate_border (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer data);
static gboolean gtk_frame_render (GtkCssGadget *gadget,
cairo_t *cr,
int x,
int y,
int width,
int height,
gpointer data);
G_DEFINE_TYPE_WITH_CODE (GtkFrame, gtk_frame, GTK_TYPE_BIN,
@@ -163,6 +202,7 @@ gtk_frame_class_init (GtkFrameClass *class)
widget_class = GTK_WIDGET_CLASS (class);
container_class = GTK_CONTAINER_CLASS (class);
gobject_class->finalize = gtk_frame_finalize;
gobject_class->set_property = gtk_frame_set_property;
gobject_class->get_property = gtk_frame_get_property;
@@ -212,6 +252,7 @@ gtk_frame_class_init (GtkFrameClass *class)
widget_class->get_preferred_height = gtk_frame_get_preferred_height;
widget_class->get_preferred_height_for_width = gtk_frame_get_preferred_height_for_width;
widget_class->get_preferred_width_for_height = gtk_frame_get_preferred_width_for_height;
widget_class->state_flags_changed = gtk_frame_state_flags_changed;
container_class->remove = gtk_frame_remove;
container_class->forall = gtk_frame_forall;
@@ -246,6 +287,7 @@ static void
gtk_frame_init (GtkFrame *frame)
{
GtkFramePrivate *priv;
GtkCssNode *widget_node;
frame->priv = gtk_frame_get_instance_private (frame);
priv = frame->priv;
@@ -254,6 +296,36 @@ gtk_frame_init (GtkFrame *frame)
priv->shadow_type = GTK_SHADOW_ETCHED_IN;
priv->label_xalign = 0.0;
priv->label_yalign = 0.5;
widget_node = gtk_widget_get_css_node (GTK_WIDGET (frame));
priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
GTK_WIDGET (frame),
gtk_frame_measure,
gtk_frame_allocate,
gtk_frame_render,
NULL,
NULL);
priv->border_gadget = gtk_css_custom_gadget_new ("border",
GTK_WIDGET (frame),
priv->gadget,
NULL,
NULL,
gtk_frame_allocate_border,
NULL,
NULL,
NULL);
}
static void
gtk_frame_finalize (GObject *object)
{
GtkFrame *frame = GTK_FRAME (object);
GtkFramePrivate *priv = frame->priv;
g_clear_object (&priv->border_gadget);
g_clear_object (&priv->gadget);
G_OBJECT_CLASS (gtk_frame_parent_class)->finalize (object);
}
static void
@@ -273,7 +345,7 @@ gtk_frame_set_property (GObject *object,
case PROP_LABEL_XALIGN:
gtk_frame_set_label_align (frame, g_value_get_float (value),
priv->label_yalign);
break;
break;
case PROP_LABEL_YALIGN:
gtk_frame_set_label_align (frame, priv->label_xalign,
g_value_get_float (value));
@@ -579,8 +651,6 @@ gtk_frame_set_shadow_type (GtkFrame *frame,
GtkShadowType type)
{
GtkFramePrivate *priv;
GtkWidget *widget;
GtkStyleContext *context;
g_return_if_fail (GTK_IS_FRAME (frame));
@@ -588,19 +658,13 @@ gtk_frame_set_shadow_type (GtkFrame *frame,
if ((GtkShadowType) priv->shadow_type != type)
{
widget = GTK_WIDGET (frame);
priv->shadow_type = type;
context = gtk_widget_get_style_context (GTK_WIDGET (frame));
if (type == GTK_SHADOW_NONE)
gtk_style_context_add_class (context, GTK_STYLE_CLASS_FLAT);
gtk_css_gadget_add_class (priv->border_gadget, GTK_STYLE_CLASS_FLAT);
else
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_FLAT);
gtk_css_gadget_remove_class (priv->border_gadget, GTK_STYLE_CLASS_FLAT);
if (gtk_widget_is_drawable (widget))
gtk_widget_queue_draw (widget);
gtk_widget_queue_resize (widget);
g_object_notify_by_pspec (G_OBJECT (frame), frame_props[PROP_SHADOW_TYPE]);
}
}
@@ -622,88 +686,66 @@ gtk_frame_get_shadow_type (GtkFrame *frame)
return frame->priv->shadow_type;
}
static void
get_padding_and_border (GtkFrame *frame,
GtkBorder *border)
{
GtkStyleContext *context;
GtkStateFlags state;
context = gtk_widget_get_style_context (GTK_WIDGET (frame));
state = gtk_style_context_get_state (context);
gtk_style_context_get_padding (context, state, border);
if (frame->priv->shadow_type != GTK_SHADOW_NONE)
{
GtkBorder tmp;
gtk_style_context_get_border (context, state, &tmp);
border->top += tmp.top;
border->right += tmp.right;
border->bottom += tmp.bottom;
border->left += tmp.left;
}
}
static gboolean
gtk_frame_draw (GtkWidget *widget,
cairo_t *cr)
{
GtkFrame *frame;
GtkFramePrivate *priv;
GtkStyleContext *context;
gint x, y, width, height;
GtkAllocation allocation;
GtkBorder padding;
gtk_css_gadget_draw (GTK_FRAME (widget)->priv->gadget, cr);
frame = GTK_FRAME (widget);
priv = frame->priv;
return FALSE;
}
static gboolean
gtk_frame_render (GtkCssGadget *gadget,
cairo_t *cr,
int x,
int y,
int width,
int height,
gpointer data)
{
GtkWidget *widget;
GtkFramePrivate *priv;
gint xc, yc, w, h;
GtkAllocation allocation;
widget = gtk_css_gadget_get_owner (gadget);
priv = GTK_FRAME (widget)->priv;
cairo_save (cr);
gtk_widget_get_allocation (widget, &allocation);
get_padding_and_border (frame, &padding);
context = gtk_widget_get_style_context (widget);
x = priv->child_allocation.x - allocation.x - padding.left;
y = priv->child_allocation.y - allocation.y - padding.top;
width = priv->child_allocation.width + padding.left + padding.right;
height = priv->child_allocation.height + padding.top + padding.bottom;
/* We want to use the standard gadget drawing for the border,
* so we clip out the label allocation in order to get the
* frame gap.
*/
xc = priv->label_allocation.x - allocation.x;
yc = y;
w = priv->label_allocation.width;
h = priv->label_allocation.height;
if (priv->label_widget)
if (GTK_IS_LABEL (priv->label_widget))
{
gfloat xalign;
gint height_extra;
gint x2;
PangoRectangle ink_rect;
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
xalign = priv->label_xalign;
else
xalign = 1 - priv->label_xalign;
height_extra = MAX (0, priv->label_allocation.height - padding.top)
- priv->label_yalign * priv->label_allocation.height;
y -= height_extra;
height += height_extra;
x2 = padding.left + (priv->child_allocation.width - priv->label_allocation.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_SIDE_PAD;
gtk_render_background (context, cr, x, y, width, height);
/* If the label is completely over or under the frame we can omit the gap */
if (priv->label_yalign == 0.0 || priv->label_yalign == 1.0)
gtk_render_frame (context, cr, x, y, width, height);
else
gtk_render_frame_gap (context, cr,
x, y, width, height,
GTK_POS_TOP, x2,
x2 + priv->label_allocation.width + 2 * LABEL_PAD);
}
else
{
gtk_render_background (context, cr, x, y, width, height);
gtk_render_frame (context, cr, x, y, width, height);
/* Shrink the clip area for labels, so we get unclipped
* frames for the yalign 0.0 and 1.0 cases.
*/
pango_layout_get_pixel_extents (gtk_label_get_layout (GTK_LABEL (priv->label_widget)), &ink_rect, NULL);
yc += (h - ink_rect.height) / 2;
h = ink_rect.height;
}
cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
cairo_rectangle (cr, xc + w, yc, - w, h);
cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
cairo_clip (cr);
gtk_css_gadget_draw (priv->border_gadget, cr);
cairo_restore (cr);
GTK_WIDGET_CLASS (gtk_frame_parent_class)->draw (widget, cr);
return FALSE;
@@ -713,61 +755,95 @@ static void
gtk_frame_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkFrame *frame = GTK_FRAME (widget);
GtkFramePrivate *priv = frame->priv;
GtkBin *bin = GTK_BIN (widget);
GtkAllocation new_allocation;
GtkWidget *child;
GtkAllocation clip;
gtk_widget_set_allocation (widget, allocation);
gtk_css_gadget_allocate (GTK_FRAME (widget)->priv->gadget,
allocation,
gtk_widget_get_allocated_baseline (widget),
&clip);
gtk_widget_set_clip (widget, &clip);
}
static void
gtk_frame_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer data)
{
GtkWidget *widget;
GtkFrame *frame;
GtkFramePrivate *priv;
GtkAllocation new_allocation;
GtkAllocation frame_allocation;
gint height_extra;
GtkAllocation clip;
widget = gtk_css_gadget_get_owner (gadget);
frame = GTK_FRAME (widget);
priv = frame->priv;
gtk_frame_compute_child_allocation (frame, &new_allocation);
/* If the child allocation changed, that means that the frame is drawn
* in a new place, so we must redraw the entire widget.
*/
if (gtk_widget_get_mapped (widget) && !gdk_rectangle_equal (&priv->child_allocation, &new_allocation))
{
gdk_window_invalidate_rect (gtk_widget_get_window (widget), allocation, FALSE);
}
child = gtk_bin_get_child (bin);
if (child && gtk_widget_get_visible (child))
gtk_widget_size_allocate (child, &new_allocation);
priv->child_allocation = new_allocation;
if (priv->label_widget && gtk_widget_get_visible (priv->label_widget))
{
GtkBorder padding;
gint nat_width, width, height;
gfloat xalign;
get_padding_and_border (frame, &padding);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
xalign = priv->label_xalign;
else
xalign = 1 - priv->label_xalign;
gtk_widget_get_preferred_width (priv->label_widget, NULL, &nat_width);
width = new_allocation.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD;
width = MIN (width, nat_width);
gtk_widget_get_preferred_height_for_width (priv->label_widget, width,
&height, NULL);
priv->label_allocation.x = priv->child_allocation.x + LABEL_SIDE_PAD +
(new_allocation.width - width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_PAD;
width = MIN (new_allocation.width, nat_width);
gtk_widget_get_preferred_height_for_width (priv->label_widget, width, &height, NULL);
priv->label_allocation.x = new_allocation.x + (new_allocation.width - width) * xalign;
priv->label_allocation.y = new_allocation.y - height;
priv->label_allocation.height = height;
priv->label_allocation.width = width;
priv->label_allocation.y = priv->child_allocation.y - MAX (height, padding.top);
priv->label_allocation.height = height;
gtk_widget_size_allocate (priv->label_widget, &priv->label_allocation);
height_extra = (1 - priv->label_yalign) * height;
}
else
height_extra = 0;
frame_allocation.x = priv->child_allocation.x;
frame_allocation.y = priv->child_allocation.y - height_extra;
frame_allocation.width = priv->child_allocation.width;
frame_allocation.height = priv->child_allocation.height + height_extra;
gtk_css_gadget_allocate (priv->border_gadget,
&frame_allocation,
-1,
&clip);
gtk_container_get_children_clip (GTK_CONTAINER (widget), out_clip);
gdk_rectangle_union (out_clip, &clip, out_clip);
}
static void
gtk_frame_allocate_border (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer data)
{
GtkWidget *widget;
GtkWidget *child;
widget = gtk_css_gadget_get_owner (gadget);
child = gtk_bin_get_child (GTK_BIN (widget));
if (child && gtk_widget_get_visible (child))
gtk_widget_size_allocate (child, (GtkAllocation *)allocation);
}
static void
@@ -787,188 +863,163 @@ gtk_frame_real_compute_child_allocation (GtkFrame *frame,
GtkFramePrivate *priv = frame->priv;
GtkWidget *widget = GTK_WIDGET (frame);
GtkAllocation allocation;
GtkBorder padding;
gint top_margin;
gint border_width;
gint border_width, height;
gtk_widget_get_allocation (widget, &allocation);
get_padding_and_border (frame, &padding);
border_width = gtk_container_get_border_width (GTK_CONTAINER (frame));
if (priv->label_widget)
{
gint nat_width, width, height;
gint nat_width, width;
gtk_widget_get_preferred_width (priv->label_widget, NULL, &nat_width);
width = allocation.width;
width -= 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD;
width -= (border_width * 2) + padding.left + padding.right;
width = MIN (width, nat_width);
gtk_widget_get_preferred_height_for_width (priv->label_widget, width,
&height, NULL);
top_margin = MAX (height, padding.top);
width = MIN (allocation.width - 2 * border_width, nat_width);
gtk_widget_get_preferred_height_for_width (priv->label_widget, width, &height, NULL);
}
else
top_margin = padding.top;
height = 0;
child_allocation->x = allocation.x + border_width;
child_allocation->y = allocation.y + border_width + height;
child_allocation->width = MAX (1, allocation.width - 2 * border_width);
child_allocation->height = MAX (1, allocation.height - 2 * border_width - height);
child_allocation->x = border_width + padding.left;
child_allocation->y = border_width + top_margin;
child_allocation->width = MAX (1, (gint) (allocation.width - (border_width * 2) -
padding.left - padding.right));
child_allocation->height = MAX (1, (gint) (allocation.height - child_allocation->y -
border_width - padding.bottom));
child_allocation->x += allocation.x;
child_allocation->y += allocation.y;
}
static void
gtk_frame_get_preferred_size (GtkWidget *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
gtk_frame_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline,
gpointer data)
{
GtkFrame *frame = GTK_FRAME (widget);
GtkFramePrivate *priv = frame->priv;
GtkBorder padding;
GtkWidget *widget;
GtkFrame *frame;
GtkFramePrivate *priv;
GtkWidget *child;
GtkBin *bin = GTK_BIN (widget);
gint child_min, child_nat;
gint minimum, natural;
guint border_width;
get_padding_and_border (frame, &padding);
widget = gtk_css_gadget_get_owner (gadget);
frame = GTK_FRAME (widget);
priv = frame->priv;
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
if (priv->label_widget && gtk_widget_get_visible (priv->label_widget))
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
gtk_widget_get_preferred_width (priv->label_widget,
&child_min, &child_nat);
minimum = child_min + 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD;
natural = child_nat + 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD;
gtk_widget_get_preferred_width (priv->label_widget, &child_min, &child_nat);
*minimum = child_min;
*natural = child_nat;
}
else
{
gtk_widget_get_preferred_height (priv->label_widget,
&child_min, &child_nat);
minimum = MAX (0, child_min - padding.top);
natural = MAX (0, child_nat - padding.top);
if (for_size > 0)
gtk_widget_get_preferred_height_for_width (priv->label_widget,
for_size - 2 * border_width, &child_min, &child_nat);
else
gtk_widget_get_preferred_height (priv->label_widget, &child_min, &child_nat);
*minimum = child_min;
*natural = child_nat;
}
}
else
{
minimum = 0;
natural = 0;
*minimum = 0;
*natural = 0;
}
child = gtk_bin_get_child (bin);
child = gtk_bin_get_child (GTK_BIN (widget));
if (child && gtk_widget_get_visible (child))
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
gtk_widget_get_preferred_width (child,
&child_min, &child_nat);
minimum = MAX (minimum, child_min);
natural = MAX (natural, child_nat);
gtk_widget_get_preferred_width (child, &child_min, &child_nat);
*minimum = MAX (*minimum, child_min);
*natural = MAX (*natural, child_nat);
}
else
{
gtk_widget_get_preferred_height (child,
&child_min, &child_nat);
minimum += child_min;
natural += child_nat;
if (for_size > 0)
gtk_widget_get_preferred_height_for_width (child, for_size - 2 * border_width, &child_min, &child_nat);
else
gtk_widget_get_preferred_height (child, &child_min, &child_nat);
*minimum += child_min;
*natural += child_nat;
}
}
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
minimum += (border_width * 2) + padding.left + padding.right;
natural += (border_width * 2) + padding.left + padding.right;
}
else
{
minimum += (border_width * 2) + padding.top + padding.bottom;
natural += (border_width * 2) + padding.top + padding.bottom;
}
*minimum_size = minimum;
*natural_size = natural;
*minimum += 2 * border_width;
*natural += 2 * border_width;
}
static void
gtk_frame_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
gint *minimum,
gint *natural)
{
gtk_frame_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
GTK_ORIENTATION_HORIZONTAL,
-1,
minimum, natural,
NULL, NULL);
}
static void
gtk_frame_get_preferred_width_for_height (GtkWidget *widget,
gint height,
gint *minimum,
gint *natural)
{
gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
GTK_ORIENTATION_HORIZONTAL,
height,
minimum, natural,
NULL, NULL);
}
static void
gtk_frame_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
gint *minimum,
gint *natural)
{
gtk_frame_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
GTK_ORIENTATION_VERTICAL,
-1,
minimum, natural,
NULL, NULL);
}
static void
gtk_frame_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height)
gint *minimum,
gint *natural)
{
GtkWidget *child;
GtkFrame *frame = GTK_FRAME (widget);
GtkFramePrivate *priv = frame->priv;
GtkBin *bin = GTK_BIN (widget);
GtkBorder padding;
gint child_min, child_nat, label_width;
gint minimum, natural;
guint border_width;
get_padding_and_border (frame, &padding);
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
minimum = (border_width * 2) + padding.top + padding.bottom;
natural = (border_width * 2) + padding.top + padding.bottom;
width -= (border_width * 2) + padding.left + padding.right;
label_width = width - 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD;
if (priv->label_widget && gtk_widget_get_visible (priv->label_widget))
{
gtk_widget_get_preferred_height_for_width (priv->label_widget,
label_width, &child_min, &child_nat);
minimum += child_min;
natural += child_nat;
}
child = gtk_bin_get_child (bin);
if (child && gtk_widget_get_visible (child))
{
gtk_widget_get_preferred_height_for_width (child,
width, &child_min, &child_nat);
minimum += child_min;
natural += child_nat;
}
*minimum_height = minimum;
*natural_height = natural;
gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
GTK_ORIENTATION_VERTICAL,
width,
minimum, natural,
NULL, NULL);
}
static void
gtk_frame_get_preferred_width_for_height (GtkWidget *widget,
gint height,
gint *minimum_width,
gint *natural_width)
gtk_frame_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state)
{
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width);
}
GtkCssNode *border_node;
border_node = gtk_css_gadget_get_node (GTK_FRAME (widget)->priv->border_gadget);
gtk_css_node_set_state (border_node, gtk_widget_get_state_flags (widget));
GTK_WIDGET_CLASS (gtk_frame_parent_class)->state_flags_changed (widget, previous_state);
}

File diff suppressed because it is too large Load Diff

View File

@@ -34,6 +34,9 @@
#include "gtkrender.h"
#include "gtksearchbar.h"
#include "gtksearchentryprivate.h"
#include "gtkcsscustomgadgetprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkcontainerprivate.h"
/**
* SECTION:gtksearchbar
@@ -74,6 +77,8 @@ typedef struct {
GtkWidget *box_center;
GtkWidget *close_button;
GtkCssGadget *gadget;
GtkWidget *entry;
gboolean reveal_child;
} GtkSearchBarPrivate;
@@ -355,9 +360,12 @@ static void
gtk_search_bar_dispose (GObject *object)
{
GtkSearchBar *bar = GTK_SEARCH_BAR (object);
GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (bar);
gtk_search_bar_set_entry (bar, NULL);
g_clear_object (&priv->gadget);
G_OBJECT_CLASS (gtk_search_bar_parent_class)->dispose (object);
}
@@ -365,21 +373,106 @@ static gboolean
gtk_search_bar_draw (GtkWidget *widget,
cairo_t *cr)
{
gint width, height;
GtkStyleContext *context;
GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (GTK_SEARCH_BAR (widget));
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
context = gtk_widget_get_style_context (widget);
gtk_render_background (context, cr, 0, 0, width, height);
gtk_render_frame (context, cr, 0, 0, width, height);
GTK_WIDGET_CLASS (gtk_search_bar_parent_class)->draw (widget, cr);
gtk_css_gadget_draw (priv->gadget, cr);
return FALSE;
}
static gboolean
gtk_search_bar_render_contents (GtkCssGadget *gadget,
cairo_t *cr,
int x,
int y,
int width,
int height,
gpointer unused)
{
GTK_WIDGET_CLASS (gtk_search_bar_parent_class)->draw (gtk_css_gadget_get_owner (gadget), cr);
return FALSE;
}
static void
gtk_search_bar_allocate_contents (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer unused)
{
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
GTK_WIDGET_CLASS (gtk_search_bar_parent_class)->size_allocate (widget, (GtkAllocation *)allocation);
gtk_container_get_children_clip (GTK_CONTAINER (widget), out_clip);
}
static void
gtk_search_bar_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (GTK_SEARCH_BAR (widget));
GtkAllocation clip;
gtk_widget_set_allocation (widget, allocation);
gtk_css_gadget_allocate (priv->gadget, allocation, gtk_widget_get_allocated_baseline (widget), &clip);
gtk_widget_set_clip (widget, &clip);
}
static void
gtk_search_bar_get_content_size (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline,
gpointer unused)
{
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (GTK_SEARCH_BAR (widget));
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_widget_get_preferred_width_for_height (priv->revealer, for_size, minimum, natural);
else
gtk_widget_get_preferred_height_and_baseline_for_width (priv->revealer, for_size, minimum, natural, minimum_baseline, natural_baseline);
}
static void
gtk_search_bar_get_preferred_width_for_height (GtkWidget *widget,
gint height,
gint *minimum,
gint *natural)
{
GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (GTK_SEARCH_BAR (widget));
gtk_css_gadget_get_preferred_size (priv->gadget,
GTK_ORIENTATION_HORIZONTAL,
height,
minimum, natural,
NULL, NULL);
}
static void
gtk_search_bar_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (GTK_SEARCH_BAR (widget));
gtk_css_gadget_get_preferred_size (priv->gadget,
GTK_ORIENTATION_VERTICAL,
width,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
gtk_search_bar_class_init (GtkSearchBarClass *klass)
{
@@ -390,7 +483,11 @@ gtk_search_bar_class_init (GtkSearchBarClass *klass)
object_class->dispose = gtk_search_bar_dispose;
object_class->set_property = gtk_search_bar_set_property;
object_class->get_property = gtk_search_bar_get_property;
widget_class->draw = gtk_search_bar_draw;
widget_class->size_allocate = gtk_search_bar_size_allocate;
widget_class->get_preferred_width_for_height = gtk_search_bar_get_preferred_width_for_height;
widget_class->get_preferred_height_and_baseline_for_width = gtk_search_bar_get_preferred_height_and_baseline_for_width;
container_class->add = gtk_search_bar_add;
@@ -433,6 +530,7 @@ static void
gtk_search_bar_init (GtkSearchBar *bar)
{
GtkSearchBarPrivate *priv = gtk_search_bar_get_instance_private (bar);
GtkCssNode *widget_node;
gtk_widget_init_template (GTK_WIDGET (bar));
@@ -449,6 +547,16 @@ gtk_search_bar_init (GtkSearchBar *bar)
gtk_widget_set_no_show_all (priv->close_button, TRUE);
g_signal_connect (priv->close_button, "clicked",
G_CALLBACK (close_button_clicked_cb), bar);
widget_node = gtk_widget_get_css_node (GTK_WIDGET (bar));
priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
GTK_WIDGET (bar),
gtk_search_bar_get_content_size,
gtk_search_bar_allocate_contents,
gtk_search_bar_render_contents,
NULL,
NULL);
};
/**

View File

@@ -1213,7 +1213,6 @@ gtk_spin_button_get_preferred_width (GtkWidget *widget,
if (gtk_entry_get_width_chars (entry) < 0)
{
gint width, w;
GtkBorder borders;
PangoLayout *layout;
gchar *str;
@@ -1234,9 +1233,6 @@ gtk_spin_button_get_preferred_width (GtkWidget *widget,
width = MAX (width, w);
g_free (str);
_gtk_entry_get_borders (entry, &borders);
width += borders.left + borders.right;
*minimum = width;
*natural = width;

View File

@@ -2488,12 +2488,15 @@ levelbar {
/**********
* Frames *
**********/
frame,
frame border,
.frame {
box-shadow: none;
margin: 0;
padding: 0;
border-radius: 0;
border: 1px solid $borders_color;
&.flat { border-style: none; }
&:backdrop { border-color: $backdrop_borders_color; }
padding: 0;
}
paper {

View File

@@ -3478,14 +3478,17 @@ levelbar {
/**********
* Frames *
**********/
frame,
frame border,
.frame {
border: 1px solid #1c1f1f;
padding: 0; }
frame.flat,
box-shadow: none;
margin: 0;
padding: 0;
border-radius: 0;
border: 1px solid #1c1f1f; }
frame border.flat,
.frame.flat {
border-style: none; }
frame:backdrop,
frame border:backdrop,
.frame:backdrop {
border-color: #1f2222; }

View File

@@ -3640,14 +3640,17 @@ levelbar {
/**********
* Frames *
**********/
frame,
frame border,
.frame {
border: 1px solid #9d9d99;
padding: 0; }
frame.flat,
box-shadow: none;
margin: 0;
padding: 0;
border-radius: 0;
border: 1px solid #9d9d99; }
frame border.flat,
.frame.flat {
border-style: none; }
frame:backdrop,
frame border:backdrop,
.frame:backdrop {
border-color: #a5a5a1; }