/** * 文 件 名: MT_FolderWorkspace.java * 描 述: * 版 权: Copyright (c)20010-2011 motone All Rights Reserved. * 公 司: 摩通科技 * 作 者: * 版 本: 1.0 * 创建时间: 2011-3-10 * * 修改历史: * 时间 作者 版本 描述 * ------------------------------------------------------------------ * 2011-3-10 author 1.0 1.0 Version */ package com.mogoo.launcher2; import com.mogoo.launcher.R; import com.mogoo.launcher2.CellEntry.CellEntryInface; import com.mogoo.launcher2.CellLayout.CellInfo; import com.mogoo.launcher2.animation.Mogoo_IconFolderAnimation; import com.mogoo.launcher2.config.Mogoo_GlobalConfig; import com.mogoo.launcher2.utils.Mogoo_BitmapCache; import com.mogoo.launcher2.utils.Mogoo_ClearBase; import com.mogoo.launcher2.utils.Mogoo_ComponentBus; import com.mogoo.launcher2.utils.Mogoo_Utilities; import android.app.WallpaperManager; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ProviderInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Handler; import android.text.Editable; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.View.MeasureSpec; import android.view.View.OnLongClickListener; import android.view.ViewParent; import android.widget.EditText; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.RelativeLayout.LayoutParams; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; public class Mogoo_FolderWorkspace extends ViewGroup implements DropTarget, DragSource, Mogoo_ClearBase, CellEntryInface, View.OnKeyListener { private final static String TAG = "Launcher.Mogoo_FolderWorkspace" ; private boolean mPortrait = Mogoo_GlobalConfig.isPortrait(); private int mCellWidth; private int mCellHeight; private int mLongAxisStartPadding; private int mLongAxisEndPadding; private int mShortAxisStartPadding; private int mShortAxisEndPadding; private int mShortAxisCells; private int mLongAxisCells; private int mWidthGap; private int mHeightGap; boolean[][] mOccupied; int[] mCellXY = new int[2]; private RectF mDragRect = new RectF(); private final Rect mRect = new Rect(); private final CellInfo mCellInfo = new CellInfo(); private final WallpaperManager mWallpaperManager; private boolean mLastDownOnOccupiedCell = false; private boolean mDirtyTag; private Launcher launcher ; private Mogoo_FolderWorkspace folderWorkspace ; private Mogoo_BitmapCache mIconCache; private DragController dragController ; private CellLayout.CellInfo mDragInfo = new CellLayout.CellInfo(); private ArrayList<CellEntry> cellCoordinateList = new ArrayList<CellEntry>(); private Mogoo_IconFolderAnimation iconFolderAnimation; //正在打开的文件夹 private Mogoo_FolderBubbleText loadingFolder; //刚关闭的文件夹 private Mogoo_FolderBubbleText closeFolder ; //保存当前打开的文件夹ID private long folderId ; //新生成的文件夹是否关闭过 private boolean newFolderClosed = true ; //判断是否在本区域内拖动过 private boolean isLocaleDrag = false; private Mogoo_FolderBubbleText folderTemp = null ; private CellEntry dockLastOpenEntry = null; public static boolean acceptFlag = false; public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER && loadingFolder != null) { saveFolderName(); } return false; } public void setDockLastOpenEntry(CellEntry dockLastOpenEntry) { this.dockLastOpenEntry = dockLastOpenEntry; } /** * * 保存文件名称 * @ author: 黄悦 */ public void saveFolderName() { EditText titleEdit = (EditText)Mogoo_ComponentBus.getInstance().getActivityComp(R.id.titleEdit, getContext()); Editable eidtText = titleEdit.getText(); if(eidtText == null || eidtText.toString().trim().length() == 0 || loadingFolder == null){ return; } Mogoo_FolderInfo info = (Mogoo_FolderInfo) loadingFolder.getTag(); mIconCache.recycle(info.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); info.title = titleEdit.getText(); loadingFolder.setText(info.title); LauncherModel.updateItemInDatabase(getContext(), info); loadingFolder.requestLayout(); loadingFolder.invalidate(); } public Mogoo_FolderWorkspace(Context context) { this(context,null); } public Mogoo_FolderWorkspace(Context context, AttributeSet attrs) { this(context, attrs,0); } public Mogoo_FolderWorkspace(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0); mCellWidth = a.getDimensionPixelSize(R.styleable.CellLayout_cellWidth, 10); mCellHeight = a.getDimensionPixelSize(R.styleable.CellLayout_cellHeight, 10); mLongAxisStartPadding = a.getDimensionPixelSize(R.styleable.CellLayout_longAxisStartPadding, 10); mLongAxisEndPadding = a.getDimensionPixelSize(R.styleable.CellLayout_longAxisEndPadding, 10); mShortAxisStartPadding = a.getDimensionPixelSize(R.styleable.CellLayout_shortAxisStartPadding, 10); mShortAxisEndPadding = a.getDimensionPixelSize(R.styleable.CellLayout_shortAxisEndPadding, 10); mLongAxisCells = Mogoo_GlobalConfig.isPortrait()?1:Mogoo_GlobalConfig.getWorkspaceLongAxisCellsLand(); mShortAxisCells = Mogoo_GlobalConfig.isPortrait()?Mogoo_GlobalConfig.getWorkspaceShortAxisCellsPort():1; a.recycle(); setAlwaysDrawnWithCacheEnabled(false); if (mOccupied == null) { if (mPortrait) { mOccupied = new boolean[mShortAxisCells][mLongAxisCells]; } else { mOccupied = new boolean[mLongAxisCells][mShortAxisCells]; } } mWallpaperManager = WallpaperManager.getInstance(getContext()); folderWorkspace = this ; LauncherApplication app = (LauncherApplication) this.getContext().getApplicationContext(); mIconCache = app.getIconCache(); iconFolderAnimation = new Mogoo_IconFolderAnimation(context, mIconCache); CellInfo cellInfo = new CellInfo(); cellInfo.containter = R.id.folderWorkspace; setTag(cellInfo); } public Mogoo_IconFolderAnimation getIconFolderAnimation() { return iconFolderAnimation; } @Override public void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); } @Override public void cancelLongPress() { super.cancelLongPress(); // Cancel long press for all children final int count = getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); child.cancelLongPress(); } } int getCountX() { return mPortrait ? mShortAxisCells : mLongAxisCells; } int getCountY() { return mPortrait ? mLongAxisCells : mShortAxisCells; } @Override public void addView(View child, int index, ViewGroup.LayoutParams params) { // Generate an id for each view, this assumes we have at most 256x256 cells // per workspace screen final CellLayout.LayoutParams cellParams = (CellLayout.LayoutParams) params; cellParams.regenerateId = true; super.addView(child, index, params); } @Override public void requestChildFocus(View child, View focused) { super.requestChildFocus(child, focused); if (child != null) { Rect r = new Rect(); child.getDrawingRect(r); requestRectangleOnScreen(r); } } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); mCellInfo.screen = ((ViewGroup) getParent()).indexOfChild(this); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------call onInterceptTouchEvent()--------------------------------------"); } final int action = ev.getAction(); final CellInfo cellInfo = mCellInfo; //----add by 魏景春 2011-1-28 //如果当前是searchScreen屏,禁止禁止执行该事件 Mogoo_ComponentBus componentBus = Mogoo_ComponentBus.getInstance(); Workspace ws = (Workspace)componentBus.getActivityComp(R.id.workspace, getContext()); if (Mogoo_GlobalConfig.isSearchScreen(ws.getCurrentScreen())) { return false; } //-----end-------------- if (action == MotionEvent.ACTION_DOWN) { final Rect frame = mRect; final int x = (int) ev.getX() + getScrollX(); final int y = (int) ev.getY() + getScrollY(); final int count = getChildCount(); boolean found = false; for (int i = count - 1; i >= 0; i--) { final View child = getChildAt(i); if ((child.getVisibility()) == VISIBLE || child.getAnimation() != null) { child.getHitRect(frame); if (frame.contains(x, y)) { final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); cellInfo.cell = child; cellInfo.cellX = lp.cellX; cellInfo.cellY = lp.cellY; cellInfo.spanX = lp.cellHSpan; cellInfo.spanY = lp.cellVSpan; cellInfo.cellIndex = getIndexByCellXY(cellInfo.cellX, cellInfo.cellY); cellInfo.containter = R.id.folderWorkspace; cellInfo.valid = true; found = true; mDirtyTag = false; break; } } } mLastDownOnOccupiedCell = found; if (!found) { int cellXY[] = mCellXY; pointToCellExact(x, y, cellXY); final boolean portrait = mPortrait; final int xCount = portrait ? mShortAxisCells : mLongAxisCells; final int yCount = portrait ? mLongAxisCells : mShortAxisCells; final boolean[][] occupied = mOccupied; findOccupiedCells(xCount, yCount, occupied, null); cellInfo.cell = null; cellInfo.cellX = cellXY[0]; cellInfo.cellY = cellXY[1]; cellInfo.spanX = 1; cellInfo.spanY = 1; cellInfo.valid = cellXY[0] >= 0 && cellXY[1] >= 0 && cellXY[0] < xCount && cellXY[1] < yCount && !occupied[cellXY[0]][cellXY[1]]; // Instead of finding the interesting vacant cells here, wait until a // caller invokes getTag() to retrieve the result. Finding the vacant // cells is a bit expensive and can generate many new objects, it's // therefore better to defer it until we know we actually need it. mDirtyTag = true; } setTag(cellInfo); } else if (action == MotionEvent.ACTION_UP) { cellInfo.cell = null; cellInfo.cellX = -1; cellInfo.cellY = -1; cellInfo.spanX = 0; cellInfo.spanY = 0; cellInfo.valid = false; mDirtyTag = false; setTag(cellInfo); } if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------end--------------------------------------"); } return false; } @Override public CellInfo getTag() { final CellInfo info = (CellInfo) super.getTag(); if (mDirtyTag && info.valid) { final boolean portrait = mPortrait; final int xCount = portrait ? mShortAxisCells : mLongAxisCells; final int yCount = portrait ? mLongAxisCells : mShortAxisCells; final boolean[][] occupied = mOccupied; findOccupiedCells(xCount, yCount, occupied, null); findIntersectingVacantCells(info, info.cellX, info.cellY, xCount, yCount, occupied); mDirtyTag = false; } return info; } private static void findIntersectingVacantCells(CellInfo cellInfo, int x, int y, int xCount, int yCount, boolean[][] occupied) { cellInfo.maxVacantSpanX = Integer.MIN_VALUE; cellInfo.maxVacantSpanXSpanY = Integer.MIN_VALUE; cellInfo.maxVacantSpanY = Integer.MIN_VALUE; cellInfo.maxVacantSpanYSpanX = Integer.MIN_VALUE; cellInfo.clearVacantCells(); if (occupied[x][y]) { return; } cellInfo.current.set(x, y, x, y); findVacantCell(cellInfo.current, xCount, yCount, occupied, cellInfo); } private static void findVacantCell(Rect current, int xCount, int yCount, boolean[][] occupied, CellInfo cellInfo) { addVacantCell(current, cellInfo); if (current.left > 0) { if (isColumnEmpty(current.left - 1, current.top, current.bottom, occupied)) { current.left--; findVacantCell(current, xCount, yCount, occupied, cellInfo); current.left++; } } if (current.right < xCount - 1) { if (isColumnEmpty(current.right + 1, current.top, current.bottom, occupied)) { current.right++; findVacantCell(current, xCount, yCount, occupied, cellInfo); current.right--; } } if (current.top > 0) { if (isRowEmpty(current.top - 1, current.left, current.right, occupied)) { current.top--; findVacantCell(current, xCount, yCount, occupied, cellInfo); current.top++; } } if (current.bottom < yCount - 1) { if (isRowEmpty(current.bottom + 1, current.left, current.right, occupied)) { current.bottom++; findVacantCell(current, xCount, yCount, occupied, cellInfo); current.bottom--; } } } private static void addVacantCell(Rect current, CellInfo cellInfo) { CellInfo.VacantCell cell = CellInfo.VacantCell.acquire(); cell.cellX = current.left; cell.cellY = current.top; cell.spanX = current.right - current.left + 1; cell.spanY = current.bottom - current.top + 1; if (cell.spanX > cellInfo.maxVacantSpanX) { cellInfo.maxVacantSpanX = cell.spanX; cellInfo.maxVacantSpanXSpanY = cell.spanY; } if (cell.spanY > cellInfo.maxVacantSpanY) { cellInfo.maxVacantSpanY = cell.spanY; cellInfo.maxVacantSpanYSpanX = cell.spanX; } cellInfo.vacantCells.add(cell); } private static boolean isColumnEmpty(int x, int top, int bottom, boolean[][] occupied) { for (int y = top; y <= bottom; y++) { if (occupied[x][y]) { return false; } } return true; } private static boolean isRowEmpty(int y, int left, int right, boolean[][] occupied) { for (int x = left; x <= right; x++) { if (occupied[x][y]) { return false; } } return true; } CellInfo findAllVacantCells(boolean[] occupiedCells, View ignoreView) { final boolean portrait = mPortrait; final int xCount = portrait ? mShortAxisCells : mLongAxisCells; final int yCount = portrait ? mLongAxisCells : mShortAxisCells; boolean[][] occupied = mOccupied; if (occupiedCells != null) { for (int y = 0; y < yCount; y++) { for (int x = 0; x < xCount; x++) { occupied[x][y] = occupiedCells[y * xCount + x]; } } } else { findOccupiedCells(xCount, yCount, occupied, ignoreView); } CellInfo cellInfo = new CellInfo(); cellInfo.cellX = -1; cellInfo.cellY = -1; cellInfo.spanY = 0; cellInfo.spanX = 0; cellInfo.maxVacantSpanX = Integer.MIN_VALUE; cellInfo.maxVacantSpanXSpanY = Integer.MIN_VALUE; cellInfo.maxVacantSpanY = Integer.MIN_VALUE; cellInfo.maxVacantSpanYSpanX = Integer.MIN_VALUE; cellInfo.screen = mCellInfo.screen; Rect current = cellInfo.current; for (int x = 0; x < xCount; x++) { for (int y = 0; y < yCount; y++) { if (!occupied[x][y]) { current.set(x, y, x, y); findVacantCell(current, xCount, yCount, occupied, cellInfo); occupied[x][y] = true; } } } cellInfo.valid = cellInfo.vacantCells.size() > 0; // Assume the caller will perform their own cell searching, otherwise we // risk causing an unnecessary rebuild after findCellForSpan() return cellInfo; } /** * Given a point, return the cell that strictly encloses that point * @param x X coordinate of the point * @param y Y coordinate of the point * @param result Array of 2 ints to hold the x and y coordinate of the cell */ void pointToCellExact(int x, int y, int[] result) { final boolean portrait = mPortrait; final int hStartPadding = portrait ? mShortAxisStartPadding : mLongAxisStartPadding; final int vStartPadding = portrait ? mLongAxisStartPadding : mShortAxisStartPadding; result[0] = (x - hStartPadding) / (mCellWidth + mWidthGap); result[1] = (y - vStartPadding) / (mCellHeight + mHeightGap); final int xAxis = portrait ? mShortAxisCells : mLongAxisCells; final int yAxis = portrait ? mLongAxisCells : mShortAxisCells; if (result[0] < 0) result[0] = 0; if (result[0] >= xAxis) result[0] = xAxis - 1; if (result[1] < 0) result[1] = 0; if (result[1] >= yAxis) result[1] = yAxis - 1; } /** * Given a point, return the cell that most closely encloses that point * @param x X coordinate of the point * @param y Y coordinate of the point * @param result Array of 2 ints to hold the x and y coordinate of the cell */ void pointToCellRounded(int x, int y, int[] result) { pointToCellExact(x + (mCellWidth / 2), y + (mCellHeight / 2), result); } /** * Given a cell coordinate, return the point that represents the upper left corner of that cell * * @param cellX X coordinate of the cell * @param cellY Y coordinate of the cell * * @param result Array of 2 ints to hold the x and y coordinate of the point */ void cellToPoint(int cellX, int cellY, int[] result) { final boolean portrait = mPortrait; final int hStartPadding = portrait ? mShortAxisStartPadding : mLongAxisStartPadding; final int vStartPadding = portrait ? mLongAxisStartPadding : mShortAxisStartPadding; result[0] = hStartPadding + cellX * (mCellWidth + mWidthGap); result[1] = vStartPadding + cellY * (mCellHeight + mHeightGap); } int getCellWidth() { return mCellWidth; } int getCellHeight() { return mCellHeight; } int getLeftPadding() { return mPortrait ? mShortAxisStartPadding : mLongAxisStartPadding; } int getTopPadding() { return mPortrait ? mLongAxisStartPadding : mShortAxisStartPadding; } int getRightPadding() { return mPortrait ? mShortAxisEndPadding : mLongAxisEndPadding; } int getBottomPadding() { return mPortrait ? mLongAxisEndPadding : mShortAxisEndPadding; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // if(MT_GlobalConfig.LOG_DEBUG){ // Log.d(TAG, "-------------------start onMeasure()-------------------") ; // } int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); //根据父组件分配的尺寸来得到当前组件应有的尺寸大小 int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); // if(MT_GlobalConfig.LOG_DEBUG){ // Log.d(TAG, "widthSpecSize="+widthSpecSize +" heightSpecSize="+heightSpecSize) ; // } if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) { throw new RuntimeException("CellLayout cannot have UNSPECIFIED dimensions"); } final int shortAxisCells = mShortAxisCells; final int longAxisCells = mLongAxisCells; final int longAxisStartPadding = mLongAxisStartPadding; final int longAxisEndPadding = mLongAxisEndPadding; final int shortAxisStartPadding = mShortAxisStartPadding; final int shortAxisEndPadding = mShortAxisEndPadding; final int cellWidth = mCellWidth; final int cellHeight = mCellHeight; mPortrait = Mogoo_GlobalConfig.isPortrait(); int numShortGaps = shortAxisCells - 1; int numLongGaps = longAxisCells - 1; heightSpecSize = longAxisStartPadding +longAxisEndPadding + (cellHeight * longAxisCells) ; if (mPortrait) { //取得垂直方向余下的尺寸 int vSpaceLeft = heightSpecSize - longAxisStartPadding - longAxisEndPadding - (cellHeight * longAxisCells); //将垂直方向余下的尺寸平分到单元格垂直间隙中 if(numLongGaps>0){ mHeightGap = vSpaceLeft / numLongGaps; }else{ mHeightGap = 0 ; } //取得水平方向余下的尺寸 int hSpaceLeft = widthSpecSize - shortAxisStartPadding - shortAxisEndPadding - (cellWidth * shortAxisCells); //将水平方向余下的尺寸平分到单元格水平间隙中 if (numShortGaps > 0) { mWidthGap = hSpaceLeft / numShortGaps; } else { mWidthGap = 0; } } else { int hSpaceLeft = widthSpecSize - longAxisStartPadding - longAxisEndPadding - (cellWidth * longAxisCells); if(numLongGaps>0){ mWidthGap = hSpaceLeft / numLongGaps; }else{ mWidthGap = 0; } int vSpaceLeft = heightSpecSize - shortAxisStartPadding - shortAxisEndPadding - (cellHeight * shortAxisCells); if (numShortGaps > 0) { mHeightGap = vSpaceLeft / numShortGaps; } else { mHeightGap = 0; } } int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); if (mPortrait) { lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap, shortAxisStartPadding, longAxisStartPadding); } else { lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap, longAxisStartPadding, shortAxisStartPadding); } if (lp.regenerateId) { child.setId(((getId() & 0xFF) << 16) | (lp.cellX & 0xFF) << 8 | (lp.cellY & 0xFF)); lp.regenerateId = false; } int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); child.measure(childWidthMeasureSpec, childheightMeasureSpec); } setMeasuredDimension(widthSpecSize, heightSpecSize); //初始化单元个坐标列表 initCellCoordinateList(shortAxisCells,longAxisCells,longAxisStartPadding,shortAxisStartPadding,cellWidth,cellHeight,mWidthGap,mHeightGap); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // if(MT_GlobalConfig.LOG_DEBUG){ // Log.d(TAG, "-------------------start onLayout()-------------------") ; // } int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); if (child.getVisibility() != GONE) { CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); int childLeft = lp.x; int childTop = lp.y; child.layout(childLeft, childTop, childLeft + lp.width, childTop + lp.height); if (lp.dropped) { lp.dropped = false; final int[] cellXY = mCellXY; getLocationOnScreen(cellXY); mWallpaperManager.sendWallpaperCommand(getWindowToken(), "android.home.drop", cellXY[0] + childLeft + lp.width / 2, cellXY[1] + childTop + lp.height / 2, 0, null); } } } } @Override protected void setChildrenDrawingCacheEnabled(boolean enabled) { final int count = getChildCount(); for (int i = 0; i < count; i++) { final View view = getChildAt(i); view.setDrawingCacheEnabled(enabled); // Update the drawing caches view.buildDrawingCache(true); } } @Override protected void setChildrenDrawnWithCacheEnabled(boolean enabled) { super.setChildrenDrawnWithCacheEnabled(enabled); } /** * Find a vacant area that will fit the given bounds nearest the requested * cell location. Uses Euclidean distance to score multiple vacant areas. * * @param pixelX The X location at which you want to search for a vacant area. * @param pixelY The Y location at which you want to search for a vacant area. * @param spanX Horizontal span of the object. * @param spanY Vertical span of the object. * @param vacantCells Pre-computed set of vacant cells to search. * @param recycle Previously returned value to possibly recycle. * @return The X, Y cell of a vacant area that can contain this object, * nearest the requested location. */ int[] findNearestVacantArea(int pixelX, int pixelY, int spanX, int spanY, CellInfo vacantCells, int[] recycle) { // Keep track of best-scoring drop area final int[] bestXY = recycle != null ? recycle : new int[2]; final int[] cellXY = mCellXY; double bestDistance = Double.MAX_VALUE; // Bail early if vacant cells aren't valid if (!vacantCells.valid) { return null; } // Look across all vacant cells for best fit final int size = vacantCells.vacantCells.size(); for (int i = 0; i < size; i++) { final CellInfo.VacantCell cell = vacantCells.vacantCells.get(i); // Reject if vacant cell isn't our exact size if (cell.spanX != spanX || cell.spanY != spanY) { continue; } // Score is center distance from requested pixel cellToPoint(cell.cellX, cell.cellY, cellXY); double distance = Math.sqrt(Math.pow(cellXY[0] - pixelX, 2) + Math.pow(cellXY[1] - pixelY, 2)); if (distance <= bestDistance) { bestDistance = distance; bestXY[0] = cell.cellX; bestXY[1] = cell.cellY; } } // Return null if no suitable location found if (bestDistance < Double.MAX_VALUE) { return bestXY; } else { return null; } } /** * Drop a child at the specified position * * @param child The child that is being dropped * @param targetXY Destination area to move to */ void onDropChild(View child, int[] targetXY) { if (child != null) { CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); lp.cellX = targetXY[0]; lp.cellY = targetXY[1]; lp.isDragging = false; lp.dropped = true; mDragRect.setEmpty(); child.requestLayout(); invalidate(); } } void onDropAborted(View child) { if (child != null) { ((CellLayout.LayoutParams) child.getLayoutParams()).isDragging = false; invalidate(); } mDragRect.setEmpty(); } /** * Start dragging the specified child * * @param child The child that is being dragged */ void onDragChild(View child) { CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); lp.isDragging = true; mDragRect.setEmpty(); } /** * Drag a child over the specified position * * @param child The child that is being dropped * @param cellX The child's new x cell location * @param cellY The child's new y cell location */ void onDragOverChild(View child, int cellX, int cellY) { int[] cellXY = mCellXY; pointToCellRounded(cellX, cellY, cellXY); CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); cellToRect(cellXY[0], cellXY[1], lp.cellHSpan, lp.cellVSpan, mDragRect); invalidate(); } /** * Computes a bounding rectangle for a range of cells * * @param cellX X coordinate of upper left corner expressed as a cell position * @param cellY Y coordinate of upper left corner expressed as a cell position * @param cellHSpan Width in cells * @param cellVSpan Height in cells * @param dragRect Rectnagle into which to put the results */ public void cellToRect(int cellX, int cellY, int cellHSpan, int cellVSpan, RectF dragRect) { final boolean portrait = mPortrait; final int cellWidth = mCellWidth; final int cellHeight = mCellHeight; final int widthGap = mWidthGap; final int heightGap = mHeightGap; final int hStartPadding = portrait ? mShortAxisStartPadding : mLongAxisStartPadding; final int vStartPadding = portrait ? mLongAxisStartPadding : mShortAxisStartPadding; int width = cellHSpan * cellWidth + ((cellHSpan - 1) * widthGap); int height = cellVSpan * cellHeight + ((cellVSpan - 1) * heightGap); int x = hStartPadding + cellX * (cellWidth + widthGap); int y = vStartPadding + cellY * (cellHeight + heightGap); dragRect.set(x, y, x + width, y + height); } /** * Computes the required horizontal and vertical cell spans to always * fit the given rectangle. * * @param width Width in pixels * @param height Height in pixels */ public int[] rectToCell(int width, int height) { // Always assume we're working with the smallest span to make sure we // reserve enough space in both orientations. final Resources resources = getResources(); int actualWidth = resources.getDimensionPixelSize(R.dimen.workspace_cell_width); int actualHeight = resources.getDimensionPixelSize(R.dimen.workspace_cell_height); int smallerSize = Math.min(actualWidth, actualHeight); // Always round up to next largest cell int spanX = (width + smallerSize) / smallerSize; int spanY = (height + smallerSize) / smallerSize; return new int[] { spanX, spanY }; } /** * Find the first vacant cell, if there is one. * * @param vacant Holds the x and y coordinate of the vacant cell * @param spanX Horizontal cell span. * @param spanY Vertical cell span. * * @return True if a vacant cell was found */ public boolean getVacantCell(int[] vacant, int spanX, int spanY) { final boolean portrait = mPortrait; final int xCount = portrait ? mShortAxisCells : mLongAxisCells; final int yCount = portrait ? mLongAxisCells : mShortAxisCells; final boolean[][] occupied = mOccupied; findOccupiedCells(xCount, yCount, occupied, null); return findVacantCell(vacant, spanX, spanY, xCount, yCount, occupied); } static boolean findVacantCell(int[] vacant, int spanX, int spanY, int xCount, int yCount, boolean[][] occupied) { for (int x = 0; x < xCount; x++) { for (int y = 0; y < yCount; y++) { boolean available = !occupied[x][y]; out:for (int i = x; i < x + spanX - 1 && x < xCount; i++) { for (int j = y; j < y + spanY - 1 && y < yCount; j++) { available = available && !occupied[i][j]; if (!available) break out; } } if (available) { vacant[0] = x; vacant[1] = y; return true; } } } return false; } boolean[] getOccupiedCells() { final boolean portrait = mPortrait; final int xCount = portrait ? mShortAxisCells : mLongAxisCells; final int yCount = portrait ? mLongAxisCells : mShortAxisCells; final boolean[][] occupied = mOccupied; findOccupiedCells(xCount, yCount, occupied, null); final boolean[] flat = new boolean[xCount * yCount]; for (int y = 0; y < yCount; y++) { for (int x = 0; x < xCount; x++) { flat[y * xCount + x] = occupied[x][y]; } } return flat; } private void findOccupiedCells(int xCount, int yCount, boolean[][] occupied, View ignoreView) { for (int x = 0; x < xCount; x++) { for (int y = 0; y < yCount; y++) { occupied[x][y] = false; } } int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); if (child instanceof Folder || child.equals(ignoreView)) { continue; } CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); for (int x = lp.cellX; x < lp.cellX + lp.cellHSpan && x < xCount; x++) { for (int y = lp.cellY; y < lp.cellY + lp.cellVSpan && y < yCount; y++) { occupied[x][y] = true; } } } } @Override public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { return new CellLayout.LayoutParams(getContext(), attrs); } @Override protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { return p instanceof CellLayout.LayoutParams; } @Override protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { return new CellLayout.LayoutParams(p); } public boolean lastDownOnOccupiedCell() { return mLastDownOnOccupiedCell; } public void setDragController(DragController dragger) { this.dragController = dragger ; } public void startDrag(CellLayout.CellInfo cellInfo) { View child = cellInfo.cell; // Make sure the drag was started by a long press as opposed to a long click. if (!child.isInTouchMode()) { return; } //mDragCellInfo = cellInfo; setDragInfo(cellInfo.cellIndex); dragController.startDrag2(cellInfo, child, this, child.getTag(),DragController.DRAG_ACTION_MOVE); mDragInfo.cell.setVisibility(INVISIBLE); invalidate(); } public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------call onDragEnter()--------------------------------------isLocaleDrag="+isLocaleDrag); } if(!acceptFlag){ return; } //如果是从别的区域拖进来的 if(((ItemInfo)dragInfo).container != ((ItemInfo)loadingFolder.getTag()).id || fromOtherFolder(dragInfo) || isFull()) { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------drag from other area--------------------------------------mDragInfo.cell="+mDragInfo.cell); } if(!acceptDrop(source, x, y, xOffset, yOffset, dragView, dragInfo)){ return ; } isLocaleDrag = true ; View view = createFolderItem(dragInfo); mDragInfo.cell = view; mDragInfo.cellIndex = -1; mDragInfo.cell.setVisibility(View.INVISIBLE); mDragInfo.screen = Launcher.getScreen(); addView(mDragInfo.cell, false); Mogoo_FolderInfo openFolderInfo = getOpenFolderInfo() ; if(openFolderInfo!=null){ openFolderInfo.addItem(getContext(), (ShortcutInfo)mDragInfo.cell.getTag()) ; } setDragInfo(getChildCount()-1) ; // LauncherModel.setSortIconInfo(R.id.folderWorkspace, (int)folderId); } else { //拖出去又拖进来的情况 if(isLocaleDrag) { View view = createFolderItem(dragInfo); mDragInfo.cell = view; mDragInfo.cellIndex = -1; mDragInfo.cell.setVisibility(View.INVISIBLE); mDragInfo.screen = Launcher.getScreen(); addView(mDragInfo.cell, false); Mogoo_FolderInfo openFolderInfo = getOpenFolderInfo() ; if(openFolderInfo!=null){ openFolderInfo.addItem(launcher, (ShortcutInfo)mDragInfo.cell.getTag()) ; } setDragInfo(getChildCount()-1) ; // LauncherModel.setSortIconInfo(R.id.folderWorkspace, (int)folderId); } isLocaleDrag = true ; if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------drag from local area--------------------------------------"); } } if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------call onDragEnter() end--------------------------------------"); } } private boolean fromOtherFolder(Object dragInfo){ if(getOpenFolderInfo() == null){ return false; } if(!(dragInfo instanceof ItemInfo)){ return true; } ItemInfo info = (ItemInfo) dragInfo; ItemInfo targetInfo = getOpenFolderInfo(); return info.container != targetInfo.id; } public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------start onDragOver()--------------------------------------"); } if(isFull()){ return ; } int endIndex = findTargetIndex(dragView, this); if (mDragInfo != null && dragController.sortView(this, mDragInfo.cellIndex, endIndex)) { setDragInfo(endIndex); updateShortcutInfo(); // LauncherModel.setSortIconInfo(R.id.folderWorkspace, (int)folderId); } } public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { } public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------call onDrop()--------------------------------------"); } Mogoo_FolderController folderController = launcher.getFolderController(); folderController.setCanActive(false); // folderController.iconFolderInactive(); if(!acceptFlag){ source.onRestoreDragIcon(dragInfo); return; } if(mDragInfo.cell!=null) { ShortcutInfo shortcutInfo = (ShortcutInfo) mDragInfo.cell.getTag(); mIconCache.recycle(shortcutInfo.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); ((Mogoo_BubbleTextView) mDragInfo.cell).setReflection(false); ((Mogoo_BubbleTextView) mDragInfo.cell).setIconReflection(null); mDragInfo.cell.setVisibility(View.VISIBLE) ; Mogoo_FolderInfo info = null; Mogoo_FolderBubbleText folder = null; if(loadingFolder != null){ info = (Mogoo_FolderInfo) loadingFolder.getTag(); folder = loadingFolder; }else if(closeFolder != null){ info = (Mogoo_FolderInfo) closeFolder.getTag(); folder = closeFolder; } else { throw new NullPointerException(); } info.addItem(getContext(), (ShortcutInfo) mDragInfo.cell.getTag()); mIconCache.recycle(info.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); mIconCache.remove(info.intent.getComponent()); folder.setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(info.getIcon(mIconCache)), null, null); folder.setText(info.title); // redrawIconWhenOpenFolder(folder, info); // loadFolderWorkspace(loadingFolder) ; if(mDragInfo.cell instanceof Mogoo_BubbleTextView){ ((Mogoo_BubbleTextView)mDragInfo.cell).startVibrate(mIconCache, 0); } } //打开文件夹时,没有经过dragEnter直接onDrop时做如下处理 else { //文件夹中加入新图标 View view = createFolderItem(dragInfo); addView(view, false); Mogoo_FolderInfo openFolderInfo = getOpenFolderInfo() ; if(openFolderInfo!=null){ openFolderInfo.addItem(launcher, (ShortcutInfo)view.getTag()) ; } //删除之前所在的容器中的图标并排序,因为发此种情况的只有在workspace时 if(source instanceof Workspace) { Workspace workspace = (Workspace) source ; CellLayout cellLayout = (CellLayout)workspace.getChildAt(workspace.getCurrentScreen()) ; ShortcutInfo info = (ShortcutInfo) dragInfo ; int index = Mogoo_Utilities.getIndexByCellXY(info.cellX, info.cellY) ; // dragController.sortView(cellLayout, index, cellLayout.getChildCount()-1) ; cellLayout.removeViewAt(index) ; reLayoutCellLayout(cellLayout) ; } mIconCache.recycle(openFolderInfo.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); mIconCache.remove(openFolderInfo.intent.getComponent()); loadingFolder.setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(openFolderInfo.getIcon(mIconCache)), null, null); //重新load文件夹 // loadFolderWorkspace(loadingFolder) ; if(view instanceof Mogoo_BubbleTextView){ ((Mogoo_BubbleTextView)view).startVibrate(mIconCache, 0); } } resetDragInfo(); isLocaleDrag = false ; if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "-------------------------end--------------------------------------"); } } private void redrawIconWhenOpenFolder(Mogoo_FolderBubbleText folder, Mogoo_FolderInfo info) { CellEntry entry = null; Mogoo_ComponentBus bus = Mogoo_ComponentBus.getInstance(); Workspace ws = (Workspace)bus.getActivityComp(R.id.workspace, getContext()); Mogoo_DockWorkSpace dock = (Mogoo_DockWorkSpace)bus.getActivityComp(R.id.dockWorkSpace, getContext()); if(info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP){ View v = ws.getChildAt(info.screen); ImageView image = (ImageView) bus.getActivityComp(R.id.folderLayerTopImage, getContext()); if(v != null && image != null && image.getDrawable() != null){ Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap(); Canvas c = new Canvas(bitmap); folder.drawWorkspaceImage(mIconCache, c, ((CellLayout)v).getCellEntry(Mogoo_Utilities.getIndexByCellXY(info.cellX, info.cellY))); image.setImageBitmap(bitmap); c = null; } image = null; //dock 工具栏暂时不开放图标文件夹功能 } else if(info.container == LauncherSettings.Favorites.CONTAINER_TOOLBAR){ // ImageView topImage = (ImageView) bus.getActivityComp(R.id.folderLayerTopImage, getContext()); // ImageView bottomImage = (ImageView) bus.getActivityComp(R.id.folderLayerBottomImage, getContext()); // if(dock != null && bottomImage != null){ // Bitmap bitmap = ((BitmapDrawable)bottomImage.getDrawable()).getBitmap(); // Canvas c = new Canvas(bitmap); // // // 获取屏幕的高宽 // int screenWidth = MT_GlobalConfig.getScreenWidth(); // 屏幕的宽 // int screenHeight = MT_GlobalConfig.getScreenHeight(); // 屏幕的高 // //取得当前状态栏的高度 // int statusBarHeight = ws.getStatusBarHeight() ; // int dockStartY = screenHeight-statusBarHeight-dock.getHeight(); // // folder.drawDockworkspaceImage(mIconCache, c, dockLastOpenEntry, dockStartY - topImage.getHeight()); // bottomImage.setImageBitmap(bitmap); // c = null; // } // // topImage = null; // bottomImage = null; } } public void onDropCompleted(View target, boolean success) { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------start onDropCompleted()--------------------------------------"); } resetDragInfo(); LauncherModel.saveAllIconInfo(getContext()); isLocaleDrag = false ; if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "-------------------------end--------------------------------------"); } } public void onDropTargetChange(DragSource source, DropTarget dropTarget, DragView dragView, Object dragInfo) { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------start onDropTargetChange()--------------------------------------"); Log.d(TAG, "mDragInfo.cellIndex =" + mDragInfo.cellIndex); } if(mDragInfo!=null && mDragInfo.cell!=null) { Mogoo_ComponentBus bus = Mogoo_ComponentBus.getInstance(); Workspace workspace = (Workspace)bus.getActivityComp(R.id.workspace, getContext()) ; workspace.setVisibility(View.VISIBLE); bus.getActivityComp(R.id.dockWorkSpace, getContext()).setVisibility(View.VISIBLE); // MT_FolderBubbleText loadingFolderTemp = loadingFolder ; if(loadingFolder != null){ closeFolder = loadingFolder ; outputView(); // if(!newFolderClosed) // { // System.out.println("==========================================="); // //将包含一个快捷方式图标的文件夹更新为里面的快捷方式图标 // //界面 // MT_FolderInfo folderInfo = (MT_FolderInfo)loadingFolderTemp.getTag() ; // ShortcutInfo info = folderInfo.getContents().get(0) ; // View view = createFolderItem(info); // CellLayout cellLayout = (CellLayout)workspace.getChildAt(folderInfo.screen) ; // // cellLayout.addView(view,MT_Utilities.getIndexByCellXY(folderInfo.cellX, folderInfo.cellY)) ; // // workspace.removeView(loadingFolderTemp) ; // // info.cellX = folderInfo.cellX ; // info.cellY = folderInfo.cellY ; // info.container = LauncherSettings.Favorites.CONTAINER_DESKTOP ; // info.screen = folderInfo.screen ; // // //db // LauncherModel.deleteItemFromDatabase(launcher, folderInfo) ; // LauncherModel.updateItemInDatabase(launcher, info); // // } //关闭前记录下要关闭的文件夹 // closeFolder = (MT_FolderBubbleText) loadingFolder.clone() ; loadingFolder.closeFolder(); } // LauncherModel.setSortIconInfo(R.id.folderWorkspace, (int)folderId); } resetDragInfo(); if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "-------------------------- end --------------------------------------"); } } /** * * 处理从folder 内拖到 folder外的事件 * @ author: 黄悦 */ private void outputView() { final Mogoo_FolderInfo info = (Mogoo_FolderInfo) loadingFolder.getTag(); info.getContents().remove(mDragInfo.cell.getTag()); mIconCache.recycle(info.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); if(info.getContents().size() > 0){ mIconCache.remove(info.intent.getComponent()); loadingFolder.setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(info.getIcon(mIconCache)), null, null); dragController.sortWithoutAnimation(this, mDragInfo.cellIndex, getChildCount() - 1); removeView(mDragInfo.cell); LauncherModel.updateItemInDatabase(getContext(), info); }else{ // new Handler().postDelayed(new Runnable() { // public void run() { if(loadingFolder == null){ return; } ViewGroup parent = (ViewGroup) loadingFolder.getParent(); if(parent == null){ return; } int index = 0; for(int i = 0; i < parent.getChildCount(); i++){ if(loadingFolder.equals(parent.getChildAt(i))){ index = i; break; } } removeViews(0, getChildCount()) ; // closeFolder.setVisibility(View.INVISIBLE); dragController.sortView(parent, index, parent.getChildCount() - 1); LauncherModel.deleteItemFromDatabase(getContext(), info); mIconCache.recycle(((ShortcutInfo)(loadingFolder.getTag())).intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); loadingFolder.stopVibrate(); parent.removeView(loadingFolder); mIconCache.remove(((ShortcutInfo)(loadingFolder.getTag())).intent.getComponent()); LauncherModel.deleteItemFromDatabase(getContext(), info); if(parent instanceof Workspace) { LauncherModel.setSortIconInfo(R.id.workspace, info.screen); } else if(parent instanceof Mogoo_DockWorkSpace) { LauncherModel.setSortIconInfo(R.id.dockWorkSpace, -1); } // reLayoutCellLayout(parent) ; // } // }, 1500); } // updateShortcutInfo(); } public void onRestoreDragIcon(Object dragInfo) { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------start onRestoreDragIcon()--------------------------------------"); } //拖向别的区域后,别的区域不接收时 if (mDragInfo.cellIndex == -1) { //恢复文件夹 restoreFolder((ShortcutInfo)dragInfo) ; } if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "------------------------- end --------------------------------------"); } } public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { if(dragInfo instanceof ShortcutInfo && !isFull()) { return true ; } else { return false ; } } public Rect estimateDropLocation(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo, Rect recycle) { return null; } public int findTargetIndex(DragView dragView, ViewGroup parent) { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "--------------------start findTargetIndex()--------------------------------------"); } int targetIndex = -1; // 拖动图标左上角的坐标 int x = dragView.getScreenLeft(); int y = dragView.getScreenTop() - getScreenTop(); int width = dragView.getWidth(); int height = dragView.getHeight(); // 取得拖动图标相交的第一个单元格的素引号 int index = getCellIndexByDragView(dragView); if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "current screen child count:"+getChildCount()); } if (index == -1) { targetIndex = getChildCount() - 1; // 放于最后一个位置 } else if (index >= getChildCount()) { targetIndex = getChildCount() - 1; // 放于最后一个位置 } else { // index单元格 CellEntry entry = getCellEntry(index); // 拖动图标左上角是否在index所在的单元格内 if (x >= entry.left && x <= entry.right && y >= entry.top && y <= entry.bottom) {// 在里面 targetIndex = findTargetIndexInner(x, y, width, height, index) ; } else {//在外面 targetIndex = findTargetIndexOuter(x, y, width, height, index) ; } } // 如果目标位置大于等于图标总数目时,则放于最后一个位置 if (targetIndex >= getChildCount()) { targetIndex = getChildCount() - 1; } // 重置拖动开始索引值 if (targetIndex != -1) { dragView.setStartIndex(targetIndex); } if (Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "Find Target Index:" + targetIndex); Log.d(TAG, "------------------------- end --------------------------------------"); } return targetIndex; } /** * 重整celllayout * @ author: 张永辉 *@param cellLayout */ private void reLayoutCellLayout(ViewGroup parent) { if(parent instanceof CellLayout){ Workspace ws = (Workspace) Mogoo_ComponentBus.getInstance().getActivityComp(R.id.workspace, getContext()); ws.reLayoutCellLayout(parent); }else if(parent instanceof Mogoo_DockWorkSpace){ Mogoo_DockWorkSpace dw = (Mogoo_DockWorkSpace) Mogoo_ComponentBus.getInstance().getActivityComp(R.id.dockWorkSpace, getContext()); dw.resetCellLayout(new int[]{0}); } } /** * 左上角在里面 *@author: 张永辉 *@Date:2011-3-22 *@param x *@param y *@param width *@param height *@param index *@return */ private int findTargetIndexInner(int x,int y,int width,int height,int index){ int targetIndex = -1 ; // 看右上角在哪个单元格内 int rightTopIndex = getCellIndexByCoordinate(x + width, y); // 看右下角在哪个单元格内 int rightBottomIndex = getCellIndexByCoordinate(x + width, y + height); // 看左下角在哪个单元格内 int leftBottomIndex = getCellIndexByCoordinate(x, y + height); if (Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "leftBottomIndex=" + leftBottomIndex + " rightTopIndex=" + rightTopIndex + " rightBottomIndex=" + rightBottomIndex); } //行宽 int rowWidth = Mogoo_GlobalConfig.getWorkspaceLongAxisCells(Mogoo_GlobalConfig.isLandscape()) ; // 左上角与左下角在同一个单元格内 if (leftBottomIndex == index) { // 如果四个角在同一个单元格内 if (rightTopIndex == index) { targetIndex = index; } // 不在同一个单元格内,则通过面积来返回单元格号 else { //如果右下角不在单元格内,则返回左下角所在的单元格号 if(rightBottomIndex==-1) { targetIndex = leftBottomIndex ; } else { int leftPart = getCellEntry(leftBottomIndex).right - x ; int rightPart = x + width - getCellEntry(rightBottomIndex).left ; if(leftPart >= rightPart){ targetIndex = leftBottomIndex ; }else{ targetIndex = rightBottomIndex ; } } } } // 左上角与左下角不在同一个单元格内 else { // 如果左上角与右上角在同一个单元格内 if (index == rightTopIndex) { // 左下角在外面,则取左上角所在单元格号 if (leftBottomIndex == -1) { targetIndex = index; } // 左下角在单元格内,则看是否跨了三个单元格 else { //跨了三个单元格高度,则取中间的单元格号 if(leftBottomIndex-index == rowWidth*2) { targetIndex = index + rowWidth ; } //跨了二个单元格高度,则看上半部分与下半部分的面积大小 else { int topPart = getCellEntry(index).bottom - y; int bottomPart = (y + height) - getCellEntry(leftBottomIndex).top; // 上半部分大 if (topPart >= bottomPart) { targetIndex = index; } // 下半部分大 else { targetIndex = leftBottomIndex; } } } } // 如果左上角与右上角不在同一个单元格内 else { // 左下角不在单元格内,看是否跨了二个单元格高度。 if (leftBottomIndex == -1) { //左边中点所在单元格号 int leftMiddleIndex = this.getCellIndexByCoordinate(x, y+height/2) ; //占一个单元格高度,则取上半部分,再看左右大小 if(leftMiddleIndex==index||leftMiddleIndex==-1){ //add by 张永辉 2011-7-21 //跨三列或跨二列但右上角在单元格外面 if(rightTopIndex-index==2||(rightTopIndex==-1&&(rightTopIndex-index-1)%rowWidth==0)){ targetIndex = index+1 ; } //end add //跨二列或一列 //如果右上角不在单元格内,则返回左上角所在单元格号 else if(rightTopIndex==-1) { targetIndex = index ; } else { int leftPart = getCellEntry(index).right - x ; int rightPart = x + width - getCellEntry(rightTopIndex).left ; if(leftPart>=rightPart){ targetIndex = index ; }else{ targetIndex = rightTopIndex ; } } } //占二个单元格高度 else { //add by 张永辉 2011-7-21 //跨三列或跨二列但右上角在单元格外面 if(rightTopIndex-index==2||(rightTopIndex==-1&&(rightTopIndex-index-1)%rowWidth==0)){ targetIndex = index+1+rowWidth ; } //end add //跨二列或一列 //如果右上角不在单元格内,则返回左边的 else if(rightTopIndex==-1) { targetIndex = index + rowWidth ; } else { int leftPart = getCellEntry(index).right - x ; int rightPart = x + width - getCellEntry(rightTopIndex).left ; if(leftPart>=rightPart){ targetIndex = index + rowWidth ; }else{ targetIndex = rightTopIndex + rowWidth ; } } } } // 左下角在单元格内,看是否跨越了三个单元格高度, else { //跨了三行 if(leftBottomIndex-index==rowWidth*2) { //add by 张永辉 2011-7-21 //跨三列或跨二列但右上角在单元格外面 if(rightTopIndex-index==2||(rightTopIndex==-1&&(rightTopIndex-index-1)%rowWidth==0)){ targetIndex = index+1+rowWidth ; } //end add //跨二列或一列 //如果右上角不在单元格内,则返回左边的 else if(rightTopIndex==-1) { targetIndex = index + rowWidth ; } else { int leftPart = getCellEntry(index).right - x ; int rightPart = x + width - getCellEntry(rightTopIndex).left ; if(leftPart>=rightPart){ targetIndex = index + rowWidth ; }else{ targetIndex = rightTopIndex + rowWidth ; } } } //跨了二行,则看上下部分哪个部分大 else { int topPart = getCellEntry(index).bottom - y; int bottomPart = (y + height) - getCellEntry(leftBottomIndex).top; //add by 张永辉 2011-7-21 //跨三列或跨二列但右上角在单元格外面 if(rightTopIndex-index==2||(rightTopIndex==-1&&(rightTopIndex-index-1)%rowWidth==0)){ if (topPart >= bottomPart) { targetIndex = index+1 ; }else{ targetIndex = index+1+rowWidth ; } } //end add //跨一列或二列 // 上半部分大,则再看左右大小 else if (topPart >= bottomPart) { //如果右边在单元格外面,则直接返回左上角的单元格号 if(rightTopIndex==-1) { targetIndex = index ; } else { int leftPart = getCellEntry(index).right - x ; int rightPart = x + width - getCellEntry(rightTopIndex).left ; if(leftPart>=rightPart){ targetIndex = index ; }else{ targetIndex = rightTopIndex ; } } } // 下半部分大,则再左右大小 else { //右下角是否在单元格外面,如果在,则返回左下角所在的单元格号 if(rightBottomIndex==-1) { targetIndex = leftBottomIndex ; } else { int leftPart = getCellEntry(leftBottomIndex).right - x ; int rightPart = x + width - getCellEntry(rightBottomIndex).left ; if(leftPart>=rightPart){ targetIndex = leftBottomIndex ; }else{ targetIndex = rightBottomIndex ; } } } } } } } return targetIndex ; } /** * 左上角在外面 *@author: 张永辉 *@Date:2011-3-22 *@param x *@param y *@param width *@param height *@param index *@return */ private int findTargetIndexOuter(int x,int y,int width,int height,int index){ int targetIndex = -1 ; // 看右上角在哪个单元格内 int rightTopIndex = getCellIndexByCoordinate(x + width, y); // 看右下角在哪个单元格内 int rightBottomIndex = getCellIndexByCoordinate(x + width, y + height); // 看左下角在哪个单元格内 int leftBottomIndex = getCellIndexByCoordinate(x, y + height); if (Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "leftBottomIndex=" + leftBottomIndex + " rightTopIndex=" + rightTopIndex + " rightBottomIndex=" + rightBottomIndex); } //行宽 int rowWidth = Mogoo_GlobalConfig.getWorkspaceLongAxisCells(Mogoo_GlobalConfig.isLandscape()) ; // 如果左下角不在单元格内 if (leftBottomIndex == -1) { // 如果右上角不在单元格内,则返回第一个相交的单元格号 if (rightTopIndex == -1) { if (rightBottomIndex != -1) { targetIndex = index; } else { targetIndex = -1; } } // 如果右上角在单元格内,且右上角和右下角都在同一个单元格内,则返回右上角所在的单元格号 else if (rightTopIndex == rightBottomIndex) { targetIndex = rightTopIndex; } // 如果右上角和右下角所在的单元格不相同,则比较拖动图标在这二个单元格中哪个占用面积大,则返回哪个单元格号 else if (rightTopIndex != rightBottomIndex) { // 右下角在单元格外面 if (rightBottomIndex == -1){ //右边中点所在单元格 int rightMiddleIndex = this.getCellIndexByCoordinate(x+width, y+height/2) ; //add by 张永辉 2011-7-21 //跨了二列 if(rightTopIndex%rowWidth!=0&&(rightTopIndex-1)%rowWidth==0&&(index+rowWidth)<Mogoo_GlobalConfig.getWorkspaceCellCounts()-rowWidth){ //高度占一行 if(rightTopIndex==rightMiddleIndex||rightMiddleIndex==-1){ targetIndex = index ; } //高度占二行 else{ targetIndex = index + rowWidth ; } } //end add //一列 //如果右边中点与右上角在同一个单元格内,则返回右上角所在单元格号 else if(rightTopIndex==rightMiddleIndex) { targetIndex = rightTopIndex; } //右边中点在外面 else if(rightMiddleIndex==-1){ targetIndex = rightTopIndex; } //右边中间在里面,则取右中点所在单元格号 else { targetIndex = rightMiddleIndex; } } // 右下角在单元格里面 else { //如果右边跨越三个单元格,则选中间的单元格 if(rightBottomIndex-rightTopIndex==rowWidth*2){ //add by 张永辉 2011-7-21 //跨二列 if(rightTopIndex%rowWidth!=0&&(rightTopIndex-1)%rowWidth==0&&(index+rowWidth)<Mogoo_GlobalConfig.getWorkspaceCellCounts()-rowWidth){ targetIndex = index + rowWidth ; } //end //跨一列 else{ targetIndex = rightTopIndex + rowWidth ; } } //跨越二个单元格 else { int topPart = getCellEntry(rightTopIndex).bottom - y; int bottomPart = (y + height) - getCellEntry(rightBottomIndex).top; //add by 张永辉 2011-7-21 //跨二列 if(rightTopIndex%rowWidth!=0&&(rightTopIndex-1)%rowWidth==0&&(index+rowWidth)<Mogoo_GlobalConfig.getWorkspaceCellCounts()-rowWidth){ if (topPart >= bottomPart) { targetIndex = index ; } else{ targetIndex = index + rowWidth ; } } //end //跨一列 else if (topPart >= bottomPart) { targetIndex = rightTopIndex; } else { targetIndex = rightBottomIndex; } } } } } // 如果左下角在单元格内 else if (leftBottomIndex != -1) { // 左下角与右下角都在同一个单元格内,看是否跨二行单元 if (leftBottomIndex == rightBottomIndex) { //跨二行 if(leftBottomIndex-index==rowWidth){ targetIndex = index ; } //跨一行,则返回左下角所在的单元格号 else{ targetIndex = leftBottomIndex; } } // 如果不在同一个单元格内,看是否跨二行单元 else { //add by 张永辉 2011-7-21 //跨三列或二列但右下角在单元格外面 if(rightBottomIndex-index==2||(rightBottomIndex==-1&&(rightBottomIndex-index-1)%rowWidth==0)){ targetIndex = index+1; } //end add //跨二列或一列 //跨二行,看哪个占面积大,则返回哪一个单元格号 else if(leftBottomIndex-index==rowWidth){ //如果右下角在单元格外面,则返回左边的 if(rightBottomIndex==-1) { targetIndex = leftBottomIndex - rowWidth ; } else { int leftPart = this.getCellEntry(leftBottomIndex).right - x ; int rightPart = x + width - this.getCellEntry(rightBottomIndex).left ; if(leftPart>=rightPart){ targetIndex = leftBottomIndex - rowWidth ; }else{ targetIndex = rightBottomIndex - rowWidth ; } } } //跨一行,看哪个占面积大,则返回哪一个单元格号 else{ //如果右下角在单元格外面,则返回左下解所在的单元格号 if(rightBottomIndex==-1) { targetIndex = leftBottomIndex ; } else { int leftPart = this.getCellEntry(leftBottomIndex).right - x ; int rightPart = x + width - this.getCellEntry(rightBottomIndex).left ; if(leftPart>=rightPart){ targetIndex = leftBottomIndex ; }else{ targetIndex = rightBottomIndex ; } } } } } // 如果左下角也不在单元格内,则返回右下角所在的单元格 else { targetIndex = rightBottomIndex != -1 ? rightBottomIndex : -1; } return targetIndex ; } public CellEntry getCellEntry(int cellIndex) { if(cellIndex >= cellCoordinateList.size()){ return null; } return cellCoordinateList.get(cellIndex); } public List<CellEntry> getCellCoordinateList(){ return cellCoordinateList ; } /** * 初始化单元格坐标值到列表中 * @ author: 张永辉 *@param shortAxisCells 纵向单元格数 *@param longAxisCells 横向单元格数 *@param longAxisStartPadding 长轴开始大小 *@param shortAxisStartPadding 短轴开始大小 *@param cellWidth 单元格宽 *@param cellHeight 单元格高 *@param mWidthGap 单元格与单元格之间的间隙宽 *@param mHeightGap 单元格与单元格之间的间隙高 */ private void initCellCoordinateList(int shortAxisCells, int longAxisCells, int longAxisStartPadding, int shortAxisStartPadding, int cellWidth, int cellHeight, int mWidthGap, int mHeightGap) { // if(MT_GlobalConfig.LOG_DEBUG){ // Log.d(TAG, "shortAxisCells="+shortAxisCells+" longAxisCells="+longAxisCells) ; // Log.d(TAG, "longAxisStartPadding="+longAxisStartPadding+" shortAxisStartPadding="+shortAxisStartPadding) ; // Log.d(TAG, "cellWidth="+cellWidth+" cellHeight="+cellHeight) ; // Log.d(TAG, "mWidthGap="+mWidthGap+" mHeightGap="+mHeightGap) ; // } cellCoordinateList.clear(); for(int i=0;i<longAxisCells;i++) { for(int j=0;j<shortAxisCells;j++) { int left = shortAxisStartPadding+j*cellWidth+j*mWidthGap ; int right = left + cellWidth ; int top = longAxisStartPadding+i*cellHeight+i*mHeightGap ; int bottom = top + cellHeight ; CellEntry entry = new CellEntry() ; entry.left = left ; entry.bottom = bottom ; entry.right = right ; entry.top = top ; // if(MT_GlobalConfig.LOG_DEBUG) // { // Log.d(TAG, "left="+left+" top="+top+" right="+right+" bottom="+bottom); // } cellCoordinateList.add(entry); } } } /** * 加载文件夹内容区域 * @author: 张永辉 * @param folder */ public void loadFolderWorkspace(Mogoo_FolderBubbleText folder){ if(folder == null){ return; } // clearViews(); Object tag = folder.getTag() ; if(tag instanceof Mogoo_FolderInfo){ Mogoo_FolderInfo info = (Mogoo_FolderInfo)tag ; List<ShortcutInfo> items = info.getContents() ; loadingFolder = folder; //内容排序 Collections.sort(items, new Mogoo_FolderInfo.SortByIndex()) ; int size = items.size() ; folderId = info.id ; if (Mogoo_GlobalConfig.isPortrait()) { //列数 mShortAxisCells = Mogoo_GlobalConfig.getWorkspaceShortAxisCellsPort() ; //行数 mLongAxisCells = (size-1)/mShortAxisCells +1 ; if(info.isAddRow()) { mLongAxisCells+=1 ; } mOccupied = new boolean[mShortAxisCells][mLongAxisCells]; } else { //列数 mLongAxisCells = Mogoo_GlobalConfig.getWorkspaceLongAxisCellsLand() ; //行数 mShortAxisCells = (size-1)/mLongAxisCells +1 ; if(info.isAddRow()) { mShortAxisCells+=1 ; } mOccupied = new boolean[mLongAxisCells][mShortAxisCells]; } View view = null ; ShortcutInfo item = null; Mogoo_BitmapCache iconCache = ((LauncherApplication)getContext().getApplicationContext()).getIconCache(); for(int i = 0; i < items.size(); i++){ item = items.get(i); view = createFolderItem(item); if(view!=null){ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams(); int index = getIndexByCellXY(item.cellX,item.cellY); if(index >= getChildCount()){ index = i; item.cellX = index % getCountX(); item.cellY = index / getCountX(); } if (lp == null) { lp = new CellLayout.LayoutParams(item.cellX, item.cellY, 1, 1); } else { lp.cellX = item.cellX; lp.cellY = item.cellY; lp.cellHSpan = 1; lp.cellVSpan = 1; } this.addView(view, index, lp) ; if(view instanceof Mogoo_BubbleTextView){ ((Mogoo_BubbleTextView)view).startVibrate(iconCache, 0); } } } requestLayout() ; invalidate() ; } } /** * * 停止抖动,清除所有对象 * @ author: 黄悦 */ public void clearViews() { int size = getChildCount(); View v = null; for(int i = 0; i < size; i++){ v = getChildAt(i); if(v instanceof Mogoo_BubbleTextView){ ((Mogoo_BubbleTextView)v).stopVibrate(); } } this.removeAllViewsInLayout(); layout(getLeft(), getTop(), getRight(), getBottom()); } /** * 根据图标所在的单元格获取图标的索引号 * @author:张永辉 * @param cellXY 单元格 * @return 索引号 */ public int getIndexByCellXY(int cellX, int cellY) { int index = getCountX() * cellY + cellX; return index; } /** *创建文件夹内部图标 *@author: 张永辉 *@param dragInfo *@return */ View createFolderItem(Object dragInfo) { View view; ItemInfo info = (ItemInfo) dragInfo; //修正图标类型错误 if(dragInfo instanceof ShortcutInfo && !(dragInfo instanceof Mogoo_FolderInfo)){ info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; } switch (info.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: view = launcher.createShortcut(R.layout.application, folderWorkspace, (ShortcutInfo) info); break; default: throw new IllegalStateException("Unknown item type: " + info.itemType); } if (view == null) return null; // 生成快捷键图标之前,清空图标缓冲区中该图标过时的图标位图 // mIconCache.recycle(((ShortcutInfo) info).intent.getComponent(), // MT_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); view.setHapticFeedbackEnabled(false); view.setOnLongClickListener(launcher); return view; } public Launcher getLauncher() { return launcher; } public void setLauncher(Launcher launcher) { this.launcher = launcher; } public Mogoo_FolderBubbleText getLoadingFolder() { return loadingFolder; } public void setLoadingFolder(Mogoo_FolderBubbleText loadingFolder) { this.loadingFolder = loadingFolder; } public boolean isNewFolderClosed() { return newFolderClosed; } public void setNewFolderClosed(boolean newFolderClosed) { this.newFolderClosed = newFolderClosed; } public Mogoo_FolderBubbleText getCloseFolder() { return closeFolder; } public void onClear() { } private int getScreenTop() { // int topHeight = ((ImageView)(MT_ComponentBus.getInstance().getActivityComp(R.id.folderLayerTopImage, launcher))).getHeight() ; int topHeight = 0; if(loadingFolder != null){ topHeight = loadingFolder.getTopHeight(); }else{ topHeight = closeFolder.getTopHeight(); } int editTitleHeight = ((EditText)Mogoo_ComponentBus.getInstance().getActivityComp(R.id.titleEdit , launcher)).getHeight() ; int statusBarHeight = ((Workspace)Mogoo_ComponentBus.getInstance().getActivityComp(R.id.workspace , launcher)).getStatusBarHeight() ; return topHeight + editTitleHeight + statusBarHeight; } /** * 取得拖动图标相交的第一个单元格的素引号 * @author: 张永辉 * @return */ private int getCellIndexByDragView(DragView dragView) { int x = dragView.getScreenLeft(); int screenTop = getScreenTop() ; int y = dragView.getScreenTop() - screenTop; int width = dragView.getWidth(); int height = dragView.getHeight(); // 找不到在哪一个单元格中时,返回-1 int index = -1; // 单元格总数 int count = getCellCoordinateList() != null ? getCellCoordinateList() .size() : 0; int longAxisStartPadding = this.mLongAxisStartPadding; int shortAxisStartPadding = this.mShortAxisStartPadding; if ((x < shortAxisStartPadding && (x + width) <= shortAxisStartPadding) || (y < longAxisStartPadding && (y + height) <= longAxisStartPadding)) { index = -1; } else if (x < shortAxisStartPadding && y < longAxisStartPadding) { index = 0; } else if (x < shortAxisStartPadding) { for (int i = 0; i < count; i++) { CellEntry entry = getCellEntry(i); if (entry.left == shortAxisStartPadding && y >= entry.top && y <= entry.bottom) { index = i; } } } else if (y < longAxisStartPadding) { for (int i = 0; i < count; i++) { CellEntry entry = getCellEntry(i); if (entry.top == longAxisStartPadding && x >= entry.left && x <= entry.right) { index = i; } } } else { for (int i = 0; i < count; i++) { CellEntry entry = getCellEntry(i); if (x >= entry.left && x <= entry.right && y >= entry.top && y <= entry.bottom) { index = i; } } } if (Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "find DragView(" + x + "," + y + ") cellIndex :" + index + " count=" + count); } return index; } /** * 取得指定坐标所在的单元格的素引号 * @author: 张永辉 * @param x * @param y * @param width * @param height * @return */ private int getCellIndexByCoordinate(int x, int y) { // 找不到在哪一个单元格中时,返回-1 int index = -1; // 单元格总数 int count = getCellCoordinateList() != null ? getCellCoordinateList() .size() : 0; for (int i = 0; i < count; i++) { CellEntry entry = getCellEntry(i); if (x >= entry.left && x <= entry.right && y >= entry.top && y <= entry.bottom) { index = i; } } if (Mogoo_GlobalConfig.LOG_DEBUG) { // Log.d(TAG, // "find coordinate("+x+","+y+") index :"+index+" count="+count); } return index; } /** * *@author: 张永辉 *@Date:2011-3-23 *@param dragInfo *@return */ // private View createIcon(Object dragInfo) // { // // ItemInfo info = (ItemInfo) dragInfo; // // View view = null; // // switch (info.itemType) // { // case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: // case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: // view = launcher.createShortcut(R.layout.application, this,(ShortcutInfo) info, false); // break; // case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER: // case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: // case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME: // case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH: // case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK: // break; // default: // throw new IllegalStateException("Unknown item type: " + info.itemType); // } // // if (view == null) // { // return null; // } // // view.setHapticFeedbackEnabled(false); // view.setOnLongClickListener(launcher); // if (view instanceof DropTarget) // { // dragController.addDropTarget((DropTarget) view); // } // // return view; // } private void setDragInfo(int index) { mDragInfo.cell = getChildAt(index); mDragInfo.cellIndex = index; int[] cellXY = Mogoo_Utilities.convertToCell(index); mDragInfo.cellX = cellXY[0]; mDragInfo.cellY = cellXY[1]; mDragInfo.screen = launcher.getCurrentWorkspaceScreen(); } /** * 判断是否有Invisible对象 */ private boolean isInvisibleChild() { boolean flag = false; int count = getChildCount(); for (int i = 0; i < count; i++) { if (getChildAt(i).getVisibility() == INVISIBLE) { flag = true; break; } } return flag; } private void resetDragInfo() { mDragInfo.cell = null; mDragInfo.cellIndex = -1; mDragInfo.cellX = -1; mDragInfo.cellY = -1; mDragInfo.screen = -1; } /** * 取得打开文件夹的info *@author: 张永辉 *@Date:2011-3-28 *@return */ private Mogoo_FolderInfo getOpenFolderInfo(){ if(loadingFolder!=null) { return (Mogoo_FolderInfo)loadingFolder.getTag() ; } else { return null ; } } /** * 是否排満 *@author: 张永辉 *@Date:2011-3-28 *@return */ private boolean isFull(){ int count = this.getChildCount() ; for(int i=0;i<count;i++){ if(this.getChildAt(i).getVisibility()==View.INVISIBLE){ return false ; } } if(count<Mogoo_GlobalConfig.getWorkspaceLongAxisCells(Mogoo_GlobalConfig.isLandscape()) *(Mogoo_GlobalConfig.getWorkspaceShortAxisCells(Mogoo_GlobalConfig.isLandscape())-1)){ return false ; } return true ; } /** * 更新内部快捷方式的info *@author: 张永辉 *@Date:2011-3-28 */ private void updateShortcutInfo(){ int count = this.getChildCount() ; for(int i=0;i<count;i++){ View child = getChildAt(i) ; ShortcutInfo info = (ShortcutInfo) child.getTag() ; int [] cellXY = Mogoo_Utilities.convertToCell(i) ; info.cellX = cellXY[0] ; info.cellY = cellXY[1] ; } } public void removeView(View view) { super.removeView(view); Mogoo_FolderBubbleText folder = null; if(loadingFolder != null){ folder = loadingFolder; }else if(closeFolder != null){ folder = closeFolder; }else{ return; } Mogoo_ContentListener contentListener = launcher.getContentListener(); folder.stopVibrate(); if(view instanceof Mogoo_BubbleTextView){ Mogoo_BubbleTextView btv = (Mogoo_BubbleTextView) view; ShortcutInfo info = (ShortcutInfo) btv.getTag(); if(contentListener.isListenType(info.appType)){ contentListener.removeItem(info.appType, folder); folder.getCountMap().remove(info.appType); folder.setCountIcon(mIconCache, 0, info.appType); } } folder.startVibrate(mIconCache, 0); } public void addView(View child) { addView(child, false); } public void addView(View view,boolean insertAtFirst) { Mogoo_ContentListener contentListener = launcher.getContentListener(); if(loadingFolder != null){ loadingFolder.stopVibrate(); if(view instanceof Mogoo_BubbleTextView){ ShortcutInfo info = (ShortcutInfo) ((Mogoo_BubbleTextView) view).getTag(); if(contentListener.isListenType(info.appType)){ contentListener.addItem(info.appType, loadingFolder); loadingFolder.setCountIcon(mIconCache, contentListener.getCountByType(info.appType), info.appType); } } loadingFolder.startVibrate(mIconCache, 0); } addView(view, insertAtFirst ? 0 : -1); int endindex = getChildCount() -1 ; int[] endCell = Mogoo_Utilities.convertToCell(endindex); onDropChild(view, endCell); } /** * 恢复文件夹 *@author: 张永辉 *@Date:2011-4-7 *@param info */ void restoreFolder(ShortcutInfo info) { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "------------------call restoreFolder()----------------") ; } if(closeFolder!=null) { Mogoo_FolderInfo folderInfo = (Mogoo_FolderInfo)closeFolder.getTag(); int size = folderInfo.getContents().size() ; //之前关闭的文件夹己删除了,则恢复图标到原来文件夹所在面的最后一个位置 if(size==0) { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "------------------closeFolder size=0 ----------------") ; } // folderInfo = new MT_FolderInfo(folderInfo); int cellXY [] ; View view = null; //workspace中 if(folderInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { Workspace workspace = (Workspace) Mogoo_ComponentBus.getInstance().getActivityComp(R.id.workspace, getContext()); CellLayout cellLayout = (CellLayout)workspace.getChildAt(folderInfo.screen) ; cellXY = cellLayout.convertToCell(cellLayout.getChildCount()) ; if(cellXY!=null) { info.cellX = cellXY[0]; info.cellY = cellXY[1]; info.container = folderInfo.container; info.screen = folderInfo.screen; mIconCache.recycle(info.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); mIconCache.remove(info.intent.getComponent()); LauncherModel.updateItemInDatabase(getContext(), info) ; view = workspace.createIcon(info) ; workspace.addView(cellLayout, view, false) ; LauncherModel.setSortIconInfo(R.id.workspace, folderInfo.screen); ((Mogoo_BubbleTextView)view).startVibrate(mIconCache, 0); closeFolder = null; } } else { Mogoo_DockWorkSpace docWorkspace = (Mogoo_DockWorkSpace) Mogoo_ComponentBus.getInstance().getActivityComp(R.id.dockWorkSpace, getContext()) ; cellXY = Mogoo_Utilities.convertToCell(docWorkspace.getChildCount()) ; if(cellXY!=null) { info.cellX = cellXY[0]; info.cellY = cellXY[1]; info.container = folderInfo.container; info.screen = folderInfo.screen; mIconCache.recycle(info.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); mIconCache.remove(info.intent.getComponent()); LauncherModel.updateItemInDatabase(getContext(), info) ; view = docWorkspace.createReflectionIcon(info) ; docWorkspace.addView(view, docWorkspace.getChildCount()) ; docWorkspace.resetCellLayout(new int [1]) ; LauncherModel.setSortIconInfo(R.id.dockWorkSpace, -1); ((Mogoo_BubbleTextView)view).startVibrate(mIconCache, 0); closeFolder = null; } } view = null; //DB中 //内存中 // if(cellXY!=null) // { // folderInfo.cellX = cellXY[0] ; // folderInfo.cellY = cellXY[1] ; // LauncherModel.addItemToDatabase(getContext(), folderInfo, folderInfo.container, folderInfo.screen, folderInfo.cellX, folderInfo.cellY, false) ; // // System.out.println("----------id="+folderInfo.id+"-----------------"); // if(folderInfo.id != -1) // { // folderInfo.intent = MT_Utilities.generateMtFolderIntent(folderInfo.id) ; // LauncherModel.updateItemInDatabase(getContext(), folderInfo) ; // // folderInfo.addItem(getContext(), info) ; // // //界面上 // View view = launcher.createShortcut(folderInfo) ; // // if(folderInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) // { // Workspace workspace = (Workspace) MT_ComponentBus.getInstance().getActivityComp(R.id.workspace, getContext()); // CellLayout cellLayout = (CellLayout)workspace.getChildAt(folderInfo.screen) ; // cellLayout.addView(view,cellLayout.getChildCount()); // reLayoutCellLayout(cellLayout) ; // } // else // { // MT_DockWorkSpace docWorkspace = (MT_DockWorkSpace) MT_ComponentBus.getInstance().getActivityComp(R.id.dockWorkSpace, getContext()) ; // docWorkspace.addView(view, docWorkspace.getChildCount()) ; // docWorkspace.resetCellLayout(new int[0]) ; // } // // if(view instanceof MT_BubbleTextView){ // ((MT_BubbleTextView)view).startVibrate(mIconCache, 0); // } // // LauncherModel.setSortIconInfo(R.id.folderWorkspace, (int)folderInfo.id); // } // } } //之前关闭的文件夹没有删除,还在某个面上 else { if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "------------------closeFolder size="+size+" ----------------") ; } //内存中 //DB中 folderInfo.addItem(getContext(), info) ; //界面上更新图标文件夹图标 closeFolder.stopVibrate(); mIconCache.recycle(folderInfo.getIntent().getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); mIconCache.remove(folderInfo.getIntent().getComponent()); closeFolder.setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(folderInfo.getIcon(mIconCache)), null, null); closeFolder.startVibrate(mIconCache, 0); } } if(Mogoo_GlobalConfig.LOG_DEBUG) { Log.d(TAG, "------------------end ----------------") ; } } /** * 移除图标 *@author: 张永辉 *@Date:2011-4-11 *@param packageName */ void removeItem(String packageName) { final String packageNameTemp = packageName ; List<Mogoo_FolderBubbleText> folders = getAllFolder() ; for(Mogoo_FolderBubbleText folder : folders) { Mogoo_FolderInfo folderInfo = (Mogoo_FolderInfo)folder.getTag() ; List<ShortcutInfo> items = folderInfo.getContents() ; boolean isBreak = false ; for(ShortcutInfo item:items) { if(packageName.equals(item.intent.getComponent().getPackageName())) { folderInfo.removeItem(launcher,item) ; folderTemp = folder ; mIconCache.recycle(folderInfo.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); mIconCache.remove(folderInfo.intent.getComponent()); folder.setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(folderInfo.getIcon(mIconCache)), null, null); folder.setText(folderInfo.title); isBreak = true ; break ; } } if(isBreak) { break ; } } final int count = getChildCount(); post(new Runnable() { public void run() { final ArrayList<View> childrenToRemove = new ArrayList<View>(); childrenToRemove.clear(); int index = -1 ; for (int j = 0; j < count; j++) { final View view = getChildAt(j); Object tag = view.getTag(); if (tag instanceof ShortcutInfo) { final ShortcutInfo info = (ShortcutInfo) tag; final Intent intent = info.intent; final ComponentName name = intent.getComponent(); if (Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) { if (packageNameTemp.equals(name.getPackageName())) { childrenToRemove.add(view); index = j ; } } } } int childCount = childrenToRemove.size(); for (int j = 0; j < childCount; j++) { View child = childrenToRemove.get(j); if(index!=-1) { removeViewAt(index); } if (child instanceof DropTarget) { dragController.removeDropTarget((DropTarget) child); } } reLayoutFolderWorkspace() ; //如果文件夹中没有图标了则同时也删除文件夹 if(folderTemp!=null) { Mogoo_FolderInfo folderInfo = (Mogoo_FolderInfo)folderTemp.getTag() ; if(folderInfo.getContents().size()==0) { //桌面 if(folderInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { Workspace workspace = (Workspace)Mogoo_ComponentBus.getInstance().getActivityComp(R.id.workspace, launcher); CellLayout cellLayout =(CellLayout)workspace.getChildAt(folderInfo.screen) ; cellLayout.removeView(folderTemp) ; workspace.reLayoutCellLayout(cellLayout) ; LauncherModel.setSortIconInfo(R.id.workspace, folderInfo.screen) ; LauncherModel.saveAllIconInfo(launcher) ; } //工具栏 else if(folderInfo.container == LauncherSettings.Favorites.CONTAINER_TOOLBAR) { Mogoo_DockWorkSpace dockWorkspace = (Mogoo_DockWorkSpace)Mogoo_ComponentBus.getInstance().getActivityComp(R.id.dockWorkSpace, launcher); dockWorkspace.removeView(folderTemp) ; dockWorkspace.resetCellLayout(new int[]{0}) ; LauncherModel.setSortIconInfo(R.id.dockWorkSpace, -1) ; LauncherModel.saveAllIconInfo(launcher) ; } LauncherModel.deleteItemFromDatabase(launcher, folderInfo) ; } } } }); } /** * 更新图标信息 *@author: 张永辉 *@Date:2011-4-11 *@param packageNames */ void updateItem(String packageName) { List<Mogoo_FolderBubbleText> folders = getAllFolder() ; for(Mogoo_FolderBubbleText folder : folders) { Mogoo_FolderInfo folderInfo = (Mogoo_FolderInfo)folder.getTag() ; List<ShortcutInfo> items = folderInfo.getContents() ; boolean isBreak = false ; for(ShortcutInfo item:items) { if(packageName.equals(item.intent.getComponent().getPackageName())) { PackageManager pm = launcher.getPackageManager() ; String title = pm.resolveActivity(item.intent, 0).activityInfo .loadLabel(pm).toString(); item.title = title; mIconCache.recycle(item.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL) ; mIconCache.remove(item.intent.getComponent()); item.setIcon(mIconCache.getIcon(item.intent)); folderInfo.updateItem(launcher,item) ; mIconCache.recycle(folderInfo.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_ALL); mIconCache.remove(folderInfo.intent.getComponent()); folder.setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(folderInfo.getIcon(mIconCache)), null, null); folder.setText(folderInfo.title); isBreak = true ; break ; } } if(isBreak) { break ; } } } /** * 取得所有的文件夹 *@author: 张永辉 *@Date:2011-4-11 *@return */ private List<Mogoo_FolderBubbleText> getAllFolder() { List<Mogoo_FolderBubbleText> folders = new ArrayList<Mogoo_FolderBubbleText>() ; Workspace workspace = (Workspace)Mogoo_ComponentBus.getInstance().getActivityComp(R.id.workspace, launcher) ; int cellLayoutCount = workspace.getChildCount() ; for(int i=0;i<cellLayoutCount;i++) { CellLayout cellLayout = (CellLayout)workspace.getChildAt(i) ; int childCount = cellLayout.getChildCount() ; for(int j=0;j<childCount;j++) { View child = cellLayout.getChildAt(j) ; if(child instanceof Mogoo_FolderBubbleText) { folders.add((Mogoo_FolderBubbleText)child) ; } } } Mogoo_DockWorkSpace dockWorkspace = (Mogoo_DockWorkSpace) Mogoo_ComponentBus.getInstance().getActivityComp(R.id.dockWorkSpace, launcher) ; int childCount = dockWorkspace.getChildCount() ; for(int j=0;j<childCount;j++) { View child = dockWorkspace.getChildAt(j) ; if(child instanceof Mogoo_FolderBubbleText) { folders.add((Mogoo_FolderBubbleText)child) ; } } return folders ; } /** * 重整界面 *@author: 张永辉 *@Date:2011-4-11 */ void reLayoutFolderWorkspace() { for(int i=0; i < getChildCount();i++) { View child = getChildAt(i); if(child!=null) { CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); int[] cellXY = Mogoo_Utilities.convertToCell(i); lp.cellX = cellXY[0]; lp.cellY = cellXY[1]; } } requestLayout() ; } /** * screen屏及其之后的所有快捷方式屏是否全满屏 * @ author:张永辉 *@param screen *@return */ /*private boolean isFullFromCurrentScreen(int screen){ int [] shortcutScreen = MT_GlobalConfig.getShortcutScreen() ; CellLayout layout = (CellLayout)getChildAt(getCurrentScreen()); if(layout.getChildCount() < MT_GlobalConfig.getWorkspaceCellCounts()){ return false; }else if (isInvisibleChild(layout)) { return false; } for(int i:shortcutScreen) { if( i>= screen) { layout = (CellLayout)getChildAt(i); if(layout.getChildCount() < MT_GlobalConfig.getWorkspaceCellCounts()) { return false ; } } } return true ; }*/ }