/* * Copyright (C) 2015 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 com.android.deskclock.uidata; import android.content.Context; import android.content.SharedPreferences; import android.graphics.Typeface; import android.support.annotation.DrawableRes; import android.support.annotation.StringRes; import com.android.deskclock.AlarmClockFragment; import com.android.deskclock.ClockFragment; import com.android.deskclock.R; import com.android.deskclock.stopwatch.StopwatchFragment; import com.android.deskclock.timer.TimerFragment; import java.util.Calendar; import static com.android.deskclock.Utils.enforceMainLooper; /** * All application-wide user interface data is accessible through this singleton. */ public final class UiDataModel { /** Identifies each of the primary tabs within the application. */ public enum Tab { ALARMS(AlarmClockFragment.class, R.drawable.ic_tab_alarm, R.string.menu_alarm), CLOCKS(ClockFragment.class, R.drawable.ic_tab_clock, R.string.menu_clock), TIMERS(TimerFragment.class, R.drawable.ic_tab_timer, R.string.menu_timer), STOPWATCH(StopwatchFragment.class, R.drawable.ic_tab_stopwatch, R.string.menu_stopwatch); private final String mFragmentClassName; private final @DrawableRes int mIconResId; private final @StringRes int mLabelResId; Tab(Class fragmentClass, @DrawableRes int iconResId, @StringRes int labelResId) { mFragmentClassName = fragmentClass.getName(); mIconResId = iconResId; mLabelResId = labelResId; } public String getFragmentClassName() { return mFragmentClassName; } public @DrawableRes int getIconResId() { return mIconResId; } public @StringRes int getLabelResId() { return mLabelResId; } } /** The single instance of this data model that exists for the life of the application. */ private static final UiDataModel sUiDataModel = new UiDataModel(); public static UiDataModel getUiDataModel() { return sUiDataModel; } private Context mContext; /** The model from which tab data are fetched. */ private TabModel mTabModel; /** The model from which formatted strings are fetched. */ private FormattedStringModel mFormattedStringModel; /** The model from which timed callbacks originate. */ private PeriodicCallbackModel mPeriodicCallbackModel; private UiDataModel() {} /** * The context may be set precisely once during the application life. */ public void init(Context context, SharedPreferences prefs) { if (mContext != context) { mContext = context.getApplicationContext(); mPeriodicCallbackModel = new PeriodicCallbackModel(mContext); mFormattedStringModel = new FormattedStringModel(mContext); mTabModel = new TabModel(prefs); } } /** * To display the alarm clock in this font, use the character {@link R.string#clock_emoji}. * * @return a special font containing a glyph that draws an alarm clock */ public Typeface getAlarmIconTypeface() { return Typeface.createFromAsset(mContext.getAssets(), "fonts/clock.ttf"); } // // Formatted Strings // /** * This method is intended to be used when formatting numbers occurs in a hotspot such as the * update loop of a timer or stopwatch. It returns cached results when possible in order to * provide speed and limit garbage to be collected by the virtual machine. * * @param value a positive integer to format as a String * @return the {@code value} formatted as a String in the current locale * @throws IllegalArgumentException if {@code value} is negative */ public String getFormattedNumber(int value) { enforceMainLooper(); return mFormattedStringModel.getFormattedNumber(value); } /** * This method is intended to be used when formatting numbers occurs in a hotspot such as the * update loop of a timer or stopwatch. It returns cached results when possible in order to * provide speed and limit garbage to be collected by the virtual machine. * * @param value a positive integer to format as a String * @param length the length of the String; zeroes are padded to match this length * @return the {@code value} formatted as a String in the current locale and padded to the * requested {@code length} * @throws IllegalArgumentException if {@code value} is negative */ public String getFormattedNumber(int value, int length) { enforceMainLooper(); return mFormattedStringModel.getFormattedNumber(value, length); } /** * This method is intended to be used when formatting numbers occurs in a hotspot such as the * update loop of a timer or stopwatch. It returns cached results when possible in order to * provide speed and limit garbage to be collected by the virtual machine. * * @param negative force a minus sign (-) onto the display, even if {@code value} is {@code 0} * @param value a positive integer to format as a String * @param length the length of the String; zeroes are padded to match this length. If * {@code negative} is {@code true} the return value will contain a minus sign and a total * length of {@code length + 1}. * @return the {@code value} formatted as a String in the current locale and padded to the * requested {@code length} * @throws IllegalArgumentException if {@code value} is negative */ public String getFormattedNumber(boolean negative, int value, int length) { enforceMainLooper(); return mFormattedStringModel.getFormattedNumber(negative, value, length); } /** * @param calendarDay any of the following values *