Implement popup suggestions pane
Bug: 5023981 Change-Id: Ie1d69131dbf884a3f6a2beb3ac3427e5437c1486main
parent
e5c705f164
commit
29e7b7ed6e
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2011, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
style="?attr/miniKeyboardPanelStyle"
|
||||||
|
>
|
||||||
|
<com.android.inputmethod.latin.MoreSuggestionsView
|
||||||
|
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
||||||
|
android:id="@+id/more_suggestions_view"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
latin:keyLabelSize="@dimen/candidate_text_size"
|
||||||
|
latin:keyHintLetterRatio="@fraction/more_suggestions_info_ratio"
|
||||||
|
latin:keyHintLetterColor="@android:color/white"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
|
@ -59,6 +59,8 @@
|
||||||
<dimen name="key_preview_offset_ics">0.01in</dimen>
|
<dimen name="key_preview_offset_ics">0.01in</dimen>
|
||||||
|
|
||||||
<dimen name="candidate_strip_height">36dip</dimen>
|
<dimen name="candidate_strip_height">36dip</dimen>
|
||||||
|
<dimen name="more_suggestions_row_height">36dip</dimen>
|
||||||
|
<dimen name="candidate_strip_minimum_height">160sp</dimen>
|
||||||
<dimen name="candidate_strip_fading_edge_length">63dip</dimen>
|
<dimen name="candidate_strip_fading_edge_length">63dip</dimen>
|
||||||
<!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
|
<!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
|
||||||
<!-- popup_key_height x 1.2 -->
|
<!-- popup_key_height x 1.2 -->
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
<dimen name="key_preview_offset_ics">0.05in</dimen>
|
<dimen name="key_preview_offset_ics">0.05in</dimen>
|
||||||
|
|
||||||
<dimen name="candidate_strip_height">44dip</dimen>
|
<dimen name="candidate_strip_height">44dip</dimen>
|
||||||
|
<dimen name="more_suggestions_row_height">44dip</dimen>
|
||||||
<dimen name="candidate_strip_padding">15.0mm</dimen>
|
<dimen name="candidate_strip_padding">15.0mm</dimen>
|
||||||
<dimen name="candidate_min_width">0.3in</dimen>
|
<dimen name="candidate_min_width">0.3in</dimen>
|
||||||
<dimen name="candidate_padding">12dip</dimen>
|
<dimen name="candidate_padding">12dip</dimen>
|
||||||
|
|
|
@ -70,9 +70,8 @@
|
||||||
<dimen name="key_preview_offset_ics">0.05in</dimen>
|
<dimen name="key_preview_offset_ics">0.05in</dimen>
|
||||||
|
|
||||||
<dimen name="candidate_strip_height">44dip</dimen>
|
<dimen name="candidate_strip_height">44dip</dimen>
|
||||||
<!-- candidate_strip_minimum_height =
|
<dimen name="more_suggestions_row_height">44dip</dimen>
|
||||||
key_preview_height_holo - key_preview_offset_holo + alpha -->
|
<dimen name="candidate_strip_minimum_height">200sp</dimen>
|
||||||
<dimen name="candidate_strip_minimum_height">18mm</dimen>
|
|
||||||
<dimen name="candidate_strip_padding">15.0mm</dimen>
|
<dimen name="candidate_strip_padding">15.0mm</dimen>
|
||||||
<dimen name="candidate_min_width">46dip</dimen>
|
<dimen name="candidate_min_width">46dip</dimen>
|
||||||
<dimen name="candidate_padding">8dip</dimen>
|
<dimen name="candidate_padding">8dip</dimen>
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
<attr name="miniKeyboardPanelStyle" format="reference" />
|
<attr name="miniKeyboardPanelStyle" format="reference" />
|
||||||
<!-- Suggestions strip style -->
|
<!-- Suggestions strip style -->
|
||||||
<attr name="suggestionsStripBackgroundStyle" format="reference" />
|
<attr name="suggestionsStripBackgroundStyle" format="reference" />
|
||||||
|
<attr name="suggestionsPaneViewStyle" format="reference" />
|
||||||
<attr name="suggestionBackgroundStyle" format="reference" />
|
<attr name="suggestionBackgroundStyle" format="reference" />
|
||||||
<attr name="suggestionPreviewBackgroundStyle" format="reference" />
|
<attr name="suggestionPreviewBackgroundStyle" format="reference" />
|
||||||
<attr name="candidateViewStyle" format="reference" />
|
<attr name="candidateViewStyle" format="reference" />
|
||||||
|
|
|
@ -77,9 +77,11 @@
|
||||||
<dimen name="key_preview_offset_ics">0.05in</dimen>
|
<dimen name="key_preview_offset_ics">0.05in</dimen>
|
||||||
|
|
||||||
<dimen name="candidate_strip_height">40dip</dimen>
|
<dimen name="candidate_strip_height">40dip</dimen>
|
||||||
<!-- candidate_strip_minimum_height =
|
<dimen name="more_suggestions_key_horizontal_padding">12dip</dimen>
|
||||||
key_preview_height_holo - key_preview_offset_holo + alpha -->
|
<dimen name="more_suggestions_row_height">40dip</dimen>
|
||||||
<dimen name="candidate_strip_minimum_height">100sp</dimen>
|
<dimen name="more_suggestions_slide_allowance">0.2in</dimen>
|
||||||
|
<fraction name="more_suggestions_info_ratio">12%</fraction>
|
||||||
|
<dimen name="candidate_strip_minimum_height">200sp</dimen>
|
||||||
<dimen name="candidate_strip_fading_edge_length">63dip</dimen>
|
<dimen name="candidate_strip_fading_edge_length">63dip</dimen>
|
||||||
<dimen name="candidate_strip_padding">0dip</dimen>
|
<dimen name="candidate_strip_padding">0dip</dimen>
|
||||||
<dimen name="candidate_min_width">44dip</dimen>
|
<dimen name="candidate_min_width">44dip</dimen>
|
||||||
|
|
|
@ -79,6 +79,11 @@
|
||||||
<item name="android:paddingLeft">@dimen/mini_keyboard_horizontal_edges_padding</item>
|
<item name="android:paddingLeft">@dimen/mini_keyboard_horizontal_edges_padding</item>
|
||||||
<item name="android:paddingRight">@dimen/mini_keyboard_horizontal_edges_padding</item>
|
<item name="android:paddingRight">@dimen/mini_keyboard_horizontal_edges_padding</item>
|
||||||
</style>
|
</style>
|
||||||
|
<style
|
||||||
|
name="SuggestionsPaneViewStyle"
|
||||||
|
parent="MiniKeyboardView"
|
||||||
|
>
|
||||||
|
</style>
|
||||||
<style name="SuggestionsStripBackgroundStyle">
|
<style name="SuggestionsStripBackgroundStyle">
|
||||||
<item name="android:background">@drawable/keyboard_suggest_strip</item>
|
<item name="android:background">@drawable/keyboard_suggest_strip</item>
|
||||||
</style>
|
</style>
|
||||||
|
@ -235,6 +240,11 @@
|
||||||
parent="MiniKeyboardPanelStyle.IceCreamSandwich"
|
parent="MiniKeyboardPanelStyle.IceCreamSandwich"
|
||||||
>
|
>
|
||||||
</style>
|
</style>
|
||||||
|
<style
|
||||||
|
name="SuggestionsPaneViewStyle.IceCreamSandwich"
|
||||||
|
parent="MiniKeyboardView.IceCreamSandwich"
|
||||||
|
>
|
||||||
|
</style>
|
||||||
<style
|
<style
|
||||||
name="CandidateViewStyle.IceCreamSandwich"
|
name="CandidateViewStyle.IceCreamSandwich"
|
||||||
parent="SuggestionsStripBackgroundStyle.IceCreamSandwich"
|
parent="SuggestionsStripBackgroundStyle.IceCreamSandwich"
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView</item>
|
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView</item>
|
||||||
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
|
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
|
||||||
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
|
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
|
||||||
|
<item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle</item>
|
||||||
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
|
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
|
||||||
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
|
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
|
||||||
<item name="candidateViewStyle">@style/CandidateViewStyle</item>
|
<item name="candidateViewStyle">@style/CandidateViewStyle</item>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView</item>
|
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView</item>
|
||||||
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
|
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
|
||||||
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
|
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
|
||||||
|
<item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle</item>
|
||||||
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
|
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
|
||||||
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
|
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
|
||||||
<item name="candidateViewStyle">@style/CandidateViewStyle</item>
|
<item name="candidateViewStyle">@style/CandidateViewStyle</item>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Gingerbread</item>
|
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Gingerbread</item>
|
||||||
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
|
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
|
||||||
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
|
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
|
||||||
|
<item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle</item>
|
||||||
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
|
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
|
||||||
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
|
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
|
||||||
<item name="candidateViewStyle">@style/CandidateViewStyle</item>
|
<item name="candidateViewStyle">@style/CandidateViewStyle</item>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView.IceCreamSandwich</item>
|
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView.IceCreamSandwich</item>
|
||||||
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle.IceCreamSandwich</item>
|
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle.IceCreamSandwich</item>
|
||||||
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle.IceCreamSandwich</item>
|
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle.IceCreamSandwich</item>
|
||||||
|
<item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle.IceCreamSandwich</item>
|
||||||
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle.IceCreamSandwich</item>
|
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle.IceCreamSandwich</item>
|
||||||
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle.IceCreamSandwich</item>
|
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle.IceCreamSandwich</item>
|
||||||
<item name="candidateViewStyle">@style/CandidateViewStyle.IceCreamSandwich</item>
|
<item name="candidateViewStyle">@style/CandidateViewStyle.IceCreamSandwich</item>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Stone</item>
|
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Stone</item>
|
||||||
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
|
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
|
||||||
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
|
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
|
||||||
|
<item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle</item>
|
||||||
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
|
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
|
||||||
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
|
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
|
||||||
<item name="candidateViewStyle">@style/CandidateViewStyle</item>
|
<item name="candidateViewStyle">@style/CandidateViewStyle</item>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Stone</item>
|
<item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Stone</item>
|
||||||
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
|
<item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
|
||||||
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
|
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
|
||||||
|
<item name="suggestionsPaneViewStyle">@style/SuggestionsPaneViewStyle</item>
|
||||||
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
|
<item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
|
||||||
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
|
<item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
|
||||||
<item name="candidateViewStyle">@style/CandidateViewStyle</item>
|
<item name="candidateViewStyle">@style/CandidateViewStyle</item>
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
||||||
latin:keyWidth="8%p"
|
latin:keyWidth="8%p"
|
||||||
latin:horizontalGap="@fraction/key_horizontal_gap"
|
|
||||||
latin:verticalGap="0px"
|
|
||||||
latin:rowHeight="@dimen/popup_key_height"
|
latin:rowHeight="@dimen/popup_key_height"
|
||||||
>
|
>
|
||||||
</Keyboard>
|
</Keyboard>
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
||||||
latin:keyWidth="5.0%p"
|
latin:keyWidth="5.0%p"
|
||||||
latin:horizontalGap="0px"
|
|
||||||
latin:verticalGap="0px"
|
|
||||||
latin:rowHeight="@dimen/popup_key_height"
|
latin:rowHeight="@dimen/popup_key_height"
|
||||||
>
|
>
|
||||||
</Keyboard>
|
</Keyboard>
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
||||||
latin:keyWidth="10%p"
|
latin:keyWidth="10%p"
|
||||||
latin:horizontalGap="@fraction/key_horizontal_gap"
|
|
||||||
latin:verticalGap="0px"
|
|
||||||
latin:rowHeight="@dimen/popup_key_height"
|
latin:rowHeight="@dimen/popup_key_height"
|
||||||
>
|
>
|
||||||
</Keyboard>
|
</Keyboard>
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2011, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
||||||
|
latin:keyWidth="10%p"
|
||||||
|
latin:rowHeight="@dimen/more_suggestions_row_height"
|
||||||
|
>
|
||||||
|
</Keyboard>
|
|
@ -88,16 +88,7 @@ public class MiniKeyboardView extends KeyboardView implements MoreKeysPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy() {
|
private static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy.Adapter();
|
||||||
@Override
|
|
||||||
public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {}
|
|
||||||
@Override
|
|
||||||
public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {}
|
|
||||||
@Override
|
|
||||||
public void cancelLongPressTimer() {}
|
|
||||||
@Override
|
|
||||||
public void cancelKeyTimers() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final KeyboardActionListener mMiniKeyboardListener =
|
private final KeyboardActionListener mMiniKeyboardListener =
|
||||||
new KeyboardActionListener.Adapter() {
|
new KeyboardActionListener.Adapter() {
|
||||||
|
|
|
@ -76,6 +76,17 @@ public class PointerTracker {
|
||||||
public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker);
|
public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker);
|
||||||
public void cancelLongPressTimer();
|
public void cancelLongPressTimer();
|
||||||
public void cancelKeyTimers();
|
public void cancelKeyTimers();
|
||||||
|
|
||||||
|
public static class Adapter implements TimerProxy {
|
||||||
|
@Override
|
||||||
|
public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {}
|
||||||
|
@Override
|
||||||
|
public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {}
|
||||||
|
@Override
|
||||||
|
public void cancelLongPressTimer() {}
|
||||||
|
@Override
|
||||||
|
public void cancelKeyTimers() {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static KeyboardSwitcher sKeyboardSwitcher;
|
private static KeyboardSwitcher sKeyboardSwitcher;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import android.graphics.Color;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
|
@ -34,8 +35,10 @@ import android.text.style.ForegroundColorSpan;
|
||||||
import android.text.style.StyleSpan;
|
import android.text.style.StyleSpan;
|
||||||
import android.text.style.UnderlineSpan;
|
import android.text.style.UnderlineSpan;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.View.OnLongClickListener;
|
import android.view.View.OnLongClickListener;
|
||||||
|
@ -46,6 +49,9 @@ import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.inputmethod.compat.FrameLayoutCompatUtils;
|
import com.android.inputmethod.compat.FrameLayoutCompatUtils;
|
||||||
import com.android.inputmethod.compat.LinearLayoutCompatUtils;
|
import com.android.inputmethod.compat.LinearLayoutCompatUtils;
|
||||||
|
import com.android.inputmethod.keyboard.KeyboardActionListener;
|
||||||
|
import com.android.inputmethod.keyboard.MoreKeysPanel;
|
||||||
|
import com.android.inputmethod.keyboard.PointerTracker;
|
||||||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -58,16 +64,22 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
||||||
}
|
}
|
||||||
|
|
||||||
// The maximum number of suggestions available. See {@link Suggest#mPrefMaxSuggestions}.
|
// The maximum number of suggestions available. See {@link Suggest#mPrefMaxSuggestions}.
|
||||||
private static final int MAX_SUGGESTIONS = 18;
|
public static final int MAX_SUGGESTIONS = 18;
|
||||||
|
|
||||||
private static final boolean DBG = LatinImeLogger.sDBG;
|
private static final boolean DBG = LatinImeLogger.sDBG;
|
||||||
|
|
||||||
private final ViewGroup mCandidatesPlacer;
|
private final ViewGroup mCandidatesPlacer;
|
||||||
private final ViewGroup mCandidatesStrip;
|
private final ViewGroup mCandidatesStrip;
|
||||||
|
// TODO: Remove these pane related fields and stuffs.
|
||||||
private ViewGroup mCandidatesPane;
|
private ViewGroup mCandidatesPane;
|
||||||
private ViewGroup mCandidatesPaneContainer;
|
private ViewGroup mCandidatesPaneContainer;
|
||||||
private View mKeyboardView;
|
private View mKeyboardView;
|
||||||
|
|
||||||
|
private final View mMoreSuggestionsContainer;
|
||||||
|
private final MoreSuggestionsView mMoreSuggestionsView;
|
||||||
|
private final MoreSuggestions.Builder mMoreSuggestionsBuilder;
|
||||||
|
private final PopupWindow mMoreSuggestionsWindow;
|
||||||
|
|
||||||
private final ArrayList<TextView> mWords = new ArrayList<TextView>();
|
private final ArrayList<TextView> mWords = new ArrayList<TextView>();
|
||||||
private final ArrayList<TextView> mInfos = new ArrayList<TextView>();
|
private final ArrayList<TextView> mInfos = new ArrayList<TextView>();
|
||||||
private final ArrayList<View> mDividers = new ArrayList<View>();
|
private final ArrayList<View> mDividers = new ArrayList<View>();
|
||||||
|
@ -159,7 +171,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
||||||
mDividerHeight = divider.getMeasuredHeight();
|
mDividerHeight = divider.getMeasuredHeight();
|
||||||
|
|
||||||
final Resources res = word.getResources();
|
final Resources res = word.getResources();
|
||||||
mCandidateStripHeight = res.getDimensionPixelOffset(R.dimen.candidate_strip_height);
|
mCandidateStripHeight = res.getDimensionPixelSize(R.dimen.candidate_strip_height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +269,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
||||||
private final int mColorTypedWord;
|
private final int mColorTypedWord;
|
||||||
private final int mColorAutoCorrect;
|
private final int mColorAutoCorrect;
|
||||||
private final int mColorSuggestedCandidate;
|
private final int mColorSuggestedCandidate;
|
||||||
private final int mCandidateCountInStrip;
|
public final int mCandidateCountInStrip;
|
||||||
private final float mCenterCandidateWeight;
|
private final float mCenterCandidateWeight;
|
||||||
private final int mCenterCandidateIndex;
|
private final int mCenterCandidateIndex;
|
||||||
private final Drawable mMoreCandidateHint;
|
private final Drawable mMoreCandidateHint;
|
||||||
|
@ -449,7 +461,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return countInStrip;
|
return countInStrip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,6 +596,15 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
||||||
mInfos);
|
mInfos);
|
||||||
mPaneParams = new SuggestionsPaneParams(mWords, mDividers, mInfos);
|
mPaneParams = new SuggestionsPaneParams(mWords, mDividers, mInfos);
|
||||||
mStripParams.mWordToSaveView.setOnClickListener(this);
|
mStripParams.mWordToSaveView.setOnClickListener(this);
|
||||||
|
|
||||||
|
mMoreSuggestionsContainer = inflater.inflate(R.layout.more_suggestions, null);
|
||||||
|
mMoreSuggestionsView = (MoreSuggestionsView)mMoreSuggestionsContainer
|
||||||
|
.findViewById(R.id.more_suggestions_view);
|
||||||
|
mMoreSuggestionsBuilder = new MoreSuggestions.Builder(mMoreSuggestionsView);
|
||||||
|
mMoreSuggestionsWindow = new PopupWindow(context);
|
||||||
|
mMoreSuggestionsWindow.setWindowLayoutMode(
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
mMoreSuggestionsWindow.setBackgroundDrawable(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -621,8 +641,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
||||||
final int width = getWidth();
|
final int width = getWidth();
|
||||||
final int countInStrip = mStripParams.layout(
|
final int countInStrip = mStripParams.layout(
|
||||||
mSuggestions, mCandidatesStrip, mCandidatesPlacer, width);
|
mSuggestions, mCandidatesStrip, mCandidatesPlacer, width);
|
||||||
mPaneParams.layout(
|
|
||||||
mSuggestions, mCandidatesPane, countInStrip, mStripParams.getTextColor(), width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CharSequence getDebugInfo(SuggestedWords suggestions, int pos) {
|
private static CharSequence getDebugInfo(SuggestedWords suggestions, int pos) {
|
||||||
|
@ -787,6 +805,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
||||||
mCandidatesStrip.removeAllViews();
|
mCandidatesStrip.removeAllViews();
|
||||||
mCandidatesPane.removeAllViews();
|
mCandidatesPane.removeAllViews();
|
||||||
closeCandidatesPane();
|
closeCandidatesPane();
|
||||||
|
mMoreSuggestionsWindow.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hidePreview() {
|
private void hidePreview() {
|
||||||
|
@ -823,14 +842,101 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final KeyboardActionListener mMoreSuggestionsListener =
|
||||||
|
new KeyboardActionListener.Adapter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onLongClick(View view) {
|
public boolean onCustomRequest(int requestCode) {
|
||||||
if (mStripParams.mMoreSuggestionsAvailable) {
|
final int index = requestCode;
|
||||||
toggleCandidatesPane();
|
final CharSequence word = mSuggestions.getWord(index);
|
||||||
|
mListener.pickSuggestionManually(index, word);
|
||||||
|
mMoreSuggestionsView.dismissMoreKeysPanel();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelInput() {
|
||||||
|
mMoreSuggestionsView.dismissMoreKeysPanel();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final MoreKeysPanel.Controller mMoreSuggestionsController =
|
||||||
|
new MoreKeysPanel.Controller() {
|
||||||
|
@Override
|
||||||
|
public boolean dismissMoreKeysPanel() {
|
||||||
|
if (mMoreSuggestionsWindow.isShowing()) {
|
||||||
|
mMoreSuggestionsWindow.dismiss();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View view) {
|
||||||
|
final SuggestionsStripParams params = mStripParams;
|
||||||
|
if (params.mMoreSuggestionsAvailable) {
|
||||||
|
final int stripWidth = getWidth();
|
||||||
|
final View container = mMoreSuggestionsContainer;
|
||||||
|
final int maxWidth = stripWidth - container.getPaddingLeft()
|
||||||
|
- container.getPaddingRight();
|
||||||
|
final DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
|
||||||
|
// TODO: Revise how we determine the height
|
||||||
|
final int maxHeight = dm.heightPixels - mKeyboardView.getHeight() - getHeight() * 3;
|
||||||
|
final MoreSuggestions.Builder builder = mMoreSuggestionsBuilder;
|
||||||
|
builder.layout(mSuggestions, params.mCandidateCountInStrip, maxWidth, maxHeight);
|
||||||
|
mMoreSuggestionsView.setKeyboard(builder.build());
|
||||||
|
container.measure(
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
|
||||||
|
final MoreKeysPanel moreKeysPanel = mMoreSuggestionsView;
|
||||||
|
final int pointX = stripWidth / 2;
|
||||||
|
final int pointY = 0;
|
||||||
|
moreKeysPanel.showMoreKeysPanel(
|
||||||
|
this, mMoreSuggestionsController, pointX, pointY,
|
||||||
|
mMoreSuggestionsWindow, mMoreSuggestionsListener);
|
||||||
|
// TODO: Should figure out how to select the pointer tracker correctly.
|
||||||
|
final PointerTracker tracker = PointerTracker.getPointerTracker(0, moreKeysPanel);
|
||||||
|
final int translatedX = moreKeysPanel.translateX(tracker.getLastX());
|
||||||
|
final int translatedY = moreKeysPanel.translateY(tracker.getLastY());
|
||||||
|
tracker.onShowMoreKeysPanel(
|
||||||
|
translatedX, translatedY, SystemClock.uptimeMillis(), moreKeysPanel);
|
||||||
|
view.setPressed(false);
|
||||||
|
// TODO: Should gray out the keyboard here as well?
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchTouchEvent(MotionEvent me) {
|
||||||
|
if (!mMoreSuggestionsWindow.isShowing()) {
|
||||||
|
return super.dispatchTouchEvent(me);
|
||||||
|
}
|
||||||
|
final int action = me.getAction();
|
||||||
|
final long eventTime = me.getEventTime();
|
||||||
|
final int index = me.getActionIndex();
|
||||||
|
final int id = me.getPointerId(index);
|
||||||
|
final PointerTracker tracker = PointerTracker.getPointerTracker(id, mMoreSuggestionsView);
|
||||||
|
final int x = mMoreSuggestionsView.translateX((int)me.getX(index));
|
||||||
|
final int y = mMoreSuggestionsView.translateY((int)me.getY(index));
|
||||||
|
switch (action) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
|
tracker.onDownEvent(x, y, eventTime, mMoreSuggestionsView);
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
|
tracker.onUpEvent(x, y, eventTime);
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
tracker.onMoveEvent(x, y, eventTime);
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
tracker.onCancelEvent(x, y, eventTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
|
|
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.android.inputmethod.keyboard.Key;
|
||||||
|
import com.android.inputmethod.keyboard.Keyboard;
|
||||||
|
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
||||||
|
import com.android.inputmethod.keyboard.KeyboardView;
|
||||||
|
import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
|
||||||
|
import com.android.inputmethod.keyboard.internal.KeyboardParams;
|
||||||
|
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||||
|
|
||||||
|
public class MoreSuggestions extends Keyboard {
|
||||||
|
private static final boolean DBG = LatinImeLogger.sDBG;
|
||||||
|
|
||||||
|
public static final int SUGGESTION_CODE_BASE = 1024;
|
||||||
|
|
||||||
|
private MoreSuggestions(Builder.MoreSuggestionsParam params) {
|
||||||
|
super(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder extends KeyboardBuilder<Builder.MoreSuggestionsParam> {
|
||||||
|
private final MoreSuggestionsView mPaneView;
|
||||||
|
private SuggestedWords mSuggestions;
|
||||||
|
private int mFromPos;
|
||||||
|
private int mToPos;
|
||||||
|
|
||||||
|
public static class MoreSuggestionsParam extends KeyboardParams {
|
||||||
|
private final int[] mWidths = new int[CandidateView.MAX_SUGGESTIONS];
|
||||||
|
private final int[] mRowNumbers = new int[CandidateView.MAX_SUGGESTIONS];
|
||||||
|
private final int[] mColumnOrders = new int[CandidateView.MAX_SUGGESTIONS];
|
||||||
|
private final int[] mNumColumnsInRow = new int[CandidateView.MAX_SUGGESTIONS];
|
||||||
|
private static final int MAX_COLUMNS_IN_ROW = 3;
|
||||||
|
private int mNumRows;
|
||||||
|
|
||||||
|
public int layout(SuggestedWords suggestions, int fromPos, int maxWidth, int maxHeight,
|
||||||
|
KeyboardView view) {
|
||||||
|
clearKeys();
|
||||||
|
final Paint paint = new Paint();
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
final int padding = (int) view.getContext().getResources()
|
||||||
|
.getDimension(R.dimen.more_suggestions_key_horizontal_padding);
|
||||||
|
|
||||||
|
int row = 0;
|
||||||
|
int pos = fromPos, rowStartPos = fromPos;
|
||||||
|
final int size = Math.min(suggestions.size(), CandidateView.MAX_SUGGESTIONS);
|
||||||
|
while (pos < size) {
|
||||||
|
final CharSequence word = suggestions.getWord(pos);
|
||||||
|
// TODO: Should take care of text x-scaling.
|
||||||
|
mWidths[pos] = (int)view.getDefaultLabelWidth(word, paint) + padding;
|
||||||
|
final int numColumn = pos - rowStartPos + 1;
|
||||||
|
if (numColumn > MAX_COLUMNS_IN_ROW
|
||||||
|
|| !fitInWidth(rowStartPos, pos + 1, maxWidth / numColumn)) {
|
||||||
|
if ((row + 1) * mDefaultRowHeight > maxHeight) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mNumColumnsInRow[row] = pos - rowStartPos;
|
||||||
|
rowStartPos = pos;
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
mColumnOrders[pos] = pos - rowStartPos;
|
||||||
|
mRowNumbers[pos] = row;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
mNumColumnsInRow[row] = pos - rowStartPos;
|
||||||
|
mNumRows = row + 1;
|
||||||
|
mWidth = mOccupiedWidth = calcurateMaxRowWidth(fromPos, pos);
|
||||||
|
mHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight + mVerticalGap;
|
||||||
|
return pos - fromPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean fitInWidth(int startPos, int endPos, int width) {
|
||||||
|
for (int pos = startPos; pos < endPos; pos++) {
|
||||||
|
if (mWidths[pos] > width)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calcurateMaxRowWidth(int startPos, int endPos) {
|
||||||
|
int maxRowWidth = 0;
|
||||||
|
int pos = startPos;
|
||||||
|
for (int row = 0; row < mNumRows; row++) {
|
||||||
|
final int numColumn = mNumColumnsInRow[row];
|
||||||
|
int maxKeyWidth = 0;
|
||||||
|
while (pos < endPos && mRowNumbers[pos] == row) {
|
||||||
|
maxKeyWidth = Math.max(maxKeyWidth, mWidths[pos]);
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
maxRowWidth = Math.max(maxRowWidth, maxKeyWidth * numColumn);
|
||||||
|
}
|
||||||
|
return maxRowWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int[][] COLUMN_ORDER_TO_NUMBER = {
|
||||||
|
{ 0, },
|
||||||
|
{ 1, 0, },
|
||||||
|
{ 2, 0, 1},
|
||||||
|
};
|
||||||
|
|
||||||
|
private int getColumnNumber(int pos) {
|
||||||
|
final int columnOrder = mColumnOrders[pos];
|
||||||
|
final int numColumn = mNumColumnsInRow[mRowNumbers[pos]];
|
||||||
|
return COLUMN_ORDER_TO_NUMBER[numColumn - 1][columnOrder];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX(int pos) {
|
||||||
|
final int columnNumber = getColumnNumber(pos);
|
||||||
|
return columnNumber * getWidth(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY(int pos) {
|
||||||
|
final int row = mRowNumbers[pos];
|
||||||
|
return (mNumRows -1 - row) * mDefaultRowHeight + mTopPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth(int pos) {
|
||||||
|
final int row = mRowNumbers[pos];
|
||||||
|
final int numColumn = mNumColumnsInRow[row];
|
||||||
|
return mWidth / numColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFlags(int pos) {
|
||||||
|
int rowFlags = 0;
|
||||||
|
|
||||||
|
final int row = mRowNumbers[pos];
|
||||||
|
if (row == 0)
|
||||||
|
rowFlags |= Keyboard.EDGE_BOTTOM;
|
||||||
|
if (row == mNumRows - 1)
|
||||||
|
rowFlags |= Keyboard.EDGE_TOP;
|
||||||
|
|
||||||
|
final int numColumn = mNumColumnsInRow[row];
|
||||||
|
final int column = getColumnNumber(pos);
|
||||||
|
if (column == 0)
|
||||||
|
rowFlags |= Keyboard.EDGE_LEFT;
|
||||||
|
if (column == numColumn - 1)
|
||||||
|
rowFlags |= Keyboard.EDGE_RIGHT;
|
||||||
|
|
||||||
|
return rowFlags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder(MoreSuggestionsView paneView) {
|
||||||
|
super(paneView.getContext(), new MoreSuggestionsParam());
|
||||||
|
mPaneView = paneView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder layout(SuggestedWords suggestions, int fromPos, int maxWidth,
|
||||||
|
int maxHeight) {
|
||||||
|
final Keyboard keyboard = KeyboardSwitcher.getInstance().getLatinKeyboard();
|
||||||
|
final int xmlId = R.xml.kbd_suggestions_pane_template;
|
||||||
|
load(keyboard.mId.cloneWithNewXml(mResources.getResourceEntryName(xmlId), xmlId));
|
||||||
|
mParams.mVerticalGap = mParams.mTopPadding = keyboard.mVerticalGap / 2;
|
||||||
|
|
||||||
|
final int count = mParams.layout(suggestions, fromPos, maxWidth, maxHeight, mPaneView);
|
||||||
|
mFromPos = fromPos;
|
||||||
|
mToPos = fromPos + count;
|
||||||
|
mSuggestions = suggestions;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getDebugInfo(SuggestedWords suggestions, int pos) {
|
||||||
|
if (!DBG) return null;
|
||||||
|
final SuggestedWordInfo wordInfo = suggestions.getInfo(pos);
|
||||||
|
if (wordInfo == null) return null;
|
||||||
|
final String info = wordInfo.getDebugString();
|
||||||
|
if (TextUtils.isEmpty(info)) return null;
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoreSuggestions build() {
|
||||||
|
final MoreSuggestionsParam params = mParams;
|
||||||
|
for (int pos = mFromPos; pos < mToPos; pos++) {
|
||||||
|
final String word = mSuggestions.getWord(pos).toString();
|
||||||
|
final String info = getDebugInfo(mSuggestions, pos);
|
||||||
|
final int index = pos + SUGGESTION_CODE_BASE;
|
||||||
|
final Key key = new Key(
|
||||||
|
params, word, info, null, index, null, params.getX(pos), params.getY(pos),
|
||||||
|
params.getWidth(pos), params.mDefaultRowHeight, params.getFlags(pos));
|
||||||
|
params.onAddKey(key);
|
||||||
|
}
|
||||||
|
return new MoreSuggestions(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,237 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.PopupWindow;
|
||||||
|
|
||||||
|
import com.android.inputmethod.keyboard.Key;
|
||||||
|
import com.android.inputmethod.keyboard.KeyDetector;
|
||||||
|
import com.android.inputmethod.keyboard.Keyboard;
|
||||||
|
import com.android.inputmethod.keyboard.KeyboardActionListener;
|
||||||
|
import com.android.inputmethod.keyboard.KeyboardView;
|
||||||
|
import com.android.inputmethod.keyboard.MoreKeysPanel;
|
||||||
|
import com.android.inputmethod.keyboard.PointerTracker;
|
||||||
|
import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
|
||||||
|
import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A view that renders a virtual {@link MoreSuggestions}. It handles rendering of keys and detecting
|
||||||
|
* key presses and touch movements.
|
||||||
|
*/
|
||||||
|
public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel {
|
||||||
|
private final int[] mCoordinates = new int[2];
|
||||||
|
|
||||||
|
private final KeyDetector mKeyDetector;
|
||||||
|
|
||||||
|
private Controller mController;
|
||||||
|
private KeyboardActionListener mListener;
|
||||||
|
private int mOriginX;
|
||||||
|
private int mOriginY;
|
||||||
|
|
||||||
|
private static class SuggestionsPaneKeyDetector extends KeyDetector {
|
||||||
|
private final int mSlideAllowanceSquare;
|
||||||
|
private final int mSlideAllowanceSquareTop;
|
||||||
|
|
||||||
|
public SuggestionsPaneKeyDetector(float slideAllowance) {
|
||||||
|
super(/* keyHysteresisDistance */0);
|
||||||
|
mSlideAllowanceSquare = (int)(slideAllowance * slideAllowance);
|
||||||
|
// Top slide allowance is slightly longer (sqrt(2) times) than other edges.
|
||||||
|
mSlideAllowanceSquareTop = mSlideAllowanceSquare * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean alwaysAllowsSlidingInput() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getMaxNearbyKeys() {
|
||||||
|
// No nearby key will be returned.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
|
||||||
|
final List<Key> keys = getKeyboard().mKeys;
|
||||||
|
final int touchX = getTouchX(x);
|
||||||
|
final int touchY = getTouchY(y);
|
||||||
|
|
||||||
|
int nearestIndex = NOT_A_KEY;
|
||||||
|
int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
|
||||||
|
final int keyCount = keys.size();
|
||||||
|
for (int index = 0; index < keyCount; index++) {
|
||||||
|
final int dist = keys.get(index).squaredDistanceToEdge(touchX, touchY);
|
||||||
|
if (dist < nearestDist) {
|
||||||
|
nearestIndex = index;
|
||||||
|
nearestDist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allCodes != null && nearestIndex != NOT_A_KEY)
|
||||||
|
allCodes[0] = keys.get(nearestIndex).mCode;
|
||||||
|
return nearestIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy.Adapter();
|
||||||
|
|
||||||
|
private final KeyboardActionListener mSuggestionsPaneListener =
|
||||||
|
new KeyboardActionListener.Adapter() {
|
||||||
|
@Override
|
||||||
|
public void onPress(int primaryCode, boolean withSliding) {
|
||||||
|
mListener.onPress(primaryCode, withSliding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRelease(int primaryCode, boolean withSliding) {
|
||||||
|
mListener.onRelease(primaryCode, withSliding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
|
||||||
|
mListener.onCustomRequest(primaryCode - MoreSuggestions.SUGGESTION_CODE_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelInput() {
|
||||||
|
mListener.onCancelInput();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public MoreSuggestionsView(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, R.attr.suggestionsPaneViewStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoreSuggestionsView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
|
||||||
|
final Resources res = context.getResources();
|
||||||
|
// Override default ProximityKeyDetector.
|
||||||
|
mKeyDetector = new SuggestionsPaneKeyDetector(res.getDimension(
|
||||||
|
R.dimen.more_suggestions_slide_allowance));
|
||||||
|
// Remove gesture detector on suggestions pane
|
||||||
|
setKeyPreviewPopupEnabled(false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
final Keyboard keyboard = getKeyboard();
|
||||||
|
if (keyboard != null) {
|
||||||
|
final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight();
|
||||||
|
final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom();
|
||||||
|
setMeasuredDimension(width, height);
|
||||||
|
} else {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setKeyboard(Keyboard keyboard) {
|
||||||
|
super.setKeyboard(keyboard);
|
||||||
|
mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
|
||||||
|
-getPaddingTop() + mVerticalCorrection);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyDetector getKeyDetector() {
|
||||||
|
return mKeyDetector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyboardActionListener getKeyboardActionListener() {
|
||||||
|
return mSuggestionsPaneListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DrawingProxy getDrawingProxy() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimerProxy getTimerProxy() {
|
||||||
|
return EMPTY_TIMER_PROXY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
|
||||||
|
// Suggestions pane needs no pop-up key preview displayed, so we pass always false with a
|
||||||
|
// delay of 0. The delay does not matter actually since the popup is not shown anyway.
|
||||||
|
super.setKeyPreviewPopupEnabled(false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShifted(boolean shifted) {
|
||||||
|
// Nothing to do with.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showMoreKeysPanel(View parentView, Controller controller, int pointX, int pointY,
|
||||||
|
PopupWindow window, KeyboardActionListener listener) {
|
||||||
|
mController = controller;
|
||||||
|
mListener = listener;
|
||||||
|
final View container = (View)getParent();
|
||||||
|
final MoreSuggestions pane = (MoreSuggestions)getKeyboard();
|
||||||
|
|
||||||
|
parentView.getLocationInWindow(mCoordinates);
|
||||||
|
final int paneLeft = pointX - (pane.mOccupiedWidth / 2) + parentView.getPaddingLeft();
|
||||||
|
final int x = wrapUp(Math.max(0, Math.min(paneLeft,
|
||||||
|
parentView.getWidth() - pane.mOccupiedWidth))
|
||||||
|
- container.getPaddingLeft() + mCoordinates[0],
|
||||||
|
container.getMeasuredWidth(), 0, parentView.getWidth());
|
||||||
|
final int y = pointY
|
||||||
|
- (container.getMeasuredHeight() - container.getPaddingBottom())
|
||||||
|
+ parentView.getPaddingTop() + mCoordinates[1];
|
||||||
|
|
||||||
|
window.setContentView(container);
|
||||||
|
window.setWidth(container.getMeasuredWidth());
|
||||||
|
window.setHeight(container.getMeasuredHeight());
|
||||||
|
window.showAtLocation(parentView, Gravity.NO_GRAVITY, x, y);
|
||||||
|
|
||||||
|
mOriginX = x + container.getPaddingLeft() - mCoordinates[0];
|
||||||
|
mOriginY = y + container.getPaddingTop() - mCoordinates[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int wrapUp(int x, int width, int left, int right) {
|
||||||
|
if (x < left)
|
||||||
|
return left;
|
||||||
|
if (x + width > right)
|
||||||
|
return right - width;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dismissMoreKeysPanel() {
|
||||||
|
return mController.dismissMoreKeysPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int translateX(int x) {
|
||||||
|
return x - mOriginX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int translateY(int y) {
|
||||||
|
return y - mOriginY;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue