Merge "New Launcher feature: "hotseat" icons." into froyo

This commit is contained in:
Daniel Sandler 2010-04-23 10:26:30 -07:00 committed by Android (Google) Code Review
commit e547b6238a
45 changed files with 277 additions and 51 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 688 B

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 830 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 695 B

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 821 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 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_pressed="true" android:drawable="@drawable/hotseat_browser_pressed" />
<item android:state_focused="true" android:state_window_focused="true" android:drawable="@drawable/hotseat_browser_focused" />
<item android:state_focused="true" android:state_window_focused="false" android:drawable="@drawable/hotseat_browser_normal" />
<item android:drawable="@drawable/hotseat_browser_normal" />
</selector>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 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_pressed="true" android:drawable="@drawable/hotseat_phone_pressed" />
<item android:state_focused="true" android:state_window_focused="true" android:drawable="@drawable/hotseat_phone_focused" />
<item android:state_focused="true" android:state_window_focused="false" android:drawable="@drawable/hotseat_phone_normal" />
<item android:drawable="@drawable/hotseat_phone_normal" />
</selector>

View File

@ -75,24 +75,11 @@
android:focusable="true" android:focusable="true"
android:clickable="true" /> android:clickable="true" />
<com.android.launcher2.HandleView
android:id="@+id/all_apps_button"
android:layout_width="@dimen/button_bar_height"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:focusable="true"
android:clickable="true"
android:scaleType="center"
android:src="@drawable/all_apps_button"
launcher:direction="vertical"
/>
<com.android.launcher2.DeleteZone <com.android.launcher2.DeleteZone
android:id="@+id/delete_zone" android:id="@+id/delete_zone"
android:layout_width="@dimen/button_bar_height" android:layout_width="@dimen/button_bar_height_portrait"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginBottom="@dimen/half_status_bar_height"
android:layout_gravity="right|center_vertical" android:layout_gravity="right|center_vertical"
android:scaleType="center" android:scaleType="center"
@ -101,4 +88,43 @@
launcher:direction="vertical" launcher:direction="vertical"
/> />
<RelativeLayout
android:id="@+id/all_apps_button_cluster"
android:layout_height="fill_parent"
android:layout_width="@dimen/button_bar_height_portrait"
android:layout_gravity="right|center_vertical"
android:layout_marginBottom="@dimen/half_status_bar_height"
android:padding="4dip"
>
<com.android.launcher2.HandleView
style="@style/HotseatButton"
android:id="@+id/all_apps_button"
android:layout_centerInParent="true"
android:src="@drawable/all_apps_button"
launcher:direction="vertical"
/>
<ImageView
android:id="@+id/hotseat_left"
style="@style/HotseatButton.Left"
android:layout_below="@id/all_apps_button"
android:src="@drawable/hotseat_phone"
android:onClick="launchHotSeat"
/>
<ImageView
android:id="@+id/hotseat_right"
style="@style/HotseatButton.Right"
android:layout_above="@id/all_apps_button"
android:src="@drawable/hotseat_browser"
android:onClick="launchHotSeat"
/>
</RelativeLayout>
</com.android.launcher2.DragLayer> </com.android.launcher2.DragLayer>

View File

@ -63,26 +63,12 @@
android:scaleType="center" android:scaleType="center"
android:src="@drawable/home_arrows_right" android:src="@drawable/home_arrows_right"
android:onClick="nextScreen" android:onClick="nextScreen"
android:focusable="true" android:focusable="true"
android:clickable="true" /> android:clickable="true" />
<com.android.launcher2.HandleView
android:id="@+id/all_apps_button"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_bar_height"
android:layout_gravity="bottom|center_horizontal"
android:focusable="true"
android:clickable="true"
android:scaleType="center"
android:src="@drawable/all_apps_button"
launcher:direction="horizontal"
/>
<com.android.launcher2.DeleteZone <com.android.launcher2.DeleteZone
android:id="@+id/delete_zone" android:id="@+id/delete_zone"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -95,4 +81,43 @@
launcher:direction="horizontal" launcher:direction="horizontal"
/> />
<RelativeLayout
android:id="@+id/all_apps_button_cluster"
android:layout_width="fill_parent"
android:layout_height="@dimen/button_bar_height"
android:layout_gravity="bottom|center_horizontal"
android:padding="4dip"
>
<com.android.launcher2.HandleView
style="@style/HotseatButton"
android:id="@+id/all_apps_button"
android:layout_centerInParent="true"
android:src="@drawable/all_apps_button"
launcher:direction="horizontal"
/>
<ImageView
android:id="@+id/hotseat_left"
style="@style/HotseatButton.Left"
android:layout_toLeftOf="@id/all_apps_button"
android:src="@drawable/hotseat_phone"
android:onClick="launchHotSeat"
/>
<ImageView
android:id="@+id/hotseat_right"
style="@style/HotseatButton.Right"
android:layout_toRightOf="@id/all_apps_button"
android:src="@drawable/hotseat_browser"
android:onClick="launchHotSeat"
/>
</RelativeLayout>
</com.android.launcher2.DragLayer> </com.android.launcher2.DragLayer>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright (C) 2008 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.
*/
-->
<resources>
<style name="HotseatButton">
<item name="android:paddingTop">12dip</item>
<item name="android:paddingBottom">12dip</item>
<item name="android:background">@drawable/hotseat_bg_center</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:scaleType">center</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
</style>
<style name="HotseatButton.Left">
<item name="android:layout_marginBottom">4dip</item>
<item name="android:background">@drawable/hotseat_bg_left</item>
</style>
<style name="HotseatButton.Right">
<item name="android:layout_marginTop">4dip</item>
<item name="android:background">@drawable/hotseat_bg_right</item>
</style>
</resources>

View File

@ -16,5 +16,15 @@
<resources> <resources>
<dimen name="title_texture_width">120px</dimen> <dimen name="title_texture_width">120px</dimen>
<!-- height of the bottom row of controls -->
<dimen name="button_bar_height">56dip</dimen> <dimen name="button_bar_height">56dip</dimen>
<!-- so we have access to this dimension in landscape mode even though
button_bar_height changes -->
<dimen name="button_bar_height_portrait">56dip</dimen>
<!-- roughly half a status bar (for vertically centering the right-hand
button cluster in landscape) -->
<dimen name="half_status_bar_height">12dip</dimen>
</resources> </resources>

View File

@ -65,4 +65,23 @@
<item name="android:paddingRight">10dip</item> <item name="android:paddingRight">10dip</item>
</style> </style>
<style name="HotseatButton">
<item name="android:paddingLeft">12dip</item>
<item name="android:paddingRight">12dip</item>
<item name="android:background">@drawable/hotseat_bg_center</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:scaleType">center</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
</style>
<style name="HotseatButton.Left">
<item name="android:layout_marginLeft">4dip</item>
<item name="android:background">@drawable/hotseat_bg_left</item>
</style>
<style name="HotseatButton.Right">
<item name="android:layout_marginRight">4dip</item>
<item name="android:background">@drawable/hotseat_bg_right</item>
</style>
</resources> </resources>

View File

@ -183,15 +183,7 @@ public class DeleteZone extends ImageView implements DropTarget, DragController.
animationSet.setDuration(ANIMATION_DURATION); animationSet.setDuration(ANIMATION_DURATION);
} }
if (mHandleInAnimation == null) { if (mHandleInAnimation == null) {
if (mOrientation == ORIENTATION_HORIZONTAL) { mHandleInAnimation = new AlphaAnimation(0.0f, 1.0f);
mHandleInAnimation = new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f,
Animation.RELATIVE_TO_SELF, 0.0f);
} else {
mHandleInAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 0.0f);
}
mHandleInAnimation.setDuration(ANIMATION_DURATION); mHandleInAnimation.setDuration(ANIMATION_DURATION);
} }
if (mOutAnimation == null) { if (mOutAnimation == null) {
@ -211,15 +203,7 @@ public class DeleteZone extends ImageView implements DropTarget, DragController.
animationSet.setDuration(ANIMATION_DURATION); animationSet.setDuration(ANIMATION_DURATION);
} }
if (mHandleOutAnimation == null) { if (mHandleOutAnimation == null) {
if (mOrientation == ORIENTATION_HORIZONTAL) { mHandleOutAnimation = new AlphaAnimation(1.0f, 0.0f);
mHandleOutAnimation = new FastTranslateAnimation(Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 1.0f);
} else {
mHandleOutAnimation = new FastTranslateAnimation(Animation.RELATIVE_TO_SELF,
0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 0.0f);
}
mHandleOutAnimation.setFillAfter(true); mHandleOutAnimation.setFillAfter(true);
mHandleOutAnimation.setDuration(ANIMATION_DURATION); mHandleOutAnimation.setDuration(ANIMATION_DURATION);
} }

View File

@ -26,12 +26,14 @@ import android.app.StatusBarManager;
import android.app.WallpaperManager; import android.app.WallpaperManager;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.Intent.ShortcutIconResource; import android.content.Intent.ShortcutIconResource;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
@ -41,6 +43,7 @@ import android.graphics.Rect;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Parcelable; import android.os.Parcelable;
@ -197,6 +200,17 @@ public final class Launcher extends Activity
private ImageView mPreviousView; private ImageView mPreviousView;
private ImageView mNextView; private ImageView mNextView;
// Hotseats (quick-launch icons next to AllApps)
// TODO: move these intial intents out to Uris in an XML resource
private static final int NUM_HOTSEATS = 2;
private Intent[] mHotseats = new Intent[] {
new Intent(Intent.ACTION_MAIN)
.setComponent(ComponentName.unflattenFromString(
"com.android.contacts/.ContactsLaunchActivity")),
new Intent(Intent.ACTION_WEB_SEARCH, Uri.EMPTY),
};
private CharSequence[] mHotseatLabels = new CharSequence[2];
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -215,6 +229,7 @@ public final class Launcher extends Activity
android.os.Debug.startMethodTracing("/sdcard/launcher"); android.os.Debug.startMethodTracing("/sdcard/launcher");
} }
loadHotseats();
checkForLocaleChange(); checkForLocaleChange();
setWallpaperDimension(); setWallpaperDimension();
@ -273,6 +288,8 @@ public final class Launcher extends Activity
writeConfiguration(this, localeConfiguration); writeConfiguration(this, localeConfiguration);
mIconCache.flush(); mIconCache.flush();
loadHotseats();
} }
} }
@ -351,6 +368,44 @@ public final class Launcher extends Activity
wpm.suggestDesiredDimensions(width * WALLPAPER_SCREENS_SPAN, height); wpm.suggestDesiredDimensions(width * WALLPAPER_SCREENS_SPAN, height);
} }
private void loadHotseats() {
PackageManager pm = getPackageManager();
for (int i=0; i<mHotseats.length; i++) {
Intent intent = mHotseats[i];
if (LOGD) {
Log.d(TAG, "loadHotseats: hotseat " + i
+ " initial intent=[" + intent.toUri(Intent.URI_INTENT_SCHEME)
+ "]");
}
// fix up the default intents
if (intent.getAction().equals(Intent.ACTION_WEB_SEARCH)
&& intent.getData().equals(Uri.EMPTY)) {
// use this to represent "default web browser"
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com/"));
}
ComponentName com = intent.resolveActivity(pm);
mHotseats[i] = new Intent(Intent.ACTION_MAIN).setComponent(com);
// load the labels for accessibility
try {
ActivityInfo ai = pm.getActivityInfo(com, 0);
mHotseatLabels[i] = ai.loadLabel(pm);
} catch (PackageManager.NameNotFoundException ex) {
mHotseatLabels[i] = "";
}
if (LOGD) {
Log.d(TAG, "loadHotseats: hotseat " + i
+ " intent=[" + mHotseats[i].toUri(Intent.URI_INTENT_SCHEME)
+ "] label=[" + mHotseatLabels[i]
+ "]"
);
}
}
}
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mWaitingForResult = false; mWaitingForResult = false;
@ -567,6 +622,9 @@ public final class Launcher extends Activity
mHandleView.setOnClickListener(this); mHandleView.setOnClickListener(this);
mHandleView.setOnLongClickListener(this); mHandleView.setOnLongClickListener(this);
findViewById(R.id.hotseat_left).setContentDescription(mHotseatLabels[0]);
findViewById(R.id.hotseat_right).setContentDescription(mHotseatLabels[1]);
mPreviousView = (ImageView) dragLayer.findViewById(R.id.previous_screen); mPreviousView = (ImageView) dragLayer.findViewById(R.id.previous_screen);
mNextView = (ImageView) dragLayer.findViewById(R.id.next_screen); mNextView = (ImageView) dragLayer.findViewById(R.id.next_screen);
@ -585,7 +643,7 @@ public final class Launcher extends Activity
deleteZone.setLauncher(this); deleteZone.setLauncher(this);
deleteZone.setDragController(dragController); deleteZone.setDragController(dragController);
deleteZone.setHandle(mHandleView); deleteZone.setHandle(findViewById(R.id.all_apps_button_cluster));
dragController.setDragScoller(workspace); dragController.setDragScoller(workspace);
dragController.setDragListener(deleteZone); dragController.setDragListener(deleteZone);
@ -610,6 +668,23 @@ public final class Launcher extends Activity
mWorkspace.scrollRight(); mWorkspace.scrollRight();
} }
} }
@SuppressWarnings({"UnusedDeclaration"})
public void launchHotSeat(View v) {
int index = -1;
if (v.getId() == R.id.hotseat_left) {
index = 0;
} else if (v.getId() == R.id.hotseat_right) {
index = 1;
}
if (index >= 0 && mHotseats[index] != null) {
startActivitySafely(
mHotseats[index],
"hotseat"
);
}
}
/** /**
* Creates a view representing a shortcut. * Creates a view representing a shortcut.
@ -1280,7 +1355,7 @@ public final class Launcher extends Activity
startActivity(intent); startActivity(intent);
} catch (ActivityNotFoundException e) { } catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent); Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
} catch (SecurityException e) { } catch (SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Launcher does not have the permission to launch " + intent + Log.e(TAG, "Launcher does not have the permission to launch " + intent +