Beispiel #1
0
bool RenderThemeGtk::paintSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect)
{
    if (info.context->paintingDisabled())
        return false;

    ControlPart part = object->style()->appearance();
    ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart);

    GtkWidget* widget = 0;
    const char* detail = 0;
    GtkOrientation orientation;
    if (part == SliderThumbVerticalPart) {
        widget = gtkVScale();
        detail = "vscale";
        orientation = GTK_ORIENTATION_VERTICAL;
    } else {
        widget = gtkHScale();
        detail = "hscale";
        orientation = GTK_ORIENTATION_HORIZONTAL;
    }
    gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction()));

    // Only some themes have slider thumbs respond to clicks and some don't. This information is
    // gathered via the 'activate-slider' property, but it's deprecated in GTK+ 2.22 and removed in
    // GTK+ 3.x. The drawback of not honoring it is that slider thumbs change color when you click
    // on them. 
    IntRect thumbRect(IntPoint(), rect.size());
    WidgetRenderingContext widgetContext(info.context, rect);
    widgetContext.gtkPaintSlider(thumbRect, widget, getGtkStateType(object), GTK_SHADOW_OUT, detail, orientation);
    return false;
}
Beispiel #2
0
bool RenderThemeGtk::paintSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect)
{
    if (info.context->paintingDisabled())
        return false;

    ControlPart part = object->style()->appearance();
    ASSERT(part == SliderHorizontalPart || part == SliderVerticalPart);

    // We shrink the trough rect slightly to make room for the focus indicator.
    IntRect troughRect(IntPoint(), rect.size()); // This is relative to rect.
    GtkWidget* widget = 0;
    if (part == SliderVerticalPart) {
        widget = gtkVScale();
        troughRect.inflateY(-gtk_widget_get_style(widget)->ythickness);
    } else {
        widget = gtkHScale();
        troughRect.inflateX(-gtk_widget_get_style(widget)->xthickness);
    }
    gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction()));

    WidgetRenderingContext widgetContext(info.context, rect);
    widgetContext.gtkPaintBox(troughRect, widget, GTK_STATE_ACTIVE, GTK_SHADOW_OUT, "trough");
    if (isFocused(object))
        widgetContext.gtkPaintFocus(IntRect(IntPoint(), rect.size()), widget, getGtkStateType(object), "trough");

    return false;
}
bool RenderThemeGtk::paintMenuList(RenderObject* object, const PaintInfo& info, const IntRect& rect)
{
    if (paintButton(object, info, rect))
        return true;

    // Menu list button painting strategy.
    // For buttons with appears-as-list set to false (having a separator):
    // | left border | Button text | xthickness | vseparator | xthickness | arrow | xthickness | right border |
    // For buttons with appears-as-list set to true (not having a separator):
    // | left border | Button text | arrow | xthickness | right border |

    int leftBorder = 0, rightBorder = 0, bottomBorder = 0, topBorder = 0;
    getButtonInnerBorder(gtkComboBoxButton(), leftBorder, topBorder, rightBorder, bottomBorder);
    RenderStyle* style = &object->style();
    int arrowSize = comboBoxArrowSize(style);
    GtkStyle* buttonStyle = gtk_widget_get_style(gtkComboBoxButton());

    IntRect arrowRect(0, (rect.height() - arrowSize) / 2, arrowSize, arrowSize);
    if (style->direction() == RTL)
        arrowRect.setX(leftBorder + buttonStyle->xthickness);
    else
        arrowRect.setX(rect.width() - rightBorder - buttonStyle->xthickness - arrowSize);
    GtkShadowType shadowType = isPressed(object) ? GTK_SHADOW_IN : GTK_SHADOW_OUT;

    WidgetRenderingContext widgetContext(info.context, rect);
    GtkStateType stateType = getGtkStateType(this, object);
    widgetContext.gtkPaintArrow(arrowRect, gtkComboBoxArrow(), stateType, shadowType, GTK_ARROW_DOWN, "arrow");

    // Some combo boxes do not have a separator.
    GtkWidget* separator = gtkComboBoxSeparator();
    if (!separator)
        return false;

    // We want to decrease the height of the separator based on the focus padding of the button.
    gint focusPadding = 0, focusWidth = 0; 
    gtk_widget_style_get(gtkComboBoxButton(),
                         "focus-line-width", &focusWidth,
                         "focus-padding", &focusPadding, NULL);
    topBorder += focusPadding + focusWidth;
    bottomBorder += focusPadding + focusWidth;
    int separatorWidth = getComboBoxSeparatorWidth();
    IntRect separatorRect(0, topBorder, separatorWidth, rect.height() - topBorder - bottomBorder);
    if (style->direction() == RTL)
        separatorRect.setX(arrowRect.x() + arrowRect.width() + buttonStyle->xthickness + separatorWidth);
    else
        separatorRect.setX(arrowRect.x() - buttonStyle->xthickness - separatorWidth);

    gboolean hasWideSeparators = FALSE;
    gtk_widget_style_get(separator, "wide-separators", &hasWideSeparators, NULL);
    if (hasWideSeparators)
        widgetContext.gtkPaintBox(separatorRect, separator, GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT, "vseparator");
    else
        widgetContext.gtkPaintVLine(separatorRect, separator, GTK_STATE_NORMAL, "vseparator");

    return false;
}
Beispiel #4
0
bool RenderThemeGtk::paintButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
{
    if (info.context->paintingDisabled())
        return false;

    GtkWidget* widget = gtkButton();
    IntRect buttonRect(IntPoint(), rect.size());
    IntRect focusRect(buttonRect);

    GtkStateType state = getGtkStateType(object);
    gtk_widget_set_state(widget, state);
    gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction()));

    if (isFocused(object)) {
        if (isEnabled(object)) {
#if !GTK_CHECK_VERSION(2, 22, 0)
            GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
#endif
            g_object_set(widget, "has-focus", TRUE, NULL);
        }

        gboolean interiorFocus = 0, focusWidth = 0, focusPadding = 0;
        gtk_widget_style_get(widget,
                             "interior-focus", &interiorFocus,
                             "focus-line-width", &focusWidth,
                             "focus-padding", &focusPadding, NULL);
        // If we are using exterior focus, we shrink the button rect down before
        // drawing. If we are using interior focus we shrink the focus rect. This
        // approach originates from the Mozilla theme drawing code (gtk2drawing.c).
        if (interiorFocus) {
            GtkStyle* style = gtk_widget_get_style(widget);
            focusRect.inflateX(-style->xthickness - focusPadding);
            focusRect.inflateY(-style->ythickness - focusPadding);
        } else {
            buttonRect.inflateX(-focusWidth - focusPadding);
            buttonRect.inflateY(-focusPadding - focusPadding);
        }
    }

    WidgetRenderingContext widgetContext(info.context, rect);
    GtkShadowType shadowType = state == GTK_STATE_ACTIVE ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
    widgetContext.gtkPaintBox(buttonRect, widget, state, shadowType, "button");
    if (isFocused(object))
        widgetContext.gtkPaintFocus(focusRect, widget, state, "button");

#if !GTK_CHECK_VERSION(2, 22, 0)
    GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
#endif
    g_object_set(widget, "has-focus", FALSE, NULL);
    return false;
}
static void paintToggle(RenderThemeGtk* theme, RenderObject* renderObject, const PaintInfo& info, const IntRect& rect, GtkWidget* widget)
{
    // We do not call gtk_toggle_button_set_active here, because some themes begin a series of
    // animation frames in a "toggled" signal handler. This puts some checkboxes in a half-way
    // checked state. Every GTK+ theme I tested merely looks at the shadow type (and not the
    // 'active' property) to determine whether or not to draw the check.
    gtk_widget_set_sensitive(widget, theme->isEnabled(renderObject) && !theme->isReadOnlyControl(renderObject));
    gtk_widget_set_direction(widget, gtkTextDirection(renderObject->style().direction()));

    bool indeterminate = theme->isIndeterminate(renderObject);
    gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(widget), indeterminate);

    GtkShadowType shadowType = GTK_SHADOW_OUT;
    if (indeterminate) // This originates from the Mozilla code.
        shadowType = GTK_SHADOW_ETCHED_IN;
    else if (theme->isChecked(renderObject))
        shadowType = GTK_SHADOW_IN;

    WidgetRenderingContext widgetContext(info.context, rect);
    IntRect buttonRect(IntPoint(), rect.size());
    GtkStateType toggleState = getGtkStateType(theme, renderObject);
    const char* detail = 0;
    if (GTK_IS_RADIO_BUTTON(widget)) {
        detail = "radiobutton";
        widgetContext.gtkPaintOption(buttonRect, widget, toggleState, shadowType, detail);
    } else {
        detail = "checkbutton";
        widgetContext.gtkPaintCheck(buttonRect, widget, toggleState, shadowType, detail);
    }

    if (theme->isFocused(renderObject)) {
        IntRect focusRect(buttonRect);
        adjustRectForFocus(widget, focusRect, true);
        widgetContext.gtkPaintFocus(focusRect, widget, toggleState, detail);
    }
}