summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml22
-rw-r--r--core/java/android/widget/TextView.java104
-rw-r--r--core/res/res/drawable-hdpi/text_edit_side_paste_window.9.pngbin0 -> 892 bytes
-rw-r--r--core/res/res/drawable-mdpi/text_edit_side_paste_window.9.pngbin0 -> 426 bytes
-rw-r--r--core/res/res/layout/text_edit_side_no_paste_window.xml38
-rw-r--r--core/res/res/layout/text_edit_side_paste_window.xml38
-rwxr-xr-xcore/res/res/values/attrs.xml11
-rw-r--r--core/res/res/values/public.xml2
-rw-r--r--core/res/res/values/styles.xml2
-rw-r--r--core/res/res/values/themes.xml2
10 files changed, 189 insertions, 30 deletions
diff --git a/api/current.xml b/api/current.xml
index 52d48b63a0ac..8655ad32f8fd 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -9926,6 +9926,28 @@
visibility="public"
>
</field>
+<field name="textEditSideNoPasteWindowLayout"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843615"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="textEditSidePasteWindowLayout"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843614"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="textFilterEnabled"
type="int"
transient="false"
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d09e52f7ba8b..fad0a4f43d48 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -307,8 +307,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
int mTextSelectHandleLeftRes;
int mTextSelectHandleRightRes;
int mTextSelectHandleRes;
- int mTextEditPasteWindowLayout;
- int mTextEditNoPasteWindowLayout;
+ int mTextEditPasteWindowLayout, mTextEditSidePasteWindowLayout;
+ int mTextEditNoPasteWindowLayout, mTextEditSideNoPasteWindowLayout;
Drawable mSelectHandleLeft;
Drawable mSelectHandleRight;
@@ -762,6 +762,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mTextEditNoPasteWindowLayout = a.getResourceId(attr, 0);
break;
+ case com.android.internal.R.styleable.TextView_textEditSidePasteWindowLayout:
+ mTextEditSidePasteWindowLayout = a.getResourceId(attr, 0);
+ break;
+
+ case com.android.internal.R.styleable.TextView_textEditSideNoPasteWindowLayout:
+ mTextEditSideNoPasteWindowLayout = a.getResourceId(attr, 0);
+ break;
+
case com.android.internal.R.styleable.TextView_textIsSelectable:
mTextIsSelectable = a.getBoolean(attr, false);
break;
@@ -8422,8 +8430,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private final PopupWindow mContainer;
private int mPositionX;
private int mPositionY;
- private View mPasteView, mNoPasteView;
-
+ private final View[] mPasteViews = new View[4];
+ private final int[] mPasteViewLayouts = new int[] {
+ mTextEditPasteWindowLayout, mTextEditNoPasteWindowLayout,
+ mTextEditSidePasteWindowLayout, mTextEditSideNoPasteWindowLayout };
+
public PastePopupMenu() {
mContainer = new PopupWindow(TextView.this.mContext, null,
com.android.internal.R.attr.textSelectHandleWindowStyle);
@@ -8435,12 +8446,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mContainer.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
}
- private void updateContent() {
- View view = canPaste() ? mPasteView : mNoPasteView;
+ private int viewIndex(boolean onTop) {
+ return (onTop ? 0 : 1<<1) + (canPaste() ? 0 : 1<<0);
+ }
+
+ private void updateContent(boolean onTop) {
+ final int viewIndex = viewIndex(onTop);
+ View view = mPasteViews[viewIndex];
if (view == null) {
- final int layout = canPaste() ? mTextEditPasteWindowLayout :
- mTextEditNoPasteWindowLayout;
+ final int layout = mPasteViewLayouts[viewIndex];
LayoutInflater inflater = (LayoutInflater)TextView.this.mContext.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (inflater != null) {
@@ -8457,26 +8472,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
view.measure(size, size);
view.setOnClickListener(this);
-
- if (canPaste()) mPasteView = view;
- else mNoPasteView = view;
+
+ mPasteViews[viewIndex] = view;
}
mContainer.setContentView(view);
}
public void show() {
- updateContent();
- final int[] coords = mTempCoords;
- TextView.this.getLocationInWindow(coords);
+ updateContent(true);
positionAtCursor();
- coords[0] += mPositionX;
- coords[1] += mPositionY;
- coords[0] = Math.max(0, coords[0]);
- final int screenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
- coords[0] = Math.min(screenWidth - mContainer.getContentView().getMeasuredWidth(),
- coords[0]);
- mContainer.showAtLocation(TextView.this, Gravity.NO_GRAVITY, coords[0], coords[1]);
}
public void hide() {
@@ -8496,15 +8501,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
void positionAtCursor() {
- final int offset = TextView.this.getSelectionStart();
View contentView = mContainer.getContentView();
- final int width = contentView.getMeasuredWidth();
- final int height = contentView.getMeasuredHeight();
+ int width = contentView.getMeasuredWidth();
+ int height = contentView.getMeasuredHeight();
+ final int offset = TextView.this.getSelectionStart();
final int line = mLayout.getLineForOffset(offset);
final int lineTop = mLayout.getLineTop(line);
+ float primaryHorizontal = mLayout.getPrimaryHorizontal(offset);
final Rect bounds = sCursorControllerTempRect;
- bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - width / 2.0f);
+ bounds.left = (int) (primaryHorizontal - width / 2.0f);
bounds.top = lineTop - height;
bounds.right = bounds.left + width;
@@ -8514,6 +8520,44 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mPositionX = bounds.left;
mPositionY = bounds.top;
+
+
+ final int[] coords = mTempCoords;
+ TextView.this.getLocationInWindow(coords);
+ coords[0] += mPositionX;
+ coords[1] += mPositionY;
+
+ final int screenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
+ if (coords[1] < 0) {
+ updateContent(false);
+ // Update dimensions from new view
+ contentView = mContainer.getContentView();
+ width = contentView.getMeasuredWidth();
+ height = contentView.getMeasuredHeight();
+
+ // Vertical clipping, move under edited line and to the side of insertion cursor
+ // TODO bottom clipping in case there is no system bar
+ coords[1] += height;
+ final int lineBottom = mLayout.getLineBottom(line);
+ final int lineHeight = lineBottom - lineTop;
+ coords[1] += lineHeight;
+
+ // Move to right hand side of insertion cursor by default. TODO RTL text.
+ final Drawable handle = mContext.getResources().getDrawable(mTextSelectHandleRes);
+ final int handleHalfWidth = handle.getIntrinsicWidth() / 2;
+
+ if (primaryHorizontal + handleHalfWidth + width < screenWidth) {
+ coords[0] += handleHalfWidth + width / 2;
+ } else {
+ coords[0] -= handleHalfWidth + width / 2;
+ }
+ } else {
+ // Horizontal clipping
+ coords[0] = Math.max(0, coords[0]);
+ coords[0] = Math.min(screenWidth - width, coords[0]);
+ }
+
+ mContainer.showAtLocation(TextView.this, Gravity.NO_GRAVITY, coords[0], coords[1]);
}
}
@@ -8915,11 +8959,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
hideDelayed();
getHandle().show();
removePastePopupCallback();
- if (canPaste()) {
- final long durationSinceCutOrCopy = SystemClock.uptimeMillis() - sLastCutOrCopyTime;
- if (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION) {
- delayBeforePaste = 0;
- }
+ final long durationSinceCutOrCopy = SystemClock.uptimeMillis() - sLastCutOrCopyTime;
+ if (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION) {
+ delayBeforePaste = 0;
+ }
+ if (delayBeforePaste == 0 || canPaste()) {
if (mPastePopupShower == null) {
mPastePopupShower = new Runnable() {
public void run() {
diff --git a/core/res/res/drawable-hdpi/text_edit_side_paste_window.9.png b/core/res/res/drawable-hdpi/text_edit_side_paste_window.9.png
new file mode 100644
index 000000000000..7cd000bfd47d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/text_edit_side_paste_window.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_edit_side_paste_window.9.png b/core/res/res/drawable-mdpi/text_edit_side_paste_window.9.png
new file mode 100644
index 000000000000..d87c35b85bdd
--- /dev/null
+++ b/core/res/res/drawable-mdpi/text_edit_side_paste_window.9.png
Binary files differ
diff --git a/core/res/res/layout/text_edit_side_no_paste_window.xml b/core/res/res/layout/text_edit_side_no_paste_window.xml
new file mode 100644
index 000000000000..0ed384979ecd
--- /dev/null
+++ b/core/res/res/layout/text_edit_side_no_paste_window.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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">
+
+ <TextView android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
+ android:drawableLeft="@android:drawable/ic_menu_paste_dark"
+ android:drawablePadding="8dip"
+ android:gravity="center"
+ android:textAppearance="?android:attr/textAppearanceMediumInverse"
+ android:textColor="@android:color/dim_foreground_dark_inverse_disabled"
+ android:background="@android:drawable/text_edit_side_paste_window"
+ android:text="@android:string/pasteDisabled"
+ android:layout_marginBottom="12dip"
+ />
+
+</LinearLayout>
diff --git a/core/res/res/layout/text_edit_side_paste_window.xml b/core/res/res/layout/text_edit_side_paste_window.xml
new file mode 100644
index 000000000000..689a0392a8fe
--- /dev/null
+++ b/core/res/res/layout/text_edit_side_paste_window.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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">
+
+ <TextView android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
+ android:drawableLeft="@android:drawable/ic_menu_paste_light"
+ android:drawablePadding="8dip"
+ android:gravity="center"
+ android:textAppearance="?android:attr/textAppearanceMediumInverse"
+ android:textColor="@android:color/black"
+ android:background="@android:drawable/text_edit_side_paste_window"
+ android:text="@android:string/paste"
+ android:layout_marginBottom="12dip"
+ />
+
+</LinearLayout>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index fbd5b5e81234..e76692ad3ee0 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -649,6 +649,11 @@
<attr name="textEditPasteWindowLayout" format="reference" />
<!-- Variation of textEditPasteWindowLayout displayed when the clipboard is empty. -->
<attr name="textEditNoPasteWindowLayout" format="reference" />
+ <!-- Used instead of textEditPasteWindowLayout when the window is moved on the side of the
+ insertion cursor because it would be clipped if it were positioned on top. -->
+ <attr name="textEditSidePasteWindowLayout" format="reference" />
+ <!-- Variation of textEditSidePasteWindowLayout displayed when the clipboard is empty. -->
+ <attr name="textEditSideNoPasteWindowLayout" format="reference" />
<!-- Theme to use for dialogs spawned from this theme. -->
<attr name="dialogTheme" format="reference" />
@@ -2741,6 +2746,12 @@
<attr name="textEditPasteWindowLayout" />
<!-- Variation of textEditPasteWindowLayout displayed when the clipboard is empty. -->
<attr name="textEditNoPasteWindowLayout" />
+ <!-- Used instead of textEditPasteWindowLayout when the window is moved on the side of the
+ insertion cursor because it would be clipped if it were positioned on top. -->
+ <attr name="textEditSidePasteWindowLayout" />
+ <!-- Variation of textEditSidePasteWindowLayout displayed when the clipboard is empty. -->
+ <attr name="textEditSideNoPasteWindowLayout" />
+
<!-- Indicates that the content of a non-editable text can be selected. -->
<attr name="textIsSelectable" />
</declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 786c4d080acf..e6552dfcea8b 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1633,6 +1633,8 @@
<public type="style" name="Widget.Holo.Light.CalendarView" />
<public type="style" name="Widget.DatePicker" />
<public type="style" name="Widget.Holo.DatePicker" />
+ <public type="attr" name="textEditSidePasteWindowLayout" />
+ <public type="attr" name="textEditSideNoPasteWindowLayout" />
<public type="string" name="selectTextMode" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 939e9ef10063..2c627309c880 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -419,6 +419,8 @@
<item name="android:textSelectHandle">?android:attr/textSelectHandle</item>
<item name="android:textEditPasteWindowLayout">?android:attr/textEditPasteWindowLayout</item>
<item name="android:textEditNoPasteWindowLayout">?android:attr/textEditNoPasteWindowLayout</item>
+ <item name="android:textEditSidePasteWindowLayout">?android:attr/textEditSidePasteWindowLayout</item>
+ <item name="android:textEditSideNoPasteWindowLayout">?android:attr/textEditSideNoPasteWindowLayout</item>
</style>
<style name="Widget.TextView.ListSeparator">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 2f8cffcb3505..e6e23aa06044 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -174,6 +174,8 @@
<item name="textSelectHandleWindowStyle">@android:style/Widget.TextSelectHandle</item>
<item name="textEditPasteWindowLayout">@android:layout/text_edit_paste_window</item>
<item name="textEditNoPasteWindowLayout">@android:layout/text_edit_no_paste_window</item>
+ <item name="textEditSidePasteWindowLayout">@android:layout/text_edit_side_paste_window</item>
+ <item name="textEditSideNoPasteWindowLayout">@android:layout/text_edit_side_no_paste_window</item>
<!-- Widget styles -->
<item name="absListViewStyle">@android:style/Widget.AbsListView</item>