зеркало из https://github.com/mozilla/gecko-dev.git
Bug 118294: NS_THEME_DROPDOWN implementation (GTK2)
(+ add forgotten style for menulist-description binding in the new toolkit) r=bryner, sr=roc.
This commit is contained in:
Родитель
195591cece
Коммит
c9ae7e0a54
|
@ -116,6 +116,8 @@ typedef enum {
|
|||
MOZ_GTK_GRIPPER,
|
||||
/* Paints a GtkEntry. */
|
||||
MOZ_GTK_ENTRY,
|
||||
/* Paints a GtkOptionMenu. */
|
||||
MOZ_GTK_DROPDOWN,
|
||||
/* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */
|
||||
MOZ_GTK_DROPDOWN_ARROW,
|
||||
/* Paints the container part of a GtkCheckButton. */
|
||||
|
|
|
@ -246,9 +246,10 @@ nsNativeThemeGTK::GetGtkWidgetAndState(PRUint8 aWidgetType, nsIFrame* aFrame,
|
|||
memset(aState, 0, sizeof(GtkWidgetState));
|
||||
} else {
|
||||
|
||||
// for dropdown textfields, look at the parent frame (the textbox)
|
||||
// for dropdown textfields, look at the parent frame (textbox or menulist)
|
||||
if (aWidgetType == NS_THEME_DROPDOWN_TEXTFIELD)
|
||||
aFrame = aFrame->GetParent();
|
||||
|
||||
// For XUL checkboxes and radio buttons, the state of the parent
|
||||
// determines our state.
|
||||
if (aWidgetType == NS_THEME_CHECKBOX || aWidgetType == NS_THEME_RADIO ||
|
||||
|
@ -369,10 +370,15 @@ nsNativeThemeGTK::GetGtkWidgetAndState(PRUint8 aWidgetType, nsIFrame* aFrame,
|
|||
case NS_THEME_TOOLBAR_GRIPPER:
|
||||
aGtkWidgetType = MOZ_GTK_GRIPPER;
|
||||
break;
|
||||
case NS_THEME_DROPDOWN_TEXTFIELD:
|
||||
case NS_THEME_TEXTFIELD:
|
||||
case NS_THEME_DROPDOWN_TEXTFIELD:
|
||||
aGtkWidgetType = MOZ_GTK_ENTRY;
|
||||
break;
|
||||
case NS_THEME_DROPDOWN:
|
||||
aGtkWidgetType = MOZ_GTK_DROPDOWN;
|
||||
break;
|
||||
case NS_THEME_DROPDOWN_TEXT:
|
||||
return PR_FALSE; // nothing to do, but prevents the bg from being drawn
|
||||
case NS_THEME_DROPDOWN_BUTTON:
|
||||
aGtkWidgetType = MOZ_GTK_DROPDOWN_ARROW;
|
||||
break;
|
||||
|
@ -754,9 +760,7 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
|
|||
// case NS_THEME_SCROLLBAR_GRIPPER_VERTICAL: (n/a for gtk)
|
||||
case NS_THEME_TEXTFIELD:
|
||||
// case NS_THEME_TEXTFIELD_CARET:
|
||||
// case NS_THEME_DROPDOWN:
|
||||
case NS_THEME_DROPDOWN_BUTTON:
|
||||
// case NS_THEME_DROPDOWN_TEXT:
|
||||
case NS_THEME_DROPDOWN_TEXTFIELD:
|
||||
// case NS_THEME_SLIDER:
|
||||
// case NS_THEME_SLIDER_THUMB:
|
||||
|
@ -773,6 +777,8 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
|
|||
case NS_THEME_MENUITEM:
|
||||
case NS_THEME_WINDOW:
|
||||
case NS_THEME_DIALOG:
|
||||
case NS_THEME_DROPDOWN:
|
||||
case NS_THEME_DROPDOWN_TEXT:
|
||||
#endif
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ static GtkWidget* gHorizScrollbarWidget;
|
|||
static GtkWidget* gVertScrollbarWidget;
|
||||
static GtkWidget* gEntryWidget;
|
||||
static GtkWidget* gArrowWidget;
|
||||
static GtkWidget* gOptionMenuWidget;
|
||||
static GtkWidget* gDropdownButtonWidget;
|
||||
static GtkWidget* gHandleBoxWidget;
|
||||
static GtkWidget* gToolbarWidget;
|
||||
|
@ -164,6 +165,16 @@ ensure_entry_widget()
|
|||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
||||
static gint
|
||||
ensure_option_menu_widget()
|
||||
{
|
||||
if (!gOptionMenuWidget) {
|
||||
gOptionMenuWidget = gtk_option_menu_new();
|
||||
setup_widget_prototype(gOptionMenuWidget);
|
||||
}
|
||||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
||||
static gint
|
||||
ensure_arrow_widget()
|
||||
{
|
||||
|
@ -459,6 +470,45 @@ moz_gtk_radio_get_focus(gboolean* interior_focus,
|
|||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
||||
static gint
|
||||
moz_gtk_option_menu_get_metrics(gboolean* interior_focus,
|
||||
GtkRequisition* indicator_size,
|
||||
GtkBorder* indicator_spacing,
|
||||
gint* focus_width,
|
||||
gint* focus_pad)
|
||||
{
|
||||
static const GtkRequisition default_indicator_size = { 7, 13 };
|
||||
static const GtkBorder default_indicator_spacing = { 7, 5, 2, 2 };
|
||||
/* these default values are not used in gtkoptionmenu.c
|
||||
static const gboolean default_interior_focus = TRUE;
|
||||
static const gint default_focus_width = 1;
|
||||
static const gint default_focus_pad = 0; */
|
||||
GtkRequisition *tmp_indicator_size;
|
||||
GtkBorder *tmp_indicator_spacing;
|
||||
|
||||
gtk_widget_style_get(gOptionMenuWidget,
|
||||
"interior_focus", interior_focus,
|
||||
"indicator_size", &tmp_indicator_size,
|
||||
"indicator_spacing", &tmp_indicator_spacing,
|
||||
"focus_line_width", focus_width,
|
||||
"focus_padding", focus_pad,
|
||||
NULL);
|
||||
|
||||
if (tmp_indicator_size)
|
||||
*indicator_size = *tmp_indicator_size;
|
||||
else
|
||||
*indicator_size = default_indicator_size;
|
||||
if (tmp_indicator_spacing)
|
||||
*indicator_spacing = *tmp_indicator_spacing;
|
||||
else
|
||||
*indicator_spacing = default_indicator_spacing;
|
||||
|
||||
g_free(tmp_indicator_size);
|
||||
g_free(tmp_indicator_spacing);
|
||||
|
||||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
||||
static gint
|
||||
moz_gtk_toggle_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
GdkRectangle* cliprect, GtkWidgetState* state,
|
||||
|
@ -754,6 +804,78 @@ moz_gtk_entry_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
|||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
||||
static gint
|
||||
moz_gtk_option_menu_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
GdkRectangle* cliprect, GtkWidgetState* state)
|
||||
{
|
||||
GtkStyle* style;
|
||||
GtkStateType state_type = ConvertGtkState(state);
|
||||
gint x = rect->x, y=rect->y, width=rect->width, height=rect->height;
|
||||
gint tab_x, tab_y;
|
||||
gboolean interior_focus;
|
||||
GtkRequisition indicator_size;
|
||||
GtkBorder indicator_spacing;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
|
||||
ensure_option_menu_widget();
|
||||
moz_gtk_option_menu_get_metrics(&interior_focus, &indicator_size,
|
||||
&indicator_spacing, &focus_width,
|
||||
&focus_pad);
|
||||
|
||||
style = gOptionMenuWidget->style;
|
||||
|
||||
if (!interior_focus && state->focused) {
|
||||
x += focus_width + focus_pad;
|
||||
y += focus_width + focus_pad;
|
||||
width -= 2 * (focus_width + focus_pad);
|
||||
height -= 2 * (focus_width + focus_pad);
|
||||
}
|
||||
|
||||
TSOffsetStyleGCs(style, x, y);
|
||||
gtk_paint_box(style, drawable, state_type, GTK_SHADOW_OUT,
|
||||
cliprect, gOptionMenuWidget, "optionmenu",
|
||||
x, y, width, height);
|
||||
|
||||
if (gtk_widget_get_direction(gOptionMenuWidget) == GTK_TEXT_DIR_RTL) {
|
||||
tab_x = x + indicator_spacing.right + XTHICKNESS(style);
|
||||
} else {
|
||||
tab_x = x + width - indicator_size.width - indicator_spacing.right -
|
||||
XTHICKNESS(style);
|
||||
}
|
||||
tab_y = y + (height - indicator_size.height) / 2;
|
||||
|
||||
TSOffsetStyleGCs(style, tab_x, tab_y);
|
||||
gtk_paint_tab(style, drawable, state_type, GTK_SHADOW_OUT, cliprect,
|
||||
gOptionMenuWidget, "optionmenutab", tab_x, tab_y,
|
||||
indicator_size.width, indicator_size.height);
|
||||
|
||||
if (state->focused) {
|
||||
if (interior_focus) {
|
||||
x += XTHICKNESS(style) + focus_pad;
|
||||
y += YTHICKNESS(style) + focus_pad;
|
||||
width -= 2 * (XTHICKNESS(style) + focus_pad) +
|
||||
indicator_spacing.left + indicator_spacing.right +
|
||||
indicator_size.width;
|
||||
height -= 2 * (YTHICKNESS(style) + focus_pad);
|
||||
if (gtk_widget_get_direction(gOptionMenuWidget) == GTK_TEXT_DIR_RTL)
|
||||
x += indicator_spacing.left + indicator_spacing.right +
|
||||
indicator_size.width;
|
||||
} else {
|
||||
x -= focus_width + focus_pad;
|
||||
y -= focus_width + focus_pad;
|
||||
width += 2 * (focus_width + focus_pad);
|
||||
height += 2 * (focus_width + focus_pad);
|
||||
}
|
||||
|
||||
TSOffsetStyleGCs(style, x, y);
|
||||
gtk_paint_focus (style, drawable, state_type, cliprect, gOptionMenuWidget,
|
||||
"button", x, y, width, height);
|
||||
}
|
||||
|
||||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
||||
static gint
|
||||
moz_gtk_dropdown_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
GdkRectangle* cliprect, GtkWidgetState* state)
|
||||
|
@ -1163,6 +1285,10 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* xthickness,
|
|||
ensure_arrow_widget();
|
||||
w = gDropdownButtonWidget;
|
||||
break;
|
||||
case MOZ_GTK_DROPDOWN:
|
||||
ensure_option_menu_widget();
|
||||
w = gOptionMenuWidget;
|
||||
break;
|
||||
case MOZ_GTK_TABPANELS:
|
||||
ensure_tab_widget();
|
||||
w = gTabWidget;
|
||||
|
@ -1340,6 +1466,9 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
|
|||
case MOZ_GTK_ENTRY:
|
||||
return moz_gtk_entry_paint(drawable, rect, cliprect, state);
|
||||
break;
|
||||
case MOZ_GTK_DROPDOWN:
|
||||
return moz_gtk_option_menu_paint(drawable, rect, cliprect, state);
|
||||
break;
|
||||
case MOZ_GTK_DROPDOWN_ARROW:
|
||||
return moz_gtk_dropdown_arrow_paint(drawable, rect, cliprect, state);
|
||||
break;
|
||||
|
|
|
@ -116,6 +116,8 @@ typedef enum {
|
|||
MOZ_GTK_GRIPPER,
|
||||
/* Paints a GtkEntry. */
|
||||
MOZ_GTK_ENTRY,
|
||||
/* Paints a GtkOptionMenu. */
|
||||
MOZ_GTK_DROPDOWN,
|
||||
/* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */
|
||||
MOZ_GTK_DROPDOWN_ARROW,
|
||||
/* Paints the container part of a GtkCheckButton. */
|
||||
|
|
|
@ -246,9 +246,10 @@ nsNativeThemeGTK::GetGtkWidgetAndState(PRUint8 aWidgetType, nsIFrame* aFrame,
|
|||
memset(aState, 0, sizeof(GtkWidgetState));
|
||||
} else {
|
||||
|
||||
// for dropdown textfields, look at the parent frame (the textbox)
|
||||
// for dropdown textfields, look at the parent frame (textbox or menulist)
|
||||
if (aWidgetType == NS_THEME_DROPDOWN_TEXTFIELD)
|
||||
aFrame = aFrame->GetParent();
|
||||
|
||||
// For XUL checkboxes and radio buttons, the state of the parent
|
||||
// determines our state.
|
||||
if (aWidgetType == NS_THEME_CHECKBOX || aWidgetType == NS_THEME_RADIO ||
|
||||
|
@ -369,10 +370,15 @@ nsNativeThemeGTK::GetGtkWidgetAndState(PRUint8 aWidgetType, nsIFrame* aFrame,
|
|||
case NS_THEME_TOOLBAR_GRIPPER:
|
||||
aGtkWidgetType = MOZ_GTK_GRIPPER;
|
||||
break;
|
||||
case NS_THEME_DROPDOWN_TEXTFIELD:
|
||||
case NS_THEME_TEXTFIELD:
|
||||
case NS_THEME_DROPDOWN_TEXTFIELD:
|
||||
aGtkWidgetType = MOZ_GTK_ENTRY;
|
||||
break;
|
||||
case NS_THEME_DROPDOWN:
|
||||
aGtkWidgetType = MOZ_GTK_DROPDOWN;
|
||||
break;
|
||||
case NS_THEME_DROPDOWN_TEXT:
|
||||
return PR_FALSE; // nothing to do, but prevents the bg from being drawn
|
||||
case NS_THEME_DROPDOWN_BUTTON:
|
||||
aGtkWidgetType = MOZ_GTK_DROPDOWN_ARROW;
|
||||
break;
|
||||
|
@ -754,9 +760,7 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
|
|||
// case NS_THEME_SCROLLBAR_GRIPPER_VERTICAL: (n/a for gtk)
|
||||
case NS_THEME_TEXTFIELD:
|
||||
// case NS_THEME_TEXTFIELD_CARET:
|
||||
// case NS_THEME_DROPDOWN:
|
||||
case NS_THEME_DROPDOWN_BUTTON:
|
||||
// case NS_THEME_DROPDOWN_TEXT:
|
||||
case NS_THEME_DROPDOWN_TEXTFIELD:
|
||||
// case NS_THEME_SLIDER:
|
||||
// case NS_THEME_SLIDER_THUMB:
|
||||
|
@ -773,6 +777,8 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
|
|||
case NS_THEME_MENUITEM:
|
||||
case NS_THEME_WINDOW:
|
||||
case NS_THEME_DIALOG:
|
||||
case NS_THEME_DROPDOWN:
|
||||
case NS_THEME_DROPDOWN_TEXT:
|
||||
#endif
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче