+2007-03-08 Mathias Hasselmann <mathias.hasselmann@gmx.de>
+
+ * gtk/gtkcombobox.c: Add shadow-type style property, set shadow-type
+ property of GtkEntry accordingly, unify size-allocation of toggle
+ button (#411123, patch from Mathias Hasselmann).
+ * gtk/gtkentry.c: Add shadow-type property. Query style properties
+ on style changes only (#411123, patch from Mathias Hasselmann).
+ * modules/engines/ms-windows/msw_style.c: Drop combo_box_draw_box
+ hack as GtkComboBox emits drawing requests now (#411123, patch
+ from Mathias Hasselmann).
+
2007-03-08 Mathias Hasselmann <mathias.hasselmann@gmx.de>
* gtk/gtkscrolledindow.c: Improve look of GtkScrolledWindow on Windows
gint row_column;
gint wrap_width;
+ GtkShadowType shadow_type;
GtkTreeRowReference *active_row;
15,
GTK_PARAM_READABLE));
+ /**
+ * GtkComboBox:shadow-type:
+ *
+ * Which kind of shadow to draw around the combo box.
+ *
+ * Since: 2.12
+ */
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_enum ("shadow-type",
+ P_("Shadow type"),
+ P_("Which kind of shadow to draw around the combo box"),
+ GTK_TYPE_SHADOW_TYPE,
+ GTK_SHADOW_NONE,
+ GTK_PARAM_READABLE));
+
g_type_class_add_private (object_class, sizeof (GtkComboBoxPrivate));
}
if (!GTK_IS_MENU (combo_box->priv->popup_widget))
gtk_combo_box_menu_setup (combo_box, TRUE);
}
+
+ gtk_widget_style_get (GTK_WIDGET (combo_box),
+ "shadow-type", &combo_box->priv->shadow_type,
+ NULL);
}
static void
if (combo_box->priv->tree_view && combo_box->priv->cell_view)
gtk_cell_view_set_background_color (GTK_CELL_VIEW (combo_box->priv->cell_view),
&widget->style->base[GTK_WIDGET_STATE (widget)]);
+
+ if (GTK_IS_ENTRY (GTK_BIN (combo_box)->child))
+ g_object_set (GTK_BIN (combo_box)->child, "shadow-type",
+ GTK_SHADOW_NONE == combo_box->priv->shadow_type ?
+ GTK_SHADOW_IN : GTK_SHADOW_NONE, NULL);
}
static void
sy += child->allocation.y;
}
+ if (GTK_SHADOW_NONE != combo_box->priv->shadow_type)
+ sx -= GTK_WIDGET (combo_box)->style->xthickness;
+
gtk_widget_size_request (GTK_WIDGET (menu), &req);
if (gtk_widget_get_direction (GTK_WIDGET (combo_box)) == GTK_TEXT_DIR_LTR)
requisition->height = MAX (requisition->height, button_req.height);
requisition->width += button_req.width;
}
+
+ if (GTK_SHADOW_NONE != combo_box->priv->shadow_type)
+ {
+ requisition->height += 2 * widget->style->ythickness;
+ requisition->width += 2 * widget->style->xthickness;
+ }
}
+#define GTK_COMBO_BOX_SIZE_ALLOCATE_BUTTON \
+ gtk_widget_size_request (combo_box->priv->button, &req); \
+ \
+ if (is_rtl) \
+ child.x = allocation->x + shadow_width; \
+ else \
+ child.x = allocation->x + allocation->width - req.width - shadow_width; \
+ \
+ child.y = allocation->y + shadow_height; \
+ child.width = req.width; \
+ child.height = allocation->height - 2 * shadow_height; \
+ child.width = MAX (1, child.width); \
+ child.height = MAX (1, child.height); \
+ \
+ gtk_widget_size_allocate (combo_box->priv->button, &child);
+
static void
gtk_combo_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
+ gint shadow_width, shadow_height;
gint focus_width, focus_pad;
GtkAllocation child;
GtkRequisition req;
"focus-padding", &focus_pad,
NULL);
+ if (GTK_SHADOW_NONE != combo_box->priv->shadow_type)
+ {
+ shadow_width = widget->style->xthickness;
+ shadow_height = widget->style->ythickness;
+ }
+ else
+ {
+ shadow_width = 0;
+ shadow_height = 0;
+ }
+
if (!combo_box->priv->tree_view)
{
if (combo_box->priv->cell_view)
gint width;
/* menu mode */
+ allocation->x += shadow_width;
+ allocation->y += shadow_height;
+ allocation->width -= 2 * shadow_width;
+ allocation->height -= 2 * shadow_height;
+
gtk_widget_size_allocate (combo_box->priv->button, allocation);
/* set some things ready */
}
else
{
- gtk_widget_size_request (combo_box->priv->button, &req);
- if (is_rtl)
- child.x = allocation->x;
- else
- child.x = allocation->x + allocation->width - req.width;
- child.y = allocation->y;
- child.width = req.width;
- child.height = allocation->height;
- child.width = MAX (1, child.width);
- child.height = MAX (1, child.height);
- gtk_widget_size_allocate (combo_box->priv->button, &child);
+ GTK_COMBO_BOX_SIZE_ALLOCATE_BUTTON
if (is_rtl)
- child.x = allocation->x + req.width;
+ child.x = allocation->x + req.width + shadow_width;
else
- child.x = allocation->x;
- child.y = allocation->y;
- child.width = allocation->width - req.width;
+ child.x = allocation->x + shadow_width;
+ child.y = allocation->y + shadow_height;
+ child.width = allocation->width - req.width - 2 * shadow_width;
child.width = MAX (1, child.width);
child.height = MAX (1, child.height);
gtk_widget_size_allocate (GTK_BIN (widget)->child, &child);
/* list mode */
/* button */
- gtk_widget_size_request (combo_box->priv->button, &req);
- if (is_rtl)
- child.x = allocation->x;
- else
- child.x = allocation->x + allocation->width - req.width;
- child.y = allocation->y;
- child.width = req.width;
- child.height = allocation->height;
- child.width = MAX (1, child.width);
- child.height = MAX (1, child.height);
- gtk_widget_size_allocate (combo_box->priv->button, &child);
+ GTK_COMBO_BOX_SIZE_ALLOCATE_BUTTON
/* frame */
if (is_rtl)
}
}
+#undef GTK_COMBO_BOX_ALLOCATE_BUTTON
+
static void
gtk_combo_box_unset_model (GtkComboBox *combo_box)
{
{
GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
+ if (GTK_WIDGET_DRAWABLE (widget) &&
+ GTK_SHADOW_NONE != combo_box->priv->shadow_type)
+ {
+ gtk_paint_shadow (widget->style, widget->window,
+ GTK_STATE_NORMAL, combo_box->priv->shadow_type,
+ NULL, widget, "combobox",
+ widget->allocation.x, widget->allocation.y,
+ widget->allocation.width, widget->allocation.height);
+ }
+
gtk_container_propagate_expose (GTK_CONTAINER (widget),
combo_box->priv->button, event);
guint blink_time; /* time in msec the cursor has blinked since last user event */
guint real_changed : 1;
guint change_count : 8;
+
+ gint focus_width;
+ gboolean interior_focus;
+ GtkShadowType shadow_type;
};
typedef struct _GtkEntryPasswordHint GtkEntryPasswordHint;
PROP_SCROLL_OFFSET,
PROP_TEXT,
PROP_XALIGN,
- PROP_TRUNCATE_MULTILINE
+ PROP_TRUNCATE_MULTILINE,
+ PROP_SHADOW_TYPE
};
static guint signals[LAST_SIGNAL] = { 0 };
FALSE,
GTK_PARAM_READWRITE));
+ /**
+ * GtkEntry:shadow-type:
+ *
+ * Which kind of shadow to draw around the entry when has-frame is set.
+ *
+ * Since: 2.12
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_SHADOW_TYPE,
+ g_param_spec_enum ("shadow-type",
+ P_("Shadow type"),
+ P_("Which kind of shadow to draw around the entry when has-frame is set"),
+ GTK_TYPE_SHADOW_TYPE,
+ GTK_SHADOW_IN,
+ GTK_PARAM_READWRITE));
+
signals[POPULATE_POPUP] =
g_signal_new (I_("populate_popup"),
G_OBJECT_CLASS_TYPE (gobject_class),
const GValue *value,
GParamSpec *pspec)
{
+ GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (object);
GtkEntry *entry = GTK_ENTRY (object);
switch (prop_id)
entry->truncate_multiline = g_value_get_boolean (value);
break;
+ case PROP_SHADOW_TYPE:
+ priv->shadow_type = g_value_get_enum (value);
+ break;
+
case PROP_SCROLL_OFFSET:
case PROP_CURSOR_POSITION:
default:
GValue *value,
GParamSpec *pspec)
{
+ GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (object);
GtkEntry *entry = GTK_ENTRY (object);
switch (prop_id)
case PROP_TRUNCATE_MULTILINE:
g_value_set_boolean (value, entry->truncate_multiline);
break;
+ case PROP_SHADOW_TYPE:
+ g_value_set_enum (value, priv->shadow_type);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
entry->editing_canceled = FALSE;
entry->has_frame = TRUE;
entry->truncate_multiline = FALSE;
+ priv->shadow_type = GTK_SHADOW_IN;
priv->xalign = 0.0;
gtk_drag_dest_set (GTK_WIDGET (entry),
gint *yborder)
{
GtkWidget *widget = GTK_WIDGET (entry);
- gint focus_width;
- gboolean interior_focus;
-
- gtk_widget_style_get (widget,
- "interior-focus", &interior_focus,
- "focus-line-width", &focus_width,
- NULL);
+ GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget);
if (entry->has_frame)
{
*yborder = 0;
}
- if (!interior_focus)
+ if (!priv->interior_focus)
{
- *xborder += focus_width;
- *yborder += focus_width;
+ *xborder += priv->focus_width;
+ *yborder += priv->focus_width;
}
}
gint xborder, yborder;
GtkRequisition requisition;
GtkWidget *widget = GTK_WIDGET (entry);
- gboolean interior_focus;
- gint focus_width;
-
- gtk_widget_style_get (widget,
- "interior-focus", &interior_focus,
- "focus-line-width", &focus_width,
- NULL);
+ GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget);
gtk_widget_get_child_requisition (widget, &requisition);
_gtk_entry_get_borders (entry, &xborder, &yborder);
else
frame_height = requisition.height;
- if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
- frame_height -= 2 * focus_width;
+ if (GTK_WIDGET_HAS_FOCUS (widget) && !priv->interior_focus)
+ frame_height -= 2 * priv->focus_width;
if (x)
*x = xborder;
gtk_entry_draw_frame (GtkWidget *widget,
GdkRectangle *area)
{
- gint x = 0, y = 0;
- gint width, height;
- gboolean interior_focus;
- gint focus_width;
-
- gtk_widget_style_get (widget,
- "interior-focus", &interior_focus,
- "focus-line-width", &focus_width,
- NULL);
+ GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget);
+ gint x = 0, y = 0, width, height;
gdk_drawable_get_size (widget->window, &width, &height);
- if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
+ if (GTK_WIDGET_HAS_FOCUS (widget) && !priv->interior_focus)
{
- x += focus_width;
- y += focus_width;
- width -= 2 * focus_width;
- height -= 2 * focus_width;
+ x += priv->focus_width;
+ y += priv->focus_width;
+ width -= 2 * priv->focus_width;
+ height -= 2 * priv->focus_width;
}
gtk_paint_shadow (widget->style, widget->window,
- GTK_STATE_NORMAL, GTK_SHADOW_IN,
- area, widget, "entry",
- x, y, width, height);
+ GTK_STATE_NORMAL, priv->shadow_type,
+ area, widget, "entry", x, y, width, height);
- if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
+ if (GTK_WIDGET_HAS_FOCUS (widget) && !priv->interior_focus)
{
- x -= focus_width;
- y -= focus_width;
- width += 2 * focus_width;
- height += 2 * focus_width;
+ x -= priv->focus_width;
+ y -= priv->focus_width;
+ width += 2 * priv->focus_width;
+ height += 2 * priv->focus_width;
gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget),
area, widget, "entry",
GtkStyle *previous_style)
{
GtkEntry *entry = GTK_ENTRY (widget);
+ GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
+ gtk_widget_style_get (widget,
+ "focus-line-width", &priv->focus_width,
+ "interior-focus", &priv->interior_focus,
+ NULL);
+
gtk_entry_recompute (entry);
if (previous_style && GTK_WIDGET_REALIZED (widget))
gtk_rc_parse_string (buf);
/* size of combo box toggle button */
- g_snprintf (buf, sizeof(buf),
- "style \"msw-combo-button\" = \"msw-default\"\n"
+ g_snprintf (buf, sizeof(buf),
+ "style \"msw-combobox-button\" = \"msw-default\"\n"
"{\n"
- "xthickness = 0\n"
- "ythickness = 0\n"
- "GtkButton::default-border = { 0, 0, 0, 0 }\n"
- "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
- "GtkButton::child-displacement-x = 0\n"
- "GtkButton::child-displacement-y = 0\n"
- "GtkWidget::focus-padding = 0\n"
- "GtkWidget::focus-line-width = 0\n"
+ "xthickness = 0\n"
+ "ythickness = 0\n"
+ "GtkButton::default-border = { 0, 0, 0, 0 }\n"
+ "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
+ "GtkButton::child-displacement-x = 0\n"
+ "GtkButton::child-displacement-y = 0\n"
+ "GtkWidget::focus-padding = 0\n"
+ "GtkWidget::focus-line-width = 0\n"
"}\n"
- "widget_class \"*ComboBox*ToggleButton*\" style \"msw-combo-button\"\n");
- gtk_rc_parse_string (buf);
+ "widget_class \"*ComboBox*ToggleButton*\" style \"msw-combobox-button\"\n");
+ gtk_rc_parse_string (buf);
+
+ g_snprintf (buf, sizeof(buf),
+ "style \"msw-combobox\" = \"msw-default\"\n"
+ "{\n"
+ "GtkComboBox::shadow-type = in\n"
+ "xthickness = %d\n"
+ "ythickness = %d\n"
+ "}\n"
+ "class \"GtkComboBox\" style \"msw-combobox\"\n",
+ GetSystemMetrics (SM_CXEDGE),
+ GetSystemMetrics (SM_CYEDGE));
+ gtk_rc_parse_string (buf);
/* size of tree view header */
g_snprintf (buf, sizeof(buf),
GdkRectangle * area,
GtkWidget * widget)
{
- HDC dc;
- RECT rect;
-
- if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
- style, widget->allocation.x, widget->allocation.y,
- widget->allocation.width, widget->allocation.height,
- state, area))
- {
- return TRUE;
- }
- else if ( !xp_theme_is_active () && widget && GTK_IS_TOGGLE_BUTTON(widget->parent) )
- {
- dc = get_window_dc( style, window, state, area->x, area->y, area->width, area->height, &rect );
- InflateRect( &rect, 1, 1 );
- DrawFrameControl( dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN |
- (GTK_TOGGLE_BUTTON(widget->parent)->active ? DFCS_PUSHED|DFCS_FLAT : 0) );
- release_window_dc( style, window, state );
+ if (xp_theme_is_active ())
return TRUE;
- }
- return FALSE;
-}
-/* This is ugly because no box drawing function is invoked for the combo
- box as a whole, so we draw part of the entire box in every subwidget.
- We do this by finding the allocation of the combo box in the given
- window's coordinates and drawing. The xp drawing routines take care
- of the clipping. */
-static gboolean
-combo_box_draw_box (GtkStyle * style,
- GdkWindow * window,
- GtkStateType state_type,
- GtkShadowType shadow_type,
- GdkRectangle * area,
- GtkWidget * widget,
- const gchar * detail, gint x, gint y, gint width, gint height)
-{
- GtkWidget* combo_box;
- GdkRectangle combo_alloc;
- HDC dc;
- RECT rect;
-
- if (!widget)
- return FALSE;
- for (combo_box = widget->parent; combo_box; combo_box = combo_box->parent)
- {
- if (GTK_IS_COMBO_BOX(combo_box))
- break;
- }
- if (!combo_box)
- return FALSE;
+ if (widget && GTK_IS_TOGGLE_BUTTON(widget->parent) )
+ {
+ DWORD border;
+ RECT rect;
+ HDC dc;
- combo_alloc = combo_box->allocation;
- if (window != combo_box->window)
- {
- GtkWidget* tmp;
- for (tmp = widget; tmp && tmp != combo_box; tmp = widget->parent)
- {
- if (tmp->parent && tmp->window != tmp->parent->window)
- {
- combo_alloc.x -= tmp->allocation.x;
- combo_alloc.y -= tmp->allocation.y;
- }
- }
- }
+ dc = get_window_dc( style, window, state, area->x, area->y, area->width, area->height, &rect );
+ border = (GTK_TOGGLE_BUTTON(widget->parent)->active ? DFCS_PUSHED|DFCS_FLAT : 0);
- if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
- style, combo_alloc.x, combo_alloc.y,
- combo_alloc.width, combo_alloc.height,
- state_type, area))
- return TRUE;
- else
- {
- UINT edges = 0;
- gboolean rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
-
- if( !strcmp(detail, "button") )
- edges = BF_BOTTOM|BF_TOP|(rtl ? BF_LEFT : BF_RIGHT);
- else if( !strcmp( detail, "frame") || !strcmp( detail, "entry" ) )
- edges = BF_BOTTOM|BF_TOP|(rtl ? BF_RIGHT : BF_LEFT);
- else
- return TRUE;
- dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
- DrawEdge( dc, &rect, EDGE_SUNKEN, edges );
+ InflateRect( &rect, 1, 1 );
+ DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
- /* Fill blank area between frame/entry and button */
- if( !strcmp(detail, "button") ) { /* button */
- if( rtl ) {
- rect.left = rect.right;
- rect.right += 2;
- }
- else
- rect.right = rect.left + 2;
- }
- else{ /* frame or entry */
- if( rtl ) {
- rect.right = rect.left;
- rect.left -= 2;
- }
- else
- rect.left = rect.right - 2;
- }
- rect.top += 2;
- rect.bottom -= 2;
- FillRect( dc, &rect, GetSysColorBrush(COLOR_WINDOW) );
- release_window_dc( style, window, state_type );
+ release_window_dc( style, window, state );
return TRUE;
}
case GTK_ARROW_RIGHT:
btn_type = DFCS_SCROLLRIGHT;
break;
+ case GTK_ARROW_NONE:
+ break;
}
if( state == GTK_STATE_INSENSITIVE )
btn_type |= DFCS_INACTIVE;
GtkWidget * widget,
const gchar * detail, gint x, gint y, gint width, gint height)
{
- if (is_combo_box_child (widget)
- && combo_box_draw_box (style, window, state_type, shadow_type,
- area, widget, detail, x, y, width, height))
- {
+ if (is_combo_box_child (widget) && detail && !strcmp (detail, "button")) {
+ RECT rect;
+ HDC dc;
+ int cx;
+
+ dc = get_window_dc (style, window, state_type, x, y, width - cx, height, &rect);
+ FillRect (dc, &rect, GetSysColorBrush(COLOR_WINDOW));
+ release_window_dc (style, window, state_type);
+
+ cx = 2 * GetSystemMetrics (SM_CXEDGE) + 16; /* TODO evaluate arrow width */
+ x += width - cx;
+ width = cx;
+
+ if (xp_theme_is_active () && xp_theme_draw (
+ window, XP_THEME_ELEMENT_COMBOBUTTON, style,
+ x, y, width, height, state_type, area))
return;
- }
- else if (detail &&
+ }
+
+ if (detail &&
(!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
{
if (GTK_IS_TREE_VIEW (widget->parent)
SetRect(&lightRect, R.left, R.bottom-3, R.left+2, R.bottom-1);
SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
break;
+ default:
+ g_return_if_reached();
}
/* Background */
gboolean is_handlebox;
gboolean is_toolbar;
- if (is_combo_box_child (widget)
- && combo_box_draw_box (style, window, state_type, shadow_type,
- area, widget, detail, x, y, width, height))
- {
- return;
- }
if( detail && !strcmp( detail, "frame") )
{
HDC dc;
InflateRect( &rect, -1, -1 );
draw_3d_border(dc, &rect, TRUE);
break;
+ case GTK_SHADOW_NONE:
+ break;
}
}
release_window_dc( style, window, state_type );
return;
}
- if (detail && !strcmp (detail, "entry") )
+ if (detail && (!strcmp (detail, "entry") || !strcmp (detail, "combobox")) )
{
- if ( xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
- x, y, width, height, state_type, area))
- {
- return;
- }
- if( shadow_type == GTK_SHADOW_IN ) {
- HDC dc;
- RECT rect;
- dc = get_window_dc( style, window, state_type,
- x, y, width, height, &rect );
- DrawEdge( dc, &rect, EDGE_SUNKEN, BF_RECT );
- release_window_dc( style, window, state_type );
- return;
- }
+ if( shadow_type != GTK_SHADOW_IN )
+ return;
+
+ if ( !xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
+ x, y, width, height, state_type, area))
+ {
+ HDC dc;
+ RECT rect;
+
+ dc = get_window_dc (style, window, state_type,
+ x, y, width, height, &rect);
+ DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT);
+ release_window_dc (style, window, state_type);
+ }
+
+ return;
}
if( detail && !strcmp( detail, "spinbutton" ) )
if( widget ) {
HDC dc;
RECT rect;
- HGDIOBJ old_pen;
+ HGDIOBJ old_pen = NULL;
GtkPositionType pos;
sanitize_size (window, &width, &height);
MoveToEx( dc, rect.left, rect.bottom-1, NULL );
LineTo( dc, rect.right, rect.bottom-1 );
}
- SelectObject( dc, old_pen );
+ if (old_pen)
+ SelectObject( dc, old_pen );
release_window_dc( style, window, state_type );
}
return;