From 1b31b5cfe26deef8fa5df7391f3ca591b3c4ffec Mon Sep 17 00:00:00 2001 From: Christopher Beckmann Date: Sat, 30 Jan 2016 12:38:26 +0100 Subject: [PATCH] Added some Layouts for landscape ordientation as well as some for high density screens. Also made the arrows in the main menu clickable. --- .idea/misc.xml | 2 +- app/app.iml | 15 +- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 7 +- .../controller/GameController.java | 24 +- .../controller/NewLevelManager.java | 12 +- .../controller/UndoRedoManager.java | 5 + .../privacyfriendlysudoku/game/GameBoard.java | 27 ++ .../ui/AppCompatPreferenceActivity.java | 2 - .../ui/GameActivity.java | 4 + .../ui/HelpActivity.java | 193 +++++++++++ .../ui/MainActivity.java | 69 ++-- .../ui/SettingsActivity.java | 41 +-- .../ui/view/SudokuFieldLayout.java | 61 ++-- .../ui/view/SudokuKeyboardLayout.java | 46 +-- .../ui/view/SudokuSpecialButtonLayout.java | 32 +- .../ic_info_black_24dp.png | Bin .../secuso_logo_blau_blau.png | Bin .../main/res/layout-land/activity_about.xml | 145 ++++++++ .../res/layout-land/activity_main_menu.xml | 165 +++++++++ .../res/layout-land/content_game_view.xml | 50 +++ .../main/res/layout-land/fragment_stats.xml | 316 ++++++++++++++++++ .../res/layout-xlarge-land/activity_about.xml | 146 ++++++++ .../main/res/layout-xlarge/activity_about.xml | 108 ++++++ app/src/main/res/layout/activity_about.xml | 4 +- .../main/res/layout/activity_game_view.xml | 4 +- .../main/res/layout/activity_main_menu.xml | 32 +- app/src/main/res/layout/content_game_view.xml | 2 +- app/src/main/res/values-xlarge/dimens.xml | 11 + app/src/main/res/values/colors.xml | 2 +- app/src/main/res/values/dimens.xml | 6 + app/src/main/res/values/strings.xml | 60 ++++ app/src/main/res/values/styles.xml | 10 + ...pref_general.xml => pref_help_general.xml} | 0 app/src/main/res/xml/pref_help_headers.xml | 8 + app/src/main/res/xml/pref_highlighting.xml | 33 -- .../main/res/xml/pref_settings_general.xml | 64 ++++ ..._headers.xml => pref_settings_headers.xml} | 5 - build.gradle | 2 +- 39 files changed, 1516 insertions(+), 201 deletions(-) create mode 100644 app/src/main/java/org/secuso/privacyfriendlysudoku/ui/HelpActivity.java rename app/src/main/res/{drawable-hdpi => drawable}/ic_info_black_24dp.png (100%) rename app/src/main/res/{drawable-hdpi => drawable}/secuso_logo_blau_blau.png (100%) create mode 100644 app/src/main/res/layout-land/activity_about.xml create mode 100644 app/src/main/res/layout-land/activity_main_menu.xml create mode 100644 app/src/main/res/layout-land/content_game_view.xml create mode 100644 app/src/main/res/layout-land/fragment_stats.xml create mode 100644 app/src/main/res/layout-xlarge-land/activity_about.xml create mode 100644 app/src/main/res/layout-xlarge/activity_about.xml create mode 100644 app/src/main/res/values-xlarge/dimens.xml rename app/src/main/res/xml/{pref_general.xml => pref_help_general.xml} (100%) create mode 100644 app/src/main/res/xml/pref_help_headers.xml delete mode 100644 app/src/main/res/xml/pref_highlighting.xml create mode 100644 app/src/main/res/xml/pref_settings_general.xml rename app/src/main/res/xml/{pref_headers.xml => pref_settings_headers.xml} (62%) diff --git a/.idea/misc.xml b/.idea/misc.xml index fbb6828..5d19981 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -37,7 +37,7 @@ - + diff --git a/app/app.iml b/app/app.iml index 74d7e06..7932f75 100644 --- a/app/app.iml +++ b/app/app.iml @@ -67,28 +67,25 @@ - + - + - - - - - + - + - + + diff --git a/app/build.gradle b/app/build.gradle index 4265675..d47f92c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { } defaultConfig { - applicationId "tu_darmstadt.sudoku" - minSdkVersion 14 + applicationId "org.secuso.privacyfriendlysudoku" + minSdkVersion 16 targetSdkVersion 23 versionCode 1 versionName "1.0" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3f96727..c51ade1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -26,7 +26,6 @@ @@ -35,7 +34,11 @@ + android:theme="@style/AppTheme.NoActionBar" > + + diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/GameController.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/GameController.java index 6791322..df6e6b0 100644 --- a/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/GameController.java +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/GameController.java @@ -92,7 +92,7 @@ public class GameController implements IModelChangedListener { } public void loadNewLevel(GameType type, GameDifficulty difficulty) { - NewLevelManager newLevelManager = NewLevelManager.getInstance(); + NewLevelManager newLevelManager = NewLevelManager.getInstance(context, settings); int[] level = newLevelManager.loadLevel(type, difficulty); @@ -173,7 +173,6 @@ public class GameController implements IModelChangedListener { } int[] solved = solve(); - // TODO test every placed value so far // and reveal the selected value. selectValue(solved[selectedRow * getSize() + selectedCol]); usedHints++; @@ -215,14 +214,14 @@ public class GameController implements IModelChangedListener { } } - public LinkedList getConnectedCells(int row, int col, boolean connectedRow, boolean connectedCol, boolean connectedSec) { + public LinkedList getConnectedCells(int row, int col) { LinkedList list = new LinkedList<>(); - if(connectedRow) list.addAll(gameBoard.getRow(row)); + list.addAll(gameBoard.getRow(row)); list.remove(gameBoard.getCell(row, col)); - if(connectedCol) list.addAll(gameBoard.getColumn(col)); + list.addAll(gameBoard.getColumn(col)); list.remove(gameBoard.getCell(row, col)); - if(connectedSec) list.addAll(gameBoard.getSection(row, col)); + list.addAll(gameBoard.getSection(row, col)); list.remove(gameBoard.getCell(row, col)); return list; @@ -308,6 +307,7 @@ public class GameController implements IModelChangedListener { public void resetLevel() { gameBoard.reset(); + undoRedoManager.addState(gameBoard); //notifyListeners(); notifyHighlightChangedListeners(); } @@ -441,10 +441,11 @@ public class GameController implements IModelChangedListener { highlightValue = value; } } - } else { + } else if(selectedRow == -1 && selectedCol == -1){ if(value == selectedValue) { // if the value we are selecting is the one we already have selected... deselect it selectedValue = 0; + highlightValue = 0; } else { selectedValue = value; highlightValue = value; @@ -506,6 +507,7 @@ public class GameController implements IModelChangedListener { if(!notifiedOnSolvedListeners) { notifiedOnSolvedListeners = true; notifySolvedListeners(); + resetSelects(); } } else { // notifyErrorListener(); @@ -517,6 +519,14 @@ public class GameController implements IModelChangedListener { } } + private void resetSelects() { + selectedCol = -1; + selectedRow = -1; + selectedValue = 0; + highlightValue = 0; + notifyHighlightChangedListeners(); + } + public void registerGameSolvedListener(IGameSolvedListener l) { if(!solvedListeners.contains(l)) { solvedListeners.add(l); diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/NewLevelManager.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/NewLevelManager.java index 04ecda9..309ea7f 100644 --- a/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/NewLevelManager.java +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/NewLevelManager.java @@ -11,6 +11,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.LinkedList; import java.util.List; +import java.util.Random; import org.secuso.privacyfriendlysudoku.game.GameDifficulty; import org.secuso.privacyfriendlysudoku.game.GameType; @@ -30,10 +31,7 @@ public class NewLevelManager { private static String LEVELS_DIR = "level"; private static File DIR; - public static NewLevelManager getInstance() { - return instance; - } - public static NewLevelManager init(Context context, SharedPreferences settings) { + public static NewLevelManager getInstance(Context context, SharedPreferences settings) { if(instance == null) { instance = new NewLevelManager(context, settings); } @@ -118,8 +116,10 @@ public class NewLevelManager { } if(result.size() > 0) { - int chosen = availableFiles.get(0); - int[] resultPuzzle = result.get(0); + Random r = new Random(); + int i = r.nextInt(availableFiles.size()); + int chosen = availableFiles.get(i); + int[] resultPuzzle = result.get(i); StringBuilder sb = new StringBuilder(); sb.append(LEVEL_PREFIX); diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/UndoRedoManager.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/UndoRedoManager.java index e9408ec..7230c4b 100644 --- a/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/UndoRedoManager.java +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/controller/UndoRedoManager.java @@ -50,6 +50,11 @@ public class UndoRedoManager { public void addState(GameBoard gameBoard) { + // don't add duplicates right after each other.. + if(gameBoard.equals(states.get(activeState))) { + return; + } + LinkedList deleteList = new LinkedList<>(); for(int i = 0; i < states.size(); i++) { diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/game/GameBoard.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/game/GameBoard.java index 0bc85e3..27d5af1 100644 --- a/app/src/main/java/org/secuso/privacyfriendlysudoku/game/GameBoard.java +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/game/GameBoard.java @@ -245,4 +245,31 @@ public class GameBoard implements Cloneable { modelChangedListeners.remove(listener); } } + + @Override + public boolean equals(Object o) { + if(o instanceof GameBoard) { + GameBoard other = (GameBoard) o; + + if(!other.gameType.equals(gameType) + || other.sectionHeight != sectionHeight + || other.sectionWidth != sectionWidth + || other.size != size) { + return false; + } + try { + for(int i = 0; i < size; i++) { + for(int j = 0; j < size; j++) { + if(!other.field[i][j].equals(field[i][j])) { + return false; + } + } + } + } catch(IndexOutOfBoundsException e) { + return false; + } + return true; + } + return false; + } } diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/AppCompatPreferenceActivity.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/AppCompatPreferenceActivity.java index 0a7891c..ac22c1a 100644 --- a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/AppCompatPreferenceActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/AppCompatPreferenceActivity.java @@ -4,7 +4,6 @@ import android.content.res.Configuration; import android.os.Bundle; import android.preference.PreferenceActivity; import android.support.annotation.LayoutRes; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatDelegate; @@ -42,7 +41,6 @@ public abstract class AppCompatPreferenceActivity extends PreferenceActivity { getDelegate().setSupportActionBar(toolbar); } - @NonNull @Override public MenuInflater getMenuInflater() { return getDelegate().getMenuInflater(); diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/GameActivity.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/GameActivity.java index 86e6ff3..d5c2561 100644 --- a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/GameActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/GameActivity.java @@ -10,6 +10,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Point; import android.os.Bundle; +import android.preference.PreferenceActivity; import android.preference.PreferenceManager; import android.support.design.widget.NavigationView; import android.support.v4.app.FragmentManager; @@ -218,6 +219,8 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On case R.id.menu_settings: //open settings intent = new Intent(this,SettingsActivity.class); + intent.putExtra( PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.GamePreferenceFragment.class.getName() ); + intent.putExtra( PreferenceActivity.EXTRA_NO_HEADERS, true ); startActivity(intent); break; @@ -267,6 +270,7 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On dialog.getWindow().setBackgroundDrawableResource(R.color.transparent); dialog.show(); + layout.setEnabled(false); keyboard.setButtonsEnabled(false); specialButtonLayout.setButtonsEnabled(false); } diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/HelpActivity.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/HelpActivity.java new file mode 100644 index 0000000..9106d72 --- /dev/null +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/HelpActivity.java @@ -0,0 +1,193 @@ +package org.secuso.privacyfriendlysudoku.ui; + + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.Intent; +import android.content.res.Configuration; +import android.media.Ringtone; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.PreferenceActivity; +import android.support.v7.app.ActionBar; +import android.preference.PreferenceFragment; +import android.preference.PreferenceManager; +import android.preference.RingtonePreference; +import android.text.TextUtils; +import android.view.MenuItem; + +import org.secuso.privacyfriendlysudoku.ui.view.R; + +import java.util.List; + +/** + * A {@link PreferenceActivity} that presents a set of application settings. On + * handset devices, settings are presented as a single list. On tablets, + * settings are split by category, with category headers shown to the left of + * the list of settings. + *

+ * See + * Android Design: Settings for design guidelines and the Settings + * API Guide for more information on developing a Settings UI. + */ +public class HelpActivity extends AppCompatPreferenceActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setupActionBar(); + } + + /** + * Set up the {@link android.app.ActionBar}, if the API is available. + */ + private void setupActionBar() { + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + // Show the Up button in the action bar. + actionBar.setDisplayHomeAsUpEnabled(true); + } + } + + + /** + * {@inheritDoc} + */ + @Override + public boolean onIsMultiPane() { + return isXLargeTablet(this); + } + + /** + * Helper method to determine if the device has an extra-large screen. For + * example, 10" tablets are extra-large. + */ + private static boolean isXLargeTablet(Context context) { + return (context.getResources().getConfiguration().screenLayout + & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE; + } + + /** + * {@inheritDoc} + */ + @Override + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public void onBuildHeaders(List

target) { + loadHeadersFromResource(R.xml.pref_help_headers, target); + } + + /** + * A preference value change listener that updates the preference's summary + * to reflect its new value. + */ + private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object value) { + String stringValue = value.toString(); + + if (preference instanceof ListPreference) { + // For list preferences, look up the correct display value in + // the preference's 'entries' list. + ListPreference listPreference = (ListPreference) preference; + int index = listPreference.findIndexOfValue(stringValue); + + // Set the summary to reflect the new value. + preference.setSummary( + index >= 0 + ? listPreference.getEntries()[index] + : null); + + } else if (preference instanceof RingtonePreference) { + // For ringtone preferences, look up the correct display value + // using RingtoneManager. + if (TextUtils.isEmpty(stringValue)) { + // Empty values correspond to 'silent' (no ringtone). + preference.setSummary(R.string.pref_ringtone_silent); + + } else { + Ringtone ringtone = RingtoneManager.getRingtone( + preference.getContext(), Uri.parse(stringValue)); + + if (ringtone == null) { + // Clear the summary if there was a lookup error. + preference.setSummary(null); + } else { + // Set the summary to reflect the new ringtone display + // name. + String name = ringtone.getTitle(preference.getContext()); + preference.setSummary(name); + } + } + + } else { + // For all other preferences, set the summary to the value's + // simple string representation. + preference.setSummary(stringValue); + } + return true; + } + }; + + /** + * Binds a preference's summary to its value. More specifically, when the + * preference's value is changed, its summary (line of text below the + * preference title) is updated to reflect the value. The summary is also + * immediately updated upon calling this method. The exact display format is + * dependent on the type of preference. + * + * @see #sBindPreferenceSummaryToValueListener + */ + private static void bindPreferenceSummaryToValue(Preference preference) { + // Set the listener to watch for value changes. + preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener); + + // Trigger the listener immediately with the preference's + // current value. + sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, + PreferenceManager + .getDefaultSharedPreferences(preference.getContext()) + .getString(preference.getKey(), "")); + } + + /** + * This method stops fragment injection in malicious applications. + * Make sure to deny any unknown fragments here. + */ + protected boolean isValidFragment(String fragmentName) { + return PreferenceFragment.class.getName().equals(fragmentName) + || HelpFragment.class.getName().equals(fragmentName); + } + + /** + * This fragment shows general preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public static class HelpFragment extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.pref_help_general); + setHasOptionsMenu(true); + + // Bind the summaries of EditText/List/Dialog/Ringtone preferences + // to their values. When their values change, their summaries are + // updated to reflect the new value, per the Android Design + // guidelines. + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + if (id == android.R.id.home) { + startActivity(new Intent(getActivity(), SettingsActivity.class)); + return true; + } + return super.onOptionsItemSelected(item); + } + } +} diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/MainActivity.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/MainActivity.java index 10017be..b9f5661 100644 --- a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/MainActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/MainActivity.java @@ -4,6 +4,7 @@ import android.app.Dialog; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; +import android.preference.PreferenceActivity; import android.preference.PreferenceManager; import android.support.design.widget.NavigationView; import android.support.v4.view.GravityCompat; @@ -58,8 +59,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On settings = PreferenceManager.getDefaultSharedPreferences(this); - NewLevelManager.init(getApplicationContext(), settings); - NewLevelManager newLevelManager = NewLevelManager.getInstance(); + NewLevelManager newLevelManager = NewLevelManager.getInstance(getApplicationContext(), settings); // Is this the very first time we start this app? boolean firstStart = settings.getBoolean("firstStart", true); @@ -151,38 +151,41 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On Intent i = null; - if(view instanceof Button) { - Button b = (Button)view; - switch(b.getId()) { - case R.id.continueButton: - i = new Intent(this, LoadGameActivity.class); - break; - case R.id.playButton: - GameType gameType = GameType.getValidGameTypes().get(mViewPager.getCurrentItem()); - int index = difficultyBar.getProgress()-1; - GameDifficulty gameDifficulty = GameDifficulty.getValidDifficultyList().get(index < 0 ? 0 : index); + switch(view.getId()) { + case R.id.arrow_left: + mViewPager.arrowScroll(View.FOCUS_LEFT); + break; + case R.id.arrow_right: + mViewPager.arrowScroll(View.FOCUS_RIGHT); + break; + case R.id.continueButton: + i = new Intent(this, LoadGameActivity.class); + break; + case R.id.playButton: + GameType gameType = GameType.getValidGameTypes().get(mViewPager.getCurrentItem()); + int index = difficultyBar.getProgress()-1; + GameDifficulty gameDifficulty = GameDifficulty.getValidDifficultyList().get(index < 0 ? 0 : index); - NewLevelManager newLevelManager = NewLevelManager.getInstance(); - if(newLevelManager.isLevelLoadable(gameType, gameDifficulty)) { - // save current setting for later - SharedPreferences.Editor editor = settings.edit(); - editor.putString("lastChosenGameType", gameType.name()); - editor.putString("lastChosenDifficulty", gameDifficulty.name()); - editor.apply(); + NewLevelManager newLevelManager = NewLevelManager.getInstance(getApplicationContext(), settings); + if(newLevelManager.isLevelLoadable(gameType, gameDifficulty)) { + // save current setting for later + SharedPreferences.Editor editor = settings.edit(); + editor.putString("lastChosenGameType", gameType.name()); + editor.putString("lastChosenDifficulty", gameDifficulty.name()); + editor.apply(); - // send everything to game activity - i = new Intent(this, GameActivity.class); - i.putExtra("gameType", gameType); - i.putExtra("gameDifficulty", gameDifficulty); - } else { - newLevelManager.checkAndRestock(); - Toast t = Toast.makeText(getApplicationContext(), R.string.generating, Toast.LENGTH_SHORT); - t.show(); - return; - } - break; - default: - } + // send everything to game activity + i = new Intent(this, GameActivity.class); + i.putExtra("gameType", gameType); + i.putExtra("gameDifficulty", gameDifficulty); + } else { + newLevelManager.checkAndRestock(); + Toast t = Toast.makeText(getApplicationContext(), R.string.generating, Toast.LENGTH_SHORT); + t.show(); + return; + } + break; + default: } if(i != null) { startActivity(i); @@ -221,6 +224,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On case R.id.menu_settings_main: //open settings intent = new Intent(this,SettingsActivity.class); + intent.putExtra( PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.GamePreferenceFragment.class.getName() ); + intent.putExtra( PreferenceActivity.EXTRA_NO_HEADERS, true ); startActivity(intent); break; diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/SettingsActivity.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/SettingsActivity.java index 05bd179..0cf60ea 100644 --- a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/SettingsActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/SettingsActivity.java @@ -84,7 +84,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity { @Override @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void onBuildHeaders(List
target) { - loadHeadersFromResource(R.xml.pref_headers, target); + loadHeadersFromResource(R.xml.pref_settings_headers, target); } /** @@ -144,8 +144,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity { */ protected boolean isValidFragment(String fragmentName) { return PreferenceFragment.class.getName().equals(fragmentName) - || GamePreferenceFragment.class.getName().equals(fragmentName) - || HighlightingPreferenceFragment.class.getName().equals(fragmentName); + || GamePreferenceFragment.class.getName().equals(fragmentName); } /** @@ -157,7 +156,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.pref_general); + addPreferencesFromResource(R.xml.pref_settings_general); setHasOptionsMenu(true); // Bind the summaries of EditText/List/Dialog/Ringtone preferences @@ -181,38 +180,4 @@ public class SettingsActivity extends AppCompatPreferenceActivity { return super.onOptionsItemSelected(item); } } - - /** - * This fragment shows notification preferences only. It is used when the - * activity is showing a two-pane settings UI. - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public static class HighlightingPreferenceFragment extends PreferenceFragment { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.pref_highlighting); - setHasOptionsMenu(true); - - // Bind the summaries of EditText/List/Dialog/Ringtone preferences - // to their values. When their values change, their summaries are - // updated to reflect the new value, per the Android Design - // guidelines. - - //bindPreferenceSummaryToValue(findPreference("highlighting_connected_rows")); - //bindPreferenceSummaryToValue(findPreference("highlighting_connected_columns")); - //bindPreferenceSummaryToValue(findPreference("highlighting_connected_sections")); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int id = item.getItemId(); - if (id == android.R.id.home) { - getActivity().finish(); - //startActivity(new Intent(getActivity(), SettingsActivity.class)); - return true; - } - return super.onOptionsItemSelected(item); - } - } } diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuFieldLayout.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuFieldLayout.java index 938770a..e12bf9a 100644 --- a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuFieldLayout.java +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuFieldLayout.java @@ -30,6 +30,22 @@ public class SudokuFieldLayout extends RelativeLayout implements IHighlightChang private int gameCellHeight; private SharedPreferences settings; + private OnTouchListener listener = new OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if(v instanceof SudokuCellView) { + + SudokuCellView scv = ((SudokuCellView) v); + + int row = scv.getRow(); + int col = scv.getCol(); + + gameController.selectCell(row, col); + } + return false; + } + }; + private Paint p = new Paint(); public SudokuCellView [][] gamecells; @@ -52,22 +68,6 @@ public class SudokuFieldLayout extends RelativeLayout implements IHighlightChang gamecells = new SudokuCellView[gc.getSize()][gc.getSize()]; - OnTouchListener listener = new OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - if(v instanceof SudokuCellView) { - - SudokuCellView scv = ((SudokuCellView) v); - - int row = scv.getRow(); - int col = scv.getCol(); - - gameController.selectCell(row, col); - } - return false; - } - }; - sectionHeight = gameController.getSectionHeight(); sectionWidth = gameController.getSectionWidth(); @@ -80,6 +80,17 @@ public class SudokuFieldLayout extends RelativeLayout implements IHighlightChang } } + @Override + public void setEnabled(boolean enabled) { + for (int i = 0; i < gameController.getSize(); i++) { + for (int j = 0; j < gameController.getSize(); j++) { + gamecells[i][j].setEnabled(false); + gamecells[i][j].setOnTouchListener(null); + } + } + return; + } + @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); @@ -143,12 +154,12 @@ public class SudokuFieldLayout extends RelativeLayout implements IHighlightChang // Set connected Fields if(gameController.isValidCellSelected()) { //String syncConnPref = sharedPref.getString(SettingsActivity., ""); - final boolean highlightConnectedRow = settings.getBoolean("pref_highlight_rows", true); - final boolean highlightConnectedColumn = settings.getBoolean("pref_highlight_cols", true); - final boolean highlightConnectedSection = settings.getBoolean("pref_highlight_secs", true); + final boolean highlightConnected = settings.getBoolean("pref_highlight_connected", true); - for (GameCell c : gameController.getConnectedCells(row, col, highlightConnectedRow, highlightConnectedColumn, highlightConnectedSection)) { - gamecells[c.getRow()][c.getCol()].setHighlightType(CellHighlightTypes.Connected); + if(highlightConnected) { + for (GameCell c : gameController.getConnectedCells(row, col)) { + gamecells[c.getRow()][c.getCol()].setHighlightType(CellHighlightTypes.Connected); + } } } @@ -180,5 +191,13 @@ public class SudokuFieldLayout extends RelativeLayout implements IHighlightChang gamecells[gc.getRow()][gc.getCol()].setHighlightType(CellHighlightTypes.Selected); } } + + // invalidate everything, so it gets redrawn + for(int i = 0; i < gameController.getSize(); i++) { + for(int j = 0; j < gameController.getSize(); j++) { + gamecells[i][j].invalidate(); + } + } + } } diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuKeyboardLayout.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuKeyboardLayout.java index 452bdae..75f0330 100644 --- a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuKeyboardLayout.java +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuKeyboardLayout.java @@ -4,12 +4,8 @@ import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.util.TypedValue; -import android.view.Gravity; import android.view.View; import android.view.ViewGroup; -import android.view.WindowManager; -import android.widget.GridLayout; -import android.widget.GridView; import android.widget.LinearLayout; import org.secuso.privacyfriendlysudoku.controller.GameController; @@ -58,10 +54,11 @@ public class SudokuKeyboardLayout extends LinearLayout implements IHighlightChan public void setKeyBoard(int size,int width, int height) { LayoutParams p; - buttons = new SudokuButton[size]; int number = 0; - int torun = (size % 2 == 0) ? size/2 :(size+1)/2 ; - int realSize = torun; + int numberOfButtonsPerRow = (size % 2 == 0) ? size/2 :(size+1)/2; + int numberOfButtons = numberOfButtonsPerRow * 2; + + buttons = new SudokuButton[numberOfButtons]; //set layout parameters and init Layouts @@ -71,7 +68,7 @@ public class SudokuKeyboardLayout extends LinearLayout implements IHighlightChan p.setMargins(0,5,0,5); layouts[i] = new LinearLayout(getContext(),null); layouts[i].setLayoutParams(p); - layouts[i].setWeightSum(torun); + layouts[i].setWeightSum(numberOfButtonsPerRow); layouts[i].setOrientation(LinearLayout.HORIZONTAL); addView(layouts[i]); } @@ -80,15 +77,13 @@ public class SudokuKeyboardLayout extends LinearLayout implements IHighlightChan - for (int k = 0; k<2;k++){ - for (int i = 0; i< torun; i++){ - if (number == size) { - break; - } - buttons[number] = new SudokuButton(getContext(),null); + for (int layoutNumber = 0; layoutNumber <= 1 ; layoutNumber++){ + for (int i = 0; i < numberOfButtonsPerRow; i++){ + int buttonIndex = i + layoutNumber * numberOfButtonsPerRow; + buttons[buttonIndex] = new SudokuButton(getContext(),null); p = new LayoutParams(0, LayoutParams.MATCH_PARENT,1); p.setMargins(5,5,5,5); - buttons[number].setLayoutParams(p); + buttons[buttonIndex].setLayoutParams(p); /* removed GridLayout because of bad scaling will use now a Linearlayout Spec rowSpec = spec(k,1); Spec colSpec = spec(i,1); @@ -106,14 +101,18 @@ public class SudokuKeyboardLayout extends LinearLayout implements IHighlightChan // buttons[number].setLayoutParams(p); //buttons[number].setGravity(Gravity.CENTER); - buttons[number].setType(SudokuButtonType.Value); - buttons[number].setTextColor(getResources().getColor(R.color.white)); - buttons[number].setBackgroundResource(R.drawable.mnenomic_numpad_button); - buttons[number].setText(Symbol.getSymbol(symbolsToUse, number)); - buttons[number].setValue(number + 1); - buttons[number].setOnClickListener(listener); - layouts[k].addView(buttons[number]); - number++; + buttons[buttonIndex].setType(SudokuButtonType.Value); + buttons[buttonIndex].setTextColor(getResources().getColor(R.color.white)); + buttons[buttonIndex].setBackgroundResource(R.drawable.mnenomic_numpad_button); + buttons[buttonIndex].setText(Symbol.getSymbol(symbolsToUse, buttonIndex)); + buttons[buttonIndex].setValue(buttonIndex + 1); + buttons[buttonIndex].setOnClickListener(listener); + + if (buttonIndex == size) { + buttons[buttonIndex].setVisibility(INVISIBLE); + } + + layouts[layoutNumber].addView(buttons[buttonIndex]); } } } @@ -175,6 +174,7 @@ public class SudokuKeyboardLayout extends LinearLayout implements IHighlightChan } } } + public void fixHeight (){ int i = getHeight(); i = buttons[0].getHeight(); diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuSpecialButtonLayout.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuSpecialButtonLayout.java index 0645c8b..2791586 100644 --- a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuSpecialButtonLayout.java +++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/SudokuSpecialButtonLayout.java @@ -22,16 +22,19 @@ import android.widget.Toast; import java.util.LinkedList; import org.secuso.privacyfriendlysudoku.controller.GameController; +import org.secuso.privacyfriendlysudoku.game.listener.IHighlightChangedListener; import org.secuso.privacyfriendlysudoku.ui.listener.IHintDialogFragmentListener; +import static org.secuso.privacyfriendlysudoku.ui.view.SudokuButtonType.*; + /** * Created by TMZ_LToP on 17.11.2015. */ -public class SudokuSpecialButtonLayout extends LinearLayout { +public class SudokuSpecialButtonLayout extends LinearLayout implements IHighlightChangedListener { SudokuSpecialButton[] fixedButtons; - public int fixedButtonsCount = SudokuButtonType.getSpecialButtons().size(); + public int fixedButtonsCount = getSpecialButtons().size(); GameController gameController; SudokuKeyboardLayout keyboard; Bitmap bitMap,bitResult; @@ -114,18 +117,21 @@ public class SudokuSpecialButtonLayout extends LinearLayout { fragmentManager = fm; keyboard=key; gameController = gc; + if(gc != null) { + gc.registerHighlightChangedListener(this); + } fixedButtons = new SudokuSpecialButton[fixedButtonsCount]; LayoutParams p; int i = 0; //ArrayList type = (ArrayList) SudokuButtonType.getSpecialButtons(); - for (SudokuButtonType t : SudokuButtonType.getSpecialButtons()){ + for (SudokuButtonType t : getSpecialButtons()){ fixedButtons[i] = new SudokuSpecialButton(getContext(),null); p = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,1); p.setMargins(5, 5, 5, 5); //int width2 =width/(fixedButtonsCount); //p.width= width2-15; - if(t == SudokuButtonType.Spacer) { + if(t == Spacer) { fixedButtons[i].setVisibility(View.INVISIBLE); } /*if(t == SudokuButtonType.Do && !gameController.isRedoAvailable()) { @@ -148,6 +154,24 @@ public class SudokuSpecialButtonLayout extends LinearLayout { } + @Override + public void onHighlightChanged() { + for(int i = 0; i < fixedButtons.length; i++) { + switch(fixedButtons[i].getType()) { + case Undo: + fixedButtons[i].setBackgroundResource(gameController.isUndoAvailable() ? + R.drawable.numpad_highlighted_four : R.drawable.inactive_button); + break; + case Do: + fixedButtons[i].setBackgroundResource(gameController.isRedoAvailable() ? + R.drawable.numpad_highlighted_four : R.drawable.inactive_button); + break; + default: + break; + } + } + } + @SuppressLint("ValidFragment") public class HintConfirmationDialog extends DialogFragment { diff --git a/app/src/main/res/drawable-hdpi/ic_info_black_24dp.png b/app/src/main/res/drawable/ic_info_black_24dp.png similarity index 100% rename from app/src/main/res/drawable-hdpi/ic_info_black_24dp.png rename to app/src/main/res/drawable/ic_info_black_24dp.png diff --git a/app/src/main/res/drawable-hdpi/secuso_logo_blau_blau.png b/app/src/main/res/drawable/secuso_logo_blau_blau.png similarity index 100% rename from app/src/main/res/drawable-hdpi/secuso_logo_blau_blau.png rename to app/src/main/res/drawable/secuso_logo_blau_blau.png diff --git a/app/src/main/res/layout-land/activity_about.xml b/app/src/main/res/layout-land/activity_about.xml new file mode 100644 index 0000000..02a88bd --- /dev/null +++ b/app/src/main/res/layout-land/activity_about.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_main_menu.xml b/app/src/main/res/layout-land/activity_main_menu.xml new file mode 100644 index 0000000..d35eb51 --- /dev/null +++ b/app/src/main/res/layout-land/activity_main_menu.xml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +