From ad7596bca26a176f23aa870194fc90936e96c23b Mon Sep 17 00:00:00 2001 From: serso Date: Fri, 12 Oct 2012 17:41:13 +0400 Subject: [PATCH] Matrix support --- calculatorpp/project.properties | 18 +- .../res/layout/matrix_edit_fragment.xml | 64 +++-- .../matrix/CalculatorMatrixEditFragment.java | 28 +- .../android/calculator/matrix/MatrixView.java | 259 ++++++++++++++++++ 4 files changed, 334 insertions(+), 35 deletions(-) create mode 100644 calculatorpp/src/main/java/org/solovyev/android/calculator/matrix/MatrixView.java diff --git a/calculatorpp/project.properties b/calculatorpp/project.properties index 0b0ebc4d..03180409 100644 --- a/calculatorpp/project.properties +++ b/calculatorpp/project.properties @@ -9,12 +9,16 @@ # Project target. target=android-15 -android.library.reference.1=../calculatorpp-service -android.library.reference.2=gen-external-apklibs/org.solovyev.android_android-common-core_1.0.0 -android.library.reference.3=gen-external-apklibs/org.solovyev.android_android-common-ads_1.0.0 -android.library.reference.4=gen-external-apklibs/org.solovyev.android_android-common-view_1.0.0 -android.library.reference.5=gen-external-apklibs/org.solovyev.android_android-common-preferences_1.0.0 -android.library.reference.6=gen-external-apklibs/org.solovyev.android_android-common-other_1.0.0 -android.library.reference.7=gen-external-apklibs/org.solovyev.android_android-common-menu_1.0.0 +android.library.reference.1=gen-external-apklibs/org.solovyev.android_android-common-core_1.0.0 +android.library.reference.2=gen-external-apklibs/org.solovyev.android_android-common-ads_1.0.0 +android.library.reference.3=gen-external-apklibs/org.solovyev.android_billing_0.2 +android.library.reference.4=gen-external-apklibs/org.solovyev.android_android-common-db_1.0.0 +android.library.reference.5=gen-external-apklibs/org.solovyev.android_android-common-view_1.0.0 +android.library.reference.6=gen-external-apklibs/org.solovyev.android_android-common-preferences_1.0.0 +android.library.reference.7=gen-external-apklibs/org.solovyev.android_android-common-other_1.0.0 +android.library.reference.8=gen-external-apklibs/org.solovyev.android_android-common-menu_1.0.0 +android.library.reference.9=gen-external-apklibs/org.solovyev.android_android-common-sherlock_1.0.0 +android.library.reference.10=gen-external-apklibs/com.actionbarsherlock_library_4.1.0 +android.library.reference.11=gen-external-apklibs/org.solovyev.android_android-common-list_1.0.0 diff --git a/calculatorpp/res/layout/matrix_edit_fragment.xml b/calculatorpp/res/layout/matrix_edit_fragment.xml index 2dc0b9b6..d3133f42 100644 --- a/calculatorpp/res/layout/matrix_edit_fragment.xml +++ b/calculatorpp/res/layout/matrix_edit_fragment.xml @@ -1,35 +1,59 @@ + + a:layout_height="match_parent"> - + + + + - - - - - - + a:orientation="vertical"> + a:layout_width="wrap_content" + a:layout_gravity="center" + picker:orientation="horizontal"/> + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/matrix/CalculatorMatrixEditFragment.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/matrix/CalculatorMatrixEditFragment.java index 1d36190e..02f4753c 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/matrix/CalculatorMatrixEditFragment.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/matrix/CalculatorMatrixEditFragment.java @@ -2,7 +2,6 @@ package org.solovyev.android.calculator.matrix; import android.os.Bundle; import android.view.View; -import android.widget.TableLayout; import org.jetbrains.annotations.NotNull; import org.solovyev.android.calculator.CalculatorFragment; import org.solovyev.android.calculator.R; @@ -27,6 +26,9 @@ public class CalculatorMatrixEditFragment extends CalculatorFragment implements private static final int MAX_COUNT = 10; private static final int MIN_COUNT = 2; + private static final int DEFAULT_ROWS = 2; + private static final int DEFAULT_COLS = 2; + /* ********************************************************************** @@ -40,6 +42,15 @@ public class CalculatorMatrixEditFragment extends CalculatorFragment implements super(CalculatorFragmentType.matrix_edit); } + /* + ********************************************************************** + * + * METHODS + * + ********************************************************************** + */ + + @Override public void onViewCreated(View root, Bundle savedInstanceState) { super.onViewCreated(root, savedInstanceState); @@ -49,16 +60,16 @@ public class CalculatorMatrixEditFragment extends CalculatorFragment implements final Picker matrixColsCountPicker = (Picker) root.findViewById(R.id.matrix_cols_count_picker); initPicker(matrixColsCountPicker); - getMatrixTable(root); + getMatrixView(root).setMatrixDimensions(DEFAULT_ROWS, DEFAULT_COLS); } @NotNull - private TableLayout getMatrixTable(@NotNull View root) { - return (TableLayout) root.findViewById(R.id.matrix_layout); + private MatrixView getMatrixView(@NotNull View root) { + return (MatrixView) root.findViewById(R.id.matrix_layout); } private void initPicker(@NotNull Picker picker) { - picker.setRange(new IntegerRange(MIN_COUNT, MAX_COUNT, 1, 2, null)); + picker.setRange(new IntegerRange(MIN_COUNT, MAX_COUNT, 1, 0, null)); picker.setOnChangeListener(this); } @@ -74,10 +85,11 @@ public class CalculatorMatrixEditFragment extends CalculatorFragment implements } } - private void onColsCountChange(@NotNull Integer cols) { - final TableLayout matrixTable = getMatrixTable(getView()); + private void onColsCountChange(@NotNull Integer newCols) { + getMatrixView(getView()).setMatrixCols(newCols); } - private void onRowsCountChange(@NotNull Integer rows) { + private void onRowsCountChange(@NotNull Integer newRows) { + getMatrixView(getView()).setMatrixRows(newRows); } } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/matrix/MatrixView.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/matrix/MatrixView.java new file mode 100644 index 00000000..ab18dd04 --- /dev/null +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/matrix/MatrixView.java @@ -0,0 +1,259 @@ +package org.solovyev.android.calculator.matrix; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.TableLayout; +import android.widget.TableRow; +import android.widget.TextView; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * User: Solovyev_S + * Date: 12.10.12 + * Time: 15:41 + */ +public class MatrixView extends TableLayout { + + /* + ********************************************************************** + * + * CONSTANTS + * + ********************************************************************** + */ + + private static final CharSequence DEFAULT_CELL_TEXT = "0"; + private static final int NUMBER_INDEX = -1; + + + /* + ********************************************************************** + * + * FIELDS + * + ********************************************************************** + */ + + private int rows = 0; + private int cols = 0; + + @Nullable + private CharSequence defaultCellText = DEFAULT_CELL_TEXT; + + private boolean initialized = false; + + /* + ********************************************************************** + * + * CONSTRUCTORS + * + ********************************************************************** + */ + + public MatrixView(Context context) { + super(context); + } + + public MatrixView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + /* + ********************************************************************** + * + * METHODS + * + ********************************************************************** + */ + + public void setMatrixCols(int newCols) { + setMatrixDimensions(rows, newCols); + } + + public void setMatrixRows(int newRows) { + setMatrixDimensions(newRows, cols); + } + + public void setMatrixDimensions(int newRows, int newCols) { + if ( newRows <= 1 ) { + throw new IllegalArgumentException("Number of rows must be more than 1: " + newRows); + } + + if ( newCols <= 1 ) { + throw new IllegalArgumentException("Number of columns must be more than 1: " + newCols); + } + + boolean rowsChanged = this.rows != newRows; + boolean colsChanged = this.cols != newCols; + + if (rowsChanged || colsChanged) { + if ( !initialized ) { + addRow(NUMBER_INDEX, 0); + initialized = true; + } + + if (this.cols > newCols) { + removeCols(newCols); + } else if (this.cols < newCols) { + addCols(newCols); + } + + this.cols = newCols; + + if (this.rows > newRows) { + removeRows(newRows); + } else if (this.rows < newRows) { + addRows(newRows); + } + + this.rows = newRows; + } + } + + public void setMatrix(@NotNull Object[][] matrix) { + final int rows = matrix.length; + final int cols = matrix[0].length; + + setMatrixDimensions(rows, cols); + for ( int row = 0; row < rows; row++ ) { + for ( int col = 0; col < cols; col++ ) { + setCell(row, col, matrix[row][col]); + } + } + + } + + private void setCell(int row, int col, @Nullable Object o) { + getCell(this, row, col); + } + + /* + ********************************************************************** + * + * PRIVATE METHODS + * + ********************************************************************** + */ + + private void addRows(int newRows) { + for (int row = this.rows; row < newRows; row++) { + addRow(row, cols); + } + } + + private void removeRows(int newRows) { + for (int row = this.rows - 1; row >= newRows; row--) { + removeRow(row); + } + } + + private void addCols(int newCols) { + for (int row = NUMBER_INDEX; row < rows; row++) { + final ViewGroup rowView = getRow(row); + if (rowView != null) { + for (int col = this.cols; col < newCols; col++) { + rowView.addView(createCellView(row, col)); + } + } + } + } + + private void removeCols(int newCols) { + for (int row = NUMBER_INDEX; row < rows; row++) { + final ViewGroup rowView = getRow(row); + if (rowView != null) { + for (int col = this.cols - 1; col >= newCols; col--) { + final View cellView = getCell(rowView, row, col); + if (cellView != null) { + rowView.removeView(cellView); + } + } + } + } + } + + private void addRow(int row, int newCols) { + this.addView(createRowView(row, newCols)); + } + + private void removeRow(int row) { + final View rowView = getRow(row); + if (rowView != null) { + this.removeView(rowView); + } + } + + @Nullable + private TableRow getRow(int row) { + return (TableRow) this.findViewWithTag(getRowTag(row)); + } + + @Nullable + private View getCell(@NotNull View view, int row, int col) { + return view.findViewWithTag(getCellTag(row, col)); + } + + @NotNull + private String getRowTag(int row) { + if (row != NUMBER_INDEX) { + return "row_" + row; + } else { + return "row_index"; + } + } + + @NotNull + private View createRowView(int row, int cols) { + final ViewGroup rowView = new TableRow(this.getContext()); + + rowView.setTag(getRowTag(row)); + + if (row != NUMBER_INDEX) { + rowView.addView(createCellView(row, NUMBER_INDEX)); + } else { + // empty cell + rowView.addView(new View(this.getContext())); + } + + for (int col = 0; col < cols; col++) { + rowView.addView(createCellView(row, col)); + } + return rowView; + } + + @NotNull + private View createCellView(int row, int col) { + final TextView result; + + if (row != NUMBER_INDEX && col != NUMBER_INDEX) { + result = new EditText(this.getContext()); + result.setText(defaultCellText); + } else { + result = new TextView(this.getContext()); + if (row == NUMBER_INDEX) { + result.setText(String.valueOf(col + 1)); + } else { + result.setText(String.valueOf(row + 1)); + } + } + + result.setTag(getCellTag(row, col)); + + return result; + + } + + @NotNull + private String getCellTag(int row, int col) { + if (row != NUMBER_INDEX) { + return "cell_" + row + "_" + col; + } else { + return "cell_index_" + col; + } + } + +}