summaryrefslogtreecommitdiff
path: root/core/java/android/service/controls/templates/RangeTemplate.java
blob: 0d977d30f7c1c28abb22498ffdb8f0a55e8037ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.service.controls.templates;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
import android.service.controls.Control;
import android.service.controls.actions.FloatAction;

/**
 * A template for a {@link Control} with inputs in a "continuous" range of values.
 *
 * @see FloatAction
 */
public final class RangeTemplate extends ControlTemplate {

    private static final @TemplateType int TYPE = TYPE_RANGE;
    private static final String KEY_MIN_VALUE = "key_min_value";
    private static final String KEY_MAX_VALUE = "key_max_value";
    private static final String KEY_CURRENT_VALUE = "key_current_value";
    private static final String KEY_STEP_VALUE = "key_step_value";
    private static final String KEY_FORMAT_STRING = "key_format_string";

    private final float mMinValue;
    private final float mMaxValue;
    private final float mCurrentValue;
    private final float mStepValue;
    private final @NonNull CharSequence mFormatString;

    /**
     * Construct a new {@link RangeTemplate}.
     *
     * The range must be valid, meaning:
     * <ul>
     *     <li> {@code minValue} < {@code maxValue}
     *     <li> {@code minValue} < {@code currentValue}
     *     <li> {@code currentValue} < {@code maxValue}
     *     <li> 0 < {@code stepValue}
     * </ul>
     * <p>
     * The current value of the Control will be formatted accordingly.
     *
     * @param templateId the identifier for this template object
     * @param minValue minimum value for the input
     * @param maxValue maximum value for the input
     * @param currentValue the current value of the {@link Control} containing this object.
     * @param stepValue minimum value of increments/decrements when interacting with this control.
     * @param formatString a formatting string as per {@link String#format} used to display the
     *                    {@code currentValue}. If {@code null} is passed, the "%.1f" is used.
     * @throws IllegalArgumentException if the parameters passed do not make a valid range.
     */
    public RangeTemplate(@NonNull String templateId,
            float minValue,
            float maxValue,
            float currentValue,
            float stepValue,
            @Nullable CharSequence formatString) {
        super(templateId);
        mMinValue = minValue;
        mMaxValue = maxValue;
        mCurrentValue = currentValue;
        mStepValue = stepValue;
        if (formatString != null) {
            mFormatString = formatString;
        } else {
            mFormatString = "%.1f";
        }
        validate();
    }

    /**
     * Construct a new {@link RangeTemplate} from a {@link Bundle}.
     *
     * @throws IllegalArgumentException if the parameters passed do not make a valid range
     * @see RangeTemplate#RangeTemplate(String, float, float, float, float, CharSequence)
     * @hide
     */
    RangeTemplate(Bundle b) {
        super(b);
        mMinValue = b.getFloat(KEY_MIN_VALUE);
        mMaxValue = b.getFloat(KEY_MAX_VALUE);
        mCurrentValue = b.getFloat(KEY_CURRENT_VALUE);
        mStepValue = b.getFloat(KEY_STEP_VALUE);
        mFormatString = b.getCharSequence(KEY_FORMAT_STRING, "%.1f");
        validate();
    }

    /**
     * The minimum value for this range.
     */
    public float getMinValue() {
        return mMinValue;
    }

    /**
     * The maximum value for this range.
     */
    public float getMaxValue() {
        return mMaxValue;
    }

    /**
     * The current value for this range.
     */
    public float getCurrentValue() {
        return mCurrentValue;
    }

    /**
     * The value of the smallest increment or decrement that can be performed on this range.
     */
    public float getStepValue() {
        return mStepValue;
    }

    /**
     * Formatter for generating a user visible {@link String} representing the value
     *         returned by {@link RangeTemplate#getCurrentValue}.
     * @return a formatting string as specified in {@link String#format}
     */
    @NonNull
    public CharSequence getFormatString() {
        return mFormatString;
    }

    /**
     * @return {@link ControlTemplate#TYPE_RANGE}
     */
    @Override
    public int getTemplateType() {
        return TYPE;
    }

    /**
     * @return
     * @hide
     */
    @Override
    @NonNull
    Bundle getDataBundle() {
        Bundle b = super.getDataBundle();
        b.putFloat(KEY_MIN_VALUE, mMinValue);
        b.putFloat(KEY_MAX_VALUE, mMaxValue);
        b.putFloat(KEY_CURRENT_VALUE, mCurrentValue);
        b.putFloat(KEY_STEP_VALUE, mStepValue);
        b.putCharSequence(KEY_FORMAT_STRING, mFormatString);
        return b;
    }

    /**
     * Validate constructor parameters
     *
     * @throws IllegalArgumentException if the parameters passed do not make a valid range
     */
    private void validate() {
        if (Float.compare(mMinValue, mMaxValue) > 0) {
            throw new IllegalArgumentException(
                    String.format("minValue=%f > maxValue=%f", mMinValue, mMaxValue));
        }
        if (Float.compare(mMinValue, mCurrentValue) > 0) {
            throw new IllegalArgumentException(
                    String.format("minValue=%f > currentValue=%f", mMinValue, mCurrentValue));
        }
        if (Float.compare(mCurrentValue, mMaxValue) > 0) {
            throw new IllegalArgumentException(
                    String.format("currentValue=%f > maxValue=%f", mCurrentValue, mMaxValue));
        }
        if (mStepValue <= 0) {
            throw new IllegalArgumentException(String.format("stepValue=%f <= 0", mStepValue));
        }
    }
}