Changeset 27398 in webkit


Ignore:
Timestamp:
Nov 3, 2007 7:33:25 AM (16 years ago)
Author:
alp
Message:

Reviewed by Adam Roben.

RenderThemeGtk implementation based on Mozilla's GTK+ style code

There is still work needed to complete this feature.

Location:
trunk/WebCore
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r27397 r27398  
     12007-11-03  Alp Toker  <alp@atoker.com>
     2
     3        Reviewed by Adam Roben.
     4
     5        RenderThemeGtk implementation based on Mozilla's GTK+ style code
     6
     7        There is still work needed to complete this feature.
     8
     9        * WebCore.pro:
     10        * platform/gtk/RenderThemeGtk.cpp:
     11        (WebCore::theme):
     12        (WebCore::RenderThemeGtk::RenderThemeGtk):
     13        (WebCore::supportsFocus):
     14        (WebCore::RenderThemeGtk::supportsFocusRing):
     15        (WebCore::RenderThemeGtk::controlSupportsTints):
     16        (WebCore::RenderThemeGtk::baselinePosition):
     17        (WebCore::adjustMozStyle):
     18        (WebCore::setMozState):
     19        (WebCore::paintMozWidget):
     20        (WebCore::setButtonPadding):
     21        (WebCore::setToggleSize):
     22        (WebCore::RenderThemeGtk::setCheckboxSize):
     23        (WebCore::RenderThemeGtk::paintCheckbox):
     24        (WebCore::RenderThemeGtk::setRadioSize):
     25        (WebCore::RenderThemeGtk::paintRadio):
     26        (WebCore::RenderThemeGtk::adjustButtonStyle):
     27        (WebCore::RenderThemeGtk::paintButton):
     28        (WebCore::RenderThemeGtk::adjustMenuListStyle):
     29        (WebCore::RenderThemeGtk::paintMenuList):
     30        (WebCore::RenderThemeGtk::adjustTextFieldStyle):
     31        (WebCore::RenderThemeGtk::paintTextField):
     32        (WebCore::RenderThemeGtk::adjustSearchFieldResultsButtonStyle):
     33        (WebCore::RenderThemeGtk::paintSearchFieldResultsButton):
     34        (WebCore::RenderThemeGtk::adjustSearchFieldResultsDecorationStyle):
     35        (WebCore::RenderThemeGtk::paintSearchFieldResultsDecoration):
     36        (WebCore::RenderThemeGtk::adjustSearchFieldCancelButtonStyle):
     37        (WebCore::RenderThemeGtk::paintSearchFieldCancelButton):
     38        (WebCore::RenderThemeGtk::adjustSearchFieldStyle):
     39        (WebCore::RenderThemeGtk::paintSearchField):
     40        (WebCore::RenderThemeGtk::platformActiveSelectionBackgroundColor):
     41        (WebCore::RenderThemeGtk::platformInactiveSelectionBackgroundColor):
     42        (WebCore::RenderThemeGtk::platformActiveSelectionForegroundColor):
     43        (WebCore::RenderThemeGtk::platformInactiveSelectionForegroundColor):
     44        (WebCore::RenderThemeGtk::activeListBoxSelectionBackgroundColor):
     45        (WebCore::RenderThemeGtk::inactiveListBoxSelectionBackgroundColor):
     46        (WebCore::RenderThemeGtk::activeListBoxSelectionForegroundColor):
     47        (WebCore::RenderThemeGtk::inactiveListBoxSelectionForegroundColor):
     48        (WebCore::RenderThemeGtk::caretBlinkFrequency):
     49        (WebCore::RenderThemeGtk::systemFont):
     50        (WebCore::gtkStyleSetCallback):
     51        (WebCore::RenderThemeGtk::gtkContainer):
     52        (WebCore::RenderThemeGtk::gtkEntry):
     53        (WebCore::RenderThemeGtk::gtkTreeView):
     54        * platform/gtk/RenderThemeGtk.h:
     55        * platform/gtk/gtk2drawing.c: Added.
     56        (moz_gtk_enable_style_props):
     57        (ensure_window_widget):
     58        (setup_widget_prototype):
     59        (ensure_button_widget):
     60        (ensure_checkbox_widget):
     61        (ensure_radiobutton_widget):
     62        (ensure_scrollbar_widget):
     63        (ensure_spin_widget):
     64        (ensure_scale_widget):
     65        (ensure_entry_widget):
     66        (ensure_option_menu_widget):
     67        (ensure_arrow_widget):
     68        (ensure_handlebox_widget):
     69        (ensure_toolbar_widget):
     70        (ensure_tooltip_widget):
     71        (ensure_tab_widget):
     72        (ensure_progress_widget):
     73        (ensure_frame_widget):
     74        (ensure_menu_bar_widget):
     75        (ensure_menu_bar_item_widget):
     76        (ensure_menu_popup_widget):
     77        (ensure_menu_item_widget):
     78        (ensure_check_menu_item_widget):
     79        (ConvertGtkState):
     80        (TSOffsetStyleGCArray):
     81        (TSOffsetStyleGCs):
     82        (moz_gtk_button_paint):
     83        (moz_gtk_init):
     84        (moz_gtk_checkbox_get_metrics):
     85        (moz_gtk_radio_get_metrics):
     86        (moz_gtk_checkbox_get_focus):
     87        (moz_gtk_radio_get_focus):
     88        (moz_gtk_button_get_focus):
     89        (moz_gtk_option_menu_get_metrics):
     90        (moz_gtk_toggle_paint):
     91        (calculate_arrow_dimensions):
     92        (moz_gtk_scrollbar_button_paint):
     93        (moz_gtk_scrollbar_trough_paint):
     94        (moz_gtk_scrollbar_thumb_paint):
     95        (moz_gtk_spin_paint):
     96        (moz_gtk_scale_paint):
     97        (moz_gtk_scale_thumb_paint):
     98        (moz_gtk_gripper_paint):
     99        (moz_gtk_entry_paint):
     100        (moz_gtk_option_menu_paint):
     101        (moz_gtk_dropdown_arrow_paint):
     102        (moz_gtk_container_paint):
     103        (moz_gtk_toggle_label_paint):
     104        (moz_gtk_toolbar_paint):
     105        (moz_gtk_tooltip_paint):
     106        (moz_gtk_frame_paint):
     107        (moz_gtk_progressbar_paint):
     108        (moz_gtk_progress_chunk_paint):
     109        (moz_gtk_tab_paint):
     110        (moz_gtk_tabpanels_paint):
     111        (moz_gtk_menu_bar_paint):
     112        (moz_gtk_menu_popup_paint):
     113        (moz_gtk_menu_item_paint):
     114        (moz_gtk_check_menu_item_paint):
     115        (moz_gtk_window_paint):
     116        (moz_gtk_get_widget_border):
     117        (moz_gtk_get_dropdown_arrow_size):
     118        (moz_gtk_get_scalethumb_metrics):
     119        (moz_gtk_get_scrollbar_metrics):
     120        (moz_gtk_widget_paint):
     121        (moz_gtk_get_scrollbar_widget):
     122        (moz_gtk_shutdown):
     123        * platform/gtk/gtkdrawing.h: Added.
     124
    11252007-11-03  Alp Toker  <alp@atoker.com>
    2126
  • trunk/WebCore/WebCore.pro

    r27318 r27398  
    950950        platform/gtk/WheelEventGtk.cpp \
    951951        platform/gtk/WidgetGtk.cpp \
     952        platform/gtk/gtk2drawing.c \
    952953        platform/graphics/gtk/ColorGtk.cpp \
    953954        platform/graphics/gtk/IconGtk.cpp \
  • trunk/WebCore/platform/gtk/RenderThemeGtk.cpp

    r27169 r27398  
    11/*
    2  * This file is part of the WebKit project.
    3  *
    4  * Copyright (C) 2006 Apple Computer, Inc.
    5  * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
    6  * Copyright (C) 2007 Holger Hans Peter Freyther
    7  * Copyright (C) 2007 Alp Toker <alp.toker@collabora.co.uk>
    8  * All rights reserved.
     2 * Copyright (C) 2007 Apple Inc.
     3 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
    94 *
    105 * This library is free software; you can redistribute it and/or
     
    2621
    2722#include "config.h"
    28 #include "RenderThemeGtk.h"
    29 
    3023#include "NotImplemented.h"
    3124#include "RenderObject.h"
     25#include "RenderThemeGtk.h"
     26#include "gtkdrawing.h"
    3227
    3328#include <gdk/gdk.h>
    3429
    35 #define THEME_COLOR 204
    36 #define THEME_FONT  210
    37 
    38 // Button constants
    39 #define BP_BUTTON    1
    40 #define BP_RADIO     2
    41 #define BP_CHECKBOX  3
    42 
    43 // Textfield constants
    44 #define TFP_TEXTFIELD 1
    45 #define TFS_READONLY  6
    46 
    47 /*
    48  * Approach to theming:
    49  *  a) keep one copy of each to be drawn widget, GtkEntry, GtkButton, Gtk...
    50  *     + the button will look like the native control
    51  *     + we don't need to worry about style updates and loading the right GtkStyle
    52  *     - resources are wasted. The native windows will not be used, we might have issues
    53  *       with
    54  *
    55  *  b) Use GtkStyle directly and copy and paste Gtk+ code
    56  *
    57  *
    58  * We will mix a and b
    59  *
    60  * - Create GtkWidgets to hold the state (disabled/enabled), selected, not selected.
    61  * - Use a GdkPixmap to make the GtkStyle draw to and then try to convert set it the
    62  *   source of the current operation.
    63  *
    64  */
    65 
    6630namespace WebCore {
    6731
    6832RenderTheme* theme()
    6933{
    70     static RenderThemeGtk gdkTheme;
    71     return &gdkTheme;
     34    static RenderThemeGtk gtkTheme;
     35    return &gtkTheme;
    7236}
    7337
    7438RenderThemeGtk::RenderThemeGtk()
    75     : m_gtkButton(0)
    76     , m_gtkCheckbox(0)
    77     , m_gtkRadioButton(0)
     39    : m_gtkWindow(0)
     40    , m_gtkContainer(0)
    7841    , m_gtkEntry(0)
    79     , m_gtkEditable(0)
    8042    , m_gtkTreeView(0)
    81     , m_unmappedWindow(0)
    82     , m_container(0)
    83 {
    84 }
    85 
    86 void RenderThemeGtk::close()
    87 {
    88 }
    89 
    90 void RenderThemeGtk::addIntrinsicMargins(RenderStyle* style) const
    91 {
    92     // Cut out the intrinsic margins completely if we end up using a small font size
    93     if (style->fontSize() < 11)
    94         return;
    95 
    96     // Intrinsic margin value.
    97     const int m = 2;
    98 
    99     // FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed.
    100     if (style->width().isIntrinsicOrAuto()) {
    101         if (style->marginLeft().quirk())
    102             style->setMarginLeft(Length(m, Fixed));
    103         if (style->marginRight().quirk())
    104             style->setMarginRight(Length(m, Fixed));
    105     }
    106 
    107     if (style->height().isAuto()) {
    108         if (style->marginTop().quirk())
    109             style->setMarginTop(Length(m, Fixed));
    110         if (style->marginBottom().quirk())
    111             style->setMarginBottom(Length(m, Fixed));
    112     }
    113 }
    114 
    115 bool RenderThemeGtk::supportsFocus(EAppearance appearance) const
     43{
     44}
     45
     46static bool supportsFocus(EAppearance appearance)
    11647{
    11748    switch (appearance) {
     
    12051        case TextFieldAppearance:
    12152        case TextAreaAppearance:
     53        case SearchFieldAppearance:
    12254        case MenulistAppearance:
    12355        case RadioAppearance:
     
    12961}
    13062
    131 bool RenderThemeGtk::supportsFocusRing(const RenderStyle* style) const 
     63bool RenderThemeGtk::supportsFocusRing(const RenderStyle* style) const
    13264{
    13365    return supportsFocus(style->appearance());
     
    13668bool RenderThemeGtk::controlSupportsTints(const RenderObject* o) const
    13769{
    138     if (!isEnabled(o))
    139         return false;
    140 
    141     // Checkboxes have tints when enabled.
    142     if (o->style()->appearance() == CheckboxAppearance)
    143         return isChecked(o);
    144 
    145     return true;
    146 }
    147 
    148 short RenderThemeGtk::baselinePosition(const RenderObject* o) const
    149 {
     70    return isEnabled(o);
     71}
     72
     73short RenderThemeGtk::baselinePosition(const RenderObject* o) const
     74{
     75    // FIXME: This strategy is possibly incorrect for the GTK+ port.
    15076    if (o->style()->appearance() == CheckboxAppearance ||
    15177        o->style()->appearance() == RadioAppearance)
    152         return o->marginTop() + o->height() - 2; // Same as in old khtml
     78        return o->marginTop() + o->height() - 2;
    15379    return RenderTheme::baselinePosition(o);
    15480}
    155    
    156 GtkStateType RenderThemeGtk::determineState(RenderObject* o)
    157 {
    158     if (!isEnabled(o) || isReadOnlyControl(o))
    159         return GTK_STATE_INSENSITIVE;
    160     if (isPressed(o) || isFocused(o))
    161         return GTK_STATE_ACTIVE;
    162     if (isHovered(o))
    163         return GTK_STATE_PRELIGHT;
    164     if (isChecked(o))
    165         return GTK_STATE_SELECTED;
    166 
    167     return GTK_STATE_NORMAL;
    168 }
    169 
    170 GtkShadowType RenderThemeGtk::determineShadow(RenderObject* o)
    171 {
    172     return isChecked(o) ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
    173 }
    174 
    175 ThemeData RenderThemeGtk::getThemeData(RenderObject* o)
    176 {
    177     ThemeData result;
    178     switch (o->style()->appearance()) {
    179         case PushButtonAppearance:
    180         case ButtonAppearance:
    181             result.m_part = BP_BUTTON;
     81
     82static void adjustMozStyle(RenderStyle* style, GtkThemeWidgetType type)
     83{
     84    gint left, top, right, bottom;
     85    gboolean inhtml = true;
     86
     87    if (moz_gtk_get_widget_border(type, &left, &top, &right, &bottom, inhtml) != MOZ_GTK_SUCCESS)
     88        return;
     89
     90    // FIXME: This approach is likely to be incorrect. See other ports and layout tests to see the problem.
     91    const int xpadding = 1;
     92    const int ypadding = 1;
     93
     94    style->setPaddingLeft(Length(xpadding + left, Fixed));
     95    style->setPaddingTop(Length(ypadding + top, Fixed));
     96    style->setPaddingRight(Length(xpadding + right, Fixed));
     97    style->setPaddingBottom(Length(ypadding + bottom, Fixed));
     98}
     99
     100static void setMozState(RenderTheme* theme, GtkWidgetState* state, RenderObject* o)
     101{
     102    state->active = theme->isPressed(o);
     103    state->focused = theme->isFocused(o);
     104    state->inHover = theme->isHovered(o);
     105    // FIXME: Disabled does not always give the correct appearance for ReadOnly
     106    state->disabled = !theme->isEnabled(o) || theme->isReadOnlyControl(o);
     107    state->isDefault = false;
     108    state->canDefault = false;
     109}
     110
     111static bool paintMozWidget(RenderTheme* theme, GtkThemeWidgetType type, RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
     112{
     113    GtkWidgetState mozState;
     114    setMozState(theme, &mozState, o);
     115
     116    int flags;
     117
     118    // We might want to make setting flags the caller's job at some point rather than doing it here.
     119    switch (type) {
     120        case MOZ_GTK_BUTTON:
     121            flags = GTK_RELIEF_NORMAL;
    182122            break;
     123        case MOZ_GTK_CHECKBUTTON:
     124        case MOZ_GTK_RADIOBUTTON:
     125            flags = theme->isChecked(o);
     126            break;
     127        default:
     128            flags = 0;
     129            break;
     130    }
     131
     132    IntPoint pos = i.context->translatePoint(rect.location());
     133    GdkRectangle gdkRect = IntRect(pos.x(), pos.y(), rect.width(), rect.height());
     134
     135    // FIXME: Pass the real clip region.
     136    return moz_gtk_widget_paint(type, i.context->gdkDrawable(), &gdkRect, &gdkRect, &mozState, flags) != MOZ_GTK_SUCCESS;
     137}
     138
     139static void setButtonPadding(RenderStyle* style)
     140{
     141    // FIXME: This looks incorrect.
     142    const int padding = 8;
     143    style->setPaddingLeft(Length(padding, Fixed));
     144    style->setPaddingRight(Length(padding, Fixed));
     145    style->setPaddingTop(Length(padding / 2, Fixed));
     146    style->setPaddingBottom(Length(padding / 2, Fixed));
     147}
     148
     149static void setToggleSize(RenderStyle* style, EAppearance appearance)
     150{
     151    // The width and height are both specified, so we shouldn't change them.
     152    if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
     153        return;
     154
     155    // FIXME: This is probably not correct use of indicator_size and indicator_spacing.
     156    gint indicator_size, indicator_spacing;
     157
     158    switch (appearance) {
    183159        case CheckboxAppearance:
    184             result.m_part = BP_CHECKBOX;
     160            if (moz_gtk_checkbox_get_metrics(&indicator_size, &indicator_spacing) != MOZ_GTK_SUCCESS)
     161                return;
    185162            break;
    186163        case RadioAppearance:
    187             result.m_part = BP_RADIO;
    188             break;
    189         case TextFieldAppearance:
    190         case ListboxAppearance:
    191         case MenulistAppearance:
    192         case TextAreaAppearance:
    193             result.m_part = TFP_TEXTFIELD;
     164            if (moz_gtk_radio_get_metrics(&indicator_size, &indicator_spacing) != MOZ_GTK_SUCCESS)
     165                return;
    194166            break;
    195167        default:
    196             break; // FIXME: much more?
     168            return;
    197169    }
    198170
    199     result.m_state = determineState(o);
    200 
    201     return result;
    202 }
    203 
    204 void RenderThemeGtk::setCheckboxSize(RenderStyle* style) const
    205 {
    206     setRadioSize(style);
     171    // Other ports hard-code this to 13, but GTK+ users tend to demand the native look.
     172    // It could be made a configuration option values other than 13 actually break site compatibility.
     173    int length = indicator_size + indicator_spacing;
     174    if (style->width().isIntrinsicOrAuto())
     175        style->setWidth(Length(length, Fixed));
     176
     177    if (style->height().isAuto())
     178        style->setHeight(Length(length, Fixed));
     179}
     180
     181void RenderThemeGtk::setCheckboxSize(RenderStyle* style) const
     182{
     183    setToggleSize(style, RadioAppearance);
    207184}
    208185
    209186bool RenderThemeGtk::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
    210187{
    211     paintButton(o, i, rect);   
    212     return false;
     188    return paintMozWidget(this, MOZ_GTK_CHECKBUTTON, o, i, rect);
     189}
     190
     191void RenderThemeGtk::setRadioSize(RenderStyle* style) const
     192{
     193    setToggleSize(style, RadioAppearance);
    213194}
    214195
    215196bool RenderThemeGtk::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
    216197{
    217     paintButton(o, i, rect);
    218     return false;
    219 }
    220 
    221 void RenderThemeGtk::setRadioSize(RenderStyle* style) const
    222 {
    223     // If the width and height are both specified, then we have nothing to do.
    224     if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
    225         return;
    226 
    227 
    228     // FIXME:  A hard-coded size of 13 is used.  This is wrong but necessary for now.  It matches Firefox.
    229     // At different DPI settings on Windows, querying the theme gives you a larger size that accounts for
    230     // the higher DPI.  Until our entire engine honors a DPI setting other than 96, we can't rely on the theme's
    231     // metrics.
    232     const int ff = 13;
    233     if (style->width().isIntrinsicOrAuto())
    234         style->setWidth(Length(ff, Fixed));
    235 
    236     if (style->height().isAuto())
    237         style->setHeight(Length(ff, Fixed));
    238 }
    239 
    240 bool RenderThemeGtk::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
    241 {
    242     EAppearance appearance = o->style()->appearance();
    243 
    244     if (appearance == PushButtonAppearance || appearance == ButtonAppearance) {
    245         GtkWidget* button = gtkButton();
    246         IntPoint pos = i.context->translatePoint(rect.location());
    247         gtk_paint_box(button->style, i.context->gdkDrawable(),
    248                       determineState(o), determineShadow(o),
    249                       0, button, "button",
    250                       pos.x(), pos.y(), rect.width(), rect.height());
    251     } else if (appearance == CheckboxAppearance) {
    252         GtkWidget* checkbox = gtkCheckbox();
    253         IntPoint pos = i.context->translatePoint(rect.location());
    254         gtk_paint_check(checkbox->style, i.context->gdkDrawable(),
    255                         determineState(o), determineShadow(o),
    256                         0, checkbox, "checkbutton",
    257                         pos.x(), pos.y(), rect.width(), rect.height());
    258     } else if (appearance == RadioAppearance) {
    259         GtkWidget* radio = gtkRadioButton();
    260         IntPoint pos = i.context->translatePoint(rect.location());
    261         gtk_paint_option(radio->style, i.context->gdkDrawable(),
    262                          determineState(o), determineShadow(o),
    263                          0, radio, "radiobutton",
    264                          pos.x(), pos.y(), rect.width(), rect.height());
     198    return paintMozWidget(this, MOZ_GTK_RADIOBUTTON, o, i, rect);
     199}
     200
     201void RenderThemeGtk::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const
     202{
     203    // FIXME: Is this condition necessary?
     204    if (style->appearance() == PushButtonAppearance) {
     205        style->resetBorder();
     206        style->setHeight(Length(Auto));
     207        style->setWhiteSpace(PRE);
     208        setButtonPadding(style);
     209    } else {
     210        // FIXME: This should not be hard-coded.
     211        style->setMinHeight(Length(14, Fixed));
     212        style->resetBorderTop();
     213        style->resetBorderBottom();
    265214    }
    266 
    267     return false;
     215}
     216
     217bool RenderThemeGtk::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
     218{
     219    return paintMozWidget(this, MOZ_GTK_BUTTON, o, i, rect);
    268220}
    269221
    270222void RenderThemeGtk::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const
    271223{
    272     addIntrinsicMargins(style);
     224    style->resetBorder();
     225    style->resetPadding();
     226    style->setHeight(Length(Auto));
     227    style->setWhiteSpace(PRE);
     228    adjustMozStyle(style, MOZ_GTK_DROPDOWN);
    273229}
    274230
    275231bool RenderThemeGtk::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
    276232{
    277     // TODO: Render a real menu list button, not just a box
    278     GtkWidget* button = gtkButton();
    279     IntPoint pos = i.context->translatePoint(rect.location());
    280     gtk_paint_box(button->style, i.context->gdkDrawable(),
    281                   determineState(o), determineShadow(o),
    282                   0, button, 0,
    283                   pos.x(), pos.y(), rect.width(), rect.height());
    284     return false;
    285 }
    286 
    287 void RenderThemeGtk::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
    288 {
    289     addIntrinsicMargins(style);
     233    return paintMozWidget(this, MOZ_GTK_DROPDOWN, o, i, rect);
     234}
     235
     236void RenderThemeGtk::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
     237{
     238    style->resetBorder();
     239    style->resetPadding();
     240    style->setHeight(Length(Auto));
     241    style->setWhiteSpace(PRE);
     242    adjustMozStyle(style, MOZ_GTK_ENTRY);
    290243}
    291244
    292245bool RenderThemeGtk::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
    293246{
    294     GtkWidget* entry = gtkEntry();
    295     IntPoint pos = i.context->translatePoint(rect.location());
    296 
    297     gtk_paint_shadow(entry->style, i.context->gdkDrawable(),
    298                      determineState(o), determineShadow(o),
    299                      0, entry, "entry",
    300                      pos.x(), pos.y(), rect.width(), rect.height());
    301     return false;
     247    return paintMozWidget(this, MOZ_GTK_ENTRY, o, i, rect);
     248}
     249
     250void RenderThemeGtk::adjustTextAreaStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
     251{
     252    adjustTextFieldStyle(selector, style, e);
    302253}
    303254
     
    307258}
    308259
    309 void RenderThemeGtk::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const
    310 {
    311     addIntrinsicMargins(style);
     260void RenderThemeGtk::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
     261{
     262    adjustSearchFieldCancelButtonStyle(selector, style, e);
     263}
     264
     265bool RenderThemeGtk::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
     266{
     267    return paintMozWidget(this, MOZ_GTK_DROPDOWN_ARROW, o, i, rect);
     268}
     269
     270void RenderThemeGtk::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
     271{
     272    style->resetBorder();
     273    style->resetPadding();
     274
     275    // FIXME: This should not be hard-coded.
     276    IntSize size = IntSize(14, 14);
     277    style->setWidth(Length(size.width(), Fixed));
     278    style->setHeight(Length(size.height(), Fixed));
     279}
     280
     281bool RenderThemeGtk::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
     282{
     283    return paintMozWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect);
     284}
     285
     286void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
     287{
     288    style->resetBorder();
     289    style->resetPadding();
     290
     291    // FIXME: This should not be hard-coded.
     292    IntSize size = IntSize(14, 14);
     293    style->setWidth(Length(size.width(), Fixed));
     294    style->setHeight(Length(size.height(), Fixed));
     295}
     296
     297bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
     298{
     299    return paintMozWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect);
     300}
     301
     302void RenderThemeGtk::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
     303{
     304    adjustTextFieldStyle(selector, style, e);
     305}
     306
     307bool RenderThemeGtk::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
     308{
     309    return paintTextField(o, i, rect);
    312310}
    313311
    314312Color RenderThemeGtk::platformActiveSelectionBackgroundColor() const
    315313{
    316     GtkWidget* entry = gtkEntry();
    317     GdkColor color = entry->style->base[GTK_STATE_SELECTED];
    318     return Color(color.red >> 8, color.green >> 8, color.blue >> 8);
     314    GtkWidget* widget = gtkEntry();
     315    return widget->style->base[GTK_STATE_SELECTED];
    319316}
    320317
    321318Color RenderThemeGtk::platformInactiveSelectionBackgroundColor() const
    322319{
    323     GtkWidget* entry = gtkEntry();
    324     GdkColor color = entry->style->base[GTK_STATE_ACTIVE];
    325     return Color(color.red >> 8, color.green >> 8, color.blue >> 8);
     320    GtkWidget* widget = gtkEntry();
     321    return widget->style->base[GTK_STATE_ACTIVE];
    326322}
    327323
    328324Color RenderThemeGtk::platformActiveSelectionForegroundColor() const
    329325{
    330     GtkWidget* entry = gtkEntry();
    331     GdkColor color = entry->style->text[GTK_STATE_SELECTED];
    332     return Color(color.red >> 8, color.green >> 8, color.blue >> 8);
     326    GtkWidget* widget = gtkEntry();
     327    return widget->style->text[GTK_STATE_SELECTED];
    333328}
    334329
    335330Color RenderThemeGtk::platformInactiveSelectionForegroundColor() const
    336331{
    337     GtkWidget* entry = gtkEntry();
    338     GdkColor color = entry->style->text[GTK_STATE_ACTIVE];
    339     return Color(color.red >> 8, color.green >> 8, color.blue >> 8);
     332    GtkWidget* widget = gtkEntry();
     333    return widget->style->text[GTK_STATE_ACTIVE];
    340334}
    341335
     
    343337{
    344338    GtkWidget* widget = gtkTreeView();
    345     GdkColor color = widget->style->base[GTK_STATE_SELECTED];
    346     return Color(color.red >> 8, color.green >> 8, color.blue >> 8);
     339    return widget->style->base[GTK_STATE_SELECTED];
    347340}
    348341
     
    350343{
    351344    GtkWidget* widget = gtkTreeView();
    352     GdkColor color = widget->style->base[GTK_STATE_ACTIVE];
    353     return Color(color.red >> 8, color.green >> 8, color.blue >> 8);
     345    return widget->style->base[GTK_STATE_ACTIVE];
    354346}
    355347
     
    357349{
    358350    GtkWidget* widget = gtkTreeView();
    359     GdkColor color = widget->style->text[GTK_STATE_SELECTED];
    360     return Color(color.red >> 8, color.green >> 8, color.blue >> 8);
     351    return widget->style->text[GTK_STATE_SELECTED];
    361352}
    362353
     
    364355{
    365356    GtkWidget* widget = gtkTreeView();
    366     GdkColor color = widget->style->text[GTK_STATE_ACTIVE];
    367     return Color(color.red >> 8, color.green >> 8, color.blue >> 8);
    368 }
    369 
    370 bool RenderThemeGtk::caretShouldBlink() const
    371 {
    372     GtkSettings* settings = gtk_widget_get_settings(gtkEntry());
    373 
    374     gboolean value;
    375     g_object_get(settings, "gtk-cursor-blink", &value, 0);
    376 
    377     return value;
     357    return widget->style->text[GTK_STATE_ACTIVE];
    378358}
    379359
    380360double RenderThemeGtk::caretBlinkFrequency() const
    381361{
    382     if (!caretShouldBlink())
     362    GtkSettings* settings = gtk_settings_get_default();
     363
     364    gboolean shouldBlink;
     365    gint time;
     366
     367    g_object_get(settings, "gtk-cursor-blink", &shouldBlink, "gtk-cursor-blink-time", &time, 0);
     368
     369    if (!shouldBlink)
    383370        return 0;
    384371
    385     GtkSettings* settings = gtk_widget_get_settings(gtkEntry());
    386 
    387     gint time;
    388     g_object_get(settings, "gtk-cursor-blink-time", &time, 0);
    389 
    390372    return time / 2000.;
    391373}
    392374
    393 void RenderThemeGtk::systemFont(int propId, FontDescription&) const
    394 {
    395 }
    396 
    397 GtkWidget* RenderThemeGtk::gtkButton() const
    398 {
    399     if (!m_gtkButton) {
    400         m_gtkButton = gtk_button_new();
    401         gtk_container_add(GTK_CONTAINER(gtkWindowContainer()), m_gtkButton);
    402         gtk_widget_realize(m_gtkButton);
    403     }
    404 
    405     return m_gtkButton;
    406 }
    407 
    408 GtkWidget* RenderThemeGtk::gtkCheckbox() const
    409 {
    410     if (!m_gtkCheckbox) {
    411         m_gtkCheckbox = gtk_check_button_new();
    412         gtk_container_add(GTK_CONTAINER(gtkWindowContainer()), m_gtkCheckbox);
    413         gtk_widget_realize(m_gtkCheckbox);
    414     }
    415 
    416     return m_gtkCheckbox;
    417 }
    418 
    419 GtkWidget* RenderThemeGtk::gtkRadioButton() const
    420 {
    421     if (!m_gtkRadioButton) {
    422         m_gtkRadioButton = gtk_radio_button_new(NULL);
    423         gtk_container_add(GTK_CONTAINER(gtkWindowContainer()), m_gtkRadioButton);
    424         gtk_widget_realize(m_gtkRadioButton);
    425     }
    426 
    427     return m_gtkRadioButton;
    428 }
    429 
    430 void RenderThemeGtk::gtkStyleSet(GtkWidget* widget, GtkStyle* previous, RenderTheme* renderTheme)
    431 {
     375void RenderThemeGtk::systemFont(int, FontDescription&) const
     376{
     377    // If you remove this notImplemented(), replace it with an comment that explains why.
     378    notImplemented();
     379}
     380
     381static void gtkStyleSetCallback(GtkWidget* widget, GtkStyle* previous, RenderTheme* renderTheme)
     382{
     383    // FIXME: Make sure this function doesn't get called many times for a single GTK+ style change signal.
    432384    renderTheme->platformColorsDidChange();
    433385}
    434386
     387GtkContainer* RenderThemeGtk::gtkContainer() const
     388{
     389    if (m_gtkContainer)
     390        return m_gtkContainer;
     391
     392    m_gtkWindow = gtk_window_new(GTK_WINDOW_POPUP);
     393    m_gtkContainer = GTK_CONTAINER(gtk_fixed_new());
     394    gtk_container_add(GTK_CONTAINER(m_gtkWindow), GTK_WIDGET(m_gtkContainer));
     395    gtk_widget_realize(m_gtkWindow);
     396
     397    return m_gtkContainer;
     398}
     399
    435400GtkWidget* RenderThemeGtk::gtkEntry() const
    436401{
    437     if (!m_gtkEntry) {
    438         m_gtkEntry = gtk_entry_new();
    439         g_signal_connect(m_gtkEntry, "style-set", G_CALLBACK(gtkStyleSet), theme());
    440         gtk_container_add(GTK_CONTAINER(gtkWindowContainer()), m_gtkEntry);
    441         gtk_widget_realize(m_gtkEntry);
    442     }
     402    if (m_gtkEntry)
     403        return m_gtkEntry;
     404
     405    m_gtkEntry = gtk_entry_new();
     406    g_signal_connect(m_gtkEntry, "style-set", G_CALLBACK(gtkStyleSetCallback), theme());
     407    gtk_container_add(gtkContainer(), m_gtkEntry);
     408    gtk_widget_realize(m_gtkEntry);
    443409
    444410    return m_gtkEntry;
     
    447413GtkWidget* RenderThemeGtk::gtkTreeView() const
    448414{
    449     if (!m_gtkTreeView) {
    450         m_gtkTreeView = gtk_tree_view_new();
    451         g_signal_connect(m_gtkTreeView, "style-set", G_CALLBACK(gtkStyleSet), theme());
    452         gtk_container_add(GTK_CONTAINER(gtkWindowContainer()), m_gtkTreeView);
    453         gtk_widget_realize(m_gtkTreeView);
    454     }
     415    if (m_gtkTreeView)
     416        return m_gtkTreeView;
     417
     418    m_gtkTreeView = gtk_tree_view_new();
     419    g_signal_connect(m_gtkTreeView, "style-set", G_CALLBACK(gtkStyleSetCallback), theme());
     420    gtk_container_add(gtkContainer(), m_gtkTreeView);
     421    gtk_widget_realize(m_gtkTreeView);
    455422
    456423    return m_gtkTreeView;
    457424}
    458425
    459 GtkWidget* RenderThemeGtk::gtkWindowContainer() const
    460 {
    461     if (!m_container) {
    462         m_unmappedWindow = gtk_window_new(GTK_WINDOW_POPUP);
    463         // Some GTK themes (i.e. Clearlooks) draw the buttons differently
    464         // (in particular, call gtk_style_apply_default_background) if they
    465         // are unallocated and are children of a GtkFixed widget, which is
    466         // apparently what some "make Firefox buttons look like GTK" code
    467         // does.  To avoid this ugly look, we use a GtkHBox as a parent,
    468         // rather than a GtkFixed.
    469         m_container = gtk_hbox_new(false, 0);
    470         gtk_container_add(GTK_CONTAINER(m_unmappedWindow), m_container);
    471         gtk_widget_realize(m_unmappedWindow);
    472     }
    473 
    474     return m_container;
    475 }
    476 }
     426}
  • trunk/WebCore/platform/gtk/RenderThemeGtk.h

    r27169 r27398  
    55 * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
    66 * Copyright (C) 2007 Holger Hans Peter Freyther
     7 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
    78 * All rights reserved.
    89 *
     
    3334
    3435namespace WebCore {
    35 
    36 struct ThemeData {
    37     ThemeData() : m_part(0), m_state(0) {}
    38 
    39     unsigned m_part;
    40     unsigned m_state;
    41 };
    4236
    4337class RenderThemeGtk : public RenderTheme {
     
    7468    virtual Color inactiveListBoxSelectionForegroundColor() const;
    7569
    76     virtual bool caretShouldBlink() const;
    7770    virtual double caretBlinkFrequency() const;
    7871
     
    9386    virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
    9487
     88    virtual void adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
    9589    virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
    9690
     
    9892    virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
    9993
     94    virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
     95    virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
     96
     97    virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
     98    virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
     99
     100    virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
     101    virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
     102
     103    virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
     104    virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
     105
     106
    100107private:
    101     void addIntrinsicMargins(RenderStyle*) const;
    102     void close();
    103 
    104     GtkStateType determineState(RenderObject*);
    105     GtkShadowType determineShadow(RenderObject*);
    106     bool supportsFocus(EAppearance) const;
    107 
    108     ThemeData getThemeData(RenderObject*);
    109 
    110     static void gtkStyleSet(GtkWidget*, GtkStyle*, RenderTheme*);
    111 
    112108    /*
    113109     * hold the state
    114110     */
    115     GtkWidget* gtkButton() const;
    116     GtkWidget* gtkCheckbox() const;
    117     GtkWidget* gtkRadioButton() const;
    118111    GtkWidget* gtkEntry() const;
    119     GtkWidget* gtkEditable() const;
    120112    GtkWidget* gtkTreeView() const;
    121113
     
    124116     * our fake widgets
    125117     */
    126     GtkWidget* gtkWindowContainer() const;
     118    GtkContainer* gtkContainer() const;
    127119
    128120private:
    129     mutable GtkWidget* m_gtkButton;
    130     mutable GtkWidget* m_gtkCheckbox;
    131     mutable GtkWidget* m_gtkRadioButton;
     121    mutable GtkWidget* m_gtkWindow;
     122    mutable GtkContainer* m_gtkContainer;
    132123    mutable GtkWidget* m_gtkEntry;
    133     mutable GtkWidget* m_gtkEditable;
    134124    mutable GtkWidget* m_gtkTreeView;
    135 
    136     mutable GtkWidget* m_unmappedWindow;
    137     mutable GtkWidget* m_container;
    138125};
    139126
Note: See TracChangeset for help on using the changeset viewer.