package com.iwedia.gui.widgets; import android.app.Activity; import android.app.Dialog; import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Context; import android.content.res.TypedArray; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.Window; import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import com.iwedia.comm.content.Content; import com.iwedia.gui.MainActivity; import com.iwedia.gui.R; import com.iwedia.gui.components.A4TVToast; import com.iwedia.gui.listeners.MainKeyListener; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; /** * Handler class for handling installed widgets * * @author Veljko Ilkic */ public class WidgetsHandler { public static final String WIDGET_OBJECT_FILE_NAME = "widgetObjects.bin"; public static final String WIDGET_CELL_FILE_NAME = "widgetCells.bin"; /** Constant key for bundle saving */ public static final String WIDGET_PACKAGE_NAMES = "WIDGET_PACKAGE_NAMES"; public static final String WIDGET_CLASS_NAMES = "WIDGET_CLASS_NAMES"; public static final String WIDGET_ID_COUNTER = "WIDGER_ID_COUNTER"; static final int APPWIDGET_HOST_ID = 2037; /** Reference of main activity */ private Activity activity; /** Widget dialog */ private Dialog widgetDialog; /** Layout inflater */ private LayoutInflater inflater; /** Widget host object */ private AppWidgetHost mAppWidgetHost; /** Widget manager object */ private AppWidgetManager mAppWidgetManager; /** Drag fields */ private DragController mDragController; private static DragLayer mDragLayer; /** View holders for widget objects */ private ArrayList<AppWidgetHostView> widgetsViewHolders = new ArrayList<AppWidgetHostView>(); /** List of active widgets */ private ArrayList<WidgetObject> widgetObjects = new ArrayList<WidgetObject>(); /** Counter for widget ids */ private int widgetIdCounter = 0; /** Arranging handler */ private WidgetArrangingHandler widgetArrangingHandler; /** Drop spot area */ private LinearLayout widgetDropSpotArea; /** Drop zone animations */ private Animation showDropZone; private Animation hideDropZone; /** Constructor 1 */ public WidgetsHandler(Activity activity) { super(); // Take reference of main activity this.activity = activity; } /** Init widget handler method */ public void init() { // Create widget dialog widgetDialog = new Dialog(activity, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen); widgetDialog.setContentView(com.iwedia.gui.R.layout.widget_layout_main); // Init dialog Window window = widgetDialog.getWindow(); window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); widgetDialog.setCancelable(false); widgetDialog.setOnKeyListener(new MainKeyListener( (MainActivity) activity)); // Init widget arranging handler widgetArrangingHandler = new WidgetArrangingHandler(activity); // Get widget manager mAppWidgetManager = AppWidgetManager.getInstance(activity); // Init widget host mAppWidgetHost = new AppWidgetHost(activity, APPWIDGET_HOST_ID); mAppWidgetHost.startListening(); // Init drag controller mDragController = new DragController(activity, this); DragController dragController = mDragController; mDragLayer = (DragLayer) widgetDialog .findViewById(com.iwedia.gui.R.id.drag_layer); mDragLayer.setDragController(dragController); dragController.addDropTarget(mDragLayer); // ////////////////////////////////////////// // Drop spot area // ////////////////////////////////////////// widgetDropSpotArea = (LinearLayout) widgetDialog .findViewById(R.id.widgetDropSpot); FrameLayout.LayoutParams dropSpotParams = new FrameLayout.LayoutParams( LayoutParams.MATCH_PARENT, WidgetArrangingHandler.DROP_SPOT_HEIGHT); dropSpotParams.gravity = Gravity.BOTTOM; widgetDropSpotArea.setLayoutParams(dropSpotParams); // Set visible on start widgetDropSpotArea.setVisibility(View.INVISIBLE); // ///////////////////////////////////////////// // Load drop zone animations // ///////////////////////////////////////////// showDropZone = AnimationUtils.loadAnimation(activity, com.iwedia.gui.R.anim.scale_alpha_in2); hideDropZone = AnimationUtils.loadAnimation(activity, com.iwedia.gui.R.anim.scale_alpha_out); // Attach animation listener on hide animation hideDropZone.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { widgetDropSpotArea.setVisibility(View.INVISIBLE); } }); try { // Load important data on init loadImportantData(); // Reinit widgets for (int i = 0; i < widgetObjects.size(); i++) { String packageName = widgetObjects.get(i).getPackageName(); String className = widgetObjects.get(i).getClassName(); int appWidgetId = mAppWidgetHost.allocateAppWidgetId(); ComponentName componentName = new ComponentName(packageName, className); mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, componentName); addAppWidget(appWidgetId, widgetObjects.get(i), false); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** Show widgets */ public void showWidgets() { // Show widget dialog widgetDialog.show(); } /** Create widget object */ public void createWidgetComponent(String packageName, String className) { // Create new widget object WidgetObject widgetObject = new WidgetObject(packageName, className, null, -1); // Store widget object into list widgetObjects.add(widgetObject); // Get id for widget int appWidgetId = mAppWidgetHost.allocateAppWidgetId(); // Create component name ComponentName componentName = new ComponentName(packageName, className); // Bind widget mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, componentName); // Add widget on screen addAppWidget(appWidgetId, widgetObject, true); try { saveImportantData(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** Add widget on screen */ private void addAppWidget(int appWidgetId, final WidgetObject widgetObject, boolean init) { // Increment widget counter widgetIdCounter++; // Get widget info AppWidgetProviderInfo appWidget = mAppWidgetManager .getAppWidgetInfo(appWidgetId); // Widget host view final AppWidgetHostView widgetHostView = attachWidget(mAppWidgetHost .createView(activity, appWidgetId, appWidget)); // Add widget into widget list widgetsViewHolders.add(widgetHostView); // Inflate widget holder xml inflater = (LayoutInflater) activity .getSystemService(Context.LAYOUT_INFLATER_SERVICE); /** Widget overlay for long click detection */ final WidgetOverlayLinearLayout widgetOverlayFrame; /** Real content holder for widget */ final LinearLayout widgetView; // Inflate main widget layout FrameLayout widgetMainView = (FrameLayout) inflater.inflate( R.layout.widget_layout_item, null); // Get overlay layout widgetOverlayFrame = (com.iwedia.gui.widgets.WidgetOverlayLinearLayout) widgetMainView .findViewById(R.id.widgetOverlayFrame); // Get widget content holder widgetView = (LinearLayout) widgetMainView .findViewById(R.id.widgetView); // //////////////////////////////////////////////////// // Handle widget click if system didn't bug fix // //////////////////////////////////////////////////// widgetHostView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) ((LinearLayout) widgetHostView.getParent()) .dispatchTouchEvent(event); return true; } }); // ////////////////////////////////////////////// // Prepare overlay layout for manipulation // /////////////////////////////////////////////// // widgetOverlayFrame.setVisibility(View.GONE); widgetOverlayFrame.setWidgetObject(widgetObject); widgetOverlayFrame.setWidgetHandler(this); widgetOverlayFrame.setWidgetMainLayout(widgetMainView); widgetOverlayFrame.setWidgetContent(widgetHostView); // Attach widget content in container widgetView.addView(widgetHostView); // //////////////////////////// // Set tag on init // //////////////////////////// if (init) { widgetMainView.setTag(new WidgetViewTagObject(widgetHostView .getId(), -1, null)); } // ///////////////////////////////////////////////////// // Reset tag if widget is already showed on screen // ////////////////////////////////////////////////////// else { widgetMainView.setTag(new WidgetViewTagObject(widgetHostView .getId(), widgetObject.getCellId(), widgetObject .getHowManyCellsTake())); } // Determine widget size int[] widgetSizeCells = widgetArrangingHandler .howManyCellsTake(appWidget); // Set widget size in object widgetObject.setHowManyCellsTake(widgetSizeCells); // Real widget size on screen int[] widgetSizeReal = new int[2]; // Calculate width and height of widget on screen widgetSizeReal[0] = widgetSizeCells[0] * widgetArrangingHandler.getCellWidth(); widgetSizeReal[1] = widgetSizeCells[1] * widgetArrangingHandler.getCellHeight(); // Set widget size DragLayer.LayoutParams widgetParams = new DragLayer.LayoutParams( widgetSizeReal[0], widgetSizeReal[1], 0, 0); widgetMainView.setLayoutParams(widgetParams); LinearLayout.LayoutParams widgetHostParams = new LinearLayout.LayoutParams( widgetSizeReal[0], android.app.ActionBar.LayoutParams.WRAP_CONTENT); widgetHostView.setLayoutParams(widgetHostParams); // ///////////////////////////////// // Init time // ///////////////////////////////// if (init) { // ///////////////////////////////////////////////////////// // Check if there is enough space for widget and show it // ////////////////////////////////////////////////////////// if (widgetArrangingHandler.setXY(widgetMainView, widgetSizeCells, widgetObject)) { // Add widget on screen mDragLayer.addView(widgetMainView); mDragLayer.invalidate(); } // /////////////////////////////////////////////////////////////// // Remove added widget if there is no enough space on screen // /////////////////////////////////////////////////////////////// else { // Unbind widget mAppWidgetHost.deleteAppWidgetId(widgetHostView.getId()); // Remove widget data from list widgetsViewHolders.remove(widgetsViewHolders.size() - 1); widgetObjects.remove(widgetsViewHolders.size() - 1); // Show no empty space message A4TVToast toast = new A4TVToast(activity); toast.showToast(activity.getResources().getString( com.iwedia.gui.R.string.no_enough_space_on_screen)); } } // /////////////////////////// // After init // /////////////////////////// else { // Just add widgets on screen widgetArrangingHandler.setXYAfterInit(widgetMainView, widgetObject); // Add widget on screen mDragLayer.addView(widgetMainView); mDragLayer.invalidate(); } } /** Check if widget is already active */ public boolean checkWidgetVisibility(Content widgetContent) { String packageName = widgetContent.getImage(); // Check if widget with the same package name is already in list for (int i = 0; i < widgetObjects.size(); i++) { if (widgetObjects.get(i).getPackageName().equals(packageName)) { return true; } } return false; } /** Get id of widget */ public int getIndexOfWidget(String packageName) { int i; // Find widget with the same package name in list and return index for (i = 0; i < widgetObjects.size(); i++) { if (widgetObjects.get(i).getPackageName().equals(packageName)) { break; } } return i; } /** Remove widget content */ public void removeWidgetFromScreen(Content widgetContent) { // Get package name String packageName = widgetContent.getImage(); // Get index of widget in list int widgetIndex = getIndexOfWidget(packageName); // View that needs to be removed View viewToRemove = null; // Find view that needs to be removed for (int i = 0; i < mDragLayer.getChildCount(); i++) { if (((WidgetViewTagObject) mDragLayer.getChildAt(i).getTag()) .getWidgetId() == widgetsViewHolders.get(widgetIndex) .getId()) { viewToRemove = mDragLayer.getChildAt(i); break; } } // Unbind widget from host mAppWidgetHost.deleteAppWidgetId(widgetsViewHolders.get(widgetIndex) .getId()); // Deinit flag in widget cell grid if (viewToRemove != null) widgetArrangingHandler.deinitTakenCells( ((WidgetViewTagObject) viewToRemove.getTag()).getCellId(), (int[]) ((WidgetViewTagObject) viewToRemove.getTag()) .getCellsTaken()); // Refresh graphic layer mDragLayer.removeView(viewToRemove); mDragLayer.invalidate(); // Remove widget data from list widgetsViewHolders.remove(widgetIndex); widgetObjects.remove(widgetIndex); try { saveImportantData(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** Remove widget from drop zone */ public void removeWidgetFromDropZone(WidgetObject widgetObject) { // Get package name String packageName = widgetObject.getPackageName(); // Get index of widget in list int widgetIndex = getIndexOfWidget(packageName); // View that needs to be removed View viewToRemove = null; // Find view that needs to be removed for (int i = 0; i < mDragLayer.getChildCount(); i++) { if (((WidgetViewTagObject) mDragLayer.getChildAt(i).getTag()) .getWidgetId() == widgetsViewHolders.get(widgetIndex) .getId()) { viewToRemove = mDragLayer.getChildAt(i); break; } } // Unbind widget from host mAppWidgetHost.deleteAppWidgetId(widgetsViewHolders.get(widgetIndex) .getId()); // Deinit flag in widget cell grid if (viewToRemove != null) widgetArrangingHandler.deinitTakenCells( ((WidgetViewTagObject) viewToRemove.getTag()).getCellId(), (int[]) ((WidgetViewTagObject) viewToRemove.getTag()) .getCellsTaken()); // Refresh graphic layer mDragLayer.removeView(viewToRemove); mDragLayer.invalidate(); // Remove widget data from list widgetsViewHolders.remove(widgetIndex); widgetObjects.remove(widgetIndex); try { saveImportantData(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** Clear screen from widgets */ public void clearScreen() { // Close widget dialog widgetDialog.dismiss(); // Clear list of widgets widgetsViewHolders.clear(); // Clear widget layout container if (mDragLayer != null) { mDragLayer.removeAllViews(); mDragLayer.invalidate(); } // Widget counter deinit widgetIdCounter = 0; } /** Remove all widgets */ public void removeAllWidgets() { // Remove all widget holders widgetsViewHolders.clear(); // Remove all widget objects widgetObjects.clear(); // Init grid cell widgetArrangingHandler.initCellGrid(); } /** Аttach widget method and set params */ private AppWidgetHostView attachWidget(AppWidgetHostView widget) { FrameLayout.LayoutParams flp = new FrameLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); flp.gravity = Gravity.CENTER_VERTICAL | Gravity.LEFT; widget.setLayoutParams(flp); widget.setId(100 + widgetIdCounter); return widget; } /** Dragging method */ public boolean startDrag(View v, WidgetObject widgetObject) { showWidgetBackground(v); showDropArea(); Object dragInfo = v; mDragController.startDrag(v, mDragLayer, dragInfo, DragController.DRAG_ACTION_MOVE, widgetObject); return true; } /** Show widget background while dragging */ public void showWidgetBackground(View widgetView) { for (int i = 0; i < mDragLayer.getChildCount(); i++) { mDragLayer.getChildAt(i).setBackgroundResource( R.color.widget_static_background); } widgetView.setBackgroundResource(R.color.widget_selected_background); widgetView.invalidate(); } /** Hide widgets background on drag end */ public void hideWidgetBackground(View widgetView) { for (int i = 0; i < mDragLayer.getChildCount(); i++) { mDragLayer.getChildAt(i).setBackgroundResource( android.R.color.transparent); } hideDropArea(); } /** Show drop area */ public void showDropArea() { widgetDropSpotArea.setVisibility(View.VISIBLE); widgetDropSpotArea.startAnimation(showDropZone); } /** Hide drop area */ public void hideDropArea() { widgetDropSpotArea.startAnimation(hideDropZone); } /** Drop zone active indicator */ public void widgetInsideDropZone() { widgetDropSpotArea.setBackgroundColor(activity.getResources().getColor( R.color.widget_drop_zone_active)); } /** Drop zone inactive */ public void widgetOutsideDropZone() { // get drawable from theme for image source TypedArray atts = activity.getTheme().obtainStyledAttributes( new int[] { R.attr.MainMenuDescriptionBackground }); int backgroundID = atts.getResourceId(0, 0); widgetDropSpotArea.setBackgroundResource(backgroundID); atts.recycle(); } /** Save important data */ public void saveImportantData() throws FileNotFoundException, IOException { FileSaveLoad.save(widgetObjects, WIDGET_OBJECT_FILE_NAME, activity); FileSaveLoad.save(widgetArrangingHandler.getWidgetCells(), WIDGET_CELL_FILE_NAME, activity); } /** Show widgets */ public void showWidgetDialog() { widgetDialog.show(); } /** Hide widgets from screen */ public void hideWidgetDialog() { widgetDialog.cancel(); } /** * Load important data * * @throws ClassNotFoundException * @throws IOException * @throws FileNotFoundException */ @SuppressWarnings("unchecked") public void loadImportantData() throws FileNotFoundException, IOException, ClassNotFoundException { widgetObjects = (ArrayList<WidgetObject>) FileSaveLoad.load( WIDGET_OBJECT_FILE_NAME, activity); widgetArrangingHandler.setWidgetCells((WidgetCell[]) FileSaveLoad.load( WIDGET_CELL_FILE_NAME, activity)); } // ///////////////////////////////////////// // Getters and setters // ///////////////////////////////////////// /** Get widget host */ public AppWidgetHost getmAppWidgetHost() { return mAppWidgetHost; } /** Set widget host object */ public void setmAppWidgetHost(AppWidgetHost mAppWidgetHost) { this.mAppWidgetHost = mAppWidgetHost; } /** Get Widget Manager object */ public AppWidgetManager getmAppWidgetManager() { return mAppWidgetManager; } /** Set widget manager object */ public void setmAppWidgetManager(AppWidgetManager mAppWidgetManager) { this.mAppWidgetManager = mAppWidgetManager; } /** Get list of active widget objects */ public ArrayList<WidgetObject> getWidgetObjects() { return widgetObjects; } /** Set list of widget objects */ public void setWidgetObjects(ArrayList<WidgetObject> widgetObjects) { this.widgetObjects = widgetObjects; } /** Get widget arranging handler */ public WidgetArrangingHandler getWidgetArrangingHandler() { return widgetArrangingHandler; } }