package com.iwedia.gui.widgets; import android.app.Activity; import android.appwidget.AppWidgetProviderInfo; import android.view.View; import com.iwedia.gui.MainActivity; /** * Widget Arranging Handler Class * * @author Veljko Ilkic */ public class WidgetArrangingHandler { /** Grid size */ public static final int NUMBER_OF_CELL_PER_ROW = 5; public static final int NUMBER_OF_ROWS = 3; /** Drop spot height| */ public static final int DROP_SPOT_HEIGHT = 50; /** Drop spot coordinates */ private int[] widgetDropSpotCoordinates = new int[4]; /** Screen width and height */ private int screenWidth, screenHeight; /** Cell size */ private int cellWidth, cellHeight; private WidgetCell[] widgetCells = new WidgetCell[NUMBER_OF_CELL_PER_ROW * NUMBER_OF_ROWS]; /** Constructor 1 */ public WidgetArrangingHandler(Activity activity) { super(); // Take screen height and width if (((MainActivity) activity).isFullHD()) { this.screenHeight = 1080; } else { this.screenHeight = 720; } this.screenWidth = MainActivity.screenWidth; // Calculate cell size calculateCellSize(); // Init cell grid initCellGrid(); // Calculate drop spot size calculateDropSpotSize(); } /** Calculate cell's size */ private void calculateCellSize() { cellHeight = (screenHeight - DROP_SPOT_HEIGHT) / NUMBER_OF_ROWS; cellWidth = screenWidth / NUMBER_OF_CELL_PER_ROW; } /** Init cell grid */ public void initCellGrid() { for (int i = 0; i < NUMBER_OF_CELL_PER_ROW * NUMBER_OF_ROWS; i++) { widgetCells[i] = new WidgetCell(0, 0, i, false); } } /** Calculate drop spot size */ private void calculateDropSpotSize() { // X left widgetDropSpotCoordinates[0] = 0; // X right widgetDropSpotCoordinates[1] = screenWidth; // Y top widgetDropSpotCoordinates[2] = screenHeight - DROP_SPOT_HEIGHT; // Y bottom widgetDropSpotCoordinates[3] = screenHeight; } /** Calculate how many cells is needed for widget */ public int[] howManyCellsTake(AppWidgetProviderInfo widget) { // Return value int[] retVal = new int[2]; // Get real widget size int widgetWidth = widget.minWidth; int widgetHeight = widget.minHeight; // Calculate number horizontally taken cells int horizontalCellsTaken = widgetWidth / cellWidth; // Calculate number vertically taken cells int verticalCellsTaken = widgetHeight / cellHeight; // Check for part of cell taken if (horizontalCellsTaken > 0) { if (widgetWidth % cellWidth > 0) { horizontalCellsTaken++; } } // Check for part of cell taken if (verticalCellsTaken > 0) { if (widgetHeight % cellHeight > 0) { verticalCellsTaken++; } } // If widget is smaller that one cell, set one cell taken if (horizontalCellsTaken == 0) { horizontalCellsTaken = 1; } // If widget is smaller that one cell, set one cell taken if (verticalCellsTaken == 0) { verticalCellsTaken = 1; } retVal[0] = horizontalCellsTaken; retVal[1] = verticalCellsTaken; return retVal; } /** Set X and Y position of widget */ public boolean setXY(View widgetView, int[] cellsNeeded, WidgetObject widgetObject) { // Get id of first cell int id = findEmptyCell(cellsNeeded); // Set id of first taken cell widgetObject.setCellId(id); // Check for errors if (id != -1) { int widgetX = id % NUMBER_OF_CELL_PER_ROW; int widgetY = id / NUMBER_OF_CELL_PER_ROW; widgetView.setX(widgetX * cellWidth); widgetView.setY(widgetY * cellHeight); // Tell widget in what cell it is ((WidgetViewTagObject) widgetView.getTag()).setCellId(id); // Tell widget how many cells it takes ((WidgetViewTagObject) widgetView.getTag()) .setCellsTaken(cellsNeeded); return true; } else { // No empty cell return false; } } /** * Set coordinates to widget from drag controller */ public void setXYFromDrag(View widgetView, int cellId, WidgetObject widgetObject) { widgetObject.setCellId(cellId); int widgetX = cellId % NUMBER_OF_CELL_PER_ROW; int widgetY = cellId / NUMBER_OF_CELL_PER_ROW; widgetView.setX(widgetX * cellWidth); widgetView.setY(widgetY * cellHeight); } /** Set coordinates after init time */ public void setXYAfterInit(View widgetView, WidgetObject widgetObject) { int cellId = widgetObject.getCellId(); int widgetX = cellId % NUMBER_OF_CELL_PER_ROW; int widgetY = cellId / NUMBER_OF_CELL_PER_ROW; widgetView.setX(widgetX * cellWidth); widgetView.setY(widgetY * cellHeight); } /** * Find empty cell */ private int findEmptyCell(int[] cellsNeeded) { // ///////////////////////////// // 1x1 // ///////////////////////////// if (cellsNeeded[0] * cellsNeeded[1] == 1) { // Find first empty cell for (int i = 0; i < NUMBER_OF_CELL_PER_ROW; i++) { int x = i; for (int j = 0; j < NUMBER_OF_ROWS; j++) { if (!widgetCells[x].isTaken()) { widgetCells[x].setTaken(true); return widgetCells[x].getId(); } x = x + NUMBER_OF_CELL_PER_ROW; } } } // //////////////////////////////////////// // 2 cells // //////////////////////////////////////// if (cellsNeeded[0] * cellsNeeded[1] == 2) { // ///////////////////////////// // 2x1 // ///////////////////////////// if (cellsNeeded[0] == 2) { // Find first empty cell for (int i = 0; i < NUMBER_OF_CELL_PER_ROW - 1; i++) { int x = i; for (int j = 0; j < NUMBER_OF_ROWS; j++) { if (!widgetCells[x].isTaken() && !widgetCells[x + 1].isTaken()) { widgetCells[x].setTaken(true); widgetCells[x + 1].setTaken(true); return widgetCells[x].getId(); } x = x + NUMBER_OF_CELL_PER_ROW; } } } // ///////////////////////////// // 1x2 // ///////////////////////////// else { // Find first empty cell // Find first empty cell for (int i = 0; i < NUMBER_OF_CELL_PER_ROW; i++) { int x = i; for (int j = 0; j < NUMBER_OF_ROWS - 1; j++) { if (!widgetCells[x].isTaken() && !widgetCells[x + NUMBER_OF_CELL_PER_ROW] .isTaken()) { widgetCells[x].setTaken(true); widgetCells[x + NUMBER_OF_CELL_PER_ROW] .setTaken(true); return widgetCells[x].getId(); } x = x + NUMBER_OF_CELL_PER_ROW; } } } } // //////////////////////////////////////// // 3 cells // //////////////////////////////////////// if (cellsNeeded[0] * cellsNeeded[1] == 3) { // ///////////////////////////// // 3x1 // ///////////////////////////// if (cellsNeeded[0] == 3) { // Find first empty cell for (int i = 0; i < NUMBER_OF_CELL_PER_ROW - 2; i++) { int x = i; for (int j = 0; j < NUMBER_OF_ROWS; j++) { if (!widgetCells[x].isTaken() && !widgetCells[x + 1].isTaken() && !widgetCells[x + 2].isTaken()) { widgetCells[x].setTaken(true); widgetCells[x + 1].setTaken(true); widgetCells[x + 2].setTaken(true); return widgetCells[x].getId(); } x = x + NUMBER_OF_CELL_PER_ROW; } } } // ///////////////////////////// // 1x3 // ///////////////////////////// else { // Find first empty cell for (int i = 0; i < NUMBER_OF_CELL_PER_ROW; i++) { int x = i; for (int j = 0; j < NUMBER_OF_ROWS - 2; j++) { if (!widgetCells[x].isTaken() && !widgetCells[x + NUMBER_OF_CELL_PER_ROW] .isTaken() && !widgetCells[x + 2 * NUMBER_OF_CELL_PER_ROW] .isTaken()) { widgetCells[x].setTaken(true); widgetCells[x + NUMBER_OF_CELL_PER_ROW] .setTaken(true); widgetCells[x + 2 * NUMBER_OF_CELL_PER_ROW] .setTaken(true); return widgetCells[x].getId(); } x = x + NUMBER_OF_CELL_PER_ROW; } } } } // //////////////////////////////////////// // 4 cells // //////////////////////////////////////// if (cellsNeeded[0] * cellsNeeded[1] == 4) { // ///////////////////////////// // 4x1 // ///////////////////////////// if (cellsNeeded[0] == 4) { // Find first empty cell for (int i = 0; i < NUMBER_OF_CELL_PER_ROW - 3; i++) { int x = i; for (int j = 0; j < NUMBER_OF_ROWS; j++) { if (!widgetCells[x].isTaken() && !widgetCells[x + 1].isTaken() && !widgetCells[x + 2].isTaken() && !widgetCells[x + 3].isTaken()) { widgetCells[x].setTaken(true); widgetCells[x + 1].setTaken(true); widgetCells[x + 2].setTaken(true); widgetCells[x + 3].setTaken(true); return widgetCells[x].getId(); } x = x + NUMBER_OF_CELL_PER_ROW; } } } // //////////////////////////////// // 2x2 // //////////////////////////////// if (cellsNeeded[0] == 2) { // Find first empty cell for (int i = 0; i < NUMBER_OF_CELL_PER_ROW - 1; i++) { int x = i; for (int j = 0; j < NUMBER_OF_ROWS - 1; j++) { if (!widgetCells[x].isTaken() && !widgetCells[x + 1].isTaken() && !widgetCells[x + NUMBER_OF_CELL_PER_ROW] .isTaken() && !widgetCells[x + NUMBER_OF_CELL_PER_ROW + 1] .isTaken()) { widgetCells[x].setTaken(true); widgetCells[x + 1].setTaken(true); widgetCells[x + NUMBER_OF_CELL_PER_ROW] .setTaken(true); widgetCells[x + NUMBER_OF_CELL_PER_ROW + 1] .setTaken(true); return widgetCells[x].getId(); } x = x + NUMBER_OF_CELL_PER_ROW; } } } } // No empty cells return -1; } /** Deinit take cells */ public void deinitTakenCells(int id, int[] cellsTaken) { // //////////////////////////////////// // 1x1 // //////////////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 1) { widgetCells[id].setTaken(false); } // ///////////////////////////////// // 2 Cells // ///////////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 2) { // ////////////////////////////////// // 2x1 // ////////////////////////////////// if (cellsTaken[0] == 2) { widgetCells[id].setTaken(false); widgetCells[id + 1].setTaken(false); } // ////////////////////////////////// // 1x2 // ////////////////////////////////// if (cellsTaken[0] == 1) { widgetCells[id].setTaken(false); widgetCells[id + NUMBER_OF_CELL_PER_ROW].setTaken(false); } } // ///////////////////////////////// // 3 Cells // ///////////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 3) { // ////////////////////////////////// // 3x1 // ////////////////////////////////// if (cellsTaken[0] == 3) { widgetCells[id].setTaken(false); widgetCells[id + 1].setTaken(false); widgetCells[id + 2].setTaken(false); } // ////////////////////////////////// // 1x3 // ////////////////////////////////// if (cellsTaken[0] == 1) { widgetCells[id].setTaken(false); widgetCells[id + NUMBER_OF_CELL_PER_ROW].setTaken(false); widgetCells[id + 2 * NUMBER_OF_CELL_PER_ROW].setTaken(false); } } // ///////////////////////////////// // 4 Cells // ///////////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 4) { // ////////////////////////////////// // 4x1 // ////////////////////////////////// if (cellsTaken[0] == 4) { widgetCells[id].setTaken(false); widgetCells[id + 1].setTaken(false); widgetCells[id + 2].setTaken(false); widgetCells[id + 3].setTaken(false); } // ////////////////////////////////// // 2x2 // ////////////////////////////////// if (cellsTaken[0] == 2) { widgetCells[id].setTaken(false); widgetCells[id + 1].setTaken(false); widgetCells[id + NUMBER_OF_CELL_PER_ROW].setTaken(false); widgetCells[id + NUMBER_OF_CELL_PER_ROW + 1].setTaken(false); } } } /** Check what cell should be taken */ public int checkWhatCellWidgetWantsToTake(int x, int y) { int horizontalCell = x / cellWidth; int verticalCell = y / cellHeight; int cellId = horizontalCell + NUMBER_OF_CELL_PER_ROW * verticalCell; return cellId; } /** Check neighbour cells */ public boolean checkNeighbourCells(int newCellId, View widget) { // Get tag WidgetViewTagObject tag = (WidgetViewTagObject) widget.getTag(); /** Id of first cell that was taken by widget */ int oldCellId = tag.getCellId(); /** How many cells widget takes */ int[] cellsTaken = tag.getCellsTaken(); // Check horizontal if ((newCellId % NUMBER_OF_CELL_PER_ROW) + cellsTaken[0] > NUMBER_OF_CELL_PER_ROW) { return false; } // Check vertical if (newCellId + (cellsTaken[1] - 1) * NUMBER_OF_CELL_PER_ROW > NUMBER_OF_CELL_PER_ROW * NUMBER_OF_ROWS - 1) { return false; } // ///////////////////////////// // 1x1 // ///////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 1) { if (widgetCells[newCellId].isTaken()) { return false; } } // //////////////////////////////////////// // 2 cells // //////////////////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 2) { // ///////////////////////////// // 2x1 // ///////////////////////////// if (cellsTaken[0] == 2) { if (widgetCells[newCellId].isTaken() || widgetCells[newCellId + 1].isTaken()) { // /////////////////////////////////////////////////////////////// // Check if new position has take same cells as old position // /////////////////////////////////////////////////////////////// if ((newCellId + 1 == oldCellId) || (newCellId == oldCellId + 1)) { // Deinit taken cell and take new cells refreshWidgetCellsState(oldCellId, newCellId, cellsTaken); // Refresh cell id in tag tag.setCellId(newCellId); return true; } else { // ///////////////////////////////////// // Cell is taken by other widget // ///////////////////////////////////// return false; } } } // ///////////////////////////// // 1x2 // ///////////////////////////// else { if (widgetCells[newCellId].isTaken() || widgetCells[newCellId + NUMBER_OF_CELL_PER_ROW] .isTaken()) { // /////////////////////////////////////////////////////////////// // Check if new position has take same cells as old position // /////////////////////////////////////////////////////////////// if ((newCellId + NUMBER_OF_CELL_PER_ROW == oldCellId) || (newCellId == oldCellId + NUMBER_OF_CELL_PER_ROW)) { // Deinit taken cell and take new cells refreshWidgetCellsState(oldCellId, newCellId, cellsTaken); // Refresh cell id in tag tag.setCellId(newCellId); return true; } else { // ///////////////////////////////////// // Cell is taken by other widget // ///////////////////////////////////// return false; } } } } // ///////////////////////////////// // 3 Cells // ///////////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 3) { // ////////////////////////////////// // 3x1 // ////////////////////////////////// if (cellsTaken[0] == 3) { if (widgetCells[newCellId].isTaken() || widgetCells[newCellId + 1].isTaken() || widgetCells[newCellId + 2].isTaken()) { // /////////////////////////////////////////////////////////////// // Check if new position has take same cells as old position // /////////////////////////////////////////////////////////////// if ((newCellId + 1 == oldCellId) || (newCellId + 2 == oldCellId)) { // Deinit taken cell and take new cells refreshWidgetCellsState(oldCellId, newCellId, cellsTaken); // Refresh cell id in tag tag.setCellId(newCellId); return true; } else { // ///////////////////////////////////// // Cell is taken by other widget // ///////////////////////////////////// return false; } } } // ////////////////////////////////// // 1x3 // ////////////////////////////////// if (cellsTaken[0] == 1) { if (widgetCells[newCellId].isTaken() || widgetCells[newCellId + 1 * NUMBER_OF_CELL_PER_ROW] .isTaken() || widgetCells[newCellId + 2 * NUMBER_OF_CELL_PER_ROW] .isTaken()) { return false; } } } // ///////////////////////////////// // 4 Cells // ///////////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 4) { // ////////////////////////////////// // 4x1 // ////////////////////////////////// if (cellsTaken[0] == 4) { if (widgetCells[newCellId].isTaken() || widgetCells[newCellId + 1].isTaken() || widgetCells[newCellId + 2].isTaken() || widgetCells[newCellId + 3].isTaken()) { // /////////////////////////////////////////////////////////////// // Check if new position has take same cells as old position // /////////////////////////////////////////////////////////////// if ((newCellId + 1 == oldCellId) || (newCellId + 2 == oldCellId) || (newCellId + 3 == oldCellId)) { // Deinit taken cell and take new cells refreshWidgetCellsState(oldCellId, newCellId, cellsTaken); // Refresh cell id in tag tag.setCellId(newCellId); return true; } else { // ///////////////////////////////////// // Cell is taken by other widget // ///////////////////////////////////// return false; } } } // ////////////////////////////////// // 2x2 // ////////////////////////////////// if (cellsTaken[0] == 2) { if (widgetCells[newCellId].isTaken() || widgetCells[newCellId + 1].isTaken() || widgetCells[newCellId + 1 * NUMBER_OF_CELL_PER_ROW] .isTaken() || widgetCells[newCellId + 2 * NUMBER_OF_CELL_PER_ROW] .isTaken()) { // /////////////////////////////////////////////////////////////// // Check if new position has take same cells as old position // /////////////////////////////////////////////////////////////// if ((newCellId + 1 == oldCellId) || (newCellId == oldCellId + 1) || (newCellId + NUMBER_OF_CELL_PER_ROW == oldCellId) || (newCellId == oldCellId + NUMBER_OF_CELL_PER_ROW)) { // Deinit taken cell and take new cells refreshWidgetCellsState(oldCellId, newCellId, cellsTaken); // Refresh cell id in tag tag.setCellId(newCellId); return true; } else { // ///////////////////////////////////// // Cell is taken by other widget // ///////////////////////////////////// return false; } } } } // Deinit taken cell and take new cells refreshWidgetCellsState(oldCellId, newCellId, cellsTaken); // Refresh cell id in tag tag.setCellId(newCellId); return true; } /** Refresh widget cell state after drag success */ private void refreshWidgetCellsState(int oldId, int newId, int[] cellsTaken) { // ///////////////////////////// // 1x1 // ///////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 1) { widgetCells[oldId].setTaken(false); widgetCells[newId].setTaken(true); } // //////////////////////////////////////// // 2 cells // //////////////////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 2) { // ///////////////////////////// // 2x1 // ///////////////////////////// if (cellsTaken[0] == 2) { widgetCells[oldId].setTaken(false); widgetCells[oldId + 1].setTaken(false); widgetCells[newId].setTaken(true); widgetCells[newId + 1].setTaken(true); } // ///////////////////////////// // 1x2 // ///////////////////////////// else { widgetCells[oldId].setTaken(false); widgetCells[oldId + NUMBER_OF_CELL_PER_ROW].setTaken(false); widgetCells[newId].setTaken(true); widgetCells[newId + NUMBER_OF_CELL_PER_ROW].setTaken(true); } } // ///////////////////////////////// // 3 Cells // ///////////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 3) { // ////////////////////////////////// // 3x1 // ////////////////////////////////// if (cellsTaken[0] == 3) { widgetCells[oldId].setTaken(false); widgetCells[oldId + 1].setTaken(false); widgetCells[oldId + 2].setTaken(false); widgetCells[newId].setTaken(true); widgetCells[newId + 1].setTaken(true); widgetCells[newId + 2].setTaken(true); } // ////////////////////////////////// // 1x3 // ////////////////////////////////// if (cellsTaken[0] == 1) { widgetCells[oldId].setTaken(false); widgetCells[oldId + 1 * NUMBER_OF_CELL_PER_ROW].setTaken(false); widgetCells[oldId + 2 * NUMBER_OF_CELL_PER_ROW].setTaken(false); widgetCells[newId].setTaken(true); widgetCells[newId + 1 * NUMBER_OF_CELL_PER_ROW].setTaken(true); widgetCells[newId + 2 * NUMBER_OF_CELL_PER_ROW].setTaken(true); } } // ///////////////////////////////// // 4 Cells // ///////////////////////////////// if (cellsTaken[0] * cellsTaken[1] == 4) { // ////////////////////////////////// // 4x1 // ////////////////////////////////// if (cellsTaken[0] == 4) { widgetCells[oldId].setTaken(false); widgetCells[oldId + 1].setTaken(false); widgetCells[oldId + 2].setTaken(false); widgetCells[oldId + 3].setTaken(false); widgetCells[newId].setTaken(true); widgetCells[newId + 1].setTaken(true); widgetCells[newId + 2].setTaken(true); widgetCells[newId + 3].setTaken(true); } // ////////////////////////////////// // 2x2 // ////////////////////////////////// if (cellsTaken[0] == 2) { widgetCells[oldId].setTaken(false); widgetCells[oldId + 1].setTaken(false); widgetCells[oldId + 1 * NUMBER_OF_CELL_PER_ROW].setTaken(false); widgetCells[oldId + 2 * NUMBER_OF_CELL_PER_ROW].setTaken(false); widgetCells[newId].setTaken(true); widgetCells[newId + 1].setTaken(true); widgetCells[newId + 1 * NUMBER_OF_CELL_PER_ROW].setTaken(true); widgetCells[newId + 2 * NUMBER_OF_CELL_PER_ROW].setTaken(true); } } } /** Check widget remove */ public boolean checkDeleteZone(int dropX, int dropY) { // ///////////////////////// // Inside drop zone // ///////////////////////// if (dropY > widgetDropSpotCoordinates[2]) { return true; } // ////////////////////////// // Outside drop zone // ////////////////////////// else { return false; } } // /////////////////////////////////////// // Getters and Setters // /////////////////////////////////////// public int getScreenWidth() { return screenWidth; } public void setScreenWidth(int screenWidth) { this.screenWidth = screenWidth; } public int getScreenHeight() { return screenHeight; } public void setScreenHeight(int screenHeight) { this.screenHeight = screenHeight; } public int getCellWidth() { return cellWidth; } public void setCellWidth(int cellWidth) { this.cellWidth = cellWidth; } public int getCellHeight() { return cellHeight; } public void setCellHeight(int cellHeight) { this.cellHeight = cellHeight; } public WidgetCell[] getWidgetCells() { return widgetCells; } public void setWidgetCells(WidgetCell[] widgetCells) { this.widgetCells = widgetCells; } }