diff options
Diffstat (limited to 'java')
35 files changed, 375 insertions, 253 deletions
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_popup_background_holo.9.png b/java/res/drawable-hdpi/keyboard_popup_panel_background_holo.9.png Binary files differindex 53d7b6fb3..53d7b6fb3 100644 --- a/java/res/drawable-hdpi/btn_keyboard_key_popup_background_holo.9.png +++ b/java/res/drawable-hdpi/keyboard_popup_panel_background_holo.9.png diff --git a/java/res/drawable-hdpi/sym_keyboard_search_holo.png b/java/res/drawable-hdpi/sym_keyboard_search_holo.png Binary files differindex 72d9e24bf..d888214ec 100644 --- a/java/res/drawable-hdpi/sym_keyboard_search_holo.png +++ b/java/res/drawable-hdpi/sym_keyboard_search_holo.png diff --git a/java/res/drawable-mdpi/btn_keyboard_key_popup_background_holo.9.png b/java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.png Binary files differindex 61988a8e1..61988a8e1 100644 --- a/java/res/drawable-mdpi/btn_keyboard_key_popup_background_holo.9.png +++ b/java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.png diff --git a/java/res/drawable-mdpi/sym_keyboard_search_holo.png b/java/res/drawable-mdpi/sym_keyboard_search_holo.png Binary files differindex 709012a73..9eb214a9d 100644 --- a/java/res/drawable-mdpi/sym_keyboard_search_holo.png +++ b/java/res/drawable-mdpi/sym_keyboard_search_holo.png diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_popup_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.png Binary files differindex 1dee699f4..1dee699f4 100644 --- a/java/res/drawable-xhdpi/btn_keyboard_key_popup_background_holo.9.png +++ b/java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_search_holo.png b/java/res/drawable-xhdpi/sym_keyboard_search_holo.png Binary files differindex 1009706cb..0f4caad91 100644 --- a/java/res/drawable-xhdpi/sym_keyboard_search_holo.png +++ b/java/res/drawable-xhdpi/sym_keyboard_search_holo.png diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml index 88b48fccd..13560e0cf 100644 --- a/java/res/layout/input_view.xml +++ b/java/res/layout/input_view.xml @@ -25,6 +25,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" > + <View + android:id="@+id/key_preview_backing" + android:layout_width="match_parent" + android:layout_height="@dimen/key_preview_backing_height" /> + <!-- On tablets, the suggestions strip is centered with horizontal paddings on both sides because width of the landscape mode is too long for the suggestions strip. This LinearLayout is required to hold the paddings. --> @@ -33,8 +38,6 @@ android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="@dimen/suggestions_view_minimum_height" - android:gravity="bottom" > <View android:layout_width="@dimen/suggestions_strip_padding" diff --git a/java/res/layout/suggestions_strip.xml b/java/res/layout/suggestions_strip.xml index 9252017b4..cbf31e6dc 100644 --- a/java/res/layout/suggestions_strip.xml +++ b/java/res/layout/suggestions_strip.xml @@ -22,16 +22,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" > - <!-- Placer for debug information --> - <RelativeLayout - android:id="@+id/suggestions_placer" + <LinearLayout + android:id="@+id/suggestions_strip" + android:orientation="horizontal" android:layout_width="match_parent" - android:layout_height="match_parent" - > - <LinearLayout - android:id="@+id/suggestions_strip" - android:orientation="horizontal" - android:layout_width="match_parent" - android:layout_height="match_parent" /> - </RelativeLayout> + android:layout_height="match_parent" /> </merge> diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml index 9149b5d2a..0f9bde882 100644 --- a/java/res/values-land/dimens.xml +++ b/java/res/values-land/dimens.xml @@ -60,7 +60,10 @@ <dimen name="suggestions_strip_height">36dip</dimen> <dimen name="more_suggestions_row_height">36dip</dimen> - <dimen name="suggestions_view_minimum_height">160sp</dimen> + <integer name="max_more_suggestions_row">2</integer> + <fraction name="min_more_suggestions_width">60%</fraction> + <!-- key_preview_backing_height = more_suggestions_row_height * max_more_suggestions_row --> + <dimen name="key_preview_backing_height">72dip</dimen> <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> <!-- popup_key_height x 1.2 --> <dimen name="mini_keyboard_slide_allowance">0.336in</dimen> diff --git a/java/res/values-sw600dp-land/dimens.xml b/java/res/values-sw600dp-land/dimens.xml index f1715af64..c1cef1d24 100644 --- a/java/res/values-sw600dp-land/dimens.xml +++ b/java/res/values-sw600dp-land/dimens.xml @@ -51,4 +51,8 @@ <fraction name="key_uppercase_letter_ratio">29%</fraction> <dimen name="suggestions_strip_padding">40.0mm</dimen> + <integer name="max_more_suggestions_row">5</integer> + <fraction name="min_more_suggestions_width">50%</fraction> + <!-- key_preview_backing_height = more_suggestions_row_height * max_more_suggestions_row --> + <dimen name="key_preview_backing_height">220dip</dimen> </resources> diff --git a/java/res/values-sw600dp/dimens.xml b/java/res/values-sw600dp/dimens.xml index 6955736b3..d02b4eaad 100644 --- a/java/res/values-sw600dp/dimens.xml +++ b/java/res/values-sw600dp/dimens.xml @@ -68,6 +68,10 @@ <dimen name="suggestions_strip_height">44dip</dimen> <dimen name="more_suggestions_row_height">44dip</dimen> + <integer name="max_more_suggestions_row">6</integer> + <fraction name="min_more_suggestions_width">90%</fraction> + <!-- key_preview_backing_height = more_suggestions_row_height * max_more_suggestions_row --> + <dimen name="key_preview_backing_height">264dip</dimen> <dimen name="suggestions_strip_padding">15.0mm</dimen> <dimen name="suggestion_min_width">0.3in</dimen> <dimen name="suggestion_padding">12dip</dimen> diff --git a/java/res/values-sw768dp-land/dimens.xml b/java/res/values-sw768dp-land/dimens.xml index 7303ea1e7..8f9b00672 100644 --- a/java/res/values-sw768dp-land/dimens.xml +++ b/java/res/values-sw768dp-land/dimens.xml @@ -59,4 +59,5 @@ <dimen name="key_preview_offset_ics">0.05in</dimen> <dimen name="suggestions_strip_padding">40.0mm</dimen> + <fraction name="min_more_suggestions_width">50%</fraction> </resources> diff --git a/java/res/values-sw768dp/dimens.xml b/java/res/values-sw768dp/dimens.xml index 7d2ac4860..bfc2593db 100644 --- a/java/res/values-sw768dp/dimens.xml +++ b/java/res/values-sw768dp/dimens.xml @@ -71,7 +71,10 @@ <dimen name="suggestions_strip_height">44dip</dimen> <dimen name="more_suggestions_row_height">44dip</dimen> - <dimen name="suggestions_view_minimum_height">200sp</dimen> + <integer name="max_more_suggestions_row">6</integer> + <fraction name="min_more_suggestions_width">90%</fraction> + <!-- key_preview_backing_height = more_suggestions_row_height * max_more_suggestions_row --> + <dimen name="key_preview_backing_height">264dip</dimen> <dimen name="suggestions_strip_padding">15.0mm</dimen> <dimen name="suggestion_min_width">46dip</dimen> <dimen name="suggestion_padding">8dip</dimen> diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index fa6b2eb39..e964889c4 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -22,16 +22,18 @@ <attr name="latinKeyboardStyle" format="reference" /> <!-- KeyboardView style --> <attr name="keyboardViewStyle" format="reference" /> + <!-- MiniKeyboard style --> + <attr name="miniKeyboardStyle" format="reference" /> <!-- MiniKeyboardView style --> <attr name="miniKeyboardViewStyle" format="reference" /> <attr name="miniKeyboardPanelStyle" format="reference" /> <!-- Suggestions strip style --> <attr name="suggestionsStripBackgroundStyle" format="reference" /> - <attr name="suggestionsPaneViewStyle" format="reference" /> + <attr name="suggestionsViewStyle" format="reference" /> + <attr name="moreSuggestionsViewStyle" format="reference" /> <attr name="suggestionBackgroundStyle" format="reference" /> <attr name="suggestionPreviewBackgroundStyle" format="reference" /> - <attr name="suggestionsViewStyle" format="reference" /> - </declare-styleable> + </declare-styleable> <declare-styleable name="KeyboardView"> <!-- Image for the key. This image needs to be a StateListDrawable, with the following @@ -124,19 +126,21 @@ <attr name="colorSuggested" format="color" /> <attr name="suggestionsCountInStrip" format="integer" /> <attr name="centerSuggestionPercentile" format="integer" /> + <attr name="maxMoreSuggestionsRow" format="integer" /> + <attr name="minMoreSuggestionsWidth" format="float" /> </declare-styleable> <declare-styleable name="Keyboard"> <!-- Default keyboard height --> - <attr name="keyboardHeight" format="dimension" /> + <attr name="keyboardHeight" format="dimension|fraction" /> <!-- Maximum keyboard height, in pixels or percentage of display height --> <attr name="maxKeyboardHeight" format="dimension|fraction" /> <!-- Minimum keyboard height represented in pixels, percentage of display height if fraction is positive, or percentage of display width if fraction is negative. --> <attr name="minKeyboardHeight" format="dimension|fraction" /> <!-- Keyboard top and bottom paddings. --> - <attr name="keyboardTopPadding" format="dimension" /> - <attr name="keyboardBottomPadding" format="dimension" /> + <attr name="keyboardTopPadding" format="dimension|fraction" /> + <attr name="keyboardBottomPadding" format="dimension|fraction" /> <!-- Default width of a key, in pixels or percentage of display width. If the value is zero, the actual key width will be determined to fill out the area up to the right edge of the keyboard. diff --git a/java/res/values/config.xml b/java/res/values/config.xml index 1ffbbacbe..d9ff8d7b9 100644 --- a/java/res/values/config.xml +++ b/java/res/values/config.xml @@ -80,6 +80,8 @@ will be subject to auto-correction. --> <item>0</item> </string-array> + <!-- Threshold of the normalized score of the best suggestion for the spell checker to declare a word to be a typo --> + <string name="spellchecker_typo_threshold_value">0.11</string> <!-- Screen metrics for logging. 0 = "mdpi", 1 = "hdpi", 2 = "xlarge" --> <integer name="log_screen_metrics">0</integer> <bool name="config_require_umlaut_processing">false</bool> diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index a506ed74d..feb119db2 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -48,7 +48,7 @@ <fraction name="keyboard_bottom_padding_ics">4.669%p</fraction> <fraction name="key_bottom_gap_ics">6.127%p</fraction> <fraction name="key_horizontal_gap_ics">1.739%p</fraction> - <dimen name="mini_keyboard_horizontal_edges_padding_ics">6dp</dimen> + <dimen name="mini_keyboard_horizontal_edges_padding_ics">4dip</dimen> <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> <!-- popup_key_height x 1.2 --> @@ -79,9 +79,14 @@ <dimen name="suggestions_strip_height">40dip</dimen> <dimen name="more_suggestions_key_horizontal_padding">12dip</dimen> <dimen name="more_suggestions_row_height">40dip</dimen> - <dimen name="more_suggestions_slide_allowance">0.2in</dimen> - <fraction name="more_suggestions_info_ratio">12%</fraction> - <dimen name="suggestions_view_minimum_height">200sp</dimen> + <dimen name="more_suggestions_bottom_gap">6dip</dimen> + <dimen name="more_suggestions_modal_tolerance">0.05in</dimen> + <dimen name="more_suggestions_slide_allowance">0.1in</dimen> + <integer name="max_more_suggestions_row">6</integer> + <fraction name="min_more_suggestions_width">90%</fraction> + <fraction name="more_suggestions_info_ratio">18%</fraction> + <!-- key_preview_backing_height = more_suggestions_row_height * max_more_suggestions_row --> + <dimen name="key_preview_backing_height">160dip</dimen> <dimen name="suggestions_strip_padding">0dip</dimen> <dimen name="suggestion_min_width">44dip</dimen> <dimen name="suggestion_padding">6dip</dimen> diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml index 17b3d14ab..0e8216b48 100644 --- a/java/res/values/styles.xml +++ b/java/res/values/styles.xml @@ -68,6 +68,14 @@ <item name="backgroundDimAmount">0.5</item> </style> <style + name="MiniKeyboard" + parent="Keyboard" + > + <item name="keyboardTopPadding">0dip</item> + <item name="keyboardBottomPadding">0dip</item> + <item name="horizontalGap">0dip</item> + </style> + <style name="MiniKeyboardView" parent="KeyboardView" > @@ -79,20 +87,9 @@ <item name="android:paddingLeft">@dimen/mini_keyboard_horizontal_edges_padding</item> <item name="android:paddingRight">@dimen/mini_keyboard_horizontal_edges_padding</item> </style> - <style - name="SuggestionsPaneViewStyle" - parent="MiniKeyboardView" - > - </style> <style name="SuggestionsStripBackgroundStyle"> <item name="android:background">@drawable/keyboard_suggest_strip</item> </style> - <style name="SuggestionBackgroundStyle"> - <item name="android:background">@drawable/btn_suggestion</item> - </style> - <style name="SuggestionPreviewBackgroundStyle"> - <item name="android:background">@drawable/suggestion_feedback_background</item> - </style> <style name="SuggestionsViewStyle" parent="SuggestionsStripBackgroundStyle" @@ -103,6 +100,19 @@ <item name="colorSuggested">#FFFCAE00</item> <item name="suggestionsCountInStrip">@integer/suggestions_count_in_strip</item> <item name="centerSuggestionPercentile">@integer/center_suggestion_percentile</item> + <item name="maxMoreSuggestionsRow">@integer/max_more_suggestions_row</item> + <item name="minMoreSuggestionsWidth">@fraction/min_more_suggestions_width</item> + </style> + <style + name="MoreSuggestionsViewStyle" + parent="MiniKeyboardView" + > + </style> + <style name="SuggestionBackgroundStyle"> + <item name="android:background">@drawable/btn_suggestion</item> + </style> + <style name="SuggestionPreviewBackgroundStyle"> + <item name="android:background">@drawable/suggestion_feedback_background</item> </style> <!-- Theme "Basic high contrast" --> <style @@ -144,6 +154,14 @@ <item name="shadowColor">#FFFFFFFF</item> </style> <style + name="MiniKeyboard.Stone" + parent="Keyboard.Stone" + > + <item name="keyboardTopPadding">0dip</item> + <item name="keyboardBottomPadding">0dip</item> + <item name="horizontalGap">0dip</item> + </style> + <style name="MiniKeyboardView.Stone" parent="MiniKeyboardView" > @@ -175,6 +193,14 @@ <item name="keyTextStyle">bold</item> </style> <style + name="MiniKeyboard.Gingerbread" + parent="Keyboard.Gingerbread" + > + <item name="keyboardTopPadding">0dip</item> + <item name="keyboardBottomPadding">0dip</item> + <item name="horizontalGap">0dip</item> + </style> + <style name="MiniKeyboardView.Gingerbread" parent="MiniKeyboardView" > @@ -218,6 +244,14 @@ <item name="shadowRadius">0.0</item> </style> <style + name="MiniKeyboard.IceCreamSandwich" + parent="Keyboard.IceCreamSandwich" + > + <item name="keyboardTopPadding">0dip</item> + <item name="keyboardBottomPadding">0dip</item> + <item name="horizontalGap">0dip</item> + </style> + <style name="MiniKeyboardView.IceCreamSandwich" parent="MiniKeyboardView" > @@ -225,26 +259,13 @@ <item name="keyBackground">@drawable/btn_keyboard_key_popup_ics</item> </style> <style name="MiniKeyboardPanelStyle.IceCreamSandwich"> - <item name="android:background">@drawable/btn_keyboard_key_popup_background_holo</item> + <item name="android:background">@drawable/keyboard_popup_panel_background_holo</item> <item name="android:paddingLeft">@dimen/mini_keyboard_horizontal_edges_padding_ics</item> <item name="android:paddingRight">@dimen/mini_keyboard_horizontal_edges_padding_ics</item> </style> <style name="SuggestionsStripBackgroundStyle.IceCreamSandwich"> <item name="android:background">@drawable/keyboard_suggest_strip_holo</item> </style> - <style name="SuggestionBackgroundStyle.IceCreamSandwich"> - <item name="android:background">@drawable/btn_suggestion_ics</item> - </style> - <style - name="SuggestionPreviewBackgroundStyle.IceCreamSandwich" - parent="MiniKeyboardPanelStyle.IceCreamSandwich" - > - </style> - <style - name="SuggestionsPaneViewStyle.IceCreamSandwich" - parent="MiniKeyboardView.IceCreamSandwich" - > - </style> <style name="SuggestionsViewStyle.IceCreamSandwich" parent="SuggestionsStripBackgroundStyle.IceCreamSandwich" @@ -255,6 +276,21 @@ <item name="colorSuggested">#FFA7A9AC</item> <item name="suggestionsCountInStrip">@integer/suggestions_count_in_strip</item> <item name="centerSuggestionPercentile">@integer/center_suggestion_percentile</item> + <item name="maxMoreSuggestionsRow">@integer/max_more_suggestions_row</item> + <item name="minMoreSuggestionsWidth">@fraction/min_more_suggestions_width</item> + </style> + <style + name="MoreSuggestionsViewStyle.IceCreamSandwich" + parent="MiniKeyboardView.IceCreamSandwich" + > + </style> + <style name="SuggestionBackgroundStyle.IceCreamSandwich"> + <item name="android:background">@drawable/btn_suggestion_ics</item> + </style> + <style + name="SuggestionPreviewBackgroundStyle.IceCreamSandwich" + parent="MiniKeyboardPanelStyle.IceCreamSandwich" + > </style> <style name="MiniKeyboardAnimation"> <item name="android:windowEnterAnimation">@anim/mini_keyboard_fadein</item> diff --git a/java/res/values/themes-basic-highcontrast.xml b/java/res/values/themes-basic-highcontrast.xml index ee4109326..ce0598042 100644 --- a/java/res/values/themes-basic-highcontrast.xml +++ b/java/res/values/themes-basic-highcontrast.xml @@ -19,12 +19,13 @@ <item name="keyboardStyle">@style/Keyboard</item> <item name="latinKeyboardStyle">@style/LatinKeyboard</item> <item name="keyboardViewStyle">@style/KeyboardView.HighContrast</item> + <item name="miniKeyboardStyle">@style/MiniKeyboard</item> <item name="miniKeyboardViewStyle">@style/MiniKeyboardView</item> <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item> <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item> - <item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle</item> + <item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item> + <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item> <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item> <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item> - <item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item> </style> </resources> diff --git a/java/res/values/themes-basic.xml b/java/res/values/themes-basic.xml index ff7f9ed35..ff9fed55f 100644 --- a/java/res/values/themes-basic.xml +++ b/java/res/values/themes-basic.xml @@ -19,12 +19,13 @@ <item name="keyboardStyle">@style/Keyboard</item> <item name="latinKeyboardStyle">@style/LatinKeyboard</item> <item name="keyboardViewStyle">@style/KeyboardView</item> + <item name="miniKeyboardStyle">@style/MiniKeyboard</item> <item name="miniKeyboardViewStyle">@style/MiniKeyboardView</item> <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item> <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item> - <item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle</item> + <item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item> + <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item> <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item> <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item> - <item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item> </style> </resources> diff --git a/java/res/values/themes-gingerbread.xml b/java/res/values/themes-gingerbread.xml index af91c3bed..be853eb0f 100644 --- a/java/res/values/themes-gingerbread.xml +++ b/java/res/values/themes-gingerbread.xml @@ -19,12 +19,13 @@ <item name="keyboardStyle">@style/Keyboard.Gingerbread</item> <item name="latinKeyboardStyle">@style/LatinKeyboard</item> <item name="keyboardViewStyle">@style/KeyboardView.Gingerbread</item> + <item name="miniKeyboardStyle">@style/MiniKeyboard.Gingerbread</item> <item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Gingerbread</item> <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item> <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item> - <item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle</item> + <item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item> + <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item> <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item> <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item> - <item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item> </style> </resources> diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml index 341afcc53..618aaed79 100644 --- a/java/res/values/themes-ics.xml +++ b/java/res/values/themes-ics.xml @@ -19,12 +19,13 @@ <item name="keyboardStyle">@style/Keyboard.IceCreamSandwich</item> <item name="latinKeyboardStyle">@style/LatinKeyboard.IceCreamSandwich</item> <item name="keyboardViewStyle">@style/KeyboardView.IceCreamSandwich</item> + <item name="miniKeyboardStyle">@style/MiniKeyboard.IceCreamSandwich</item> <item name="miniKeyboardViewStyle">@style/MiniKeyboardView.IceCreamSandwich</item> <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle.IceCreamSandwich</item> <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle.IceCreamSandwich</item> - <item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle.IceCreamSandwich</item> + <item name="suggestionsViewStyle">@style/SuggestionsViewStyle.IceCreamSandwich</item> + <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle.IceCreamSandwich</item> <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle.IceCreamSandwich</item> <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle.IceCreamSandwich</item> - <item name="suggestionsViewStyle">@style/SuggestionsViewStyle.IceCreamSandwich</item> </style> </resources> diff --git a/java/res/values/themes-stone-bold.xml b/java/res/values/themes-stone-bold.xml index 915f2263e..fdf9c51f5 100644 --- a/java/res/values/themes-stone-bold.xml +++ b/java/res/values/themes-stone-bold.xml @@ -19,12 +19,13 @@ <item name="keyboardStyle">@style/Keyboard.Stone</item> <item name="latinKeyboardStyle">@style/LatinKeyboard.Stone</item> <item name="keyboardViewStyle">@style/KeyboardView.Stone.Bold</item> + <item name="miniKeyboardStyle">@style/MiniKeyboard.Stone</item> <item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Stone</item> <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item> <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item> - <item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle</item> - <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item> - <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item> <item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item> + <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item> + <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item> + <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item> </style> </resources> diff --git a/java/res/values/themes-stone.xml b/java/res/values/themes-stone.xml index 6d5b9dbae..cb3edc58f 100644 --- a/java/res/values/themes-stone.xml +++ b/java/res/values/themes-stone.xml @@ -19,12 +19,13 @@ <item name="keyboardStyle">@style/Keyboard.Stone</item> <item name="latinKeyboardStyle">@style/LatinKeyboard.Stone</item> <item name="keyboardViewStyle">@style/KeyboardView.Stone</item> + <item name="miniKeyboardStyle">@style/MiniKeyboard.Stone</item> <item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Stone</item> <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item> <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item> - <item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle</item> + <item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item> + <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item> <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item> <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item> - <item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item> </style> </resources> diff --git a/java/res/xml/kbd_mini_keyboard_template.xml b/java/res/xml/kbd_mini_keyboard_template.xml index d25878b48..ad6cf51fe 100644 --- a/java/res/xml/kbd_mini_keyboard_template.xml +++ b/java/res/xml/kbd_mini_keyboard_template.xml @@ -21,5 +21,6 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyWidth="10%p" latin:rowHeight="@dimen/popup_key_height" + style="?attr/miniKeyboardStyle" > </Keyboard> diff --git a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java index b6b86a4a0..a6bb83adf 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java @@ -100,8 +100,7 @@ public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper public String getLocale() { if (mObj == null) return mDummyLocale; final String s = (String)CompatUtils.invoke(mObj, null, METHOD_getLocale); - if (TextUtils.isEmpty(s)) return DEFAULT_LOCALE; - return s; + return s != null ? s : DEFAULT_LOCALE; } public String getMode() { diff --git a/java/src/com/android/inputmethod/compat/LinearLayoutCompatUtils.java b/java/src/com/android/inputmethod/compat/LinearLayoutCompatUtils.java deleted file mode 100644 index 674cbe74b..000000000 --- a/java/src/com/android/inputmethod/compat/LinearLayoutCompatUtils.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2011 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.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.util.Log; - -import java.lang.reflect.Field; - -public class LinearLayoutCompatUtils { - private static final String TAG = LinearLayoutCompatUtils.class.getSimpleName(); - - private static final Class<?> CLASS_R_STYLEABLE = CompatUtils.getClass( - "com.android.internal.R$styleable"); - private static final Field STYLEABLE_VIEW = CompatUtils.getField( - CLASS_R_STYLEABLE, "View"); - private static final Field STYLEABLE_VIEW_BACKGROUND = CompatUtils.getField( - CLASS_R_STYLEABLE, "View_background"); - private static final Object VALUE_STYLEABLE_VIEW = CompatUtils.getFieldValue( - null, null, STYLEABLE_VIEW); - private static final Integer VALUE_STYLEABLE_VIEW_BACKGROUND = - (Integer)CompatUtils.getFieldValue(null, null, STYLEABLE_VIEW_BACKGROUND); - - public static Drawable getBackgroundDrawable(Context context, AttributeSet attrs, - int defStyleAttr, int defStyleRes) { - if (!(VALUE_STYLEABLE_VIEW instanceof int[]) || VALUE_STYLEABLE_VIEW_BACKGROUND == null) { - Log.w(TAG, "Can't get View background attribute using reflection"); - return null; - } - - final int[] styleableView = (int[])VALUE_STYLEABLE_VIEW; - final TypedArray a = context.obtainStyledAttributes( - attrs, styleableView, defStyleAttr, defStyleRes); - final Drawable background = a.getDrawable(VALUE_STYLEABLE_VIEW_BACKGROUND); - a.recycle(); - return background; - } -} diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index d9089e199..4ec16bdcf 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -438,8 +438,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke mMoreKeysWindow = new PopupWindow(getContext()); mMoreKeysWindow.setBackgroundDrawable(null); mMoreKeysWindow.setAnimationStyle(R.style.MiniKeyboardAnimation); - // Allow popup window to be drawn off the screen. - mMoreKeysWindow.setClippingEnabled(false); } mMoreKeysPanel = moreKeysPanel; mMoreKeysPanelPointerTrackerId = tracker.mPointerId; @@ -552,7 +550,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke mOldKeyIndex = tracker.getKeyIndexOn(lastX, lastY); tracker.onUpEvent(lastX, lastY, eventTime); } else if (pointerCount == 1 && oldPointerCount == 1) { - processMotionEvent(tracker, action, x, y, eventTime, this); + tracker.processMotionEvent(action, x, y, eventTime, this); } else { Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount + " (old " + oldPointerCount + ")"); @@ -575,32 +573,12 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke tracker.onMoveEvent(px, py, eventTime); } } else { - processMotionEvent(getPointerTracker(id), action, x, y, eventTime, this); + getPointerTracker(id).processMotionEvent(action, x, y, eventTime, this); } return true; } - private static void processMotionEvent(PointerTracker tracker, int action, int x, int y, - long eventTime, PointerTracker.KeyEventHandler handler) { - switch (action) { - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_POINTER_DOWN: - tracker.onDownEvent(x, y, eventTime, handler); - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_POINTER_UP: - tracker.onUpEvent(x, y, eventTime); - break; - case MotionEvent.ACTION_MOVE: - tracker.onMoveEvent(x, y, eventTime); - break; - case MotionEvent.ACTION_CANCEL: - tracker.onCancelEvent(x, y, eventTime); - break; - } - } - @Override public void closing() { super.closing(); diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java index da91b62d9..ad8056cc0 100644 --- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java @@ -123,7 +123,9 @@ public class MiniKeyboard extends Keyboard { } mWidth = mOccupiedWidth = mNumColumns * mDefaultKeyWidth; - mHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight + mVerticalGap; + // Need to subtract the bottom row's gutter only. + mHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight - mVerticalGap + + mTopPadding + mBottomPadding; } // Return key position according to column count (0 is default). @@ -209,20 +211,9 @@ public class MiniKeyboard extends Keyboard { super(view.getContext(), new MiniKeyboardParams()); load(parentKeyboard.mId.cloneWithNewXml(mResources.getResourceEntryName(xmlId), xmlId)); - // HACK: Current mini keyboard design totally relies on the 9-patch - // padding about horizontal - // and vertical key spacing. To keep the visual of mini keyboard as - // is, these hacks are - // needed to keep having the same horizontal and vertical key - // spacing. - mParams.mHorizontalGap = 0; - mParams.mVerticalGap = mParams.mTopPadding = parentKeyboard.mVerticalGap / 2; - // TODO: When we have correctly padded key background 9-patch - // drawables for mini keyboard, - // revert the above hacks and uncomment the following lines. - // mParams.mHorizontalGap = parentKeyboard.mHorizontalGap; - // mParams.mVerticalGap = parentKeyboard.mVerticalGap; - + // TODO: Mini keyboard's vertical gap is currently calculated heuristically. + // Should revise the algorithm. + mParams.mVerticalGap = parentKeyboard.mVerticalGap / 2; mParams.mIsRtlKeyboard = parentKeyboard.mIsRtlKeyboard; mMoreKeys = parentKey.mMoreKeys; diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java index 29861fe4a..0e6e129bb 100644 --- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java @@ -79,10 +79,8 @@ public class MiniKeyboardView extends KeyboardView implements MoreKeysPanel { super(context, attrs, defStyle); final Resources res = context.getResources(); - // Override default ProximityKeyDetector. - mKeyDetector = new MoreKeysDetector(res.getDimension( - R.dimen.mini_keyboard_slide_allowance)); - // Remove gesture detector on mini-keyboard + mKeyDetector = new MoreKeysDetector( + res.getDimension(R.dimen.mini_keyboard_slide_allowance)); setKeyPreviewPopupEnabled(false, 0); } diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 0314867b3..38c419dc6 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard; import android.content.Context; import android.content.res.Resources; import android.util.Log; +import android.view.MotionEvent; import android.widget.TextView; import com.android.inputmethod.keyboard.internal.PointerTrackerQueue; @@ -398,6 +399,26 @@ public class PointerTracker { return onMoveKeyInternal(x, y); } + public void processMotionEvent(int action, int x, int y, long eventTime, + KeyEventHandler handler) { + switch (action) { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_POINTER_DOWN: + onDownEvent(x, y, eventTime, handler); + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_POINTER_UP: + onUpEvent(x, y, eventTime); + break; + case MotionEvent.ACTION_MOVE: + onMoveEvent(x, y, eventTime); + break; + case MotionEvent.ACTION_CANCEL: + onCancelEvent(x, y, eventTime); + break; + } + } + public void onDownEvent(int x, int y, long eventTime, KeyEventHandler handler) { if (DEBUG_EVENT) printTouchEvent("onDownEvent:", x, y, eventTime); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index cea59fe0a..191ae5811 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -157,6 +157,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private Settings.Values mSettingsValues; + private View mKeyPreviewBackingView; private View mSuggestionsContainer; private int mSuggestionsStripHeight; private SuggestionsView mSuggestionsView; @@ -607,6 +608,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar @Override public void setInputView(View view) { super.setInputView(view); + mKeyPreviewBackingView = view.findViewById(R.id.key_preview_backing); mSuggestionsContainer = view.findViewById(R.id.suggestions_container); mSuggestionsView = (SuggestionsView) view.findViewById(R.id.suggestions_view); if (mSuggestionsView != null) @@ -945,12 +947,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true); if (isFullscreenMode()) { // No need to have extra space to show the key preview. - mSuggestionsContainer.setMinimumHeight(0); + mKeyPreviewBackingView.setVisibility(View.GONE); mSuggestionsContainer.setVisibility( shouldShowSuggestions ? View.VISIBLE : View.GONE); } else { // We must control the visibility of the suggestion strip in order to avoid clipped // key previews, even when we don't show the suggestion strip. + mKeyPreviewBackingView.setVisibility(View.VISIBLE); mSuggestionsContainer.setVisibility( shouldShowSuggestions ? View.VISIBLE : View.INVISIBLE); } @@ -967,15 +970,17 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar final KeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); if (inputView == null || mSuggestionsContainer == null) return; - final int containerHeight = mSuggestionsContainer.getHeight(); - int touchY = containerHeight; + final int backingHeight = (mKeyPreviewBackingView.getVisibility() == View.GONE) ? 0 + : mKeyPreviewBackingView.getHeight(); + final int extraHeight = mSuggestionsContainer.getHeight() + backingHeight; + int touchY = extraHeight; // Need to set touchable region only if input view is being shown if (mKeyboardSwitcher.isInputViewShown()) { if (mSuggestionsContainer.getVisibility() == View.VISIBLE) { touchY -= mSuggestionsStripHeight; } final int touchWidth = inputView.getWidth(); - final int touchHeight = inputView.getHeight() + containerHeight + final int touchHeight = inputView.getHeight() + extraHeight // Extend touchable region below the keyboard. + EXTENDED_TOUCHABLE_REGION_HEIGHT; if (DEBUG) { diff --git a/java/src/com/android/inputmethod/latin/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/MoreSuggestions.java index a9e75b7b3..10d5b5c48 100644 --- a/java/src/com/android/inputmethod/latin/MoreSuggestions.java +++ b/java/src/com/android/inputmethod/latin/MoreSuggestions.java @@ -50,8 +50,8 @@ public class MoreSuggestions extends Keyboard { private static final int MAX_COLUMNS_IN_ROW = 3; private int mNumRows; - public int layout(SuggestedWords suggestions, int fromPos, int maxWidth, int maxHeight, - KeyboardView view) { + public int layout(SuggestedWords suggestions, int fromPos, int maxWidth, int minWidth, + int maxRow, KeyboardView view) { clearKeys(); final Paint paint = new Paint(); paint.setAntiAlias(true); @@ -68,7 +68,7 @@ public class MoreSuggestions extends Keyboard { final int numColumn = pos - rowStartPos + 1; if (numColumn > MAX_COLUMNS_IN_ROW || !fitInWidth(rowStartPos, pos + 1, maxWidth / numColumn)) { - if ((row + 1) * mDefaultRowHeight > maxHeight) { + if ((row + 1) >= maxRow) { break; } mNumColumnsInRow[row] = pos - rowStartPos; @@ -81,7 +81,7 @@ public class MoreSuggestions extends Keyboard { } mNumColumnsInRow[row] = pos - rowStartPos; mNumRows = row + 1; - mWidth = mOccupiedWidth = calcurateMaxRowWidth(fromPos, pos); + mWidth = mOccupiedWidth = Math.max(minWidth, calcurateMaxRowWidth(fromPos, pos)); mHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight + mVerticalGap; return pos - fromPos; } @@ -163,13 +163,14 @@ public class MoreSuggestions extends Keyboard { } public Builder layout(SuggestedWords suggestions, int fromPos, int maxWidth, - int maxHeight) { + int minWidth, int maxRow) { final Keyboard keyboard = KeyboardSwitcher.getInstance().getLatinKeyboard(); final int xmlId = R.xml.kbd_suggestions_pane_template; load(keyboard.mId.cloneWithNewXml(mResources.getResourceEntryName(xmlId), xmlId)); mParams.mVerticalGap = mParams.mTopPadding = keyboard.mVerticalGap / 2; - final int count = mParams.layout(suggestions, fromPos, maxWidth, maxHeight, mPaneView); + final int count = mParams.layout(suggestions, fromPos, maxWidth, minWidth, maxRow, + mPaneView); mFromPos = fromPos; mToPos = fromPos + count; mSuggestions = suggestions; diff --git a/java/src/com/android/inputmethod/latin/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/MoreSuggestionsView.java index 9fd90241b..f595510a3 100644 --- a/java/src/com/android/inputmethod/latin/MoreSuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/MoreSuggestionsView.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.res.Resources; import android.util.AttributeSet; import android.view.Gravity; +import android.view.MotionEvent; import android.view.View; import android.widget.PopupWindow; @@ -29,7 +30,9 @@ import com.android.inputmethod.keyboard.KeyboardActionListener; import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.keyboard.MoreKeysDetector; import com.android.inputmethod.keyboard.MoreKeysPanel; +import com.android.inputmethod.keyboard.PointerTracker; import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy; +import com.android.inputmethod.keyboard.PointerTracker.KeyEventHandler; import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; @@ -40,7 +43,8 @@ import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel { private final int[] mCoordinates = new int[2]; - private final KeyDetector mKeyDetector; + private final KeyDetector mModalPanelKeyDetector; + private final KeyDetector mSlidingPanelKeyDetector; private Controller mController; private KeyboardActionListener mListener; @@ -73,17 +77,16 @@ public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel { }; public MoreSuggestionsView(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.suggestionsPaneViewStyle); + this(context, attrs, R.attr.moreSuggestionsViewStyle); } public MoreSuggestionsView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); final Resources res = context.getResources(); - // Override default ProximityKeyDetector. - mKeyDetector = new MoreKeysDetector(res.getDimension( - R.dimen.more_suggestions_slide_allowance)); - // Remove gesture detector on suggestions pane + mModalPanelKeyDetector = new KeyDetector(/* keyHysteresisDistance */ 0); + mSlidingPanelKeyDetector = new MoreKeysDetector( + res.getDimension(R.dimen.more_suggestions_slide_allowance)); setKeyPreviewPopupEnabled(false, 0); } @@ -102,13 +105,14 @@ public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel { @Override public void setKeyboard(Keyboard keyboard) { super.setKeyboard(keyboard); - mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), + mModalPanelKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), -getPaddingTop()); + mSlidingPanelKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection); } @Override public KeyDetector getKeyDetector() { - return mKeyDetector; + return mSlidingPanelKeyDetector; } @Override @@ -187,4 +191,39 @@ public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel { public int translateY(int y) { return y - mOriginY; } + + private final KeyEventHandler mModalPanelKeyEventHandler = new KeyEventHandler() { + @Override + public KeyDetector getKeyDetector() { + return mModalPanelKeyDetector; + } + + @Override + public KeyboardActionListener getKeyboardActionListener() { + return mSuggestionsPaneListener; + } + + @Override + public DrawingProxy getDrawingProxy() { + return MoreSuggestionsView.this; + } + + @Override + public TimerProxy getTimerProxy() { + return EMPTY_TIMER_PROXY; + } + }; + + @Override + public boolean onTouchEvent(MotionEvent me) { + final int action = me.getAction(); + final long eventTime = me.getEventTime(); + final int index = me.getActionIndex(); + final int id = me.getPointerId(index); + final PointerTracker tracker = PointerTracker.getPointerTracker(id, this); + final int x = (int)me.getX(index); + final int y = (int)me.getY(index); + tracker.processMotionEvent(action, x, y, eventTime, mModalPanelKeyEventHandler); + return true; + } } diff --git a/java/src/com/android/inputmethod/latin/SuggestionsView.java b/java/src/com/android/inputmethod/latin/SuggestionsView.java index 10cd73dd3..22aa5e259 100644 --- a/java/src/com/android/inputmethod/latin/SuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/SuggestionsView.java @@ -35,7 +35,6 @@ import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.text.style.UnderlineSpan; import android.util.AttributeSet; -import android.util.DisplayMetrics; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -45,10 +44,10 @@ import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.PopupWindow; +import android.widget.RelativeLayout; import android.widget.TextView; import com.android.inputmethod.compat.FrameLayoutCompatUtils; -import com.android.inputmethod.compat.LinearLayoutCompatUtils; import com.android.inputmethod.keyboard.KeyboardActionListener; import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.keyboard.MoreKeysPanel; @@ -58,7 +57,8 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import java.util.ArrayList; import java.util.List; -public class SuggestionsView extends LinearLayout implements OnClickListener, OnLongClickListener { +public class SuggestionsView extends RelativeLayout implements OnClickListener, + OnLongClickListener { public interface Listener { public boolean addWordToDictionary(String word); public void pickSuggestionManually(int index, CharSequence word); @@ -69,7 +69,6 @@ public class SuggestionsView extends LinearLayout implements OnClickListener, On private static final boolean DBG = LatinImeLogger.sDBG; - private final ViewGroup mSuggestionsPlacer; private final ViewGroup mSuggestionsStrip; private KeyboardView mKeyboardView; @@ -146,12 +145,16 @@ public class SuggestionsView extends LinearLayout implements OnClickListener, On private static class SuggestionsViewParams { private static final int DEFAULT_SUGGESTIONS_COUNT_IN_STRIP = 3; private static final int DEFAULT_CENTER_SUGGESTION_PERCENTILE = 40; + private static final int DEFAULT_MAX_MORE_SUGGESTIONS_ROW = 2; private static final int PUNCTUATIONS_IN_STRIP = 6; public final int mPadding; public final int mDividerWidth; public final int mSuggestionsStripHeight; public final int mSuggestionsCountInStrip; + public final int mMaxMoreSuggestionsRow; + public final float mMinMoreSuggestionsWidth; + public final int mMoreSuggestionsBottomGap; private final List<TextView> mWords; private final List<View> mDividers; @@ -211,10 +214,17 @@ public class SuggestionsView extends LinearLayout implements OnClickListener, On mCenterSuggestionWeight = a.getInt( R.styleable.SuggestionsView_centerSuggestionPercentile, DEFAULT_CENTER_SUGGESTION_PERCENTILE) / 100.0f; + mMaxMoreSuggestionsRow = a.getInt( + R.styleable.SuggestionsView_maxMoreSuggestionsRow, + DEFAULT_MAX_MORE_SUGGESTIONS_ROW); + mMinMoreSuggestionsWidth = getRatio(a, + R.styleable.SuggestionsView_minMoreSuggestionsWidth); a.recycle(); mCenterSuggestionIndex = mSuggestionsCountInStrip / 2; mMoreSuggestionsHint = res.getDrawable(R.drawable.more_suggestions_hint); + mMoreSuggestionsBottomGap = res.getDimensionPixelOffset( + R.dimen.more_suggestions_bottom_gap); mInvertedForegroundColorSpan = new ForegroundColorSpan(mColorTypedWord ^ 0x00ffffff); mInvertedBackgroundColorSpan = new BackgroundColorSpan(mColorTypedWord); @@ -225,6 +235,11 @@ public class SuggestionsView extends LinearLayout implements OnClickListener, On mHintToSaveText = context.getText(R.string.hint_add_to_dictionary); } + // Read fraction value in TypedArray as float. + private static float getRatio(TypedArray a, int index) { + return a.getFraction(index, 1000, 1000, 1) / 1000.0f; + } + private CharSequence getStyledSuggestionWord(SuggestedWords suggestions, int pos) { final CharSequence word = suggestions.getWord(pos); final boolean isAutoCorrect = pos == 1 && willAutoCorrect(suggestions); @@ -451,18 +466,7 @@ public class SuggestionsView extends LinearLayout implements OnClickListener, On } public SuggestionsView(Context context, AttributeSet attrs, int defStyle) { - // Note: Up to version 10 (Gingerbread) of the API, LinearLayout doesn't have 3-argument - // constructor. - // TODO: Call 3-argument constructor, super(context, attrs, defStyle), when we abandon - // backward compatibility with the version 10 or earlier of the API. - super(context, attrs); - if (defStyle != R.attr.suggestionsViewStyle) { - throw new IllegalArgumentException( - "can't accept defStyle other than R.attr.suggestionsViewStyle: defStyle=" - + defStyle); - } - setBackgroundDrawable(LinearLayoutCompatUtils.getBackgroundDrawable( - context, attrs, defStyle, R.style.SuggestionsViewStyle)); + super(context, attrs, defStyle); final LayoutInflater inflater = LayoutInflater.from(context); inflater.inflate(R.layout.suggestions_strip, this); @@ -474,7 +478,6 @@ public class SuggestionsView extends LinearLayout implements OnClickListener, On mPreviewPopup.setContentView(mPreviewText); mPreviewPopup.setBackgroundDrawable(null); - mSuggestionsPlacer = (ViewGroup)findViewById(R.id.suggestions_placer); mSuggestionsStrip = (ViewGroup)findViewById(R.id.suggestions_strip); for (int pos = 0; pos < MAX_SUGGESTIONS; pos++) { final TextView word = (TextView)inflater.inflate(R.layout.suggestion_word, null); @@ -500,6 +503,9 @@ public class SuggestionsView extends LinearLayout implements OnClickListener, On mMoreSuggestionsWindow.setWindowLayoutMode( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); mMoreSuggestionsWindow.setBackgroundDrawable(null); + final Resources res = context.getResources(); + mMoreSuggestionsModalTolerance = res.getDimensionPixelOffset( + R.dimen.more_suggestions_modal_tolerance); } /** @@ -527,7 +533,7 @@ public class SuggestionsView extends LinearLayout implements OnClickListener, On if (mSuggestions.size() == 0) return; - mParams.layout(mSuggestions, mSuggestionsStrip, mSuggestionsPlacer, getWidth()); + mParams.layout(mSuggestions, mSuggestionsStrip, this, getWidth()); } private static CharSequence getDebugInfo(SuggestedWords suggestions, int pos) { @@ -648,9 +654,9 @@ public class SuggestionsView extends LinearLayout implements OnClickListener, On public void clear() { mShowingAutoCorrectionInverted = false; - mSuggestionsPlacer.removeAllViews(); - mSuggestionsPlacer.addView(mSuggestionsStrip); mSuggestionsStrip.removeAllViews(); + removeAllViews(); + addView(mSuggestionsStrip); dismissMoreSuggestions(); } @@ -730,27 +736,23 @@ public class SuggestionsView extends LinearLayout implements OnClickListener, On final View container = mMoreSuggestionsContainer; final int maxWidth = stripWidth - container.getPaddingLeft() - container.getPaddingRight(); - final DisplayMetrics dm = getContext().getResources().getDisplayMetrics(); - // TODO: Revise how we determine the height - final int maxHeight = dm.heightPixels - mKeyboardView.getHeight() - getHeight() * 3; final MoreSuggestions.Builder builder = mMoreSuggestionsBuilder; - builder.layout(mSuggestions, params.mSuggestionsCountInStrip, maxWidth, maxHeight); + builder.layout(mSuggestions, params.mSuggestionsCountInStrip, maxWidth, + (int)(maxWidth * params.mMinMoreSuggestionsWidth), + params.mMaxMoreSuggestionsRow); mMoreSuggestionsView.setKeyboard(builder.build()); container.measure( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); final MoreKeysPanel moreKeysPanel = mMoreSuggestionsView; final int pointX = stripWidth / 2; - final int pointY = 0; + final int pointY = -params.mMoreSuggestionsBottomGap; moreKeysPanel.showMoreKeysPanel( this, mMoreSuggestionsController, pointX, pointY, mMoreSuggestionsWindow, mMoreSuggestionsListener); - // TODO: Should figure out how to select the pointer tracker correctly. - final PointerTracker tracker = PointerTracker.getPointerTracker(0, moreKeysPanel); - final int translatedX = moreKeysPanel.translateX(tracker.getLastX()); - final int translatedY = moreKeysPanel.translateY(tracker.getLastY()); - tracker.onShowMoreKeysPanel( - translatedX, translatedY, SystemClock.uptimeMillis(), moreKeysPanel); + mCheckingIfModalOrSlidingMode = true; + mOriginX = mLastX; + mOriginY = mLastY; view.setPressed(false); mKeyboardView.dimEntireKeyboard(true); return true; @@ -758,34 +760,51 @@ public class SuggestionsView extends LinearLayout implements OnClickListener, On return false; } + // Working variables for onLongClick and dispatchTouchEvent. + private boolean mCheckingIfModalOrSlidingMode; + private int mLastX; + private int mLastY; + private int mOriginX; + private int mOriginY; + private final int mMoreSuggestionsModalTolerance; + @Override public boolean dispatchTouchEvent(MotionEvent me) { if (!mMoreSuggestionsWindow.isShowing()) { + mLastX = (int)me.getX(); + mLastY = (int)me.getY(); return super.dispatchTouchEvent(me); } + + final MoreKeysPanel moreKeysPanel = mMoreSuggestionsView; final int action = me.getAction(); final long eventTime = me.getEventTime(); final int index = me.getActionIndex(); final int id = me.getPointerId(index); - final PointerTracker tracker = PointerTracker.getPointerTracker(id, mMoreSuggestionsView); - final int x = mMoreSuggestionsView.translateX((int)me.getX(index)); - final int y = mMoreSuggestionsView.translateY((int)me.getY(index)); - switch (action) { - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_POINTER_DOWN: - tracker.onDownEvent(x, y, eventTime, mMoreSuggestionsView); - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_POINTER_UP: - tracker.onUpEvent(x, y, eventTime); - break; - case MotionEvent.ACTION_MOVE: - tracker.onMoveEvent(x, y, eventTime); - break; - case MotionEvent.ACTION_CANCEL: - tracker.onCancelEvent(x, y, eventTime); - break; + final PointerTracker tracker = PointerTracker.getPointerTracker(id, moreKeysPanel); + final int x = (int)me.getX(index); + final int y = (int)me.getY(index); + final int translatedX = moreKeysPanel.translateX(x); + final int translatedY = moreKeysPanel.translateY(y); + + if (mCheckingIfModalOrSlidingMode) { + final int deltaX = Math.abs(x - mOriginX); + final int deltaY = Math.abs(y - mOriginY); + if (deltaX >= mMoreSuggestionsModalTolerance + || deltaY >= mMoreSuggestionsModalTolerance) { + // Decided to be in the sliding input mode + mCheckingIfModalOrSlidingMode = false; + tracker.onShowMoreKeysPanel( + translatedX, translatedY, SystemClock.uptimeMillis(), moreKeysPanel); + } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) { + // Decided to be in the modal input mode + mCheckingIfModalOrSlidingMode = false; + } + return true; } + + // Process sliding motion events + tracker.processMotionEvent(action, translatedX, translatedY, eventTime, moreKeysPanel); return true; } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index a6a5b6dd6..85c142f1e 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -34,6 +34,7 @@ import com.android.inputmethod.latin.Dictionary.WordCallback; import com.android.inputmethod.latin.DictionaryCollection; import com.android.inputmethod.latin.DictionaryFactory; import com.android.inputmethod.latin.LocaleUtils; +import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SynchronouslyLoadedUserDictionary; import com.android.inputmethod.latin.UserDictionary; import com.android.inputmethod.latin.Utils; @@ -62,18 +63,38 @@ public class AndroidSpellCheckerService extends SpellCheckerService { private Map<String, Dictionary> mUserDictionaries = Collections.synchronizedMap(new TreeMap<String, Dictionary>()); + private double mTypoThreshold; + + @Override public void onCreate() { + super.onCreate(); + mTypoThreshold = Double.parseDouble(getString(R.string.spellchecker_typo_threshold_value)); + } + @Override public Session createSession() { - return new AndroidSpellCheckerSession(); + return new AndroidSpellCheckerSession(this); } private static class SuggestionsGatherer implements WordCallback { + public static class Result { + public final String[] mSuggestions; + public final boolean mLooksLikeTypo; + public Result(final String[] gatheredSuggestions, final boolean looksLikeTypo) { + mSuggestions = gatheredSuggestions; + mLooksLikeTypo = looksLikeTypo; + } + } + private final int DEFAULT_SUGGESTION_LENGTH = 16; private final ArrayList<CharSequence> mSuggestions; private final int[] mScores; private final int mMaxLength; private int mLength = 0; - private boolean mSeenSuggestions = false; + + // The two following attributes are only ever filled if the requested max length + // is 0 (or less, which is treated the same). + private String mBestSuggestion = null; + private int mBestScore = Integer.MIN_VALUE; // As small as possible SuggestionsGatherer(final int maxLength) { mMaxLength = maxLength; @@ -89,14 +110,26 @@ public class AndroidSpellCheckerService extends SpellCheckerService { // if it doesn't. See documentation for binarySearch. final int insertIndex = positionIndex >= 0 ? positionIndex : -positionIndex - 1; - mSeenSuggestions = true; if (mLength < mMaxLength) { final int copyLen = mLength - insertIndex; ++mLength; System.arraycopy(mScores, insertIndex, mScores, insertIndex + 1, copyLen); mSuggestions.add(insertIndex, new String(word, wordOffset, wordLength)); } else { - if (insertIndex == 0) return true; + if (insertIndex == 0) { + // If the maxLength is 0 (should never be less, but if it is, it's treated as 0) + // then we need to keep track of the best suggestion in mBestScore and + // mBestSuggestion. This is so that we know whether the best suggestion makes + // the score cutoff, since we need to know that to return a meaningful + // looksLikeTypo. + if (0 >= mMaxLength) { + if (score > mBestScore) { + mBestScore = score; + mBestSuggestion = new String(word, wordOffset, wordLength); + } + } + return true; + } System.arraycopy(mScores, 1, mScores, 0, insertIndex); mSuggestions.add(insertIndex, new String(word, wordOffset, wordLength)); mSuggestions.remove(0); @@ -106,20 +139,41 @@ public class AndroidSpellCheckerService extends SpellCheckerService { return true; } - public String[] getGatheredSuggestions() { - if (!mSeenSuggestions) return null; - if (0 == mLength) return EMPTY_STRING_ARRAY; - - if (DBG) { - if (mLength != mSuggestions.size()) { - Log.e(TAG, "Suggestion size is not the same as stored mLength"); + public Result getResults(final CharSequence originalText, final double threshold) { + final String[] gatheredSuggestions; + final boolean looksLikeTypo; + if (0 == mLength) { + // Either we found no suggestions, or we found some BUT the max length was 0. + // If we found some mBestSuggestion will not be null. If it is null, then + // we found none, regardless of the max length. + if (null == mBestSuggestion) { + gatheredSuggestions = null; + looksLikeTypo = false; + } else { + gatheredSuggestions = EMPTY_STRING_ARRAY; + final double normalizedScore = + Utils.calcNormalizedScore(originalText, mBestSuggestion, mBestScore); + looksLikeTypo = (normalizedScore > threshold); + } + } else { + if (DBG) { + if (mLength != mSuggestions.size()) { + Log.e(TAG, "Suggestion size is not the same as stored mLength"); + } } + Collections.reverse(mSuggestions); + Utils.removeDupes(mSuggestions); + // This returns a String[], while toArray() returns an Object[] which cannot be cast + // into a String[]. + gatheredSuggestions = mSuggestions.toArray(EMPTY_STRING_ARRAY); + + final int bestScore = mScores[0]; + final CharSequence bestSuggestion = mSuggestions.get(0); + final double normalizedScore = + Utils.calcNormalizedScore(originalText, bestSuggestion, bestScore); + looksLikeTypo = (normalizedScore > threshold); } - Collections.reverse(mSuggestions); - Utils.removeDupes(mSuggestions); - // This returns a String[], while toArray() returns an Object[] which cannot be cast - // into a String[]. - return mSuggestions.toArray(EMPTY_STRING_ARRAY); + return new Result(gatheredSuggestions, looksLikeTypo); } } @@ -164,16 +218,22 @@ public class AndroidSpellCheckerService extends SpellCheckerService { return new DictAndProximity(dictionaryCollection, proximityInfo); } - private class AndroidSpellCheckerSession extends Session { + private static class AndroidSpellCheckerSession extends Session { // Immutable, but need the locale which is not available in the constructor yet - DictionaryPool mDictionaryPool; + private DictionaryPool mDictionaryPool; // Likewise - Locale mLocale; + private Locale mLocale; + + private final AndroidSpellCheckerService mService; + + AndroidSpellCheckerSession(final AndroidSpellCheckerService service) { + mService = service; + } @Override public void onCreate() { final String localeString = getLocale(); - mDictionaryPool = getDictionaryPool(localeString); + mDictionaryPool = mService.getDictionaryPool(localeString); mLocale = LocaleUtils.constructLocaleFromString(localeString); } @@ -242,13 +302,14 @@ public class AndroidSpellCheckerService extends SpellCheckerService { return EMPTY_SUGGESTIONS_INFO; } - final String[] suggestions = suggestionsGatherer.getGatheredSuggestions(); + final SuggestionsGatherer.Result result = + suggestionsGatherer.getResults(text, mService.mTypoThreshold); final int flags = (isInDict ? SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY : 0) - | (null != suggestions + | (result.mLooksLikeTypo ? SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO : 0); - return new SuggestionsInfo(flags, suggestions); + return new SuggestionsInfo(flags, result.mSuggestions); } } } |