diff options
Diffstat (limited to 'WebCore/platform/gtk')
-rw-r--r-- | WebCore/platform/gtk/ClipboardGtk.h | 2 | ||||
-rw-r--r-- | WebCore/platform/gtk/DataObjectGtk.h | 4 | ||||
-rw-r--r-- | WebCore/platform/gtk/FileSystemGtk.cpp | 3 | ||||
-rw-r--r-- | WebCore/platform/gtk/GOwnPtrGtk.h | 3 | ||||
-rw-r--r-- | WebCore/platform/gtk/GRefPtrGtk.h | 3 | ||||
-rw-r--r-- | WebCore/platform/gtk/GtkVersioning.c (renamed from WebCore/platform/gtk/GtkVersioning.cpp) | 21 | ||||
-rw-r--r-- | WebCore/platform/gtk/GtkVersioning.h | 11 | ||||
-rw-r--r-- | WebCore/platform/gtk/PasteboardHelper.h | 7 | ||||
-rw-r--r-- | WebCore/platform/gtk/PopupMenuGtk.h | 4 | ||||
-rw-r--r-- | WebCore/platform/gtk/RenderThemeGtk.cpp | 164 | ||||
-rw-r--r-- | WebCore/platform/gtk/RenderThemeGtk.h | 21 | ||||
-rw-r--r-- | WebCore/platform/gtk/ScrollbarGtk.h | 2 | ||||
-rw-r--r-- | WebCore/platform/gtk/ScrollbarThemeGtk.cpp | 323 | ||||
-rw-r--r-- | WebCore/platform/gtk/ScrollbarThemeGtk.h | 44 | ||||
-rw-r--r-- | WebCore/platform/gtk/gtk2drawing.c | 3 |
15 files changed, 483 insertions, 132 deletions
diff --git a/WebCore/platform/gtk/ClipboardGtk.h b/WebCore/platform/gtk/ClipboardGtk.h index 8b8ee38..f0af318 100644 --- a/WebCore/platform/gtk/ClipboardGtk.h +++ b/WebCore/platform/gtk/ClipboardGtk.h @@ -31,8 +31,6 @@ #include "Clipboard.h" #include "DataObjectGtk.h" -typedef struct _GtkClipboard GtkClipboard; - namespace WebCore { class CachedImage; class Frame; diff --git a/WebCore/platform/gtk/DataObjectGtk.h b/WebCore/platform/gtk/DataObjectGtk.h index 6f7149c..e6095da 100644 --- a/WebCore/platform/gtk/DataObjectGtk.h +++ b/WebCore/platform/gtk/DataObjectGtk.h @@ -27,10 +27,6 @@ #include <wtf/text/CString.h> #include <wtf/text/StringHash.h> -typedef struct _GdkPixbuf GdkPixbuf; -typedef struct _GdkDragContext GdkDragContext; -typedef struct _GtkClipboard GtkClipboard; - namespace WebCore { class DataObjectGtk : public RefCounted<DataObjectGtk> { diff --git a/WebCore/platform/gtk/FileSystemGtk.cpp b/WebCore/platform/gtk/FileSystemGtk.cpp index 7ad2a39..6f3fa19 100644 --- a/WebCore/platform/gtk/FileSystemGtk.cpp +++ b/WebCore/platform/gtk/FileSystemGtk.cpp @@ -187,8 +187,7 @@ String pathGetFileName(const String& pathName) String directoryName(const String& path) { /* No null checking needed */ - GOwnPtr<char> tmpFilename(const_cast<char*>(fileSystemRepresentation(path).data())); - GOwnPtr<char> dirname(g_path_get_dirname(tmpFilename.get())); + GOwnPtr<char> dirname(g_path_get_dirname(fileSystemRepresentation(path).data())); return String::fromUTF8(dirname.get()); } diff --git a/WebCore/platform/gtk/GOwnPtrGtk.h b/WebCore/platform/gtk/GOwnPtrGtk.h index 8341661..c5d9cdc 100644 --- a/WebCore/platform/gtk/GOwnPtrGtk.h +++ b/WebCore/platform/gtk/GOwnPtrGtk.h @@ -22,9 +22,6 @@ #include "GOwnPtr.h" -typedef union _GdkEvent GdkEvent; -typedef struct _GtkIconInfo GtkIconInfo; - namespace WTF { template <> void freeOwnedGPtr<GdkEvent>(GdkEvent*); diff --git a/WebCore/platform/gtk/GRefPtrGtk.h b/WebCore/platform/gtk/GRefPtrGtk.h index ea1b089..5e6ab78 100644 --- a/WebCore/platform/gtk/GRefPtrGtk.h +++ b/WebCore/platform/gtk/GRefPtrGtk.h @@ -23,9 +23,6 @@ #include "GRefPtr.h" -typedef struct _GtkTargetList GtkTargetList; -typedef struct _GdkCursor GdkCursor; - namespace WTF { template <> GtkTargetList* refPlatformPtr(GtkTargetList* ptr); diff --git a/WebCore/platform/gtk/GtkVersioning.cpp b/WebCore/platform/gtk/GtkVersioning.c index e7734a8..7dd601e 100644 --- a/WebCore/platform/gtk/GtkVersioning.cpp +++ b/WebCore/platform/gtk/GtkVersioning.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Collabora Ltd. + * Copyright (C) 2010 Igalia, S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,7 +18,6 @@ * Boston, MA 02110-1301, USA. */ -#include "config.h" #include "GtkVersioning.h" #include <gtk/gtk.h> @@ -48,3 +48,22 @@ void gtk_adjustment_configure(GtkAdjustment* adjustment, gdouble value, gdouble gtk_adjustment_value_changed(adjustment); } #endif + +GdkDevice *getDefaultGDKPointerDevice(GdkWindow* window) +{ +#ifndef GTK_API_VERSION_2 + GdkDeviceManager *manager = gdk_display_get_device_manager(gdk_drawable_get_display(window)); + return gdk_device_manager_get_client_pointer(manager); +#else + return gdk_device_get_core_pointer(); +#endif // GTK_API_VERSION_2 +} + +#if !GTK_CHECK_VERSION(2, 17, 3) +static void gdk_window_get_root_coords(GdkWindow* window, gint x, gint y, gint* rootX, gint* rootY) +{ + gdk_window_get_root_origin(window, rootX, rootY); + *rootX = *rootX + x; + *rootY = *rootY + y; +} +#endif diff --git a/WebCore/platform/gtk/GtkVersioning.h b/WebCore/platform/gtk/GtkVersioning.h index 34e6081..eac3cb5 100644 --- a/WebCore/platform/gtk/GtkVersioning.h +++ b/WebCore/platform/gtk/GtkVersioning.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Collabora Ltd. + * Copyright (C) 2010 Igalia, S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,6 +23,8 @@ #include <gtk/gtk.h> +G_BEGIN_DECLS + // Macros to avoid deprecation checking churn #if !GTK_CHECK_VERSION(2, 21, 2) #define gdk_visual_get_depth(visual) (visual)->depth @@ -51,6 +54,10 @@ #define gtk_widget_set_allocation(widget, alloc) ((widget)->allocation = *(alloc)) #endif // GTK_CHECK_VERSION(2, 18, 0) +#if !GTK_CHECK_VERSION(2, 17, 3) +static void gdk_window_get_root_coords(GdkWindow* window, gint x, gint y, gint* rootX, gint* rootY); +#endif //GTK_CHECK_VERSION(2, 17, 3) + #if !GTK_CHECK_VERSION(2, 14, 0) #define gtk_widget_get_window(widget) (widget)->window #define gtk_adjustment_get_value(adj) (adj)->value @@ -67,4 +74,8 @@ void gtk_adjustment_configure(GtkAdjustment* adjustment, gdouble value, gdouble void gtk_adjustment_set_value(GtkAdjustment* adjusment, gdouble value); #endif // GTK_CHECK_VERSION(2, 14, 0) +GdkDevice* getDefaultGDKPointerDevice(GdkWindow* window); + +G_END_DECLS + #endif // GtkVersioning_h diff --git a/WebCore/platform/gtk/PasteboardHelper.h b/WebCore/platform/gtk/PasteboardHelper.h index 33be1a8..bb1b580 100644 --- a/WebCore/platform/gtk/PasteboardHelper.h +++ b/WebCore/platform/gtk/PasteboardHelper.h @@ -32,13 +32,6 @@ #include "Frame.h" -typedef struct _GtkClipboard GtkClipboard; -typedef struct _GtkTargetList GtkTargetList; -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkSelectionData GtkSelectionData; -typedef struct _GdkDragContext GdkDragContext; -typedef struct _GdkAtom* GdkAtom; - namespace WebCore { class DataObjectGtk; diff --git a/WebCore/platform/gtk/PopupMenuGtk.h b/WebCore/platform/gtk/PopupMenuGtk.h index d63e6d9..8848e06 100644 --- a/WebCore/platform/gtk/PopupMenuGtk.h +++ b/WebCore/platform/gtk/PopupMenuGtk.h @@ -29,10 +29,6 @@ #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> -typedef struct _GtkMenu GtkMenu; -typedef struct _GtkMenuItem GtkMenuItem; -typedef struct _GtkWidget GtkWidget; - namespace WebCore { class FrameView; 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 diff --git a/WebCore/platform/gtk/RenderThemeGtk.h b/WebCore/platform/gtk/RenderThemeGtk.h index b9c076d..4e24c97 100644 --- a/WebCore/platform/gtk/RenderThemeGtk.h +++ b/WebCore/platform/gtk/RenderThemeGtk.h @@ -29,21 +29,9 @@ #define RenderThemeGtk_h #include "GRefPtr.h" +#include "gtkdrawing.h" #include "RenderTheme.h" -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkStyle GtkStyle; -typedef struct _GtkContainer GtkContainer; -#ifdef GTK_API_VERSION_2 -typedef struct _GdkRectangle GdkRectangle; -#else -typedef struct _cairo_rectangle_int cairo_rectangle_int_t; -typedef cairo_rectangle_int_t GdkRectangle; -#endif -typedef struct _GdkDrawable GdkDrawable; -typedef struct _GtkBorder GtkBorder; -typedef struct _GtkThemeParts GtkThemeParts; - namespace WebCore { class RenderThemeGtk : public RenderTheme { @@ -95,7 +83,9 @@ public: virtual String extraMediaControlsStyleSheet(); #endif - GtkThemeParts* partsForDrawable(GdkDrawable*) const; + bool paintMozillaGtkWidget(GtkThemeWidgetType, GraphicsContext*, const IntRect&, GtkWidgetState*, int flags, GtkTextDirection = GTK_TEXT_DIR_NONE); + + GtkWidget* gtkScrollbar(); protected: virtual bool paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r); @@ -167,6 +157,9 @@ private: */ GtkContainer* gtkContainer() const; + bool paintRenderObject(GtkThemeWidgetType, RenderObject*, GraphicsContext*, const IntRect& rect, int flags = 0); + GtkThemeParts* partsForDrawable(GdkDrawable*) const; + mutable GtkWidget* m_gtkWindow; mutable GtkContainer* m_gtkContainer; mutable GtkWidget* m_gtkButton; diff --git a/WebCore/platform/gtk/ScrollbarGtk.h b/WebCore/platform/gtk/ScrollbarGtk.h index e02bb50..1a078c9 100644 --- a/WebCore/platform/gtk/ScrollbarGtk.h +++ b/WebCore/platform/gtk/ScrollbarGtk.h @@ -29,8 +29,6 @@ #include "Scrollbar.h" #include <wtf/PassRefPtr.h> -typedef struct _GtkAdjustment GtkAdjustment; - namespace WebCore { class ScrollbarGtk : public Scrollbar { diff --git a/WebCore/platform/gtk/ScrollbarThemeGtk.cpp b/WebCore/platform/gtk/ScrollbarThemeGtk.cpp index fee2c70..b6efe54 100644 --- a/WebCore/platform/gtk/ScrollbarThemeGtk.cpp +++ b/WebCore/platform/gtk/ScrollbarThemeGtk.cpp @@ -26,30 +26,339 @@ #include "config.h" #include "ScrollbarThemeGtk.h" +#include "PlatformMouseEvent.h" +#include "RenderThemeGtk.h" +#include "ScrollView.h" +#include "Scrollbar.h" #include "gtkdrawing.h" #include <gtk/gtk.h> namespace WebCore { +static HashSet<Scrollbar*>* gScrollbars; +static void gtkStyleSetCallback(GtkWidget*, GtkStyle*, ScrollbarThemeGtk*); + ScrollbarTheme* ScrollbarTheme::nativeTheme() { static ScrollbarThemeGtk theme; return &theme; } +ScrollbarThemeGtk::ScrollbarThemeGtk() +{ + updateThemeProperties(); + g_signal_connect(static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->gtkScrollbar(), + "style-set", G_CALLBACK(gtkStyleSetCallback), this); +} + ScrollbarThemeGtk::~ScrollbarThemeGtk() { } -int ScrollbarThemeGtk::scrollbarThickness(ScrollbarControlSize controlSize) +void ScrollbarThemeGtk::registerScrollbar(Scrollbar* scrollbar) +{ + if (!gScrollbars) + gScrollbars = new HashSet<Scrollbar*>; + gScrollbars->add(scrollbar); +} + +void ScrollbarThemeGtk::unregisterScrollbar(Scrollbar* scrollbar) +{ + gScrollbars->remove(scrollbar); + if (gScrollbars->isEmpty()) { + delete gScrollbars; + gScrollbars = 0; + } +} + +void ScrollbarThemeGtk::updateThemeProperties() +{ + MozGtkScrollbarMetrics metrics; + moz_gtk_get_scrollbar_metrics(&metrics); + + m_thumbFatness = metrics.slider_width; + m_troughBorderWidth = metrics.trough_border; + m_stepperSize = metrics.stepper_size; + m_stepperSpacing = metrics.stepper_spacing; + m_minThumbLength = metrics.min_slider_size; + m_troughUnderSteppers = metrics.trough_under_steppers; + + if (!gScrollbars) + return; + + // Update the thickness of every interior frame scrollbar widget. The + // platform-independent scrollbar them code isn't yet smart enough to get + // this information when it paints. + HashSet<Scrollbar*>::iterator end = gScrollbars->end(); + for (HashSet<Scrollbar*>::iterator it = gScrollbars->begin(); it != end; ++it) { + Scrollbar* scrollbar = (*it); + + // Top-level scrollbar i.e. scrollbars who have a parent ScrollView + // with no parent are native, and thus do not need to be resized. + if (!scrollbar->parent() || !scrollbar->parent()->parent()) + return; + + int thickness = scrollbarThickness(scrollbar->controlSize()); + if (scrollbar->orientation() == HorizontalScrollbar) + scrollbar->setFrameRect(IntRect(0, scrollbar->parent()->height() - thickness, scrollbar->width(), thickness)); + else + scrollbar->setFrameRect(IntRect(scrollbar->parent()->width() - thickness, 0, thickness, scrollbar->height())); + } +} + +static void gtkStyleSetCallback(GtkWidget* widget, GtkStyle* previous, ScrollbarThemeGtk* scrollbarTheme) +{ + scrollbarTheme->updateThemeProperties(); +} + +bool ScrollbarThemeGtk::hasThumb(Scrollbar* scrollbar) +{ + // This method is just called as a paint-time optimization to see if + // painting the thumb can be skipped. We don't have to be exact here. + return thumbLength(scrollbar) > 0; +} + +IntRect ScrollbarThemeGtk::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool) +{ + // We do not support multiple steppers per end yet. + if (part == BackButtonEndPart) + return IntRect(); + + IntSize size = buttonSize(scrollbar); + return IntRect(scrollbar->x() + m_troughBorderWidth, scrollbar->y() + m_troughBorderWidth, size.width(), size.height()); +} + +IntRect ScrollbarThemeGtk::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool) +{ + // We do not support multiple steppers per end yet. + if (part == ForwardButtonStartPart) + return IntRect(); + + IntSize size = buttonSize(scrollbar); + int x, y; + if (scrollbar->orientation() == HorizontalScrollbar) { + x = scrollbar->x() + scrollbar->width() - size.width() - m_troughBorderWidth; + y = scrollbar->y() + m_troughBorderWidth; + } else { + x = scrollbar->x() + m_troughBorderWidth; + y = scrollbar->y() + scrollbar->height() - size.height() - m_troughBorderWidth; + } + return IntRect(x, y, size.width(), size.height()); +} + +IntRect ScrollbarThemeGtk::trackRect(Scrollbar* scrollbar, bool) +{ + // The padding along the thumb movement axis (from outside to in) + // is the size of trough border plus the size of the stepper (button) + // plus the size of stepper spacing (the space between the stepper and + // the place where the thumb stops). There is often no stepper spacing. + int movementAxisPadding = m_troughBorderWidth + m_stepperSize + m_stepperSpacing; + + // The fatness of the scrollbar on the non-movement axis. + int thickness = scrollbarThickness(scrollbar->controlSize()); + + if (scrollbar->orientation() == HorizontalScrollbar) { + // Once the scrollbar becomes smaller than the natural size of the + // two buttons, the track disappears. + if (scrollbar->width() < 2 * thickness) + return IntRect(); + return IntRect(scrollbar->x() + movementAxisPadding, scrollbar->y(), scrollbar->width() - (2 * movementAxisPadding), thickness); + } + + if (scrollbar->height() < 2 * thickness) + return IntRect(); + return IntRect(scrollbar->x(), scrollbar->y() + movementAxisPadding, thickness, scrollbar->height() - (2 * movementAxisPadding)); +} + +void ScrollbarThemeGtk::paintTrackBackground(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) +{ + GtkWidgetState state; + state.focused = FALSE; + state.isDefault = FALSE; + state.canDefault = FALSE; + state.disabled = FALSE; + state.active = FALSE; + state.inHover = FALSE; + + // Paint the track background. If the trough-under-steppers property is true, this + // should be the full size of the scrollbar, but if is false, it should only be the + // track rect. + IntRect fullScrollbarRect = rect; + if (m_troughUnderSteppers) + fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height()); + + GtkThemeWidgetType type = scrollbar->orientation() == VerticalScrollbar ? MOZ_GTK_SCROLLBAR_TRACK_VERTICAL : MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL; + static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(type, context, fullScrollbarRect, &state, 0); +} + +void ScrollbarThemeGtk::paintScrollbarBackground(GraphicsContext* context, Scrollbar* scrollbar) +{ + GtkWidgetState state; + state.focused = FALSE; + state.isDefault = FALSE; + state.canDefault = FALSE; + state.disabled = FALSE; + state.active = TRUE; + state.inHover = FALSE; + + IntRect fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height()); + static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(MOZ_GTK_SCROLLED_WINDOW, context, fullScrollbarRect, &state, 0); +} + +void ScrollbarThemeGtk::paintThumb(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) +{ + GtkWidgetState state; + state.focused = FALSE; + state.isDefault = FALSE; + state.canDefault = FALSE; + state.disabled = FALSE; + state.active = scrollbar->pressedPart() == ThumbPart; + state.inHover = scrollbar->hoveredPart() == ThumbPart; + state.maxpos = scrollbar->maximum(); + state.curpos = scrollbar->currentPos(); + + GtkThemeWidgetType type = scrollbar->orientation() == VerticalScrollbar ? MOZ_GTK_SCROLLBAR_THUMB_VERTICAL : MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL; + static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(type, context, rect, &state, 0); +} + +IntRect ScrollbarThemeGtk::thumbRect(Scrollbar* scrollbar, const IntRect& unconstrainedTrackRect) +{ + IntRect trackRect = constrainTrackRectToTrackPieces(scrollbar, unconstrainedTrackRect); + int thumbPos = thumbPosition(scrollbar); + if (scrollbar->orientation() == HorizontalScrollbar) + return IntRect(trackRect.x() + thumbPos, trackRect.y() + (trackRect.height() - m_thumbFatness) / 2, thumbLength(scrollbar), m_thumbFatness); + + // VerticalScrollbar + return IntRect(trackRect.x() + (trackRect.width() - m_thumbFatness) / 2, trackRect.y() + thumbPos, m_thumbFatness, thumbLength(scrollbar)); +} + +bool ScrollbarThemeGtk::paint(Scrollbar* scrollbar, GraphicsContext* graphicsContext, const IntRect& damageRect) { - static int size; - if (!size) { - MozGtkScrollbarMetrics metrics; - moz_gtk_get_scrollbar_metrics(&metrics); - size = metrics.slider_width; + // Create the ScrollbarControlPartMask based on the damageRect + ScrollbarControlPartMask scrollMask = NoPart; + + IntRect backButtonStartPaintRect; + IntRect backButtonEndPaintRect; + IntRect forwardButtonStartPaintRect; + IntRect forwardButtonEndPaintRect; + if (hasButtons(scrollbar)) { + backButtonStartPaintRect = backButtonRect(scrollbar, BackButtonStartPart, true); + if (damageRect.intersects(backButtonStartPaintRect)) + scrollMask |= BackButtonStartPart; + backButtonEndPaintRect = backButtonRect(scrollbar, BackButtonEndPart, true); + if (damageRect.intersects(backButtonEndPaintRect)) + scrollMask |= BackButtonEndPart; + forwardButtonStartPaintRect = forwardButtonRect(scrollbar, ForwardButtonStartPart, true); + if (damageRect.intersects(forwardButtonStartPaintRect)) + scrollMask |= ForwardButtonStartPart; + forwardButtonEndPaintRect = forwardButtonRect(scrollbar, ForwardButtonEndPart, true); + if (damageRect.intersects(forwardButtonEndPaintRect)) + scrollMask |= ForwardButtonEndPart; + } + + IntRect trackPaintRect = trackRect(scrollbar, true); + if (damageRect.intersects(trackPaintRect)) + scrollMask |= TrackBGPart; + + if (m_troughUnderSteppers && (scrollMask & BackButtonStartPart + || scrollMask & BackButtonEndPart + || scrollMask & ForwardButtonStartPart + || scrollMask & ForwardButtonEndPart)) + scrollMask |= TrackBGPart; + + bool thumbPresent = hasThumb(scrollbar); + IntRect currentThumbRect; + if (thumbPresent) { + IntRect track = trackRect(scrollbar, false); + currentThumbRect = thumbRect(scrollbar, track); + if (damageRect.intersects(currentThumbRect)) + scrollMask |= ThumbPart; } - return size; + + // Paint the scrollbar background (only used by custom CSS scrollbars). + paintScrollbarBackground(graphicsContext, scrollbar); + + if (scrollMask & TrackBGPart) + paintTrackBackground(graphicsContext, scrollbar, trackPaintRect); + + // Paint the back and forward buttons. + if (scrollMask & BackButtonStartPart) + paintButton(graphicsContext, scrollbar, backButtonStartPaintRect, BackButtonStartPart); + if (scrollMask & BackButtonEndPart) + paintButton(graphicsContext, scrollbar, backButtonEndPaintRect, BackButtonEndPart); + if (scrollMask & ForwardButtonStartPart) + paintButton(graphicsContext, scrollbar, forwardButtonStartPaintRect, ForwardButtonStartPart); + if (scrollMask & ForwardButtonEndPart) + paintButton(graphicsContext, scrollbar, forwardButtonEndPaintRect, ForwardButtonEndPart); + + // Paint the thumb. + if (scrollMask & ThumbPart) + paintThumb(graphicsContext, scrollbar, currentThumbRect); + + return true; +} + +void ScrollbarThemeGtk::paintButton(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part) +{ + int flags = 0; + if (scrollbar->orientation() == VerticalScrollbar) + flags |= MOZ_GTK_STEPPER_VERTICAL; + + if (part == ForwardButtonEndPart) { + flags |= MOZ_GTK_STEPPER_DOWN; + flags |= MOZ_GTK_STEPPER_BOTTOM; + } + + GtkWidgetState state; + state.focused = TRUE; + state.isDefault = TRUE; + state.canDefault = TRUE; + + if ((BackButtonStartPart == part && scrollbar->currentPos()) + || (ForwardButtonEndPart == part && scrollbar->currentPos() != scrollbar->maximum())) { + state.disabled = FALSE; + state.active = part == scrollbar->pressedPart(); + state.inHover = part == scrollbar->hoveredPart(); + } else { + state.disabled = TRUE; + state.active = FALSE; + state.inHover = FALSE; + } + + static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(MOZ_GTK_SCROLLBAR_BUTTON, context, rect, &state, flags); +} + +void ScrollbarThemeGtk::paintScrollCorner(ScrollView* view, GraphicsContext* context, const IntRect& cornerRect) +{ + // ScrollbarThemeComposite::paintScrollCorner incorrectly assumes that the + // ScrollView is a FrameView (see FramelessScrollView), so we cannot let + // that code run. For FrameView's this is correct since we don't do custom + // scrollbar corner rendering, which ScrollbarThemeComposite supports. + ScrollbarTheme::paintScrollCorner(view, context, cornerRect); +} + +bool ScrollbarThemeGtk::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& event) +{ + return (event.shiftKey() && event.button() == LeftButton) || (event.button() == MiddleButton); +} + +int ScrollbarThemeGtk::scrollbarThickness(ScrollbarControlSize) +{ + return m_thumbFatness + (m_troughBorderWidth * 2); +} + +IntSize ScrollbarThemeGtk::buttonSize(Scrollbar* scrollbar) +{ + if (scrollbar->orientation() == VerticalScrollbar) + return IntSize(m_thumbFatness, m_stepperSize); + + // HorizontalScrollbar + return IntSize(m_stepperSize, m_thumbFatness); +} + +int ScrollbarThemeGtk::minimumThumbLength(Scrollbar* scrollbar) +{ + return m_minThumbLength; } } diff --git a/WebCore/platform/gtk/ScrollbarThemeGtk.h b/WebCore/platform/gtk/ScrollbarThemeGtk.h index 618da35..eff2fee 100644 --- a/WebCore/platform/gtk/ScrollbarThemeGtk.h +++ b/WebCore/platform/gtk/ScrollbarThemeGtk.h @@ -26,20 +26,48 @@ #ifndef ScrollbarThemeGtk_h #define ScrollbarThemeGtk_h -#include "ScrollbarTheme.h" - -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkStyle GtkStyle; -typedef struct _GtkContainer GtkContainer; -typedef struct _GtkBorder GtkBorder; +#include "ScrollbarThemeComposite.h" namespace WebCore { -class ScrollbarThemeGtk : public ScrollbarTheme { +class Scrollbar; + +class ScrollbarThemeGtk : public ScrollbarThemeComposite { public: + ScrollbarThemeGtk(); virtual ~ScrollbarThemeGtk(); - virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar); + virtual bool hasButtons(Scrollbar*) { return true; } + virtual bool hasThumb(Scrollbar*); + virtual IntRect backButtonRect(Scrollbar*, ScrollbarPart, bool); + virtual IntRect forwardButtonRect(Scrollbar*, ScrollbarPart, bool); + virtual IntRect trackRect(Scrollbar*, bool); + IntRect thumbRect(Scrollbar*, const IntRect& unconstrainedTrackRect); + bool paint(Scrollbar*, GraphicsContext*, const IntRect& damageRect); + void paintScrollbarBackground(GraphicsContext*, Scrollbar*); + void paintTrackBackground(GraphicsContext*, Scrollbar*, const IntRect&); + void paintThumb(GraphicsContext*, Scrollbar*, const IntRect&); + virtual void paintButton(GraphicsContext*, Scrollbar*, const IntRect&, ScrollbarPart); + virtual void paintScrollCorner(ScrollView*, GraphicsContext*, const IntRect&); + virtual bool shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent&); + virtual int scrollbarThickness(ScrollbarControlSize); + virtual IntSize buttonSize(Scrollbar*); + virtual int minimumThumbLength(Scrollbar*); + + // TODO: These are the default GTK+ values. At some point we should pull these from the theme itself. + virtual double initialAutoscrollTimerDelay() { return 0.20; } + virtual double autoscrollTimerDelay() { return 0.02; } + void updateThemeProperties(); + void registerScrollbar(Scrollbar*); + void unregisterScrollbar(Scrollbar*); + +protected: + int m_thumbFatness; + int m_troughBorderWidth; + int m_stepperSize; + int m_stepperSpacing; + int m_minThumbLength; + bool m_troughUnderSteppers; }; } diff --git a/WebCore/platform/gtk/gtk2drawing.c b/WebCore/platform/gtk/gtk2drawing.c index 349bde0..b33fb1f 100644 --- a/WebCore/platform/gtk/gtk2drawing.c +++ b/WebCore/platform/gtk/gtk2drawing.c @@ -46,10 +46,7 @@ #include <gdk/gdkprivate.h> #include "gtkdrawing.h" - -#include "Assertions.h" #include "GtkVersioning.h" - #include <math.h> #include <string.h> |