Merge "Initial changes to make folders accessible" into ics-mr1

This commit is contained in:
Adam Cohen
2011-10-26 14:48:57 -07:00
committed by Android (Google) Code Review
5 changed files with 134 additions and 14 deletions
+18 -4
View File
@@ -208,13 +208,13 @@ s -->
<skip />
<!-- The format string for default page scroll text [CHAR_LIMIT=none] -->
<string name="default_scroll_format" translatable="false">Page %1$d of %2$d</string>
<string name="default_scroll_format">Page %1$d of %2$d</string>
<!-- The format string for Workspace page scroll text [CHAR_LIMIT=none] -->
<string name="workspace_scroll_format" translatable="false">Workspace %1$d of %2$d</string>
<string name="workspace_scroll_format">Workspace %1$d of %2$d</string>
<!-- The format string for AppsCustomize Apps page scroll text [CHAR_LIMIT=none] -->
<string name="apps_customize_apps_scroll_format" translatable="false">Apps page %1$d of %2$d</string>
<string name="apps_customize_apps_scroll_format">Apps page %1$d of %2$d</string>
<!-- The format string for AppsCustomize Apps page scroll text [CHAR_LIMIT=none] -->
<string name="apps_customize_widgets_scroll_format" translatable="false">Widgets page %1$d of %2$d</string>
<string name="apps_customize_widgets_scroll_format">Widgets page %1$d of %2$d</string>
<!-- Clings -->
<!-- The title text for the workspace cling [CHAR_LIMIT=none] -->
@@ -237,4 +237,18 @@ s -->
<string name="cling_dismiss">OK</string>
<add-resource type="string" name="default_folder_name" />
<!-- Folder accessibility -->
<!-- The format string for when a folder is opened, speaks the dimensions -->
<string name="folder_opened">Folder opened, %1$d by %2$d</string>
<!-- Instruction that clicking outside will close folder -->
<string name="folder_tap_to_close">Tap to close folder</string>
<!-- Instruction that clicking outside will commit folder rename -->
<string name="folder_tap_to_rename">Tap to commit rename</string>
<!-- Indication that folder closed -->
<string name="folder_closed">Folder closed</string>
<!-- Folder renamed format -->
<string name="folder_renamed">Folder renamed to %1$s</string>
<!-- Folder name format -->
<string name="folder_name_format">Folder: %1$s</string>
</resources>
+79 -3
View File
@@ -32,6 +32,8 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
@@ -65,6 +67,8 @@ public class DragLayer extends FrameLayout {
private int[] mDropViewPos = new int[2];
private float mDropViewScale;
private float mDropViewAlpha;
private boolean mHoverPointClosesFolder = false;
private Rect mHitRect = new Rect();
/**
* Used to create a new DragLayer from XML.
@@ -89,6 +93,22 @@ public class DragLayer extends FrameLayout {
return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}
private boolean isEventOverFolderTextRegion(Folder folder, MotionEvent ev) {
getDescendantRectRelativeToSelf(folder.getEditTextRegion(), mHitRect);
if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) {
return true;
}
return false;
}
private boolean isEventOverFolder(Folder folder, MotionEvent ev) {
getDescendantRectRelativeToSelf(folder, mHitRect);
if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) {
return true;
}
return false;
}
private boolean handleTouchDown(MotionEvent ev, boolean intercept) {
Rect hitRect = new Rect();
int x = (int) ev.getX();
@@ -110,15 +130,14 @@ public class DragLayer extends FrameLayout {
Folder currentFolder = mLauncher.getWorkspace().getOpenFolder();
if (currentFolder != null && !mLauncher.isFolderClingVisible() && intercept) {
if (currentFolder.isEditingName()) {
getDescendantRectRelativeToSelf(currentFolder.getEditTextRegion(), hitRect);
if (!hitRect.contains(x, y)) {
if (!isEventOverFolderTextRegion(currentFolder, ev)) {
currentFolder.dismissEditingName();
return true;
}
}
getDescendantRectRelativeToSelf(currentFolder, hitRect);
if (!hitRect.contains(x, y)) {
if (!isEventOverFolder(currentFolder, ev)) {
mLauncher.closeFolder();
return true;
}
@@ -137,6 +156,63 @@ public class DragLayer extends FrameLayout {
return mDragController.onInterceptTouchEvent(ev);
}
@Override
public boolean onInterceptHoverEvent(MotionEvent ev) {
Folder currentFolder = mLauncher.getWorkspace().getOpenFolder();
if (currentFolder == null) {
return false;
} else {
if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) {
final int action = ev.getAction();
boolean isOverFolder;
switch (action) {
case MotionEvent.ACTION_HOVER_ENTER:
isOverFolder = isEventOverFolder(currentFolder, ev);
if (!isOverFolder) {
sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName());
mHoverPointClosesFolder = true;
return true;
} else if (isOverFolder) {
mHoverPointClosesFolder = false;
} else {
return true;
}
case MotionEvent.ACTION_HOVER_MOVE:
isOverFolder = isEventOverFolder(currentFolder, ev);
if (!isOverFolder && !mHoverPointClosesFolder) {
sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName());
mHoverPointClosesFolder = true;
return true;
} else if (isOverFolder) {
mHoverPointClosesFolder = false;
} else {
return true;
}
}
}
}
return false;
}
private void sendTapOutsideFolderAccessibilityEvent(boolean isEditingName) {
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
Folder currentFolder = mLauncher.getWorkspace().getOpenFolder();
int stringId = isEditingName ? R.string.folder_tap_to_rename : R.string.folder_tap_to_close;
AccessibilityEvent event = AccessibilityEvent.obtain(
AccessibilityEvent.TYPE_VIEW_FOCUSED);
onInitializeAccessibilityEvent(event);
event.getText().add(mContext.getString(stringId));
AccessibilityManager.getInstance(mContext).sendAccessibilityEvent(event);
}
}
@Override
public boolean onHoverEvent(MotionEvent ev) {
// If we've received this, we've already done the necessary handling
// in onInterceptHoverEvent. Return true to consume the event.
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean handled = false;
+28 -2
View File
@@ -37,6 +37,8 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.EditorInfo;
@@ -95,7 +97,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
private Alarm mReorderAlarm = new Alarm();
private Alarm mOnExitAlarm = new Alarm();
private int mFolderNameHeight;
private Rect mHitRect = new Rect();
private Rect mTempRect = new Rect();
private boolean mDragInProgress = false;
private boolean mDeleteFolderOnDropCompleted = false;
@@ -240,9 +241,14 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
mFolderName.setHint(sHintText);
// Convert to a string here to ensure that no other state associated with the text field
// gets saved.
mInfo.setTitle(mFolderName.getText().toString());
String newTitle = mFolderName.getText().toString();
mInfo.setTitle(newTitle);
LauncherModel.updateItemInDatabase(mLauncher, mInfo);
if (commit) {
sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
String.format(mContext.getString(R.string.folder_renamed), newTitle));
}
// In order to clear the focus from the text field, we set the focus on ourself. This
// ensures that every time the field is clicked, focus is gained, giving reliable behavior.
requestFocus();
@@ -283,6 +289,12 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
mFolderIcon = icon;
}
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
// When the folder gets focus, we don't want to announce the list of items.
return true;
}
/**
* @return the FolderInfo object associated with this folder
*/
@@ -398,6 +410,9 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
oa.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
String.format(mContext.getString(R.string.folder_opened),
mContent.getCountX(), mContent.getCountY()));
mState = STATE_ANIMATING;
}
@Override
@@ -415,6 +430,15 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
oa.start();
}
private void sendCustomAccessibilityEvent(int type, String text) {
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain(type);
onInitializeAccessibilityEvent(event);
event.getText().add(text);
AccessibilityManager.getInstance(mContext).sendAccessibilityEvent(event);
}
}
private void setFocusOnFirstChild() {
View firstChild = mContent.getChildAt(0, 0);
if (firstChild != null) {
@@ -460,6 +484,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
}
@Override
public void onAnimationStart(Animator animation) {
sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
mContext.getString(R.string.folder_closed));
mState = STATE_ANIMATING;
}
});
+5 -4
View File
@@ -32,6 +32,7 @@ import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
@@ -122,19 +123,18 @@ public class FolderIcon extends LinearLayout implements FolderListener {
icon.mFolderName = (BubbleTextView) icon.findViewById(R.id.folder_icon_name);
icon.mFolderName.setText(folderInfo.title);
icon.mPreviewBackground = (ImageView) icon.findViewById(R.id.preview_background);
icon.mPreviewBackground.setContentDescription(folderInfo.title);
icon.setTag(folderInfo);
icon.setOnClickListener(launcher);
icon.mInfo = folderInfo;
icon.mLauncher = launcher;
icon.setContentDescription(String.format(launcher.getString(R.string.folder_name_format),
folderInfo.title));
Folder folder = Folder.fromXml(launcher);
folder.setDragController(launcher.getDragController());
folder.setFolderIcon(icon);
folder.bind(folderInfo);
icon.mFolder = folder;
Resources res = launcher.getResources();
icon.mFolderRingAnimator = new FolderRingAnimator(launcher, icon);
folderInfo.addListener(icon);
@@ -587,6 +587,7 @@ public class FolderIcon extends LinearLayout implements FolderListener {
public void onTitleChanged(CharSequence title) {
mFolderName.setText(title.toString());
mPreviewBackground.setContentDescription(title.toString());
setContentDescription(String.format(mContext.getString(R.string.folder_name_format),
title));
}
}
@@ -25,6 +25,8 @@ import android.content.IntentFilter;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.os.Handler;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import java.lang.ref.WeakReference;
@@ -40,7 +42,8 @@ public class LauncherApplication extends Application {
super.onCreate();
// set sIsScreenXLarge and sScreenDensity *before* creating icon cache
final int screenSize = getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
final int screenSize = getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK;
sIsScreenLarge = screenSize == Configuration.SCREENLAYOUT_SIZE_LARGE ||
screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE;
sScreenDensity = getResources().getDisplayMetrics().density;