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:
p_ch%verizon.net 2005-08-20 07:14:05 +00:00
Родитель 195591cece
Коммит c9ae7e0a54
5 изменённых файлов: 153 добавлений и 8 удалений

Просмотреть файл

@ -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;
}