diff options
Diffstat (limited to 'WebCore/platform/gtk/RenderThemeGtk.cpp')
-rw-r--r-- | WebCore/platform/gtk/RenderThemeGtk.cpp | 453 |
1 files changed, 288 insertions, 165 deletions
diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp index fe6c9e9..73b2d6b 100644 --- a/WebCore/platform/gtk/RenderThemeGtk.cpp +++ b/WebCore/platform/gtk/RenderThemeGtk.cpp @@ -55,6 +55,19 @@ namespace WebCore { using namespace HTMLNames; +static void paintStockIcon(GraphicsContext* context, const IntPoint& iconPoint, GtkStyle* style, const char* iconName, + GtkTextDirection direction, GtkStateType state, GtkIconSize iconSize) +{ + GtkIconSet* iconSet = gtk_style_lookup_icon_set(style, iconName); + PlatformRefPtr<GdkPixbuf> icon = adoptPlatformRef(gtk_icon_set_render_icon(iconSet, style, direction, state, iconSize, 0, 0)); + + cairo_t* cr = context->platformContext(); + cairo_save(cr); + gdk_cairo_set_source_pixbuf(cr, icon.get(), iconPoint.x(), iconPoint.y()); + cairo_paint(cr); + cairo_restore(cr); +} + #if ENABLE(VIDEO) static HTMLMediaElement* getMediaElementFromRenderObject(RenderObject* o) { @@ -66,57 +79,46 @@ static HTMLMediaElement* getMediaElementFromRenderObject(RenderObject* o) return static_cast<HTMLMediaElement*>(mediaNode); } -static gchar* getIconNameForTextDirection(const char* baseName) +static GtkIconSize getMediaButtonIconSize(int mediaIconSize) { - GString* nameWithDirection = g_string_new(baseName); - GtkTextDirection textDirection = gtk_widget_get_default_direction(); - - if (textDirection == GTK_TEXT_DIR_RTL) - g_string_append(nameWithDirection, "-rtl"); - else if (textDirection == GTK_TEXT_DIR_LTR) - g_string_append(nameWithDirection, "-ltr"); - - return g_string_free(nameWithDirection, FALSE); + GtkIconSize iconSize = gtk_icon_size_from_name("webkit-media-button-size"); + if (!iconSize) + iconSize = gtk_icon_size_register("webkit-media-button-size", mediaIconSize, mediaIconSize); + return iconSize; } -void RenderThemeGtk::initMediaStyling(GtkStyle* style, bool force) +void RenderThemeGtk::initMediaColors() { - static bool stylingInitialized = false; + GtkStyle* style = gtk_widget_get_style(GTK_WIDGET(gtkContainer())); + m_panelColor = style->bg[GTK_STATE_NORMAL]; + m_sliderColor = style->bg[GTK_STATE_ACTIVE]; + m_sliderThumbColor = style->bg[GTK_STATE_SELECTED]; +} - if (!stylingInitialized || force) { - m_panelColor = style->bg[GTK_STATE_NORMAL]; - m_sliderColor = style->bg[GTK_STATE_ACTIVE]; - m_sliderThumbColor = style->bg[GTK_STATE_SELECTED]; +void RenderThemeGtk::initMediaButtons() +{ + static bool iconsInitialized = false; - // Names of these icons can vary because of text direction. - gchar* playButtonIconName = getIconNameForTextDirection("gtk-media-play"); - gchar* seekBackButtonIconName = getIconNameForTextDirection("gtk-media-rewind"); - gchar* seekForwardButtonIconName = getIconNameForTextDirection("gtk-media-forward"); + if (iconsInitialized) + return; - m_fullscreenButton.clear(); - m_muteButton.clear(); - m_unmuteButton.clear(); - m_playButton.clear(); - m_pauseButton.clear(); - m_seekBackButton.clear(); - m_seekForwardButton.clear(); + PlatformRefPtr<GtkIconFactory> iconFactory = adoptPlatformRef(gtk_icon_factory_new()); + GtkIconSource* iconSource = gtk_icon_source_new(); + const char* icons[] = { "audio-volume-high", "audio-volume-muted" }; - m_fullscreenButton = Image::loadPlatformThemeIcon("gtk-fullscreen", m_mediaIconSize); - // Note that the muteButton and unmuteButton take icons reflecting - // the *current* state. Hence, the unmuteButton represents the *muted* - // status, the muteButton represents the then current *unmuted* status. - m_muteButton = Image::loadPlatformThemeIcon("audio-volume-high", m_mediaIconSize); - m_unmuteButton = Image::loadPlatformThemeIcon("audio-volume-muted", m_mediaIconSize); - m_playButton = Image::loadPlatformThemeIcon(reinterpret_cast<const char*>(playButtonIconName), m_mediaIconSize); - m_pauseButton = Image::loadPlatformThemeIcon("gtk-media-pause", m_mediaIconSize); - m_seekBackButton = Image::loadPlatformThemeIcon(reinterpret_cast<const char*>(seekBackButtonIconName), m_mediaIconSize); - m_seekForwardButton = Image::loadPlatformThemeIcon(reinterpret_cast<const char*>(seekForwardButtonIconName), m_mediaIconSize); + gtk_icon_factory_add_default(iconFactory.get()); - g_free(playButtonIconName); - g_free(seekBackButtonIconName); - g_free(seekForwardButtonIconName); - stylingInitialized = true; + for (size_t i = 0; i < G_N_ELEMENTS(icons); ++i) { + gtk_icon_source_set_icon_name(iconSource, icons[i]); + GtkIconSet* iconSet = gtk_icon_set_new(); + gtk_icon_set_add_source(iconSet, iconSource); + gtk_icon_factory_add(iconFactory.get(), icons[i], iconSet); + gtk_icon_set_unref(iconSet); } + + gtk_icon_source_free(iconSource); + + iconsInitialized = true; } #endif @@ -146,13 +148,6 @@ RenderThemeGtk::RenderThemeGtk() , m_mediaSliderHeight(14) , m_mediaSliderThumbWidth(12) , m_mediaSliderThumbHeight(12) - , m_fullscreenButton(0) - , m_muteButton(0) - , m_unmuteButton(0) - , m_playButton(0) - , m_pauseButton(0) - , m_seekBackButton(0) - , m_seekForwardButton(0) #ifdef GTK_API_VERSION_2 , m_themePartsHaveRGBAColormap(true) #endif @@ -176,7 +171,8 @@ RenderThemeGtk::RenderThemeGtk() ++mozGtkRefCount; #if ENABLE(VIDEO) - initMediaStyling(gtk_rc_get_style(GTK_WIDGET(gtkContainer())), false); + initMediaColors(); + initMediaButtons(); #endif } @@ -187,14 +183,6 @@ RenderThemeGtk::~RenderThemeGtk() if (!mozGtkRefCount) moz_gtk_shutdown(); - m_fullscreenButton.clear(); - m_muteButton.clear(); - m_unmuteButton.clear(); - m_playButton.clear(); - m_pauseButton.clear(); - m_seekBackButton.clear(); - m_seekForwardButton.clear(); - gtk_widget_destroy(m_gtkWindow); } @@ -229,6 +217,17 @@ static bool supportsFocus(ControlPart appearance) } } +GtkStateType RenderThemeGtk::getGtkStateType(RenderObject* object) +{ + if (!isEnabled(object) || isReadOnlyControl(object)) + return GTK_STATE_INSENSITIVE; + if (isPressed(object)) + return GTK_STATE_ACTIVE; + if (isHovered(object)) + return GTK_STATE_PRELIGHT; + return GTK_STATE_NORMAL; +} + bool RenderThemeGtk::supportsFocusRing(const RenderStyle* style) const { return supportsFocus(style->appearance()); @@ -266,23 +265,16 @@ static GtkTextDirection gtkTextDirection(TextDirection direction) } } -static void adjustMozillaStyle(const RenderThemeGtk* theme, RenderStyle* style, GtkThemeWidgetType type) +GtkStateType RenderThemeGtk::gtkIconState(RenderObject* renderObject) { - gint left, top, right, bottom; - GtkTextDirection direction = gtkTextDirection(style->direction()); - gboolean inhtml = true; - - if (moz_gtk_get_widget_border(type, &left, &top, &right, &bottom, direction, inhtml) != MOZ_GTK_SUCCESS) - return; + if (!isEnabled(renderObject)) + return GTK_STATE_INSENSITIVE; + if (isPressed(renderObject)) + return GTK_STATE_ACTIVE; + if (isHovered(renderObject)) + return GTK_STATE_PRELIGHT; - // FIXME: This approach is likely to be incorrect. See other ports and layout tests to see the problem. - const int xpadding = 1; - const int ypadding = 1; - - style->setPaddingLeft(Length(xpadding + left, Fixed)); - style->setPaddingTop(Length(ypadding + top, Fixed)); - style->setPaddingRight(Length(xpadding + right, Fixed)); - style->setPaddingBottom(Length(ypadding + bottom, Fixed)); + return GTK_STATE_NORMAL; } bool RenderThemeGtk::paintRenderObject(GtkThemeWidgetType type, RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, int flags) @@ -306,14 +298,7 @@ bool RenderThemeGtk::paintRenderObject(GtkThemeWidgetType type, RenderObject* re widgetState.disabled = !isEnabled(renderObject) || isReadOnlyControl(renderObject); widgetState.isDefault = false; widgetState.canDefault = false; - - // FIXME: The depressed value should probably apply for other theme parts too. - // It must be used for range thumbs, because otherwise when the thumb is pressed, - // the rendering is incorrect. - if (type == MOZ_GTK_SCALE_THUMB_HORIZONTAL || type == MOZ_GTK_SCALE_THUMB_VERTICAL) - widgetState.depressed = isPressed(renderObject); - else - widgetState.depressed = false; + widgetState.depressed = false; WidgetRenderingContext widgetContext(context, rect); return !widgetContext.paintMozillaWidget(type, &widgetState, flags, gtkTextDirection(renderObject->style()->direction())); @@ -366,9 +351,56 @@ void RenderThemeGtk::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style->setLineHeight(RenderStyle::initialLineHeight()); } -bool RenderThemeGtk::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintRenderObject(MOZ_GTK_BUTTON, o, i.context, rect, GTK_RELIEF_NORMAL); + if (info.context->paintingDisabled()) + return false; + + GtkWidget* widget = gtkButton(); + IntRect buttonRect(IntPoint(), rect.size()); + IntRect focusRect(buttonRect); + + GtkStateType state = getGtkStateType(object); + gtk_widget_set_state(widget, state); + gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction())); + + if (isFocused(object)) { + if (isEnabled(object)) { +#if !GTK_CHECK_VERSION(2, 22, 0) + GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS); +#endif + g_object_set(widget, "has-focus", TRUE, NULL); + } + + gboolean interiorFocus = 0, focusWidth = 0, focusPadding = 0; + gtk_widget_style_get(widget, + "interior-focus", &interiorFocus, + "focus-line-width", &focusWidth, + "focus-padding", &focusPadding, NULL); + // If we are using exterior focus, we shrink the button rect down before + // drawing. If we are using interior focus we shrink the focus rect. This + // approach originates from the Mozilla theme drawing code (gtk2drawing.c). + if (interiorFocus) { + GtkStyle* style = gtk_widget_get_style(widget); + focusRect.inflateX(-style->xthickness - focusPadding); + focusRect.inflateY(-style->ythickness - focusPadding); + } else { + buttonRect.inflateX(-focusWidth - focusPadding); + buttonRect.inflateY(-focusPadding - focusPadding); + } + } + + WidgetRenderingContext widgetContext(info.context, rect); + GtkShadowType shadowType = state == GTK_STATE_ACTIVE ? GTK_SHADOW_IN : GTK_SHADOW_OUT; + widgetContext.gtkPaintBox(buttonRect, widget, state, shadowType, "button"); + if (isFocused(object)) + widgetContext.gtkPaintFocus(focusRect, widget, state, "button"); + +#if !GTK_CHECK_VERSION(2, 22, 0) + GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS); +#endif + g_object_set(widget, "has-focus", FALSE, NULL); + return false; } static void getComboBoxPadding(RenderStyle* style, int& left, int& top, int& right, int& bottom) @@ -433,13 +465,27 @@ bool RenderThemeGtk::paintMenuListButton(RenderObject* object, const PaintInfo& return paintMenuList(object, info, rect); } +static void setTextInputBorders(RenderStyle* style) +{ + // If this control isn't drawn using the native theme, we don't touch the borders. + if (style->appearance() == NoControlPart) + return; + + // We cannot give a proper rendering when border radius is active, unfortunately. + style->resetBorderRadius(); + + int left = 0, top = 0, right = 0, bottom = 0; + moz_gtk_get_widget_border(MOZ_GTK_ENTRY, &left, &top, &right, &bottom, + gtkTextDirection(style->direction()), TRUE); + style->setBorderLeftWidth(left); + style->setBorderTopWidth(top); + style->setBorderRightWidth(right); + style->setBorderBottomWidth(bottom); +} + void RenderThemeGtk::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { - style->resetBorder(); - style->resetPadding(); - style->setHeight(Length(Auto)); - style->setWhiteSpace(PRE); - adjustMozillaStyle(this, style, MOZ_GTK_ENTRY); + setTextInputBorders(style); } bool RenderThemeGtk::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& rect) @@ -447,6 +493,11 @@ bool RenderThemeGtk::paintTextField(RenderObject* o, const PaintInfo& i, const I return paintRenderObject(MOZ_GTK_ENTRY, o, i.context, rect); } +void RenderThemeGtk::adjustTextAreaStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +{ + setTextInputBorders(style); +} + bool RenderThemeGtk::paintTextArea(RenderObject* o, const PaintInfo& i, const IntRect& r) { return paintTextField(o, i, r); @@ -467,32 +518,33 @@ void RenderThemeGtk::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* s style->resetBorder(); style->resetPadding(); - // FIXME: This should not be hard-coded. - IntSize size = IntSize(14, 14); - style->setWidth(Length(size.width(), Fixed)); - style->setHeight(Length(size.height(), Fixed)); + gint width = 0, height = 0; + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); + style->setWidth(Length(width, Fixed)); + style->setHeight(Length(height, Fixed)); } -static IntRect centerRectVerticallyInParentInputElement(RenderObject* object, const IntRect& rect) +static IntPoint centerRectVerticallyInParentInputElement(RenderObject* object, const IntRect& rect) { - IntRect centeredRect(rect); Node* input = object->node()->shadowAncestorNode(); // Get the renderer of <input> element. - if (!input->renderer()->isBox()) - return centeredRect; + if (!input->renderer()->isBox()) + return rect.topLeft(); // If possible center the y-coordinate of the rect vertically in the parent input element. // We also add one pixel here to ensure that the y coordinate is rounded up for box heights // that are even, which looks in relation to the box text. IntRect inputContentBox = toRenderBox(input->renderer())->absoluteContentBox(); - centeredRect.setY(inputContentBox.y() + (inputContentBox.height() - centeredRect.height() + 1) / 2); - return centeredRect; + + return IntPoint(rect.x(), inputContentBox.y() + (inputContentBox.height() - rect.height() + 1) / 2); } -bool RenderThemeGtk::paintSearchFieldResultsDecoration(RenderObject* object, const PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintSearchFieldResultsDecoration(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - static Image* searchImage = Image::loadPlatformThemeIcon(GTK_STOCK_FIND, rect.width()).releaseRef(); - IntRect centeredRect(centerRectVerticallyInParentInputElement(object, rect)); - i.context->drawImage(searchImage, ColorSpaceDeviceRGB, centeredRect); + GtkStyle* style = gtk_widget_get_style(GTK_WIDGET(gtkEntry())); + IntPoint iconPoint(centerRectVerticallyInParentInputElement(renderObject, rect)); + paintStockIcon(paintInfo.context, iconPoint, style, GTK_STOCK_FIND, + gtkTextDirection(renderObject->style()->direction()), + gtkIconState(renderObject), GTK_ICON_SIZE_MENU); return false; } @@ -501,24 +553,26 @@ void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* select style->resetBorder(); style->resetPadding(); - // FIXME: This should not be hard-coded. - IntSize size = IntSize(14, 14); - style->setWidth(Length(size.width(), Fixed)); - style->setHeight(Length(size.height(), Fixed)); + gint width = 0, height = 0; + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); + style->setWidth(Length(width, Fixed)); + style->setHeight(Length(height, Fixed)); } -bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* object, const PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - // TODO: Brightening up the image on hover is desirable here, I believe. - static Image* cancelImage = Image::loadPlatformThemeIcon(GTK_STOCK_CLEAR, rect.width()).releaseRef(); - IntRect centeredRect(centerRectVerticallyInParentInputElement(object, rect)); - i.context->drawImage(cancelImage, ColorSpaceDeviceRGB, centeredRect); + GtkStyle* style = gtk_widget_get_style(GTK_WIDGET(gtkEntry())); + IntPoint iconPoint(centerRectVerticallyInParentInputElement(renderObject, rect)); + paintStockIcon(paintInfo.context, iconPoint, style, GTK_STOCK_CLEAR, + gtkTextDirection(renderObject->style()->direction()), + gtkIconState(renderObject), GTK_ICON_SIZE_MENU); return false; } void RenderThemeGtk::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { - adjustTextFieldStyle(selector, style, e); + style->setLineHeight(RenderStyle::initialLineHeight()); + setTextInputBorders(style); } bool RenderThemeGtk::paintSearchField(RenderObject* o, const PaintInfo& i, const IntRect& rect) @@ -528,14 +582,30 @@ bool RenderThemeGtk::paintSearchField(RenderObject* o, const PaintInfo& i, const bool RenderThemeGtk::paintSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect) { + if (info.context->paintingDisabled()) + return false; + ControlPart part = object->style()->appearance(); ASSERT(part == SliderHorizontalPart || part == SliderVerticalPart); - GtkThemeWidgetType gtkPart = MOZ_GTK_SCALE_HORIZONTAL; - if (part == SliderVerticalPart) - gtkPart = MOZ_GTK_SCALE_VERTICAL; + // We shrink the trough rect slightly to make room for the focus indicator. + IntRect troughRect(IntPoint(), rect.size()); // This is relative to rect. + GtkWidget* widget = 0; + if (part == SliderVerticalPart) { + widget = gtkVScale(); + troughRect.inflateY(-gtk_widget_get_style(widget)->ythickness); + } else { + widget = gtkHScale(); + troughRect.inflateX(-gtk_widget_get_style(widget)->xthickness); + } + gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction())); + + WidgetRenderingContext widgetContext(info.context, rect); + widgetContext.gtkPaintBox(troughRect, widget, GTK_STATE_ACTIVE, GTK_SHADOW_OUT, "trough"); + if (isFocused(object)) + widgetContext.gtkPaintFocus(IntRect(IntPoint(), rect.size()), widget, getGtkStateType(object), "trough"); - return paintRenderObject(gtkPart, object, info.context, rect); + return false; } void RenderThemeGtk::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* style, Element*) const @@ -545,14 +615,34 @@ void RenderThemeGtk::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* styl bool RenderThemeGtk::paintSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect) { + if (info.context->paintingDisabled()) + return false; + ControlPart part = object->style()->appearance(); ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart); - GtkThemeWidgetType gtkPart = MOZ_GTK_SCALE_THUMB_HORIZONTAL; - if (part == SliderThumbVerticalPart) - gtkPart = MOZ_GTK_SCALE_THUMB_VERTICAL; - - return paintRenderObject(gtkPart, object, info.context, rect); + GtkWidget* widget = 0; + const char* detail = 0; + GtkOrientation orientation; + if (part == SliderThumbVerticalPart) { + widget = gtkVScale(); + detail = "vscale"; + orientation = GTK_ORIENTATION_VERTICAL; + } else { + widget = gtkHScale(); + detail = "hscale"; + orientation = GTK_ORIENTATION_HORIZONTAL; + } + gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction())); + + // Only some themes have slider thumbs respond to clicks and some don't. This information is + // gathered via the 'activate-slider' property, but it's deprecated in GTK+ 2.22 and removed in + // GTK+ 3.x. The drawback of not honoring it is that slider thumbs change color when you click + // on them. + IntRect thumbRect(IntPoint(), rect.size()); + WidgetRenderingContext widgetContext(info.context, rect); + widgetContext.gtkPaintSlider(thumbRect, widget, getGtkStateType(object), GTK_SHADOW_OUT, detail, orientation); + return false; } void RenderThemeGtk::adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle* style, Element*) const @@ -567,14 +657,27 @@ void RenderThemeGtk::adjustSliderThumbSize(RenderObject* o) const if (part == MediaSliderThumbPart) { o->style()->setWidth(Length(m_mediaSliderThumbWidth, Fixed)); o->style()->setHeight(Length(m_mediaSliderThumbHeight, Fixed)); - } else + return; + } + if (part == MediaVolumeSliderThumbPart) + return; #endif - if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) { - gint width, height; - moz_gtk_get_scalethumb_metrics(part == SliderThumbHorizontalPart ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, &width, &height); - o->style()->setWidth(Length(width, Fixed)); - o->style()->setHeight(Length(height, Fixed)); + + GtkWidget* widget = part == SliderThumbHorizontalPart ? gtkHScale() : gtkVScale(); + int length = 0, width = 0; + gtk_widget_style_get(widget, + "slider_length", &length, + "slider_width", &width, + NULL); + + if (part == SliderThumbHorizontalPart) { + o->style()->setWidth(Length(length, Fixed)); + o->style()->setHeight(Length(width, Fixed)); + return; } + ASSERT(part == SliderThumbVerticalPart); + o->style()->setWidth(Length(width, Fixed)); + o->style()->setHeight(Length(length, Fixed)); } Color RenderThemeGtk::platformActiveSelectionBackgroundColor() const @@ -700,17 +803,30 @@ static void gtkStyleSetCallback(GtkWidget* widget, GtkStyle* previous, RenderThe renderTheme->platformColorsDidChange(); } -GtkContainer* RenderThemeGtk::gtkContainer() const +void RenderThemeGtk::setupWidgetAndAddToContainer(GtkWidget* widget, GtkWidget* window) const +{ + gtk_container_add(GTK_CONTAINER(window), widget); + gtk_widget_realize(widget); + g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE)); + + // FIXME: Perhaps this should only be called for the containing window or parent container. + g_signal_connect(widget, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this)); +} + +GtkWidget* RenderThemeGtk::gtkContainer() const { if (m_gtkContainer) return m_gtkContainer; m_gtkWindow = gtk_window_new(GTK_WINDOW_POPUP); - m_gtkContainer = GTK_CONTAINER(gtk_fixed_new()); - g_signal_connect(m_gtkWindow, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this)); - gtk_container_add(GTK_CONTAINER(m_gtkWindow), GTK_WIDGET(m_gtkContainer)); +#ifdef GTK_API_VERSION_2 + gtk_widget_set_colormap(m_gtkWindow, m_themeParts.colormap); +#endif gtk_widget_realize(m_gtkWindow); + gtk_widget_set_name(m_gtkWindow, "MozillaGtkWidget"); + m_gtkContainer = gtk_fixed_new(); + setupWidgetAndAddToContainer(m_gtkContainer, m_gtkWindow); return m_gtkContainer; } @@ -718,12 +834,8 @@ GtkWidget* RenderThemeGtk::gtkButton() const { if (m_gtkButton) return m_gtkButton; - m_gtkButton = gtk_button_new(); - g_signal_connect(m_gtkButton, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this)); - gtk_container_add(gtkContainer(), m_gtkButton); - gtk_widget_realize(m_gtkButton); - + setupWidgetAndAddToContainer(m_gtkButton, gtkContainer()); return m_gtkButton; } @@ -731,12 +843,8 @@ GtkWidget* RenderThemeGtk::gtkEntry() const { if (m_gtkEntry) return m_gtkEntry; - m_gtkEntry = gtk_entry_new(); - g_signal_connect(m_gtkEntry, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this)); - gtk_container_add(gtkContainer(), m_gtkEntry); - gtk_widget_realize(m_gtkEntry); - + setupWidgetAndAddToContainer(m_gtkEntry, gtkContainer()); return m_gtkEntry; } @@ -744,15 +852,29 @@ GtkWidget* RenderThemeGtk::gtkTreeView() const { if (m_gtkTreeView) return m_gtkTreeView; - m_gtkTreeView = gtk_tree_view_new(); - g_signal_connect(m_gtkTreeView, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this)); - gtk_container_add(gtkContainer(), m_gtkTreeView); - gtk_widget_realize(m_gtkTreeView); - + setupWidgetAndAddToContainer(m_gtkTreeView, gtkContainer()); return m_gtkTreeView; } +GtkWidget* RenderThemeGtk::gtkVScale() const +{ + if (m_gtkVScale) + return m_gtkVScale; + m_gtkVScale = gtk_vscale_new(0); + setupWidgetAndAddToContainer(m_gtkVScale, gtkContainer()); + return m_gtkVScale; +} + +GtkWidget* RenderThemeGtk::gtkHScale() const +{ + if (m_gtkHScale) + return m_gtkHScale; + m_gtkHScale = gtk_hscale_new(0); + setupWidgetAndAddToContainer(m_gtkHScale, gtkContainer()); + return m_gtkHScale; +} + GtkWidget* RenderThemeGtk::gtkScrollbar() { return moz_gtk_get_scrollbar_widget(); @@ -761,7 +883,7 @@ GtkWidget* RenderThemeGtk::gtkScrollbar() void RenderThemeGtk::platformColorsDidChange() { #if ENABLE(VIDEO) - initMediaStyling(gtk_rc_get_style(GTK_WIDGET(gtkContainer())), true); + initMediaColors(); #endif RenderTheme::platformColorsDidChange(); } @@ -772,49 +894,50 @@ String RenderThemeGtk::extraMediaControlsStyleSheet() return String(mediaControlsGtkUserAgentStyleSheet, sizeof(mediaControlsGtkUserAgentStyleSheet)); } -static inline bool paintMediaButton(GraphicsContext* context, const IntRect& r, Image* image, Color panelColor, int mediaIconSize) +bool RenderThemeGtk::paintMediaButton(RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, const char* iconName) { - context->fillRect(FloatRect(r), panelColor, ColorSpaceDeviceRGB); - context->drawImage(image, ColorSpaceDeviceRGB, - IntRect(r.x() + (r.width() - mediaIconSize) / 2, - r.y() + (r.height() - mediaIconSize) / 2, - mediaIconSize, mediaIconSize)); + GtkStyle* style = gtk_widget_get_style(GTK_WIDGET(gtkContainer())); + IntPoint iconPoint(rect.x() + (rect.width() - m_mediaIconSize) / 2, + rect.y() + (rect.height() - m_mediaIconSize) / 2); + context->fillRect(FloatRect(rect), m_panelColor, ColorSpaceDeviceRGB); + paintStockIcon(context, iconPoint, style, iconName, gtkTextDirection(renderObject->style()->direction()), + gtkIconState(renderObject), getMediaButtonIconSize(m_mediaIconSize)); return false; } -bool RenderThemeGtk::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaFullscreenButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - return paintMediaButton(paintInfo.context, r, m_fullscreenButton.get(), m_panelColor, m_mediaIconSize); + return paintMediaButton(renderObject, paintInfo.context, rect, GTK_STOCK_FULLSCREEN); } -bool RenderThemeGtk::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaMuteButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o); + HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(renderObject); if (!mediaElement) return false; - return paintMediaButton(paintInfo.context, r, mediaElement->muted() ? m_unmuteButton.get() : m_muteButton.get(), m_panelColor, m_mediaIconSize); + return paintMediaButton(renderObject, paintInfo.context, rect, mediaElement->muted() ? "audio-volume-muted" : "audio-volume-high"); } -bool RenderThemeGtk::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaPlayButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - Node* node = o->node(); + Node* node = renderObject->node(); if (!node) return false; MediaControlPlayButtonElement* button = static_cast<MediaControlPlayButtonElement*>(node); - return paintMediaButton(paintInfo.context, r, button->displayType() == MediaPlayButton ? m_playButton.get() : m_pauseButton.get(), m_panelColor, m_mediaIconSize); + return paintMediaButton(renderObject, paintInfo.context, rect, button->displayType() == MediaPlayButton ? GTK_STOCK_MEDIA_PLAY : GTK_STOCK_MEDIA_PAUSE); } -bool RenderThemeGtk::paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaSeekBackButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - return paintMediaButton(paintInfo.context, r, m_seekBackButton.get(), m_panelColor, m_mediaIconSize); + return paintMediaButton(renderObject, paintInfo.context, rect, GTK_STOCK_MEDIA_REWIND); } -bool RenderThemeGtk::paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaSeekForwardButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - return paintMediaButton(paintInfo.context, r, m_seekForwardButton.get(), m_panelColor, m_mediaIconSize); + return paintMediaButton(renderObject, paintInfo.context, rect, GTK_STOCK_MEDIA_FORWARD); } bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) @@ -852,7 +975,7 @@ bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const PaintInfo& pai rangeRect = trackRect; rangeRect.setWidth(width); } else { - rangeRect.setLocation(IntPoint((start * totalWidth) / mediaDuration, trackRect.y())); + rangeRect.setLocation(IntPoint(trackRect.x() + start / mediaDuration* totalWidth, trackRect.y())); rangeRect.setSize(IntSize(width, trackRect.height())); } |