コード例 #1
0
void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point)
{
    RefPtrWillBeRawPtr<HTMLInputElement> input(hostInput());
    Element* trackElement = input->closedShadowRoot()->getElementById(ShadowElementNames::sliderTrack());

    if (!input->layoutObject() || !layoutBox() || !trackElement->layoutBox())
        return;

    LayoutPoint offset = roundedLayoutPoint(input->layoutObject()->absoluteToLocal(FloatPoint(point), UseTransforms));
    bool isVertical = hasVerticalAppearance(input.get());
    bool isLeftToRightDirection = layoutBox()->style()->isLeftToRightDirection();
    LayoutUnit trackSize;
    LayoutUnit position;
    LayoutUnit currentPosition;
    // We need to calculate currentPosition from absolute points becaue the
    // renderer for this node is usually on a layer and layoutBox()->x() and
    // y() are unusable.
    // FIXME: This should probably respect transforms.
    LayoutPoint absoluteThumbOrigin = layoutBox()->absoluteBoundingBoxRectIgnoringTransforms().location();
    LayoutPoint absoluteSliderContentOrigin = roundedLayoutPoint(input->layoutObject()->localToAbsolute());
    IntRect trackBoundingBox = trackElement->layoutObject()->absoluteBoundingBoxRectIgnoringTransforms();
    IntRect inputBoundingBox = input->layoutObject()->absoluteBoundingBoxRectIgnoringTransforms();
    if (isVertical) {
        trackSize = trackElement->layoutBox()->contentHeight() - layoutBox()->size().height();
        position = offset.y() - layoutBox()->size().height() / 2 - trackBoundingBox.y() + inputBoundingBox.y() - layoutBox()->marginBottom();
        currentPosition = absoluteThumbOrigin.y() - absoluteSliderContentOrigin.y();
    } else {
        trackSize = trackElement->layoutBox()->contentWidth() - layoutBox()->size().width();
        position = offset.x() - layoutBox()->size().width() / 2 - trackBoundingBox.x() + inputBoundingBox.x();
        position -= isLeftToRightDirection ? layoutBox()->marginLeft() : layoutBox()->marginRight();
        currentPosition = absoluteThumbOrigin.x() - absoluteSliderContentOrigin.x();
    }
    position = std::max<LayoutUnit>(0, std::min(position, trackSize));
    const Decimal ratio = Decimal::fromDouble(static_cast<double>(position) / trackSize);
    const Decimal fraction = isVertical || !isLeftToRightDirection ? Decimal(1) - ratio : ratio;
    StepRange stepRange(input->createStepRange(RejectAny));
    Decimal value = stepRange.clampValue(stepRange.valueFromProportion(fraction));

    Decimal closest = input->findClosestTickMarkValue(value);
    if (closest.isFinite()) {
        double closestFraction = stepRange.proportionFromValue(closest).toDouble();
        double closestRatio = isVertical || !isLeftToRightDirection ? 1.0 - closestFraction : closestFraction;
        LayoutUnit closestPosition = trackSize * closestRatio;
        const LayoutUnit snappingThreshold = 5;
        if ((closestPosition - position).abs() <= snappingThreshold)
            value = closest;
    }

    String valueString = serializeForNumberType(value);
    if (valueString == input->value())
        return;

    // FIXME: This is no longer being set from renderer. Consider updating the method name.
    input->setValueFromRenderer(valueString);
    if (layoutObject())
        layoutObject()->setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::SliderValueChanged);
}
コード例 #2
0
ファイル: BasicShapes.cpp プロジェクト: MYSHLIFE/webkit
bool BasicShape::canBlend(const BasicShape* other) const
{
    // FIXME: Support animations between different shapes in the future.
    if (type() != other->type())
        return false;

    // Both shapes must use the same reference box.
    if (layoutBox() != other->layoutBox())
        return false;

    // Just polygons with same number of vertices can be animated.
    if (type() == BasicShape::BasicShapePolygonType
        && (static_cast<const BasicShapePolygon*>(this)->values().size() != static_cast<const BasicShapePolygon*>(other)->values().size()
        || static_cast<const BasicShapePolygon*>(this)->windRule() != static_cast<const BasicShapePolygon*>(other)->windRule()))
        return false;

    // Circles with keywords for radii coordinates cannot be animated.
    if (type() == BasicShape::BasicShapeCircleType) {
        const BasicShapeCircle* thisCircle = static_cast<const BasicShapeCircle*>(this);
        const BasicShapeCircle* otherCircle = static_cast<const BasicShapeCircle*>(other);
        if (!thisCircle->radius().canBlend(otherCircle->radius()))
            return false;
    }

    // Ellipses with keywords for radii coordinates cannot be animated.
    if (type() != BasicShape::BasicShapeEllipseType)
        return true;

    const BasicShapeEllipse* thisEllipse = static_cast<const BasicShapeEllipse*>(this);
    const BasicShapeEllipse* otherEllipse = static_cast<const BasicShapeEllipse*>(other);
    return (thisEllipse->radiusX().canBlend(otherEllipse->radiusX())
        && thisEllipse->radiusY().canBlend(otherEllipse->radiusY()));
}