am 1dd3a077: New gestures UI.

Merge commit '1dd3a077a293bf3ac4e61e91dcc3dfc99487acd4'

* commit '1dd3a077a293bf3ac4e61e91dcc3dfc99487acd4':
  New gestures UI.
This commit is contained in:
Romain Guy 2009-07-16 23:46:54 -07:00 committed by Android Git Automerger
commit aba68a3dbf
31 changed files with 453 additions and 171 deletions

View File

@ -94,7 +94,8 @@
<activity
android:name="GesturesActivity"
android:label="@string/gestures_activity" />
android:label="@string/gestures_activity"
android:theme="@android:style/Theme.Light.NoTitleBar" />
<!-- Enable system-default search mode for any activity in Home -->
<meta-data

View File

@ -16,17 +16,11 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_circle_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_circle_disable" />
android:drawable="@drawable/plus_normal" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_circle_pressed" />
android:drawable="@drawable/plus_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_circle_selected" />
android:drawable="@drawable/plus_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_circle_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_circle_disable_focused" />
<item
android:drawable="@drawable/btn_circle_disable" />
android:drawable="@drawable/plus_normal" />
</selector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 938 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

26
res/drawable/btn_g.xml Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 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_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/g_normal" />
<item android:state_pressed="true"
android:drawable="@drawable/g_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/g_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/g_normal" />
</selector>

26
res/drawable/btn_list.xml Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 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_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/list_normal" />
<item android:state_pressed="true"
android:drawable="@drawable/list_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/list_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/list_normal" />
</selector>

BIN
res/drawable/g_normal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
res/drawable/g_pressed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
res/drawable/g_selected.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

27
res/drawable/gestures_background.xml Executable file → Normal file
View File

@ -1,20 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2009 Romain Guy
<!-- Copyright (C) 2009 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
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
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.
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.
-->
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/texture_paper"
android:tileMode="repeat" />
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/gestures_frame"
android:dither="true" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 989 B

View File

@ -14,83 +14,89 @@
limitations under the License.
-->
<!-- Note: GesturesPanel is a special implementation that forces the widget
to be opaque for performance reasons. Make sure it visually is. -->
<!-- TODO: Replace all this with a RelativeLayout -->
<com.android.launcher.GesturesPanel
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gestures_panel"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
android:layout_height="fill_parent"
android:paddingLeft="13dip"
android:paddingRight="13dip"
android:orientation="vertical"
android:background="@drawable/gestures_background">
<ViewSwitcher
android:id="@+id/gestures_actions"
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="83dip"
android:layout_alignParentBottom="true"
android:inAnimation="@anim/fade_in_fast"
android:outAnimation="@anim/fade_out_fast"
android:foregroundGravity="top|fill_horizontal"
android:foreground="@*android:drawable/title_bar_shadow"
android:background="@android:drawable/title_bar_tall">
android:layout_height="wrap_content"
android:paddingTop="13dip"
android:paddingBottom="13dip">
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:gravity="center_vertical"
android:shadowColor="#FF000000"
android:shadowRadius="2.0"
android:drawablePadding="8dip"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/gestures_prompt"
android:layout_width="fill_parent"
android:layout_height="64dip"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:ellipsize="end"
android:maxLines="2"
android:maxLines="1"
android:singleLine="true"
android:text="@string/gestures_instructions" />
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
<Button
android:id="@+id/gestures_action"
android:layout_width="fill_parent"
android:layout_height="64dip"
android:gravity="center_vertical"
android:shadowColor="#FF000000"
android:shadowRadius="2.0"
android:drawablePadding="8dip"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="left|center_vertical"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:ellipsize="end"
android:maxLines="2"
android:text="@string/gestures_instructions" />
</ViewSwitcher>
android:maxLines="1"
android:singleLine="true"
android:drawablePadding="6dip"
android:visibility="gone" />
</FrameLayout>
<android.gesture.GestureOverlayView
android:id="@+id/gestures_overlay"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1.0"
android:layout_alignParentTop="true"
android:layout_above="@id/gestures_actions"
android:background="@drawable/gestures_background"
android:layout_marginLeft="6dip"
android:layout_marginRight="6dip"
android:gestureColor="@color/gesture_color"
android:uncertainGestureColor="@color/uncertain_gesture_color"
android:gestureStrokeType="multiple" />
<ImageButton
style="@style/PlusButton"
android:id="@+id/gestures_add"
android:layout_width="wrap_content"
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="@id/gestures_actions"
android:layout_marginRight="5dip"
android:layout_marginTop="-47dip" />
android:paddingTop="15dip"
android:paddingBottom="13dip">
<ImageButton
android:id="@+id/gestures_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:background="@drawable/btn_add" />
<ImageButton
android:id="@+id/gestures_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@drawable/btn_list" />
</RelativeLayout>
</com.android.launcher.GesturesPanel>

View File

@ -14,9 +14,7 @@
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ListView
android:id="@android:id/list"
@ -34,4 +32,4 @@
android:text="@string/gestures_loading"
android:textAppearance="?android:attr/textAppearanceMedium" />
</FrameLayout>
</merge>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 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.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
style="?android:attr/listSeparatorTextViewStyle" />

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 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="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dip"
android:layout_marginRight="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<TextView android:id="@+id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_alignLeft="@id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:maxLines="2" />
</RelativeLayout>
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="4dip"
android:layout_gravity="center_vertical"
android:focusable="false"
android:clickable="false" />
</LinearLayout>

View File

@ -26,5 +26,6 @@
<color name="appwidget_error_color">#FCCC</color>
<color name="snag_callout_color">#F444</color>
<color name="gesture_color">#FFFFFF00</color>
<color name="gesture_color">#ff0563c1</color>
<color name="uncertain_gesture_color">#ff848484</color>
</resources>

View File

@ -61,9 +61,4 @@
<item name="android:paddingRight">10dip</item>
</style>
<style name="PlusButton">
<item name="android:background">@drawable/btn_circle</item>
<item name="android:src">@drawable/ic_btn_round_plus</item>
</style>
</resources>

View File

@ -26,8 +26,11 @@ import android.widget.TextView;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.EditText;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.view.View;
import android.view.ViewGroup;
@ -40,18 +43,22 @@ import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.BitmapDrawable;
import android.text.TextUtils;
import android.database.DataSetObserver;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Collections;
import java.util.Map;
public class GesturesActivity extends ListActivity {
public class GesturesActivity extends ListActivity implements AdapterView.OnItemClickListener {
private static final int MENU_ID_RENAME = 1;
private static final int MENU_ID_REMOVE = 2;
private static final int DIALOG_RENAME_GESTURE = 1;
static final String PREFERENCES_NAME = "gestures";
static final String PREFERENCES_HOME_KEY = "gestures.home";
// Type: long (id)
private static final String GESTURES_INFO_ID = "gestures.info_id";
@ -66,6 +73,7 @@ public class GesturesActivity extends ListActivity {
private Dialog mRenameDialog;
private EditText mInput;
private ApplicationInfo mCurrentRenameInfo;
private SharedPreferences mPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -74,13 +82,16 @@ public class GesturesActivity extends ListActivity {
setContentView(R.layout.gestures_settings);
mAdapter = new GesturesAdapter(this);
setListAdapter(mAdapter);
setListAdapter(new GesturesSettingsAdapter(mAdapter));
getListView().setOnItemClickListener(this);
mStore = Launcher.getGestureLibrary();
mEmpty = (TextView) findViewById(android.R.id.empty);
mTask = (GesturesLoadTask) new GesturesLoadTask().execute();
registerForContextMenu(getListView());
mPreferences = getSharedPreferences(PREFERENCES_NAME, MODE_PRIVATE);
}
@Override
@ -127,10 +138,12 @@ public class GesturesActivity extends ListActivity {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
menu.setHeaderTitle(((TextView) info.targetView).getText());
if (info.position > 2) {
menu.setHeaderTitle(((TextView) info.targetView).getText());
menu.add(0, MENU_ID_RENAME, 0, R.string.gestures_rename);
menu.add(0, MENU_ID_REMOVE, 0, R.string.gestures_delete);
menu.add(0, MENU_ID_RENAME, 0, R.string.gestures_rename);
menu.add(0, MENU_ID_REMOVE, 0, R.string.gestures_delete);
}
}
@Override
@ -252,6 +265,14 @@ public class GesturesActivity extends ListActivity {
Toast.makeText(this, R.string.gestures_delete_success, Toast.LENGTH_SHORT).show();
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 1) {
final CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkbox);
checkBox.toggle();
mPreferences.edit().putBoolean(PREFERENCES_HOME_KEY, checkBox.isChecked()).commit();
}
}
private class GesturesLoadTask extends AsyncTask<Void, ApplicationInfo, Boolean> {
private int mThumbnailSize;
private int mThumbnailInset;
@ -346,4 +367,121 @@ public class GesturesActivity extends ListActivity {
return convertView;
}
}
private class GesturesSettingsAdapter extends BaseAdapter {
private static final int FIXED_CHILDREN_COUNT = 3;
private static final int VIEW_TYPE_SEPARATOR = 0;
private static final int VIEW_TYPE_CHECKBOX = 1;
private final GesturesAdapter mAdapter;
private final LayoutInflater mInflater;
public GesturesSettingsAdapter(GesturesAdapter adapter) {
mAdapter = adapter;
mInflater = adapter.mInflater;
adapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
notifyDataSetChanged();
}
@Override
public void onInvalidated() {
notifyDataSetInvalidated();
}
});
}
public int getCount() {
return FIXED_CHILDREN_COUNT + mAdapter.getCount();
}
public Object getItem(int position) {
if (position < FIXED_CHILDREN_COUNT) {
return String.valueOf(position);
}
return mAdapter.getItem(position - FIXED_CHILDREN_COUNT);
}
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
if (position < FIXED_CHILDREN_COUNT) {
switch (position) {
case 0:
case 2:
return VIEW_TYPE_SEPARATOR;
case 1:
return VIEW_TYPE_CHECKBOX;
}
}
return 2 + super.getItemViewType(position);
}
@Override
public int getViewTypeCount() {
return 2 + mAdapter.getViewTypeCount();
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return position != 0 && position != 2;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (position < FIXED_CHILDREN_COUNT) {
// NOTE: Don't bother with ViewHolders here, we only have 3 items and
// the list is likely to not be very long
switch (position) {
case 0:
convertView = createHeader(convertView, parent,
R.string.gestures_group_settings);
break;
case 1:
convertView = createSetting(convertView, parent,
R.string.gestures_preference_hotkey_title,
R.string.gestures_preference_hotkey_summary);
break;
case 2:
convertView = createHeader(convertView, parent,
R.string.gestures_group_gestures);
break;
}
return convertView;
}
return mAdapter.getView(position - FIXED_CHILDREN_COUNT, convertView, parent);
}
private View createSetting(View convertView, ViewGroup parent,
int title, int summary) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_checkbox_2lines, parent, false);
}
((TextView) convertView.findViewById(R.id.title)).setText(title);
((TextView) convertView.findViewById(R.id.summary)).setText(summary);
((CheckBox) convertView.findViewById(R.id.checkbox)).setChecked(
mPreferences.getBoolean(PREFERENCES_HOME_KEY, false));
return convertView;
}
private View createHeader(View convertView, ViewGroup parent, int text) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_category, parent, false);
}
((TextView) convertView).setText(text);
return convertView;
}
}
}

View File

@ -16,12 +16,12 @@
package com.android.launcher;
import android.widget.RelativeLayout;
import android.widget.LinearLayout;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
public class GesturesPanel extends RelativeLayout {
public class GesturesPanel extends LinearLayout {
public GesturesPanel(Context context) {
super(context);
}
@ -37,7 +37,26 @@ public class GesturesPanel extends RelativeLayout {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK &&
final int keyCode = event.getKeyCode();
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
case KeyEvent.KEYCODE_MUTE:
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_STOP:
case KeyEvent.KEYCODE_MEDIA_NEXT:
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
case KeyEvent.KEYCODE_MEDIA_REWIND:
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
case KeyEvent.KEYCODE_CAMERA:
case KeyEvent.KEYCODE_CALL:
case KeyEvent.KEYCODE_SEARCH:
return ((Launcher) mContext).getWorkspace().getRootView().dispatchKeyEvent(event);
}
if (keyCode == KeyEvent.KEYCODE_BACK &&
event.getAction() == KeyEvent.ACTION_DOWN) {
((Launcher) mContext).hideGesturesPanel();

View File

@ -32,6 +32,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.Intent.ShortcutIconResource;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
@ -79,7 +80,7 @@ import android.widget.TextView;
import android.widget.Toast;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.ViewSwitcher;
import android.widget.Button;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.gesture.GestureOverlayView;
@ -233,13 +234,14 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private View mGesturesPanel;
private GestureOverlayView mGesturesOverlay;
private ViewSwitcher mGesturesPrompt;
private ImageView mGesturesAdd;
private PopupWindow mGesturesWindow;
private Launcher.GesturesProcessor mGesturesProcessor;
private Gesture mCurrentGesture;
private GesturesAction mGesturesAction;
private boolean mHideGesturesPanel;
private TextView mGesturesPrompt;
private Button mGesturesSend;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -605,7 +607,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
mWorkspace.post(new Runnable() {
public void run() {
showGesturesPanel(false);
mGesturesProcessor.matchGesture(gesture, false);
mGesturesProcessor.matchGesture(gesture);
mWorkspace.post(new Runnable() {
public void run() {
if (gesture != null) {
@ -667,22 +669,26 @@ public final class Launcher extends Activity implements View.OnClickListener, On
mGesturesPanel = mInflater.inflate(R.layout.gestures, mDragLayer, false);
final View gesturesPanel = mGesturesPanel;
mGesturesPrompt = (ViewSwitcher) gesturesPanel.findViewById(R.id.gestures_actions);
mGesturesAction = new GesturesAction();
mGesturesPrompt.getChildAt(0).setOnClickListener(mGesturesAction);
mGesturesPrompt.getChildAt(1).setOnClickListener(mGesturesAction);
mGesturesPrompt = (TextView) gesturesPanel.findViewById(R.id.gestures_prompt);
mGesturesSend = (Button) gesturesPanel.findViewById(R.id.gestures_action);
mGesturesSend.setOnClickListener(mGesturesAction);
mGesturesAdd = (ImageView) gesturesPanel.findViewById(R.id.gestures_add);
final ImageView gesturesAdd = mGesturesAdd;
gesturesAdd.setAlpha(128);
gesturesAdd.setEnabled(false);
gesturesAdd.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
createGesture();
}
});
gesturesPanel.findViewById(R.id.gestures_list).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(Launcher.this, GesturesActivity.class));
}
});
mGesturesOverlay = (GestureOverlayView) gesturesPanel.findViewById(R.id.gestures_overlay);
mGesturesProcessor = new GesturesProcessor();
@ -976,17 +982,34 @@ public final class Launcher extends Activity implements View.OnClickListener, On
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) !=
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) {
if (mGesturesPanel != null && mDragLayer.getWindowVisibility() == View.VISIBLE &&
(mDragLayer.hasWindowFocus() ||
(mGesturesWindow != null && mGesturesWindow.isShowing()))) {
// TODO: This really should not be done here every time
final SharedPreferences preferences =
getSharedPreferences(GesturesActivity.PREFERENCES_NAME, MODE_PRIVATE);
final boolean homeKey = preferences.getBoolean(
GesturesActivity.PREFERENCES_HOME_KEY, false);
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
if (!homeKey) {
if (!mWorkspace.isDefaultScreenShowing()) {
mWorkspace.moveToDefaultScreen();
}
if (!searchManager.isVisible()) {
onHomeKeyPressed();
if (mGesturesWindow == null || mGesturesWindow.isShowing()) {
hideGesturesPanel();
}
} else {
if (mGesturesPanel != null && mDragLayer.getWindowVisibility() == View.VISIBLE
&& (mDragLayer.hasWindowFocus() || (mGesturesWindow != null
&& mGesturesWindow.isShowing()))) {
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
if (!searchManager.isVisible()) {
onHomeKeyPressed();
}
}
}
closeDrawer();
final View v = getWindow().peekDecorView();
@ -1016,8 +1039,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private void showGesturesPanel(boolean animate) {
resetGesturesPrompt();
mGesturesAdd.setEnabled(false);
mGesturesAdd.setAlpha(128);
mGesturesAdd.setVisibility(View.GONE);
mGesturesOverlay.clear(false);
@ -1027,12 +1049,13 @@ public final class Launcher extends Activity implements View.OnClickListener, On
window = mGesturesWindow;
window.setFocusable(true);
window.setTouchable(true);
window.setBackgroundDrawable(null);
window.setBackgroundDrawable(getResources().getDrawable(
android.R.drawable.screen_background_dark));
window.setContentView(mGesturesPanel);
} else {
window = mGesturesWindow;
}
window.setAnimationStyle(animate ? com.android.internal.R.style.Animation_SlidingCard : 0);
window.setAnimationStyle(animate ? com.android.internal.R.style.Animation_Toast : 0);
final int[] xy = new int[2];
final DragLayer dragLayer = mDragLayer;
@ -1045,31 +1068,23 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private void resetGesturesPrompt() {
mGesturesAction.intent = null;
final TextView prompt = (TextView) mGesturesPrompt.getCurrentView();
prompt.setText(R.string.gestures_instructions);
prompt.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
prompt.setClickable(false);
mGesturesPrompt.setText(R.string.gestures_instructions);
mGesturesPrompt.setVisibility(View.VISIBLE);
mGesturesSend.setVisibility(View.GONE);
}
private void resetGesturesNextPrompt() {
private void setGestureUnknown() {
mGesturesAction.intent = null;
setGesturesNextPrompt(null, getString(R.string.gestures_instructions));
mGesturesPrompt.getNextView().setClickable(false);
mGesturesPrompt.setText(R.string.gestures_unknown);
mGesturesPrompt.setVisibility(View.VISIBLE);
mGesturesSend.setVisibility(View.GONE);
}
private void setGesturesNextPrompt(Drawable icon, CharSequence title) {
final TextView prompt = (TextView) mGesturesPrompt.getNextView();
prompt.setText(title);
prompt.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
prompt.setClickable(true);
mGesturesPrompt.showNext();
}
private void setGesturesPrompt(Drawable icon, CharSequence title) {
final TextView prompt = (TextView) mGesturesPrompt.getCurrentView();
prompt.setText(title);
prompt.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
prompt.setClickable(true);
private void setGestureAction(Drawable icon, CharSequence title) {
mGesturesPrompt.setVisibility(View.GONE);
mGesturesSend.setVisibility(View.VISIBLE);
mGesturesSend.setText(title);
mGesturesSend.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
}
void hideGesturesPanel() {
@ -1080,7 +1095,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
if (mGesturesWindow != null) {
final PopupWindow popupWindow = mGesturesWindow;
popupWindow.setAnimationStyle(animate ?
com.android.internal.R.style.Animation_SlidingCard : 0);
com.android.internal.R.style.Animation_Toast : 0);
popupWindow.update();
popupWindow.dismiss();
}
@ -1270,10 +1285,10 @@ public final class Launcher extends Activity implements View.OnClickListener, On
.setIcon(com.android.internal.R.drawable.ic_menu_notifications)
.setAlphabeticShortcut('N');
final Intent gestures = new Intent(this, GesturesActivity.class);
// TODO: Remove
menu.add(0, MENU_GESTURES, 0, R.string.menu_gestures)
.setIcon(com.android.internal.R.drawable.ic_menu_compose).setAlphabeticShortcut('G')
.setIntent(gestures);
.setIcon(com.android.internal.R.drawable.ic_menu_compose)
.setAlphabeticShortcut('G');
final Intent settings = new Intent(android.provider.Settings.ACTION_SETTINGS);
settings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
@ -1311,6 +1326,9 @@ public final class Launcher extends Activity implements View.OnClickListener, On
case MENU_NOTIFICATIONS:
showNotifications();
return true;
case MENU_GESTURES:
showGesturesPanel();
return true;
}
return super.onOptionsItemSelected(item);
@ -2509,11 +2527,10 @@ public final class Launcher extends Activity implements View.OnClickListener, On
//noinspection PointlessBooleanExpression,ConstantConditions
if (!CONFIG_GESTURES_IMMEDIATE_MODE) {
overlay.removeCallbacks(mMatcher);
resetGesturesNextPrompt();
resetGesturesPrompt();
}
mGesturesAdd.setAlpha(128);
mGesturesAdd.setEnabled(false);
mGesturesAdd.setVisibility(View.GONE);
}
public void onGesture(GestureOverlayView overlay, MotionEvent event) {
@ -2529,7 +2546,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
overlay.clear(false);
if (mGesturesAction.intent != null) {
mGesturesAction.intent = null;
setGesturesNextPrompt(null, getString(R.string.gestures_unknown));
setGestureAction(null, getString(R.string.gestures_unknown));
}
} else {
mMatcher.run();
@ -2542,7 +2559,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
overlay.clear(false);
if (mGesturesAction.intent != null) {
mGesturesAction.intent = null;
setGesturesNextPrompt(null, getString(R.string.gestures_unknown));
setGestureAction(null, getString(R.string.gestures_unknown));
}
} else {
overlay.postDelayed(mMatcher, GesturesConstants.MATCH_DELAY);
@ -2551,12 +2568,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
}
void matchGesture(Gesture gesture) {
matchGesture(gesture, true);
}
void matchGesture(Gesture gesture, boolean animate) {
mGesturesAdd.setAlpha(255);
mGesturesAdd.setEnabled(true);
mGesturesAdd.setVisibility(View.VISIBLE);
if (gesture != null) {
final ArrayList<Prediction> predictions = sLibrary.recognize(gesture);
@ -2575,38 +2587,27 @@ public final class Launcher extends Activity implements View.OnClickListener, On
ApplicationInfo info = sModel.queryGesture(Launcher.this, prediction.name);
if (info != null) {
updatePrompt(info, animate);
updatePrompt(info);
}
}
}
if (!match){
mGesturesAction.intent = null;
if (animate) {
setGesturesNextPrompt(null, getString(R.string.gestures_unknown));
} else {
setGesturesPrompt(null, getString(R.string.gestures_unknown));
}
setGestureUnknown();
}
}
}
private void updatePrompt(ApplicationInfo info) {
updatePrompt(info, true);
}
private void updatePrompt(ApplicationInfo info, boolean animate) {
// TODO: BRING BACK
if (mGesturesAction.intent != null &&
info.intent.toUri(0).equals(mGesturesAction.intent.toUri(0)) &&
info.title.equals(((TextView) mGesturesPrompt.getCurrentView()).getText())) {
info.title.equals(mGesturesSend.getText())) {
return;
}
if (animate) {
setGesturesNextPrompt(info.icon, info.title);
} else {
setGesturesPrompt(info.icon, info.title);
}
setGestureAction(info.icon, info.title);
mGesturesAction.intent = info.intent;
}