Merge "Initial changes to make folders accessible" into ics-mr1
This commit is contained in:
+18
-4
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user