/* Copyright (c) 2002-2011 by XMLVM.org * * Project Info: http://www.xmlvm.org * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ package android.view; import org.xmlvm.acl.common.adapter.ScrollViewAdapter; import org.xmlvm.acl.common.objects.CommonView; import org.xmlvm.acl.common.subsystems.CommonTextFieldDelegate; import android.app.Activity; import android.app.Application; import android.content.pm.ActivityInfo; import android.graphics.Color; import android.graphics.RectF; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.internal.CommonDeviceAPIFinder; import android.internal.DecorView; import android.internal.LayoutManager; import android.view.View.MeasureSpec; import android.view.ViewGroup.LayoutParams; import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ScrollView; /** * iPhone Implementation of Android's Window class. * * @see http://developer.android.com/reference/android/view/Window.html */ public class Window { public static final int FEATURE_NO_TITLE = 1; private Activity activity; private CommonView iContainerView; private ScrollViewAdapter iScrollView; private CommonTextFieldDelegate iTextFieldDelegate; private FrameLayout internalView; private DecorView decorView; private FrameLayout contentParent; private boolean floating = false; public Window(Activity parent) { this.activity = parent; this.iTextFieldDelegate = CommonDeviceAPIFinder.instance().getTextFieldDelegate(this); } public void setContentView(View view) { xmlvmRemoveWindow(); // Set default FrameLayout.LayoutParams if view does not have layout // params if (view.getLayoutParams() == null) { view.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); } // Create UIWindow and transparent internal FrameLayout used to layout // the content views. iContainerView = CommonDeviceAPIFinder.instance().getWidgetFactory() .createView(new View(this.activity)); iContainerView.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); iScrollView = CommonDeviceAPIFinder.instance().getWidgetFactory() .createScrollView(new ScrollView(this.activity)); iScrollView.setScrollEnabled(false); iContainerView.addSubview(iScrollView); internalView = new FrameLayout(activity); internalView.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); internalView.setBackgroundColor(0x80000000); iScrollView.addSubview(internalView.getCommonView()); FrameLayout rootView = new FrameLayout(activity); int layoutWidth = view.layoutParams.width == LayoutParams.FILL_PARENT ? LayoutParams.FILL_PARENT : LayoutParams.WRAP_CONTENT; int layoutHeight = view.layoutParams.height == LayoutParams.FILL_PARENT ? LayoutParams.FILL_PARENT : LayoutParams.WRAP_CONTENT; rootView.setLayoutParams(new FrameLayout.LayoutParams(layoutWidth, layoutHeight, Gravity.CENTER)); internalView.addView(rootView); // Create DecorView used as the window for all content views int gravity = ((FrameLayout.LayoutParams) view.getLayoutParams()).gravity; decorView = new DecorView(activity); // TODO: Set DecorView's LayoutParams based on Window.isFloating() FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( isFloating() ? LayoutParams.WRAP_CONTENT : LayoutParams.FILL_PARENT, isFloating() ? LayoutParams.WRAP_CONTENT : LayoutParams.FILL_PARENT, gravity); decorView.setLayoutParams(lp); rootView.addView(decorView); // Wrap the provided view with a FrameLayout as Android it does. Android // uses this to layout the window's decoration. We do it the same way to // support all FrameLayout.LayoutParams imposed on the content view. contentParent = new FrameLayout(activity); contentParent.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); contentParent.setBackgroundColor(0x00000000); contentParent.addView(view); decorView.addView(contentParent); setEditTextDelegates(view); adjustFrameSize(); Application.getApplication().xmlvmAddActivityView(iContainerView); xmlvmSetHidden(true); } public void setContentView(int id) { View v = LayoutManager.getLayout(activity, id, null); setContentView(v); } public void addContentView(View view, ViewGroup.LayoutParams params) { contentParent.addView(view, params); layoutContentView(view); } public void setFlags(int flags, int mask) { int maskedFlags = (flags & mask); if ((maskedFlags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0) { CommonDeviceAPIFinder.instance().getWindowInstance().setStatusBarHidden(true); adjustFrameSize(); } } public void setBackgroundDrawableResource(int resId) { if (decorView != null) { decorView.setBackgroundResource(resId); } } public void setBackgroundDrawable(Drawable drawable) { if (decorView != null) { decorView.setBackgroundDrawable(drawable); } } public void xmlvmShowToast(View toast) { layoutContentView(toast); CommonView itoast = toast.getCommonView(); itoast.setUserInteractionEnabled(false); iContainerView.addSubview(itoast); } public void xmlvmSetHidden(boolean flag) { if (iContainerView != null) { iContainerView.setHidden(flag); } } public void xmlvmRemoveWindow() { if (iContainerView != null) { xmlvmSetHidden(true); internalView.removeAllViews(); internalView = null; decorView.removeAllViews(); decorView = null; contentParent.removeAllViews(); contentParent = null; iScrollView.removeFromSuperview(); iScrollView = null; Application.getApplication().xmlvmRemoveActivityView(iContainerView); iContainerView = null; } } /** * Internal. Not part of Android API. Called whenever the size or * orientation of the top-level window has changed (e.g., when the status * bar is made invisible). */ private void adjustFrameSize() { if (iContainerView == null) { return; } RectF rect = xmlvmGetRect(); // AndroidAppLauncher.getApplication().xmlvmGetTopLevelWindow().setFrame(rect); // iContainerView.setTransform(null); iContainerView.setFrame(rect); rect.left = 0; rect.top = 0; iScrollView.setFrame(rect); layoutContentView(internalView); } private void setEditTextDelegates(View view) { if (view instanceof EditText) { EditText editText = (EditText) view; editText.xmlvmSetKeyboardDelegate(iTextFieldDelegate); } if (view instanceof ViewGroup) { ViewGroup viewGroup = (ViewGroup) view; for (int i = 0; i < viewGroup.getChildCount(); i++) { View child = viewGroup.getChildAt(i); setEditTextDelegates(child); } } } private void layoutContentView(View view) { if (view.getLayoutParams() == null) { view.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); } int widthMeasureSpec; int heightMeasureSpec; RectF rect = xmlvmGetRect(); LayoutParams lp = view.getLayoutParams(); if (lp == null || lp.width == LayoutParams.FILL_PARENT) { widthMeasureSpec = MeasureSpec.makeMeasureSpec((int) rect.width(), MeasureSpec.EXACTLY); } else if (lp.width == LayoutParams.WRAP_CONTENT) { widthMeasureSpec = MeasureSpec.makeMeasureSpec((int) rect.width(), MeasureSpec.AT_MOST); } else { widthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); } if (lp == null || lp.height == LayoutParams.FILL_PARENT) { heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) rect.height(), MeasureSpec.EXACTLY); } else if (lp.height == LayoutParams.WRAP_CONTENT) { heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) rect.height(), MeasureSpec.AT_MOST); } else { heightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); } view.xmlvmSetMeasureSpec(widthMeasureSpec, heightMeasureSpec); view.requestLayout(); } public RectF xmlvmGetRect() { RectF rect = CommonDeviceAPIFinder.instance().getProperties().getApplicationFrame(); if (activity.getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { float t = rect.height(); rect.bottom = rect.top + rect.width(); rect.right = rect.left + t; } return rect; } public ScrollViewAdapter getScrollView() { return this.iScrollView; } /** * @param id * @return */ public View findViewById(int id) { return internalView.findViewById(id); } public WindowManager.LayoutParams getAttributes() { // TODO return proper attributes return new WindowManager.LayoutParams(); } public boolean isFloating() { return floating; } }