aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/AndroidManifest.xml2
-rw-r--r--java/res/anim/key_preview_dismiss_holo.xml32
-rw-r--r--java/res/anim/key_preview_dismiss_lxx.xml32
-rw-r--r--java/res/anim/key_preview_show_up_holo.xml32
-rw-r--r--java/res/anim/key_preview_show_up_lxx.xml32
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_active_lxx_dark.9.pngbin1710 -> 1200 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_active_lxx_light.9.pngbin1470 -> 1199 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_dark.9.pngbin1756 -> 1195 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_light.9.pngbin1237 -> 1200 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png (renamed from java/res/drawable-hdpi/sym_keyboard_spacebar_lxx_dark.9.png)bin306 -> 306 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_spacebar_normal_lxx_light.9.png (renamed from java/res/drawable-hdpi/sym_keyboard_spacebar_lxx_light.9.png)bin333 -> 333 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.pngbin0 -> 321 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_spacebar_pressed_lxx_light.9.pngbin0 -> 346 bytes
-rw-r--r--java/res/drawable-hdpi/ic_launcher_keyboard.pngbin8523 -> 3967 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_dark.9.pngbin774 -> 937 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_light.9.pngbin714 -> 901 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_dark.9.pngbin1020 -> 1199 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_light.9.pngbin974 -> 1123 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_active_lxx_dark.9.pngbin1094 -> 782 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_active_lxx_light.9.pngbin974 -> 781 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_dark.9.pngbin1159 -> 778 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_light.9.pngbin868 -> 782 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png (renamed from java/res/drawable-mdpi/sym_keyboard_spacebar_lxx_dark.9.png)bin234 -> 234 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_spacebar_normal_lxx_light.9.png (renamed from java/res/drawable-mdpi/sym_keyboard_spacebar_lxx_light.9.png)bin260 -> 260 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.pngbin0 -> 244 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_spacebar_pressed_lxx_light.9.pngbin0 -> 265 bytes
-rw-r--r--java/res/drawable-mdpi/ic_launcher_keyboard.pngbin4772 -> 2586 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_dark.9.pngbin517 -> 580 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_light.9.pngbin494 -> 553 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_dark.9.pngbin658 -> 716 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_light.9.pngbin643 -> 709 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_dark.9.pngbin2258 -> 1534 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_light.9.pngbin1978 -> 1538 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.pngbin2380 -> 1536 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_light.9.pngbin1648 -> 1534 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png (renamed from java/res/drawable-xhdpi/sym_keyboard_spacebar_lxx_dark.9.png)bin386 -> 386 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png (renamed from java/res/drawable-xhdpi/sym_keyboard_spacebar_lxx_light.9.png)bin415 -> 415 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.pngbin0 -> 398 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.pngbin0 -> 450 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_launcher_keyboard.pngbin13098 -> 5387 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_dark.9.pngbin1073 -> 1312 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_light.9.pngbin943 -> 1166 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_dark.9.pngbin1304 -> 1564 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_light.9.pngbin1218 -> 1443 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_dark.9.pngbin3615 -> 2588 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_light.9.pngbin3280 -> 2584 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.pngbin3712 -> 2585 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.pngbin2662 -> 2588 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png (renamed from java/res/drawable-xxhdpi/sym_keyboard_spacebar_lxx_dark.9.png)bin585 -> 585 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png (renamed from java/res/drawable-xxhdpi/sym_keyboard_spacebar_lxx_light.9.png)bin658 -> 658 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.pngbin0 -> 608 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.pngbin0 -> 673 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_launcher_keyboard.pngbin25067 -> 8365 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_dark.9.pngbin1751 -> 2162 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_light.9.pngbin1573 -> 1975 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.pngbin2164 -> 2584 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_light.9.pngbin2000 -> 2381 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_dark.9.pngbin0 -> 3343 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_light.9.pngbin0 -> 3342 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.pngbin0 -> 3341 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.pngbin0 -> 3340 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_dark.9.pngbin0 -> 1162 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_light.9.pngbin0 -> 1152 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_dark.9.pngbin0 -> 1167 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_light.9.pngbin0 -> 1164 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_dark.9.pngbin0 -> 1232 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_light.9.pngbin0 -> 1284 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.pngbin0 -> 1147 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_light.9.pngbin0 -> 1156 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.pngbin0 -> 1167 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_light.9.pngbin0 -> 1172 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.pngbin0 -> 1554 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_light.9.pngbin0 -> 1611 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.pngbin0 -> 1606 bytes
-rw-r--r--java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.pngbin0 -> 1655 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_add_circle_white_24dp.pngbin0 -> 889 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_dark.pngbin0 -> 3558 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_light.pngbin0 -> 4392 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_dark.pngbin0 -> 3150 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_light.pngbin0 -> 3974 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_dark.pngbin0 -> 3158 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_light.pngbin0 -> 3266 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_dark.pngbin0 -> 2918 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_light.pngbin0 -> 2992 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_dark.pngbin0 -> 2811 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_light.pngbin0 -> 2899 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_dark.pngbin0 -> 2613 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_light.pngbin0 -> 2648 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_dark.pngbin0 -> 3111 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_light.pngbin0 -> 3402 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_dark.pngbin0 -> 2844 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_light.pngbin0 -> 3113 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_dark.pngbin0 -> 1810 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_light.pngbin0 -> 1834 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_dark.pngbin0 -> 1747 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_light.pngbin0 -> 1766 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_dark.pngbin0 -> 2978 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_light.pngbin0 -> 3220 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_dark.pngbin0 -> 2720 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_light.pngbin0 -> 2958 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_dark.pngbin0 -> 1916 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_light.pngbin0 -> 1872 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_dark.pngbin0 -> 1760 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_light.pngbin0 -> 1783 bytes
-rw-r--r--java/res/drawable-xxxhdpi/ic_launcher_keyboard.pngbin0 -> 11435 bytes
-rw-r--r--java/res/drawable-xxxhdpi/keyboard_background_lxx_dark.9.pngbin0 -> 1139 bytes
-rw-r--r--java/res/drawable-xxxhdpi/keyboard_background_lxx_light.9.pngbin0 -> 1133 bytes
-rw-r--r--java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_dark.9.pngbin0 -> 3475 bytes
-rw-r--r--java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_light.9.pngbin0 -> 3259 bytes
-rw-r--r--java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.pngbin0 -> 3883 bytes
-rw-r--r--java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_light.9.pngbin0 -> 3682 bytes
-rw-r--r--java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_dark.9.pngbin0 -> 2780 bytes
-rw-r--r--java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_light.9.pngbin0 -> 2624 bytes
-rw-r--r--java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_dark.9.pngbin0 -> 1138 bytes
-rw-r--r--java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_light.9.pngbin0 -> 1124 bytes
-rw-r--r--java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_dark.pngbin0 -> 1017 bytes
-rw-r--r--java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_light.pngbin0 -> 1017 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_dark.pngbin0 -> 1974 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_light.pngbin0 -> 2051 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_dark.pngbin0 -> 2091 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_light.pngbin0 -> 2162 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_dark.pngbin0 -> 1474 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_light.pngbin0 -> 1474 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_dark.pngbin0 -> 3263 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_light.pngbin0 -> 3405 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_dark.pngbin0 -> 1826 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_light.pngbin0 -> 1826 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_dark.pngbin0 -> 1827 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_light.pngbin0 -> 1701 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_dark.pngbin0 -> 1385 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_light.pngbin0 -> 1385 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_dark.pngbin0 -> 2443 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_light.pngbin0 -> 2434 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_dark.pngbin0 -> 1886 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_light.pngbin0 -> 1845 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_dark.pngbin0 -> 2565 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_light.pngbin0 -> 2694 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_dark.pngbin0 -> 1865 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_light.pngbin0 -> 1865 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_dark.pngbin0 -> 1913 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_light.pngbin0 -> 1801 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_dark.pngbin0 -> 2587 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_light.pngbin0 -> 2612 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_dark.pngbin0 -> 1196 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_light.pngbin0 -> 1208 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_dark.pngbin0 -> 1424 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_light.pngbin0 -> 1450 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_dark.pngbin0 -> 2135 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_light.pngbin0 -> 2189 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_dark.pngbin0 -> 2138 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_light.pngbin0 -> 2209 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_dark.pngbin0 -> 1393 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_light.pngbin0 -> 1423 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_dark.pngbin0 -> 1370 bytes
-rw-r--r--java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_light.pngbin0 -> 1397 bytes
-rw-r--r--java/res/drawable/btn_keyboard_key_lxx_dark.xml5
-rw-r--r--java/res/drawable/btn_keyboard_key_lxx_light.xml5
-rw-r--r--java/res/drawable/btn_keyboard_key_popup_action_lxx_dark.xml21
-rw-r--r--java/res/drawable/btn_keyboard_key_popup_action_lxx_light.xml21
-rw-r--r--java/res/drawable/btn_keyboard_key_popup_lxx_light.xml21
-rw-r--r--java/res/drawable/btn_keyboard_spacebar_lxx_dark.xml4
-rw-r--r--java/res/drawable/btn_keyboard_spacebar_lxx_light.xml4
-rw-r--r--java/res/layout/additional_subtype_dialog.xml89
-rw-r--r--java/res/layout/emoji_palettes_view.xml4
-rw-r--r--java/res/layout/input_view.xml35
-rw-r--r--java/res/layout/main_keyboard_frame.xml45
-rw-r--r--java/res/layout/more_keys_keyboard.xml3
-rw-r--r--java/res/layout/more_keys_keyboard_for_action_lxx.xml32
-rw-r--r--java/res/values-az-rAZ/bools.xml24
-rw-r--r--java/res/values-bn-rIN/bools.xml24
-rw-r--r--java/res/values-eu-rES/bools.xml24
-rw-r--r--java/res/values-gl-rES/bools.xml24
-rw-r--r--java/res/values-hy-rAM/bools.xml24
-rw-r--r--java/res/values-is-rIS/bools.xml24
-rw-r--r--java/res/values-kk-rKZ/bools.xml24
-rw-r--r--java/res/values-km-rKH/bools.xml24
-rw-r--r--java/res/values-kn-rIN/bools.xml24
-rw-r--r--java/res/values-ky-rKG/bools.xml24
-rw-r--r--java/res/values-land/config.xml16
-rw-r--r--java/res/values-land/keyboard-heights.xml2
-rw-r--r--java/res/values-lo-rLA/bools.xml24
-rw-r--r--java/res/values-mk-rMK/bools.xml24
-rw-r--r--java/res/values-ml-rIN/bools.xml24
-rw-r--r--java/res/values-mn-rMN/bools.xml24
-rw-r--r--java/res/values-mr-rIN/bools.xml24
-rw-r--r--java/res/values-ne-rNP/bools.xml24
-rw-r--r--java/res/values-sw600dp-land/config.xml14
-rw-r--r--java/res/values-sw600dp/config.xml14
-rw-r--r--java/res/values-sw768dp-land/config.xml16
-rw-r--r--java/res/values-sw768dp/config.xml14
-rw-r--r--java/res/values-ta-rIN/bools.xml24
-rw-r--r--java/res/values-te-rIN/bools.xml24
-rw-r--r--java/res/values/attrs.xml31
-rw-r--r--java/res/values/colors.xml2
-rw-r--r--java/res/values/config.xml17
-rw-r--r--java/res/values/donottranslate-debug-settings.xml59
-rw-r--r--java/res/values/donottranslate-text-decorator.xml76
-rw-r--r--java/res/values/donottranslate.xml7
-rw-r--r--java/res/values/keyboard-icons-lxx-dark.xml2
-rw-r--r--java/res/values/keyboard-icons-lxx-light.xml2
-rw-r--r--java/res/values/strings.xml47
-rw-r--r--java/res/values/themes-common.xml12
-rw-r--r--java/res/values/themes-holo.xml4
-rw-r--r--java/res/values/themes-ics.xml10
-rw-r--r--java/res/values/themes-klp.xml10
-rw-r--r--java/res/values/themes-lxx-dark.xml21
-rw-r--r--java/res/values/themes-lxx-light.xml24
-rw-r--r--java/res/values/themes-lxx.xml4
-rw-r--r--java/res/xml-sw600dp/key_styles_common.xml1
-rw-r--r--java/res/xml-sw600dp/key_styles_enter.xml138
-rw-r--r--java/res/xml-sw600dp/rows_number_normal.xml5
-rw-r--r--java/res/xml-sw600dp/rows_phone.xml5
-rw-r--r--java/res/xml/key_space_symbols.xml1
-rw-r--r--java/res/xml/key_styles_actions.xml133
-rw-r--r--java/res/xml/key_styles_common.xml24
-rw-r--r--java/res/xml/key_styles_enter.xml197
-rw-r--r--java/res/xml/key_styles_navigate_more_keys.xml86
-rw-r--r--java/res/xml/key_styles_number.xml20
-rw-r--r--java/res/xml/prefs.xml16
-rw-r--r--java/res/xml/prefs_screen_appearance.xml29
-rw-r--r--java/res/xml/prefs_screen_debug.xml27
-rw-r--r--java/res/xml/prefs_screen_multilingual.xml (renamed from java/res/xml/prefs_screen_multi_lingual.xml)8
-rw-r--r--java/res/xml/prefs_screen_preferences.xml (renamed from java/res/xml/prefs_screen_input.xml)2
-rw-r--r--java/res/xml/prefs_screen_theme.xml2
-rw-r--r--java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java79
-rw-r--r--java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java32
-rw-r--r--java/src/com/android/inputmethod/compat/NotificationCompatUtils.java83
-rw-r--r--java/src/com/android/inputmethod/compat/ViewCompatUtils.java19
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/DownloadManagerWrapper.java18
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java13
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java73
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java10
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java53
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardTheme.java20
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java26
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java48
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java70
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java42
-rw-r--r--java/src/com/android/inputmethod/keyboard/TextDecorator.java368
-rw-r--r--java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java262
-rw-r--r--java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java51
-rw-r--r--java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java3
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java93
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java86
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java18
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java5
-rw-r--r--java/src/com/android/inputmethod/latin/InputAttributes.java13
-rw-r--r--java/src/com/android/inputmethod/latin/InputView.java4
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java351
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java66
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java12
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java16
-rw-r--r--java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java29
-rw-r--r--java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java2
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java282
-rw-r--r--java/src/com/android/inputmethod/latin/settings/AppearanceSettingsFragment.java41
-rw-r--r--java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java46
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettings.java14
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java18
-rw-r--r--java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java43
-rw-r--r--java/src/com/android/inputmethod/latin/settings/PreferencesSettingsFragment.java (renamed from java/src/com/android/inputmethod/latin/settings/InputSettingsFragment.java)6
-rw-r--r--java/src/com/android/inputmethod/latin/settings/Settings.java18
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsFragment.java11
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java63
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java17
-rw-r--r--java/src/com/android/inputmethod/latin/setup/LauncherIconVisibilityManager.java9
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java4
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java236
-rw-r--r--java/src/com/android/inputmethod/latin/utils/FragmentUtils.java6
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java41
-rw-r--r--java/src/com/android/inputmethod/latin/utils/StringUtils.java63
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SuggestionResults.java13
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java39
273 files changed, 3788 insertions, 1096 deletions
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index f37f6cc4b..1797dc92c 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -33,7 +33,6 @@
<application android:label="@string/english_ime_name"
android:icon="@drawable/ic_launcher_keyboard"
- android:killAfterRestore="false"
android:supportsRtl="true"
android:allowBackup="true">
@@ -82,6 +81,7 @@
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_INITIALIZE" />
+ <action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>
diff --git a/java/res/anim/key_preview_dismiss_holo.xml b/java/res/anim/key_preview_dismiss_holo.xml
new file mode 100644
index 000000000..0bf725435
--- /dev/null
+++ b/java/res/anim/key_preview_dismiss_holo.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:propertyName="scaleX"
+ android:duration="53"
+ android:valueFrom="1.00"
+ android:valueTo="0.94" />
+ <objectAnimator
+ android:propertyName="scaleY"
+ android:duration="53"
+ android:valueFrom="1.00"
+ android:valueTo="0.94" />
+</set>
diff --git a/java/res/anim/key_preview_dismiss_lxx.xml b/java/res/anim/key_preview_dismiss_lxx.xml
new file mode 100644
index 000000000..326e534ec
--- /dev/null
+++ b/java/res/anim/key_preview_dismiss_lxx.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:propertyName="scaleX"
+ android:duration="53"
+ android:valueFrom="1.00"
+ android:valueTo="1.00" />
+ <objectAnimator
+ android:propertyName="scaleY"
+ android:duration="53"
+ android:valueFrom="1.00"
+ android:valueTo="0.94" />
+</set>
diff --git a/java/res/anim/key_preview_show_up_holo.xml b/java/res/anim/key_preview_show_up_holo.xml
new file mode 100644
index 000000000..ad2e413a1
--- /dev/null
+++ b/java/res/anim/key_preview_show_up_holo.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:propertyName="scaleX"
+ android:duration="17"
+ android:valueFrom="0.98"
+ android:valueTo="1.00" />
+ <objectAnimator
+ android:propertyName="scaleY"
+ android:duration="17"
+ android:valueFrom="0.98"
+ android:valueTo="1.00" />
+</set>
diff --git a/java/res/anim/key_preview_show_up_lxx.xml b/java/res/anim/key_preview_show_up_lxx.xml
new file mode 100644
index 000000000..f5003499c
--- /dev/null
+++ b/java/res/anim/key_preview_show_up_lxx.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:propertyName="scaleX"
+ android:duration="17"
+ android:valueFrom="1.00"
+ android:valueTo="1.00" />
+ <objectAnimator
+ android:propertyName="scaleY"
+ android:duration="17"
+ android:valueFrom="0.98"
+ android:valueTo="1.00" />
+</set>
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_active_lxx_dark.9.png b/java/res/drawable-hdpi/btn_keyboard_key_active_lxx_dark.9.png
index bbdc41116..55ef3e7f5 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_active_lxx_dark.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_active_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_active_lxx_light.9.png b/java/res/drawable-hdpi/btn_keyboard_key_active_lxx_light.9.png
index 854c849cb..9f307dc7f 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_active_lxx_light.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_active_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png b/java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
index 33f7d8077..17a77cccb 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_light.9.png b/java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
index 7a7e98297..55ef3e7f5 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_spacebar_lxx_dark.9.png b/java/res/drawable-hdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
index 32311666f..32311666f 100644
--- a/java/res/drawable-hdpi/sym_keyboard_spacebar_lxx_dark.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_spacebar_lxx_light.9.png b/java/res/drawable-hdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
index 1256b8b21..1256b8b21 100644
--- a/java/res/drawable-hdpi/sym_keyboard_spacebar_lxx_light.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png b/java/res/drawable-hdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
new file mode 100644
index 000000000..cd0d884c6
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png b/java/res/drawable-hdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
new file mode 100644
index 000000000..c05605fbf
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_launcher_keyboard.png b/java/res/drawable-hdpi/ic_launcher_keyboard.png
index 7ae00ed3f..3a01e61b9 100644
--- a/java/res/drawable-hdpi/ic_launcher_keyboard.png
+++ b/java/res/drawable-hdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_dark.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_dark.9.png
index 306e4554c..93f300a13 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_dark.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_light.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_light.9.png
index 867f5516d..e7c516a0e 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_light.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_dark.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
index b3e6ee784..b56fcf910 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_light.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_light.9.png
index 827f80f13..32005c37b 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_light.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_active_lxx_dark.9.png b/java/res/drawable-mdpi/btn_keyboard_key_active_lxx_dark.9.png
index 787ce45ce..765191881 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_active_lxx_dark.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_active_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_active_lxx_light.9.png b/java/res/drawable-mdpi/btn_keyboard_key_active_lxx_light.9.png
index e7a585b70..8131549e5 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_active_lxx_light.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_active_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png b/java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
index 7e34c6cf1..dcf814ada 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_light.9.png b/java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
index 5a6513392..765191881 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_spacebar_lxx_dark.9.png b/java/res/drawable-mdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
index b8e56dab4..b8e56dab4 100644
--- a/java/res/drawable-mdpi/sym_keyboard_spacebar_lxx_dark.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_spacebar_lxx_light.9.png b/java/res/drawable-mdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
index 281f83062..281f83062 100644
--- a/java/res/drawable-mdpi/sym_keyboard_spacebar_lxx_light.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png b/java/res/drawable-mdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
new file mode 100644
index 000000000..cb2ca06d3
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png b/java/res/drawable-mdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
new file mode 100644
index 000000000..653da974c
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_launcher_keyboard.png b/java/res/drawable-mdpi/ic_launcher_keyboard.png
index cc73f3be1..574da25f5 100644
--- a/java/res/drawable-mdpi/ic_launcher_keyboard.png
+++ b/java/res/drawable-mdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_dark.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_dark.9.png
index 4f6731f60..1a7dd34ed 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_dark.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_light.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_light.9.png
index 14da5f919..268863e68 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_light.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_dark.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
index 9bca991b2..08d67ef6a 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_light.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_light.9.png
index 14f4b5f24..d0e46b14e 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_light.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_dark.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_dark.9.png
index 47264065a..0f3d3196b 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_dark.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_light.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_light.9.png
index dca7a3274..cef6d00c0 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_light.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
index 8063fcd82..b5768e629 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
index fa32a2c6e..0f3d3196b 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_spacebar_lxx_dark.9.png b/java/res/drawable-xhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
index ab032dc17..ab032dc17 100644
--- a/java/res/drawable-xhdpi/sym_keyboard_spacebar_lxx_dark.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_spacebar_lxx_light.9.png b/java/res/drawable-xhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
index c1ed863f8..c1ed863f8 100644
--- a/java/res/drawable-xhdpi/sym_keyboard_spacebar_lxx_light.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png b/java/res/drawable-xhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
new file mode 100644
index 000000000..c3428bede
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png b/java/res/drawable-xhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
new file mode 100644
index 000000000..f795ee9af
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_launcher_keyboard.png b/java/res/drawable-xhdpi/ic_launcher_keyboard.png
index f2ac50dfe..17695015a 100644
--- a/java/res/drawable-xhdpi/ic_launcher_keyboard.png
+++ b/java/res/drawable-xhdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_dark.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_dark.9.png
index 654ccd10c..f934e33bd 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_dark.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_light.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_light.9.png
index c566e3d7c..f70599e99 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_light.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
index f5f613caa..fa5ddf2b6 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_light.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_light.9.png
index 35aaa7d7c..0da8919b2 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_light.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_dark.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_dark.9.png
index f49239794..927d87b58 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_dark.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_light.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_light.9.png
index 1f5f922dc..ce84bde4c 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_light.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
index 65e455c7b..5b0854e46 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
index 031014360..927d87b58 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_spacebar_lxx_dark.9.png b/java/res/drawable-xxhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
index 0339de37d..0339de37d 100644
--- a/java/res/drawable-xxhdpi/sym_keyboard_spacebar_lxx_dark.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_spacebar_lxx_light.9.png b/java/res/drawable-xxhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
index b57cfb3d2..b57cfb3d2 100644
--- a/java/res/drawable-xxhdpi/sym_keyboard_spacebar_lxx_light.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png b/java/res/drawable-xxhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
new file mode 100644
index 000000000..8e74c6723
--- /dev/null
+++ b/java/res/drawable-xxhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png b/java/res/drawable-xxhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
new file mode 100644
index 000000000..1ca1ae3e9
--- /dev/null
+++ b/java/res/drawable-xxhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_launcher_keyboard.png b/java/res/drawable-xxhdpi/ic_launcher_keyboard.png
index df386e827..624c82efd 100644
--- a/java/res/drawable-xxhdpi/ic_launcher_keyboard.png
+++ b/java/res/drawable-xxhdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_dark.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_dark.9.png
index f5215bc56..1b92455e9 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_dark.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_light.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_light.9.png
index b565ff07c..3effde383 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_light.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
index 6d931ed42..55d633098 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_light.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_light.9.png
index 2c5ced966..4523be965 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_light.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_dark.9.png
new file mode 100644
index 000000000..eac447583
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_light.9.png
new file mode 100644
index 000000000..16d1f687f
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
new file mode 100644
index 000000000..78923a887
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
new file mode 100644
index 000000000..e57e80d05
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_active_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
new file mode 100644
index 000000000..0b3d796e4
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_light.9.png
new file mode 100644
index 000000000..6edd4e3d5
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_off_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
new file mode 100644
index 000000000..61a5efc2f
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_light.9.png
new file mode 100644
index 000000000..c60a23547
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_normal_on_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_dark.9.png
new file mode 100644
index 000000000..842c6858d
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_light.9.png
new file mode 100644
index 000000000..6b033067f
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_popup_selected_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
new file mode 100644
index 000000000..276065e3b
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_light.9.png
new file mode 100644
index 000000000..e64147f4f
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_off_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
new file mode 100644
index 000000000..c1300140c
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_light.9.png
new file mode 100644
index 000000000..e433f5669
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_key_pressed_on_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
new file mode 100644
index 000000000..ee4d16b64
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
new file mode 100644
index 000000000..14cba3c24
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_normal_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
new file mode 100644
index 000000000..671c31f08
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
new file mode 100644
index 000000000..8a6f32afe
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/btn_keyboard_spacebar_pressed_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_add_circle_white_24dp.png b/java/res/drawable-xxxhdpi/ic_add_circle_white_24dp.png
new file mode 100644
index 000000000..a0116fafe
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_add_circle_white_24dp.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_dark.png
new file mode 100644
index 000000000..0198bce94
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_light.png
new file mode 100644
index 000000000..f530ba139
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_dark.png
new file mode 100644
index 000000000..d9022bbe3
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_light.png
new file mode 100644
index 000000000..89dc4cd92
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_emoticons_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_dark.png
new file mode 100644
index 000000000..efbf51c11
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_light.png
new file mode 100644
index 000000000..95355c635
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_nature_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_dark.png
new file mode 100644
index 000000000..f5531ea11
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_light.png
new file mode 100644
index 000000000..b5085cb6a
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_nature_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_dark.png
new file mode 100644
index 000000000..730f75d94
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_light.png
new file mode 100644
index 000000000..f4a250ddd
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_objects_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_dark.png
new file mode 100644
index 000000000..4658ceac0
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_light.png
new file mode 100644
index 000000000..7b27829e7
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_objects_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_dark.png
new file mode 100644
index 000000000..b70f07ac5
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_light.png
new file mode 100644
index 000000000..7e052080b
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_people_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_dark.png
new file mode 100644
index 000000000..c960d15e4
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_light.png
new file mode 100644
index 000000000..44325cf35
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_people_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_dark.png
new file mode 100644
index 000000000..bca6bbaa7
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_light.png
new file mode 100644
index 000000000..8f340d2df
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_places_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_dark.png
new file mode 100644
index 000000000..a06e1d858
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_light.png
new file mode 100644
index 000000000..b247768f7
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_places_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_dark.png
new file mode 100644
index 000000000..3508374ba
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_light.png
new file mode 100644
index 000000000..82a029ee7
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_recents_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_dark.png
new file mode 100644
index 000000000..6797d7b31
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_light.png
new file mode 100644
index 000000000..6b622ac6d
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_recents_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_dark.png
new file mode 100644
index 000000000..51336e93a
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_light.png
new file mode 100644
index 000000000..2ab8fa6a7
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_symbols_activated_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_dark.png b/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_dark.png
new file mode 100644
index 000000000..e02ad6175
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_light.png b/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_light.png
new file mode 100644
index 000000000..b17f06674
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_emoji_symbols_normal_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/ic_launcher_keyboard.png b/java/res/drawable-xxxhdpi/ic_launcher_keyboard.png
new file mode 100644
index 000000000..39636a1b7
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_background_lxx_dark.9.png b/java/res/drawable-xxxhdpi/keyboard_background_lxx_dark.9.png
new file mode 100644
index 000000000..a7dd5378b
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_background_lxx_light.9.png b/java/res/drawable-xxxhdpi/keyboard_background_lxx_light.9.png
new file mode 100644
index 000000000..ef7ab2097
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_dark.9.png b/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_dark.9.png
new file mode 100644
index 000000000..0e08b6b95
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_light.9.png b/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_light.9.png
new file mode 100644
index 000000000..fb10523d2
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_key_feedback_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png b/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
new file mode 100644
index 000000000..fd88668bb
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_light.9.png b/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_light.9.png
new file mode 100644
index 000000000..ab1bfad7d
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_key_feedback_more_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_dark.9.png b/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_dark.9.png
new file mode 100644
index 000000000..3489a9c4c
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_light.9.png b/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_light.9.png
new file mode 100644
index 000000000..2e3797263
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_popup_panel_background_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_dark.9.png b/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_dark.9.png
new file mode 100644
index 000000000..098fa0652
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_light.9.png b/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_light.9.png
new file mode 100644
index 000000000..c1c48c973
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/keyboard_suggest_strip_lxx_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_dark.png b/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_dark.png
new file mode 100644
index 000000000..0dc783d7c
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_light.png b/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_light.png
new file mode 100644
index 000000000..f3162e422
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/suggestions_strip_divider_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_dark.png
new file mode 100644
index 000000000..c8a064d87
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_light.png
new file mode 100644
index 000000000..2d2e6e158
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_delete_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_dark.png
new file mode 100644
index 000000000..27426da97
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_light.png
new file mode 100644
index 000000000..4b1a69f5b
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_done_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_dark.png
new file mode 100644
index 000000000..79d3eef5d
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_light.png
new file mode 100644
index 000000000..a87e24028
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_go_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_dark.png
new file mode 100644
index 000000000..26f361540
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_light.png
new file mode 100644
index 000000000..93efb378f
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_language_switch_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_dark.png
new file mode 100644
index 000000000..27bf68941
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_light.png
new file mode 100644
index 000000000..c62410429
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_next_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_dark.png
new file mode 100644
index 000000000..50e0a31d2
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_light.png
new file mode 100644
index 000000000..3f4424927
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_previous_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_dark.png
new file mode 100644
index 000000000..c10107125
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_light.png
new file mode 100644
index 000000000..54e7fb05b
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_return_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_dark.png
new file mode 100644
index 000000000..8f7dfcefc
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_light.png
new file mode 100644
index 000000000..07d555149
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_search_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_dark.png
new file mode 100644
index 000000000..9c12ec29f
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_light.png
new file mode 100644
index 000000000..fc6882833
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_send_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_dark.png
new file mode 100644
index 000000000..d728b8308
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_light.png
new file mode 100644
index 000000000..1351710ad
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_settings_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_dark.png
new file mode 100644
index 000000000..e75d556b4
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_light.png
new file mode 100644
index 000000000..00521bf09
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_shift_locked_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_dark.png
new file mode 100644
index 000000000..f47bf66e2
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_light.png
new file mode 100644
index 000000000..fdb6cd77a
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_shift_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_dark.png
new file mode 100644
index 000000000..26fd4e7ef
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_light.png
new file mode 100644
index 000000000..7b0467aa2
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_smiley_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_dark.png
new file mode 100644
index 000000000..1f6c92da0
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_light.png
new file mode 100644
index 000000000..656cf99ca
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_space_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_dark.png
new file mode 100644
index 000000000..89884698c
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_light.png
new file mode 100644
index 000000000..aeedba6da
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_tab_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_dark.png
new file mode 100644
index 000000000..9d5b73307
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_light.png
new file mode 100644
index 000000000..9db910daa
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_voice_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_dark.png
new file mode 100644
index 000000000..e233d0993
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_light.png
new file mode 100644
index 000000000..7e0a964dc
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_voice_off_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_dark.png
new file mode 100644
index 000000000..94de9165b
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_light.png
new file mode 100644
index 000000000..2b13ba737
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_zwj_lxx_light.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_dark.png b/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_dark.png
new file mode 100644
index 000000000..134bca67c
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_light.png b/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_light.png
new file mode 100644
index 000000000..31cf75bb3
--- /dev/null
+++ b/java/res/drawable-xxxhdpi/sym_keyboard_zwnj_lxx_light.png
Binary files differ
diff --git a/java/res/drawable/btn_keyboard_key_lxx_dark.xml b/java/res/drawable/btn_keyboard_key_lxx_dark.xml
index c82c13829..bb1789ae3 100644
--- a/java/res/drawable/btn_keyboard_key_lxx_dark.xml
+++ b/java/res/drawable/btn_keyboard_key_lxx_dark.xml
@@ -15,11 +15,6 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Custom label action keys. -->
- <item android:state_active="true" android:state_checked="true" android:state_pressed="true"
- android:drawable="@color/key_background_pressed_lxx_dark" />
- <item android:state_active="true" android:state_checked="true"
- android:drawable="@color/key_background_lxx_dark" />
<!-- Action keys. -->
<item android:state_active="true" android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_active_pressed_lxx_dark" />
diff --git a/java/res/drawable/btn_keyboard_key_lxx_light.xml b/java/res/drawable/btn_keyboard_key_lxx_light.xml
index f237fbea9..60fe02dd2 100644
--- a/java/res/drawable/btn_keyboard_key_lxx_light.xml
+++ b/java/res/drawable/btn_keyboard_key_lxx_light.xml
@@ -15,11 +15,6 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Custom label action keys. -->
- <item android:state_active="true" android:state_checked="true" android:state_pressed="true"
- android:drawable="@color/key_background_pressed_lxx_light" />
- <item android:state_active="true" android:state_checked="true"
- android:drawable="@color/key_background_lxx_light" />
<!-- Action keys. -->
<item android:state_active="true" android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_active_pressed_lxx_light" />
diff --git a/java/res/drawable/btn_keyboard_key_popup_action_lxx_dark.xml b/java/res/drawable/btn_keyboard_key_popup_action_lxx_dark.xml
new file mode 100644
index 000000000..8b637f204
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_popup_action_lxx_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_active_pressed_lxx_dark" />
+ <item android:drawable="@drawable/btn_keyboard_key_active_lxx_dark" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_key_popup_action_lxx_light.xml b/java/res/drawable/btn_keyboard_key_popup_action_lxx_light.xml
new file mode 100644
index 000000000..67fc52144
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_popup_action_lxx_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_active_pressed_lxx_light" />
+ <item android:drawable="@drawable/btn_keyboard_key_active_lxx_light" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_key_popup_lxx_light.xml b/java/res/drawable/btn_keyboard_key_popup_lxx_light.xml
new file mode 100644
index 000000000..d6cd2b831
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_popup_lxx_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_popup_selected_lxx_light" />
+ <item android:drawable="@android:color/transparent" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_spacebar_lxx_dark.xml b/java/res/drawable/btn_keyboard_spacebar_lxx_dark.xml
index 5c595d9ed..e930e40e4 100644
--- a/java/res/drawable/btn_keyboard_spacebar_lxx_dark.xml
+++ b/java/res/drawable/btn_keyboard_spacebar_lxx_dark.xml
@@ -16,6 +16,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
- android:drawable="@color/key_background_pressed_lxx_dark" />
- <item android:drawable="@color/key_background_lxx_dark" />
+ android:drawable="@drawable/btn_keyboard_spacebar_pressed_lxx_dark" />
+ <item android:drawable="@drawable/btn_keyboard_spacebar_normal_lxx_dark" />
</selector>
diff --git a/java/res/drawable/btn_keyboard_spacebar_lxx_light.xml b/java/res/drawable/btn_keyboard_spacebar_lxx_light.xml
index acd19fda4..2b059938d 100644
--- a/java/res/drawable/btn_keyboard_spacebar_lxx_light.xml
+++ b/java/res/drawable/btn_keyboard_spacebar_lxx_light.xml
@@ -16,6 +16,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
- android:drawable="@color/key_background_pressed_lxx_light" />
- <item android:drawable="@color/key_background_lxx_light" />
+ android:drawable="@drawable/btn_keyboard_spacebar_pressed_lxx_light" />
+ <item android:drawable="@drawable/btn_keyboard_spacebar_normal_lxx_light" />
</selector>
diff --git a/java/res/layout/additional_subtype_dialog.xml b/java/res/layout/additional_subtype_dialog.xml
index f97c006d6..b7804f5df 100644
--- a/java/res/layout/additional_subtype_dialog.xml
+++ b/java/res/layout/additional_subtype_dialog.xml
@@ -18,39 +18,60 @@
*/
-->
-<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:columnCount="2"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginLeft="8dip"
- android:layout_marginRight="8dip"
- android:padding="8dip">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="left|center_vertical"
- style="?android:attr/textAppearanceSmall"
- android:text="@string/subtype_locale" />
- <Spinner
- android:id="@+id/subtype_locale_spinner"
- android:layout_width="wrap_content"
- android:layout_marginLeft="8dip"
- android:layout_marginBottom="8dip"
- android:layout_marginTop="8dip"
- android:layout_gravity="fill_horizontal|center_vertical"
- android:prompt="@string/subtype_locale" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="left|center_vertical"
- style="?android:attr/textAppearanceSmall"
- android:text="@string/keyboard_layout_set" />
- <Spinner
- android:id="@+id/keyboard_layout_set_spinner"
- android:layout_width="wrap_content"
- android:layout_marginLeft="8dip"
- android:layout_marginBottom="8dip"
- android:layout_marginTop="8dip"
- android:layout_gravity="fill_horizontal|center_vertical"
- android:prompt="@string/keyboard_layout_set" />
-</GridLayout>
+ android:padding="16dip">
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TextView
+ android:layout_width="0dp"
+ android:layout_weight="30"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start|center_vertical"
+ android:gravity="start|left"
+ android:textAlignment="viewStart"
+ style="?android:attr/textAppearanceSmall"
+ android:text="@string/subtype_locale" />
+ <Spinner
+ android:id="@+id/subtype_locale_spinner"
+ android:spinnerMode="dialog"
+ android:layout_width="0dp"
+ android:layout_weight="70"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="8dip"
+ android:layout_marginBottom="8dip"
+ android:layout_marginTop="8dip"
+ android:layout_gravity="fill_horizontal|center_vertical"
+ android:gravity="start|left"
+ android:prompt="@string/subtype_locale" />
+ </LinearLayout>
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TextView
+ android:layout_width="0dp"
+ android:layout_weight="30"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start|center_vertical"
+ android:textAlignment="viewStart"
+ style="?android:attr/textAppearanceSmall"
+ android:text="@string/keyboard_layout_set" />
+ <Spinner
+ android:id="@+id/keyboard_layout_set_spinner"
+ android:spinnerMode="dialog"
+ android:layout_width="0dp"
+ android:layout_weight="70"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="8dip"
+ android:layout_marginBottom="8dip"
+ android:layout_marginTop="8dip"
+ android:layout_gravity="fill_horizontal|center_vertical"
+ android:gravity="start|left"
+ android:prompt="@string/keyboard_layout_set" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/java/res/layout/emoji_palettes_view.xml b/java/res/layout/emoji_palettes_view.xml
index a6ea38ba4..26cc042ab 100644
--- a/java/res/layout/emoji_palettes_view.xml
+++ b/java/res/layout/emoji_palettes_view.xml
@@ -20,10 +20,10 @@
<com.android.inputmethod.keyboard.emoji.EmojiPalettesView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/emoji_keyboard_view"
- android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:orientation="vertical"
style="?attr/emojiPalettesViewStyle"
>
<LinearLayout
diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml
index a4bcdcc8a..46551f63f 100644
--- a/java/res/layout/input_view.xml
+++ b/java/res/layout/input_view.xml
@@ -21,38 +21,11 @@
<com.android.inputmethod.latin.InputView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="bottom|center_horizontal"
- android:orientation="vertical" >
- <!-- The height of key_preview_backing view will automatically be determined by code. -->
- <FrameLayout
- android:id="@+id/key_preview_backing"
- android:layout_width="match_parent"
- android:layout_height="0dp" />
- <LinearLayout
+ android:layout_height="wrap_content">
+ <include
android:id="@+id/main_keyboard_frame"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
-
- <!-- To ensure that key preview popup is correctly placed when the current system locale is
- one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
- <com.android.inputmethod.latin.suggestions.SuggestionStripView
- android:id="@+id/suggestion_strip_view"
- android:layoutDirection="ltr"
- android:layout_width="match_parent"
- android:layout_height="@dimen/config_suggestions_strip_height"
- android:gravity="center_vertical"
- style="?attr/suggestionStripViewStyle" />
-
- <!-- To ensure that key preview popup is correctly placed when the current system locale is
- one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
- <com.android.inputmethod.keyboard.MainKeyboardView
- android:id="@+id/keyboard_view"
- android:layoutDirection="ltr"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
+ layout="@layout/main_keyboard_frame" />
<include
+ android:id="@+id/emoji_palettes_view"
layout="@layout/emoji_palettes_view" />
</com.android.inputmethod.latin.InputView>
diff --git a/java/res/layout/main_keyboard_frame.xml b/java/res/layout/main_keyboard_frame.xml
new file mode 100644
index 000000000..ebf746679
--- /dev/null
+++ b/java/res/layout/main_keyboard_frame.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:orientation="vertical" >
+
+ <!-- To ensure that key preview popup is correctly placed when the current system locale is
+ one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
+ <com.android.inputmethod.latin.suggestions.SuggestionStripView
+ android:id="@+id/suggestion_strip_view"
+ android:layoutDirection="ltr"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/config_suggestions_strip_height"
+ android:gravity="center_vertical"
+ style="?attr/suggestionStripViewStyle" />
+
+ <!-- To ensure that key preview popup is correctly placed when the current system locale is
+ one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
+ <com.android.inputmethod.keyboard.MainKeyboardView
+ android:id="@+id/keyboard_view"
+ android:layoutDirection="ltr"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/java/res/layout/more_keys_keyboard.xml b/java/res/layout/more_keys_keyboard.xml
index f3795afdc..449c00f92 100644
--- a/java/res/layout/more_keys_keyboard.xml
+++ b/java/res/layout/more_keys_keyboard.xml
@@ -27,5 +27,6 @@
<com.android.inputmethod.keyboard.MoreKeysKeyboardView
android:id="@+id/more_keys_keyboard_view"
android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ android:layout_height="wrap_content"
+ style="?attr/moreKeysKeyboardViewStyle" />
</LinearLayout>
diff --git a/java/res/layout/more_keys_keyboard_for_action_lxx.xml b/java/res/layout/more_keys_keyboard_for_action_lxx.xml
new file mode 100644
index 000000000..d23faa4f0
--- /dev/null
+++ b/java/res/layout/more_keys_keyboard_for_action_lxx.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+>
+ <com.android.inputmethod.keyboard.MoreKeysKeyboardView
+ android:id="@+id/more_keys_keyboard_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="?attr/moreKeysKeyboardViewForActionStyle" />
+</LinearLayout>
diff --git a/java/res/values-az-rAZ/bools.xml b/java/res/values-az-rAZ/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-az-rAZ/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-bn-rIN/bools.xml b/java/res/values-bn-rIN/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-bn-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-eu-rES/bools.xml b/java/res/values-eu-rES/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-eu-rES/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-gl-rES/bools.xml b/java/res/values-gl-rES/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-gl-rES/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-hy-rAM/bools.xml b/java/res/values-hy-rAM/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-hy-rAM/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-is-rIS/bools.xml b/java/res/values-is-rIS/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-is-rIS/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-kk-rKZ/bools.xml b/java/res/values-kk-rKZ/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-kk-rKZ/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-km-rKH/bools.xml b/java/res/values-km-rKH/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-km-rKH/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-kn-rIN/bools.xml b/java/res/values-kn-rIN/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-kn-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-ky-rKG/bools.xml b/java/res/values-ky-rKG/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-ky-rKG/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-land/config.xml b/java/res/values-land/config.xml
index 34d6d4e19..d36f6a0fc 100644
--- a/java/res/values-land/config.xml
+++ b/java/res/values-land/config.xml
@@ -40,16 +40,22 @@
<!-- config_more_keys_keyboard_key_height x -0.5 -->
<dimen name="config_more_keys_keyboard_vertical_correction_holo">-22.4dp</dimen>
<dimen name="config_key_preview_offset_holo">1.6dp</dimen>
-
+ <dimen name="config_key_preview_height_holo">80dp</dimen>
+ <dimen name="config_key_preview_offset_lxx">43.6dp</dimen>
+ <dimen name="config_key_preview_height_lxx">122dp</dimen>
<fraction name="config_key_preview_text_ratio">90%</fraction>
- <fraction name="config_key_letter_ratio">65%</fraction>
+ <fraction name="config_key_letter_ratio_holo">65%</fraction>
+ <fraction name="config_key_letter_ratio_lxx">65%</fraction>
<fraction name="config_key_large_letter_ratio_holo">74%</fraction>
<fraction name="config_key_large_letter_ratio_lxx">90%</fraction>
- <fraction name="config_key_label_ratio">40%</fraction>
- <fraction name="config_key_hint_letter_ratio">30%</fraction>
+ <fraction name="config_key_label_ratio_holo">40%</fraction>
+ <fraction name="config_key_label_ratio_lxx">40%</fraction>
+ <fraction name="config_key_hint_letter_ratio_holo">30%</fraction>
+ <fraction name="config_key_hint_letter_ratio_lxx">30%</fraction>
<fraction name="config_key_hint_label_ratio_holo">52%</fraction>
<fraction name="config_key_hint_label_ratio_lxx">30%</fraction>
- <fraction name="config_key_shifted_letter_hint_ratio">40%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_holo">40%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_lxx">40%</fraction>
<fraction name="config_language_on_spacebar_text_ratio">40.000%</fraction>
<!-- For 5-row keyboard -->
diff --git a/java/res/values-land/keyboard-heights.xml b/java/res/values-land/keyboard-heights.xml
index d57f96be3..02d8b14c8 100644
--- a/java/res/values-land/keyboard-heights.xml
+++ b/java/res/values-land/keyboard-heights.xml
@@ -33,5 +33,7 @@
<!-- Preferable keyboard height in absolute scale: 45.0mm -->
<!-- Xoom -->
<item>HARDWARE=stingray,265.4378</item>
+ <!-- Volantis -->
+ <item>HARDWARE=flounder,272.0</item>
</string-array>
</resources>
diff --git a/java/res/values-lo-rLA/bools.xml b/java/res/values-lo-rLA/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-lo-rLA/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-mk-rMK/bools.xml b/java/res/values-mk-rMK/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-mk-rMK/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-ml-rIN/bools.xml b/java/res/values-ml-rIN/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-ml-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-mn-rMN/bools.xml b/java/res/values-mn-rMN/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-mn-rMN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-mr-rIN/bools.xml b/java/res/values-mr-rIN/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-mr-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-ne-rNP/bools.xml b/java/res/values-ne-rNP/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-ne-rNP/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-sw600dp-land/config.xml b/java/res/values-sw600dp-land/config.xml
index c238b2c42..d33af2e37 100644
--- a/java/res/values-sw600dp-land/config.xml
+++ b/java/res/values-sw600dp-land/config.xml
@@ -23,7 +23,7 @@
<!-- Preferable keyboard height in absolute scale: 45.0mm -->
<!-- This config_default_keyboard_height value should match with keyboard-heights.xml -->
<dimen name="config_default_keyboard_height">283.5dp</dimen>
- <fraction name="config_min_keyboard_height">45%p</fraction>
+ <fraction name="config_min_keyboard_height">40%p</fraction>
<dimen name="config_more_keys_keyboard_key_height">81.9dp</dimen>
@@ -32,14 +32,18 @@
<fraction name="config_key_vertical_gap_holo">4.5%p</fraction>
<fraction name="config_key_horizontal_gap_holo">0.9%p</fraction>
- <fraction name="config_key_letter_ratio">50%</fraction>
+ <fraction name="config_key_letter_ratio_holo">50%</fraction>
+ <fraction name="config_key_letter_ratio_lxx">50%</fraction>
<fraction name="config_key_large_letter_ratio_holo">48%</fraction>
<fraction name="config_key_large_letter_ratio_lxx">60%</fraction>
- <fraction name="config_key_label_ratio">32%</fraction>
- <fraction name="config_key_hint_letter_ratio">23%</fraction>
+ <fraction name="config_key_label_ratio_holo">32%</fraction>
+ <fraction name="config_key_label_ratio_lxx">32%</fraction>
+ <fraction name="config_key_hint_letter_ratio_holo">23%</fraction>
+ <fraction name="config_key_hint_letter_ratio_lxx">23%</fraction>
<fraction name="config_key_hint_label_ratio_holo">34%</fraction>
<fraction name="config_key_hint_label_ratio_lxx">20%</fraction>
- <fraction name="config_key_shifted_letter_hint_ratio">29%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_holo">29%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_lxx">29%</fraction>
<fraction name="config_language_on_spacebar_text_ratio">30.0%</fraction>
<dimen name="config_key_shifted_letter_hint_padding">4dp</dimen>
diff --git a/java/res/values-sw600dp/config.xml b/java/res/values-sw600dp/config.xml
index 3c489bbe8..44e0d0632 100644
--- a/java/res/values-sw600dp/config.xml
+++ b/java/res/values-sw600dp/config.xml
@@ -40,18 +40,20 @@
<fraction name="config_key_horizontal_gap_holo">1.565%p</fraction>
<!-- config_more_keys_keyboard_key_height x -0.5 -->
<dimen name="config_more_keys_keyboard_vertical_correction_holo">-31.5dp</dimen>
- <dimen name="config_key_preview_offset_holo">8.0dp</dimen>
- <dimen name="config_key_preview_height">94.5dp</dimen>
<fraction name="config_key_preview_text_ratio">50%</fraction>
- <fraction name="config_key_letter_ratio">42%</fraction>
+ <fraction name="config_key_letter_ratio_holo">42%</fraction>
+ <fraction name="config_key_letter_ratio_lxx">50%</fraction>
<fraction name="config_key_large_letter_ratio_holo">45%</fraction>
<fraction name="config_key_large_letter_ratio_lxx">60%</fraction>
- <fraction name="config_key_label_ratio">25%</fraction>
- <fraction name="config_key_hint_letter_ratio">23%</fraction>
+ <fraction name="config_key_label_ratio_holo">25%</fraction>
+ <fraction name="config_key_label_ratio_lxx">32%</fraction>
+ <fraction name="config_key_hint_letter_ratio_holo">23%</fraction>
+ <fraction name="config_key_hint_letter_ratio_lxx">23%</fraction>
<fraction name="config_key_hint_label_ratio_holo">28%</fraction>
<fraction name="config_key_hint_label_ratio_lxx">20%</fraction>
- <fraction name="config_key_shifted_letter_hint_ratio">22%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_holo">22%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_lxx">22%</fraction>
<fraction name="config_language_on_spacebar_text_ratio">28.0%</fraction>
<dimen name="config_key_hint_letter_padding">3dp</dimen>
<dimen name="config_key_shifted_letter_hint_padding">3dp</dimen>
diff --git a/java/res/values-sw768dp-land/config.xml b/java/res/values-sw768dp-land/config.xml
index 587a3c1a4..fdb95c6cc 100644
--- a/java/res/values-sw768dp-land/config.xml
+++ b/java/res/values-sw768dp-land/config.xml
@@ -23,25 +23,27 @@
<!-- Preferable keyboard height in absolute scale: 58.0mm -->
<!-- This config_default_keyboard_height value should match with keyboard-heights.xml -->
<dimen name="config_default_keyboard_height">365.4dp</dimen>
- <fraction name="config_min_keyboard_height">45%p</fraction>
+ <fraction name="config_min_keyboard_height">35%p</fraction>
<fraction name="config_keyboard_top_padding_holo">1.896%p</fraction>
<fraction name="config_keyboard_bottom_padding_holo">0.0%p</fraction>
<fraction name="config_key_vertical_gap_holo">3.690%p</fraction>
<fraction name="config_key_horizontal_gap_holo">1.030%p</fraction>
- <dimen name="config_key_preview_offset_holo">8.0dp</dimen>
<dimen name="config_more_keys_keyboard_key_height">81.9dp</dimen>
- <dimen name="config_key_preview_height">107.1dp</dimen>
- <fraction name="config_key_letter_ratio">43%</fraction>
+ <fraction name="config_key_letter_ratio_holo">43%</fraction>
+ <fraction name="config_key_letter_ratio_lxx">50%</fraction>
<fraction name="config_key_large_letter_ratio_holo">42%</fraction>
<fraction name="config_key_large_letter_ratio_lxx">60%</fraction>
- <fraction name="config_key_label_ratio">28%</fraction>
- <fraction name="config_key_hint_letter_ratio">23%</fraction>
+ <fraction name="config_key_label_ratio_holo">28%</fraction>
+ <fraction name="config_key_label_ratio_lxx">32%</fraction>
+ <fraction name="config_key_hint_letter_ratio_holo">23%</fraction>
+ <fraction name="config_key_hint_letter_ratio_lxx">23%</fraction>
<fraction name="config_key_hint_label_ratio_holo">28%</fraction>
<fraction name="config_key_hint_label_ratio_lxx">20%</fraction>
- <fraction name="config_key_shifted_letter_hint_ratio">24%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_holo">24%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_lxx">24%</fraction>
<fraction name="config_language_on_spacebar_text_ratio">24.00%</fraction>
<!-- For 5-row keyboard -->
diff --git a/java/res/values-sw768dp/config.xml b/java/res/values-sw768dp/config.xml
index f573c40df..13be6bedf 100644
--- a/java/res/values-sw768dp/config.xml
+++ b/java/res/values-sw768dp/config.xml
@@ -32,7 +32,6 @@
<fraction name="config_key_horizontal_gap_holo">1.066%p</fraction>
<!-- config_more_keys_keyboard_key_height x -0.5 -->
<dimen name="config_more_keys_keyboard_vertical_correction_holo">-31.5dp</dimen>
- <dimen name="config_key_preview_offset_holo">8.0dp</dimen>
<dimen name="config_more_keys_keyboard_key_height">63.0dp</dimen>
<dimen name="config_more_keys_keyboard_key_horizontal_padding">12dp</dimen>
@@ -40,16 +39,19 @@
<!-- config_more_keys_keyboard_key_height x 1.2 -->
<dimen name="config_more_keys_keyboard_slide_allowance">98.3dp</dimen>
- <dimen name="config_key_preview_height">94.5dp</dimen>
<fraction name="config_key_preview_text_ratio">50%</fraction>
- <fraction name="config_key_letter_ratio">40%</fraction>
+ <fraction name="config_key_letter_ratio_holo">40%</fraction>
+ <fraction name="config_key_letter_ratio_lxx">50%</fraction>
<fraction name="config_key_large_letter_ratio_holo">42%</fraction>
<fraction name="config_key_large_letter_ratio_lxx">60%</fraction>
- <fraction name="config_key_label_ratio">28%</fraction>
- <fraction name="config_key_hint_letter_ratio">23%</fraction>
+ <fraction name="config_key_label_ratio_holo">28%</fraction>
+ <fraction name="config_key_label_ratio_lxx">32%</fraction>
+ <fraction name="config_key_hint_letter_ratio_holo">23%</fraction>
+ <fraction name="config_key_hint_letter_ratio_lxx">23%</fraction>
<fraction name="config_key_hint_label_ratio_holo">28%</fraction>
<fraction name="config_key_hint_label_ratio_lxx">20%</fraction>
- <fraction name="config_key_shifted_letter_hint_ratio">26%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_holo">26%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_lxx">26%</fraction>
<fraction name="config_language_on_spacebar_text_ratio">29.03%</fraction>
<dimen name="config_key_hint_letter_padding">3dp</dimen>
<dimen name="config_key_shifted_letter_hint_padding">3dp</dimen>
diff --git a/java/res/values-ta-rIN/bools.xml b/java/res/values-ta-rIN/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-ta-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values-te-rIN/bools.xml b/java/res/values-te-rIN/bools.xml
new file mode 100644
index 000000000..130e52eab
--- /dev/null
+++ b/java/res/values-te-rIN/bools.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- Whether this input method should be used as the default for a locale. Override it
+ for supported languages. -->
+ <bool name="im_is_default">true</bool>
+</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index e89912a9d..f1253b40c 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -32,6 +32,8 @@
<attr name="moreKeysKeyboardStyle" format="reference" />
<!-- MoreKeysKeyboardView style -->
<attr name="moreKeysKeyboardViewStyle" format="reference" />
+ <!-- MoreKeysKeyboardView style for action key -->
+ <attr name="moreKeysKeyboardViewForActionStyle" format="reference" />
<!-- Suggestions strip style -->
<attr name="suggestionStripViewStyle" format="reference" />
<!-- Suggestion word style -->
@@ -113,8 +115,14 @@
<!-- TODO: consolidate key preview linger timeout with the key preview animation parameters. -->
<!-- Delay after key releasing and key press feedback dismissing in millisecond -->
<attr name="keyPreviewLingerTimeout" format="integer" />
+ <!-- Key preview show up animator -->
+ <attr name="keyPreviewShowUpAnimator" format="reference" />
+ <!-- Key preview dismiss animator -->
+ <attr name="keyPreviewDismissAnimator" format="reference" />
<!-- Layout resource for more keys keyboard -->
<attr name="moreKeysKeyboardLayout" format="reference" />
+ <!-- Layout resource for more keys keyboard of action key -->
+ <attr name="moreKeysKeyboardForActionLayout" format="reference" />
<attr name="backgroundDimAlpha" format="integer" />
<!-- More keys keyboard will shown at touched point. -->
<attr name="showMoreKeysKeyboardAtTouchedPoint" format="boolean" />
@@ -169,6 +177,10 @@
<attr name="suppressKeyPreviewAfterBatchInputDuration" format="integer" />
</declare-styleable>
+ <declare-styleable name="MoreKeysKeyboardView">
+ <attr name="divider" format="reference" />
+ </declare-styleable>
+
<declare-styleable name="EmojiPalettesView">
<attr name="categoryIndicatorEnabled" format="boolean" />
<attr name="categoryIndicatorDrawable" format="reference" />
@@ -203,7 +215,13 @@
</declare-styleable>
<declare-styleable name="Keyboard">
- <attr name="themeId" format="integer" />
+ <attr name="themeId" format="enum">
+ <!-- This should be aligned with KeyboardTheme.THEME_ID_*. -->
+ <enum name="ICS" value="0" />
+ <enum name="KLP" value="2" />
+ <enum name="LXXLight" value="3" />
+ <enum name="LXXDark" value="4" />
+ </attr>
<!-- Touch position correction -->
<attr name="touchPositionCorrectionData" format="reference" />
<!-- Keyboard top, bottom, left, right edges paddings, in propotion of keyboard height. -->
@@ -274,7 +292,7 @@
<enum name="stickyOff" value="3" />
<enum name="stickyOn" value="4" />
<enum name="action" value="5" />
- <enum name="customAction" value="6" />
+ <enum name="spacebar" value="6" />
</attr>
<!-- The key action flags. -->
<attr name="keyActionFlags" format="integer">
@@ -320,6 +338,8 @@
<!-- If true, use functionalTextColor instead of ketTextColor to drawing the label on
the key -->
<flag name="followFunctionalTextColor" value="0x80000" />
+ <!-- Keep aspect ratio of key background. -->
+ <flag name="keepBackgroundAspectRatio" value="0x100000" />
<!-- If true, disable keyHintLabel. -->
<flag name="disableKeyHintLabel" value="0x40000000" />
<!-- If true, disable additionalMoreKeys. -->
@@ -423,6 +443,13 @@
<enum name="emojiCategory5" value="15" />
<enum name="emojiCategory6" value="16" />
</attr>
+ <!-- This should be aligned with Keyboard.themeId and KeyboardTheme.THEME_ID_* -->
+ <attr name="keyboardTheme" format="enum|string">
+ <enum name="ICS" value="0" />
+ <enum name="KLP" value="2" />
+ <enum name="LXXLight" value="3" />
+ <enum name="LXXDark" value="4" />
+ </attr>
<!-- This should be aligned with KeyboardId.MODE_* -->
<attr name="mode" format="enum|string">
<enum name="text" value="0" />
diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml
index d42b4e900..5453d51c1 100644
--- a/java/res/values/colors.xml
+++ b/java/res/values/colors.xml
@@ -82,4 +82,6 @@
<color name="setup_text_action">@android:color/holo_blue_light</color>
<color name="setup_step_background">@android:color/background_light</color>
<color name="setup_welcome_video_margin_color">#FFCCCCCC</color>
+ <!-- Accent color for the notification. We need to match this to the OS build -->
+ <color name="notification_accent_color">#FF607D8B</color>
</resources>
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index af3b5890b..40760f686 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -43,17 +43,22 @@
<!-- config_more_keys_keyboard_key_height x -0.5 -->
<dimen name="config_more_keys_keyboard_vertical_correction_holo">-26.4dp</dimen>
<dimen name="config_key_preview_offset_holo">8.0dp</dimen>
-
- <dimen name="config_key_preview_height">80dp</dimen>
+ <dimen name="config_key_preview_height_holo">80dp</dimen>
+ <dimen name="config_key_preview_offset_lxx">50.0dp</dimen>
+ <dimen name="config_key_preview_height_lxx">122dp</dimen>
<fraction name="config_key_preview_text_ratio">82%</fraction>
- <fraction name="config_key_letter_ratio">55%</fraction>
+ <fraction name="config_key_letter_ratio_holo">55%</fraction>
+ <fraction name="config_key_letter_ratio_lxx">55%</fraction>
<fraction name="config_key_large_letter_ratio_holo">65%</fraction>
<fraction name="config_key_large_letter_ratio_lxx">90%</fraction>
- <fraction name="config_key_label_ratio">34%</fraction>
- <fraction name="config_key_hint_letter_ratio">25%</fraction>
+ <fraction name="config_key_label_ratio_holo">34%</fraction>
+ <fraction name="config_key_label_ratio_lxx">34%</fraction>
+ <fraction name="config_key_hint_letter_ratio_holo">25%</fraction>
+ <fraction name="config_key_hint_letter_ratio_lxx">25%</fraction>
<fraction name="config_key_hint_label_ratio_holo">44%</fraction>
<fraction name="config_key_hint_label_ratio_lxx">30%</fraction>
- <fraction name="config_key_shifted_letter_hint_ratio">35%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_holo">35%</fraction>
+ <fraction name="config_key_shifted_letter_hint_ratio_lxx">35%</fraction>
<fraction name="config_language_on_spacebar_text_ratio">33.735%</fraction>
<dimen name="config_key_hint_letter_padding">1dp</dimen>
<dimen name="config_key_shifted_letter_hint_padding">2dp</dimen>
diff --git a/java/res/values/donottranslate-debug-settings.xml b/java/res/values/donottranslate-debug-settings.xml
new file mode 100644
index 000000000..35e6efa77
--- /dev/null
+++ b/java/res/values/donottranslate-debug-settings.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Title for Android keyboard debug settings activity / dialog -->
+ <string name="english_ime_debug_settings">Android Keyboard Debug settings</string>
+ <string name="prefs_debug_mode">Debug Mode</string>
+ <string name="prefs_force_non_distinct_multitouch">Force non-distinct multitouch</string>
+ <string name="prefs_force_physical_keyboard_special_key">Force physical keyboard special key</string>
+ <string name="prefs_show_ui_to_accept_typed_word">Show UI to accept typed word</string>
+ <!-- Option to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=30]-->
+ <string name="sliding_key_input_preview">Show slide indicator</string>
+ <!-- Option summary to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=66]-->
+ <string name="sliding_key_input_preview_summary">Display visual cue while sliding from Shift or Symbol keys</string>
+ <!-- Title of the settings for key long press delay [CHAR LIMIT=35] -->
+ <string name="prefs_key_longpress_timeout_settings">Key long press delay</string>
+ <!-- Title of the settings for customize key popup animation parameters [CHAR LIMIT=35] -->
+ <string name="prefs_customize_key_preview_animation">Customize key preview animation</string>
+ <!-- Title of the settings for key popup show up animation duration (in milliseconds) [CHAR LIMIT=35] -->
+ <string name="prefs_key_popup_show_up_duration_settings">Key popup show up duration</string>
+ <!-- Title of the settings for key popup dismiss animation duration (in milliseconds) [CHAR LIMIT=35] -->
+ <string name="prefs_key_popup_dismiss_duration_settings">Key popup dismiss duration</string>
+ <!-- Title of the settings for key popup show up animation start X-scale (in percentile) [CHAR LIMIT=35] -->
+ <string name="prefs_key_popup_show_up_start_x_scale_settings">Key popup show up start X scale</string>
+ <!-- Title of the settings for key popup show up animation start Y-scale (in percentile) [CHAR LIMIT=35] -->
+ <string name="prefs_key_popup_show_up_start_y_scale_settings">Key popup show up start Y scale</string>
+ <!-- Title of the settings for key popup dismiss animation end X-scale (in percentile) [CHAR LIMIT=35] -->
+ <string name="prefs_key_popup_dismiss_end_x_scale_settings">Key popup dismiss end X scale</string>
+ <!-- Title of the settings for key popup dismiss animation end Y-scale (in percentile) [CHAR LIMIT=35] -->
+ <string name="prefs_key_popup_dismiss_end_y_scale_settings">Key popup dismiss end Y scale</string>
+ <!-- Title of the settings for reading an external dictionary file -->
+ <string name="prefs_read_external_dictionary">Read external dictionary file</string>
+ <!-- Message to show when there are no files to install as an external dictionary [CHAR LIMIT=100] -->
+ <string name="read_external_dictionary_no_files_message">No dictionary files in the Downloads folder</string>
+ <!-- Title of the dialog that selects a file to install as an external dictionary [CHAR LIMIT=50] -->
+ <string name="read_external_dictionary_multiple_files_title">Select a dictionary file to install</string>
+ <!-- Title of the confirmation dialog to install a file as an external dictionary [CHAR LIMIT=50] -->
+ <string name="read_external_dictionary_confirm_install_message">Really install this file for <xliff:g id="LANGUAGE_NAME" example="English">%s</xliff:g>?</string>
+ <!-- Title for an error dialog that contains the details of the error in the body [CHAR LIMIT=80] -->
+ <string name="read_external_dictionary_error">There was an error</string>
+ <!-- Title of the settings group for dumpping dictionary files that have been created on the device [CHAR LIMIT=35] -->
+ <string name="prefs_dump_dynamic_dicts">Dump dictionary</string>
+</resources>
diff --git a/java/res/values/donottranslate-text-decorator.xml b/java/res/values/donottranslate-text-decorator.xml
new file mode 100644
index 000000000..269364573
--- /dev/null
+++ b/java/res/values/donottranslate-text-decorator.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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>
+ <!-- The extra margin in dp around the hit area of the commit/add-to-dictionary indicator -->
+ <integer name="text_decorator_hit_area_margin_in_dp">
+ 4
+ </integer>
+
+ <!-- Background color to be used to highlight the target text when the add-to-dictionary
+ indicator is visible. -->
+ <color name="text_decorator_add_to_dictionary_indicator_text_highlight_color">
+ #D1E7B7
+ </color>
+
+ <!-- Foreground color of the commit indicator. -->
+ <color name="text_decorator_add_to_dictionary_indicator_background_color">
+ #4EB848
+ </color>
+
+ <!-- Foreground color of the add-to-dictionary indicator. -->
+ <color name="text_decorator_add_to_dictionary_indicator_foreground_color">
+ #FFFFFF
+ </color>
+
+ <!-- Viewport size of "text_decorator_add_to_dictionary_indicator_path". -->
+ <integer name="text_decorator_add_to_dictionary_indicator_path_size">
+ 480
+ </integer>
+
+ <!-- Coordinates of the closed path to be used to render the add-to-dictionary indicator.
+ The format is: X[0], Y[0], X[1], Y[1], ..., X[N-1], Y[N-1] -->
+ <integer-array name="text_decorator_add_to_dictionary_indicator_path">
+ <item>380</item>
+ <item>260</item>
+ <item>260</item>
+ <item>260</item>
+ <item>260</item>
+ <item>380</item>
+ <item>220</item>
+ <item>380</item>
+ <item>220</item>
+ <item>260</item>
+ <item>100</item>
+ <item>260</item>
+ <item>100</item>
+ <item>220</item>
+ <item>220</item>
+ <item>220</item>
+ <item>220</item>
+ <item>100</item>
+ <item>260</item>
+ <item>100</item>
+ <item>260</item>
+ <item>220</item>
+ <item>380</item>
+ <item>220</item>
+ </integer-array>
+</resources>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index b25a20803..c54b995f8 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -22,13 +22,6 @@
See {@link SettingsValues#needsToShowVoiceInputKey(SharedPreferences,Resources)} -->
<string name="voice_mode_main">0</string>
- <!-- Title for Android keyboard debug settings activity / dialog -->
- <string name="english_ime_debug_settings">Android Keyboard Debug settings</string>
- <string name="prefs_debug_mode">Debug Mode</string>
- <string name="prefs_force_non_distinct_multitouch">Force non-distinct multitouch</string>
- <string name="prefs_force_physical_keyboard_special_key">Force physical keyboard special key</string>
- <string name="prefs_show_ui_to_accept_typed_word">Show UI to accept typed word</string>
-
<!-- Subtype locale display name exceptions.
For each exception, there should be related string resources for display name that may have
explicit keyboard layout. The string resource name must be "subtype_<locale>" or
diff --git a/java/res/values/keyboard-icons-lxx-dark.xml b/java/res/values/keyboard-icons-lxx-dark.xml
index 305df02cd..2e2fd0abb 100644
--- a/java/res/values/keyboard-icons-lxx-dark.xml
+++ b/java/res/values/keyboard-icons-lxx-dark.xml
@@ -24,7 +24,7 @@
<item name="iconShiftKey">@drawable/sym_keyboard_shift_lxx_dark</item>
<item name="iconDeleteKey">@drawable/sym_keyboard_delete_lxx_dark</item>
<item name="iconSettingsKey">@drawable/sym_keyboard_settings_lxx_dark</item>
- <item name="iconSpaceKey">@drawable/sym_keyboard_spacebar_lxx_dark</item>
+ <item name="iconSpaceKey">@null</item>
<item name="iconEnterKey">@drawable/sym_keyboard_return_lxx_dark</item>
<item name="iconGoKey">@drawable/sym_keyboard_go_lxx_dark</item>
<item name="iconSearchKey">@drawable/sym_keyboard_search_lxx_dark</item>
diff --git a/java/res/values/keyboard-icons-lxx-light.xml b/java/res/values/keyboard-icons-lxx-light.xml
index 866dc682f..099a706fe 100644
--- a/java/res/values/keyboard-icons-lxx-light.xml
+++ b/java/res/values/keyboard-icons-lxx-light.xml
@@ -24,7 +24,7 @@
<item name="iconShiftKey">@drawable/sym_keyboard_shift_lxx_light</item>
<item name="iconDeleteKey">@drawable/sym_keyboard_delete_lxx_light</item>
<item name="iconSettingsKey">@drawable/sym_keyboard_settings_lxx_light</item>
- <item name="iconSpaceKey">@drawable/sym_keyboard_spacebar_lxx_light</item>
+ <item name="iconSpaceKey">@null</item>
<item name="iconEnterKey">@drawable/sym_keyboard_return_lxx_light</item>
<item name="iconGoKey">@drawable/sym_keyboard_go_lxx_light</item>
<item name="iconSearchKey">@drawable/sym_keyboard_search_lxx_light</item>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index b3e58e92a..2f8b3800d 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -36,18 +36,20 @@
<!-- Option to control whether or not to show a popup with a larger font on each key press. -->
<string name="popup_on_keypress">Popup on keypress</string>
- <!-- Settings screen title for input preferences [CHAR LIMIT=33]-->
- <string name="settings_screen_input">Input preferences</string>
- <!-- Settings screen title for appearance preferences [CHAR LIMIT=33] -->
- <string name="settings_screen_appearances">Appearance</string>
- <!-- Settings screen title for multi lingual options [CHAR_LIMIT=33] -->
- <string name="settings_screen_multi_lingual">Multi lingual options</string>
+ <!-- Settings screen title for preferences [CHAR LIMIT=33]-->
+ <string name="settings_screen_preferences">Preferences</string>
+ <!-- Settings screen title for appearance & layouts preferences [CHAR LIMIT=33] -->
+ <string name="settings_screen_appearance">Appearance &amp; layouts</string>
+ <!-- Settings screen title for multilingual options [CHAR_LIMIT=33] -->
+ <string name="settings_screen_multilingual">Multilingual options</string>
<!-- Settings screen title for gesture typing preferences [CHAR_LIMIT=33] -->
- <string name="settings_screen_gesture">Gesture typing preferences</string>
+ <string name="settings_screen_gesture">Gesture Typing</string>
<!-- Settings screen title for text correction options [CHAR_LIMIT=33] -->
<string name="settings_screen_correction">Text correction</string>
<!-- Settings screen title for advanced settings [CHAR LIMIT=33] -->
<string name="settings_screen_advanced">Advanced</string>
+ <!-- Settings screen title for keyboard theme settings [CHAR LIMIT=33] -->
+ <string name="settings_screen_theme">Theme</string>
<!-- Option name for including other IMEs in the language switch list [CHAR LIMIT=30] -->
<string name="include_other_imes_in_language_switch_list">Switch to other input methods</string>
@@ -58,11 +60,6 @@
<!-- Option summary for showing language switch key [CHAR LIMIT=65] -->
<string name="show_language_switch_key_summary">Show when multiple input languages are enabled</string>
- <!-- Option to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=30]-->
- <string name="sliding_key_input_preview">Show slide indicator</string>
- <!-- Option summary to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=66]-->
- <string name="sliding_key_input_preview_summary">Display visual cue while sliding from Shift or Symbol keys</string>
-
<!-- Option for the dismiss delay of the key popup [CHAR LIMIT=25] -->
<string name="key_preview_popup_dismiss_delay">Key popup dismiss delay</string>
<!-- Description for delay for dismissing a popup on keypress: no delay [CHAR LIMIT=15] -->
@@ -157,14 +154,14 @@
<string name="configure_input_method">Configure input methods</string>
<!-- Title for input language selection screen -->
- <string name="language_selection_title">Input languages</string>
+ <string name="language_selection_title">Languages</string>
<!-- Title for the 'Help & feedback' settings fragment which shows a help page and has a button
for submitting feedback. [CHAR LIMIT=35] -->
<string name="help_and_feedback">Help &amp; feedback</string>
<!-- Preference for input language selection -->
- <string name="select_language">Input languages</string>
+ <string name="select_language">Languages</string>
<!-- Add to dictionary hint -->
<string name="hint_add_to_dictionary">Touch again to save</string>
@@ -325,32 +322,10 @@ mobile devices. [CHAR LIMIT=25] -->
<!-- Toast text to describe the same input style already exists [CHAR LIMIT=64]-->
<string name="custom_input_style_already_exists">"The same input style already exists: <xliff:g id="INPUT_STYLE_NAME" example="English (Dvorak)">%s</xliff:g>"</string>
- <!-- Title of the settings for key long press delay [CHAR LIMIT=35] -->
- <string name="prefs_key_longpress_timeout_settings">Key long press delay</string>
<!-- Title of the settings for keypress vibration duration [CHAR LIMIT=35] -->
<string name="prefs_keypress_vibration_duration_settings">Keypress vibration duration</string>
<!-- Title of the settings for keypress sound volume [CHAR LIMIT=35] -->
<string name="prefs_keypress_sound_volume_settings">Keypress sound volume</string>
- <!-- Title of the settings for key popup show up animation duration (in milliseconds) [CHAR LIMIT=35] -->
- <string name="prefs_key_popup_show_up_duration_settings" translatable="false">Key popup show up duration</string>
- <!-- Title of the settings for key popup dismiss animation duration (in milliseconds) [CHAR LIMIT=35] -->
- <string name="prefs_key_popup_dismiss_duration_settings" translatable="false">Key popup dismiss duration</string>
- <!-- Title of the settings for key popup show up animation start scale (in percentile) [CHAR LIMIT=35] -->
- <string name="prefs_key_popup_show_up_start_scale_settings" translatable="false">Key popup show up start scale</string>
- <!-- Title of the settings for key popup dismiss animation end scale (in percentile) [CHAR LIMIT=35] -->
- <string name="prefs_key_popup_dismiss_end_scale_settings" translatable="false">Key popup dismiss end scale</string>
- <!-- Title of the settings for reading an external dictionary file -->
- <string name="prefs_read_external_dictionary">Read external dictionary file</string>
- <!-- Message to show when there are no files to install as an external dictionary [CHAR LIMIT=100] -->
- <string name="read_external_dictionary_no_files_message">No dictionary files in the Downloads folder</string>
- <!-- Title of the dialog that selects a file to install as an external dictionary [CHAR LIMIT=50] -->
- <string name="read_external_dictionary_multiple_files_title">Select a dictionary file to install</string>
- <!-- Title of the confirmation dialog to install a file as an external dictionary [CHAR LIMIT=50] -->
- <string name="read_external_dictionary_confirm_install_message">Really install this file for <xliff:g id="LANGUAGE_NAME" example="English">%s</xliff:g>?</string>
- <!-- Title for an error dialog that contains the details of the error in the body [CHAR LIMIT=80] -->
- <string name="error">There was an error</string>
- <!-- Title of the settings group for dumpping dictionary files that have been created on the device [CHAR LIMIT=35] -->
- <string name="prefs_dump_dynamic_dicts" translatable="false">Dump dictionary</string>
<!-- 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>
diff --git a/java/res/values/themes-common.xml b/java/res/values/themes-common.xml
index 6805830cb..110f6b792 100644
--- a/java/res/values/themes-common.xml
+++ b/java/res/values/themes-common.xml
@@ -37,12 +37,6 @@
<!-- This keyBackground is needed to run unit tests based on {@link InputTestBase}. -->
<!-- TODO: Apply default {@link KeyboardTheme} to {@link InputTestBase} and remove this. -->
<item name="keyBackground">@drawable/btn_keyboard_key_klp</item>
- <item name="keyLetterSize">@fraction/config_key_letter_ratio</item>
- <item name="keyLargeLetterRatio">@fraction/config_key_large_letter_ratio_holo</item>
- <item name="keyLabelSize">@fraction/config_key_label_ratio</item>
- <item name="keyHintLetterRatio">@fraction/config_key_hint_letter_ratio</item>
- <item name="keyHintLabelRatio">@fraction/config_key_hint_label_ratio_holo</item>
- <item name="keyShiftedLetterHintRatio">@fraction/config_key_shifted_letter_hint_ratio</item>
<item name="keyTypeface">normal</item>
<!-- A negative value to disable key text shadow layer. -->
<item name="keyTextShadowRadius">-1.0</item>
@@ -81,7 +75,6 @@
<item name="keyRepeatInterval">@integer/config_key_repeat_interval</item>
<item name="longPressShiftLockTimeout">@integer/config_longpress_shift_lock_timeout</item>
<item name="ignoreAltCodeKeyTimeout">@integer/config_ignore_alt_code_key_timeout</item>
- <item name="keyPreviewHeight">@dimen/config_key_preview_height</item>
<!-- TODO: consolidate key preview linger timeout with the key preview animation parameters. -->
<item name="keyPreviewLingerTimeout">@integer/config_key_preview_linger_timeout</item>
<item name="moreKeysKeyboardLayout">@layout/more_keys_keyboard</item>
@@ -115,10 +108,7 @@
for instance delete button, need themed {@link KeyboardView} attributes. -->
<style name="EmojiPalettesView" />
<style name="MoreKeysKeyboard" />
- <style
- name="MoreKeysKeyboardView"
- parent="KeyboardView" />
- <style name="MoreKeysKeyboardContainer" />
+ <style name="MoreKeysKeyboardView" />
<style name="SuggestionStripView" />
<style name="SuggestionWord">
<item name="android:minWidth">@dimen/config_suggestion_min_width</item>
diff --git a/java/res/values/themes-holo.xml b/java/res/values/themes-holo.xml
index cb3ad7a3a..9f1bd2f78 100644
--- a/java/res/values/themes-holo.xml
+++ b/java/res/values/themes-holo.xml
@@ -25,6 +25,10 @@
parent="KeyboardView"
>
<item name="keyTypeface">bold</item>
+ <item name="keyLetterSize">@fraction/config_key_letter_ratio_holo</item>
+ <item name="keyLabelSize">@fraction/config_key_label_ratio_holo</item>
+ <item name="keyHintLetterRatio">@fraction/config_key_hint_letter_ratio_holo</item>
+ <item name="keyShiftedLetterHintRatio">@fraction/config_key_shifted_letter_hint_ratio_holo</item>
<item name="keyLargeLetterRatio">@fraction/config_key_large_letter_ratio_holo</item>
<item name="keyLabelOffCenterRatio">-175%</item>
<item name="keyHintLabelRatio">@fraction/config_key_hint_label_ratio_holo</item>
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
index 6fddcb905..bfbac0a94 100644
--- a/java/res/values/themes-ics.xml
+++ b/java/res/values/themes-ics.xml
@@ -25,7 +25,9 @@
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.ICS</item>
<item name="emojiPalettesViewStyle">@style/EmojiPalettesView.ICS</item>
<item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.ICS</item>
+ <!-- Note: ICS theme uses the same style for both general more keys and action more keys. -->
<item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.ICS</item>
+ <item name="moreKeysKeyboardViewForActionStyle">@style/MoreKeysKeyboardView.ICS</item>
<item name="suggestionStripViewStyle">@style/SuggestionStripView.ICS</item>
<item name="suggestionWordStyle">@style/SuggestionWord.ICS</item>
</style>
@@ -33,8 +35,8 @@
name="Keyboard.ICS"
parent="Keyboard"
>
- <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
- <item name="themeId">2</item>
+ <!-- This should be aligned with KeyboardTheme.THEME_ID_* -->
+ <item name="themeId">ICS</item>
</style>
<style
name="KeyboardView.ICS"
@@ -58,7 +60,10 @@
parent="KeyboardView.ICS"
>
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_ics</item>
+ <item name="keyPreviewHeight">@dimen/config_key_preview_height_holo</item>
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
+ <item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_holo</item>
+ <item name="keyPreviewDismissAnimator">@anim/key_preview_dismiss_holo</item>
<item name="gestureFloatingPreviewTextColor">@color/highlight_color_ics</item>
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_holo</item>
<item name="gestureTrailColor">@color/highlight_color_ics</item>
@@ -101,6 +106,7 @@
>
<item name="android:background">@drawable/keyboard_popup_panel_background_ics</item>
<item name="keyBackground">@drawable/btn_keyboard_key_popup_ics</item>
+ <item name="divider">@drawable/more_keys_divider</item>
<item name="keyTypeface">normal</item>
<item name="verticalCorrection">@dimen/config_more_keys_keyboard_vertical_correction_holo</item>
</style>
diff --git a/java/res/values/themes-klp.xml b/java/res/values/themes-klp.xml
index c9b83316c..36b1fc117 100644
--- a/java/res/values/themes-klp.xml
+++ b/java/res/values/themes-klp.xml
@@ -25,7 +25,9 @@
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.KLP</item>
<item name="emojiPalettesViewStyle">@style/EmojiPalettesView.KLP</item>
<item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.KLP</item>
+ <!-- Note: KLP theme uses the same style for both general more keys and action more keys. -->
<item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.KLP</item>
+ <item name="moreKeysKeyboardViewForActionStyle">@style/MoreKeysKeyboardView.KLP</item>
<item name="suggestionStripViewStyle">@style/SuggestionStripView.KLP</item>
<item name="suggestionWordStyle">@style/SuggestionWord.KLP</item>
</style>
@@ -33,8 +35,8 @@
name="Keyboard.KLP"
parent="Keyboard"
>
- <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
- <item name="themeId">0</item>
+ <!-- This should be aligned with KeyboardTheme.THEME_ID_* -->
+ <item name="themeId">KLP</item>
</style>
<style
name="KeyboardView.KLP"
@@ -58,7 +60,10 @@
parent="KeyboardView.KLP"
>
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_klp</item>
+ <item name="keyPreviewHeight">@dimen/config_key_preview_height_holo</item>
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
+ <item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_holo</item>
+ <item name="keyPreviewDismissAnimator">@anim/key_preview_dismiss_holo</item>
<item name="gestureFloatingPreviewTextColor">@color/highlight_color_klp</item>
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_holo</item>
<item name="gestureTrailColor">@color/highlight_color_klp</item>
@@ -101,6 +106,7 @@
>
<item name="android:background">@drawable/keyboard_popup_panel_background_klp</item>
<item name="keyBackground">@drawable/btn_keyboard_key_popup_klp</item>
+ <item name="divider">@drawable/more_keys_divider</item>
<item name="keyTypeface">normal</item>
<item name="verticalCorrection">@dimen/config_more_keys_keyboard_vertical_correction_holo</item>
</style>
diff --git a/java/res/values/themes-lxx-dark.xml b/java/res/values/themes-lxx-dark.xml
index 6afbd9b15..67f94f329 100644
--- a/java/res/values/themes-lxx-dark.xml
+++ b/java/res/values/themes-lxx-dark.xml
@@ -26,6 +26,7 @@
<item name="emojiPalettesViewStyle">@style/EmojiPalettesView.LXX_Dark</item>
<item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.LXX_Dark</item>
<item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.LXX_Dark</item>
+ <item name="moreKeysKeyboardViewForActionStyle">@style/MoreKeysKeyboardView.LXX_Dark.Action</item>
<item name="suggestionStripViewStyle">@style/SuggestionStripView.LXX_Dark</item>
<item name="suggestionWordStyle">@style/SuggestionWord.LXX_Dark</item>
</style>
@@ -33,8 +34,8 @@
name="Keyboard.LXX_Dark"
parent="Keyboard"
>
- <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
- <item name="themeId">4</item>
+ <!-- This should be aligned with KeyboardTheme.THEME_ID_* -->
+ <item name="themeId">LXXDark</item>
</style>
<style
name="KeyboardView.LXX_Dark"
@@ -57,8 +58,12 @@
name="MainKeyboardView.LXX_Dark"
parent="KeyboardView.LXX_Dark"
>
+ <item name="moreKeysKeyboardForActionLayout">@layout/more_keys_keyboard_for_action_lxx</item>
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_lxx_dark</item>
- <item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
+ <item name="keyPreviewHeight">@dimen/config_key_preview_height_lxx</item>
+ <item name="keyPreviewOffset">@dimen/config_key_preview_offset_lxx</item>
+ <item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_lxx</item>
+ <item name="keyPreviewDismissAnimator">@anim/key_preview_dismiss_lxx</item>
<item name="gestureFloatingPreviewTextColor">@color/auto_correct_color_lxx_dark</item>
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_lxx_dark</item>
<item name="gestureTrailColor">@color/gesture_trail_color_lxx_dark</item>
@@ -99,10 +104,20 @@
>
<item name="android:background">@drawable/keyboard_popup_panel_background_lxx_dark</item>
<item name="keyBackground">@drawable/btn_keyboard_key_popup_lxx_dark</item>
+ <item name="divider">@drawable/more_keys_divider</item>
<item name="keyTypeface">normal</item>
<item name="verticalCorrection">@dimen/config_more_keys_keyboard_vertical_correction_holo</item>
</style>
<style
+ name="MoreKeysKeyboardView.LXX_Dark.Action"
+ parent="MoreKeysKeyboardView.LXX_Dark"
+ >
+ <item name="android:background">@android:color/transparent</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_popup_action_lxx_dark</item>
+ <item name="divider">@null</item>
+ <item name="keyLabelFlags">keepBackgroundAspectRatio</item>
+ </style>
+ <style
name="SuggestionStripView.LXX_Dark"
parent="KeyboardView.LXX_Dark"
>
diff --git a/java/res/values/themes-lxx-light.xml b/java/res/values/themes-lxx-light.xml
index b3ced80a1..be817f46a 100644
--- a/java/res/values/themes-lxx-light.xml
+++ b/java/res/values/themes-lxx-light.xml
@@ -26,6 +26,7 @@
<item name="emojiPalettesViewStyle">@style/EmojiPalettesView.LXX_Light</item>
<item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.LXX_Light</item>
<item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.LXX_Light</item>
+ <item name="moreKeysKeyboardViewForActionStyle">@style/MoreKeysKeyboardView.LXX_Light.Action</item>
<item name="suggestionStripViewStyle">@style/SuggestionStripView.LXX_Light</item>
<item name="suggestionWordStyle">@style/SuggestionWord.LXX_Light</item>
</style>
@@ -33,8 +34,8 @@
name="Keyboard.LXX_Light"
parent="Keyboard"
>
- <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
- <item name="themeId">3</item>
+ <!-- This should be aligned with KeyboardTheme.THEME_ID_* -->
+ <item name="themeId">LXXLight</item>
</style>
<style
name="KeyboardView.LXX_Light"
@@ -57,8 +58,12 @@
name="MainKeyboardView.LXX_Light"
parent="KeyboardView.LXX_Light"
>
+ <item name="moreKeysKeyboardForActionLayout">@layout/more_keys_keyboard_for_action_lxx</item>
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_lxx_light</item>
- <item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
+ <item name="keyPreviewHeight">@dimen/config_key_preview_height_lxx</item>
+ <item name="keyPreviewOffset">@dimen/config_key_preview_offset_lxx</item>
+ <item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_lxx</item>
+ <item name="keyPreviewDismissAnimator">@anim/key_preview_dismiss_lxx</item>
<item name="gestureFloatingPreviewTextColor">@color/auto_correct_color_lxx_light</item>
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_lxx_light</item>
<item name="gestureTrailColor">@color/gesture_trail_color_lxx_light</item>
@@ -98,12 +103,21 @@
parent="KeyboardView.LXX_Light"
>
<item name="android:background">@drawable/keyboard_popup_panel_background_lxx_light</item>
- <!-- Reuse KLP key background -->
- <item name="keyBackground">@drawable/btn_keyboard_key_popup_klp</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_popup_lxx_light</item>
+ <item name="divider">@drawable/more_keys_divider</item>
<item name="keyTypeface">normal</item>
<item name="verticalCorrection">@dimen/config_more_keys_keyboard_vertical_correction_holo</item>
</style>
<style
+ name="MoreKeysKeyboardView.LXX_Light.Action"
+ parent="MoreKeysKeyboardView.LXX_Light"
+ >
+ <item name="android:background">@android:color/transparent</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_popup_action_lxx_light</item>
+ <item name="divider">@null</item>
+ <item name="keyLabelFlags">keepBackgroundAspectRatio</item>
+ </style>
+ <style
name="SuggestionStripView.LXX_Light"
parent="KeyboardView.LXX_Light"
>
diff --git a/java/res/values/themes-lxx.xml b/java/res/values/themes-lxx.xml
index 1c33cd60b..c72188871 100644
--- a/java/res/values/themes-lxx.xml
+++ b/java/res/values/themes-lxx.xml
@@ -25,6 +25,10 @@
parent="KeyboardView"
>
<item name="keyTypeface">normal</item>
+ <item name="keyLetterSize">@fraction/config_key_letter_ratio_lxx</item>
+ <item name="keyLabelSize">@fraction/config_key_label_ratio_lxx</item>
+ <item name="keyHintLetterRatio">@fraction/config_key_hint_letter_ratio_lxx</item>
+ <item name="keyShiftedLetterHintRatio">@fraction/config_key_shifted_letter_hint_ratio_lxx</item>
<item name="keyLargeLetterRatio">@fraction/config_key_large_letter_ratio_lxx</item>
<item name="keyLabelOffCenterRatio">-80%</item>
<item name="keyHintLabelRatio">@fraction/config_key_hint_label_ratio_lxx</item>
diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml
index c750a9319..006cda370 100644
--- a/java/res/xml-sw600dp/key_styles_common.xml
+++ b/java/res/xml-sw600dp/key_styles_common.xml
@@ -86,6 +86,7 @@
<key-style
latin:styleName="spaceKeyStyle"
latin:keySpec="!icon/space_key|!code/key_space"
+ latin:backgroundType="spacebar"
latin:keyActionFlags="noKeyPreview|enableLongPress" />
<!-- U+200C: ZERO WIDTH NON-JOINER
U+200D: ZERO WIDTH JOINER -->
diff --git a/java/res/xml-sw600dp/key_styles_enter.xml b/java/res/xml-sw600dp/key_styles_enter.xml
index c20523b2a..63ef2f8f9 100644
--- a/java/res/xml-sw600dp/key_styles_enter.xml
+++ b/java/res/xml-sw600dp/key_styles_enter.xml
@@ -22,20 +22,18 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<!-- Navigate more keys style -->
+ <include latin:keyboardLayout="@xml/key_styles_navigate_more_keys" />
<switch>
- <!-- latin:passwordInput="true" -->
<case
latin:imeAction="actionNext"
latin:navigatePrevious="true"
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_previous" />
+ latin:parentStyle="navigatePreviousMoreKeysStyle" />
</case>
<case
latin:imeAction="actionNext"
- latin:navigatePrevious="false"
>
<key-style
latin:styleName="navigateMoreKeysStyle" />
@@ -46,12 +44,10 @@
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_next" />
+ latin:parentStyle="navigateNextMoreKeysStyle" />
</case>
<case
latin:imeAction="actionPrevious"
- latin:navigateNext="false"
>
<key-style
latin:styleName="navigateMoreKeysStyle" />
@@ -62,47 +58,50 @@
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_action_previous,!text/keyspec_action_next" />
+ latin:parentStyle="navigatePreviousNextMoreKeysStyle" />
</case>
<case
latin:navigateNext="true"
- latin:navigatePrevious="false"
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_next" />
+ latin:parentStyle="navigateNextMoreKeysStyle" />
</case>
<case
- latin:navigateNext="false"
latin:navigatePrevious="true"
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_previous" />
+ latin:parentStyle="navigatePreviousMoreKeysStyle" />
</case>
- <case
- latin:navigateNext="false"
- latin:navigatePrevious="false"
- >
+ <default>
<key-style
latin:styleName="navigateMoreKeysStyle" />
+ </default>
+ </switch>
+ <!-- Enter key style -->
+ <switch>
+ <case latin:keyboardTheme="ICS|KLP">
+ <key-style
+ latin:styleName="defaultEnterKeyStyle"
+ latin:keySpec="!icon/enter_key|!code/key_enter"
+ latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="action"
+ latin:parentStyle="navigateMoreKeysStyle" />
</case>
+ <!-- keyboardTheme="LXXLight|LXXDark" -->
<default>
<key-style
- latin:styleName="navigateMoreKeysStyle" />
+ latin:styleName="defaultEnterKeyStyle"
+ latin:keySpec="!icon/enter_key|!code/key_enter"
+ latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor|keepBackgroundAspectRatio"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="action"
+ latin:parentStyle="navigateMoreKeysStyle" />
</default>
</switch>
- <!-- Enter key style -->
- <key-style
- latin:styleName="defaultEnterKeyStyle"
- latin:keySpec="!icon/enter_key|!code/key_enter"
- latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor"
- latin:keyActionFlags="noKeyPreview"
- latin:backgroundType="action"
- latin:parentStyle="navigateMoreKeysStyle" />
+ <include latin:keyboardLayout="@xml/key_styles_actions" />
<switch>
<!-- Shift + Enter in textMultiLine field. -->
<case
@@ -116,121 +115,52 @@
</case>
<case
latin:imeAction="actionGo"
- latin:isIconDefined="go_key"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/go_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionGo"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_go_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="goActionKeyStyle" />
</case>
<case
latin:imeAction="actionNext"
- latin:isIconDefined="next_key"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/next_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionNext"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_next_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="nextActionKeyStyle" />
</case>
<case
latin:imeAction="actionPrevious"
- latin:isIconDefined="previous_key"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/previous_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionPrevious"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_previous_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="previousActionKeyStyle" />
</case>
<case
latin:imeAction="actionDone"
- latin:isIconDefined="done_key"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/done_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionDone"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_done_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="doneActionKeyStyle" />
</case>
<case
latin:imeAction="actionSend"
- latin:isIconDefined="send_key"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/send_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionSend"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_send_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionSearch"
- latin:isIconDefined="search_key"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/search_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="sendActionKeyStyle" />
</case>
<case
latin:imeAction="actionSearch"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_search_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="searchActionKeyStyle" />
</case>
<case
latin:imeAction="actionCustomLabel"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="dummy_label|!code/key_enter"
- latin:keyLabelFlags="fromCustomActionLabel"
- latin:backgroundType="customAction"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="customLabelActionKeyStyle" />
</case>
<!-- imeAction is either actionNone or actionUnspecified. -->
<default>
diff --git a/java/res/xml-sw600dp/rows_number_normal.xml b/java/res/xml-sw600dp/rows_number_normal.xml
index 757e77933..7a4700d5a 100644
--- a/java/res/xml-sw600dp/rows_number_normal.xml
+++ b/java/res/xml-sw600dp/rows_number_normal.xml
@@ -141,9 +141,8 @@
</Row>
<Row>
<Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="30%p"
- latin:backgroundType="functional" />
+ latin:keyStyle="tabletNumSpaceKeyStyle"
+ latin:keyWidth="30%p" />
<Key
latin:keyStyle="numStarKeyStyle"
latin:keyXPos="31%p" />
diff --git a/java/res/xml-sw600dp/rows_phone.xml b/java/res/xml-sw600dp/rows_phone.xml
index 9022bc532..612397a90 100644
--- a/java/res/xml-sw600dp/rows_phone.xml
+++ b/java/res/xml-sw600dp/rows_phone.xml
@@ -107,9 +107,8 @@
</Row>
<Row>
<Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="30%p"
- latin:backgroundType="functional" />
+ latin:keyStyle="tabletNumSpaceKeyStyle"
+ latin:keyWidth="30%p" />
<Key
latin:keyStyle="numStarKeyStyle"
latin:keyXPos="31%p" />
diff --git a/java/res/xml/key_space_symbols.xml b/java/res/xml/key_space_symbols.xml
index 0ce522889..047de9f24 100644
--- a/java/res/xml/key_space_symbols.xml
+++ b/java/res/xml/key_space_symbols.xml
@@ -22,7 +22,6 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<Key
- latin:backgroundType="normal"
latin:keyStyle="spaceKeyStyle"
latin:keyWidth="30%p" />
</merge>
diff --git a/java/res/xml/key_styles_actions.xml b/java/res/xml/key_styles_actions.xml
new file mode 100644
index 000000000..83901cad9
--- /dev/null
+++ b/java/res/xml/key_styles_actions.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- Go key -->
+ <switch>
+ <case latin:isIconDefined="go_key">
+ <key-style
+ latin:styleName="goActionKeyStyle"
+ latin:keySpec="!icon/go_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="goActionKeyStyle"
+ latin:keySpec="!text/label_go_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </default>
+ </switch>
+ <!-- Next key -->
+ <switch>
+ <case latin:isIconDefined="next_key">
+ <key-style
+ latin:styleName="nextActionKeyStyle"
+ latin:keySpec="!icon/next_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="nextActionKeyStyle"
+ latin:keySpec="!text/label_next_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </default>
+ </switch>
+ <!-- Previous key -->
+ <switch>
+ <case latin:isIconDefined="previous_key">
+ <key-style
+ latin:styleName="previousActionKeyStyle"
+ latin:keySpec="!icon/previous_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="previousActionKeyStyle"
+ latin:keySpec="!text/label_previous_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </default>
+ </switch>
+ <!-- Done key -->
+ <switch>
+ <case latin:isIconDefined="done_key">
+ <key-style
+ latin:styleName="doneActionKeyStyle"
+ latin:keySpec="!icon/done_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="doneActionKeyStyle"
+ latin:keySpec="!text/label_done_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </default>
+ </switch>
+ <!-- Send key -->
+ <switch>
+ <case latin:isIconDefined="send_key">
+ <key-style
+ latin:styleName="sendActionKeyStyle"
+ latin:keySpec="!icon/send_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="sendActionKeyStyle"
+ latin:keySpec="!text/label_send_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </default>
+ </switch>
+ <!-- Seartch key -->
+ <switch>
+ <case latin:isIconDefined="search_key">
+ <key-style
+ latin:styleName="searchActionKeyStyle"
+ latin:keySpec="!icon/search_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="searchActionKeyStyle"
+ latin:keySpec="!text/label_search_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </default>
+ </switch>
+ <switch>
+ <case latin:keyboardTheme="ICS|KLP">
+ <key-style
+ latin:styleName="customLabelActionKeyStyle"
+ latin:keySpec="dummy_label|!code/key_enter"
+ latin:keyLabelFlags="fromCustomActionLabel"
+ latin:backgroundType="action"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <!-- keyboardTheme="LXXLight|LXXDark" -->
+ <default>
+ <key-style
+ latin:styleName="customLabelActionKeyStyle"
+ latin:keySpec="dummy_label|!code/key_enter"
+ latin:keyLabelFlags="fromCustomActionLabel"
+ latin:backgroundType="functional"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index 167e6f88d..b36ddf236 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -80,17 +80,31 @@
latin:keyActionFlags="isRepeatable|noKeyPreview"
latin:backgroundType="functional" />
<!-- emojiKeyStyle must be defined before including @xml/key_syles_enter. -->
- <key-style
- latin:styleName="emojiKeyStyle"
- latin:keySpec="!icon/emoji_action_key|!code/key_emoji"
- latin:keyActionFlags="noKeyPreview"
- latin:backgroundType="action" />
+ <switch>
+ <case latin:keyboardTheme="ICS|KLP">
+ <key-style
+ latin:styleName="emojiKeyStyle"
+ latin:keySpec="!icon/emoji_action_key|!code/key_emoji"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="action" />
+ </case>
+ <!-- keyboardTheme="LXXLight|LXXDark" -->
+ <default>
+ <key-style
+ latin:styleName="emojiKeyStyle"
+ latin:keySpec="!icon/emoji_action_key|!code/key_emoji"
+ latin:keyLabelFlags="keepBackgroundAspectRatio"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="action" />
+ </default>
+ </switch>
<include
latin:keyboardLayout="@xml/key_styles_enter" />
<!-- TODO: Currently there is no way to specify icon alignment per theme. -->
<key-style
latin:styleName="spaceKeyStyle"
latin:keySpec="!icon/space_key|!code/key_space"
+ latin:backgroundType="spacebar"
latin:keyActionFlags="noKeyPreview|enableLongPress" />
<!-- U+200C: ZERO WIDTH NON-JOINER
U+200D: ZERO WIDTH JOINER -->
diff --git a/java/res/xml/key_styles_enter.xml b/java/res/xml/key_styles_enter.xml
index 55dab78c3..564f465e9 100644
--- a/java/res/xml/key_styles_enter.xml
+++ b/java/res/xml/key_styles_enter.xml
@@ -21,8 +21,8 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <!-- TODO: Stop using many conditional cases for keyspec_emoji_action_key. There are way too many to maintain. -->
<!-- Navigate more keys style -->
+ <include latin:keyboardLayout="@xml/key_styles_navigate_more_keys" />
<switch>
<!-- latin:passwordInput="true" -->
<case
@@ -32,12 +32,10 @@
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_previous" />
+ latin:parentStyle="navigatePreviousMoreKeysStyle" />
</case>
<case
latin:imeAction="actionNext"
- latin:navigatePrevious="false"
latin:passwordInput="true"
>
<key-style
@@ -50,12 +48,10 @@
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_next" />
+ latin:parentStyle="navigateNextMoreKeysStyle" />
</case>
<case
latin:imeAction="actionPrevious"
- latin:navigateNext="false"
latin:passwordInput="true"
>
<key-style
@@ -68,32 +64,25 @@
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_action_previous,!text/keyspec_action_next" />
+ latin:parentStyle="navigatePreviousNextMoreKeysStyle" />
</case>
<case
latin:navigateNext="true"
- latin:navigatePrevious="false"
latin:passwordInput="true"
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_next" />
+ latin:parentStyle="navigateNextMoreKeysStyle" />
</case>
<case
- latin:navigateNext="false"
latin:navigatePrevious="true"
latin:passwordInput="true"
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_previous" />
+ latin:parentStyle="navigatePreviousMoreKeysStyle" />
</case>
<case
- latin:navigateNext="false"
- latin:navigatePrevious="false"
latin:passwordInput="true"
>
<key-style
@@ -107,12 +96,10 @@
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_previous" />
+ latin:parentStyle="navigatePreviousMoreKeysStyle" />
</case>
<case
latin:imeAction="actionNext"
- latin:navigatePrevious="false"
latin:mode="email|url|phone|number|date|time|datetime"
>
<key-style
@@ -125,12 +112,10 @@
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_next" />
+ latin:parentStyle="navigateNextMoreKeysStyle" />
</case>
<case
latin:imeAction="actionPrevious"
- latin:navigateNext="false"
latin:mode="email|url|phone|number|date|time|datetime"
>
<key-style
@@ -143,32 +128,25 @@
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_action_previous,!text/keyspec_action_next" />
+ latin:parentStyle="navigatePreviousNextMoreKeysStyle" />
</case>
<case
latin:navigateNext="true"
- latin:navigatePrevious="false"
latin:mode="email|url|phone|number|date|time|datetime"
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_next" />
+ latin:parentStyle="navigateNextMoreKeysStyle" />
</case>
<case
- latin:navigateNext="false"
latin:navigatePrevious="true"
latin:mode="email|url|phone|number|date|time|datetime"
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_action_previous" />
+ latin:parentStyle="navigatePreviousMoreKeysStyle" />
</case>
<case
- latin:navigateNext="false"
- latin:navigatePrevious="false"
latin:mode="email|url|phone|number|date|time|datetime"
>
<key-style
@@ -181,17 +159,14 @@
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_previous" />
+ latin:parentStyle="navigateEmojiPreviousMoreKeysStyle" />
</case>
<case
latin:imeAction="actionNext"
- latin:navigatePrevious="false"
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_emoji_action_key" />
+ latin:parentStyle="navigateEmojiMoreKeysStyle" />
</case>
<case
latin:imeAction="actionPrevious"
@@ -199,17 +174,14 @@
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_next" />
+ latin:parentStyle="navigateEmojiNextMoreKeysStyle" />
</case>
<case
latin:imeAction="actionPrevious"
- latin:navigateNext="false"
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_emoji_action_key" />
+ latin:parentStyle="navigateEmojiMoreKeysStyle" />
</case>
<case
latin:navigateNext="true"
@@ -217,53 +189,51 @@
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!fixedColumnOrder!3,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_previous,!text/keyspec_action_next" />
+ latin:parentStyle="navigateEmojiPreviousNextMoreKeysStyle" />
</case>
<case
latin:navigateNext="true"
- latin:navigatePrevious="false"
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_next" />
+ latin:parentStyle="navigateEmojiNextMoreKeysStyle" />
</case>
<case
- latin:navigateNext="false"
latin:navigatePrevious="true"
>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_previous" />
+ latin:parentStyle="navigateEmojiPreviousMoreKeysStyle" />
</case>
- <case
- latin:navigateNext="false"
- latin:navigatePrevious="false"
- >
+ <default>
<key-style
latin:styleName="navigateMoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_emoji_action_key" />
+ latin:parentStyle="navigateEmojiMoreKeysStyle" />
+ </default>
+ </switch>
+ <!-- Enter key style -->
+ <switch>
+ <case latin:keyboardTheme="ICS|KLP">
+ <key-style
+ latin:styleName="defaultEnterKeyStyle"
+ latin:keySpec="!icon/enter_key|!code/key_enter"
+ latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="action"
+ latin:parentStyle="navigateMoreKeysStyle" />
</case>
+ <!-- keyboardTheme="LXXLight|LXXDark" -->
<default>
<key-style
- latin:styleName="navigateMoreKeysStyle" />
+ latin:styleName="defaultEnterKeyStyle"
+ latin:keySpec="!icon/enter_key|!code/key_enter"
+ latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor|keepBackgroundAspectRatio"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="action"
+ latin:parentStyle="navigateMoreKeysStyle" />
</default>
</switch>
- <!-- Enter key style -->
- <key-style
- latin:styleName="defaultEnterKeyStyle"
- latin:keySpec="!icon/enter_key|!code/key_enter"
- latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor"
- latin:keyActionFlags="noKeyPreview"
- latin:backgroundType="action"
- latin:parentStyle="navigateMoreKeysStyle" />
- <key-style
- latin:styleName="shiftEnterKeyStyle"
- latin:keySpec="!icon/enter_key|!code/key_shift_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
+ <include latin:keyboardLayout="@xml/key_styles_actions" />
<switch>
<!-- Shift + Enter in textMultiLine field. -->
<case
@@ -272,7 +242,8 @@
>
<key-style
latin:styleName="enterKeyStyle"
- latin:parentStyle="shiftEnterKeyStyle" />
+ latin:keySpec="!icon/enter_key|!code/key_shift_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
</case>
<!-- Smiley in textShortMessage field.
This <case> should be after Shift + Enter <case> and before any of action <case>. -->
@@ -285,127 +256,57 @@
</case>
<case
latin:imeAction="actionGo"
- latin:isIconDefined="go_key"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/go_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionGo"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_go_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionNext"
- latin:isIconDefined="next_key"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/next_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="goActionKeyStyle" />
</case>
<case
latin:imeAction="actionNext"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_next_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="nextActionKeyStyle" />
</case>
<case
latin:imeAction="actionPrevious"
- latin:isIconDefined="previous_key"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/previous_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionPrevious"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_previous_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionDone"
- latin:isIconDefined="done_key"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/done_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="previousActionKeyStyle" />
</case>
<case
latin:imeAction="actionDone"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_done_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="doneActionKeyStyle" />
</case>
<case
latin:imeAction="actionSend"
- latin:isIconDefined="send_key"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/send_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionSend"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_send_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="sendActionKeyStyle" />
</case>
<case
latin:imeAction="actionSearch"
- latin:isIconDefined="search_key"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/search_key|!code/key_enter"
- latin:backgroundType="action"
- latin:parentStyle="defaultEnterKeyStyle" />
- </case>
- <case
- latin:imeAction="actionSearch"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keySpec="!text/label_search_key|!code/key_enter"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="searchActionKeyStyle" />
</case>
<case
latin:imeAction="actionCustomLabel"
>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="dummy_label|!code/key_enter"
- latin:keyLabelFlags="fromCustomActionLabel"
- latin:backgroundType="customAction"
- latin:parentStyle="defaultEnterKeyStyle" />
+ latin:parentStyle="customLabelActionKeyStyle" />
</case>
<!-- imeAction is either actionNone or actionUnspecified. -->
<default>
<key-style
latin:styleName="enterKeyStyle"
- latin:keySpec="!icon/enter_key|!code/key_enter"
latin:parentStyle="defaultEnterKeyStyle" />
</default>
</switch>
diff --git a/java/res/xml/key_styles_navigate_more_keys.xml b/java/res/xml/key_styles_navigate_more_keys.xml
new file mode 100644
index 000000000..f97114db9
--- /dev/null
+++ b/java/res/xml/key_styles_navigate_more_keys.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case latin:keyboardTheme="ICS|KLP">
+ <key-style
+ latin:styleName="navigateNextMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!text/keyspec_action_next" />
+ <key-style
+ latin:styleName="navigatePreviousMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!text/keyspec_action_previous" />
+ <key-style
+ latin:styleName="navigatePreviousNextMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_action_previous,!text/keyspec_action_next" />
+ <key-style
+ latin:styleName="navigateEmojiMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!text/keyspec_emoji_action_key" />
+ <key-style
+ latin:styleName="navigateEmojiNextMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_next" />
+ <key-style
+ latin:styleName="navigateEmojiPreviousMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_previous" />
+ <key-style
+ latin:styleName="navigateEmojiPreviousNextMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!fixedColumnOrder!3,!needsDividers!,!text/keyspec_emoji_action_key,!text/keyspec_action_previous,!text/keyspec_action_next" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="navigateNextMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!icon/next_key|!code/key_action_next" />
+ <key-style
+ latin:styleName="navigatePreviousMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!icon/previous_key|!code/key_action_previous" />
+ <key-style
+ latin:styleName="navigatePreviousNextMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!icon/previous_key|!code/key_action_previous,!icon/next_key|!code/key_action_next" />
+ <key-style
+ latin:styleName="navigateEmojiMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!text/keyspec_emoji_action_key" />
+ <key-style
+ latin:styleName="navigateEmojiNextMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!icon/next_key|!code/key_action_next" />
+ <key-style
+ latin:styleName="navigateEmojiPreviousMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!text/keyspec_emoji_action_key,!icon/previous_key|!code/key_action_previous" />
+ <key-style
+ latin:styleName="navigateEmojiPreviousNextMoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
+ latin:moreKeys="!fixedColumnOrder!3,!needsDividers!,!text/keyspec_emoji_action_key,!icon/previous_key|!code/key_action_previous,!icon/next_key|!code/key_action_next" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/key_styles_number.xml b/java/res/xml/key_styles_number.xml
index 14b202874..97ae6c6c3 100644
--- a/java/res/xml/key_styles_number.xml
+++ b/java/res/xml/key_styles_number.xml
@@ -123,4 +123,24 @@
latin:keyLabelFlags="alignIconToBottom"
latin:keyActionFlags="enableLongPress"
latin:parentStyle="numKeyBaseStyle" />
+ <!-- TODO: Consolidate these space key styles with numSpaceKeyStyle above by introducing <case>
+ predicator that checks device form-factor. -->
+ <switch>
+ <case latin:keyboardTheme="ICS|KLP">
+ <key-style
+ latin:styleName="tabletNumSpaceKeyStyle"
+ latin:keySpec="!icon/space_key|!code/key_space"
+ latin:backgroundType="functional"
+ latin:keyActionFlags="enableLongPress"
+ latin:parentStyle="numKeyBaseStyle" />
+ </case>
+ <case latin:keyboardTheme="LXXLight|LXXDark">
+ <key-style
+ latin:styleName="tabletNumSpaceKeyStyle"
+ latin:keySpec="!icon/space_key|!code/key_space"
+ latin:backgroundType="spacebar"
+ latin:keyActionFlags="enableLongPress"
+ latin:parentStyle="numKeyBaseStyle" />
+ </case>
+ </switch>
</merge>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index ba285de09..c14cd645a 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -19,17 +19,17 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
android:key="english_ime_settings">
<PreferenceScreen
- android:fragment="com.android.inputmethod.latin.settings.InputSettingsFragment"
- android:title="@string/settings_screen_input"
- android:key="screen_input" />
+ android:fragment="com.android.inputmethod.latin.settings.PreferencesSettingsFragment"
+ android:title="@string/settings_screen_preferences"
+ android:key="screen_preferences" />
<PreferenceScreen
- android:fragment="com.android.inputmethod.latin.settings.ThemeSettingsFragment"
- android:title="@string/keyboard_theme"
- android:key="screen_theme" />
+ android:fragment="com.android.inputmethod.latin.settings.AppearanceSettingsFragment"
+ android:title="@string/settings_screen_appearance"
+ android:key="screen_appearance" />
<PreferenceScreen
android:fragment="com.android.inputmethod.latin.settings.MultiLingualSettingsFragment"
- android:title="@string/settings_screen_multi_lingual"
- android:key="screen_multi_lingual" />
+ android:title="@string/settings_screen_multilingual"
+ android:key="screen_multilingual" />
<PreferenceScreen
android:fragment="com.android.inputmethod.latin.settings.GestureSettingsFragment"
android:title="@string/settings_screen_gesture"
diff --git a/java/res/xml/prefs_screen_appearance.xml b/java/res/xml/prefs_screen_appearance.xml
new file mode 100644
index 000000000..7719c058b
--- /dev/null
+++ b/java/res/xml/prefs_screen_appearance.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="screen_appearance"
+ android:title="@string/settings_screen_appearance">
+ <PreferenceScreen
+ android:fragment="com.android.inputmethod.latin.settings.ThemeSettingsFragment"
+ android:key="screen_theme"
+ android:title="@string/settings_screen_theme" />
+ <PreferenceScreen
+ android:fragment="com.android.inputmethod.latin.settings.CustomInputStyleSettingsFragment"
+ android:key="custom_input_styles"
+ android:title="@string/custom_input_styles_title" />
+</PreferenceScreen>
diff --git a/java/res/xml/prefs_screen_debug.xml b/java/res/xml/prefs_screen_debug.xml
index 965369a90..c47740268 100644
--- a/java/res/xml/prefs_screen_debug.xml
+++ b/java/res/xml/prefs_screen_debug.xml
@@ -52,19 +52,38 @@
latin:minValue="@integer/config_min_longpress_timeout"
latin:maxValue="@integer/config_max_longpress_timeout"
latin:stepValue="@integer/config_longpress_timeout_step" />
+ <CheckBoxPreference
+ android:key="pref_has_custom_key_preview_animation_params"
+ android:title="@string/prefs_customize_key_preview_animation"
+ android:defaultValue="false"
+ android:persistent="true" />
+ <com.android.inputmethod.latin.settings.SeekBarDialogPreference
+ android:dependency="pref_has_custom_key_preview_animation_params"
+ android:key="pref_key_preview_show_up_start_x_scale"
+ android:title="@string/prefs_key_popup_show_up_start_x_scale_settings"
+ latin:maxValue="100" /> <!-- percent -->
+ <com.android.inputmethod.latin.settings.SeekBarDialogPreference
+ android:dependency="pref_has_custom_key_preview_animation_params"
+ android:key="pref_key_preview_show_up_start_y_scale"
+ android:title="@string/prefs_key_popup_show_up_start_y_scale_settings"
+ latin:maxValue="100" /> <!-- percent -->
<com.android.inputmethod.latin.settings.SeekBarDialogPreference
- android:key="pref_key_preview_show_up_start_scale"
- android:title="@string/prefs_key_popup_show_up_start_scale_settings"
+ android:dependency="pref_has_custom_key_preview_animation_params"
+ android:key="pref_key_preview_dismiss_end_x_scale"
+ android:title="@string/prefs_key_popup_dismiss_end_x_scale_settings"
latin:maxValue="100" /> <!-- percent -->
<com.android.inputmethod.latin.settings.SeekBarDialogPreference
- android:key="pref_key_preview_dismiss_end_scale"
- android:title="@string/prefs_key_popup_dismiss_end_scale_settings"
+ android:dependency="pref_has_custom_key_preview_animation_params"
+ android:key="pref_key_preview_dismiss_end_y_scale"
+ android:title="@string/prefs_key_popup_dismiss_end_y_scale_settings"
latin:maxValue="100" /> <!-- percent -->
<com.android.inputmethod.latin.settings.SeekBarDialogPreference
+ android:dependency="pref_has_custom_key_preview_animation_params"
android:key="pref_key_preview_show_up_duration"
android:title="@string/prefs_key_popup_show_up_duration_settings"
latin:maxValue="100" /> <!-- milliseconds -->
<com.android.inputmethod.latin.settings.SeekBarDialogPreference
+ android:dependency="pref_has_custom_key_preview_animation_params"
android:key="pref_key_preview_dismiss_duration"
android:title="@string/prefs_key_popup_dismiss_duration_settings"
latin:maxValue="100" /> <!-- milliseconds -->
diff --git a/java/res/xml/prefs_screen_multi_lingual.xml b/java/res/xml/prefs_screen_multilingual.xml
index 937d439d6..07a4b701c 100644
--- a/java/res/xml/prefs_screen_multi_lingual.xml
+++ b/java/res/xml/prefs_screen_multilingual.xml
@@ -16,8 +16,8 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/settings_screen_multi_lingual"
- android:key="screen_multi_lingual">
+ android:title="@string/settings_screen_multilingual"
+ android:key="screen_multilingual">
<CheckBoxPreference
android:key="pref_show_language_switch_key"
android:title="@string/show_language_switch_key"
@@ -31,8 +31,4 @@
android:summary="@string/include_other_imes_in_language_switch_list_summary"
android:defaultValue="false"
android:persistent="true" />
- <PreferenceScreen
- android:fragment="com.android.inputmethod.latin.settings.CustomInputStyleSettingsFragment"
- android:key="custom_input_styles"
- android:title="@string/custom_input_styles_title" />
</PreferenceScreen>
diff --git a/java/res/xml/prefs_screen_input.xml b/java/res/xml/prefs_screen_preferences.xml
index 7704e3f80..101edc855 100644
--- a/java/res/xml/prefs_screen_input.xml
+++ b/java/res/xml/prefs_screen_preferences.xml
@@ -17,7 +17,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:title="@string/settings_screen_input">
+ android:title="@string/settings_screen_preferences">
<CheckBoxPreference
android:key="auto_cap"
android:title="@string/auto_cap"
diff --git a/java/res/xml/prefs_screen_theme.xml b/java/res/xml/prefs_screen_theme.xml
index b49f0bea6..677a6ea3b 100644
--- a/java/res/xml/prefs_screen_theme.xml
+++ b/java/res/xml/prefs_screen_theme.xml
@@ -17,7 +17,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:title="@string/keyboard_theme"
+ android:title="@string/settings_screen_theme"
android:key="screen_theme">
<!-- Keyboard theme list will be populated programmatically here. -->
</PreferenceScreen>
diff --git a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
index 24eaec85c..5af31795c 100644
--- a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
+++ b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
@@ -23,39 +23,28 @@ import com.android.inputmethod.annotations.UsedForTesting;
@UsedForTesting
public final class CursorAnchorInfoCompatWrapper {
- public static final int CHARACTER_RECT_TYPE_MASK = 0x0f;
/**
- * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the editor did not specify any type of this
- * character. Editor authors should not use this flag.
+ * The insertion marker or character bounds have at least one visible region.
*/
- public static final int CHARACTER_RECT_TYPE_UNSPECIFIED = 0;
+ public static final int FLAG_HAS_VISIBLE_REGION = 0x01;
/**
- * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the character is entirely visible.
+ * The insertion marker or character bounds have at least one invisible (clipped) region.
*/
- public static final int CHARACTER_RECT_TYPE_FULLY_VISIBLE = 1;
+ public static final int FLAG_HAS_INVISIBLE_REGION = 0x02;
/**
- * Type for {@link #CHARACTER_RECT_TYPE_MASK}: some area of the character is invisible.
+ * The insertion marker or character bounds is placed at right-to-left (RTL) character.
*/
- public static final int CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE = 2;
-
- /**
- * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the character is entirely invisible.
- */
- public static final int CHARACTER_RECT_TYPE_INVISIBLE = 3;
-
- /**
- * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the editor gave up to calculate the rectangle
- * for this character. Input method authors should ignore the returned rectangle.
- */
- public static final int CHARACTER_RECT_TYPE_NOT_FEASIBLE = 4;
+ public static final int FLAG_IS_RTL = 0x04;
// Note that CursorAnchorInfo has been introduced in API level XX (Build.VERSION_CODE.LXX).
private static final CompatUtils.ClassWrapper sCursorAnchorInfoClass;
- private static final CompatUtils.ToObjectMethodWrapper<RectF> sGetCharacterRectMethod;
- private static final CompatUtils.ToIntMethodWrapper sGetCharacterRectFlagsMethod;
+ private static final CompatUtils.ToIntMethodWrapper sGetSelectionStartMethod;
+ private static final CompatUtils.ToIntMethodWrapper sGetSelectionEndMethod;
+ private static final CompatUtils.ToObjectMethodWrapper<RectF> sGetCharacterBoundsMethod;
+ private static final CompatUtils.ToIntMethodWrapper sGetCharacterBoundsFlagsMethod;
private static final CompatUtils.ToObjectMethodWrapper<CharSequence> sGetComposingTextMethod;
private static final CompatUtils.ToIntMethodWrapper sGetComposingTextStartMethod;
private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerBaselineMethod;
@@ -63,20 +52,24 @@ public final class CursorAnchorInfoCompatWrapper {
private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerHorizontalMethod;
private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerTopMethod;
private static final CompatUtils.ToObjectMethodWrapper<Matrix> sGetMatrixMethod;
- private static final CompatUtils.ToBooleanMethodWrapper sIsInsertionMarkerClippedMethod;
+ private static final CompatUtils.ToIntMethodWrapper sGetInsertionMarkerFlagsMethod;
- private static int COMPOSING_TEXT_START_DEFAULT = -1;
+ private static int INVALID_TEXT_INDEX = -1;
static {
sCursorAnchorInfoClass = CompatUtils.getClassWrapper(
"android.view.inputmethod.CursorAnchorInfo");
- sGetCharacterRectMethod = sCursorAnchorInfoClass.getMethod(
- "getCharacterRect", (RectF)null, int.class);
- sGetCharacterRectFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getCharacterRectFlags", CHARACTER_RECT_TYPE_UNSPECIFIED, int.class);
+ sGetSelectionStartMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
+ "getSelectionStart", INVALID_TEXT_INDEX);
+ sGetSelectionEndMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
+ "getSelectionEnd", INVALID_TEXT_INDEX);
+ sGetCharacterBoundsMethod = sCursorAnchorInfoClass.getMethod(
+ "getCharacterBounds", (RectF)null, int.class);
+ sGetCharacterBoundsFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
+ "getCharacterBoundsFlags", 0, int.class);
sGetComposingTextMethod = sCursorAnchorInfoClass.getMethod(
"getComposingText", (CharSequence)null);
sGetComposingTextStartMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getComposingTextStart", COMPOSING_TEXT_START_DEFAULT);
+ "getComposingTextStart", INVALID_TEXT_INDEX);
sGetInsertionMarkerBaselineMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
"getInsertionMarkerBaseline", 0.0f);
sGetInsertionMarkerBottomMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
@@ -86,13 +79,13 @@ public final class CursorAnchorInfoCompatWrapper {
sGetInsertionMarkerTopMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
"getInsertionMarkerTop", 0.0f);
sGetMatrixMethod = sCursorAnchorInfoClass.getMethod("getMatrix", (Matrix)null);
- sIsInsertionMarkerClippedMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "isInsertionMarkerClipped", false);
+ sGetInsertionMarkerFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
+ "getInsertionMarkerFlags", 0);
}
@UsedForTesting
- public static boolean isAvailable() {
- return sCursorAnchorInfoClass.exists();
+ public boolean isAvailable() {
+ return sCursorAnchorInfoClass.exists() && mInstance != null;
}
private Object mInstance;
@@ -103,7 +96,7 @@ public final class CursorAnchorInfoCompatWrapper {
@UsedForTesting
public static CursorAnchorInfoCompatWrapper fromObject(final Object instance) {
- if (!isAvailable()) {
+ if (!sCursorAnchorInfoClass.exists()) {
return new CursorAnchorInfoCompatWrapper(null);
}
return new CursorAnchorInfoCompatWrapper(instance);
@@ -118,6 +111,14 @@ public final class CursorAnchorInfoCompatWrapper {
return FakeHolder.sInstance;
}
+ public int getSelectionStart() {
+ return sGetSelectionStartMethod.invoke(mInstance);
+ }
+
+ public int getSelectionEnd() {
+ return sGetSelectionEndMethod.invoke(mInstance);
+ }
+
public CharSequence getComposingText() {
return sGetComposingTextMethod.invoke(mInstance);
}
@@ -130,12 +131,12 @@ public final class CursorAnchorInfoCompatWrapper {
return sGetMatrixMethod.invoke(mInstance);
}
- public RectF getCharacterRect(final int index) {
- return sGetCharacterRectMethod.invoke(mInstance, index);
+ public RectF getCharacterBounds(final int index) {
+ return sGetCharacterBoundsMethod.invoke(mInstance, index);
}
- public int getCharacterRectFlags(final int index) {
- return sGetCharacterRectFlagsMethod.invoke(mInstance, index);
+ public int getCharacterBoundsFlags(final int index) {
+ return sGetCharacterBoundsFlagsMethod.invoke(mInstance, index);
}
public float getInsertionMarkerBaseline() {
@@ -154,7 +155,7 @@ public final class CursorAnchorInfoCompatWrapper {
return sGetInsertionMarkerTopMethod.invoke(mInstance);
}
- public boolean isInsertionMarkerClipped() {
- return sIsInsertionMarkerClippedMethod.invoke(mInstance);
+ public int getInsertionMarkerFlags() {
+ return sGetInsertionMarkerFlagsMethod.invoke(mInstance);
}
}
diff --git a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
index 862ec8a58..a5c71b22f 100644
--- a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
@@ -21,30 +21,29 @@ import android.view.inputmethod.InputMethodManager;
public final class InputConnectionCompatUtils {
private static final CompatUtils.ClassWrapper sInputConnectionType;
- private static final CompatUtils.ToBooleanMethodWrapper sRequestUpdateCursorAnchorInfoMethod;
+ private static final CompatUtils.ToBooleanMethodWrapper sRequestCursorUpdatesMethod;
static {
sInputConnectionType = new CompatUtils.ClassWrapper(InputConnection.class);
- sRequestUpdateCursorAnchorInfoMethod = sInputConnectionType.getPrimitiveMethod(
- "requestUpdateCursorAnchorInfo", false, int.class);
+ sRequestCursorUpdatesMethod = sInputConnectionType.getPrimitiveMethod(
+ "requestCursorUpdates", false, int.class);
}
- public static boolean isRequestUpdateCursorAnchorInfoAvailable() {
- return sRequestUpdateCursorAnchorInfoMethod != null;
+ public static boolean isRequestCursorUpdatesAvailable() {
+ return sRequestCursorUpdatesMethod != null;
}
/**
- * Local copies of some constants in CursorAnchorInfoRequest until the SDK becomes publicly
- * available.
+ * Local copies of some constants in InputConnection until the SDK becomes publicly available.
*/
- private static int REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE = 1 << 0;
- private static int REQUEST_UPDATE_CURSOR_UPDATE_MONITOR = 1 << 1;
+ private static int CURSOR_UPDATE_IMMEDIATE = 1 << 0;
+ private static int CURSOR_UPDATE_MONITOR = 1 << 1;
- private static boolean requestUpdateCursorAnchorInfoImpl(final InputConnection inputConnection,
+ private static boolean requestCursorUpdatesImpl(final InputConnection inputConnection,
final int cursorUpdateMode) {
- if (!isRequestUpdateCursorAnchorInfoAvailable()) {
+ if (!isRequestCursorUpdatesAvailable()) {
return false;
}
- return sRequestUpdateCursorAnchorInfoMethod.invoke(inputConnection, cursorUpdateMode);
+ return sRequestCursorUpdatesMethod.invoke(inputConnection, cursorUpdateMode);
}
/**
@@ -56,11 +55,10 @@ public final class InputConnectionCompatUtils {
* as soon as possible to notify the current cursor/anchor position to the input method.
* @return {@code false} if the request is not handled. Otherwise returns {@code true}.
*/
- public static boolean requestUpdateCursorAnchorInfo(final InputConnection inputConnection,
+ public static boolean requestCursorUpdates(final InputConnection inputConnection,
final boolean enableMonitor, final boolean requestImmediateCallback) {
- final int cursorUpdateMode = (enableMonitor ? REQUEST_UPDATE_CURSOR_UPDATE_MONITOR : 0)
- | (requestImmediateCallback ? REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE : 0);
- return requestUpdateCursorAnchorInfoImpl(inputConnection, cursorUpdateMode);
+ final int cursorUpdateMode = (enableMonitor ? CURSOR_UPDATE_MONITOR : 0)
+ | (requestImmediateCallback ? CURSOR_UPDATE_IMMEDIATE : 0);
+ return requestCursorUpdatesImpl(inputConnection, cursorUpdateMode);
}
-
}
diff --git a/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java b/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java
new file mode 100644
index 000000000..eb180071e
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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.app.Notification;
+import android.os.Build;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+public class NotificationCompatUtils {
+ // Note that TextInfo.getCharSequence() is supposed to be available in API level 21 and later.
+ private static final Method METHOD_setColor =
+ CompatUtils.getMethod(Notification.Builder.class, "setColor", int.class);
+ private static final Method METHOD_setVisibility =
+ CompatUtils.getMethod(Notification.Builder.class, "setVisibility", int.class);
+ private static final Method METHOD_setCategory =
+ CompatUtils.getMethod(Notification.Builder.class, "setCategory", String.class);
+ private static final Method METHOD_setPriority =
+ CompatUtils.getMethod(Notification.Builder.class, "setPriority", int.class);
+ private static final Method METHOD_build =
+ CompatUtils.getMethod(Notification.Builder.class, "build");
+ private static final Field FIELD_VISIBILITY_SECRET =
+ CompatUtils.getField(Notification.class, "VISIBILITY_SECRET");
+ private static final int VISIBILITY_SECRET = null == FIELD_VISIBILITY_SECRET ? 0
+ : (Integer) CompatUtils.getFieldValue(null /* receiver */, null /* defaultValue */,
+ FIELD_VISIBILITY_SECRET);
+ private static final Field FIELD_CATEGORY_RECOMMENDATION =
+ CompatUtils.getField(Notification.class, "CATEGORY_RECOMMENDATION");
+ private static final String CATEGORY_RECOMMENDATION = null == FIELD_CATEGORY_RECOMMENDATION ? ""
+ : (String) CompatUtils.getFieldValue(null /* receiver */, null /* defaultValue */,
+ FIELD_CATEGORY_RECOMMENDATION);
+ private static final Field FIELD_PRIORITY_LOW =
+ CompatUtils.getField(Notification.class, "PRIORITY_LOW");
+ private static final int PRIORITY_LOW = null == FIELD_PRIORITY_LOW ? 0
+ : (Integer) CompatUtils.getFieldValue(null /* receiver */, null /* defaultValue */,
+ FIELD_PRIORITY_LOW);
+
+ private NotificationCompatUtils() {
+ // This class is non-instantiable.
+ }
+
+ // Sets the accent color
+ public static void setColor(final Notification.Builder builder, final int color) {
+ CompatUtils.invoke(builder, null, METHOD_setColor, color);
+ }
+
+ public static void setVisibilityToSecret(final Notification.Builder builder) {
+ CompatUtils.invoke(builder, null, METHOD_setVisibility, VISIBILITY_SECRET);
+ }
+
+ public static void setCategoryToRecommendation(final Notification.Builder builder) {
+ CompatUtils.invoke(builder, null, METHOD_setCategory, CATEGORY_RECOMMENDATION);
+ }
+
+ public static void setPriorityToLow(final Notification.Builder builder) {
+ CompatUtils.invoke(builder, null, METHOD_setPriority, PRIORITY_LOW);
+ }
+
+ public static Notification build(final Notification.Builder builder) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ // #build was added in API level 16, JELLY_BEAN
+ return (Notification) CompatUtils.invoke(builder, null, METHOD_build);
+ } else {
+ // #getNotification was deprecated in API level 16, JELLY_BEAN
+ return builder.getNotification();
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
index afbe8c890..0f00be133 100644
--- a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
@@ -34,6 +34,9 @@ public final class ViewCompatUtils {
// Note that View.setElevation(float) has been introduced in API level 21.
private static final Method METHOD_setElevation = CompatUtils.getMethod(
View.class, "setElevation", float.class);
+ // Note that View.setTextAlignment(int) has been introduced in API level 17.
+ private static final Method METHOD_setTextAlignment = CompatUtils.getMethod(
+ View.class, "setTextAlignment", int.class);
private ViewCompatUtils() {
// This utility class is not publicly instantiable.
@@ -56,9 +59,19 @@ public final class ViewCompatUtils {
}
public static void setElevation(final View view, final float elevation) {
- if (METHOD_setElevation == null) {
- return;
- }
CompatUtils.invoke(view, null, METHOD_setElevation, elevation);
}
+
+ // These TEXT_ALIGNMENT_* constants have been introduced in API 17.
+ public static final int TEXT_ALIGNMENT_INHERIT = 0;
+ public static final int TEXT_ALIGNMENT_GRAVITY = 1;
+ public static final int TEXT_ALIGNMENT_TEXT_START = 2;
+ public static final int TEXT_ALIGNMENT_TEXT_END = 3;
+ public static final int TEXT_ALIGNMENT_CENTER = 4;
+ public static final int TEXT_ALIGNMENT_VIEW_START = 5;
+ public static final int TEXT_ALIGNMENT_VIEW_END = 6;
+
+ public static void setTextAlignment(final View view, final int textAlignment) {
+ CompatUtils.invoke(view, null, METHOD_setTextAlignment, textAlignment);
+ }
}
diff --git a/java/src/com/android/inputmethod/dictionarypack/DownloadManagerWrapper.java b/java/src/com/android/inputmethod/dictionarypack/DownloadManagerWrapper.java
index 75cc7d4cb..3dbbc9b9b 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DownloadManagerWrapper.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DownloadManagerWrapper.java
@@ -54,15 +54,13 @@ public class DownloadManagerWrapper {
if (null != mDownloadManager) {
mDownloadManager.remove(ids);
}
+ } catch (IllegalArgumentException e) {
+ // This is expected to happen on boot when the device is encrypted.
} catch (SQLiteException e) {
// We couldn't remove the file from DownloadManager. Apparently, the database can't
// be opened. It may be a problem with file system corruption. In any case, there is
// not much we can do apart from avoiding crashing.
Log.e(TAG, "Can't remove files with ID " + ids + " from download manager", e);
- } catch (IllegalArgumentException e) {
- // Not sure how this can happen, but it could be another case where the provider
- // is disabled. Or it could be a bug in older versions of the framework.
- Log.e(TAG, "Can't find the content URL for DownloadManager?", e);
}
}
@@ -71,10 +69,10 @@ public class DownloadManagerWrapper {
if (null != mDownloadManager) {
return mDownloadManager.openDownloadedFile(fileId);
}
+ } catch (IllegalArgumentException e) {
+ // This is expected to happen on boot when the device is encrypted.
} catch (SQLiteException e) {
Log.e(TAG, "Can't open downloaded file with ID " + fileId, e);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Can't find the content URL for DownloadManager?", e);
}
// We come here if mDownloadManager is null or if an exception was thrown.
throw new FileNotFoundException();
@@ -85,10 +83,10 @@ public class DownloadManagerWrapper {
if (null != mDownloadManager) {
return mDownloadManager.query(query);
}
+ } catch (IllegalArgumentException e) {
+ // This is expected to happen on boot when the device is encrypted.
} catch (SQLiteException e) {
Log.e(TAG, "Can't query the download manager", e);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Can't find the content URL for DownloadManager?", e);
}
// We come here if mDownloadManager is null or if an exception was thrown.
return null;
@@ -99,10 +97,10 @@ public class DownloadManagerWrapper {
if (null != mDownloadManager) {
return mDownloadManager.enqueue(request);
}
+ } catch (IllegalArgumentException e) {
+ // This is expected to happen on boot when the device is encrypted.
} catch (SQLiteException e) {
Log.e(TAG, "Can't enqueue a request with the download manager", e);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Can't find the content URL for DownloadManager?", e);
}
return 0;
}
diff --git a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
index 95a094232..6fbca44c5 100644
--- a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
+++ b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
@@ -31,12 +31,14 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.ConnectivityManager;
import android.net.Uri;
+import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.text.TextUtils;
import android.util.Log;
import com.android.inputmethod.compat.ConnectivityManagerCompatUtils;
import com.android.inputmethod.compat.DownloadManagerCompatUtils;
+import com.android.inputmethod.compat.NotificationCompatUtils;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.ApplicationUtils;
import com.android.inputmethod.latin.utils.DebugLogUtils;
@@ -858,7 +860,7 @@ public final class UpdateHandler {
final String language = (null == locale ? "" : locale.getDisplayLanguage());
final String titleFormat = context.getString(R.string.dict_available_notification_title);
final String notificationTitle = String.format(titleFormat, language);
- final Notification notification = new Notification.Builder(context)
+ final Notification.Builder builder = new Notification.Builder(context)
.setAutoCancel(true)
.setContentIntent(notificationIntent)
.setContentTitle(notificationTitle)
@@ -866,8 +868,13 @@ public final class UpdateHandler {
.setTicker(notificationTitle)
.setOngoing(false)
.setOnlyAlertOnce(true)
- .setSmallIcon(R.drawable.ic_notify_dictionary)
- .getNotification();
+ .setSmallIcon(R.drawable.ic_notify_dictionary);
+ NotificationCompatUtils.setColor(builder,
+ context.getResources().getColor(R.color.notification_accent_color));
+ NotificationCompatUtils.setPriorityToLow(builder);
+ NotificationCompatUtils.setVisibilityToSecret(builder);
+ NotificationCompatUtils.setCategoryToRecommendation(builder);
+ final Notification notification = NotificationCompatUtils.build(builder);
notificationManager.notify(DICT_AVAILABLE_NOTIFICATION_ID, notification);
}
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index f00889ed7..81ea90a4d 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -87,6 +87,7 @@ public class Key implements Comparable<Key> {
private static final int LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED = 0x20000;
private static final int LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL = 0x40000;
private static final int LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR = 0x80000;
+ private static final int LABEL_FLAGS_KEEP_BACKGROUND_ASPECT_RATIO = 0x100000;
private static final int LABEL_FLAGS_DISABLE_HINT_LABEL = 0x40000000;
private static final int LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS = 0x80000000;
@@ -108,11 +109,23 @@ public class Key implements Comparable<Key> {
private final MoreKeySpec[] mMoreKeys;
/** More keys column number and flags */
private final int mMoreKeysColumnAndFlags;
- private static final int MORE_KEYS_COLUMN_MASK = 0x000000ff;
- private static final int MORE_KEYS_FLAGS_FIXED_COLUMN_ORDER = 0x80000000;
+ private static final int MORE_KEYS_COLUMN_NUMBER_MASK = 0x000000ff;
+ // If this flag is specified, more keys keyboard should have the specified number of columns.
+ // Otherwise more keys keyboard should have less than or equal to the specified maximum number
+ // of columns.
+ private static final int MORE_KEYS_FLAGS_FIXED_COLUMN = 0x00000100;
+ // If this flag is specified, the order of more keys is determined by the order in the more
+ // keys' specification. Otherwise the order of more keys is automatically determined.
+ private static final int MORE_KEYS_FLAGS_FIXED_ORDER = 0x00000200;
+ private static final int MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER = 0;
+ private static final int MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER =
+ MORE_KEYS_FLAGS_FIXED_COLUMN;
+ private static final int MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER =
+ (MORE_KEYS_FLAGS_FIXED_COLUMN | MORE_KEYS_FLAGS_FIXED_ORDER);
private static final int MORE_KEYS_FLAGS_HAS_LABELS = 0x40000000;
private static final int MORE_KEYS_FLAGS_NEEDS_DIVIDERS = 0x20000000;
private static final int MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY = 0x10000000;
+ // TODO: Rename these specifiers to !autoOrder! and !fixedOrder! respectively.
private static final String MORE_KEYS_AUTO_COLUMN_ORDER = "!autoColumnOrder!";
private static final String MORE_KEYS_FIXED_COLUMN_ORDER = "!fixedColumnOrder!";
private static final String MORE_KEYS_HAS_LABELS = "!hasLabels!";
@@ -127,7 +140,7 @@ public class Key implements Comparable<Key> {
public static final int BACKGROUND_TYPE_STICKY_OFF = 3;
public static final int BACKGROUND_TYPE_STICKY_ON = 4;
public static final int BACKGROUND_TYPE_ACTION = 5;
- public static final int BACKGROUND_TYPE_CUSTOM_ACTION = 6;
+ public static final int BACKGROUND_TYPE_SPACEBAR = 6;
private final int mActionFlags;
private static final int ACTION_FLAGS_IS_REPEATABLE = 0x01;
@@ -255,25 +268,31 @@ public class Key implements Comparable<Key> {
int actionFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
- int moreKeysColumn = style.getInt(keyAttr,
- R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMoreKeysKeyboardColumn);
+ // Get maximum column order number and set a relevant mode value.
+ int moreKeysColumnAndFlags = MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER
+ | style.getInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn,
+ params.mMaxMoreKeysKeyboardColumn);
int value;
if ((value = MoreKeySpec.getIntValue(moreKeys, MORE_KEYS_AUTO_COLUMN_ORDER, -1)) > 0) {
- moreKeysColumn = value & MORE_KEYS_COLUMN_MASK;
+ // Override with fixed column order number and set a relevant mode value.
+ moreKeysColumnAndFlags = MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER
+ | (value & MORE_KEYS_COLUMN_NUMBER_MASK);
}
if ((value = MoreKeySpec.getIntValue(moreKeys, MORE_KEYS_FIXED_COLUMN_ORDER, -1)) > 0) {
- moreKeysColumn = MORE_KEYS_FLAGS_FIXED_COLUMN_ORDER | (value & MORE_KEYS_COLUMN_MASK);
+ // Override with fixed column order number and set a relevant mode value.
+ moreKeysColumnAndFlags = MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER
+ | (value & MORE_KEYS_COLUMN_NUMBER_MASK);
}
if (MoreKeySpec.getBooleanValue(moreKeys, MORE_KEYS_HAS_LABELS)) {
- moreKeysColumn |= MORE_KEYS_FLAGS_HAS_LABELS;
+ moreKeysColumnAndFlags |= MORE_KEYS_FLAGS_HAS_LABELS;
}
if (MoreKeySpec.getBooleanValue(moreKeys, MORE_KEYS_NEEDS_DIVIDERS)) {
- moreKeysColumn |= MORE_KEYS_FLAGS_NEEDS_DIVIDERS;
+ moreKeysColumnAndFlags |= MORE_KEYS_FLAGS_NEEDS_DIVIDERS;
}
if (MoreKeySpec.getBooleanValue(moreKeys, MORE_KEYS_NO_PANEL_AUTO_MORE_KEY)) {
- moreKeysColumn |= MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY;
+ moreKeysColumnAndFlags |= MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY;
}
- mMoreKeysColumnAndFlags = moreKeysColumn;
+ mMoreKeysColumnAndFlags = moreKeysColumnAndFlags;
final String[] additionalMoreKeys;
if ((mLabelFlags & LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS) != 0) {
@@ -488,7 +507,7 @@ public class Key implements Comparable<Key> {
case BACKGROUND_TYPE_STICKY_OFF: return "stickyOff";
case BACKGROUND_TYPE_STICKY_ON: return "stickyOn";
case BACKGROUND_TYPE_ACTION: return "action";
- case BACKGROUND_TYPE_CUSTOM_ACTION: return "customAction";
+ case BACKGROUND_TYPE_SPACEBAR: return "spacebar";
default: return null;
}
}
@@ -529,6 +548,10 @@ public class Key implements Comparable<Key> {
return this instanceof Spacer;
}
+ public final boolean isActionKey() {
+ return mBackgroundType == BACKGROUND_TYPE_ACTION;
+ }
+
public final boolean isShift() {
return mCode == CODE_SHIFT;
}
@@ -675,17 +698,29 @@ public class Key implements Comparable<Key> {
return (mLabelFlags & LABEL_FLAGS_AUTO_SCALE) == LABEL_FLAGS_AUTO_SCALE;
}
+ public final boolean needsToKeepBackgroundAspectRatio(final int defaultFlags) {
+ return ((mLabelFlags | defaultFlags) & LABEL_FLAGS_KEEP_BACKGROUND_ASPECT_RATIO) != 0;
+ }
+
+ public final boolean hasCustomActionLabel() {
+ return (mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0;
+ }
+
private final boolean isShiftedLetterActivated() {
return (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) != 0
&& !TextUtils.isEmpty(mHintLabel);
}
- public final int getMoreKeysColumn() {
- return mMoreKeysColumnAndFlags & MORE_KEYS_COLUMN_MASK;
+ public final int getMoreKeysColumnNumber() {
+ return mMoreKeysColumnAndFlags & MORE_KEYS_COLUMN_NUMBER_MASK;
+ }
+
+ public final boolean isMoreKeysFixedColumn() {
+ return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_FIXED_COLUMN) != 0;
}
- public final boolean isFixedColumnOrderMoreKeys() {
- return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_FIXED_COLUMN_ORDER) != 0;
+ public final boolean isMoreKeysFixedOrder() {
+ return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_FIXED_ORDER) != 0;
}
public final boolean hasLabelsInMoreKeys() {
@@ -851,8 +886,8 @@ public class Key implements Comparable<Key> {
new KeyBackgroundState(android.R.attr.state_checkable, android.R.attr.state_checked),
// 5: BACKGROUND_TYPE_ACTION
new KeyBackgroundState(android.R.attr.state_active),
- // 6: BACKGROUND_TYPE_CUSTOM_ACTION
- new KeyBackgroundState(android.R.attr.state_active, android.R.attr.state_checked)
+ // 6: BACKGROUND_TYPE_SPACEBAR
+ new KeyBackgroundState(),
};
}
@@ -866,7 +901,7 @@ public class Key implements Comparable<Key> {
final Drawable background;
if (mBackgroundType == BACKGROUND_TYPE_FUNCTIONAL) {
background = functionalKeyBackground;
- } else if (getCode() == Constants.CODE_SPACE) {
+ } else if (mBackgroundType == BACKGROUND_TYPE_SPACEBAR) {
background = spacebarBackground;
} else {
background = keyBackground;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index d6d0b2120..feb79efe9 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -119,7 +119,15 @@ public final class KeyboardLayoutSet {
new SparseArray<>();
}
- public static void clearKeyboardCache() {
+ public static void onSystemLocaleChanged() {
+ clearKeyboardCache();
+ }
+
+ public static void onKeyboardThemeChanged() {
+ clearKeyboardCache();
+ }
+
+ private static void clearKeyboardCache() {
sKeyboardCache.clear();
sKeysCache.clear();
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 77cdf49fb..60665f8de 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -18,7 +18,6 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
import android.content.SharedPreferences;
-import android.content.res.Configuration;
import android.content.res.Resources;
import android.preference.PreferenceManager;
import android.util.Log;
@@ -38,6 +37,7 @@ import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodManager;
import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.WordComposer;
+import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.utils.ResourceUtils;
import com.android.inputmethod.latin.utils.ScriptUtils;
@@ -60,7 +60,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
private KeyboardLayoutSet mKeyboardLayoutSet;
// TODO: The following {@link KeyboardTextsSet} should be in {@link KeyboardLayoutSet}.
private final KeyboardTextsSet mKeyboardTextsSet = new KeyboardTextsSet();
- private SettingsValues mCurrentSettingsValues;
private KeyboardTheme mKeyboardTheme;
private Context mThemeContext;
@@ -102,7 +101,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
if (mThemeContext == null || !keyboardTheme.equals(mKeyboardTheme)) {
mKeyboardTheme = keyboardTheme;
mThemeContext = new ContextThemeWrapper(context, keyboardTheme.mStyleId);
- KeyboardLayoutSet.clearKeyboardCache();
+ KeyboardLayoutSet.onKeyboardThemeChanged();
return true;
}
return false;
@@ -120,7 +119,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
builder.setVoiceInputKeyEnabled(settingsValues.mShowsVoiceInputKey);
builder.setLanguageSwitchKeyEnabled(mLatinIME.shouldShowLanguageSwitchKey());
mKeyboardLayoutSet = builder.build();
- mCurrentSettingsValues = settingsValues;
try {
mState.onLoadKeyboard(currentAutoCapsState, currentRecapitalizeState);
mKeyboardTextsSet.setLocale(mSubtypeSwitcher.getCurrentSubtypeLocale(), mThemeContext);
@@ -144,19 +142,24 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
private void setKeyboard(final Keyboard keyboard) {
// Make {@link MainKeyboardView} visible and hide {@link EmojiPalettesView}.
- setMainKeyboardFrame();
+ final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent();
+ setMainKeyboardFrame(currentSettingsValues);
+ // TODO: pass this object to setKeyboard instead of getting the current values.
final MainKeyboardView keyboardView = mKeyboardView;
final Keyboard oldKeyboard = keyboardView.getKeyboard();
keyboardView.setKeyboard(keyboard);
mCurrentInputView.setKeyboardTopPadding(keyboard.mTopPadding);
keyboardView.setKeyPreviewPopupEnabled(
- mCurrentSettingsValues.mKeyPreviewPopupOn,
- mCurrentSettingsValues.mKeyPreviewPopupDismissDelay);
+ currentSettingsValues.mKeyPreviewPopupOn,
+ currentSettingsValues.mKeyPreviewPopupDismissDelay);
keyboardView.setKeyPreviewAnimationParams(
- mCurrentSettingsValues.mKeyPreviewShowUpStartScale,
- mCurrentSettingsValues.mKeyPreviewShowUpDuration,
- mCurrentSettingsValues.mKeyPreviewDismissEndScale,
- mCurrentSettingsValues.mKeyPreviewDismissDuration);
+ currentSettingsValues.mHasCustomKeyPreviewAnimationParams,
+ currentSettingsValues.mKeyPreviewShowUpStartXScale,
+ currentSettingsValues.mKeyPreviewShowUpStartYScale,
+ currentSettingsValues.mKeyPreviewShowUpDuration,
+ currentSettingsValues.mKeyPreviewDismissEndXScale,
+ currentSettingsValues.mKeyPreviewDismissEndYScale,
+ currentSettingsValues.mKeyPreviewDismissDuration);
keyboardView.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady());
final boolean subtypeChanged = (oldKeyboard == null)
|| !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
@@ -233,22 +236,13 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS));
}
- private void setMainKeyboardFrame() {
- mMainKeyboardFrame.setVisibility(hasHardwareKeyboard() ? View.GONE : View.VISIBLE);
+ private void setMainKeyboardFrame(final SettingsValues settingsValues) {
+ mMainKeyboardFrame.setVisibility(
+ settingsValues.mHasHardwareKeyboard ? View.GONE : View.VISIBLE);
mEmojiPalettesView.setVisibility(View.GONE);
mEmojiPalettesView.stopEmojiPalettes();
}
- // TODO: Move this boolean to a member of {@link SettingsValues} and reset it
- // at {@link LatinIME#onConfigurationChanged(Configuration)}.
- public boolean hasHardwareKeyboard() {
- // Copied from {@link InputMethodServce#onEvaluateInputViewShown()}.
- final Configuration config = mLatinIME.getResources().getConfiguration();
- final boolean noHardwareKeyboard = config.keyboard == Configuration.KEYBOARD_NOKEYS
- || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES;
- return !noHardwareKeyboard;
- }
-
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void setEmojiKeyboard() {
@@ -261,13 +255,12 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
}
public void onToggleEmojiKeyboard() {
- if (mKeyboardLayoutSet == null) {
- return;
- }
- if (isShowingEmojiPalettes()) {
- setAlphabetKeyboard();
- } else {
+ if (mKeyboardLayoutSet == null || !isShowingEmojiPalettes()) {
+ mLatinIME.startShowingInputView();
setEmojiKeyboard();
+ } else {
+ mLatinIME.stopShowingInputView();
+ setAlphabetKeyboard();
}
}
@@ -359,7 +352,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
R.layout.input_view, null);
mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame);
mEmojiPalettesView = (EmojiPalettesView)mCurrentInputView.findViewById(
- R.id.emoji_keyboard_view);
+ R.id.emoji_palettes_view);
mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java b/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java
index 0cd606d19..7161d3f26 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java
@@ -32,6 +32,8 @@ public final class KeyboardTheme implements Comparable<KeyboardTheme> {
static final String KLP_KEYBOARD_THEME_KEY = "pref_keyboard_layout_20110916";
static final String LXX_KEYBOARD_THEME_KEY = "pref_keyboard_theme_20140509";
+ // These should be aligned with Keyboard.themeId and Keyboard.Case.keyboardTheme
+ // attributes' values in attrs.xml.
public static final int THEME_ID_ICS = 0;
public static final int THEME_ID_KLP = 2;
public static final int THEME_ID_LXX_LIGHT = 3;
@@ -39,16 +41,16 @@ public final class KeyboardTheme implements Comparable<KeyboardTheme> {
public static final int DEFAULT_THEME_ID = THEME_ID_KLP;
private static final KeyboardTheme[] KEYBOARD_THEMES = {
- new KeyboardTheme(THEME_ID_ICS, R.style.KeyboardTheme_ICS,
+ new KeyboardTheme(THEME_ID_ICS, "ICS", R.style.KeyboardTheme_ICS,
// This has never been selected because we support ICS or later.
VERSION_CODES.BASE),
- new KeyboardTheme(THEME_ID_KLP, R.style.KeyboardTheme_KLP,
+ new KeyboardTheme(THEME_ID_KLP, "KLP", R.style.KeyboardTheme_KLP,
// Default theme for ICS, JB, and KLP.
VERSION_CODES.ICE_CREAM_SANDWICH),
- new KeyboardTheme(THEME_ID_LXX_LIGHT, R.style.KeyboardTheme_LXX_Light,
+ new KeyboardTheme(THEME_ID_LXX_LIGHT, "LXXLight", R.style.KeyboardTheme_LXX_Light,
// Default theme for LXX.
BuildCompatUtils.VERSION_CODES_LXX),
- new KeyboardTheme(THEME_ID_LXX_DARK, R.style.KeyboardTheme_LXX_Dark,
+ new KeyboardTheme(THEME_ID_LXX_DARK, "LXXDark", R.style.KeyboardTheme_LXX_Dark,
VERSION_CODES.BASE),
};
@@ -59,12 +61,15 @@ public final class KeyboardTheme implements Comparable<KeyboardTheme> {
public final int mThemeId;
public final int mStyleId;
+ public final String mThemeName;
private final int mMinApiVersion;
// Note: The themeId should be aligned with "themeId" attribute of Keyboard style
// in values/themes-<style>.xml.
- private KeyboardTheme(final int themeId, final int styleId, final int minApiVersion) {
+ private KeyboardTheme(final int themeId, final String themeName, final int styleId,
+ final int minApiVersion) {
mThemeId = themeId;
+ mThemeName = themeName;
mStyleId = styleId;
mMinApiVersion = minApiVersion;
}
@@ -128,6 +133,11 @@ public final class KeyboardTheme implements Comparable<KeyboardTheme> {
return searchKeyboardThemeById(DEFAULT_THEME_ID);
}
+ public static String getKeyboardThemeName(final int themeId) {
+ final KeyboardTheme theme = searchKeyboardThemeById(themeId);
+ return theme.mThemeName;
+ }
+
public static void saveKeyboardThemeId(final String themeIdString,
final SharedPreferences prefs) {
saveKeyboardThemeId(themeIdString, prefs, BuildCompatUtils.EFFECTIVE_SDK_INT);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 075cd901d..98cd1da54 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -340,11 +340,27 @@ public class KeyboardView extends View {
// Draw key background.
protected void onDrawKeyBackground(final Key key, final Canvas canvas,
final Drawable background) {
- final Rect padding = mKeyBackgroundPadding;
- final int bgWidth = key.getDrawWidth() + padding.left + padding.right;
- final int bgHeight = key.getHeight() + padding.top + padding.bottom;
- final int bgX = -padding.left;
- final int bgY = -padding.top;
+ final int keyWidth = key.getDrawWidth();
+ final int keyHeight = key.getHeight();
+ final int bgWidth, bgHeight, bgX, bgY;
+ if (key.needsToKeepBackgroundAspectRatio(mDefaultKeyLabelFlags)
+ // HACK: To disable expanding normal/functional key background.
+ && !key.hasCustomActionLabel()) {
+ final int intrinsicWidth = background.getIntrinsicWidth();
+ final int intrinsicHeight = background.getIntrinsicHeight();
+ final float minScale = Math.min(
+ keyWidth / (float)intrinsicWidth, keyHeight / (float)intrinsicHeight);
+ bgWidth = (int)(intrinsicWidth * minScale);
+ bgHeight = (int)(intrinsicHeight * minScale);
+ bgX = (keyWidth - bgWidth) / 2;
+ bgY = (keyHeight - bgHeight) / 2;
+ } else {
+ final Rect padding = mKeyBackgroundPadding;
+ bgWidth = keyWidth + padding.left + padding.right;
+ bgHeight = keyHeight + padding.top + padding.bottom;
+ bgX = -padding.left;
+ bgY = -padding.top;
+ }
final Rect bounds = background.getBounds();
if (bgWidth != bounds.right || bgHeight != bounds.bottom) {
background.setBounds(0, 0, bgWidth, bgHeight);
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 1ef53a65d..2b16785c2 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -86,7 +86,10 @@ import java.util.WeakHashMap;
* @attr ref R.styleable#MainKeyboardView_keyPreviewOffset
* @attr ref R.styleable#MainKeyboardView_keyPreviewHeight
* @attr ref R.styleable#MainKeyboardView_keyPreviewLingerTimeout
+ * @attr ref R.styleable#MainKeyboardView_keyPreviewShowUpAnimator
+ * @attr ref R.styleable#MainKeyboardView_keyPreviewDismissAnimator
* @attr ref R.styleable#MainKeyboardView_moreKeysKeyboardLayout
+ * @attr ref R.styleable#MainKeyboardView_moreKeysKeyboardForActionLayout
* @attr ref R.styleable#MainKeyboardView_backgroundDimAlpha
* @attr ref R.styleable#MainKeyboardView_showMoreKeysKeyboardAtTouchPoint
* @attr ref R.styleable#MainKeyboardView_gestureFloatingPreviewTextLingerTimeout
@@ -146,6 +149,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private final Paint mBackgroundDimAlphaPaint = new Paint();
private boolean mNeedsToDimEntireKeyboard;
private final View mMoreKeysKeyboardContainer;
+ private final View mMoreKeysKeyboardForActionContainer;
private final WeakHashMap<Key, Keyboard> mMoreKeysKeyboardCache = new WeakHashMap<>();
private final boolean mConfigShowMoreKeysKeyboardAtTouchedPoint;
// More keys panel (used by both more keys keyboard and more suggestions view)
@@ -230,6 +234,9 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
final int moreKeysKeyboardLayoutId = mainKeyboardViewAttr.getResourceId(
R.styleable.MainKeyboardView_moreKeysKeyboardLayout, 0);
+ final int moreKeysKeyboardForActionLayoutId = mainKeyboardViewAttr.getResourceId(
+ R.styleable.MainKeyboardView_moreKeysKeyboardForActionLayout,
+ moreKeysKeyboardLayoutId);
mConfigShowMoreKeysKeyboardAtTouchedPoint = mainKeyboardViewAttr.getBoolean(
R.styleable.MainKeyboardView_showMoreKeysKeyboardAtTouchedPoint, false);
@@ -247,8 +254,10 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
mSlidingKeyInputDrawingPreview.setDrawingView(mDrawingPreviewPlacerView);
mainKeyboardViewAttr.recycle();
- mMoreKeysKeyboardContainer = LayoutInflater.from(getContext())
- .inflate(moreKeysKeyboardLayoutId, null);
+ final LayoutInflater inflater = LayoutInflater.from(getContext());
+ mMoreKeysKeyboardContainer = inflater.inflate(moreKeysKeyboardLayoutId, null);
+ mMoreKeysKeyboardForActionContainer = inflater.inflate(
+ moreKeysKeyboardForActionLayoutId, null);
mLanguageOnSpacebarFadeoutAnimator = loadObjectAnimator(
languageOnSpacebarFadeoutAnimatorResId, this);
mAltCodeKeyWhileTypingFadeoutAnimator = loadObjectAnimator(
@@ -391,20 +400,34 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
/**
- * Enables or disables the key feedback popup. This is a popup that shows a magnified
+ * Enables or disables the key preview popup. This is a popup that shows a magnified
* version of the depressed key. By default the preview is enabled.
* @param previewEnabled whether or not to enable the key feedback preview
* @param delay the delay after which the preview is dismissed
- * @see #isKeyPreviewPopupEnabled()
*/
public void setKeyPreviewPopupEnabled(final boolean previewEnabled, final int delay) {
mKeyPreviewDrawParams.setPopupEnabled(previewEnabled, delay);
}
- public void setKeyPreviewAnimationParams(final float showUpStartScale, final int showUpDuration,
- final float dismissEndScale, final int dismissDuration) {
- mKeyPreviewDrawParams.setAnimationParams(
- showUpStartScale, showUpDuration, dismissEndScale, dismissDuration);
+ /**
+ * Enables or disables the key preview popup animations and set animations' parameters.
+ *
+ * @param hasCustomAnimationParams false to use the default key preview popup animations
+ * specified by keyPreviewShowUpAnimator and keyPreviewDismissAnimator attributes.
+ * true to override the default animations with the specified parameters.
+ * @param showUpStartXScale from this x-scale the show up animation will start.
+ * @param showUpStartYScale from this y-scale the show up animation will start.
+ * @param showUpDuration the duration of the show up animation in milliseconds.
+ * @param dismissEndXScale to this x-scale the dismiss animation will end.
+ * @param dismissEndYScale to this y-scale the dismiss animation will end.
+ * @param dismissDuration the duration of the dismiss animation in milliseconds.
+ */
+ public void setKeyPreviewAnimationParams(final boolean hasCustomAnimationParams,
+ final float showUpStartXScale, final float showUpStartYScale, final int showUpDuration,
+ final float dismissEndXScale, final float dismissEndYScale, final int dismissDuration) {
+ mKeyPreviewDrawParams.setAnimationParams(hasCustomAnimationParams,
+ showUpStartXScale, showUpStartYScale, showUpDuration,
+ dismissEndXScale, dismissEndYScale, dismissDuration);
}
private void locatePreviewPlacerView() {
@@ -566,7 +589,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
mMoreKeysKeyboardCache.put(key, moreKeysKeyboard);
}
- final View container = mMoreKeysKeyboardContainer;
+ final View container = key.isActionKey() ? mMoreKeysKeyboardForActionContainer
+ : mMoreKeysKeyboardContainer;
final MoreKeysKeyboardView moreKeysKeyboardView =
(MoreKeysKeyboardView)container.findViewById(R.id.more_keys_keyboard_view);
moreKeysKeyboardView.setKeyboard(moreKeysKeyboard);
@@ -732,7 +756,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
public void onHideWindow() {
onDismissMoreKeysPanel();
final MainKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
- if (accessibilityDelegate != null) {
+ if (accessibilityDelegate != null
+ && AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
accessibilityDelegate.onHideWindow();
}
}
@@ -743,7 +768,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
@Override
public boolean onHoverEvent(final MotionEvent event) {
final MainKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
- if (accessibilityDelegate != null) {
+ if (accessibilityDelegate != null
+ && AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
return accessibilityDelegate.onHoverEvent(event);
}
return super.onHoverEvent(event);
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index e0184d7f1..abcfff8a6 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -18,11 +18,9 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
import android.graphics.Paint;
-import android.graphics.drawable.Drawable;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
-import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.keyboard.internal.KeyboardParams;
import com.android.inputmethod.keyboard.internal.MoreKeySpec;
import com.android.inputmethod.latin.R;
@@ -43,7 +41,7 @@ public final class MoreKeysKeyboard extends Keyboard {
@UsedForTesting
static class MoreKeysKeyboardParams extends KeyboardParams {
- public boolean mIsFixedOrder;
+ public boolean mIsMoreKeysFixedOrder;
/* package */int mTopRowAdjustment;
public int mNumRows;
public int mNumColumns;
@@ -61,29 +59,35 @@ public final class MoreKeysKeyboard extends Keyboard {
* Set keyboard parameters of more keys keyboard.
*
* @param numKeys number of keys in this more keys keyboard.
- * @param maxColumns number of maximum columns of this more keys keyboard.
+ * @param numColumn number of columns of this more keys keyboard.
* @param keyWidth more keys keyboard key width in pixel, including horizontal gap.
* @param rowHeight more keys keyboard row height in pixel, including vertical gap.
* @param coordXInParent coordinate x of the key preview in parent keyboard.
* @param parentKeyboardWidth parent keyboard width in pixel.
- * @param isFixedColumnOrder if true, more keys should be laid out in fixed order.
+ * @param isMoreKeysFixedColumn true if more keys keyboard should have
+ * <code>numColumn</code> columns. Otherwise more keys keyboard should have
+ * <code>numColumn</code> columns at most.
+ * @param isMoreKeysFixedOrder true if the order of more keys is determined by the order in
+ * the more keys' specification. Otherwise the order of more keys is automatically
+ * determined.
* @param dividerWidth width of divider, zero for no dividers.
*/
- public void setParameters(final int numKeys, final int maxColumns, final int keyWidth,
+ public void setParameters(final int numKeys, final int numColumn, final int keyWidth,
final int rowHeight, final int coordXInParent, final int parentKeyboardWidth,
- final boolean isFixedColumnOrder, final int dividerWidth) {
- mIsFixedOrder = isFixedColumnOrder;
- if (parentKeyboardWidth / keyWidth < Math.min(numKeys, maxColumns)) {
+ final boolean isMoreKeysFixedColumn, final boolean isMoreKeysFixedOrder,
+ final int dividerWidth) {
+ mIsMoreKeysFixedOrder = isMoreKeysFixedOrder;
+ if (parentKeyboardWidth / keyWidth < Math.min(numKeys, numColumn)) {
throw new IllegalArgumentException("Keyboard is too small to hold more keys: "
- + parentKeyboardWidth + " " + keyWidth + " " + numKeys + " " + maxColumns);
+ + parentKeyboardWidth + " " + keyWidth + " " + numKeys + " " + numColumn);
}
mDefaultKeyWidth = keyWidth;
mDefaultRowHeight = rowHeight;
- final int numRows = (numKeys + maxColumns - 1) / maxColumns;
+ final int numRows = (numKeys + numColumn - 1) / numColumn;
mNumRows = numRows;
- final int numColumns = mIsFixedOrder ? Math.min(numKeys, maxColumns)
- : getOptimizedColumns(numKeys, maxColumns);
+ final int numColumns = isMoreKeysFixedColumn ? Math.min(numKeys, numColumn)
+ : getOptimizedColumns(numKeys, numColumn);
mNumColumns = numColumns;
final int topKeys = numKeys % numColumns;
mTopKeys = topKeys == 0 ? numColumns : topKeys;
@@ -120,7 +124,7 @@ public final class MoreKeysKeyboard extends Keyboard {
mRightKeys = rightKeys;
// Adjustment of the top row.
- mTopRowAdjustment = mIsFixedOrder ? getFixedOrderTopRowAdjustment()
+ mTopRowAdjustment = isMoreKeysFixedOrder ? getFixedOrderTopRowAdjustment()
: getAutoOrderTopRowAdjustment();
mDividerWidth = dividerWidth;
mColumnWidth = mDefaultKeyWidth + mDividerWidth;
@@ -148,7 +152,7 @@ public final class MoreKeysKeyboard extends Keyboard {
// Return key position according to column count (0 is default).
/* package */int getColumnPos(final int n) {
- return mIsFixedOrder ? getFixedOrderColumnPos(n) : getAutomaticColumnPos(n);
+ return mIsMoreKeysFixedOrder ? getFixedOrderColumnPos(n) : getAutomaticColumnPos(n);
}
private int getFixedOrderColumnPos(final int n) {
@@ -251,7 +255,6 @@ public final class MoreKeysKeyboard extends Keyboard {
public static class Builder extends KeyboardBuilder<MoreKeysKeyboardParams> {
private final Key mParentKey;
- private final Drawable mDivider;
private static final float LABEL_PADDING_RATIO = 0.2f;
private static final float DIVIDER_RATIO = 0.2f;
@@ -263,7 +266,8 @@ public final class MoreKeysKeyboard extends Keyboard {
* @param keyboard the {@link Keyboard} that contains the parentKey.
* @param isSingleMoreKeyWithPreview true if the <code>key</code> has just a single
* "more key" and its key popup preview is enabled.
- * @param keyPreviewDrawParams the parameter to place key preview.
+ * @param keyPreviewVisibleWidth the width of visible part of key popup preview.
+ * @param keyPreviewVisibleHeight the height of visible part of key popup preview
* @param paintToMeasure the {@link Paint} object to measure a "more key" width
*/
public Builder(final Context context, final Key key, final Keyboard keyboard,
@@ -299,16 +303,14 @@ public final class MoreKeysKeyboard extends Keyboard {
}
final int dividerWidth;
if (key.needsDividersInMoreKeys()) {
- mDivider = mResources.getDrawable(R.drawable.more_keys_divider);
dividerWidth = (int)(keyWidth * DIVIDER_RATIO);
} else {
- mDivider = null;
dividerWidth = 0;
}
final MoreKeySpec[] moreKeys = key.getMoreKeys();
- mParams.setParameters(moreKeys.length, key.getMoreKeysColumn(), keyWidth, rowHeight,
- key.getX() + key.getWidth() / 2, keyboard.mId.mWidth,
- key.isFixedColumnOrderMoreKeys(), dividerWidth);
+ mParams.setParameters(moreKeys.length, key.getMoreKeysColumnNumber(), keyWidth,
+ rowHeight, key.getX() + key.getWidth() / 2, keyboard.mId.mWidth,
+ key.isMoreKeysFixedColumn(), key.isMoreKeysFixedOrder(), dividerWidth);
}
private static int getMaxKeyWidth(final Key parentKey, final int minKeyWidth,
@@ -345,7 +347,8 @@ public final class MoreKeysKeyboard extends Keyboard {
if (params.mDividerWidth > 0 && pos != 0) {
final int dividerX = (pos > 0) ? x - params.mDividerWidth
: x + params.mDefaultKeyWidth;
- final Key divider = new MoreKeyDivider(params, mDivider, dividerX, y);
+ final Key divider = new MoreKeyDivider(
+ params, dividerX, y, params.mDividerWidth, params.mDefaultRowHeight);
params.onAddKey(divider);
}
}
@@ -353,22 +356,11 @@ public final class MoreKeysKeyboard extends Keyboard {
}
}
- private static class MoreKeyDivider extends Key.Spacer {
- private final Drawable mIcon;
-
- public MoreKeyDivider(final MoreKeysKeyboardParams params, final Drawable icon,
- final int x, final int y) {
- super(params, x, y, params.mDividerWidth, params.mDefaultRowHeight);
- mIcon = icon;
- }
-
- @Override
- public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) {
- // KeyboardIconsSet and alpha are unused. Use the icon that has been passed to the
- // constructor.
- // TODO: Drawable itself should have an alpha value.
- mIcon.setAlpha(128);
- return mIcon;
+ // Used as a divider maker. A divider is drawn by {@link MoreKeysKeyboardView}.
+ public static class MoreKeyDivider extends Key.Spacer {
+ public MoreKeyDivider(final KeyboardParams params, final int x, final int y,
+ final int width, final int height) {
+ super(params, x, y, width, height);
}
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index 5140c4ffc..841283b7f 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -17,6 +17,10 @@
package com.android.inputmethod.keyboard;
import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
@@ -24,6 +28,7 @@ import android.view.ViewGroup;
import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.accessibility.MoreKeysKeyboardAccessibilityDelegate;
+import com.android.inputmethod.keyboard.internal.KeyDrawParams;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.CoordinateUtils;
@@ -35,6 +40,7 @@ import com.android.inputmethod.latin.utils.CoordinateUtils;
public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel {
private final int[] mCoordinates = CoordinateUtils.newInstance();
+ private final Drawable mDivider;
protected final KeyDetector mKeyDetector;
private Controller mController = EMPTY_CONTROLLER;
protected KeyboardActionListener mListener;
@@ -53,6 +59,14 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
public MoreKeysKeyboardView(final Context context, final AttributeSet attrs,
final int defStyle) {
super(context, attrs, defStyle);
+ final TypedArray moreKeysKeyboardViewAttr = context.obtainStyledAttributes(attrs,
+ R.styleable.MoreKeysKeyboardView, defStyle, R.style.MoreKeysKeyboardView);
+ mDivider = moreKeysKeyboardViewAttr.getDrawable(R.styleable.MoreKeysKeyboardView_divider);
+ if (mDivider != null) {
+ // TODO: Drawable itself should have an alpha value.
+ mDivider.setAlpha(128);
+ }
+ moreKeysKeyboardViewAttr.recycle();
mKeyDetector = new MoreKeysDetector(getResources().getDimension(
R.dimen.config_more_keys_keyboard_slide_allowance));
}
@@ -70,11 +84,28 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
}
@Override
+ protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint,
+ final KeyDrawParams params) {
+ if (!key.isSpacer() || !(key instanceof MoreKeysKeyboard.MoreKeyDivider)
+ || mDivider == null) {
+ super.onDrawKeyTopVisuals(key, canvas, paint, params);
+ return;
+ }
+ final int keyWidth = key.getDrawWidth();
+ final int keyHeight = key.getHeight();
+ final int iconWidth = Math.min(mDivider.getIntrinsicWidth(), keyWidth);
+ final int iconHeight = mDivider.getIntrinsicHeight();
+ final int iconX = (keyWidth - iconWidth) / 2; // Align horizontally center
+ final int iconY = (keyHeight - iconHeight) / 2; // Align vertically center
+ drawIcon(canvas, mDivider, iconX, iconY, iconWidth, iconHeight);
+ }
+
+ @Override
public void setKeyboard(final Keyboard keyboard) {
super.setKeyboard(keyboard);
mKeyDetector.setKeyboard(
keyboard, -getPaddingLeft(), -getPaddingTop() + getVerticalCorrection());
- if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+ if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
if (mAccessibilityDelegate == null) {
mAccessibilityDelegate = new MoreKeysKeyboardAccessibilityDelegate(
this, mKeyDetector);
@@ -111,7 +142,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
mOriginY = y + container.getPaddingTop();
controller.onShowMoreKeysPanel(this);
final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
- if (accessibilityDelegate != null) {
+ if (accessibilityDelegate != null
+ && AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
accessibilityDelegate.onShowMoreKeysKeyboard();
}
}
@@ -208,7 +240,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
return;
}
final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
- if (accessibilityDelegate != null) {
+ if (accessibilityDelegate != null
+ && AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
accessibilityDelegate.onDismissMoreKeysKeyboard();
}
mController.onDismissMoreKeysPanel();
@@ -254,7 +287,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
@Override
public boolean onHoverEvent(final MotionEvent event) {
final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
- if (accessibilityDelegate != null) {
+ if (accessibilityDelegate != null
+ && AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
return accessibilityDelegate.onHoverEvent(event);
}
return super.onHoverEvent(event);
diff --git a/java/src/com/android/inputmethod/keyboard/TextDecorator.java b/java/src/com/android/inputmethod/keyboard/TextDecorator.java
new file mode 100644
index 000000000..c22717f95
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/TextDecorator.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2014 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.keyboard;
+
+import android.graphics.Matrix;
+import android.graphics.RectF;
+import android.inputmethodservice.InputMethodService;
+import android.os.Message;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.inputmethod.CursorAnchorInfo;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper;
+import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A controller class of the add-to-dictionary indicator (a.k.a. TextDecorator). This class
+ * is designed to be independent of UI subsystems such as {@link View}. All the UI related
+ * operations are delegated to {@link TextDecoratorUi} via {@link TextDecoratorUiOperator}.
+ */
+public class TextDecorator {
+ private static final String TAG = TextDecorator.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private static final int INVALID_CURSOR_INDEX = -1;
+
+ private static final int MODE_MONITOR = 0;
+ private static final int MODE_WAITING_CURSOR_INDEX = 1;
+ private static final int MODE_SHOWING_INDICATOR = 2;
+
+ private int mMode = MODE_MONITOR;
+
+ private String mLastComposingText = null;
+ private boolean mHasRtlCharsInLastComposingText = false;
+ private RectF mComposingTextBoundsForLastComposingText = new RectF();
+
+ private boolean mIsFullScreenMode = false;
+ private String mWaitingWord = null;
+ private int mWaitingCursorStart = INVALID_CURSOR_INDEX;
+ private int mWaitingCursorEnd = INVALID_CURSOR_INDEX;
+ private CursorAnchorInfoCompatWrapper mCursorAnchorInfoWrapper = null;
+
+ @Nonnull
+ private final Listener mListener;
+
+ @Nonnull
+ private TextDecoratorUiOperator mUiOperator = EMPTY_UI_OPERATOR;
+
+ public interface Listener {
+ /**
+ * Called when the user clicks the indicator to add the word into the dictionary.
+ * @param word the word which the user clicked on.
+ */
+ void onClickComposingTextToAddToDictionary(final String word);
+ }
+
+ public TextDecorator(final Listener listener) {
+ mListener = (listener != null) ? listener : EMPTY_LISTENER;
+ }
+
+ /**
+ * Sets the UI operator for {@link TextDecorator}. Any user visible operations will be
+ * delegated to the associated UI operator.
+ * @param uiOperator the UI operator to be associated.
+ */
+ public void setUiOperator(final TextDecoratorUiOperator uiOperator) {
+ mUiOperator.disposeUi();
+ mUiOperator = uiOperator;
+ mUiOperator.setOnClickListener(getOnClickHandler());
+ }
+
+ private final Runnable mDefaultOnClickHandler = new Runnable() {
+ @Override
+ public void run() {
+ onClickIndicator();
+ }
+ };
+
+ @UsedForTesting
+ final Runnable getOnClickHandler() {
+ return mDefaultOnClickHandler;
+ }
+
+ /**
+ * Shows the "Add to dictionary" indicator and associates it with associating the given word.
+ *
+ * @param word the word which should be associated with the indicator. This object will be
+ * passed back in {@link Listener#onClickComposingTextToAddToDictionary(String)}.
+ * @param selectionStart the cursor index (inclusive) when the indicator should be displayed.
+ * @param selectionEnd the cursor index (exclusive) when the indicator should be displayed.
+ */
+ public void showAddToDictionaryIndicator(final String word, final int selectionStart,
+ final int selectionEnd) {
+ mWaitingWord = word;
+ mWaitingCursorStart = selectionStart;
+ mWaitingCursorEnd = selectionEnd;
+ mMode = MODE_WAITING_CURSOR_INDEX;
+ layoutLater();
+ return;
+ }
+
+ /**
+ * Must be called when the input method is about changing to for from the full screen mode.
+ * @param fullScreenMode {@code true} if the input method is entering the full screen mode.
+ * {@code false} is the input method is finishing the full screen mode.
+ */
+ public void notifyFullScreenMode(final boolean fullScreenMode) {
+ final boolean fullScreenModeChanged = (mIsFullScreenMode != fullScreenMode);
+ mIsFullScreenMode = fullScreenMode;
+ if (fullScreenModeChanged) {
+ layoutLater();
+ }
+ }
+
+ /**
+ * Resets previous requests and makes indicator invisible.
+ */
+ public void reset() {
+ mWaitingWord = null;
+ mMode = MODE_MONITOR;
+ mWaitingCursorStart = INVALID_CURSOR_INDEX;
+ mWaitingCursorEnd = INVALID_CURSOR_INDEX;
+ cancelLayoutInternalExpectedly("Resetting internal state.");
+ }
+
+ /**
+ * Must be called when the {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)}
+ * is called.
+ *
+ * <p>CAVEAT: Currently the input method author is responsible for ignoring
+ * {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} called in full screen
+ * mode.</p>
+ * @param info the compatibility wrapper object for the received {@link CursorAnchorInfo}.
+ */
+ public void onUpdateCursorAnchorInfo(final CursorAnchorInfoCompatWrapper info) {
+ mCursorAnchorInfoWrapper = info;
+ // Do not use layoutLater() to minimize the latency.
+ layoutImmediately();
+ }
+
+ private void cancelLayoutInternalUnexpectedly(final String message) {
+ mUiOperator.hideUi();
+ Log.d(TAG, message);
+ }
+
+ private void cancelLayoutInternalExpectedly(final String message) {
+ mUiOperator.hideUi();
+ if (DEBUG) {
+ Log.d(TAG, message);
+ }
+ }
+
+ private void layoutLater() {
+ mLayoutInvalidator.invalidateLayout();
+ }
+
+
+ private void layoutImmediately() {
+ // Clear pending layout requests.
+ mLayoutInvalidator.cancelInvalidateLayout();
+ layoutMain();
+ }
+
+ private void layoutMain() {
+ final CursorAnchorInfoCompatWrapper info = mCursorAnchorInfoWrapper;
+
+ if (info == null || !info.isAvailable()) {
+ cancelLayoutInternalExpectedly("CursorAnchorInfo isn't available.");
+ return;
+ }
+
+ final Matrix matrix = info.getMatrix();
+ if (matrix == null) {
+ cancelLayoutInternalUnexpectedly("Matrix is null");
+ }
+
+ final CharSequence composingText = info.getComposingText();
+ if (!TextUtils.isEmpty(composingText)) {
+ final int composingTextStart = info.getComposingTextStart();
+ final int lastCharRectIndex = composingTextStart + composingText.length() - 1;
+ final RectF lastCharRect = info.getCharacterBounds(lastCharRectIndex);
+ final int lastCharRectFlags = info.getCharacterBoundsFlags(lastCharRectIndex);
+ final boolean hasInvisibleRegionInLastCharRect =
+ (lastCharRectFlags & CursorAnchorInfoCompatWrapper.FLAG_HAS_INVISIBLE_REGION)
+ != 0;
+ if (lastCharRect == null || matrix == null || hasInvisibleRegionInLastCharRect) {
+ mUiOperator.hideUi();
+ return;
+ }
+
+ // Note that the following layout information is fragile, and must be invalidated
+ // even when surrounding text next to the composing text is changed because it can
+ // affect how the composing text is rendered.
+ // TODO: Investigate if we can change the input logic to make the target text
+ // composing state so that we can retrieve the character bounds reliably.
+ final String composingTextString = composingText.toString();
+ final float top = lastCharRect.top;
+ final float bottom = lastCharRect.bottom;
+ float left = lastCharRect.left;
+ float right = lastCharRect.right;
+ boolean useRtlLayout = false;
+ for (int i = composingText.length() - 1; i >= 0; --i) {
+ final int characterIndex = composingTextStart + i;
+ final RectF characterBounds = info.getCharacterBounds(characterIndex);
+ final int characterBoundsFlags = info.getCharacterBoundsFlags(characterIndex);
+ if (characterBounds == null) {
+ break;
+ }
+ if (characterBounds.top != top) {
+ break;
+ }
+ if (characterBounds.bottom != bottom) {
+ break;
+ }
+ if ((characterBoundsFlags & CursorAnchorInfoCompatWrapper.FLAG_IS_RTL) != 0) {
+ // This is for both RTL text and bi-directional text. RTL languages usually mix
+ // RTL characters with LTR characters and in this case we should display the
+ // indicator on the left, while in LTR languages that normally never happens.
+ // TODO: Try to come up with a better algorithm.
+ useRtlLayout = true;
+ }
+ left = Math.min(characterBounds.left, left);
+ right = Math.max(characterBounds.right, right);
+ }
+ mLastComposingText = composingTextString;
+ mHasRtlCharsInLastComposingText = useRtlLayout;
+ mComposingTextBoundsForLastComposingText.set(left, top, right, bottom);
+ }
+
+ final int selectionStart = info.getSelectionStart();
+ final int selectionEnd = info.getSelectionEnd();
+ switch (mMode) {
+ case MODE_MONITOR:
+ mUiOperator.hideUi();
+ return;
+ case MODE_WAITING_CURSOR_INDEX:
+ if (selectionStart != mWaitingCursorStart || selectionEnd != mWaitingCursorEnd) {
+ mUiOperator.hideUi();
+ return;
+ }
+ mMode = MODE_SHOWING_INDICATOR;
+ break;
+ case MODE_SHOWING_INDICATOR:
+ if (selectionStart != mWaitingCursorStart || selectionEnd != mWaitingCursorEnd) {
+ mUiOperator.hideUi();
+ mMode = MODE_MONITOR;
+ mWaitingCursorStart = INVALID_CURSOR_INDEX;
+ mWaitingCursorEnd = INVALID_CURSOR_INDEX;
+ return;
+ }
+ break;
+ default:
+ cancelLayoutInternalUnexpectedly("Unexpected internal mode=" + mMode);
+ return;
+ }
+
+ if (!TextUtils.equals(mLastComposingText, mWaitingWord)) {
+ cancelLayoutInternalUnexpectedly("mLastComposingText doesn't match mWaitingWord");
+ return;
+ }
+
+ if ((info.getInsertionMarkerFlags() &
+ CursorAnchorInfoCompatWrapper.FLAG_HAS_INVISIBLE_REGION) != 0) {
+ mUiOperator.hideUi();
+ return;
+ }
+
+ mUiOperator.layoutUi(matrix, mComposingTextBoundsForLastComposingText,
+ mHasRtlCharsInLastComposingText);
+ }
+
+ private void onClickIndicator() {
+ if (mMode != MODE_SHOWING_INDICATOR) {
+ return;
+ }
+ mListener.onClickComposingTextToAddToDictionary(mWaitingWord);
+ }
+
+ private final LayoutInvalidator mLayoutInvalidator = new LayoutInvalidator(this);
+
+ /**
+ * Used for managing pending layout tasks for {@link TextDecorator#layoutLater()}.
+ */
+ private static final class LayoutInvalidator {
+ private final HandlerImpl mHandler;
+ public LayoutInvalidator(final TextDecorator ownerInstance) {
+ mHandler = new HandlerImpl(ownerInstance);
+ }
+
+ private static final int MSG_LAYOUT = 0;
+
+ private static final class HandlerImpl
+ extends LeakGuardHandlerWrapper<TextDecorator> {
+ public HandlerImpl(final TextDecorator ownerInstance) {
+ super(ownerInstance);
+ }
+
+ @Override
+ public void handleMessage(final Message msg) {
+ final TextDecorator owner = getOwnerInstance();
+ if (owner == null) {
+ return;
+ }
+ switch (msg.what) {
+ case MSG_LAYOUT:
+ owner.layoutMain();
+ break;
+ }
+ }
+ }
+
+ /**
+ * Puts a layout task into the scheduler. Does nothing if one or more layout tasks are
+ * already scheduled.
+ */
+ public void invalidateLayout() {
+ if (!mHandler.hasMessages(MSG_LAYOUT)) {
+ mHandler.obtainMessage(MSG_LAYOUT).sendToTarget();
+ }
+ }
+
+ /**
+ * Clears the pending layout tasks.
+ */
+ public void cancelInvalidateLayout() {
+ mHandler.removeMessages(MSG_LAYOUT);
+ }
+ }
+
+ private final static Listener EMPTY_LISTENER = new Listener() {
+ @Override
+ public void onClickComposingTextToAddToDictionary(final String word) {
+ }
+ };
+
+ private final static TextDecoratorUiOperator EMPTY_UI_OPERATOR = new TextDecoratorUiOperator() {
+ @Override
+ public void disposeUi() {
+ }
+ @Override
+ public void hideUi() {
+ }
+ @Override
+ public void setOnClickListener(Runnable listener) {
+ }
+ @Override
+ public void layoutUi(Matrix matrix, RectF composingTextBounds, boolean useRtlLayout) {
+ }
+ };
+}
diff --git a/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java b/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java
new file mode 100644
index 000000000..d87dc1bfa
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2014 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.keyboard;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.RectF;
+import android.graphics.drawable.ColorDrawable;
+import android.inputmethodservice.InputMethodService;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.view.ViewParent;
+import android.widget.PopupWindow;
+import android.widget.RelativeLayout;
+
+import com.android.inputmethod.latin.R;
+
+/**
+ * Used as the UI component of {@link TextDecorator}.
+ */
+public final class TextDecoratorUi implements TextDecoratorUiOperator {
+ private static final boolean VISUAL_DEBUG = false;
+ private static final int VISUAL_DEBUG_HIT_AREA_COLOR = 0x80ff8000;
+
+ private final RelativeLayout mLocalRootView;
+ private final AddToDictionaryIndicatorView mAddToDictionaryIndicatorView;
+ private final PopupWindow mTouchEventWindow;
+ private final View mTouchEventWindowClickListenerView;
+ private final float mHitAreaMarginInPixels;
+ private final RectF mDisplayRect;
+
+ /**
+ * This constructor is designed to be called from {@link InputMethodService#setInputView(View)}.
+ * Other usages are not supported.
+ *
+ * @param context the context of the input method.
+ * @param inputView the view that is passed to {@link InputMethodService#setInputView(View)}.
+ */
+ public TextDecoratorUi(final Context context, final View inputView) {
+ final Resources resources = context.getResources();
+ final int hitAreaMarginInDP = resources.getInteger(
+ R.integer.text_decorator_hit_area_margin_in_dp);
+ mHitAreaMarginInPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+ hitAreaMarginInDP, resources.getDisplayMetrics());
+ final DisplayMetrics displayMetrics = resources.getDisplayMetrics();
+ mDisplayRect = new RectF(0.0f, 0.0f, displayMetrics.widthPixels,
+ displayMetrics.heightPixels);
+
+ mLocalRootView = new RelativeLayout(context);
+ mLocalRootView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT));
+ // TODO: Use #setBackground(null) for API Level >= 16.
+ mLocalRootView.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+
+ final ViewGroup contentView = getContentView(inputView);
+ mAddToDictionaryIndicatorView = new AddToDictionaryIndicatorView(context);
+ mLocalRootView.addView(mAddToDictionaryIndicatorView);
+ if (contentView != null) {
+ contentView.addView(mLocalRootView);
+ }
+
+ // This popup window is used to avoid the limitation that the input method is not able to
+ // observe the touch events happening outside of InputMethodService.Insets#touchableRegion.
+ // We don't use this popup window for rendering the UI for performance reasons though.
+ mTouchEventWindow = new PopupWindow(context);
+ if (VISUAL_DEBUG) {
+ mTouchEventWindow.setBackgroundDrawable(new ColorDrawable(VISUAL_DEBUG_HIT_AREA_COLOR));
+ } else {
+ mTouchEventWindow.setBackgroundDrawable(null);
+ }
+ mTouchEventWindowClickListenerView = new View(context);
+ mTouchEventWindow.setContentView(mTouchEventWindowClickListenerView);
+ }
+
+ @Override
+ public void disposeUi() {
+ if (mLocalRootView != null) {
+ final ViewParent parent = mLocalRootView.getParent();
+ if (parent != null && parent instanceof ViewGroup) {
+ ((ViewGroup) parent).removeView(mLocalRootView);
+ }
+ mLocalRootView.removeAllViews();
+ }
+ if (mTouchEventWindow != null) {
+ mTouchEventWindow.dismiss();
+ }
+ }
+
+ @Override
+ public void hideUi() {
+ mAddToDictionaryIndicatorView.setVisibility(View.GONE);
+ mTouchEventWindow.dismiss();
+ }
+
+ private static final RectF getIndicatorBoundsInScreenCoordinates(final Matrix matrix,
+ final RectF composingTextBounds, final boolean showAtLeftSide) {
+ final float indicatorSize = composingTextBounds.height();
+ final RectF indicatorBounds;
+ if (showAtLeftSide) {
+ indicatorBounds = new RectF(composingTextBounds.left - indicatorSize,
+ composingTextBounds.top, composingTextBounds.left,
+ composingTextBounds.top + indicatorSize);
+ } else {
+ indicatorBounds = new RectF(composingTextBounds.right, composingTextBounds.top,
+ composingTextBounds.right + indicatorSize,
+ composingTextBounds.top + indicatorSize);
+ }
+ matrix.mapRect(indicatorBounds);
+ return indicatorBounds;
+ }
+
+ @Override
+ public void layoutUi(final Matrix matrix, final RectF composingTextBounds,
+ final boolean useRtlLayout) {
+ RectF indicatorBoundsInScreenCoordinates = getIndicatorBoundsInScreenCoordinates(matrix,
+ composingTextBounds, useRtlLayout /* showAtLeftSide */);
+ if (indicatorBoundsInScreenCoordinates.left < mDisplayRect.left ||
+ mDisplayRect.right < indicatorBoundsInScreenCoordinates.right) {
+ // The indicator is clipped by the screen. Show the indicator at the opposite side.
+ indicatorBoundsInScreenCoordinates = getIndicatorBoundsInScreenCoordinates(matrix,
+ composingTextBounds, !useRtlLayout /* showAtLeftSide */);
+ }
+
+ mAddToDictionaryIndicatorView.setBounds(indicatorBoundsInScreenCoordinates);
+
+ final RectF hitAreaBoundsInScreenCoordinates = new RectF();
+ matrix.mapRect(hitAreaBoundsInScreenCoordinates, composingTextBounds);
+ hitAreaBoundsInScreenCoordinates.union(indicatorBoundsInScreenCoordinates);
+ hitAreaBoundsInScreenCoordinates.inset(-mHitAreaMarginInPixels, -mHitAreaMarginInPixels);
+
+ final int[] originScreen = new int[2];
+ mLocalRootView.getLocationOnScreen(originScreen);
+ final int viewOriginX = originScreen[0];
+ final int viewOriginY = originScreen[1];
+ mAddToDictionaryIndicatorView.setX(indicatorBoundsInScreenCoordinates.left - viewOriginX);
+ mAddToDictionaryIndicatorView.setY(indicatorBoundsInScreenCoordinates.top - viewOriginY);
+ mAddToDictionaryIndicatorView.setVisibility(View.VISIBLE);
+
+ if (mTouchEventWindow.isShowing()) {
+ mTouchEventWindow.update((int)hitAreaBoundsInScreenCoordinates.left - viewOriginX,
+ (int)hitAreaBoundsInScreenCoordinates.top - viewOriginY,
+ (int)hitAreaBoundsInScreenCoordinates.width(),
+ (int)hitAreaBoundsInScreenCoordinates.height());
+ } else {
+ mTouchEventWindow.setWidth((int)hitAreaBoundsInScreenCoordinates.width());
+ mTouchEventWindow.setHeight((int)hitAreaBoundsInScreenCoordinates.height());
+ mTouchEventWindow.showAtLocation(mLocalRootView, Gravity.NO_GRAVITY,
+ (int)hitAreaBoundsInScreenCoordinates.left - viewOriginX,
+ (int)hitAreaBoundsInScreenCoordinates.top - viewOriginY);
+ }
+ }
+
+ @Override
+ public void setOnClickListener(final Runnable listener) {
+ mTouchEventWindowClickListenerView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(final View arg0) {
+ listener.run();
+ }
+ });
+ }
+
+ private static class IndicatorView extends View {
+ private final Path mPath;
+ private final Path mTmpPath = new Path();
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private final Matrix mMatrix = new Matrix();
+ private final int mBackgroundColor;
+ private final int mForegroundColor;
+ private final RectF mBounds = new RectF();
+ public IndicatorView(Context context, final int pathResourceId,
+ final int sizeResourceId, final int backgroundColorResourceId,
+ final int foregroundColroResourceId) {
+ super(context);
+ final Resources resources = context.getResources();
+ mPath = createPath(resources, pathResourceId, sizeResourceId);
+ mBackgroundColor = resources.getColor(backgroundColorResourceId);
+ mForegroundColor = resources.getColor(foregroundColroResourceId);
+ }
+
+ public void setBounds(final RectF rect) {
+ mBounds.set(rect);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ mPaint.setColor(mBackgroundColor);
+ mPaint.setStyle(Paint.Style.FILL);
+ canvas.drawRect(0.0f, 0.0f, mBounds.width(), mBounds.height(), mPaint);
+
+ mMatrix.reset();
+ mMatrix.postScale(mBounds.width(), mBounds.height());
+ mPath.transform(mMatrix, mTmpPath);
+ mPaint.setColor(mForegroundColor);
+ canvas.drawPath(mTmpPath, mPaint);
+ }
+
+ private static Path createPath(final Resources resources, final int pathResourceId,
+ final int sizeResourceId) {
+ final int size = resources.getInteger(sizeResourceId);
+ final float normalizationFactor = 1.0f / size;
+ final int[] array = resources.getIntArray(pathResourceId);
+
+ final Path path = new Path();
+ for (int i = 0; i < array.length; i += 2) {
+ if (i == 0) {
+ path.moveTo(array[i] * normalizationFactor, array[i + 1] * normalizationFactor);
+ } else {
+ path.lineTo(array[i] * normalizationFactor, array[i + 1] * normalizationFactor);
+ }
+ }
+ path.close();
+ return path;
+ }
+ }
+
+ private static ViewGroup getContentView(final View view) {
+ final View rootView = view.getRootView();
+ if (rootView == null) {
+ return null;
+ }
+
+ final ViewGroup windowContentView = (ViewGroup)rootView.findViewById(android.R.id.content);
+ if (windowContentView == null) {
+ return null;
+ }
+ return windowContentView;
+ }
+
+ private static final class AddToDictionaryIndicatorView extends TextDecoratorUi.IndicatorView {
+ public AddToDictionaryIndicatorView(final Context context) {
+ super(context, R.array.text_decorator_add_to_dictionary_indicator_path,
+ R.integer.text_decorator_add_to_dictionary_indicator_path_size,
+ R.color.text_decorator_add_to_dictionary_indicator_background_color,
+ R.color.text_decorator_add_to_dictionary_indicator_foreground_color);
+ }
+ }
+} \ No newline at end of file
diff --git a/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java b/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java
new file mode 100644
index 000000000..9e30e417e
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 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.keyboard;
+
+import android.graphics.Matrix;
+import android.graphics.RectF;
+
+/**
+ * This interface defines how UI operations required for {@link TextDecorator} are delegated to
+ * the actual UI implementation class.
+ */
+public interface TextDecoratorUiOperator {
+ /**
+ * Called to notify that the UI is ready to be disposed.
+ */
+ void disposeUi();
+
+ /**
+ * Called when the UI should become invisible.
+ */
+ void hideUi();
+
+ /**
+ * Called to set the new click handler.
+ * @param onClickListener the callback object whose {@link Runnable#run()} should be called when
+ * the indicator is clicked.
+ */
+ void setOnClickListener(final Runnable onClickListener);
+
+ /**
+ * Called when the layout should be updated.
+ * @param matrix The matrix that transforms the local coordinates into the screen coordinates.
+ * @param composingTextBounds The bounding box of the composing text, in local coordinates.
+ * @param useRtlLayout {@code true} if the indicator should be optimized for RTL layout.
+ */
+ void layoutUi(final Matrix matrix, final RectF composingTextBounds, final boolean useRtlLayout);
+}
diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java
index 17dfc9cce..925ec6bfb 100644
--- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java
@@ -104,7 +104,8 @@ final class EmojiPageKeyboardView extends KeyboardView implements
public boolean onHoverEvent(final MotionEvent event) {
final KeyboardAccessibilityDelegate<EmojiPageKeyboardView> accessibilityDelegate =
mAccessibilityDelegate;
- if (accessibilityDelegate != null) {
+ if (accessibilityDelegate != null
+ && AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
return accessibilityDelegate.onHoverEvent(event);
}
return super.onHoverEvent(event);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
index cd29c8d17..5005b7d7d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
@@ -18,13 +18,9 @@ package com.android.inputmethod.keyboard.internal;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.latin.utils.CoordinateUtils;
@@ -89,9 +85,9 @@ public final class KeyPreviewChoreographer {
}
final Object tag = keyPreviewView.getTag();
if (withAnimation) {
- if (tag instanceof KeyPreviewAnimations) {
- final KeyPreviewAnimations animation = (KeyPreviewAnimations)tag;
- animation.startDismiss();
+ if (tag instanceof KeyPreviewAnimators) {
+ final KeyPreviewAnimators animators = (KeyPreviewAnimators)tag;
+ animators.startDismiss();
return;
}
}
@@ -161,87 +157,60 @@ public final class KeyPreviewChoreographer {
}
// Show preview with animation.
- final Animator showUpAnimation = createShowUpAniation(key, keyPreviewView);
- final Animator dismissAnimation = createDismissAnimation(key, keyPreviewView);
- final KeyPreviewAnimations animation = new KeyPreviewAnimations(
- showUpAnimation, dismissAnimation);
- keyPreviewView.setTag(animation);
- animation.startShowUp();
+ final Animator showUpAnimator = createShowUpAnimator(key, keyPreviewView);
+ final Animator dismissAnimator = createDismissAnimator(key, keyPreviewView);
+ final KeyPreviewAnimators animators = new KeyPreviewAnimators(
+ showUpAnimator, dismissAnimator);
+ keyPreviewView.setTag(animators);
+ animators.startShowUp();
}
- private static final float KEY_PREVIEW_SHOW_UP_END_SCALE = 1.0f;
- private static final AccelerateInterpolator ACCELERATE_INTERPOLATOR =
- new AccelerateInterpolator();
- private static final DecelerateInterpolator DECELERATE_INTERPOLATOR =
- new DecelerateInterpolator();
-
- private Animator createShowUpAniation(final Key key, final KeyPreviewView keyPreviewView) {
- // TODO: Optimization for no scale animation and no duration.
- final ObjectAnimator scaleXAnimation = ObjectAnimator.ofFloat(
- keyPreviewView, View.SCALE_X, mParams.getShowUpStartScale(),
- KEY_PREVIEW_SHOW_UP_END_SCALE);
- final ObjectAnimator scaleYAnimation = ObjectAnimator.ofFloat(
- keyPreviewView, View.SCALE_Y, mParams.getShowUpStartScale(),
- KEY_PREVIEW_SHOW_UP_END_SCALE);
- final AnimatorSet showUpAnimation = new AnimatorSet();
- showUpAnimation.play(scaleXAnimation).with(scaleYAnimation);
- showUpAnimation.setDuration(mParams.getShowUpDuration());
- showUpAnimation.setInterpolator(DECELERATE_INTERPOLATOR);
- showUpAnimation.addListener(new AnimatorListenerAdapter() {
+ public Animator createShowUpAnimator(final Key key, final KeyPreviewView keyPreviewView) {
+ final Animator animator = mParams.createShowUpAnimator(keyPreviewView);
+ animator.addListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationStart(final Animator animation) {
+ public void onAnimationStart(final Animator animator) {
showKeyPreview(key, keyPreviewView, false /* withAnimation */);
}
});
- return showUpAnimation;
+ return animator;
}
- private Animator createDismissAnimation(final Key key, final KeyPreviewView keyPreviewView) {
- // TODO: Optimization for no scale animation and no duration.
- final ObjectAnimator scaleXAnimation = ObjectAnimator.ofFloat(
- keyPreviewView, View.SCALE_X, mParams.getDismissEndScale());
- final ObjectAnimator scaleYAnimation = ObjectAnimator.ofFloat(
- keyPreviewView, View.SCALE_Y, mParams.getDismissEndScale());
- final AnimatorSet dismissAnimation = new AnimatorSet();
- dismissAnimation.play(scaleXAnimation).with(scaleYAnimation);
- final int dismissDuration = Math.min(
- mParams.getDismissDuration(), mParams.getLingerTimeout());
- dismissAnimation.setDuration(dismissDuration);
- dismissAnimation.setInterpolator(ACCELERATE_INTERPOLATOR);
- dismissAnimation.addListener(new AnimatorListenerAdapter() {
+ private Animator createDismissAnimator(final Key key, final KeyPreviewView keyPreviewView) {
+ final Animator animator = mParams.createDismissAnimator(keyPreviewView);
+ animator.addListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationEnd(final Animator animation) {
+ public void onAnimationEnd(final Animator animator) {
dismissKeyPreview(key, false /* withAnimation */);
}
});
- return dismissAnimation;
+ return animator;
}
- private static class KeyPreviewAnimations extends AnimatorListenerAdapter {
- private final Animator mShowUpAnimation;
- private final Animator mDismissAnimation;
+ private static class KeyPreviewAnimators extends AnimatorListenerAdapter {
+ private final Animator mShowUpAnimator;
+ private final Animator mDismissAnimator;
- public KeyPreviewAnimations(final Animator showUpAnimation,
- final Animator dismissAnimation) {
- mShowUpAnimation = showUpAnimation;
- mDismissAnimation = dismissAnimation;
+ public KeyPreviewAnimators(final Animator showUpAnimator, final Animator dismissAnimator) {
+ mShowUpAnimator = showUpAnimator;
+ mDismissAnimator = dismissAnimator;
}
public void startShowUp() {
- mShowUpAnimation.start();
+ mShowUpAnimator.start();
}
public void startDismiss() {
- if (mShowUpAnimation.isRunning()) {
- mShowUpAnimation.addListener(this);
+ if (mShowUpAnimator.isRunning()) {
+ mShowUpAnimator.addListener(this);
return;
}
- mDismissAnimation.start();
+ mDismissAnimator.start();
}
@Override
- public void onAnimationEnd(final Animator animation) {
- mDismissAnimation.start();
+ public void onAnimationEnd(final Animator animator) {
+ mDismissAnimator.start();
}
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java
index 68c9831fa..5ed39f986 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java
@@ -16,8 +16,14 @@
package com.android.inputmethod.keyboard.internal;
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.content.res.TypedArray;
import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
import com.android.inputmethod.latin.R;
@@ -26,10 +32,15 @@ public final class KeyPreviewDrawParams {
public final int mPreviewOffset;
public final int mPreviewHeight;
public final int mPreviewBackgroundResId;
+ private final int mShowUpAnimatorResId;
+ private final int mDismissAnimatorResId;
+ private boolean mHasCustomAnimationParams;
private int mShowUpDuration;
private int mDismissDuration;
- private float mShowUpStartScale;
- private float mDismissEndScale;
+ private float mShowUpStartXScale;
+ private float mShowUpStartYScale;
+ private float mDismissEndXScale;
+ private float mDismissEndYScale;
private int mLingerTimeout;
private boolean mShowPopup = true;
@@ -67,6 +78,10 @@ public final class KeyPreviewDrawParams {
R.styleable.MainKeyboardView_keyPreviewBackground, 0);
mLingerTimeout = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_keyPreviewLingerTimeout, 0);
+ mShowUpAnimatorResId = mainKeyboardViewAttr.getResourceId(
+ R.styleable.MainKeyboardView_keyPreviewShowUpAnimator, 0);
+ mDismissAnimatorResId = mainKeyboardViewAttr.getResourceId(
+ R.styleable.MainKeyboardView_keyPreviewDismissAnimator, 0);
}
public void setVisibleOffset(final int previewVisibleOffset) {
@@ -112,27 +127,62 @@ public final class KeyPreviewDrawParams {
return mLingerTimeout;
}
- public void setAnimationParams(final float showUpStartScale, final int showUpDuration,
- final float dismissEndScale, final int dismissDuration) {
- mShowUpStartScale = showUpStartScale;
+ public void setAnimationParams(final boolean hasCustomAnimationParams,
+ final float showUpStartXScale, final float showUpStartYScale, final int showUpDuration,
+ final float dismissEndXScale, final float dismissEndYScale, final int dismissDuration) {
+ mHasCustomAnimationParams = hasCustomAnimationParams;
+ mShowUpStartXScale = showUpStartXScale;
+ mShowUpStartYScale = showUpStartYScale;
mShowUpDuration = showUpDuration;
- mDismissEndScale = dismissEndScale;
+ mDismissEndXScale = dismissEndXScale;
+ mDismissEndYScale = dismissEndYScale;
mDismissDuration = dismissDuration;
}
- public float getShowUpStartScale() {
- return mShowUpStartScale;
+ private static final float KEY_PREVIEW_SHOW_UP_END_SCALE = 1.0f;
+ private static final AccelerateInterpolator ACCELERATE_INTERPOLATOR =
+ new AccelerateInterpolator();
+ private static final DecelerateInterpolator DECELERATE_INTERPOLATOR =
+ new DecelerateInterpolator();
+
+ public Animator createShowUpAnimator(final View target) {
+ if (mHasCustomAnimationParams) {
+ final ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(
+ target, View.SCALE_X, mShowUpStartXScale,
+ KEY_PREVIEW_SHOW_UP_END_SCALE);
+ final ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(
+ target, View.SCALE_Y, mShowUpStartYScale,
+ KEY_PREVIEW_SHOW_UP_END_SCALE);
+ final AnimatorSet showUpAnimator = new AnimatorSet();
+ showUpAnimator.play(scaleXAnimator).with(scaleYAnimator);
+ showUpAnimator.setDuration(mShowUpDuration);
+ showUpAnimator.setInterpolator(DECELERATE_INTERPOLATOR);
+ return showUpAnimator;
+ }
+ final Animator animator = AnimatorInflater.loadAnimator(
+ target.getContext(), mShowUpAnimatorResId);
+ animator.setTarget(target);
+ animator.setInterpolator(DECELERATE_INTERPOLATOR);
+ return animator;
}
- public int getShowUpDuration() {
- return mShowUpDuration;
- }
-
- public float getDismissEndScale() {
- return mDismissEndScale;
- }
-
- public int getDismissDuration() {
- return mDismissDuration;
+ public Animator createDismissAnimator(final View target) {
+ if (mHasCustomAnimationParams) {
+ final ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(
+ target, View.SCALE_X, mDismissEndXScale);
+ final ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(
+ target, View.SCALE_Y, mDismissEndYScale);
+ final AnimatorSet dismissAnimator = new AnimatorSet();
+ dismissAnimator.play(scaleXAnimator).with(scaleYAnimator);
+ final int dismissDuration = Math.min(mDismissDuration, mLingerTimeout);
+ dismissAnimator.setDuration(dismissDuration);
+ dismissAnimator.setInterpolator(ACCELERATE_INTERPOLATOR);
+ return dismissAnimator;
+ }
+ final Animator animator = AnimatorInflater.loadAnimator(
+ target.getContext(), mDismissAnimatorResId);
+ animator.setTarget(target);
+ animator.setInterpolator(ACCELERATE_INTERPOLATOR);
+ return animator;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index 8bff27574..fa4192790 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -31,6 +31,7 @@ import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.keyboard.KeyboardTheme;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.ResourceUtils;
@@ -643,6 +644,9 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
final boolean keyboardLayoutSetElementMatched = matchTypedValue(caseAttr,
R.styleable.Keyboard_Case_keyboardLayoutSetElement, id.mElementId,
KeyboardId.elementIdToName(id.mElementId));
+ final boolean keyboardThemeMacthed = matchTypedValue(caseAttr,
+ R.styleable.Keyboard_Case_keyboardTheme, mParams.mThemeId,
+ KeyboardTheme.getKeyboardThemeName(mParams.mThemeId));
final boolean modeMatched = matchTypedValue(caseAttr,
R.styleable.Keyboard_Case_mode, id.mMode, KeyboardId.modeName(id.mMode));
final boolean navigateNextMatched = matchBoolean(caseAttr,
@@ -671,19 +675,21 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
final boolean countryCodeMatched = matchString(caseAttr,
R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
final boolean selected = keyboardLayoutSetMatched && keyboardLayoutSetElementMatched
- && modeMatched && navigateNextMatched && navigatePreviousMatched
- && passwordInputMatched && clobberSettingsKeyMatched && hasShortcutKeyMatched
- && languageSwitchKeyEnabledMatched && isMultiLineMatched && imeActionMatched
- && isIconDefinedMatched && localeCodeMatched && languageCodeMatched
- && countryCodeMatched;
+ && keyboardThemeMacthed && modeMatched && navigateNextMatched
+ && navigatePreviousMatched && passwordInputMatched && clobberSettingsKeyMatched
+ && hasShortcutKeyMatched && languageSwitchKeyEnabledMatched
+ && isMultiLineMatched && imeActionMatched && isIconDefinedMatched
+ && localeCodeMatched && languageCodeMatched && countryCodeMatched;
if (DEBUG) {
- startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
+ startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
textAttr(caseAttr.getString(
R.styleable.Keyboard_Case_keyboardLayoutSet), "keyboardLayoutSet"),
textAttr(caseAttr.getString(
R.styleable.Keyboard_Case_keyboardLayoutSetElement),
"keyboardLayoutSetElement"),
+ textAttr(caseAttr.getString(
+ R.styleable.Keyboard_Case_keyboardTheme), "keyboardTheme"),
textAttr(caseAttr.getString(R.styleable.Keyboard_Case_mode), "mode"),
textAttr(caseAttr.getString(R.styleable.Keyboard_Case_imeAction),
"imeAction"),
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 36a02669d..fd1f51dd6 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -491,8 +491,9 @@ public class DictionaryFacilitator {
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) {
final Dictionaries dictionaries = mDictionaries;
- final SuggestionResults suggestionResults =
- new SuggestionResults(dictionaries.mLocale, SuggestedWords.MAX_SUGGESTIONS);
+ final SuggestionResults suggestionResults = new SuggestionResults(
+ dictionaries.mLocale, SuggestedWords.MAX_SUGGESTIONS,
+ prevWordsInfo.mPrevWordsInfo[0].mIsBeginningOfSentence);
final float[] languageWeight = new float[] { Dictionary.NOT_A_LANGUAGE_WEIGHT };
for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
final Dictionary dictionary = dictionaries.getDict(dictType);
diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java
index ebe436128..fecb0ef94 100644
--- a/java/src/com/android/inputmethod/latin/InputAttributes.java
+++ b/java/src/com/android/inputmethod/latin/InputAttributes.java
@@ -42,6 +42,7 @@ public final class InputAttributes {
final public boolean mApplicationSpecifiedCompletionOn;
final public boolean mShouldInsertSpacesAutomatically;
final public boolean mShouldShowVoiceInputKey;
+ final public boolean mIsGeneralTextInput;
final private int mInputType;
final private EditorInfo mEditorInfo;
final private String mPackageNameForPrivateImeOptions;
@@ -76,6 +77,7 @@ public final class InputAttributes {
mApplicationSpecifiedCompletionOn = false;
mShouldInsertSpacesAutomatically = false;
mShouldShowVoiceInputKey = false;
+ mIsGeneralTextInput = false;
return;
}
// inputClass == InputType.TYPE_CLASS_TEXT
@@ -102,7 +104,7 @@ public final class InputAttributes {
mShouldInsertSpacesAutomatically = InputTypeUtils.isAutoSpaceFriendlyType(inputType);
final boolean noMicrophone = mIsPasswordField
- || InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS == variation
+ || InputTypeUtils.isEmailVariation(variation)
|| InputType.TYPE_TEXT_VARIATION_URI == variation
|| hasNoMicrophoneKeyOption();
mShouldShowVoiceInputKey = !noMicrophone;
@@ -117,6 +119,15 @@ public final class InputAttributes {
|| (!flagAutoCorrect && !flagMultiLine);
mApplicationSpecifiedCompletionOn = flagAutoComplete && isFullscreenMode;
+
+ // If we come here, inputClass is always TYPE_CLASS_TEXT
+ mIsGeneralTextInput = InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS != variation
+ && InputType.TYPE_TEXT_VARIATION_PASSWORD != variation
+ && InputType.TYPE_TEXT_VARIATION_PHONETIC != variation
+ && InputType.TYPE_TEXT_VARIATION_URI != variation
+ && InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD != variation
+ && InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS != variation
+ && InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD != variation;
}
public boolean isTypeNull() {
diff --git a/java/src/com/android/inputmethod/latin/InputView.java b/java/src/com/android/inputmethod/latin/InputView.java
index e9e12f09f..7fa935413 100644
--- a/java/src/com/android/inputmethod/latin/InputView.java
+++ b/java/src/com/android/inputmethod/latin/InputView.java
@@ -21,14 +21,14 @@ import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
-import android.widget.LinearLayout;
+import android.widget.FrameLayout;
import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.latin.suggestions.MoreSuggestionsView;
import com.android.inputmethod.latin.suggestions.SuggestionStripView;
-public final class InputView extends LinearLayout {
+public final class InputView extends FrameLayout {
private final Rect mInputViewRect = new Rect();
private MainKeyboardView mMainKeyboardView;
private KeyboardTopPaddingForwarder mKeyboardTopPaddingForwarder;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index aebc7101a..d57db8e9a 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -29,7 +29,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.net.ConnectivityManager;
@@ -43,21 +42,22 @@ import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.SparseArray;
+import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
+import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodSubtype;
+import android.widget.TextView;
import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper;
-import com.android.inputmethod.compat.InputConnectionCompatUtils;
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
import com.android.inputmethod.event.Event;
@@ -69,6 +69,7 @@ import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.MainKeyboardView;
+import com.android.inputmethod.keyboard.TextDecoratorUi;
import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.DebugFlags;
@@ -86,6 +87,7 @@ import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor;
import com.android.inputmethod.latin.utils.ApplicationUtils;
import com.android.inputmethod.latin.utils.CapsModeUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
+import com.android.inputmethod.latin.utils.CursorAnchorInfoUtils;
import com.android.inputmethod.latin.utils.DialogUtils;
import com.android.inputmethod.latin.utils.DistracterFilterCheckingExactMatchesAndSuggestions;
import com.android.inputmethod.latin.utils.ImportantNoticeUtils;
@@ -94,6 +96,7 @@ import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
import com.android.inputmethod.latin.utils.StatsUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
+import com.android.inputmethod.latin.utils.ViewLayoutUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -150,15 +153,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: Move these {@link View}s to {@link KeyboardSwitcher}.
private View mInputView;
- private View mExtractArea;
- private View mKeyPreviewBackingView;
private SuggestionStripView mSuggestionStripView;
+ private TextView mExtractEditText;
private RichInputMethodManager mRichImm;
@UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
private final SubtypeSwitcher mSubtypeSwitcher;
private final SubtypeState mSubtypeState = new SubtypeState();
private final SpecialKeyDetector mSpecialKeyDetector;
+ // Working variable for {@link #startShowingInputView()} and
+ // {@link #onEvaluateInputViewShown()}.
+ private boolean mIsExecutingStartShowingInputView;
// Object for reacting to adding/removing a dictionary pack.
private final BroadcastReceiver mDictionaryPackInstallReceiver =
@@ -206,10 +211,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
final Resources res = latinIme.getResources();
- mDelayInMillisecondsToUpdateSuggestions =
- res.getInteger(R.integer.config_delay_in_milliseconds_to_update_suggestions);
- mDelayInMillisecondsToUpdateShiftState =
- res.getInteger(R.integer.config_delay_in_milliseconds_to_update_shift_state);
+ mDelayInMillisecondsToUpdateSuggestions = res.getInteger(
+ R.integer.config_delay_in_milliseconds_to_update_suggestions);
+ mDelayInMillisecondsToUpdateShiftState = res.getInteger(
+ R.integer.config_delay_in_milliseconds_to_update_shift_state);
}
@Override
@@ -258,7 +263,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
case MSG_RESET_CACHES:
final SettingsValues settingsValues = latinIme.mSettings.getCurrent();
if (latinIme.mInputLogic.retryResetCachesAndReturnSuccess(
- msg.arg1 == 1 /* tryResumeSuggestions */,
+ msg.arg1 == ARG1_TRUE /* tryResumeSuggestions */,
msg.arg2 /* remainingTries */, this /* handler */)) {
// If we were able to reset the caches, then we can reload the keyboard.
// Otherwise, we'll do it when we can.
@@ -689,11 +694,27 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onConfigurationChanged(final Configuration conf) {
- final SettingsValues settingsValues = mSettings.getCurrent();
+ SettingsValues settingsValues = mSettings.getCurrent();
if (settingsValues.mDisplayOrientation != conf.orientation) {
mHandler.startOrientationChanging();
mInputLogic.onOrientationChange(mSettings.getCurrent());
}
+ if (settingsValues.mHasHardwareKeyboard != Settings.readHasHardwareKeyboard(conf)) {
+ // If the state of having a hardware keyboard changed, then we want to reload the
+ // settings to adjust for that.
+ // TODO: we should probably do this unconditionally here, rather than only when we
+ // have a change in hardware keyboard configuration.
+ loadSettings();
+ settingsValues = mSettings.getCurrent();
+ if (settingsValues.mHasHardwareKeyboard) {
+ // We call cleanupInternalStateForFinishInput() because it's the right thing to do;
+ // however, it seems at the moment the framework is passing us a seemingly valid
+ // but actually non-functional InputConnection object. So if this bug ever gets
+ // fixed we'll be able to remove the composition, but until it is this code is
+ // actually not doing much.
+ cleanupInternalStateForFinishInput();
+ }
+ }
// TODO: Remove this test.
if (!conf.locale.equals(mPersonalizationDictionaryUpdater.getLocale())) {
refreshPersonalizationDictionarySession(settingsValues);
@@ -710,13 +731,54 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void setInputView(final View view) {
super.setInputView(view);
mInputView = view;
- mExtractArea = getWindow().getWindow().getDecorView()
- .findViewById(android.R.id.extractArea);
- mKeyPreviewBackingView = view.findViewById(R.id.key_preview_backing);
mSuggestionStripView = (SuggestionStripView)view.findViewById(R.id.suggestion_strip_view);
if (hasSuggestionStripView()) {
mSuggestionStripView.setListener(this, view);
}
+ mInputLogic.setTextDecoratorUi(new TextDecoratorUi(this, view));
+ }
+
+ @Override
+ public void setExtractView(final View view) {
+ final TextView prevExtractEditText = mExtractEditText;
+ super.setExtractView(view);
+ TextView nextExtractEditText = null;
+ if (view != null) {
+ final View extractEditText = view.findViewById(android.R.id.inputExtractEditText);
+ if (extractEditText instanceof TextView) {
+ nextExtractEditText = (TextView)extractEditText;
+ }
+ }
+ if (prevExtractEditText == nextExtractEditText) {
+ return;
+ }
+ if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK && prevExtractEditText != null) {
+ prevExtractEditText.getViewTreeObserver().removeOnPreDrawListener(
+ mExtractTextViewPreDrawListener);
+ }
+ mExtractEditText = nextExtractEditText;
+ if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK && mExtractEditText != null) {
+ mExtractEditText.getViewTreeObserver().addOnPreDrawListener(
+ mExtractTextViewPreDrawListener);
+ }
+ }
+
+ private final ViewTreeObserver.OnPreDrawListener mExtractTextViewPreDrawListener =
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ onExtractTextViewPreDraw();
+ return true;
+ }
+ };
+
+ private void onExtractTextViewPreDraw() {
+ if (!ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK || !isFullscreenMode()
+ || mExtractEditText == null) {
+ return;
+ }
+ final CursorAnchorInfo info = CursorAnchorInfoUtils.getCursorAnchorInfo(mExtractEditText);
+ mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.fromObject(info));
}
@Override
@@ -750,20 +812,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged()
// is not guaranteed. It may even be called at the same time on a different thread.
mSubtypeSwitcher.onSubtypeChanged(subtype);
- mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype));
+ mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype),
+ mSettings.getCurrent());
loadKeyboard();
}
private void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) {
super.onStartInput(editorInfo, restarting);
- if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) {
- // AcceptTypedWord feature relies on CursorAnchorInfo.
- if (mSettings.getCurrent().mShouldShowUiToAcceptTypedWord) {
- InputConnectionCompatUtils.requestUpdateCursorAnchorInfo(
- getCurrentInputConnection(), true /* enableMonitor */,
- true /* requestImmediateCallback */);
- }
- }
}
@SuppressWarnings("deprecation")
@@ -828,39 +883,52 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Note: This call should be done by InputMethodService?
updateFullscreenMode();
- // The app calling setText() has the effect of clearing the composing
- // span, so we should reset our state unconditionally, even if restarting is true.
- // We also tell the input logic about the combining rules for the current subtype, so
- // it can adjust its combiners if needed.
- mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype());
+ // ALERT: settings have not been reloaded and there is a chance they may be stale.
+ // In the practice, if it is, we should have gotten onConfigurationChanged so it should
+ // be fine, but this is horribly confusing and must be fixed AS SOON AS POSSIBLE.
- // Note: the following does a round-trip IPC on the main thread: be careful
- final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
+ // In some cases the input connection has not been reset yet and we can't access it. In
+ // this case we will need to call loadKeyboard() later, when it's accessible, so that we
+ // can go into the correct mode, so we need to do some housekeeping here.
+ final boolean needToCallLoadKeyboardLater;
final Suggest suggest = mInputLogic.mSuggest;
- if (null != currentLocale && !currentLocale.equals(suggest.getLocale())) {
- // TODO: Do this automatically.
- resetSuggest();
- }
+ if (!currentSettingsValues.mHasHardwareKeyboard) {
+ // The app calling setText() has the effect of clearing the composing
+ // span, so we should reset our state unconditionally, even if restarting is true.
+ // We also tell the input logic about the combining rules for the current subtype, so
+ // it can adjust its combiners if needed.
+ mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype(),
+ currentSettingsValues);
+
+ // Note: the following does a round-trip IPC on the main thread: be careful
+ final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
+ if (null != currentLocale && !currentLocale.equals(suggest.getLocale())) {
+ // TODO: Do this automatically.
+ resetSuggest();
+ }
- // TODO[IL]: Can the following be moved to InputLogic#startInput?
- final boolean canReachInputConnection;
- if (!mInputLogic.mConnection.resetCachesUponCursorMoveAndReturnSuccess(
- editorInfo.initialSelStart, editorInfo.initialSelEnd,
- false /* shouldFinishComposition */)) {
- // Sometimes, while rotating, for some reason the framework tells the app we are not
- // connected to it and that means we can't refresh the cache. In this case, schedule a
- // refresh later.
- // We try resetting the caches up to 5 times before giving up.
- mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */);
- // mLastSelection{Start,End} are reset later in this method, don't need to do it here
- canReachInputConnection = false;
+ // TODO[IL]: Can the following be moved to InputLogic#startInput?
+ if (!mInputLogic.mConnection.resetCachesUponCursorMoveAndReturnSuccess(
+ editorInfo.initialSelStart, editorInfo.initialSelEnd,
+ false /* shouldFinishComposition */)) {
+ // Sometimes, while rotating, for some reason the framework tells the app we are not
+ // connected to it and that means we can't refresh the cache. In this case, schedule
+ // a refresh later.
+ // We try resetting the caches up to 5 times before giving up.
+ mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */);
+ // mLastSelection{Start,End} are reset later in this method, no need to do it here
+ needToCallLoadKeyboardLater = true;
+ } else {
+ // When rotating, initialSelStart and initialSelEnd sometimes are lying. Make a best
+ // effort to work around this bug.
+ mInputLogic.mConnection.tryFixLyingCursorPosition();
+ mHandler.postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */,
+ true /* shouldDelay */);
+ needToCallLoadKeyboardLater = false;
+ }
} else {
- // When rotating, initialSelStart and initialSelEnd sometimes are lying. Make a best
- // effort to work around this bug.
- mInputLogic.mConnection.tryFixLyingCursorPosition();
- mHandler.postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */,
- true /* shouldDelay */);
- canReachInputConnection = true;
+ // If we have a hardware keyboard we don't need to call loadKeyboard later anyway.
+ needToCallLoadKeyboardLater = false;
}
if (isDifferentTextField ||
@@ -878,9 +946,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
switcher.loadKeyboard(editorInfo, currentSettingsValues, getCurrentAutoCapsState(),
getCurrentRecapitalizeState());
- if (!canReachInputConnection) {
- // If we can't reach the input connection, we will call loadKeyboard again later,
- // so we need to save its state now. The call will be done in #retryResetCaches.
+ if (needToCallLoadKeyboardLater) {
+ // If we need to call loadKeyboard again later, we need to save its state now. The
+ // later call will be done in #retryResetCaches.
switcher.saveKeyboardState();
}
} else if (restarting) {
@@ -937,6 +1005,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void onFinishInputViewInternal(final boolean finishingInput) {
super.onFinishInputView(finishingInput);
+ cleanupInternalStateForFinishInput();
+ }
+
+ private void cleanupInternalStateForFinishInput() {
mKeyboardSwitcher.deallocateMemory();
// Remove pending messages related to update suggestions
mHandler.cancelUpdateSuggestionStrip();
@@ -956,13 +1028,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
+ ", cs=" + composingSpanStart + ", ce=" + composingSpanEnd);
}
- // If the keyboard is not visible, we don't need to do all the housekeeping work, as it
- // will be reset when the keyboard shows up anyway.
- // TODO: revisit this when LatinIME supports hardware keyboards.
- // NOTE: the test harness subclasses LatinIME and overrides isInputViewShown().
- // TODO: find a better way to simulate actual execution.
- if (isInputViewShown() &&
- mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd)) {
+ // This call happens when we have a hardware keyboard as well as when we don't. While we
+ // don't support hardware keyboards yet we should avoid doing the processing associated
+ // with cursor movement when we have a hardware keyboard since we are not in charge.
+ final SettingsValues settingsValues = mSettings.getCurrent();
+ if ((!settingsValues.mHasHardwareKeyboard || ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED)
+ && mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
+ settingsValues)) {
mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(),
getCurrentRecapitalizeState());
}
@@ -971,11 +1043,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// We cannot mark this method as @Override until new SDK becomes publicly available.
// @Override
public void onUpdateCursorAnchorInfo(final CursorAnchorInfo info) {
- if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) {
- final CursorAnchorInfoCompatWrapper wrapper =
- CursorAnchorInfoCompatWrapper.fromObject(info);
- // TODO: Implement here
+ if (!ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK || isFullscreenMode()) {
+ return;
}
+ mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.fromObject(info));
}
/**
@@ -1057,102 +1128,67 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
setSuggestedWords(suggestedWords);
}
- private int getAdjustedBackingViewHeight() {
- final int currentHeight = mKeyPreviewBackingView.getHeight();
- if (currentHeight > 0) {
- return currentHeight;
- }
-
- final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView();
- if (visibleKeyboardView == null) {
- return 0;
- }
- // TODO: !!!!!!!!!!!!!!!!!!!! Handle different backing view heights between the main !!!
- // keyboard and the emoji keyboard. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- final int keyboardHeight = visibleKeyboardView.getHeight();
- final int suggestionsHeight = mSuggestionStripView.getHeight();
- final int displayHeight = getResources().getDisplayMetrics().heightPixels;
- final Rect rect = new Rect();
- mKeyPreviewBackingView.getWindowVisibleDisplayFrame(rect);
- final int notificationBarHeight = rect.top;
- final int remainingHeight = displayHeight - notificationBarHeight - suggestionsHeight
- - keyboardHeight;
-
- final LayoutParams params = mKeyPreviewBackingView.getLayoutParams();
- mSuggestionStripView.setMoreSuggestionsHeight(remainingHeight);
-
- // Let the backing cover the remaining region entirely.
- params.height = remainingHeight;
- mKeyPreviewBackingView.setLayoutParams(params);
- return params.height;
- }
-
@Override
public void onComputeInsets(final InputMethodService.Insets outInsets) {
super.onComputeInsets(outInsets);
+ final SettingsValues settingsValues = mSettings.getCurrent();
final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView();
if (visibleKeyboardView == null || !hasSuggestionStripView()) {
return;
}
- final boolean hasHardwareKeyboard = mKeyboardSwitcher.hasHardwareKeyboard();
+ final int inputHeight = mInputView.getHeight();
+ final boolean hasHardwareKeyboard = settingsValues.mHasHardwareKeyboard;
if (hasHardwareKeyboard && visibleKeyboardView.getVisibility() == View.GONE) {
// If there is a hardware keyboard and a visible software keyboard view has been hidden,
// no visual element will be shown on the screen.
- outInsets.touchableInsets = mInputView.getHeight();
- outInsets.visibleTopInsets = mInputView.getHeight();
+ outInsets.touchableInsets = inputHeight;
+ outInsets.visibleTopInsets = inputHeight;
return;
}
- final int adjustedBackingHeight = getAdjustedBackingViewHeight();
- final boolean backingGone = (mKeyPreviewBackingView.getVisibility() == View.GONE);
- final int backingHeight = backingGone ? 0 : adjustedBackingHeight;
- // In fullscreen mode, the height of the extract area managed by InputMethodService should
- // be considered.
- // See {@link android.inputmethodservice.InputMethodService#onComputeInsets}.
- final int extractHeight = isFullscreenMode() ? mExtractArea.getHeight() : 0;
- final int suggestionsHeight = (mSuggestionStripView.getVisibility() == View.GONE) ? 0
- : mSuggestionStripView.getHeight();
- final int extraHeight = extractHeight + backingHeight + suggestionsHeight;
- int visibleTopY = extraHeight;
- // Need to set touchable region only if input view is being shown
+ final int suggestionsHeight = (!mKeyboardSwitcher.isShowingEmojiPalettes()
+ && mSuggestionStripView.getVisibility() == View.VISIBLE)
+ ? mSuggestionStripView.getHeight() : 0;
+ final int visibleTopY = inputHeight - visibleKeyboardView.getHeight() - suggestionsHeight;
+ mSuggestionStripView.setMoreSuggestionsHeight(visibleTopY);
+ // Need to set touchable region only if a keyboard view is being shown.
if (visibleKeyboardView.isShown()) {
- // Note that the height of Emoji layout is the same as the height of the main keyboard
- // and the suggestion strip
- if (mKeyboardSwitcher.isShowingEmojiPalettes()
- || mSuggestionStripView.getVisibility() == View.VISIBLE) {
- visibleTopY -= suggestionsHeight;
- }
- final int touchY = mKeyboardSwitcher.isShowingMoreKeysPanel() ? 0 : visibleTopY;
- final int touchWidth = visibleKeyboardView.getWidth();
- final int touchHeight = visibleKeyboardView.getHeight() + extraHeight
+ final int touchLeft = 0;
+ final int touchTop = mKeyboardSwitcher.isShowingMoreKeysPanel() ? 0 : visibleTopY;
+ final int touchRight = visibleKeyboardView.getWidth();
+ final int touchBottom = inputHeight
// Extend touchable region below the keyboard.
+ EXTENDED_TOUCHABLE_REGION_HEIGHT;
outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
- outInsets.touchableRegion.set(0, touchY, touchWidth, touchHeight);
+ outInsets.touchableRegion.set(touchLeft, touchTop, touchRight, touchBottom);
}
outInsets.contentTopInsets = visibleTopY;
outInsets.visibleTopInsets = visibleTopY;
}
- @Override
- public boolean onEvaluateInputViewShown() {
- // Always show {@link InputView}.
- return true;
+ public void startShowingInputView() {
+ mIsExecutingStartShowingInputView = true;
+ // This {@link #showWindow(boolean)} will eventually call back
+ // {@link #onEvaluateInputViewShown()}.
+ showWindow(true /* showInput */);
+ mIsExecutingStartShowingInputView = false;
+ }
+
+ public void stopShowingInputView() {
+ showWindow(false /* showInput */);
}
@Override
- public boolean onShowInputRequested(final int flags, final boolean configChange) {
- if ((flags & InputMethod.SHOW_EXPLICIT) == 0 && mKeyboardSwitcher.hasHardwareKeyboard()) {
- // Even when IME is implicitly shown and physical keyboard is connected, we should
- // show {@link InputView}.
- // See {@link InputMethodService#onShowInputRequested(int,boolean)}.
+ public boolean onEvaluateInputViewShown() {
+ if (mIsExecutingStartShowingInputView) {
return true;
}
- return super.onShowInputRequested(flags, configChange);
+ return super.onEvaluateInputViewShown();
}
@Override
public boolean onEvaluateFullscreenMode() {
- if (mKeyboardSwitcher.hasHardwareKeyboard()) {
+ final SettingsValues settingsValues = mSettings.getCurrent();
+ if (settingsValues.mHasHardwareKeyboard) {
// If there is a hardware keyboard, disable full screen mode.
return false;
}
@@ -1165,19 +1201,34 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// hack for now. Let's get rid of this once the framework gets fixed.
final EditorInfo ei = getCurrentInputEditorInfo();
return !(ei != null && ((ei.imeOptions & EditorInfo.IME_FLAG_NO_EXTRACT_UI) != 0));
- } else {
- return false;
}
+ return false;
}
@Override
public void updateFullscreenMode() {
+ // Override layout parameters to expand {@link SoftInputWindow} to the entire screen.
+ // See {@link InputMethodService#setinputView(View) and
+ // {@link SoftInputWindow#updateWidthHeight(WindowManager.LayoutParams)}.
+ final Window window = getWindow().getWindow();
+ ViewLayoutUtils.updateLayoutHeightOf(window, LayoutParams.MATCH_PARENT);
+ // This method may be called before {@link #setInputView(View)}.
+ if (mInputView != null) {
+ // In non-fullscreen mode, {@link InputView} and its parent inputArea should expand to
+ // the entire screen and be placed at the bottom of {@link SoftInputWindow}.
+ // In fullscreen mode, these shouldn't expand to the entire screen and should be
+ // coexistent with {@link #mExtractedArea} above.
+ // See {@link InputMethodService#setInputView(View) and
+ // com.android.internal.R.layout.input_method.xml.
+ final int layoutHeight = isFullscreenMode()
+ ? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT;
+ final View inputArea = window.findViewById(android.R.id.inputArea);
+ ViewLayoutUtils.updateLayoutHeightOf(inputArea, layoutHeight);
+ ViewLayoutUtils.updateLayoutGravityOf(inputArea, Gravity.BOTTOM);
+ ViewLayoutUtils.updateLayoutHeightOf(mInputView, layoutHeight);
+ }
super.updateFullscreenMode();
-
- if (mKeyPreviewBackingView == null) return;
- // In fullscreen mode, no need to have extra space to show the key preview.
- // If not, we should have extra space above the keyboard to show the key preview.
- mKeyPreviewBackingView.setVisibility(isFullscreenMode() ? View.GONE : View.VISIBLE);
+ mInputLogic.onUpdateFullscreenMode(isFullscreenMode());
}
private int getCurrentAutoCapsState() {
@@ -1201,9 +1252,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (null == keyboard) {
return CoordinateUtils.newCoordinateArray(codePoints.length,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
- } else {
- return keyboard.getCoordinates(codePoints);
}
+ return keyboard.getCoordinates(codePoints);
}
// Callback for the {@link SuggestionStripView}, to call when the "add to dictionary" hint is
@@ -1221,6 +1271,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
wordToEdit = word;
}
mDictionaryFacilitator.addWordToUserDictionary(this /* context */, wordToEdit);
+ mInputLogic.onAddWordToUserDictionary();
}
// Callback for the {@link SuggestionStripView}, to call when the important notice strip is
@@ -1409,7 +1460,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void setSuggestedWords(final SuggestedWords suggestedWords) {
- mInputLogic.setSuggestedWords(suggestedWords);
+ final SettingsValues currentSettingsValues = mSettings.getCurrent();
+ mInputLogic.setSuggestedWords(suggestedWords, currentSettingsValues, mHandler);
// TODO: Modify this when we support suggestions with hard keyboard
if (!hasSuggestionStripView()) {
return;
@@ -1418,7 +1470,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
- final SettingsValues currentSettingsValues = mSettings.getCurrent();
final boolean shouldShowImportantNotice =
ImportantNoticeUtils.shouldShowImportantNotice(this);
final boolean shouldShowSuggestionCandidates =
@@ -1438,19 +1489,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final boolean isEmptyApplicationSpecifiedCompletions =
currentSettingsValues.isApplicationSpecifiedCompletionsOn()
&& suggestedWords.isEmpty();
- final boolean noSuggestionsToShow = (SuggestedWords.EMPTY == suggestedWords)
+ final boolean noSuggestionsFromDictionaries = (SuggestedWords.EMPTY == suggestedWords)
|| suggestedWords.isPunctuationSuggestions()
|| isEmptyApplicationSpecifiedCompletions;
- if (shouldShowImportantNotice && noSuggestionsToShow) {
+ final boolean isBeginningOfSentencePrediction = (suggestedWords.mInputStyle
+ == SuggestedWords.INPUT_STYLE_BEGINNING_OF_SENTENCE_PREDICTION);
+ final boolean noSuggestionsToOverrideImportantNotice = noSuggestionsFromDictionaries
+ || isBeginningOfSentencePrediction;
+ if (shouldShowImportantNotice && noSuggestionsToOverrideImportantNotice) {
if (mSuggestionStripView.maybeShowImportantNoticeTitle()) {
return;
}
}
if (currentSettingsValues.isSuggestionsEnabledPerUserSettings()
- // We should clear suggestions if there is no suggestion to show.
- || noSuggestionsToShow
- || currentSettingsValues.isApplicationSpecifiedCompletionsOn()) {
+ || currentSettingsValues.isApplicationSpecifiedCompletionsOn()
+ // We should clear the contextual strip if there is no suggestion from dictionaries.
+ || noSuggestionsFromDictionaries) {
mSuggestionStripView.setSuggestions(suggestedWords,
SubtypeLocaleUtils.isRtlLanguage(mSubtypeSwitcher.getCurrentSubtype()));
}
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 035557610..744b0321a 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -30,7 +30,9 @@ import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
+import com.android.inputmethod.compat.InputConnectionCompatUtils;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.CapsModeUtils;
import com.android.inputmethod.latin.utils.DebugLogUtils;
@@ -250,7 +252,7 @@ public final class RichInputConnection {
* See {@link InputConnection#commitText(CharSequence, int)}.
*/
public void commitText(final CharSequence text, final int newCursorPosition) {
- commitTextWithBackgroundColor(text, newCursorPosition, Color.TRANSPARENT);
+ commitTextWithBackgroundColor(text, newCursorPosition, Color.TRANSPARENT, text.length());
}
/**
@@ -263,9 +265,11 @@ public final class RichInputConnection {
* the background color. Note that this method specifies {@link BackgroundColorSpan} with
* {@link Spanned#SPAN_COMPOSING} flag, meaning that the background color persists until
* {@link #finishComposingText()} is called.
+ * @param coloredTextLength the length of text, in Java chars, which should be rendered with
+ * the given background color.
*/
public void commitTextWithBackgroundColor(final CharSequence text, final int newCursorPosition,
- final int color) {
+ final int color, final int coloredTextLength) {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
mCommittedTextBeforeComposingText.append(text);
@@ -283,7 +287,8 @@ public final class RichInputConnection {
mTempObjectForCommitText.clear();
mTempObjectForCommitText.append(text);
final BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(color);
- mTempObjectForCommitText.setSpan(backgroundColorSpan, 0, text.length(),
+ final int spanLength = Math.min(coloredTextLength, text.length());
+ mTempObjectForCommitText.setSpan(backgroundColorSpan, 0, spanLength,
Spanned.SPAN_COMPOSING | Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mIC.commitText(mTempObjectForCommitText, newCursorPosition);
mLastCommittedTextHasBackgroundColor = true;
@@ -621,14 +626,24 @@ public final class RichInputConnection {
return Arrays.binarySearch(sortedSeparators, code) >= 0;
}
+ private static boolean isPartOfCompositionForScript(final int codePoint,
+ final SpacingAndPunctuations spacingAndPunctuations, final int scriptId) {
+ // We always consider word connectors part of compositions.
+ return spacingAndPunctuations.isWordConnector(codePoint)
+ // Otherwise, it's part of composition if it's part of script and not a separator.
+ || (!spacingAndPunctuations.isWordSeparator(codePoint)
+ && ScriptUtils.isLetterPartOfScript(codePoint, scriptId));
+ }
+
/**
* Returns the text surrounding the cursor.
*
- * @param sortedSeparators a sorted array of code points that split words.
+ * @param spacingAndPunctuations the rules for spacing and punctuation
* @param scriptId the script we consider to be writing words, as one of ScriptUtils.SCRIPT_*
* @return a range containing the text surrounding the cursor
*/
- public TextRange getWordRangeAtCursor(final int[] sortedSeparators, final int scriptId) {
+ public TextRange getWordRangeAtCursor(final SpacingAndPunctuations spacingAndPunctuations,
+ final int scriptId) {
mIC = mParent.getCurrentInputConnection();
if (mIC == null) {
return null;
@@ -645,8 +660,7 @@ public final class RichInputConnection {
int startIndexInBefore = before.length();
while (startIndexInBefore > 0) {
final int codePoint = Character.codePointBefore(before, startIndexInBefore);
- if (isSeparator(codePoint, sortedSeparators)
- || !ScriptUtils.isLetterPartOfScript(codePoint, scriptId)) {
+ if (!isPartOfCompositionForScript(codePoint, spacingAndPunctuations, scriptId)) {
break;
}
--startIndexInBefore;
@@ -659,8 +673,7 @@ public final class RichInputConnection {
int endIndexInAfter = -1;
while (++endIndexInAfter < after.length()) {
final int codePoint = Character.codePointAt(after, endIndexInAfter);
- if (isSeparator(codePoint, sortedSeparators)
- || !ScriptUtils.isLetterPartOfScript(codePoint, scriptId)) {
+ if (!isPartOfCompositionForScript(codePoint, spacingAndPunctuations, scriptId)) {
break;
}
if (Character.isSupplementaryCodePoint(codePoint)) {
@@ -906,4 +919,39 @@ public final class RichInputConnection {
mIC.setSelection(mExpectedSelStart, mExpectedSelEnd);
}
}
+
+ private boolean mCursorAnchorInfoMonitorEnabled = false;
+
+ /**
+ * Requests the editor to call back {@link InputMethodManager#updateCursorAnchorInfo}.
+ * @param enableMonitor {@code true} to request the editor to call back the method whenever the
+ * cursor/anchor position is changed.
+ * @param requestImmediateCallback {@code true} to request the editor to call back the method
+ * as soon as possible to notify the current cursor/anchor position to the input method.
+ * @return {@code true} if the request is accepted. Returns {@code false} otherwise, which
+ * includes "not implemented" or "rejected" or "temporarily unavailable" or whatever which
+ * prevents the application from fulfilling the request. (TODO: Improve the API when it turns
+ * out that we actually need more detailed error codes)
+ */
+ public boolean requestCursorUpdates(final boolean enableMonitor,
+ final boolean requestImmediateCallback) {
+ mIC = mParent.getCurrentInputConnection();
+ final boolean scheduled;
+ if (null != mIC) {
+ scheduled = InputConnectionCompatUtils.requestCursorUpdates(mIC, enableMonitor,
+ requestImmediateCallback);
+ } else {
+ scheduled = false;
+ }
+ mCursorAnchorInfoMonitorEnabled = (scheduled && enableMonitor);
+ return scheduled;
+ }
+
+ /**
+ * @return {@code true} if the application reported that the monitor mode of
+ * {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} is currently enabled.
+ */
+ public boolean isCursorAnchorInfoMonitorEnabled() {
+ return mCursorAnchorInfoMonitorEnabled;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 6779351fd..b03818c1d 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -186,8 +186,14 @@ public final class Suggest {
suggestionsList = suggestionsContainer;
}
- final int inputStyle = resultsArePredictions ? SuggestedWords.INPUT_STYLE_PREDICTION :
- inputStyleIfNotPrediction;
+ final int inputStyle;
+ if (resultsArePredictions) {
+ inputStyle = suggestionResults.mIsBeginningOfSentence
+ ? SuggestedWords.INPUT_STYLE_BEGINNING_OF_SENTENCE_PREDICTION
+ : SuggestedWords.INPUT_STYLE_PREDICTION;
+ } else {
+ inputStyle = inputStyleIfNotPrediction;
+ }
callback.onGetSuggestedWords(new SuggestedWords(suggestionsList,
suggestionResults.mRawSuggestions,
// TODO: this first argument is lying. If this is a whitelisted word which is an
@@ -240,6 +246,8 @@ public final class Suggest {
// In the batch input mode, the most relevant suggested word should act as a "typed word"
// (typedWordValid=true), not as an "auto correct word" (willAutoCorrect=false).
+ // Note that because this method is never used to get predictions, there is no need to
+ // modify inputType such in getSuggestedWordsForNonBatchInput.
callback.onGetSuggestedWords(new SuggestedWords(suggestionsContainer,
suggestionResults.mRawSuggestions,
true /* typedWordValid */,
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 1eebabece..1d221b77f 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -39,6 +39,7 @@ public class SuggestedWords {
public static final int INPUT_STYLE_APPLICATION_SPECIFIED = 4;
public static final int INPUT_STYLE_RECORRECTION = 5;
public static final int INPUT_STYLE_PREDICTION = 6;
+ public static final int INPUT_STYLE_BEGINNING_OF_SENTENCE_PREDICTION = 7;
// The maximum number of suggestions available.
public static final int MAX_SUGGESTIONS = 18;
@@ -80,10 +81,9 @@ public class SuggestedWords {
final int inputStyle,
final int sequenceNumber) {
this(suggestedWordInfoList, rawSuggestions,
- (suggestedWordInfoList.isEmpty() || INPUT_STYLE_PREDICTION == inputStyle) ? null
+ (suggestedWordInfoList.isEmpty() || isPrediction(inputStyle)) ? null
: suggestedWordInfoList.get(INDEX_OF_TYPED_WORD).mWord,
- typedWordValid, willAutoCorrect, isObsoleteSuggestions, inputStyle,
- sequenceNumber);
+ typedWordValid, willAutoCorrect, isObsoleteSuggestions, inputStyle, sequenceNumber);
}
public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList,
@@ -171,6 +171,7 @@ public class SuggestedWords {
return "SuggestedWords:"
+ " mTypedWordValid=" + mTypedWordValid
+ " mWillAutoCorrect=" + mWillAutoCorrect
+ + " mInputStyle=" + mInputStyle
+ " words=" + Arrays.toString(mSuggestedWordInfoList.toArray());
}
@@ -377,8 +378,13 @@ public class SuggestedWords {
}
}
+ private static boolean isPrediction(final int inputStyle) {
+ return INPUT_STYLE_PREDICTION == inputStyle
+ || INPUT_STYLE_BEGINNING_OF_SENTENCE_PREDICTION == inputStyle;
+ }
+
public boolean isPrediction() {
- return INPUT_STYLE_PREDICTION == mInputStyle;
+ return isPrediction(mInputStyle);
}
// SuggestedWords is an immutable object, as much as possible. We must not just remove
@@ -429,7 +435,7 @@ public class SuggestedWords {
*/
@UsedForTesting
public SuggestedWordInfo getTypedWordInfoOrNull() {
- if (this == EMPTY) {
+ if (SuggestedWords.INDEX_OF_TYPED_WORD >= size()) {
return null;
}
final SuggestedWordInfo info = getInfo(SuggestedWords.INDEX_OF_TYPED_WORD);
diff --git a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
index e4ee42660..123ab208c 100644
--- a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
+++ b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
@@ -17,21 +17,16 @@
package com.android.inputmethod.latin;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
import android.os.Process;
-import android.preference.PreferenceManager;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.compat.IntentCompatUtils;
-import com.android.inputmethod.latin.settings.Settings;
+import com.android.inputmethod.keyboard.KeyboardLayoutSet;
import com.android.inputmethod.latin.setup.LauncherIconVisibilityManager;
-import com.android.inputmethod.latin.setup.SetupActivity;
import com.android.inputmethod.latin.utils.UncachedInputMethodManagerUtils;
/**
@@ -58,6 +53,9 @@ import com.android.inputmethod.latin.utils.UncachedInputMethodManagerUtils;
* When a multiuser account has been created, {@link Intent#ACTION_USER_INITIALIZE} is received
* by this receiver and it checks the whether the setup wizard's icon should be appeared or not on
* the launcher depending on which partition this IME is installed.
+ *
+ * When the system locale has been changed, {@link Intent#ACTION_LOCALE_CHANGED} is received by
+ * this receiver and the {@link KeyboardLayoutSet}'s cache is cleared.
*/
public final class SystemBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = SystemBroadcastReceiver.class.getSimpleName();
@@ -67,21 +65,22 @@ public final class SystemBroadcastReceiver extends BroadcastReceiver {
final String intentAction = intent.getAction();
if (Intent.ACTION_MY_PACKAGE_REPLACED.equals(intentAction)) {
Log.i(TAG, "Package has been replaced: " + context.getPackageName());
- } else if (Intent.ACTION_BOOT_COMPLETED.equals(intentAction)) {
- Log.i(TAG, "Boot has been completed");
- } else if (IntentCompatUtils.is_ACTION_USER_INITIALIZE(intentAction)) {
- Log.i(TAG, "User initialize");
- }
-
- LauncherIconVisibilityManager.onReceiveGlobalIntent(intentAction, context);
-
- if (Intent.ACTION_MY_PACKAGE_REPLACED.equals(intentAction)) {
// Need to restore additional subtypes because system always clears additional
// subtypes when the package is replaced.
RichInputMethodManager.init(context);
final RichInputMethodManager richImm = RichInputMethodManager.getInstance();
final InputMethodSubtype[] additionalSubtypes = richImm.getAdditionalSubtypes(context);
richImm.setAdditionalInputMethodSubtypes(additionalSubtypes);
+ LauncherIconVisibilityManager.updateSetupWizardIconVisibility(context);
+ } else if (Intent.ACTION_BOOT_COMPLETED.equals(intentAction)) {
+ Log.i(TAG, "Boot has been completed");
+ LauncherIconVisibilityManager.updateSetupWizardIconVisibility(context);
+ } else if (IntentCompatUtils.is_ACTION_USER_INITIALIZE(intentAction)) {
+ Log.i(TAG, "User initialize");
+ LauncherIconVisibilityManager.updateSetupWizardIconVisibility(context);
+ } else if (Intent.ACTION_LOCALE_CHANGED.equals(intentAction)) {
+ Log.i(TAG, "System locale changed");
+ KeyboardLayoutSet.onSystemLocaleChanged();
}
// The process that hosts this broadcast receiver is invoked and remains alive even after
diff --git a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
index 7071d8689..a87785b1a 100644
--- a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
+++ b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
@@ -168,7 +168,7 @@ public class ExternalDictionaryGetterForDebug {
} catch (IOException e) {
// There was an error: show a dialog
new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context))
- .setTitle(R.string.error)
+ .setTitle(R.string.read_external_dictionary_error)
.setMessage(e.toString())
.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index a6978809a..fdab7f25f 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -17,21 +17,28 @@
package com.android.inputmethod.latin.inputlogic;
import android.graphics.Color;
+import android.inputmethodservice.InputMethodService;
import android.os.SystemClock;
import android.text.SpannableString;
+import android.text.Spanned;
import android.text.TextUtils;
+import android.text.style.BackgroundColorSpan;
import android.text.style.SuggestionSpan;
import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.inputmethod.CorrectionInfo;
+import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;
+import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper;
import com.android.inputmethod.compat.SuggestionSpanUtils;
import com.android.inputmethod.event.Event;
import com.android.inputmethod.event.InputTransaction;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.keyboard.TextDecorator;
+import com.android.inputmethod.keyboard.TextDecoratorUiOperator;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.DictionaryFacilitator;
@@ -46,6 +53,7 @@ import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.define.DebugFlags;
+import com.android.inputmethod.latin.define.ProductionFlags;
import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
@@ -81,6 +89,14 @@ public final class InputLogic {
public final Suggest mSuggest;
private final DictionaryFacilitator mDictionaryFacilitator;
+ private final TextDecorator mTextDecorator = new TextDecorator(new TextDecorator.Listener() {
+ @Override
+ public void onClickComposingTextToAddToDictionary(final String word) {
+ mLatinIME.addWordToUserDictionary(word);
+ mLatinIME.dismissAddToDictionaryHint();
+ }
+ });
+
public LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
// This has package visibility so it can be accessed from InputLogicHandler.
/* package */ final WordComposer mWordComposer;
@@ -124,8 +140,9 @@ public final class InputLogic {
* Call this when input starts or restarts in some editor (typically, in onStartInputView).
*
* @param combiningSpec the combining spec string for this subtype
+ * @param settingsValues the current settings values
*/
- public void startInput(final String combiningSpec) {
+ public void startInput(final String combiningSpec, final SettingsValues settingsValues) {
mEnteredText = null;
mWordComposer.restartCombining(combiningSpec);
resetComposingState(true /* alsoResetLastComposedWord */);
@@ -143,15 +160,25 @@ public final class InputLogic {
} else {
mInputLogicHandler.reset();
}
+
+ if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) {
+ // AcceptTypedWord feature relies on CursorAnchorInfo.
+ if (settingsValues.mShouldShowUiToAcceptTypedWord) {
+ mConnection.requestCursorUpdates(true /* enableMonitor */,
+ true /* requestImmediateCallback */);
+ }
+ mTextDecorator.reset();
+ }
}
/**
* Call this when the subtype changes.
* @param combiningSpec the spec string for the combining rules
+ * @param settingsValues the current settings values
*/
- public void onSubtypeChanged(final String combiningSpec) {
+ public void onSubtypeChanged(final String combiningSpec, final SettingsValues settingsValues) {
finishInput();
- startInput(combiningSpec);
+ startInput(combiningSpec, settingsValues);
}
/**
@@ -303,8 +330,9 @@ public final class InputLogic {
return inputTransaction;
}
- commitChosenWord(settingsValues, suggestion,
- LastComposedWord.COMMIT_TYPE_MANUAL_PICK, LastComposedWord.NOT_A_SEPARATOR);
+ final boolean shouldShowAddToDictionaryHint = shouldShowAddToDictionaryHint(suggestionInfo);
+ commitChosenWord(settingsValues, suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK,
+ LastComposedWord.NOT_A_SEPARATOR);
mConnection.endBatchEdit();
// Don't allow cancellation of manual pick
mLastComposedWord.deactivate();
@@ -312,7 +340,7 @@ public final class InputLogic {
mSpaceState = SpaceState.PHANTOM;
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
- if (shouldShowAddToDictionaryHint(suggestionInfo)) {
+ if (shouldShowAddToDictionaryHint) {
mSuggestionStripViewAccessor.showAddToDictionaryHint(suggestion);
} else {
// If we're not showing the "Touch again to save", then update the suggestion strip.
@@ -330,10 +358,11 @@ public final class InputLogic {
* @param oldSelEnd old selection end
* @param newSelStart new selection start
* @param newSelEnd new selection end
+ * @param settingsValues the current values of the settings.
* @return whether the cursor has moved as a result of user interaction.
*/
public boolean onUpdateSelection(final int oldSelStart, final int oldSelEnd,
- final int newSelStart, final int newSelEnd) {
+ final int newSelStart, final int newSelEnd, final SettingsValues settingsValues) {
if (mConnection.isBelatedExpectedUpdate(oldSelStart, newSelStart, oldSelEnd, newSelEnd)) {
return false;
}
@@ -358,8 +387,9 @@ public final class InputLogic {
// should be true, but that is if the framework had taken that wrong cursor position
// into account, which means we have to reset the entire composing state whenever there
// is or was a selection regardless of whether it changed or not.
- if (hasOrHadSelection || (selectionChangedOrSafeToReset
- && !mWordComposer.moveCursorByAndReturnIfInsideComposingWord(moveAmount))) {
+ if (hasOrHadSelection || !settingsValues.needsToLookupSuggestions()
+ || (selectionChangedOrSafeToReset
+ && !mWordComposer.moveCursorByAndReturnIfInsideComposingWord(moveAmount))) {
// If we are composing a word and moving the cursor, we would want to set a
// suggestion span for recorrection to work correctly. Unfortunately, that
// would involve the keyboard committing some new text, which would move the
@@ -386,6 +416,11 @@ public final class InputLogic {
// The cursor has been moved : we now accept to perform recapitalization
mRecapitalizeStatus.enable();
+ // We moved the cursor and need to invalidate the indicator right now.
+ mTextDecorator.reset();
+ // Remaining background color that was used for the add-to-dictionary indicator should be
+ // removed.
+ mConnection.removeBackgroundColorFromHighlightedTextIfNecessary();
// We moved the cursor. If we are touching a word, we need to resume suggestion.
mLatinIME.mHandler.postResumeSuggestions(false /* shouldIncludeResumedWordInSuggestions */,
true /* shouldDelay */);
@@ -464,7 +499,9 @@ public final class InputLogic {
handler.cancelUpdateSuggestionStrip();
++mAutoCommitSequenceNumber;
mConnection.beginBatchEdit();
- if (mWordComposer.isComposingWord()) {
+ if (!mWordComposer.isComposingWord()) {
+ mConnection.removeBackgroundColorFromHighlightedTextIfNecessary();
+ } else {
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can insert the batch input at the current cursor position.
@@ -561,7 +598,8 @@ public final class InputLogic {
// TODO: on the long term, this method should become private, but it will be difficult.
// Especially, how do we deal with InputMethodService.onDisplayCompletions?
- public void setSuggestedWords(final SuggestedWords suggestedWords) {
+ public void setSuggestedWords(final SuggestedWords suggestedWords,
+ final SettingsValues settingsValues, final LatinIME.UIHandler handler) {
if (SuggestedWords.EMPTY != suggestedWords) {
final String autoCorrection;
if (suggestedWords.mWillAutoCorrect) {
@@ -575,6 +613,7 @@ public final class InputLogic {
}
mSuggestedWords = suggestedWords;
final boolean newAutoCorrectionIndicator = suggestedWords.mWillAutoCorrect;
+
// Put a blue underline to a word in TextView which will be auto-corrected.
if (mIsAutoCorrectionIndicatorOn != newAutoCorrectionIndicator
&& mWordComposer.isComposingWord()) {
@@ -585,7 +624,7 @@ public final class InputLogic {
// message, this is called outside any batch edit. Potentially, this may result in some
// janky flickering of the screen, although the display speed makes it unlikely in
// the practice.
- mConnection.setComposingText(textWithUnderline, 1);
+ setComposingTextInternal(textWithUnderline, 1);
}
}
@@ -608,7 +647,7 @@ public final class InputLogic {
inputTransaction.setDidAffectContents();
}
if (mWordComposer.isComposingWord()) {
- mConnection.setComposingText(mWordComposer.getTypedWord(), 1);
+ setComposingTextInternal(mWordComposer.getTypedWord(), 1);
inputTransaction.setDidAffectContents();
inputTransaction.setRequiresUpdateSuggestions();
}
@@ -751,11 +790,14 @@ public final class InputLogic {
final InputTransaction inputTransaction,
// TODO: remove this argument
final LatinIME.UIHandler handler) {
- // In case the "add to dictionary" hint was still displayed.
- // TODO: Do we really need to check if we have composing text here?
- if (!mWordComposer.isComposingWord() &&
- mSuggestionStripViewAccessor.isShowingAddToDictionaryHint()) {
- mSuggestionStripViewAccessor.dismissAddToDictionaryHint();
+ if (!mWordComposer.isComposingWord()) {
+ mConnection.removeBackgroundColorFromHighlightedTextIfNecessary();
+ // In case the "add to dictionary" hint was still displayed.
+ // TODO: Do we really need to check if we have composing text here?
+ if (mSuggestionStripViewAccessor.isShowingAddToDictionaryHint()) {
+ mSuggestionStripViewAccessor.dismissAddToDictionaryHint();
+ mTextDecorator.reset();
+ }
}
final int codePoint = event.mCodePoint;
@@ -842,8 +884,7 @@ public final class InputLogic {
if (mWordComposer.isSingleLetter()) {
mWordComposer.setCapitalizedModeAtStartComposingTime(inputTransaction.mShiftState);
}
- mConnection.setComposingText(getTextWithUnderline(
- mWordComposer.getTypedWord()), 1);
+ setComposingTextInternal(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
} else {
final boolean swapWeakSpace = tryStripSpaceAndReturnWhetherShouldSwapInstead(event,
inputTransaction);
@@ -1006,14 +1047,14 @@ public final class InputLogic {
mWordComposer.applyProcessedEvent(event);
}
if (mWordComposer.isComposingWord()) {
- mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
+ setComposingTextInternal(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
} else {
mConnection.commitText("", 1);
}
inputTransaction.setRequiresUpdateSuggestions();
} else {
if (mLastComposedWord.canRevertCommit()) {
- revertCommit(inputTransaction);
+ revertCommit(inputTransaction, inputTransaction.mSettingsValues);
return;
}
if (mEnteredText != null && mConnection.sameAsTextBeforeCursor(mEnteredText)) {
@@ -1395,8 +1436,7 @@ public final class InputLogic {
return;
}
final TextRange range = mConnection.getWordRangeAtCursor(
- settingsValues.mSpacingAndPunctuations.mSortedWordSeparators,
- currentKeyboardScriptId);
+ settingsValues.mSpacingAndPunctuations, currentKeyboardScriptId);
if (null == range) return; // Happens if we don't have an input connection at all
if (range.length() <= 0) {
// Race condition, or touching a word in a non-supported script.
@@ -1500,14 +1540,19 @@ public final class InputLogic {
* This is triggered upon pressing backspace just after a commit with auto-correction.
*
* @param inputTransaction The transaction in progress.
+ * @param settingsValues the current values of the settings.
*/
- private void revertCommit(final InputTransaction inputTransaction) {
+ private void revertCommit(final InputTransaction inputTransaction,
+ final SettingsValues settingsValues) {
final CharSequence originallyTypedWord = mLastComposedWord.mTypedWord;
+ final String originallyTypedWordString =
+ originallyTypedWord != null ? originallyTypedWord.toString() : "";
final CharSequence committedWord = mLastComposedWord.mCommittedWord;
final String committedWordString = committedWord.toString();
final int cancelLength = committedWord.length();
+ final String separatorString = mLastComposedWord.mSeparatorString;
// We want java chars, not codepoints for the following.
- final int separatorLength = mLastComposedWord.mSeparatorString.length();
+ final int separatorLength = separatorString.length();
// TODO: should we check our saved separator against the actual contents of the text view?
final int deleteLength = cancelLength + separatorLength;
if (DebugFlags.DEBUG_ENABLED) {
@@ -1526,7 +1571,7 @@ public final class InputLogic {
if (!TextUtils.isEmpty(committedWord)) {
mDictionaryFacilitator.removeWordFromPersonalizedDicts(committedWordString);
}
- final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString;
+ final String stringToCommit = originallyTypedWord + separatorString;
final SpannableString textToCommit = new SpannableString(stringToCommit);
if (committedWord instanceof SpannableString) {
final SpannableString committedWordWithSuggestionSpans = (SpannableString)committedWord;
@@ -1563,23 +1608,53 @@ public final class InputLogic {
suggestions.toArray(new String[suggestions.size()]), 0 /* flags */),
0 /* start */, lastCharIndex /* end */, 0 /* flags */);
}
+
+ final boolean shouldShowAddToDictionaryForTypedWord =
+ shouldShowAddToDictionaryForTypedWord(mLastComposedWord, settingsValues);
+
if (inputTransaction.mSettingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) {
// For languages with spaces, we revert to the typed string, but the cursor is still
// after the separator so we don't resume suggestions. If the user wants to correct
// the word, they have to press backspace again.
- mConnection.commitText(textToCommit, 1);
+ if (shouldShowAddToDictionaryForTypedWord) {
+ mConnection.commitTextWithBackgroundColor(textToCommit, 1,
+ settingsValues.mTextHighlightColorForAddToDictionaryIndicator,
+ originallyTypedWordString.length());
+ } else {
+ mConnection.commitText(textToCommit, 1);
+ }
} else {
// For languages without spaces, we revert the typed string but the cursor is flush
// with the typed word, so we need to resume suggestions right away.
final int[] codePoints = StringUtils.toCodePointArray(stringToCommit);
mWordComposer.setComposingWord(codePoints,
mLatinIME.getCoordinatesForCurrentKeyboard(codePoints));
- mConnection.setComposingText(textToCommit, 1);
+ if (shouldShowAddToDictionaryForTypedWord) {
+ setComposingTextInternalWithBackgroundColor(textToCommit, 1,
+ settingsValues.mTextHighlightColorForAddToDictionaryIndicator,
+ originallyTypedWordString.length());
+ } else {
+ setComposingTextInternal(textToCommit, 1);
+ }
}
// Don't restart suggestion yet. We'll restart if the user deletes the separator.
mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
- // We have a separator between the word and the cursor: we should show predictions.
- inputTransaction.setRequiresUpdateSuggestions();
+
+ if (shouldShowAddToDictionaryForTypedWord) {
+ // Due to the API limitation as of L, we cannot reliably retrieve the reverted text
+ // when the separator causes line breaking. Until this API limitation is addressed in
+ // the framework, show the indicator only when the separator doesn't contain
+ // line-breaking characters.
+ if (!StringUtils.hasLineBreakCharacter(separatorString)) {
+ mTextDecorator.showAddToDictionaryIndicator(originallyTypedWordString,
+ mConnection.getExpectedSelectionStart(),
+ mConnection.getExpectedSelectionEnd());
+ }
+ mSuggestionStripViewAccessor.showAddToDictionaryHint(originallyTypedWordString);
+ } else {
+ // We have a separator between the word and the cursor: we should show predictions.
+ inputTransaction.setRequiresUpdateSuggestions();
+ }
}
/**
@@ -1907,10 +1982,10 @@ public final class InputLogic {
}
final String lastWord = batchInputText.substring(indexOfLastSpace);
mWordComposer.setBatchInputWord(lastWord);
- mConnection.setComposingText(lastWord, 1);
+ setComposingTextInternal(lastWord, 1);
} else {
mWordComposer.setBatchInputWord(batchInputText);
- mConnection.setComposingText(batchInputText, 1);
+ setComposingTextInternal(batchInputText, 1);
}
mConnection.endBatchEdit();
// Space state must be updated before calling updateShiftState
@@ -2003,9 +2078,7 @@ public final class InputLogic {
}
/**
- * Commits the chosen word to the text field and saves it for later retrieval. This is a
- * synonym of {@code commitChosenWordWithBackgroundColor(settingsValues, chosenWord,
- * commitType, separatorString, Color.TRANSPARENT}.
+ * Commits the chosen word to the text field and saves it for later retrieval.
*
* @param settingsValues the current values of the settings.
* @param chosenWord the word we want to commit.
@@ -2014,23 +2087,6 @@ public final class InputLogic {
*/
private void commitChosenWord(final SettingsValues settingsValues, final String chosenWord,
final int commitType, final String separatorString) {
- commitChosenWordWithBackgroundColor(settingsValues, chosenWord, commitType, separatorString,
- Color.TRANSPARENT);
- }
-
- /**
- * Commits the chosen word to the text field and saves it for later retrieval.
- *
- * @param settingsValues the current values of the settings.
- * @param chosenWord the word we want to commit.
- * @param commitType the type of the commit, as one of LastComposedWord.COMMIT_TYPE_*
- * @param separatorString the separator that's causing the commit, or NOT_A_SEPARATOR if none.
- * @param backgroundColor the background color to be specified with the committed text. Pass
- * {@link Color#TRANSPARENT} to not specify the background color.
- */
- private void commitChosenWordWithBackgroundColor(final SettingsValues settingsValues,
- final String chosenWord, final int commitType, final String separatorString,
- final int backgroundColor) {
final SuggestedWords suggestedWords = mSuggestedWords;
final CharSequence chosenWordWithSuggestions =
SuggestionSpanUtils.getTextWithSuggestionSpan(mLatinIME, chosenWord,
@@ -2040,7 +2096,7 @@ public final class InputLogic {
// information from the 1st previous word.
final PrevWordsInfo prevWordsInfo = mConnection.getPrevWordsInfoFromNthPreviousWord(
settingsValues.mSpacingAndPunctuations, mWordComposer.isComposingWord() ? 2 : 1);
- mConnection.commitTextWithBackgroundColor(chosenWordWithSuggestions, 1, backgroundColor);
+ mConnection.commitText(chosenWordWithSuggestions, 1);
// Add the word to the user history dictionary
performAdditionToUserHistoryDictionary(settingsValues, chosenWord, prevWordsInfo);
// TODO: figure out here if this is an auto-correct or if the best word is actually
@@ -2108,4 +2164,122 @@ public final class InputLogic {
settingsValues.mAutoCorrectionEnabledPerUserSettings,
inputStyle, sequenceNumber, callback);
}
+
+ /**
+ * Used as an injection point for each call of
+ * {@link RichInputConnection#setComposingText(CharSequence, int)}.
+ *
+ * <p>Currently using this method is optional and you can still directly call
+ * {@link RichInputConnection#setComposingText(CharSequence, int)}, but it is recommended to
+ * use this method whenever possible to optimize the behavior of {@link TextDecorator}.<p>
+ * <p>TODO: Should we move this mechanism to {@link RichInputConnection}?</p>
+ *
+ * @param newComposingText the composing text to be set
+ * @param newCursorPosition the new cursor position
+ */
+ private void setComposingTextInternal(final CharSequence newComposingText,
+ final int newCursorPosition) {
+ setComposingTextInternalWithBackgroundColor(newComposingText, newCursorPosition,
+ Color.TRANSPARENT, newComposingText.length());
+ }
+
+ /**
+ * Equivalent to {@link #setComposingTextInternal(CharSequence, int)} except that this method
+ * allows to set {@link BackgroundColorSpan} to the composing text with the given color.
+ *
+ * <p>TODO: Currently the background color is exclusive with the black underline, which is
+ * automatically added by the framework. We need to change the framework if we need to have both
+ * of them at the same time.</p>
+ * <p>TODO: Should we move this method to {@link RichInputConnection}?</p>
+ *
+ * @param newComposingText the composing text to be set
+ * @param newCursorPosition the new cursor position
+ * @param backgroundColor the background color to be set to the composing text. Set
+ * {@link Color#TRANSPARENT} to disable the background color.
+ * @param coloredTextLength the length of text, in Java chars, which should be rendered with
+ * the given background color.
+ */
+ private void setComposingTextInternalWithBackgroundColor(final CharSequence newComposingText,
+ final int newCursorPosition, final int backgroundColor, final int coloredTextLength) {
+ final CharSequence composingTextToBeSet;
+ if (backgroundColor == Color.TRANSPARENT) {
+ composingTextToBeSet = newComposingText;
+ } else {
+ final SpannableString spannable = new SpannableString(newComposingText);
+ final BackgroundColorSpan backgroundColorSpan =
+ new BackgroundColorSpan(backgroundColor);
+ final int spanLength = Math.min(coloredTextLength, spannable.length());
+ spannable.setSpan(backgroundColorSpan, 0, spanLength,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
+ composingTextToBeSet = spannable;
+ }
+ mConnection.setComposingText(composingTextToBeSet, newCursorPosition);
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // Following methods are tentatively placed in this class for the integration with
+ // TextDecorator.
+ // TODO: Decouple things that are not related to the input logic.
+ //////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Sets the UI operator for {@link TextDecorator}.
+ * @param uiOperator the UI operator which should be associated with {@link TextDecorator}.
+ */
+ public void setTextDecoratorUi(final TextDecoratorUiOperator uiOperator) {
+ mTextDecorator.setUiOperator(uiOperator);
+ }
+
+ /**
+ * Must be called from {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} is
+ * called.
+ * @param info The wrapper object with which we can access cursor/anchor info.
+ */
+ public void onUpdateCursorAnchorInfo(final CursorAnchorInfoCompatWrapper info) {
+ mTextDecorator.onUpdateCursorAnchorInfo(info);
+ }
+
+ /**
+ * Must be called when {@link InputMethodService#updateFullscreenMode} is called.
+ * @param isFullscreen {@code true} if the input method is in full-screen mode.
+ */
+ public void onUpdateFullscreenMode(final boolean isFullscreen) {
+ mTextDecorator.notifyFullScreenMode(isFullscreen);
+ }
+
+ /**
+ * Must be called from {@link LatinIME#addWordToUserDictionary(String)}.
+ */
+ public void onAddWordToUserDictionary() {
+ mConnection.removeBackgroundColorFromHighlightedTextIfNecessary();
+ mTextDecorator.reset();
+ }
+
+ /**
+ * Returns whether the add to dictionary indicator should be shown or not.
+ * @param lastComposedWord the last composed word information.
+ * @param settingsValues the current settings value.
+ * @return {@code true} if the commit indicator should be shown.
+ */
+ private boolean shouldShowAddToDictionaryForTypedWord(final LastComposedWord lastComposedWord,
+ final SettingsValues settingsValues) {
+ if (!mConnection.isCursorAnchorInfoMonitorEnabled()) {
+ // We cannot help in this case because we are heavily relying on this new API.
+ return false;
+ }
+ if (!settingsValues.mShouldShowUiToAcceptTypedWord) {
+ return false;
+ }
+ if (TextUtils.isEmpty(lastComposedWord.mTypedWord)) {
+ return false;
+ }
+ if (TextUtils.equals(lastComposedWord.mTypedWord, lastComposedWord.mCommittedWord)) {
+ return false;
+ }
+ if (!mDictionaryFacilitator.isUserDictionaryEnabled()) {
+ return false;
+ }
+ return !mDictionaryFacilitator.isValidWord(lastComposedWord.mTypedWord,
+ true /* ignoreCase */);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/settings/AppearanceSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AppearanceSettingsFragment.java
new file mode 100644
index 000000000..f5e4d33a2
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/AppearanceSettingsFragment.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2014 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.settings;
+
+import android.os.Bundle;
+
+import com.android.inputmethod.latin.R;
+
+
+/**
+ * "Appearance" settings sub screen.
+ */
+public final class AppearanceSettingsFragment extends SubScreenFragment {
+ @Override
+ public void onCreate(final Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.prefs_screen_appearance);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ CustomInputStyleSettingsFragment.updateCustomInputStylesSummary(
+ findPreference(Settings.PREF_CUSTOM_INPUT_STYLES));
+ ThemeSettingsFragment.updateKeyboardThemeSummary(findPreference(Settings.SCREEN_THEME));
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
index 6d7f53cf0..9bc398654 100644
--- a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
@@ -30,11 +30,15 @@ import android.preference.DialogPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
+import android.support.v4.view.ViewCompat;
+import android.text.TextUtils;
import android.util.Pair;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+import android.view.ViewGroup;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.ArrayAdapter;
@@ -43,6 +47,7 @@ import android.widget.SpinnerAdapter;
import android.widget.Toast;
import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
+import com.android.inputmethod.compat.ViewCompatUtils;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodManager;
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
@@ -233,6 +238,12 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
mSubtypeLocaleSpinner.setAdapter(mProxy.getSubtypeLocaleAdapter());
mKeyboardLayoutSetSpinner = (Spinner) v.findViewById(R.id.keyboard_layout_set_spinner);
mKeyboardLayoutSetSpinner.setAdapter(mProxy.getKeyboardLayoutSetAdapter());
+ // All keyboard layout names are in the Latin script and thus left to right. That means
+ // the view would align them to the left even if the system locale is RTL, but that
+ // would look strange. To fix this, we align them to the view's start, which will be
+ // natural for any direction.
+ ViewCompatUtils.setTextAlignment(
+ mKeyboardLayoutSetSpinner, ViewCompatUtils.TEXT_ALIGNMENT_VIEW_START);
return v;
}
@@ -386,6 +397,25 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
// Empty constructor for fragment generation.
}
+ static void updateCustomInputStylesSummary(final Preference pref) {
+ // When we are called from the Settings application but we are not already running, some
+ // singleton and utility classes may not have been initialized. We have to call
+ // initialization method of these classes here. See {@link LatinIME#onCreate()}.
+ SubtypeLocaleUtils.init(pref.getContext());
+
+ final Resources res = pref.getContext().getResources();
+ final SharedPreferences prefs = pref.getSharedPreferences();
+ final String prefSubtype = Settings.readPrefAdditionalSubtypes(prefs, res);
+ final InputMethodSubtype[] subtypes =
+ AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefSubtype);
+ final ArrayList<String> subtypeNames = new ArrayList<>();
+ for (final InputMethodSubtype subtype : subtypes) {
+ subtypeNames.add(SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype));
+ }
+ // TODO: A delimiter of custom input styles should be localized.
+ pref.setSummary(TextUtils.join(", ", subtypeNames));
+ }
+
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -398,6 +428,16 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
}
@Override
+ public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+ final Bundle savedInstanceState) {
+ final View view = super.onCreateView(inflater, container, savedInstanceState);
+ // For correct display in RTL locales, we need to set the layout direction of the
+ // fragment's top view.
+ ViewCompat.setLayoutDirection(view, ViewCompat.LAYOUT_DIRECTION_LOCALE);
+ return view;
+ }
+
+ @Override
public void onActivityCreated(final Bundle savedInstanceState) {
final Context context = getActivity();
mSubtypeLocaleAdapter = new SubtypeLocaleAdapter(context);
@@ -422,7 +462,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
KEY_SUBTYPE_FOR_SUBTYPE_ENABLER);
final SubtypePreference subtypePref = (SubtypePreference)findPreference(
mSubtypePreferenceKeyForSubtypeEnabler);
- mSubtypeEnablerNotificationDialog = createDialog(subtypePref);
+ mSubtypeEnablerNotificationDialog = createDialog();
mSubtypeEnablerNotificationDialog.show();
}
}
@@ -476,7 +516,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
if (findDuplicatedSubtype(subtype) == null) {
mRichImm.setAdditionalInputMethodSubtypes(getSubtypes());
mSubtypePreferenceKeyForSubtypeEnabler = subtypePref.getKey();
- mSubtypeEnablerNotificationDialog = createDialog(subtypePref);
+ mSubtypeEnablerNotificationDialog = createDialog();
mSubtypeEnablerNotificationDialog.show();
return;
}
@@ -513,7 +553,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
localeString, keyboardLayoutSetName);
}
- private AlertDialog createDialog(final SubtypePreference subtypePref) {
+ private AlertDialog createDialog() {
final AlertDialog.Builder builder = new AlertDialog.Builder(
DialogUtils.getPlatformDialogThemeContext(getActivity()));
builder.setTitle(R.string.custom_input_styles_title)
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
index 63d848e2d..48f4c758c 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -23,10 +23,16 @@ public final class DebugSettings {
"force_physical_keyboard_special_key";
public static final String PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD =
"pref_show_ui_to_accept_typed_word";
- public static final String PREF_KEY_PREVIEW_SHOW_UP_START_SCALE =
- "pref_key_preview_show_up_start_scale";
- public static final String PREF_KEY_PREVIEW_DISMISS_END_SCALE =
- "pref_key_preview_dismiss_end_scale";
+ public static final String PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS =
+ "pref_has_custom_key_preview_animation_params";
+ public static final String PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE =
+ "pref_key_preview_show_up_start_x_scale";
+ public static final String PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE =
+ "pref_key_preview_show_up_start_y_scale";
+ public static final String PREF_KEY_PREVIEW_DISMISS_END_X_SCALE =
+ "pref_key_preview_dismiss_end_x_scale";
+ public static final String PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE =
+ "pref_key_preview_dismiss_end_y_scale";
public static final String PREF_KEY_PREVIEW_SHOW_UP_DURATION =
"pref_key_preview_show_up_duration";
public static final String PREF_KEY_PREVIEW_DISMISS_DURATION =
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
index dc2f88aa8..5640e2039 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
@@ -78,12 +78,18 @@ public final class DebugSettingsFragment extends SubScreenFragment
res.getInteger(R.integer.config_key_preview_show_up_duration));
setupKeyPreviewAnimationDuration(DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
res.getInteger(R.integer.config_key_preview_dismiss_duration));
- setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_SCALE,
- ResourceUtils.getFloatFromFraction(
- res, R.fraction.config_key_preview_show_up_start_scale));
- setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_SCALE,
- ResourceUtils.getFloatFromFraction(
- res, R.fraction.config_key_preview_dismiss_end_scale));
+ final float defaultKeyPreviewShowUpStartScale = ResourceUtils.getFloatFromFraction(
+ res, R.fraction.config_key_preview_show_up_start_scale);
+ final float defaultKeyPreviewDismissEndScale = ResourceUtils.getFloatFromFraction(
+ res, R.fraction.config_key_preview_dismiss_end_scale);
+ setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE,
+ defaultKeyPreviewShowUpStartScale);
+ setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE,
+ defaultKeyPreviewShowUpStartScale);
+ setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_X_SCALE,
+ defaultKeyPreviewDismissEndScale);
+ setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
+ defaultKeyPreviewDismissEndScale);
mServiceNeedsRestart = false;
mDebugMode = (TwoStatePreference) findPreference(DebugSettings.PREF_DEBUG_MODE);
diff --git a/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java
index fcdd39316..b073c50a4 100644
--- a/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java
@@ -16,66 +16,27 @@
package com.android.inputmethod.latin.settings;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
import android.os.Bundle;
-import android.preference.PreferenceScreen;
-import android.text.TextUtils;
-import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
-import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import java.util.ArrayList;
/**
- * "Multi lingual options" settings sub screen.
+ * "Multilingual options" settings sub screen.
*
* This settings sub screen handles the following input preferences.
* - Language switch key
* - Switch to other input methods
- * - Custom input styles
*/
public final class MultiLingualSettingsFragment extends SubScreenFragment {
@Override
public void onCreate(final Bundle icicle) {
super.onCreate(icicle);
- addPreferencesFromResource(R.xml.prefs_screen_multi_lingual);
-
- final Context context = getActivity();
-
- // When we are called from the Settings application but we are not already running, some
- // singleton and utility classes may not have been initialized. We have to call
- // initialization method of these classes here. See {@link LatinIME#onCreate()}.
- SubtypeLocaleUtils.init(context);
-
+ addPreferencesFromResource(R.xml.prefs_screen_multilingual);
if (!Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS) {
removePreference(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY);
removePreference(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST);
}
}
-
- @Override
- public void onResume() {
- super.onResume();
- updateCustomInputStylesSummary();
- }
-
- private void updateCustomInputStylesSummary() {
- final SharedPreferences prefs = getSharedPreferences();
- final Resources res = getResources();
- final PreferenceScreen customInputStyles =
- (PreferenceScreen)findPreference(Settings.PREF_CUSTOM_INPUT_STYLES);
- final String prefSubtype = Settings.readPrefAdditionalSubtypes(prefs, res);
- final InputMethodSubtype[] subtypes =
- AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefSubtype);
- final ArrayList<String> subtypeNames = new ArrayList<>();
- for (final InputMethodSubtype subtype : subtypes) {
- subtypeNames.add(SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype));
- }
- // TODO: A delimiter of custom input styles should be localized.
- customInputStyles.setSummary(TextUtils.join(", ", subtypeNames));
- }
}
diff --git a/java/src/com/android/inputmethod/latin/settings/InputSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/PreferencesSettingsFragment.java
index f459d68dd..49db2bdc0 100644
--- a/java/src/com/android/inputmethod/latin/settings/InputSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/PreferencesSettingsFragment.java
@@ -27,7 +27,7 @@ import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher;
/**
- * "Input preferences" settings sub screen.
+ * "Preferences" settings sub screen.
*
* This settings sub screen handles the following input preferences.
* - Auto-capitalization
@@ -37,11 +37,11 @@ import com.android.inputmethod.latin.SubtypeSwitcher;
* - Popup on keypress
* - Voice input key
*/
-public final class InputSettingsFragment extends SubScreenFragment {
+public final class PreferencesSettingsFragment extends SubScreenFragment {
@Override
public void onCreate(final Bundle icicle) {
super.onCreate(icicle);
- addPreferencesFromResource(R.xml.prefs_screen_input);
+ addPreferencesFromResource(R.xml.prefs_screen_preferences);
final Resources res = getResources();
final Context context = getActivity();
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 9d3c27bbe..0de2d8831 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin.settings;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;
@@ -41,9 +42,10 @@ import java.util.concurrent.locks.ReentrantLock;
public final class Settings implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = Settings.class.getSimpleName();
// Settings screens
- public static final String SCREEN_INPUT = "screen_input";
+ public static final String SCREEN_PREFERENCES = "screen_preferences";
+ public static final String SCREEN_APPEARANCE = "screen_appearance";
public static final String SCREEN_THEME = "screen_theme";
- public static final String SCREEN_MULTI_LINGUAL = "screen_multi_lingual";
+ public static final String SCREEN_MULTILINGUAL = "screen_multilingual";
public static final String SCREEN_GESTURE = "screen_gesture";
public static final String SCREEN_CORRECTION = "screen_correction";
public static final String SCREEN_ADVANCED = "screen_advanced";
@@ -68,6 +70,9 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
"pref_key_use_double_space_period";
public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE =
"pref_key_block_potentially_offensive";
+ // No multilingual options in Android L and above for now.
+ public static final boolean SHOW_MULTILINGUAL_SETTINGS =
+ BuildCompatUtils.EFFECTIVE_SDK_INT <= Build.VERSION_CODES.KITKAT;
public static final boolean ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS =
BuildCompatUtils.EFFECTIVE_SDK_INT <= Build.VERSION_CODES.KITKAT;
public static final boolean HAS_UI_TO_ACCEPT_TYPED_WORD =
@@ -368,6 +373,15 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return prefs.getBoolean(PREF_SHOW_SETUP_WIZARD_ICON, false);
}
+ public static boolean readHasHardwareKeyboard(final Configuration conf) {
+ // The standard way of finding out whether we have a hardware keyboard. This code is taken
+ // from InputMethodService#onEvaluateInputShown, which canonically determines this.
+ // In a nutshell, we have a keyboard if the configuration says the type of hardware keyboard
+ // is NOKEYS and if it's not hidden (e.g. folded inside the device).
+ return conf.keyboard != Configuration.KEYBOARD_NOKEYS
+ && conf.hardKeyboardHidden != Configuration.HARDKEYBOARDHIDDEN_YES;
+ }
+
public static boolean isInternal(final SharedPreferences prefs) {
return prefs.getBoolean(PREF_KEY_IS_INTERNAL, false);
}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index ff7495853..4fc17387f 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin.settings;
import android.content.Intent;
import android.os.Bundle;
+import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.view.Menu;
import android.view.MenuInflater;
@@ -46,12 +47,10 @@ public final class SettingsFragment extends InputMethodSettingsFragment {
final PreferenceScreen preferenceScreen = getPreferenceScreen();
preferenceScreen.setTitle(
ApplicationUtils.getActivityTitleResId(getActivity(), SettingsActivity.class));
- }
-
- @Override
- public void onResume() {
- super.onResume();
- ThemeSettingsFragment.updateKeyboardThemeSummary(findPreference(Settings.SCREEN_THEME));
+ if (!Settings.SHOW_MULTILINGUAL_SETTINGS) {
+ final Preference multilingualOptions = findPreference(Settings.SCREEN_MULTILINGUAL);
+ preferenceScreen.removePreference(multilingualOptions);
+ }
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index 1cd7b391a..d8c548d8b 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -52,7 +52,10 @@ public final class SettingsValues {
public final SpacingAndPunctuations mSpacingAndPunctuations;
public final int mDelayInMillisecondsToUpdateOldSuggestions;
public final long mDoubleSpacePeriodTimeout;
-
+ // From configuration:
+ public final Locale mLocale;
+ public final boolean mHasHardwareKeyboard;
+ public final int mDisplayOrientation;
// From preferences, in the same order as xml/prefs.xml:
public final boolean mAutoCap;
public final boolean mVibrateOn;
@@ -73,7 +76,6 @@ public final class SettingsValues {
public final boolean mSlidingKeyInputPreviewEnabled;
public final boolean mPhraseGestureEnabled;
public final int mKeyLongpressTimeout;
- public final Locale mLocale;
public final boolean mEnableMetricsLogging;
public final boolean mShouldShowUiToAcceptTypedWord;
@@ -88,19 +90,24 @@ public final class SettingsValues {
public final float mAutoCorrectionThreshold;
public final boolean mAutoCorrectionEnabledPerUserSettings;
private final boolean mSuggestionsEnabledPerUserSettings;
- public final int mDisplayOrientation;
private final AsyncResultHolder<AppWorkaroundsUtils> mAppWorkarounds;
// Setting values for additional features
public final int[] mAdditionalFeaturesSettingValues =
new int[AdditionalFeaturesSettingUtils.ADDITIONAL_FEATURES_SETTINGS_SIZE];
+ // TextDecorator
+ public final int mTextHighlightColorForAddToDictionaryIndicator;
+
// Debug settings
public final boolean mIsInternal;
+ public final boolean mHasCustomKeyPreviewAnimationParams;
public final int mKeyPreviewShowUpDuration;
public final int mKeyPreviewDismissDuration;
- public final float mKeyPreviewShowUpStartScale;
- public final float mKeyPreviewDismissEndScale;
+ public final float mKeyPreviewShowUpStartXScale;
+ public final float mKeyPreviewShowUpStartYScale;
+ public final float mKeyPreviewDismissEndXScale;
+ public final float mKeyPreviewDismissEndYScale;
public SettingsValues(final Context context, final SharedPreferences prefs, final Resources res,
final InputAttributes inputAttributes) {
@@ -138,11 +145,13 @@ public final class SettingsValues {
? Settings.readShowsLanguageSwitchKey(prefs) : true /* forcibly */;
mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
mUsePersonalizedDicts = prefs.getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true);
- mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true);
+ mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true)
+ && inputAttributes.mIsGeneralTextInput;
mBlockPotentiallyOffensive = Settings.readBlockPotentiallyOffensive(prefs, res);
mAutoCorrectEnabled = Settings.readAutoCorrectEnabled(autoCorrectionThresholdRawValue, res);
mBigramPredictionEnabled = readBigramPredictionEnabled(prefs, res);
mDoubleSpacePeriodTimeout = res.getInteger(R.integer.config_double_space_period_timeout);
+ mHasHardwareKeyboard = Settings.readHasHardwareKeyboard(res.getConfiguration());
mEnableMetricsLogging = prefs.getBoolean(Settings.PREF_ENABLE_METRICS_LOGGING, true);
mShouldShowUiToAcceptTypedWord = Settings.HAS_UI_TO_ACCEPT_TYPED_WORD
&& prefs.getBoolean(DebugSettings.PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD, true);
@@ -163,21 +172,33 @@ public final class SettingsValues {
mSuggestionsEnabledPerUserSettings = readSuggestionsEnabled(prefs);
AdditionalFeaturesSettingUtils.readAdditionalFeaturesPreferencesIntoArray(
prefs, mAdditionalFeaturesSettingValues);
+ mTextHighlightColorForAddToDictionaryIndicator = res.getColor(
+ R.color.text_decorator_add_to_dictionary_indicator_text_highlight_color);
mIsInternal = Settings.isInternal(prefs);
+ mHasCustomKeyPreviewAnimationParams = prefs.getBoolean(
+ DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS, false);
mKeyPreviewShowUpDuration = Settings.readKeyPreviewAnimationDuration(
prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
res.getInteger(R.integer.config_key_preview_show_up_duration));
mKeyPreviewDismissDuration = Settings.readKeyPreviewAnimationDuration(
prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
res.getInteger(R.integer.config_key_preview_dismiss_duration));
- mKeyPreviewShowUpStartScale = Settings.readKeyPreviewAnimationScale(
- prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_SCALE,
- ResourceUtils.getFloatFromFraction(
- res, R.fraction.config_key_preview_show_up_start_scale));
- mKeyPreviewDismissEndScale = Settings.readKeyPreviewAnimationScale(
- prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_SCALE,
- ResourceUtils.getFloatFromFraction(
- res, R.fraction.config_key_preview_dismiss_end_scale));
+ final float defaultKeyPreviewShowUpStartScale = ResourceUtils.getFloatFromFraction(
+ res, R.fraction.config_key_preview_show_up_start_scale);
+ final float defaultKeyPreviewDismissEndScale = ResourceUtils.getFloatFromFraction(
+ res, R.fraction.config_key_preview_dismiss_end_scale);
+ mKeyPreviewShowUpStartXScale = Settings.readKeyPreviewAnimationScale(
+ prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE,
+ defaultKeyPreviewShowUpStartScale);
+ mKeyPreviewShowUpStartYScale = Settings.readKeyPreviewAnimationScale(
+ prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE,
+ defaultKeyPreviewShowUpStartScale);
+ mKeyPreviewDismissEndXScale = Settings.readKeyPreviewAnimationScale(
+ prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_X_SCALE,
+ defaultKeyPreviewDismissEndScale);
+ mKeyPreviewDismissEndYScale = Settings.readKeyPreviewAnimationScale(
+ prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
+ defaultKeyPreviewDismissEndScale);
mDisplayOrientation = res.getConfiguration().orientation;
mAppWorkarounds = new AsyncResultHolder<>();
final PackageInfo packageInfo = TargetPackageInfoGetterTask.getCachedPackageInfo(
@@ -396,16 +417,22 @@ public final class SettingsValues {
sb.append("" + (null == awu ? "null" : awu.toString()));
sb.append("\n mAdditionalFeaturesSettingValues = ");
sb.append("" + Arrays.toString(mAdditionalFeaturesSettingValues));
+ sb.append("\n mTextHighlightColorForAddToDictionaryIndicator = ");
+ sb.append("" + mTextHighlightColorForAddToDictionaryIndicator);
sb.append("\n mIsInternal = ");
sb.append("" + mIsInternal);
sb.append("\n mKeyPreviewShowUpDuration = ");
sb.append("" + mKeyPreviewShowUpDuration);
sb.append("\n mKeyPreviewDismissDuration = ");
sb.append("" + mKeyPreviewDismissDuration);
- sb.append("\n mKeyPreviewShowUpStartScale = ");
- sb.append("" + mKeyPreviewShowUpStartScale);
- sb.append("\n mKeyPreviewDismissEndScale = ");
- sb.append("" + mKeyPreviewDismissEndScale);
+ sb.append("\n mKeyPreviewShowUpStartScaleX = ");
+ sb.append("" + mKeyPreviewShowUpStartXScale);
+ sb.append("\n mKeyPreviewShowUpStartScaleY = ");
+ sb.append("" + mKeyPreviewShowUpStartYScale);
+ sb.append("\n mKeyPreviewDismissEndScaleX = ");
+ sb.append("" + mKeyPreviewDismissEndXScale);
+ sb.append("\n mKeyPreviewDismissEndScaleY = ");
+ sb.append("" + mKeyPreviewDismissEndYScale);
return sb.toString();
}
}
diff --git a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
index b8d2a2248..49d81104d 100644
--- a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
+++ b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin.settings;
import android.content.res.Resources;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.internal.MoreKeySpec;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.PunctuationSuggestions;
@@ -68,6 +69,22 @@ public final class SpacingAndPunctuations {
mSuggestPuncList = PunctuationSuggestions.newPunctuationSuggestions(suggestPuncsSpec);
}
+ @UsedForTesting
+ public SpacingAndPunctuations(final SpacingAndPunctuations model,
+ final int[] overrideSortedWordSeparators) {
+ mSortedSymbolsPrecededBySpace = model.mSortedSymbolsPrecededBySpace;
+ mSortedSymbolsFollowedBySpace = model.mSortedSymbolsFollowedBySpace;
+ mSortedSymbolsClusteringTogether = model.mSortedSymbolsClusteringTogether;
+ mSortedWordConnectors = model.mSortedWordConnectors;
+ mSortedWordSeparators = overrideSortedWordSeparators;
+ mSuggestPuncList = model.mSuggestPuncList;
+ mSentenceSeparator = model.mSentenceSeparator;
+ mSentenceSeparatorAndSpace = model.mSentenceSeparatorAndSpace;
+ mCurrentLanguageHasSpaces = model.mCurrentLanguageHasSpaces;
+ mUsesAmericanTypography = model.mUsesAmericanTypography;
+ mUsesGermanRules = model.mUsesGermanRules;
+ }
+
public boolean isWordSeparator(final int code) {
return Arrays.binarySearch(mSortedWordSeparators, code) >= 0;
}
diff --git a/java/src/com/android/inputmethod/latin/setup/LauncherIconVisibilityManager.java b/java/src/com/android/inputmethod/latin/setup/LauncherIconVisibilityManager.java
index 9585736e7..3f0b10225 100644
--- a/java/src/com/android/inputmethod/latin/setup/LauncherIconVisibilityManager.java
+++ b/java/src/com/android/inputmethod/latin/setup/LauncherIconVisibilityManager.java
@@ -24,7 +24,6 @@ import android.content.pm.PackageManager;
import android.preference.PreferenceManager;
import android.util.Log;
-import com.android.inputmethod.compat.IntentCompatUtils;
import com.android.inputmethod.latin.settings.Settings;
/**
@@ -55,14 +54,6 @@ import com.android.inputmethod.latin.settings.Settings;
public final class LauncherIconVisibilityManager {
private static final String TAG = LauncherIconVisibilityManager.class.getSimpleName();
- public static void onReceiveGlobalIntent(final String action, final Context context) {
- if (Intent.ACTION_MY_PACKAGE_REPLACED.equals(action) ||
- Intent.ACTION_BOOT_COMPLETED.equals(action) ||
- IntentCompatUtils.is_ACTION_USER_INITIALIZE(action)) {
- updateSetupWizardIconVisibility(context);
- }
- }
-
public static void updateSetupWizardIconVisibility(final Context context) {
final ComponentName setupWizardActivity = new ComponentName(context, SetupActivity.class);
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 33745a846..0fd5e139e 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -408,8 +408,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
// Decided to be in the sliding suggestion mode only when the touch point has been moved
// upward. Further {@link MotionEvent}s will be delivered to
// {@link #onTouchEvent(MotionEvent)}.
- mNeedsToTransformTouchEventToHoverEvent = AccessibilityUtils.getInstance()
- .isTouchExplorationEnabled();
+ mNeedsToTransformTouchEventToHoverEvent =
+ AccessibilityUtils.getInstance().isTouchExplorationEnabled();
mIsDispatchingHoverEventToMoreSuggestions = false;
return true;
}
diff --git a/java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java
new file mode 100644
index 000000000..9dc0524a2
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2014 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.utils;
+
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.inputmethodservice.ExtractEditText;
+import android.inputmethodservice.InputMethodService;
+import android.text.Layout;
+import android.text.Spannable;
+import android.view.View;
+import android.view.ViewParent;
+import android.view.inputmethod.CursorAnchorInfo;
+import android.widget.TextView;
+
+/**
+ * This class allows input methods to extract {@link CursorAnchorInfo} directly from the given
+ * {@link TextView}. This is useful and even necessary to support full-screen mode where the default
+ * {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} event callback must be
+ * ignored because it reports the character locations of the target application rather than
+ * characters on {@link ExtractEditText}.
+ */
+public final class CursorAnchorInfoUtils {
+ private CursorAnchorInfoUtils() {
+ // This helper class is not instantiable.
+ }
+
+ private static boolean isPositionVisible(final View view, final float positionX,
+ final float positionY) {
+ final float[] position = new float[] { positionX, positionY };
+ View currentView = view;
+
+ while (currentView != null) {
+ if (currentView != view) {
+ // Local scroll is already taken into account in positionX/Y
+ position[0] -= currentView.getScrollX();
+ position[1] -= currentView.getScrollY();
+ }
+
+ if (position[0] < 0 || position[1] < 0 ||
+ position[0] > currentView.getWidth() || position[1] > currentView.getHeight()) {
+ return false;
+ }
+
+ if (!currentView.getMatrix().isIdentity()) {
+ currentView.getMatrix().mapPoints(position);
+ }
+
+ position[0] += currentView.getLeft();
+ position[1] += currentView.getTop();
+
+ final ViewParent parent = currentView.getParent();
+ if (parent instanceof View) {
+ currentView = (View) parent;
+ } else {
+ // We've reached the ViewRoot, stop iterating
+ currentView = null;
+ }
+ }
+
+ // We've been able to walk up the view hierarchy and the position was never clipped
+ return true;
+ }
+
+ /**
+ * Returns {@link CursorAnchorInfo} from the given {@link TextView}.
+ * @param textView the target text view from which {@link CursorAnchorInfo} is to be extracted.
+ * @return the {@link CursorAnchorInfo} object based on the current layout. {@code null} if it
+ * is not feasible.
+ */
+ public static CursorAnchorInfo getCursorAnchorInfo(final TextView textView) {
+ Layout layout = textView.getLayout();
+ if (layout == null) {
+ return null;
+ }
+
+ final CursorAnchorInfo.Builder builder = new CursorAnchorInfo.Builder();
+
+ final int selectionStart = textView.getSelectionStart();
+ builder.setSelectionRange(selectionStart, textView.getSelectionEnd());
+
+ // Construct transformation matrix from view local coordinates to screen coordinates.
+ final Matrix viewToScreenMatrix = new Matrix(textView.getMatrix());
+ final int[] viewOriginInScreen = new int[2];
+ textView.getLocationOnScreen(viewOriginInScreen);
+ viewToScreenMatrix.postTranslate(viewOriginInScreen[0], viewOriginInScreen[1]);
+ builder.setMatrix(viewToScreenMatrix);
+
+ if (layout.getLineCount() == 0) {
+ return null;
+ }
+ final Rect lineBoundsWithoutOffset = new Rect();
+ final Rect lineBoundsWithOffset = new Rect();
+ layout.getLineBounds(0, lineBoundsWithoutOffset);
+ textView.getLineBounds(0, lineBoundsWithOffset);
+ final float viewportToContentHorizontalOffset = lineBoundsWithOffset.left
+ - lineBoundsWithoutOffset.left - textView.getScrollX();
+ final float viewportToContentVerticalOffset = lineBoundsWithOffset.top
+ - lineBoundsWithoutOffset.top - textView.getScrollY();
+
+ final CharSequence text = textView.getText();
+ if (text instanceof Spannable) {
+ // Here we assume that the composing text is marked as SPAN_COMPOSING flag. This is not
+ // necessarily true, but basically works.
+ int composingTextStart = text.length();
+ int composingTextEnd = 0;
+ final Spannable spannable = (Spannable) text;
+ final Object[] spans = spannable.getSpans(0, text.length(), Object.class);
+ for (Object span : spans) {
+ final int spanFlag = spannable.getSpanFlags(span);
+ if ((spanFlag & Spannable.SPAN_COMPOSING) != 0) {
+ composingTextStart = Math.min(composingTextStart,
+ spannable.getSpanStart(span));
+ composingTextEnd = Math.max(composingTextEnd, spannable.getSpanEnd(span));
+ }
+ }
+
+ final boolean hasComposingText =
+ (0 <= composingTextStart) && (composingTextStart < composingTextEnd);
+ if (hasComposingText) {
+ final CharSequence composingText = text.subSequence(composingTextStart,
+ composingTextEnd);
+ builder.setComposingText(composingTextStart, composingText);
+
+ final int minLine = layout.getLineForOffset(composingTextStart);
+ final int maxLine = layout.getLineForOffset(composingTextEnd - 1);
+ for (int line = minLine; line <= maxLine; ++line) {
+ final int lineStart = layout.getLineStart(line);
+ final int lineEnd = layout.getLineEnd(line);
+ final int offsetStart = Math.max(lineStart, composingTextStart);
+ final int offsetEnd = Math.min(lineEnd, composingTextEnd);
+ final boolean ltrLine =
+ layout.getParagraphDirection(line) == Layout.DIR_LEFT_TO_RIGHT;
+ final float[] widths = new float[offsetEnd - offsetStart];
+ layout.getPaint().getTextWidths(text, offsetStart, offsetEnd, widths);
+ final float top = layout.getLineTop(line);
+ final float bottom = layout.getLineBottom(line);
+ for (int offset = offsetStart; offset < offsetEnd; ++offset) {
+ final float charWidth = widths[offset - offsetStart];
+ final boolean isRtl = layout.isRtlCharAt(offset);
+ final float primary = layout.getPrimaryHorizontal(offset);
+ final float secondary = layout.getSecondaryHorizontal(offset);
+ // TODO: This doesn't work perfectly for text with custom styles and TAB
+ // chars.
+ final float left;
+ final float right;
+ if (ltrLine) {
+ if (isRtl) {
+ left = secondary - charWidth;
+ right = secondary;
+ } else {
+ left = primary;
+ right = primary + charWidth;
+ }
+ } else {
+ if (!isRtl) {
+ left = secondary;
+ right = secondary + charWidth;
+ } else {
+ left = primary - charWidth;
+ right = primary;
+ }
+ }
+ // TODO: Check top-right and bottom-left as well.
+ final float localLeft = left + viewportToContentHorizontalOffset;
+ final float localRight = right + viewportToContentHorizontalOffset;
+ final float localTop = top + viewportToContentVerticalOffset;
+ final float localBottom = bottom + viewportToContentVerticalOffset;
+ final boolean isTopLeftVisible = isPositionVisible(textView,
+ localLeft, localTop);
+ final boolean isBottomRightVisible =
+ isPositionVisible(textView, localRight, localBottom);
+ int characterBoundsFlags = 0;
+ if (isTopLeftVisible || isBottomRightVisible) {
+ characterBoundsFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
+ }
+ if (!isTopLeftVisible || !isTopLeftVisible) {
+ characterBoundsFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
+ }
+ if (isRtl) {
+ characterBoundsFlags |= CursorAnchorInfo.FLAG_IS_RTL;
+ }
+ // Here offset is the index in Java chars.
+ builder.addCharacterBounds(offset, localLeft, localTop, localRight,
+ localBottom, characterBoundsFlags);
+ }
+ }
+ }
+ }
+
+ // Treat selectionStart as the insertion point.
+ if (0 <= selectionStart) {
+ final int offset = selectionStart;
+ final int line = layout.getLineForOffset(offset);
+ final float insertionMarkerX = layout.getPrimaryHorizontal(offset)
+ + viewportToContentHorizontalOffset;
+ final float insertionMarkerTop = layout.getLineTop(line)
+ + viewportToContentVerticalOffset;
+ final float insertionMarkerBaseline = layout.getLineBaseline(line)
+ + viewportToContentVerticalOffset;
+ final float insertionMarkerBottom = layout.getLineBottom(line)
+ + viewportToContentVerticalOffset;
+ final boolean isTopVisible =
+ isPositionVisible(textView, insertionMarkerX, insertionMarkerTop);
+ final boolean isBottomVisible =
+ isPositionVisible(textView, insertionMarkerX, insertionMarkerBottom);
+ int insertionMarkerFlags = 0;
+ if (isTopVisible || isBottomVisible) {
+ insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
+ }
+ if (!isTopVisible || !isBottomVisible) {
+ insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
+ }
+ if (layout.isRtlCharAt(offset)) {
+ insertionMarkerFlags |= CursorAnchorInfo.FLAG_IS_RTL;
+ }
+ builder.setInsertionMarkerLocation(insertionMarkerX, insertionMarkerTop,
+ insertionMarkerBaseline, insertionMarkerBottom, insertionMarkerFlags);
+ }
+ return builder.build();
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
index 08f5b0b41..c2167a76b 100644
--- a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
@@ -19,12 +19,13 @@ package com.android.inputmethod.latin.utils;
import com.android.inputmethod.dictionarypack.DictionarySettingsFragment;
import com.android.inputmethod.latin.about.AboutPreferences;
import com.android.inputmethod.latin.settings.AdvancedSettingsFragment;
+import com.android.inputmethod.latin.settings.AppearanceSettingsFragment;
import com.android.inputmethod.latin.settings.CorrectionSettingsFragment;
import com.android.inputmethod.latin.settings.CustomInputStyleSettingsFragment;
import com.android.inputmethod.latin.settings.DebugSettingsFragment;
import com.android.inputmethod.latin.settings.GestureSettingsFragment;
-import com.android.inputmethod.latin.settings.InputSettingsFragment;
import com.android.inputmethod.latin.settings.MultiLingualSettingsFragment;
+import com.android.inputmethod.latin.settings.PreferencesSettingsFragment;
import com.android.inputmethod.latin.settings.SettingsFragment;
import com.android.inputmethod.latin.settings.ThemeSettingsFragment;
import com.android.inputmethod.latin.spellcheck.SpellCheckerSettingsFragment;
@@ -40,7 +41,8 @@ public class FragmentUtils {
static {
sLatinImeFragments.add(DictionarySettingsFragment.class.getName());
sLatinImeFragments.add(AboutPreferences.class.getName());
- sLatinImeFragments.add(InputSettingsFragment.class.getName());
+ sLatinImeFragments.add(PreferencesSettingsFragment.class.getName());
+ sLatinImeFragments.add(AppearanceSettingsFragment.class.getName());
sLatinImeFragments.add(ThemeSettingsFragment.class.getName());
sLatinImeFragments.add(MultiLingualSettingsFragment.class.getName());
sLatinImeFragments.add(CustomInputStyleSettingsFragment.class.getName());
diff --git a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
index 8b7077879..ea406fa75 100644
--- a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
@@ -23,15 +23,24 @@ import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
import android.util.Log;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.R;
+import java.util.concurrent.TimeUnit;
+
public final class ImportantNoticeUtils {
private static final String TAG = ImportantNoticeUtils.class.getSimpleName();
// {@link SharedPreferences} name to save the last important notice version that has been
// displayed to users.
private static final String PREFERENCE_NAME = "important_notice_pref";
- private static final String KEY_IMPORTANT_NOTICE_VERSION = "important_notice_version";
+ @UsedForTesting
+ static final String KEY_IMPORTANT_NOTICE_VERSION = "important_notice_version";
+ @UsedForTesting
+ static final String KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE =
+ "timestamp_of_first_important_notice";
+ @UsedForTesting
+ static final long TIMEOUT_OF_IMPORTANT_NOTICE = TimeUnit.HOURS.toMillis(23);
public static final int VERSION_TO_ENABLE_PERSONALIZED_SUGGESTIONS = 1;
// Copy of the hidden {@link Settings.Secure#USER_SETUP_COMPLETE} settings key.
@@ -56,15 +65,18 @@ public final class ImportantNoticeUtils {
}
}
- private static SharedPreferences getImportantNoticePreferences(final Context context) {
+ @UsedForTesting
+ static SharedPreferences getImportantNoticePreferences(final Context context) {
return context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
}
- private static int getCurrentImportantNoticeVersion(final Context context) {
+ @UsedForTesting
+ static int getCurrentImportantNoticeVersion(final Context context) {
return context.getResources().getInteger(R.integer.config_important_notice_version);
}
- private static int getLastImportantNoticeVersion(final Context context) {
+ @UsedForTesting
+ static int getLastImportantNoticeVersion(final Context context) {
return getImportantNoticePreferences(context).getInt(KEY_IMPORTANT_NOTICE_VERSION, 0);
}
@@ -77,6 +89,20 @@ public final class ImportantNoticeUtils {
return getCurrentImportantNoticeVersion(context) > lastVersion;
}
+ @UsedForTesting
+ static boolean hasTimeoutPassed(final Context context, final long currentTimeInMillis) {
+ final SharedPreferences prefs = getImportantNoticePreferences(context);
+ if (!prefs.contains(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE)) {
+ prefs.edit()
+ .putLong(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE, currentTimeInMillis)
+ .apply();
+ }
+ final long firstDisplayTimeInMillis = prefs.getLong(
+ KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE, currentTimeInMillis);
+ final long elapsedTime = currentTimeInMillis - firstDisplayTimeInMillis;
+ return elapsedTime >= TIMEOUT_OF_IMPORTANT_NOTICE;
+ }
+
public static boolean shouldShowImportantNotice(final Context context) {
if (!hasNewImportantNotice(context)) {
return false;
@@ -88,6 +114,10 @@ public final class ImportantNoticeUtils {
if (isInSystemSetupWizard(context)) {
return false;
}
+ if (hasTimeoutPassed(context, System.currentTimeMillis())) {
+ updateLastImportantNoticeVersion(context);
+ return false;
+ }
return true;
}
@@ -95,11 +125,12 @@ public final class ImportantNoticeUtils {
getImportantNoticePreferences(context)
.edit()
.putInt(KEY_IMPORTANT_NOTICE_VERSION, getNextImportantNoticeVersion(context))
+ .remove(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE)
.apply();
}
public static String getNextImportantNoticeTitle(final Context context) {
- final int nextVersion = getCurrentImportantNoticeVersion(context);
+ final int nextVersion = getNextImportantNoticeVersion(context);
final String[] importantNoticeTitleArray = context.getResources().getStringArray(
R.array.important_notice_title_array);
if (nextVersion > 0 && nextVersion < importantNoticeTitleArray.length) {
diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
index 38f0b3fee..79128dbd2 100644
--- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
@@ -37,6 +37,14 @@ public final class StringUtils {
private static final String EMPTY_STRING = "";
+ private static final char CHAR_LINE_FEED = 0X000A;
+ private static final char CHAR_VERTICAL_TAB = 0X000B;
+ private static final char CHAR_FORM_FEED = 0X000C;
+ private static final char CHAR_CARRIAGE_RETURN = 0X000D;
+ private static final char CHAR_NEXT_LINE = 0X0085;
+ private static final char CHAR_LINE_SEPARATOR = 0X2028;
+ private static final char CHAR_PARAGRAPH_SEPARATOR = 0X2029;
+
private StringUtils() {
// This utility class is not publicly instantiable.
}
@@ -123,20 +131,20 @@ public final class StringUtils {
public static String capitalizeFirstCodePoint(final String s, final Locale locale) {
if (s.length() <= 1) {
- return s.toUpperCase(locale);
+ return toUpperCaseOfStringForLocale(s, true /* needsToUpperCase */, locale);
}
// Please refer to the comment below in
// {@link #capitalizeFirstAndDowncaseRest(String,Locale)} as this has the same shortcomings
final int cutoff = s.offsetByCodePoints(0, 1);
- return s.substring(0, cutoff).toUpperCase(locale) + s.substring(cutoff);
+ return toUpperCaseOfStringForLocale(
+ s.substring(0, cutoff), true /* needsToUpperCase */, locale) + s.substring(cutoff);
}
public static String capitalizeFirstAndDowncaseRest(final String s, final Locale locale) {
if (s.length() <= 1) {
- return s.toUpperCase(locale);
+ return toUpperCaseOfStringForLocale(s, true /* needsToUpperCase */, locale);
}
// TODO: fix the bugs below
- // - This does not work for Greek, because it returns upper case instead of title case.
// - It does not work for Serbian, because it fails to account for the "lj" character,
// which should be "Lj" in title case and "LJ" in upper case.
// - It does not work for Dutch, because it fails to account for the "ij" digraph when it's
@@ -144,7 +152,9 @@ public final class StringUtils {
// be capitalized as "IJ" as if they were a single letter in most words (not all). If the
// unicode char for the ligature is used however, it works.
final int cutoff = s.offsetByCodePoints(0, 1);
- return s.substring(0, cutoff).toUpperCase(locale) + s.substring(cutoff).toLowerCase(locale);
+ final String titleCaseFirstLetter = toUpperCaseOfStringForLocale(
+ s.substring(0, cutoff), true /* needsToUpperCase */, locale);
+ return titleCaseFirstLetter + s.substring(cutoff).toLowerCase(locale);
}
private static final int[] EMPTY_CODEPOINTS = {};
@@ -481,10 +491,23 @@ public final class StringUtils {
return bytes;
}
+ private static final String LANGUAGE_GREEK = "el";
+
+ private static Locale getLocaleUsedForToTitleCase(final Locale locale) {
+ // In Greek locale {@link String#toUpperCase(Locale)} eliminates accents from its result.
+ // In order to get accented upper case letter, {@link Locale#ROOT} should be used.
+ if (LANGUAGE_GREEK.equals(locale.getLanguage())) {
+ return Locale.ROOT;
+ }
+ return locale;
+ }
+
public static String toUpperCaseOfStringForLocale(final String text,
final boolean needsToUpperCase, final Locale locale) {
- if (text == null || !needsToUpperCase) return text;
- return text.toUpperCase(locale);
+ if (text == null || !needsToUpperCase) {
+ return text;
+ }
+ return text.toUpperCase(getLocaleUsedForToTitleCase(locale));
}
public static int toUpperCaseOfCodeForLocale(final int code, final boolean needsToUpperCase,
@@ -594,4 +617,30 @@ public final class StringUtils {
return sb + "]";
}
}
+
+ /**
+ * Returns whether the last composed word contains line-breaking character (e.g. CR or LF).
+ * @param text the text to be examined.
+ * @return {@code true} if the last composed word contains line-breaking separator.
+ */
+ @UsedForTesting
+ public static boolean hasLineBreakCharacter(final String text) {
+ if (TextUtils.isEmpty(text)) {
+ return false;
+ }
+ for (int i = text.length() - 1; i >= 0; --i) {
+ final char c = text.charAt(i);
+ switch (c) {
+ case CHAR_LINE_FEED:
+ case CHAR_VERTICAL_TAB:
+ case CHAR_FORM_FEED:
+ case CHAR_CARRIAGE_RETURN:
+ case CHAR_NEXT_LINE:
+ case CHAR_LINE_SEPARATOR:
+ case CHAR_PARAGRAPH_SEPARATOR:
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
index 7170bd789..8cd49509f 100644
--- a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
+++ b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
@@ -32,14 +32,18 @@ import java.util.TreeSet;
public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
public final Locale mLocale;
public final ArrayList<SuggestedWordInfo> mRawSuggestions;
+ // TODO: Instead of a boolean , we may want to include the context of this suggestion results,
+ // such as {@link PrevWordsInfo}.
+ public final boolean mIsBeginningOfSentence;
private final int mCapacity;
- public SuggestionResults(final Locale locale, final int capacity) {
- this(locale, sSuggestedWordInfoComparator, capacity);
+ public SuggestionResults(final Locale locale, final int capacity,
+ final boolean isBeginningOfSentence) {
+ this(locale, sSuggestedWordInfoComparator, capacity, isBeginningOfSentence);
}
- public SuggestionResults(final Locale locale, final Comparator<SuggestedWordInfo> comparator,
- final int capacity) {
+ private SuggestionResults(final Locale locale, final Comparator<SuggestedWordInfo> comparator,
+ final int capacity, final boolean isBeginningOfSentence) {
super(comparator);
mLocale = locale;
mCapacity = capacity;
@@ -48,6 +52,7 @@ public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
} else {
mRawSuggestions = null;
}
+ mIsBeginningOfSentence = isBeginningOfSentence;
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java b/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java
index f9d853493..dd122b634 100644
--- a/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ViewLayoutUtils.java
@@ -19,7 +19,10 @@ package com.android.inputmethod.latin.utils;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
+import android.view.Window;
+import android.view.WindowManager;
import android.widget.FrameLayout;
+import android.widget.LinearLayout;
import android.widget.RelativeLayout;
public final class ViewLayoutUtils {
@@ -51,4 +54,40 @@ public final class ViewLayoutUtils {
marginLayoutParams.setMargins(x, y, 0, 0);
}
}
+
+ public static void updateLayoutHeightOf(final Window window, final int layoutHeight) {
+ final WindowManager.LayoutParams params = window.getAttributes();
+ if (params.height != layoutHeight) {
+ params.height = layoutHeight;
+ window.setAttributes(params);
+ }
+ }
+
+ public static void updateLayoutHeightOf(final View view, final int layoutHeight) {
+ final ViewGroup.LayoutParams params = view.getLayoutParams();
+ if (params.height != layoutHeight) {
+ params.height = layoutHeight;
+ view.setLayoutParams(params);
+ }
+ }
+
+ public static void updateLayoutGravityOf(final View view, final int layoutGravity) {
+ final ViewGroup.LayoutParams lp = view.getLayoutParams();
+ if (lp instanceof LinearLayout.LayoutParams) {
+ final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)lp;
+ if (params.gravity != layoutGravity) {
+ params.gravity = layoutGravity;
+ view.setLayoutParams(params);
+ }
+ } else if (lp instanceof FrameLayout.LayoutParams) {
+ final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)lp;
+ if (params.gravity != layoutGravity) {
+ params.gravity = layoutGravity;
+ view.setLayoutParams(params);
+ }
+ } else {
+ throw new IllegalArgumentException("Layout parameter doesn't have gravity: "
+ + lp.getClass().getName());
+ }
+ }
}