diff options
Diffstat (limited to 'WebCore/platform/gtk/RenderThemeGtk.cpp')
-rw-r--r-- | WebCore/platform/gtk/RenderThemeGtk.cpp | 164 |
1 files changed, 92 insertions, 72 deletions
diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp index 5019f35..9329179 100644 --- a/WebCore/platform/gtk/RenderThemeGtk.cpp +++ b/WebCore/platform/gtk/RenderThemeGtk.cpp @@ -34,8 +34,11 @@ #include "HTMLNames.h" #include "MediaControlElements.h" #include "NotImplemented.h" +#include "PlatformMouseEvent.h" #include "RenderBox.h" #include "RenderObject.h" +#include "Scrollbar.h" +#include "TimeRanges.h" #include "UserAgentStyleSheets.h" #include "gtkdrawing.h" #include <gdk/gdk.h> @@ -281,55 +284,24 @@ static void adjustMozillaStyle(const RenderThemeGtk* theme, RenderStyle* style, style->setPaddingBottom(Length(ypadding + bottom, Fixed)); } -static void setMozillaState(const RenderTheme* theme, GtkThemeWidgetType type, RenderObject* o, GtkWidgetState* state) -{ - state->active = theme->isPressed(o); - state->focused = theme->isFocused(o); - state->inHover = theme->isHovered(o); - // FIXME: Disabled does not always give the correct appearance for ReadOnly - state->disabled = !theme->isEnabled(o) || theme->isReadOnlyControl(o); - state->isDefault = false; - state->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) - state->depressed = theme->isPressed(o); - else - state->depressed = false; -} - -static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetType type, RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintMozillaGtkWidget(GtkThemeWidgetType type, GraphicsContext* context, const IntRect& rect, GtkWidgetState* widgetState, int flags, GtkTextDirection textDirection) { // Painting is disabled so just claim to have succeeded - if (i.context->paintingDisabled()) + if (context->paintingDisabled()) return false; - GtkWidgetState widgetState; - setMozillaState(theme, type, o, &widgetState); - - // We might want to make setting flags the caller's job at some point rather than doing it here. - int flags = 0; - if (type == MOZ_GTK_BUTTON) - flags = GTK_RELIEF_NORMAL; - else if (type == MOZ_GTK_CHECKBUTTON || type == MOZ_GTK_RADIOBUTTON) - flags = theme->isChecked(o); - - PlatformRefPtr<GdkDrawable> drawable(i.context->gdkDrawable()); + PlatformRefPtr<GdkDrawable> drawable(context->gdkDrawable()); GdkRectangle paintRect, clipRect; if (drawable) { - AffineTransform ctm = i.context->getCTM(); + AffineTransform ctm = context->getCTM(); IntPoint pos = ctm.mapPoint(rect.location()); paintRect = IntRect(pos.x(), pos.y(), rect.width(), rect.height()); // Intersect the cairo rectangle with the target widget region. This will // prevent the theme drawing code from drawing into regions that cairo will // clip anyway. - cairo_t* cr = i.context->platformContext(); double clipX1, clipX2, clipY1, clipY2; - cairo_clip_extents(cr, &clipX1, &clipY1, &clipX2, &clipY2); + cairo_clip_extents(context->platformContext(), &clipX1, &clipY1, &clipX2, &clipY2); IntPoint clipPos = ctm.mapPoint(IntPoint(clipX1, clipY1)); clipRect.width = clipX2 - clipX1; @@ -346,13 +318,13 @@ static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetTyp paintRect = clipRect = IntRect(0, 0, rect.width(), rect.height()); } - moz_gtk_use_theme_parts(theme->partsForDrawable(drawable.get())); - bool success = moz_gtk_widget_paint(type, drawable.get(), &paintRect, &clipRect, &widgetState, flags, gtkTextDirection(o->style()->direction())) == MOZ_GTK_SUCCESS; + moz_gtk_use_theme_parts(partsForDrawable(drawable.get())); + bool success = moz_gtk_widget_paint(type, drawable.get(), &paintRect, &clipRect, widgetState, flags, textDirection) == MOZ_GTK_SUCCESS; // If the drawing was successful and we rendered onto a pixmap, copy the // results back to the original GraphicsContext. - if (success && !i.context->gdkDrawable()) { - cairo_t* cairoContext = i.context->platformContext(); + if (success && !context->gdkDrawable()) { + cairo_t* cairoContext = context->platformContext(); cairo_save(cairoContext); gdk_cairo_set_source_pixmap(cairoContext, drawable.get(), rect.x(), rect.y()); cairo_paint(cairoContext); @@ -362,6 +334,34 @@ static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetTyp return !success; } +bool RenderThemeGtk::paintRenderObject(GtkThemeWidgetType type, RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, int flags) +{ + // Painting is disabled so just claim to have succeeded + if (context->paintingDisabled()) + return false; + + GtkWidgetState widgetState; + widgetState.active = isPressed(renderObject); + widgetState.focused = isFocused(renderObject); + widgetState.inHover = isHovered(renderObject); + + // FIXME: Disabled does not always give the correct appearance for ReadOnly + 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; + + GtkTextDirection textDirection = gtkTextDirection(renderObject->style()->direction()); + return paintMozillaGtkWidget(type, context, rect, &widgetState, flags, textDirection); +} + static void setButtonPadding(RenderStyle* style) { // FIXME: This looks incorrect. @@ -411,7 +411,7 @@ void RenderThemeGtk::setCheckboxSize(RenderStyle* style) const bool RenderThemeGtk::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - return paintMozillaGtkWidget(this, MOZ_GTK_CHECKBUTTON, o, i, rect); + return paintRenderObject(MOZ_GTK_CHECKBUTTON, o, i.context, rect, isChecked(o)); } void RenderThemeGtk::setRadioSize(RenderStyle* style) const @@ -421,7 +421,7 @@ void RenderThemeGtk::setRadioSize(RenderStyle* style) const bool RenderThemeGtk::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - return paintMozillaGtkWidget(this, MOZ_GTK_RADIOBUTTON, o, i, rect); + return paintRenderObject(MOZ_GTK_RADIOBUTTON, o, i.context, rect, isChecked(o)); } void RenderThemeGtk::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const @@ -442,7 +442,7 @@ void RenderThemeGtk::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* bool RenderThemeGtk::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - return paintMozillaGtkWidget(this, MOZ_GTK_BUTTON, o, i, rect); + return paintRenderObject(MOZ_GTK_BUTTON, o, i.context, rect, GTK_RELIEF_NORMAL); } void RenderThemeGtk::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const @@ -456,7 +456,7 @@ void RenderThemeGtk::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle bool RenderThemeGtk::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - return paintMozillaGtkWidget(this, MOZ_GTK_DROPDOWN, o, i, rect); + return paintRenderObject(MOZ_GTK_DROPDOWN, o, i.context, rect); } void RenderThemeGtk::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const @@ -470,7 +470,7 @@ void RenderThemeGtk::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyl bool RenderThemeGtk::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - return paintMozillaGtkWidget(this, MOZ_GTK_ENTRY, o, i, rect); + return paintRenderObject(MOZ_GTK_ENTRY, o, i.context, rect); } bool RenderThemeGtk::paintTextArea(RenderObject* o, const PaintInfo& i, const IntRect& r) @@ -550,7 +550,7 @@ bool RenderThemeGtk::paintSliderTrack(RenderObject* object, const PaintInfo& inf if (part == SliderVerticalPart) gtkPart = MOZ_GTK_SCALE_VERTICAL; - return paintMozillaGtkWidget(this, gtkPart, object, info, rect); + return paintRenderObject(gtkPart, object, info.context, rect); } void RenderThemeGtk::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* style, Element*) const @@ -567,7 +567,7 @@ bool RenderThemeGtk::paintSliderThumb(RenderObject* object, const PaintInfo& inf if (part == SliderThumbVerticalPart) gtkPart = MOZ_GTK_SCALE_THUMB_VERTICAL; - return paintMozillaGtkWidget(this, gtkPart, object, info, rect); + return paintRenderObject(gtkPart, object, info.context, rect); } void RenderThemeGtk::adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle* style, Element*) const @@ -732,6 +732,11 @@ GtkWidget* RenderThemeGtk::gtkTreeView() const return m_gtkTreeView; } +GtkWidget* RenderThemeGtk::gtkScrollbar() +{ + return moz_gtk_get_scrollbar_widget(); +} + void RenderThemeGtk::platformColorsDidChange() { #if ENABLE(VIDEO) @@ -806,33 +811,48 @@ bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const PaintInfo& pai return false; // Draw the buffered ranges. This code is highly inspired from - // Chrome. - // FIXME: Draw multiple ranges if there are multiple buffered - // ranges. The current implementation of the player is always - // buffering a single range anyway. - IntRect bufferedRect = r; - bufferedRect.inflate(-style->borderLeftWidth()); - bufferedRect.setWidth((bufferedRect.width() * mediaElement->percentLoaded())); - - // Don't bother drawing an empty area. - if (bufferedRect.isEmpty()) - return false; - - IntPoint sliderTopLeft = bufferedRect.location(); - IntPoint sliderTopRight = sliderTopLeft; - sliderTopRight.move(0, bufferedRect.height()); - - RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight); - Color startColor = m_panelColor; - gradient->addColorStop(0.0, startColor); - gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha())); + // Chrome for the gradient code. + float mediaDuration = mediaElement->duration(); + RefPtr<TimeRanges> timeRanges = mediaElement->buffered(); + IntRect trackRect = r; + int totalWidth = trackRect.width(); + trackRect.inflate(-style->borderLeftWidth()); context->save(); context->setStrokeStyle(NoStroke); - context->setFillGradient(gradient); - context->fillRect(bufferedRect); - context->restore(); + for (unsigned index = 0; index < timeRanges->length(); ++index) { + ExceptionCode ignoredException; + float start = timeRanges->start(index, ignoredException); + float end = timeRanges->end(index, ignoredException); + int width = ((end - start) * totalWidth) / mediaDuration; + IntRect rangeRect; + if (!index) { + rangeRect = trackRect; + rangeRect.setWidth(width); + } else { + rangeRect.setLocation(IntPoint((start * totalWidth) / mediaDuration, trackRect.y())); + rangeRect.setSize(IntSize(width, trackRect.height())); + } + + // Don't bother drawing empty range. + if (rangeRect.isEmpty()) + continue; + + IntPoint sliderTopLeft = rangeRect.location(); + IntPoint sliderTopRight = sliderTopLeft; + sliderTopRight.move(0, rangeRect.height()); + + RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight); + Color startColor = m_panelColor; + gradient->addColorStop(0.0, startColor); + gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha())); + + context->setFillGradient(gradient); + context->fillRect(rangeRect); + } + + context->restore(); return false; } @@ -873,7 +893,7 @@ bool RenderThemeGtk::paintProgressBar(RenderObject* renderObject, const PaintInf if (!progressBarWidget) return true; - if (paintMozillaGtkWidget(this, MOZ_GTK_PROGRESSBAR, renderObject, paintInfo, rect)) + if (paintRenderObject(MOZ_GTK_PROGRESSBAR, renderObject, paintInfo.context, rect)) return true; IntRect chunkRect(rect); @@ -888,7 +908,7 @@ bool RenderThemeGtk::paintProgressBar(RenderObject* renderObject, const PaintInf else chunkRect.setX(chunkRect.x() + style->xthickness); - return paintMozillaGtkWidget(this, MOZ_GTK_PROGRESS_CHUNK, renderObject, paintInfo, chunkRect); + return paintRenderObject(MOZ_GTK_PROGRESS_CHUNK, renderObject, paintInfo.context, chunkRect); } #endif |