diff options
author | 2013-02-14 16:46:39 +0900 | |
---|---|---|
committer | 2013-02-21 09:54:02 +0900 | |
commit | 46878544ec894fd3db368e183404a01c3e3ecc92 (patch) | |
tree | 90b6bb61228c5c3130b1bc283141026cd287868f | |
parent | 7739190083f80152a9aa55eb8c76ed156fc277e3 (diff) | |
download | latinime-46878544ec894fd3db368e183404a01c3e3ecc92.tar.gz latinime-46878544ec894fd3db368e183404a01c3e3ecc92.tar.xz latinime-46878544ec894fd3db368e183404a01c3e3ecc92.zip |
Add preliminary setup wizard
Bug: 8159728
Change-Id: I30d9cd637fb1d2e64588550e0aa4387bc1f7e6e5
-rw-r--r-- | java/res/drawable-hdpi/ic_settings_language.png | bin | 0 -> 986 bytes | |||
-rw-r--r-- | java/res/drawable-mdpi/ic_settings_language.png | bin | 0 -> 756 bytes | |||
-rw-r--r-- | java/res/drawable-xhdpi/ic_settings_language.png | bin | 0 -> 1267 bytes | |||
-rw-r--r-- | java/res/layout/setup_step.xml | 58 | ||||
-rw-r--r-- | java/res/layout/setup_wizard.xml | 78 | ||||
-rw-r--r-- | java/res/values-sw600dp-land/setup-dimens.xml | 20 | ||||
-rw-r--r-- | java/res/values-sw768dp-land/setup-dimens.xml | 20 | ||||
-rw-r--r-- | java/res/values/colors.xml | 5 | ||||
-rw-r--r-- | java/res/values/setup-dimens.xml | 20 | ||||
-rw-r--r-- | java/res/values/setup-styles.xml | 45 | ||||
-rw-r--r-- | java/res/values/strings.xml | 25 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/compat/TextViewCompatUtils.java | 44 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/compat/ViewCompatUtils.java | 68 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/setup/SetupActivity.java | 311 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java | 56 |
15 files changed, 745 insertions, 5 deletions
diff --git a/java/res/drawable-hdpi/ic_settings_language.png b/java/res/drawable-hdpi/ic_settings_language.png Binary files differnew file mode 100644 index 000000000..f635b2e7a --- /dev/null +++ b/java/res/drawable-hdpi/ic_settings_language.png diff --git a/java/res/drawable-mdpi/ic_settings_language.png b/java/res/drawable-mdpi/ic_settings_language.png Binary files differnew file mode 100644 index 000000000..f8aca679b --- /dev/null +++ b/java/res/drawable-mdpi/ic_settings_language.png diff --git a/java/res/drawable-xhdpi/ic_settings_language.png b/java/res/drawable-xhdpi/ic_settings_language.png Binary files differnew file mode 100644 index 000000000..2c42db3aa --- /dev/null +++ b/java/res/drawable-xhdpi/ic_settings_language.png diff --git a/java/res/layout/setup_step.xml b/java/res/layout/setup_step.xml new file mode 100644 index 000000000..26d7fe799 --- /dev/null +++ b/java/res/layout/setup_step.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + <TextView + android:id="@+id/setup_step_title" + style="@style/setupStepTitleStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="16dp" + android:paddingBottom="16dp" + android:paddingLeft="24dp" + android:paddingRight="24dp" /> + <TextView + android:id="@+id/setup_step_instruction" + style="@style/setupStepInstructionStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="16dp" + android:paddingLeft="24dp" + android:paddingRight="24dp" /> + <View + android:layout_width="match_parent" + android:layout_height="2dp" /> + <TextView + android:id="@+id/setup_step_action_label" + style="@style/setupStepActionLabelStyle" + android:gravity="center_vertical" + android:drawablePadding="12dp" + android:layout_width="match_parent" + android:layout_height="48dp" + android:clickable="true" + android:focusable="true" + android:paddingLeft="12dp" + android:paddingStart="12dp" + android:paddingRight="24dp" + android:paddingEnd="24dp" /> +</LinearLayout> diff --git a/java/res/layout/setup_wizard.xml b/java/res/layout/setup_wizard.xml new file mode 100644 index 000000000..acbbe30b3 --- /dev/null +++ b/java/res/layout/setup_wizard.xml @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fillViewport="true"> + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/setup_background" + android:paddingLeft="@dimen/setup_horizontal_padding" + android:paddingRight="@dimen/setup_horizontal_padding" + android:paddingTop="16dp" + android:paddingBottom="16dp"> + <TextView + android:id="@+id/setup_title" + style="@style/setupTitleStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" + android:layout_alignParentTop="true" /> + <LinearLayout + android:id="@+id/setup_step_bullets" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/setup_title" + android:paddingTop="16dp" + android:orientation="horizontal"> + <TextView + style="@style/setupStepBulletStyle" + android:text="@string/setup_step1_bullet" /> + <TextView + style="@style/setupStepBulletStyle" + android:text="@string/setup_step2_bullet" /> + <TextView + style="@style/setupStepBulletStyle" + android:text="@string/setup_step3_bullet" /> + </LinearLayout> + <com.android.inputmethod.latin.setup.SetupStepIndicatorView + android:id="@+id/setup_step_indicator" + android:layout_width="match_parent" + android:layout_height="24dp" + android:layout_below="@id/setup_step_bullets" /> + <FrameLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/setup_step_indicator"> + <include + android:id="@+id/setup_step1" + layout="@layout/setup_step" /> + <include + android:id="@+id/setup_step2" + layout="@layout/setup_step" /> + <include + android:id="@+id/setup_step3" + layout="@layout/setup_step" /> + </FrameLayout> + </RelativeLayout> +</ScrollView> diff --git a/java/res/values-sw600dp-land/setup-dimens.xml b/java/res/values-sw600dp-land/setup-dimens.xml new file mode 100644 index 000000000..9aea21423 --- /dev/null +++ b/java/res/values-sw600dp-land/setup-dimens.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2013 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. +--> + +<resources xmlns:android="http://schemas.android.com/apk/res/android"> + <dimen name="setup_title_text_size">64sp</dimen> + <dimen name="setup_horizontal_padding">96dp</dimen> +</resources> diff --git a/java/res/values-sw768dp-land/setup-dimens.xml b/java/res/values-sw768dp-land/setup-dimens.xml new file mode 100644 index 000000000..0d2af17e3 --- /dev/null +++ b/java/res/values-sw768dp-land/setup-dimens.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2013 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. +--> + +<resources xmlns:android="http://schemas.android.com/apk/res/android"> + <dimen name="setup_title_text_size">64sp</dimen> + <dimen name="setup_horizontal_padding">192dp</dimen> +</resources> diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml index c0ea321ce..8a8049f1f 100644 --- a/java/res/values/colors.xml +++ b/java/res/values/colors.xml @@ -53,4 +53,9 @@ <color name="spacebar_text_color_ics">#FFC0C0C0</color> <color name="spacebar_text_shadow_color_ics">#80000000</color> <color name="typed_word_color_ics">@color/highlight_color_ics</color> + <!-- Color resources for setup wizard and tutorial --> + <color name="setup_background">#FFEBEBEB</color> + <color name="setup_text_dark">#FF707070</color> + <color name="setup_text_action">@android:color/holo_blue_light</color> + <color name="setup_step_background">@android:color/background_light</color> </resources> diff --git a/java/res/values/setup-dimens.xml b/java/res/values/setup-dimens.xml new file mode 100644 index 000000000..007906dc0 --- /dev/null +++ b/java/res/values/setup-dimens.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2013 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. +--> + +<resources xmlns:android="http://schemas.android.com/apk/res/android"> + <dimen name="setup_title_text_size">46sp</dimen> + <dimen name="setup_horizontal_padding">16dp</dimen> +</resources> diff --git a/java/res/values/setup-styles.xml b/java/res/values/setup-styles.xml new file mode 100644 index 000000000..cfc689a78 --- /dev/null +++ b/java/res/values/setup-styles.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2013 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. +--> + +<resources xmlns:android="http://schemas.android.com/apk/res/android"> + <style name="setupTitleStyle"> + <item name="android:textColor">@color/setup_text_dark</item> + <item name="android:textSize">@dimen/setup_title_text_size</item> + </style> + <style name="setupStepBulletStyle"> + <item name="android:textColor">@color/setup_text_dark</item> + <item name="android:textSize">22sp</item> + <item name="android:layout_width">0dp</item> + <item name="android:layout_weight">1.0</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:gravity">center_horizontal</item> + </style> + <style name="setupStepTitleStyle"> + <item name="android:background">@color/setup_step_background</item> + <item name="android:textColor">@color/setup_text_dark</item> + <item name="android:textSize">22sp</item> + </style> + <style name="setupStepInstructionStyle"> + <item name="android:background">@color/setup_step_background</item> + <item name="android:textColor">@color/setup_text_dark</item> + <item name="android:textSize">14sp</item> + </style> + <style name="setupStepActionLabelStyle"> + <item name="android:background">@color/setup_step_background</item> + <item name="android:textColor">@color/setup_text_action</item> + <item name="android:textSize">18sp</item> + </style> +</resources> diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml index ee79b450e..f7d34c8e3 100644 --- a/java/res/values/strings.xml +++ b/java/res/values/strings.xml @@ -408,4 +408,29 @@ <!-- Title of the button to revert to the default value of the device in the settings dialog [CHAR LIMIT=15] --> <string name="button_default">Default</string> + + <!-- Title of the setup wizard. [CHAR LIMT=40] --> + <string name="setup_title">"Installing <xliff:g id="application_name">%s</xliff:g>"</string> + <!-- Ordinal number of the 1st step in the setup wizard. [CHAR LIMIT=5] --> + <string name="setup_step1_bullet">1</string> + <!-- Title of the 1st step in the setup wizard. [CHAR LIMIT=64] --> + <string name="setup_step1_title">"Enable <xliff:g id="application_name">%s</xliff:g> in settings."</string> + <!-- Detailed instruction of the 1st step in the setup wizard. [CHAR LIMIT=80] --> + <string name="setup_step1_instruction">"For security, please check \"<xliff:g id="application_name">%s</xliff:g>\""</string> + <!-- Ordinal number of the 2nd step in the setup wizard. [CHAR LIMIT=5] --> + <string name="setup_step2_bullet">2</string> + <!-- Title of the 2nd step in the setup wizard. [CHAR LIMIT=64] --> + <string name="setup_step2_title">"Switch to <xliff:g id="application_name">%s</xliff:g>."</string> + <!-- Detailed instruction of the 2nd step in the setup wizard. [CHAR LIMIT=80] --> + <string name="setup_step2_instruction">"Now that you've enabled <xliff:g id="application_name">%s</xliff:g>, you can switch to it."</string> + <!-- Ordinal number of the 3rd step in the setup wizard. [CHAR LIMIT=5] --> + <string name="setup_step3_bullet">3</string> + <!-- Title of the 3rd step in the setup wizard. [CHAR LIMIT=64] --> + <string name="setup_step3_title">"Congratulations, you're all set!"</string> + <!-- Detailed instruction of the 3rd step in the setup wizard. [CHAR LIMIT=80] --> + <string name="setup_step3_instruction">Configure additional languages</string> + <!-- Title of the Language & input settings. This should be aligned with msgid="5292716747264442359" --> + <string name="language_settings">Language & input</string> + <!-- Title of the Input method picker. This should be aligned with msgid="4653387336791222978" --> + <string name="select_input_method">Choose input method</string> </resources> diff --git a/java/src/com/android/inputmethod/compat/TextViewCompatUtils.java b/java/src/com/android/inputmethod/compat/TextViewCompatUtils.java new file mode 100644 index 000000000..d4f1ea830 --- /dev/null +++ b/java/src/com/android/inputmethod/compat/TextViewCompatUtils.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013 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.inputmethod.compat; + +import android.graphics.drawable.Drawable; +import android.widget.TextView; + +import java.lang.reflect.Method; + +public final class TextViewCompatUtils { + // Note that TextView.setCompoundDrawablesRelative(Drawable,Drawable,Drawable,Drawable) has + // been introduced in API level 17 (Build.VERSION_CODE.JELLY_BEAN_MR1). + private static final Method METHOD_setCompoundDrawablesRelative = CompatUtils.getMethod( + TextView.class, "setCompoundDrawablesRelative", + Drawable.class, Drawable.class, Drawable.class, Drawable.class); + + private TextViewCompatUtils() { + // This utility class is not publicly instantiable. + } + + public static void setCompoundDrawablesRelative(final TextView textView, final Drawable start, + final Drawable top, final Drawable end, final Drawable bottom) { + if (METHOD_setCompoundDrawablesRelative == null) { + textView.setCompoundDrawables(start, top, end, bottom); + return; + } + CompatUtils.invoke(textView, null, METHOD_setCompoundDrawablesRelative, + start, top, end, bottom); + } +} diff --git a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java new file mode 100644 index 000000000..a8fab8855 --- /dev/null +++ b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2013 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.inputmethod.compat; + +import android.view.View; + +import java.lang.reflect.Method; + +public final class ViewCompatUtils { + // Note that View.LAYOUT_DIRECTION_LTR and View.LAYOUT_DIRECTION_RTL have been introduced in + // API level 17 (Build.VERSION_CODE.JELLY_BEAN_MR1). + public static final int LAYOUT_DIRECTION_LTR = (Integer)CompatUtils.getFieldValue(null, 0x0, + CompatUtils.getField(View.class, "LAYOUT_DIRECTION_LTR")); + public static final int LAYOUT_DIRECTION_RTL = (Integer)CompatUtils.getFieldValue(null, 0x1, + CompatUtils.getField(View.class, "LAYOUT_DIRECTION_RTL")); + + // Note that View.getPaddingEnd(), View.setPaddingRelative(int,int,int,int), and + // View.getLayoutDirection() have been introduced in API level 17 + // (Build.VERSION_CODE.JELLY_BEAN_MR1). + private static final Method METHOD_getPaddingEnd = CompatUtils.getMethod( + View.class, "getPaddingEnd"); + private static final Method METHOD_setPaddingRelative = CompatUtils.getMethod( + View.class, "setPaddingRelative", + Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE); + private static final Method METHOD_getLayoutDirection = CompatUtils.getMethod( + View.class, "getLayoutDirection"); + + private ViewCompatUtils() { + // This utility class is not publicly instantiable. + } + + public static int getPaddingEnd(final View view) { + if (METHOD_getPaddingEnd == null) { + return view.getPaddingRight(); + } + return (Integer)CompatUtils.invoke(view, 0, METHOD_getPaddingEnd); + } + + public static void setPaddingRelative(final View view, final int start, final int top, + final int end, final int bottom) { + if (METHOD_setPaddingRelative == null) { + view.setPadding(start, top, end, bottom); + return; + } + CompatUtils.invoke(view, null, METHOD_setPaddingRelative, start, top, end, bottom); + } + + public static int getLayoutDirection(final View view) { + if (METHOD_getLayoutDirection == null) { + return LAYOUT_DIRECTION_LTR; + } + return (Integer)CompatUtils.invoke(view, 0, METHOD_getLayoutDirection); + } +} diff --git a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java index fab894584..c30ecfb16 100644 --- a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java +++ b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java @@ -18,22 +18,323 @@ package com.android.inputmethod.latin.setup; import android.app.Activity; import android.content.Intent; +import android.content.res.Resources; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.os.Message; +import android.provider.Settings; +import android.view.View; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.TextView; +import com.android.inputmethod.compat.TextViewCompatUtils; +import com.android.inputmethod.compat.ViewCompatUtils; +import com.android.inputmethod.latin.CollectionUtils; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.RichInputMethodManager; import com.android.inputmethod.latin.SettingsActivity; +import com.android.inputmethod.latin.StaticInnerHandlerWrapper; + +import java.util.HashMap; public final class SetupActivity extends Activity { + private SetupStepIndicatorView mStepIndicatorView; + private final SetupStepGroup mSetupSteps = new SetupStepGroup(); + private static final String STATE_STEP = "step"; + private int mStepNo; + private static final int STEP_1 = 1; + private static final int STEP_2 = 2; + private static final int STEP_3 = 3; + + private final SettingsPoolingHandler mHandler = new SettingsPoolingHandler(this); + + static final class SettingsPoolingHandler extends StaticInnerHandlerWrapper<SetupActivity> { + private static final int MSG_POLLING_IME_SETTINGS = 0; + private static final long IME_SETTINGS_POLLING_INTERVAL = 200; + + public SettingsPoolingHandler(final SetupActivity outerInstance) { + super(outerInstance); + } + + @Override + public void handleMessage(final Message msg) { + final SetupActivity setupActivity = getOuterInstance(); + switch (msg.what) { + case MSG_POLLING_IME_SETTINGS: + if (setupActivity.isMyImeEnabled()) { + setupActivity.invokeSetupWizardOfThisIme(); + return; + } + startPollingImeSettings(); + break; + } + } + + public void startPollingImeSettings() { + sendMessageDelayed(obtainMessage(MSG_POLLING_IME_SETTINGS), + IME_SETTINGS_POLLING_INTERVAL); + } + + public void cancelPollingImeSettings() { + removeMessages(MSG_POLLING_IME_SETTINGS); + } + } + @Override - protected void onCreate(Bundle savedInstanceState) { + protected void onCreate(final Bundle savedInstanceState) { + setTheme(android.R.style.Theme_DeviceDefault_Light_NoActionBar); super.onCreate(savedInstanceState); - // TODO: Implement setup wizard. + setContentView(R.layout.setup_wizard); + + RichInputMethodManager.init(this); + + if (savedInstanceState == null) { + mStepNo = determineSetupStepNo(); + } else { + mStepNo = savedInstanceState.getInt(STATE_STEP); + } + + if (mStepNo == STEP_3) { + // This IME already has been enabled and set as current IME. + // TODO: Implement tutorial. + invokeSettingsOfThisIme(); + finish(); + return; + } + + // TODO: Use sans-serif-thin font family depending on the system locale white list and + // the SDK version. + final TextView titleView = (TextView)findViewById(R.id.setup_title); + titleView.setText(getString(R.string.setup_title, getString(R.string.english_ime_name))); + + mStepIndicatorView = (SetupStepIndicatorView)findViewById(R.id.setup_step_indicator); + + final SetupStep step1 = new SetupStep(findViewById(R.id.setup_step1), + R.string.setup_step1_title, R.string.setup_step1_instruction, + R.drawable.ic_settings_language, R.string.language_settings); + step1.setAction(new Runnable() { + @Override + public void run() { + invokeLanguageAndInputSettings(); + mHandler.startPollingImeSettings(); + } + }); + mSetupSteps.addStep(STEP_1, step1); + + final SetupStep step2 = new SetupStep(findViewById(R.id.setup_step2), + R.string.setup_step2_title, R.string.setup_step2_instruction, + 0 /* actionIcon */, R.string.select_input_method); + step2.setAction(new Runnable() { + @Override + public void run() { + // Invoke input method picker. + RichInputMethodManager.getInstance().getInputMethodManager() + .showInputMethodPicker(); + } + }); + mSetupSteps.addStep(STEP_2, step2); + + final SetupStep step3 = new SetupStep(findViewById(R.id.setup_step3), + R.string.setup_step3_title, 0 /* instruction */, + R.drawable.sym_keyboard_language_switch, R.string.setup_step3_instruction); + step3.setAction(new Runnable() { + @Override + public void run() { + invokeSubtypeEnablerOfThisIme(); + } + }); + mSetupSteps.addStep(STEP_3, step3); + } + + private void invokeSetupWizardOfThisIme() { + final Intent intent = new Intent(); + intent.setClass(this, SetupActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED + | Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + } + + private void invokeSettingsOfThisIme() { final Intent intent = new Intent(); intent.setClass(this, SettingsActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED + intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); - finish(); + } + + private void invokeLanguageAndInputSettings() { + final Intent intent = new Intent(); + intent.setAction(Settings.ACTION_INPUT_METHOD_SETTINGS); + intent.addCategory(Intent.CATEGORY_DEFAULT); + startActivity(intent); + } + + private void invokeSubtypeEnablerOfThisIme() { + final InputMethodInfo imi = + RichInputMethodManager.getInstance().getInputMethodInfoOfThisIme(); + final Intent intent = new Intent(); + intent.setAction(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS); + intent.addCategory(Intent.CATEGORY_DEFAULT); + intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, imi.getId()); + startActivity(intent); + } + + private boolean isMyImeEnabled() { + final String packageName = getPackageName(); + final InputMethodManager imm = RichInputMethodManager.getInstance().getInputMethodManager(); + for (final InputMethodInfo imi : imm.getEnabledInputMethodList()) { + if (packageName.equals(imi.getPackageName())) { + return true; + } + } + return false; + } + + private boolean isMyImeCurrent() { + final InputMethodInfo myImi = + RichInputMethodManager.getInstance().getInputMethodInfoOfThisIme(); + final String currentImeId = Settings.Secure.getString( + getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); + return myImi.getId().equals(currentImeId); + } + + private int determineSetupStepNo() { + mHandler.cancelPollingImeSettings(); + if (!isMyImeEnabled()) { + return STEP_1; + } + if (!isMyImeCurrent()) { + return STEP_2; + } + return STEP_3; + } + + @Override + protected void onSaveInstanceState(final Bundle outState) { + super.onSaveInstanceState(outState); + outState.putInt(STATE_STEP, mStepNo); + } + + @Override + protected void onRestoreInstanceState(final Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + mStepNo = savedInstanceState.getInt(STATE_STEP); + } + + @Override + protected void onStart() { + super.onStart(); + mStepNo = determineSetupStepNo(); + } + + @Override + protected void onRestart() { + super.onRestart(); + mStepNo = determineSetupStepNo(); + } + + @Override + protected void onResume() { + super.onResume(); + updateSetupStepView(); + } + + @Override + public void onWindowFocusChanged(final boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if (!hasFocus) { + return; + } + mStepNo = determineSetupStepNo(); + updateSetupStepView(); + } + + private void updateSetupStepView() { + final int layoutDirection = ViewCompatUtils.getLayoutDirection(mStepIndicatorView); + mStepIndicatorView.setIndicatorPosition( + getIndicatorPosition(mStepNo, mSetupSteps.getTotalStep(), layoutDirection)); + mSetupSteps.enableStep(mStepNo); + } + + private static float getIndicatorPosition(final int step, final int totalStep, + final int layoutDirection) { + final float pos = ((step - STEP_1) * 2 + 1) / (float)(totalStep * 2); + return (layoutDirection == ViewCompatUtils.LAYOUT_DIRECTION_RTL) ? 1.0f - pos : pos; + } + + static final class SetupStep implements View.OnClickListener { + private final View mRootView; + private final TextView mActionLabel; + private Runnable mAction; + + public SetupStep(final View rootView, final int title, final int instruction, + final int actionIcon, final int actionLabel) { + mRootView = rootView; + final Resources res = rootView.getResources(); + final String applicationName = res.getString(R.string.english_ime_name); + + final TextView titleView = (TextView)rootView.findViewById(R.id.setup_step_title); + titleView.setText(res.getString(title, applicationName)); + + final TextView instructionView = (TextView)rootView.findViewById( + R.id.setup_step_instruction); + if (instruction == 0) { + instructionView.setVisibility(View.GONE); + } else { + instructionView.setText(res.getString(instruction, applicationName)); + } + + mActionLabel = (TextView)rootView.findViewById(R.id.setup_step_action_label); + mActionLabel.setText(res.getString(actionLabel)); + if (actionIcon == 0) { + final int paddingEnd = ViewCompatUtils.getPaddingEnd(mActionLabel); + ViewCompatUtils.setPaddingRelative(mActionLabel, paddingEnd, 0, paddingEnd, 0); + } else { + final int overrideColor = res.getColor(R.color.setup_text_action); + final Drawable icon = res.getDrawable(actionIcon); + icon.setColorFilter(overrideColor, PorterDuff.Mode.MULTIPLY); + icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight()); + TextViewCompatUtils.setCompoundDrawablesRelative( + mActionLabel, icon, null, null, null); + } + } + + public void setEnabled(final boolean enabled) { + mRootView.setVisibility(enabled ? View.VISIBLE : View.GONE); + } + + public void setAction(final Runnable action) { + mActionLabel.setOnClickListener(this); + mAction = action; + } + + @Override + public void onClick(final View v) { + if (mAction != null) { + mAction.run(); + } + } + } + + static final class SetupStepGroup { + private final HashMap<Integer, SetupStep> mGroup = CollectionUtils.newHashMap(); + + public void addStep(final int stepNo, final SetupStep step) { + mGroup.put(stepNo, step); + } + + public void enableStep(final int enableStepNo) { + for (final Integer stepNo : mGroup.keySet()) { + final SetupStep step = mGroup.get(stepNo); + step.setEnabled(stepNo == enableStepNo); + } + } + + public int getTotalStep() { + return mGroup.size(); + } } } diff --git a/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java b/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java new file mode 100644 index 000000000..077a21793 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2013 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.inputmethod.latin.setup; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.util.AttributeSet; +import android.view.View; + +import com.android.inputmethod.latin.R; + +public final class SetupStepIndicatorView extends View { + private final Path mIndicatorPath = new Path(); + private final Paint mIndicatorPaint = new Paint(); + private float mXRatio; + + public SetupStepIndicatorView(final Context context, final AttributeSet attrs) { + super(context, attrs); + mIndicatorPaint.setColor(getResources().getColor(R.color.setup_step_background)); + mIndicatorPaint.setStyle(Paint.Style.FILL); + } + + public void setIndicatorPosition(final float xRatio) { + mXRatio = xRatio; + invalidate(); + } + + @Override + protected void onDraw(final Canvas canvas) { + super.onDraw(canvas); + final int xPos = (int)(getWidth() * mXRatio); + final int height = getHeight(); + mIndicatorPath.rewind(); + mIndicatorPath.moveTo(xPos, 0); + mIndicatorPath.lineTo(xPos + height, height); + mIndicatorPath.lineTo(xPos - height, height); + mIndicatorPath.close(); + canvas.drawPath(mIndicatorPath, mIndicatorPaint); + } +} |