Source/WebCore/ChangeLog

 12011-01-11 Carlos Garcia Campos <cgarcia@igalia.com>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 [GTK] Implement spin buttons in RenderThemeGtk
 6 https://bugs.webkit.org/show_bug.cgi?id=51454
 7
 8 Paint inner up/down buttons for spin button elements when building
 9 with GTK+ 3.x.
 10
 11 * platform/gtk/RenderThemeGtk.h:
 12 * platform/gtk/RenderThemeGtk2.cpp:
 13 (WebCore::RenderThemeGtk::adjustInnerSpinButtonStyle):
 14 (WebCore::RenderThemeGtk::paintInnerSpinButton):
 15 * platform/gtk/RenderThemeGtk3.cpp:
 16 (WebCore::spinButtonArrowSize):
 17 (WebCore::RenderThemeGtk::adjustInnerSpinButtonStyle):
 18 (WebCore::paintSpinArrowButton):
 19 (WebCore::RenderThemeGtk::paintInnerSpinButton):
 20
1212010-10-10 David Hyatt <hyatt@apple.com>
222
323 Reviewed by Simon Fraser.

Source/WebCore/platform/gtk/RenderThemeGtk.h

@@protected:
166166 virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&);
167167#endif
168168
 169 virtual void adjustInnerSpinButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
 170 virtual bool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&);
 171
169172private:
170173 void platformInit();
171174#if ENABLE(VIDEO)

Source/WebCore/platform/gtk/RenderThemeGtk2.cpp

@@bool RenderThemeGtk::paintProgressBar(RenderObject* renderObject, const PaintInf
423423}
424424#endif
425425
 426void RenderThemeGtk::adjustInnerSpinButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const
 427{
 428}
 429
 430bool RenderThemeGtk::paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&)
 431{
 432 return true;
 433}
 434
426435GRefPtr<GdkPixbuf> RenderThemeGtk::getStockIcon(GType widgetType, const char* iconName, gint direction, gint state, gint iconSize)
427436{
428437 ASSERT(widgetType == GTK_TYPE_CONTAINER || widgetType == GTK_TYPE_ENTRY);

Source/WebCore/platform/gtk/RenderThemeGtk3.cpp

@@namespace WebCore {
4848
4949// This is the default value defined by GTK+, where it was defined as MIN_ARROW_SIZE in gtkarrow.c.
5050static const int minArrowSize = 15;
 51// This is the default value defined by GTK+, where it was defined as MIN_ARROW_WIDTH in gtkspinbutton.c.
 52static const int minSpinButtonArrowSize = 6;
5153
5254typedef HashMap<GType, GRefPtr<GtkStyleContext> > StyleContextMap;
5355static StyleContextMap& styleContextMap();

@@bool RenderThemeGtk::paintProgressBar(RenderObject* renderObject, const PaintInf
755757}
756758#endif
757759
 760static gint spinButtonArrowSize(GtkStyleContext* context)
 761{
 762 const PangoFontDescription* fontDesc = gtk_style_context_get_font(context, static_cast<GtkStateFlags>(0));
 763 gint fontSize = pango_font_description_get_size(fontDesc);
 764 gint arrowSize = max(PANGO_PIXELS(fontSize), minSpinButtonArrowSize);
 765
 766 return arrowSize - arrowSize % 2; // Force even.
 767}
 768
 769void RenderThemeGtk::adjustInnerSpinButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
 770{
 771 GtkStyleContext* context = getStyleContext(GTK_TYPE_SPIN_BUTTON);
 772
 773 GtkBorder padding;
 774 gtk_style_context_get_padding(context, static_cast<GtkStateFlags>(0), &padding);
 775
 776 int width = spinButtonArrowSize(context) + padding.left + padding.right;
 777 style->setWidth(Length(width, Fixed));
 778 style->setMinWidth(Length(width, Fixed));
 779}
 780
 781static void paintSpinArrowButton(RenderTheme* theme, GtkStyleContext* context, RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect, GtkArrowType arrowType)
 782{
 783 ASSERT(arrowType == GTK_ARROW_UP || arrowType == GTK_ARROW_DOWN);
 784
 785 gtk_style_context_save(context);
 786 gtk_style_context_add_class(context, GTK_STYLE_CLASS_BUTTON);
 787
 788 GtkTextDirection direction = gtk_style_context_get_direction(context);
 789 guint state = static_cast<guint>(gtk_style_context_get_state(context));
 790 if (!(state & GTK_STATE_FLAG_INSENSITIVE)) {
 791 if (theme->isPressed(renderObject)) {
 792 if ((arrowType == GTK_ARROW_UP && theme->isSpinUpButtonPartPressed(renderObject))
 793 || (arrowType == GTK_ARROW_DOWN && !theme->isSpinUpButtonPartPressed(renderObject)))
 794 state |= GTK_STATE_FLAG_ACTIVE;
 795 } else if (theme->isHovered(renderObject)) {
 796 if ((arrowType == GTK_ARROW_UP && theme->isSpinUpButtonPartHovered(renderObject))
 797 || (arrowType == GTK_ARROW_DOWN && !theme->isSpinUpButtonPartHovered(renderObject)))
 798 state |= GTK_STATE_FLAG_PRELIGHT;
 799 }
 800 }
 801 gtk_style_context_set_state(context, static_cast<GtkStateFlags>(state));
 802
 803 // Paint button.
 804 IntRect buttonRect(rect);
 805 guint junction = gtk_style_context_get_junction_sides(context);
 806 if (arrowType == GTK_ARROW_UP)
 807 junction |= GTK_JUNCTION_BOTTOM;
 808 else {
 809 junction |= GTK_JUNCTION_TOP;
 810 buttonRect.move(0, rect.height() / 2);
 811 }
 812 buttonRect.setHeight(rect.height() / 2);
 813 gtk_style_context_set_junction_sides(context, static_cast<GtkJunctionSides>(junction));
 814
 815 gtk_render_background(context, paintInfo.context->platformContext(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
 816 gtk_render_frame(context, paintInfo.context->platformContext(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
 817
 818 // Paint arrow centered inside button.
 819 IntRect arrowRect;
 820 gdouble angle;
 821 if (arrowType == GTK_ARROW_UP) {
 822 angle = 0;
 823 arrowRect.setY(rect.y());
 824 arrowRect.setHeight(rect.height() / 2 - 2);
 825 } else {
 826 angle = G_PI;
 827 arrowRect.setY(rect.y() + buttonRect.y());
 828 arrowRect.setHeight(rect.height() - arrowRect.y() - 2);
 829 }
 830 arrowRect.setWidth(rect.width() - 3);
 831 if (direction == GTK_TEXT_DIR_LTR)
 832 arrowRect.setX(rect.x() + 1);
 833 else
 834 arrowRect.setX(rect.x() + 2);
 835
 836 gint width = arrowRect.width() / 2;
 837 width -= width % 2 - 1; // Force odd.
 838 gint height = (width + 1) / 2;
 839
 840 arrowRect.move((arrowRect.width() - width) / 2, (arrowRect.height() - height) / 2);
 841 gtk_render_arrow(context, paintInfo.context->platformContext(), angle, arrowRect.x(), arrowRect.y(), width);
 842
 843 gtk_style_context_restore(context);
 844}
 845
 846bool RenderThemeGtk::paintInnerSpinButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
 847{
 848 GtkStyleContext* context = getStyleContext(GTK_TYPE_SPIN_BUTTON);
 849 gtk_style_context_save(context);
 850
 851 GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style()->direction()));
 852 gtk_style_context_set_direction(context, direction);
 853 gtk_style_context_set_junction_sides(context, direction == GTK_TEXT_DIR_RTL ? GTK_JUNCTION_RIGHT : GTK_JUNCTION_LEFT);
 854
 855 guint flags = 0;
 856 if (!isEnabled(renderObject) || isReadOnlyControl(renderObject))
 857 flags |= GTK_STATE_FLAG_INSENSITIVE;
 858 else if (isFocused(renderObject))
 859 flags |= GTK_STATE_FLAG_FOCUSED;
 860 gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
 861 gtk_style_context_remove_class(context, GTK_STYLE_CLASS_ENTRY);
 862
 863 paintSpinArrowButton(this, context, renderObject, paintInfo, rect, GTK_ARROW_UP);
 864 paintSpinArrowButton(this, context, renderObject, paintInfo, rect, GTK_ARROW_DOWN);
 865
 866 gtk_style_context_restore(context);
 867
 868 return false;
 869}
 870
758871GRefPtr<GdkPixbuf> RenderThemeGtk::getStockIcon(GType widgetType, const char* iconName, gint direction, gint state, gint iconSize)
759872{
760873 GtkStyleContext* context = getStyleContext(widgetType);