15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef StepRange_h
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define StepRange_h
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/Decimal.h"
25591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/Forward.h"
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class HTMLInputElement;
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum AnyStepHandling { RejectAny, AnyIsDefaultStep };
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class StepRange {
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum StepValueShouldBe {
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        StepValueShouldBeReal,
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ParsedStepValueShouldBeInteger,
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ScaledStepValueShouldBeInteger,
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    struct StepDescription {
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        WTF_MAKE_FAST_ALLOCATED;
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    public:
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int defaultStep;
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int defaultStepBase;
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int stepScaleFactor;
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        StepValueShouldBe stepValueShouldBe;
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        StepDescription(int defaultStep, int defaultStepBase, int stepScaleFactor, StepValueShouldBe stepValueShouldBe = StepValueShouldBeReal)
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            : defaultStep(defaultStep)
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            , defaultStepBase(defaultStepBase)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            , stepScaleFactor(stepScaleFactor)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            , stepValueShouldBe(stepValueShouldBe)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        StepDescription()
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            : defaultStep(1)
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            , defaultStepBase(0)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            , stepScaleFactor(1)
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            , stepValueShouldBe(StepValueShouldBeReal)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Decimal defaultValue() const
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return defaultStep * stepScaleFactor;
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StepRange();
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StepRange(const StepRange&);
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StepRange(const Decimal& stepBase, const Decimal& minimum, const Decimal& maximum, const Decimal& step, const StepDescription&);
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Decimal acceptableError() const;
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Decimal alignValueForStep(const Decimal& currentValue, const Decimal& newValue) const;
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Decimal clampValue(const Decimal& value) const;
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasStep() const { return m_hasStep; }
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Decimal maximum() const { return m_maximum; }
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Decimal minimum() const { return m_minimum; }
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static Decimal parseStep(AnyStepHandling, const StepDescription&, const String&);
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Decimal step() const { return m_step; }
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Decimal stepBase() const { return m_stepBase; }
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int stepScaleFactor() const { return m_stepDescription.stepScaleFactor; }
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool stepMismatch(const Decimal&) const;
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Clamp the middle value according to the step
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Decimal defaultValue() const
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return clampValue((m_minimum + m_maximum) / 2);
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Map value into 0-1 range
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Decimal proportionFromValue(const Decimal& value) const
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_minimum == m_maximum)
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return 0;
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return (value - m_minimum) / (m_maximum - m_minimum);
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Map from 0-1 range to value
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Decimal valueFromProportion(const Decimal& proportion) const
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_minimum + proportion * (m_maximum - m_minimum);
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StepRange& operator =(const StepRange&);
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Decimal roundByStep(const Decimal& value, const Decimal& base) const;
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Decimal m_maximum; // maximum must be >= minimum.
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Decimal m_minimum;
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Decimal m_step;
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Decimal m_stepBase;
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const StepDescription m_stepDescription;
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const bool m_hasStep;
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // StepRange_h
122