diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png new file mode 100644 index 0000000000000..84e6bc89c0829 Binary files /dev/null and b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png differ diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back_default.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back_default.png deleted file mode 100644 index ac5a97b24a931..0000000000000 Binary files a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back_default.png and /dev/null differ diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png new file mode 100644 index 0000000000000..38e4f45719e7f Binary files /dev/null and b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png differ diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home_default.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home_default.png deleted file mode 100644 index a90dc9b131bbf..0000000000000 Binary files a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home_default.png and /dev/null differ diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png new file mode 100644 index 0000000000000..bf9f3009c32c2 Binary files /dev/null and b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png differ diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent_default.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent_default.png deleted file mode 100644 index cb3c4331089fe..0000000000000 Binary files a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent_default.png and /dev/null differ diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png new file mode 100644 index 0000000000000..a00bc5b5f33b1 Binary files /dev/null and b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png differ diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back_default.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back_default.png deleted file mode 100644 index 5ab09f0adaada..0000000000000 Binary files a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back_default.png and /dev/null differ diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png new file mode 100644 index 0000000000000..dc3183bf640f8 Binary files /dev/null and b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png differ diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home_default.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home_default.png deleted file mode 100644 index 62ca4276f3268..0000000000000 Binary files a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home_default.png and /dev/null differ diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png new file mode 100644 index 0000000000000..b07f611ab98c1 Binary files /dev/null and b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png differ diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent_default.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent_default.png deleted file mode 100644 index ff698fb6efa68..0000000000000 Binary files a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent_default.png and /dev/null differ diff --git a/tools/layoutlib/bridge/resources/bars/navigation_bar.xml b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml new file mode 100644 index 0000000000000..599ca08bf02cb --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml b/tools/layoutlib/bridge/resources/bars/status_bar.xml similarity index 100% rename from tools/layoutlib/bridge/resources/bars/phone_system_bar.xml rename to tools/layoutlib/bridge/resources/bars/status_bar.xml diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png new file mode 100644 index 0000000000000..bd60cd65878a3 Binary files /dev/null and b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png differ diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back_default.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back_default.png deleted file mode 100644 index 4cb305d359301..0000000000000 Binary files a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back_default.png and /dev/null differ diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png new file mode 100644 index 0000000000000..c5bc5c96ef051 Binary files /dev/null and b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png differ diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home_default.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home_default.png deleted file mode 100644 index 31d35c8f55708..0000000000000 Binary files a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home_default.png and /dev/null differ diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png new file mode 100644 index 0000000000000..f621d9cc72428 Binary files /dev/null and b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png differ diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent_default.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent_default.png deleted file mode 100644 index f0cc341ddb984..0000000000000 Binary files a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent_default.png and /dev/null differ diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java index daf520b5415ab..bf8658e402b06 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -210,7 +210,8 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { Capability.PLAY_ANIMATION, Capability.ANIMATED_VIEW_MANIPULATION, Capability.ADAPTER_BINDING, - Capability.EXTENDED_VIEWINFO); + Capability.EXTENDED_VIEWINFO, + Capability.FIXED_SCALABLE_NINE_PATCH); BridgeAssetManager.initSystem(); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java index 62c886b903067..ec9ec75283eb0 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java @@ -56,15 +56,19 @@ import java.io.InputStream; * * It also provides a few utility methods to configure the content of the layout. */ -abstract class CustomBar extends LinearLayout { +public abstract class CustomBar extends LinearLayout { protected abstract TextView getStyleableTextView(); - protected CustomBar(Context context, Density density, String layoutPath, String name) - throws XmlPullParserException { + protected CustomBar(Context context, Density density, int orientation, String layoutPath, + String name) throws XmlPullParserException { super(context); - setOrientation(LinearLayout.HORIZONTAL); - setGravity(Gravity.CENTER_VERTICAL); + setOrientation(orientation); + if (orientation == LinearLayout.HORIZONTAL) { + setGravity(Gravity.CENTER_VERTICAL); + } else { + setGravity(Gravity.CENTER_HORIZONTAL); + } LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java index 68f5aba1fc121..226649dbc4069 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java @@ -21,6 +21,7 @@ import com.android.resources.Density; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; +import android.widget.LinearLayout; import android.widget.TextView; public class FakeActionBar extends CustomBar { @@ -29,7 +30,7 @@ public class FakeActionBar extends CustomBar { public FakeActionBar(Context context, Density density, String label, String icon) throws XmlPullParserException { - super(context, density, "/bars/action_bar.xml", "action_bar.xml"); + super(context, density, LinearLayout.HORIZONTAL, "/bars/action_bar.xml", "action_bar.xml"); // Cannot access the inside items through id because no R.id values have been // created for them. diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java new file mode 100644 index 0000000000000..cc90d6b33abed --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2011 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. + */ + +package com.android.layoutlib.bridge.bars; + +import com.android.resources.Density; + +import org.xmlpull.v1.XmlPullParserException; + +import android.content.Context; +import android.widget.LinearLayout; +import android.widget.TextView; + +public class NavigationBar extends CustomBar { + + public NavigationBar(Context context, Density density, int orientation) throws XmlPullParserException { + super(context, density, orientation, "/bars/navigation_bar.xml", "navigation_bar.xml"); + + setBackgroundColor(0xFF000000); + + // Cannot access the inside items through id because no R.id values have been + // created for them. + // We do know the order though. + // 0 is a spacer. + int back = 1; + int recent = 3; + if (orientation == LinearLayout.VERTICAL) { + back = 3; + recent = 1; + } + + loadIcon(back, "ic_sysbar_back.png", density); + loadIcon(2, "ic_sysbar_home.png", density); + loadIcon(recent, "ic_sysbar_recent.png", density); + } + + @Override + protected TextView getStyleableTextView() { + return null; + } +} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java similarity index 86% rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java index 7521011c76e87..5c084121d123a 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java @@ -25,12 +25,13 @@ import android.content.Context; import android.graphics.drawable.Drawable; import android.graphics.drawable.LevelListDrawable; import android.view.Gravity; +import android.widget.LinearLayout; import android.widget.TextView; -public class PhoneSystemBar extends CustomBar { +public class StatusBar extends CustomBar { - public PhoneSystemBar(Context context, Density density) throws XmlPullParserException { - super(context, density, "/bars/phone_system_bar.xml", "phone_system_bar.xml"); + public StatusBar(Context context, Density density) throws XmlPullParserException { + super(context, density, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml"); // FIXME: use FILL_H? setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java index 456ddb4983ce2..5ddb34eece8c3 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java @@ -24,21 +24,23 @@ import org.xmlpull.v1.XmlPullParserException; import android.content.Context; import android.graphics.drawable.Drawable; import android.graphics.drawable.LevelListDrawable; +import android.widget.LinearLayout; import android.widget.TextView; public class TabletSystemBar extends CustomBar { public TabletSystemBar(Context context, Density density) throws XmlPullParserException { - super(context, density, "/bars/tablet_system_bar.xml", "tablet_system_bar.xml"); + super(context, density, LinearLayout.HORIZONTAL, + "/bars/tablet_system_bar.xml", "tablet_system_bar.xml"); setBackgroundColor(0xFF000000); // Cannot access the inside items through id because no R.id values have been // created for them. // We do know the order though. - loadIcon(0, "ic_sysbar_back_default.png", density); - loadIcon(1, "ic_sysbar_home_default.png", density); - loadIcon(2, "ic_sysbar_recent_default.png", density); + loadIcon(0, "ic_sysbar_back.png", density); + loadIcon(1, "ic_sysbar_home.png", density); + loadIcon(2, "ic_sysbar_recent.png", density); // 3 is the spacer loadIcon(4, "stat_sys_wifi_signal_4_fully.png", density); Drawable drawable = loadIcon(5, ResourceType.DRAWABLE, "stat_sys_battery_charge"); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java index 5f5ebc48d9f4d..c27859f901c19 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java @@ -21,6 +21,7 @@ import com.android.resources.Density; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; +import android.widget.LinearLayout; import android.widget.TextView; public class TitleBar extends CustomBar { @@ -29,7 +30,7 @@ public class TitleBar extends CustomBar { public TitleBar(Context context, Density density, String label) throws XmlPullParserException { - super(context, density, "/bars/title_bar.xml", "title_bar.xml"); + super(context, density, LinearLayout.HORIZONTAL, "/bars/title_bar.xml", "title_bar.xml"); // Cannot access the inside items through id because no R.id values have been // created for them. diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java index 7323c6af88397..1db7994a5772c 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java @@ -20,11 +20,12 @@ import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTE import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT; import static com.android.ide.common.rendering.api.Result.Status.SUCCESS; +import com.android.ide.common.rendering.api.HardwareConfig; import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.RenderParams; import com.android.ide.common.rendering.api.RenderResources; -import com.android.ide.common.rendering.api.Result; import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider; +import com.android.ide.common.rendering.api.Result; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.resources.Density; @@ -98,19 +99,21 @@ public abstract class RenderAction extends FrameworkReso return result; } + HardwareConfig hardwareConfig = mParams.getHardwareConfig(); + // setup the display Metrics. DisplayMetrics metrics = new DisplayMetrics(); - metrics.densityDpi = mParams.getDensity().getDpiValue(); + metrics.densityDpi = hardwareConfig.getDensity().getDpiValue(); metrics.density = metrics.noncompatDensity = metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT; metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density; - metrics.widthPixels = metrics.noncompatWidthPixels = mParams.getScreenWidth(); - metrics.heightPixels = metrics.noncompatHeightPixels = mParams.getScreenHeight(); - metrics.xdpi = metrics.noncompatXdpi = mParams.getXdpi(); - metrics.ydpi = metrics.noncompatYdpi = mParams.getYdpi(); + metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth(); + metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight(); + metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi(); + metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi(); RenderResources resources = mParams.getResources(); @@ -305,7 +308,9 @@ public abstract class RenderAction extends FrameworkReso private Configuration getConfiguration() { Configuration config = new Configuration(); - ScreenSize screenSize = mParams.getConfigScreenSize(); + HardwareConfig hardwareConfig = mParams.getHardwareConfig(); + + ScreenSize screenSize = hardwareConfig.getScreenSize(); if (screenSize != null) { switch (screenSize) { case SMALL: @@ -323,13 +328,13 @@ public abstract class RenderAction extends FrameworkReso } } - Density density = mParams.getDensity(); + Density density = hardwareConfig.getDensity(); if (density == null) { density = Density.MEDIUM; } - config.screenWidthDp = mParams.getScreenWidth() / density.getDpiValue(); - config.screenHeightDp = mParams.getScreenHeight() / density.getDpiValue(); + config.screenWidthDp = hardwareConfig.getScreenWidth() / density.getDpiValue(); + config.screenHeightDp = hardwareConfig.getScreenHeight() / density.getDpiValue(); if (config.screenHeightDp < config.screenWidthDp) { config.smallestScreenWidthDp = config.screenHeightDp; } else { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java index 813321080b7ba..b6771315b09b4 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java @@ -19,6 +19,7 @@ package com.android.layoutlib.bridge.impl; import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; import com.android.ide.common.rendering.api.DrawableParams; +import com.android.ide.common.rendering.api.HardwareConfig; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.Result; import com.android.ide.common.rendering.api.Result.Status; @@ -59,6 +60,7 @@ public class RenderDrawable extends RenderAction { try { // get the drawable resource value DrawableParams params = getParams(); + HardwareConfig hardwareConfig = params.getHardwareConfig(); ResourceValue drawableResource = params.getDrawable(); // resolve it @@ -75,15 +77,15 @@ public class RenderDrawable extends RenderAction { // get the actual Drawable object to draw Drawable d = ResourceHelper.getDrawable(drawableResource, context); - content.setBackgroundDrawable(d); + content.setBackground(d); // set the AttachInfo on the root view. AttachInfo_Accessor.setAttachInfo(content); // measure - int w = params.getScreenWidth(); - int h = params.getScreenHeight(); + int w = hardwareConfig.getScreenWidth(); + int h = hardwareConfig.getScreenHeight(); int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY); int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY); content.measure(w_spec, h_spec); @@ -99,11 +101,11 @@ public class RenderDrawable extends RenderAction { // create an Android bitmap around the BufferedImage Bitmap bitmap = Bitmap_Delegate.createBitmap(image, - true /*isMutable*/, params.getDensity()); + true /*isMutable*/, hardwareConfig.getDensity()); // create a Canvas around the Android bitmap Canvas canvas = new Canvas(bitmap); - canvas.setDensity(params.getDensity().getDpiValue()); + canvas.setDensity(hardwareConfig.getDensity().getDpiValue()); // and draw content.draw(canvas); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java index e93b41d27a9b1..7169db3ed98d4 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java @@ -24,6 +24,7 @@ import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP import static com.android.ide.common.rendering.api.Result.Status.SUCCESS; import com.android.ide.common.rendering.api.AdapterBinding; +import com.android.ide.common.rendering.api.HardwareConfig; import com.android.ide.common.rendering.api.IAnimationListener; import com.android.ide.common.rendering.api.ILayoutPullParser; import com.android.ide.common.rendering.api.IProjectCallback; @@ -42,13 +43,16 @@ import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes; import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; +import com.android.layoutlib.bridge.bars.CustomBar; import com.android.layoutlib.bridge.bars.FakeActionBar; -import com.android.layoutlib.bridge.bars.PhoneSystemBar; +import com.android.layoutlib.bridge.bars.NavigationBar; +import com.android.layoutlib.bridge.bars.StatusBar; import com.android.layoutlib.bridge.bars.TabletSystemBar; import com.android.layoutlib.bridge.bars.TitleBar; import com.android.layoutlib.bridge.impl.binding.FakeAdapter; import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter; import com.android.resources.ResourceType; +import com.android.resources.ScreenOrientation; import com.android.resources.ScreenSize; import com.android.util.Pair; @@ -120,7 +124,8 @@ public class RenderSessionImpl extends RenderAction { private boolean mWindowIsFloating; private int mStatusBarSize; - private int mSystemBarSize; + private int mNavigationBarSize; + private int mNavigationBarOrientation = LinearLayout.HORIZONTAL; private int mTitleBarSize; private int mActionBarSize; @@ -183,7 +188,7 @@ public class RenderSessionImpl extends RenderAction { findBackground(resources); findStatusBar(resources, metrics); findActionBar(resources, metrics); - findSystemBar(resources, metrics); + findNavigationBar(resources, metrics); // build the inflater and parser. mInflater = new BridgeInflater(context, params.getProjectCallback()); @@ -209,19 +214,57 @@ public class RenderSessionImpl extends RenderAction { try { SessionParams params = getParams(); + HardwareConfig hardwareConfig = params.getHardwareConfig(); BridgeContext context = getContext(); + // the view group that receives the window background. ViewGroup backgroundView = null; if (mWindowIsFloating || params.isForceNoDecor()) { backgroundView = mViewRoot = mContentRoot = new FrameLayout(context); } else { + if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) { + /* + * This is a special case where the navigation bar is on the right. + +-------------------------------------------------+---+ + | Status bar (always) | | + +-------------------------------------------------+ | + | (Layout with background drawable) | | + | +---------------------------------------------+ | | + | | Title/Action bar (optional) | | | + | +---------------------------------------------+ | | + | | Content, vertical extending | | | + | | | | | + | +---------------------------------------------+ | | + +-------------------------------------------------+---+ + + So we create a horizontal layout, with the nav bar on the right, + and the left part is the normal layout below without the nav bar at + the bottom + */ + LinearLayout topLayout = new LinearLayout(context); + mViewRoot = topLayout; + topLayout.setOrientation(LinearLayout.HORIZONTAL); + + try { + NavigationBar navigationBar = new NavigationBar(context, + hardwareConfig.getDensity(), LinearLayout.VERTICAL); + navigationBar.setLayoutParams( + new LinearLayout.LayoutParams( + mNavigationBarSize, + LayoutParams.MATCH_PARENT)); + topLayout.addView(navigationBar); + } catch (XmlPullParserException e) { + + } + } + /* * we're creating the following layout * +-------------------------------------------------+ - | System bar (only in phone UI) | + | Status bar (except for xlarge tablets) | +-------------------------------------------------+ | (Layout with background drawable) | | +---------------------------------------------+ | @@ -231,20 +274,31 @@ public class RenderSessionImpl extends RenderAction { | | | | | +---------------------------------------------+ | +-------------------------------------------------+ - | System bar (only in tablet UI) | + | Navigation bar for soft buttons, maybe see above| +-------------------------------------------------+ */ LinearLayout topLayout = new LinearLayout(context); - mViewRoot = topLayout; topLayout.setOrientation(LinearLayout.VERTICAL); + // if we don't already have a view root this is it + if (mViewRoot == null) { + mViewRoot = topLayout; + } else { + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( + LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); + layoutParams.weight = 1; + topLayout.setLayoutParams(layoutParams); + + // this is the case of soft buttons + vertical bar. + // this top layout is the first layout in the horizontal layout. see above) + mViewRoot.addView(topLayout, 0); + } if (mStatusBarSize > 0) { // system bar try { - PhoneSystemBar systemBar = new PhoneSystemBar(context, - params.getDensity()); + StatusBar systemBar = new StatusBar(context, hardwareConfig.getDensity()); systemBar.setLayoutParams( new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, mStatusBarSize)); @@ -268,7 +322,7 @@ public class RenderSessionImpl extends RenderAction { if (mActionBarSize > 0) { try { FakeActionBar actionBar = new FakeActionBar(context, - params.getDensity(), + hardwareConfig.getDensity(), params.getAppLabel(), params.getAppIcon()); actionBar.setLayoutParams( new LinearLayout.LayoutParams( @@ -280,7 +334,7 @@ public class RenderSessionImpl extends RenderAction { } else if (mTitleBarSize > 0) { try { TitleBar titleBar = new TitleBar(context, - params.getDensity(), params.getAppLabel()); + hardwareConfig.getDensity(), params.getAppLabel()); titleBar.setLayoutParams( new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, mTitleBarSize)); @@ -298,15 +352,23 @@ public class RenderSessionImpl extends RenderAction { mContentRoot.setLayoutParams(layoutParams); backgroundLayout.addView(mContentRoot); - if (mSystemBarSize > 0) { + if (mNavigationBarOrientation == LinearLayout.HORIZONTAL && + mNavigationBarSize > 0) { // system bar try { - TabletSystemBar systemBar = new TabletSystemBar(context, - params.getDensity()); - systemBar.setLayoutParams( + CustomBar navigationBar; + if (hardwareConfig.getScreenSize() == ScreenSize.XLARGE) { + navigationBar = new TabletSystemBar(context, + hardwareConfig.getDensity()); + } else { + navigationBar = new NavigationBar(context, + hardwareConfig.getDensity(), LinearLayout.HORIZONTAL); + } + + navigationBar.setLayoutParams( new LinearLayout.LayoutParams( - LayoutParams.MATCH_PARENT, mSystemBarSize)); - topLayout.addView(systemBar); + LayoutParams.MATCH_PARENT, mNavigationBarSize)); + topLayout.addView(navigationBar); } catch (XmlPullParserException e) { } @@ -334,7 +396,7 @@ public class RenderSessionImpl extends RenderAction { // get the background drawable if (mWindowBackground != null && backgroundView != null) { Drawable d = ResourceHelper.getDrawable(mWindowBackground, context); - backgroundView.setBackgroundDrawable(d); + backgroundView.setBackground(d); } return SUCCESS.createResult(); @@ -377,13 +439,14 @@ public class RenderSessionImpl extends RenderAction { } RenderingMode renderingMode = params.getRenderingMode(); + HardwareConfig hardwareConfig = params.getHardwareConfig(); // only do the screen measure when needed. boolean newRenderSize = false; if (mMeasuredScreenWidth == -1) { newRenderSize = true; - mMeasuredScreenWidth = params.getScreenWidth(); - mMeasuredScreenHeight = params.getScreenHeight(); + mMeasuredScreenWidth = hardwareConfig.getScreenWidth(); + mMeasuredScreenHeight = hardwareConfig.getScreenHeight(); if (renderingMode != RenderingMode.NORMAL) { int widthMeasureSpecMode = renderingMode.isHorizExpand() ? @@ -483,11 +546,11 @@ public class RenderSessionImpl extends RenderAction { // create an Android bitmap around the BufferedImage Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage, - true /*isMutable*/, params.getDensity()); + true /*isMutable*/, hardwareConfig.getDensity()); // create a Canvas around the Android bitmap mCanvas = new Canvas(bitmap); - mCanvas.setDensity(params.getDensity().getDpiValue()); + mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue()); } if (freshRender && newImage == false) { @@ -960,12 +1023,14 @@ public class RenderSessionImpl extends RenderAction { } } - private boolean isTabletUi() { - return getParams().getConfigScreenSize() == ScreenSize.XLARGE; + private boolean hasSoftwareButtons() { + return getParams().getHardwareConfig().hasSoftwareButtons(); } private void findStatusBar(RenderResources resources, DisplayMetrics metrics) { - if (isTabletUi() == false) { + // status bar is on for all but x-large device + HardwareConfig hardwareConfig = getParams().getHardwareConfig(); + if (hardwareConfig.getScreenSize() != ScreenSize.XLARGE) { boolean windowFullscreen = getBooleanThemeValue(resources, "windowFullscreen", false /*defaultValue*/); @@ -1050,22 +1115,48 @@ public class RenderSessionImpl extends RenderAction { } } - private void findSystemBar(RenderResources resources, DisplayMetrics metrics) { - if (isTabletUi() && mWindowIsFloating == false) { + private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) { + if (hasSoftwareButtons() && mWindowIsFloating == false) { // default value - mSystemBarSize = 48; // ?? + mNavigationBarSize = 48; // ?? + + HardwareConfig hardwareConfig = getParams().getHardwareConfig(); + + boolean barOnBottom = true; + + if (hardwareConfig.getOrientation() == ScreenOrientation.LANDSCAPE) { + // compute the dp of the screen. + int shortSize = hardwareConfig.getScreenHeight(); + + // compute in dp + int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / hardwareConfig.getDensity().getDpiValue(); + + if (shortSizeDp < 600) { + // 0-599dp: "phone" UI with bar on the side + barOnBottom = false; + } else { + // 600+dp: "tablet" UI with bar on the bottom + barOnBottom = true; + } + } + + if (barOnBottom) { + mNavigationBarOrientation = LinearLayout.HORIZONTAL; + } else { + mNavigationBarOrientation = LinearLayout.VERTICAL; + } // get the real value ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, - "status_bar_height"); + barOnBottom ? "navigation_bar_height" : "navigation_bar_width"); if (value != null) { - TypedValue typedValue = ResourceHelper.getValue("status_bar_height", + TypedValue typedValue = ResourceHelper.getValue("navigation_bar_height", value.getValue(), true /*requireUnit*/); if (typedValue != null) { // compute the pixel value based on the display metrics - mSystemBarSize = (int)typedValue.getDimension(metrics); + mNavigationBarSize = (int)typedValue.getDimension(metrics); } } }