diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7765c6c..885890b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -31,7 +31,12 @@
android:theme="@style/AppTheme.NoActionBar">
+
+
@@ -50,12 +55,21 @@
android:launchMode="singleTask"
android:theme="@style/AppTheme.NoActionBar">
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/CreateGameActivity.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/CreateGameActivity.java
new file mode 100644
index 0000000..d19b52f
--- /dev/null
+++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/CreateGameActivity.java
@@ -0,0 +1,691 @@
+package org.secuso.privacyfriendlysudoku.ui;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.graphics.Point;
+import android.net.Uri;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+import com.google.android.material.navigation.NavigationView;
+
+import androidx.appcompat.app.AppCompatDelegate;
+import androidx.core.view.GravityCompat;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.appcompat.app.ActionBarDrawerToggle;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.RatingBar;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.secuso.privacyfriendlysudoku.controller.GameController;
+import org.secuso.privacyfriendlysudoku.controller.GameStateManager;
+import org.secuso.privacyfriendlysudoku.controller.SaveLoadStatistics;
+import org.secuso.privacyfriendlysudoku.controller.Symbol;
+import org.secuso.privacyfriendlysudoku.controller.helper.GameInfoContainer;
+import org.secuso.privacyfriendlysudoku.controller.qqwing.QQWing;
+import org.secuso.privacyfriendlysudoku.game.GameDifficulty;
+import org.secuso.privacyfriendlysudoku.game.GameType;
+import org.secuso.privacyfriendlysudoku.game.listener.IGameSolvedListener;
+import org.secuso.privacyfriendlysudoku.game.listener.ITimerListener;
+import org.secuso.privacyfriendlysudoku.ui.AboutActivity;
+import org.secuso.privacyfriendlysudoku.ui.BaseActivity;
+import org.secuso.privacyfriendlysudoku.ui.HelpActivity;
+import org.secuso.privacyfriendlysudoku.ui.MainActivity;
+import org.secuso.privacyfriendlysudoku.ui.SettingsActivity;
+import org.secuso.privacyfriendlysudoku.ui.StatsActivity;
+import org.secuso.privacyfriendlysudoku.ui.listener.IHintDialogFragmentListener;
+import org.secuso.privacyfriendlysudoku.ui.listener.IResetDialogFragmentListener;
+import org.secuso.privacyfriendlysudoku.ui.listener.IShareDialogFragmentListener;
+import org.secuso.privacyfriendlysudoku.ui.view.CreateSudokuSpecialButtonLayout;
+import org.secuso.privacyfriendlysudoku.ui.view.R;
+import org.secuso.privacyfriendlysudoku.ui.view.SudokuFieldLayout;
+import org.secuso.privacyfriendlysudoku.ui.view.SudokuKeyboardLayout;
+import org.secuso.privacyfriendlysudoku.ui.view.SudokuSpecialButtonLayout;
+import org.secuso.privacyfriendlysudoku.ui.view.WinDialog;
+import org.secuso.privacyfriendlysudoku.ui.view.databinding.DialogFragmentShareBoardBinding;
+
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class CreateGameActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener, IGameSolvedListener ,ITimerListener, IHintDialogFragmentListener, IResetDialogFragmentListener, IShareDialogFragmentListener {
+
+ GameController gameController;
+ SudokuFieldLayout layout;
+ SudokuKeyboardLayout keyboard;
+ SudokuSpecialButtonLayout specialButtonLayout;
+ TextView viewName ;
+ RatingBar ratingBar;
+ private boolean gameSolved = false;
+ private boolean startGame = true;
+ SaveLoadStatistics statistics = new SaveLoadStatistics(this);
+ WinDialog dialog = null;
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+
+ if(gameSolved) {
+ gameController.pauseTimer();
+ } else {
+ // start the game
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ gameController.startTimer();
+ }
+ }, MAIN_CONTENT_FADEIN_DURATION);
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+
+ if (sharedPref.getBoolean("pref_dark_mode_setting", false )) {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
+ } else {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
+ }
+
+ if(sharedPref.getBoolean("pref_keep_screen_on", true)) {
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
+
+ GameType gameType = GameType.Unspecified;
+ GameDifficulty gameDifficulty = GameDifficulty.Unspecified;
+ int loadLevelID = 0;
+ boolean loadLevel = false;
+
+ if(savedInstanceState == null) {
+
+ Bundle extras = getIntent().getExtras();
+ Uri data = getIntent().getData();
+ gameController = new GameController(sharedPref, getApplicationContext());
+
+ boolean intentReceivedFromMainActivity = extras != null &&
+ (extras.containsKey("gameType") || extras.containsKey("loadLevel"));
+
+ if (data != null && !intentReceivedFromMainActivity) {
+ String input = "";
+ if (data.getScheme().equals("sudoku")){
+ input = data.getHost();
+ } else if (data.getScheme().equals("http") && data.getHost().equals("sudoku")){
+ input = data.getPath();
+ input =input.replace("/", "");
+ }
+
+ int sectionSize = (int)Math.sqrt(input.length());
+ int boardSize = sectionSize * sectionSize;
+ QQWing difficultyCheck;
+ GameInfoContainer container = new GameInfoContainer(0, GameDifficulty.Unspecified,
+ GameType.Unspecified, new int [boardSize], new int [boardSize], new boolean [boardSize][sectionSize]);
+
+ try {
+ container.parseGameType("Default_" + sectionSize + "x" + sectionSize);
+ container.parseFixedValues(input);
+
+ difficultyCheck = new QQWing(container.getGameType(), GameDifficulty.Unspecified);
+ difficultyCheck.setRecordHistory(true);
+ difficultyCheck.setPuzzle(container.getFixedValues());
+ startGame = difficultyCheck.solve();
+ container.parseDifficulty(difficultyCheck.getDifficulty().toString());
+
+ } catch (IllegalArgumentException e) {
+ startGame = false;
+ sectionSize = GameType.Default_9x9.getSize();
+ boardSize = sectionSize * sectionSize;
+ container = new GameInfoContainer(0, GameDifficulty.Unspecified,
+ GameType.Default_9x9, new int [boardSize], new int [boardSize], new boolean [boardSize][sectionSize]);
+ }
+
+ if (!startGame) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(org.secuso.privacyfriendlysudoku.ui.CreateGameActivity.this, R.style.AppTheme_Dialog);
+ builder.setMessage(R.string.impossible_import_notice)
+ .setCancelable(false)
+ .setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ finish();
+ }
+ });
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ gameController.loadLevel(container);
+
+ } else {
+ boolean isDailySudoku = false;
+ if (extras != null) {
+ gameType = GameType.valueOf(extras.getString("gameType", GameType.Default_9x9.name()));
+ gameDifficulty = GameDifficulty.valueOf(extras.getString("gameDifficulty", GameDifficulty.Moderate.name()));
+ isDailySudoku = extras.getBoolean("isDailySudoku", false);
+ loadLevel = extras.getBoolean("loadLevel", false);
+ if (loadLevel) {
+ loadLevelID = extras.getInt("loadLevelID");
+ }
+ }
+ if (isDailySudoku) {
+ gameController.loadNewDailySudokuLevel();
+ } else {
+
+ List loadableGames = GameStateManager.getLoadableGameList();
+
+ if (loadLevel) {
+ if (loadableGames.size() > loadLevelID) {
+ // load level from GameStateManager
+ gameController.loadLevel(loadableGames.get(loadLevelID));
+ } else if (loadLevelID == GameController.DAILY_SUDOKU_ID) {
+ for (GameInfoContainer container : loadableGames) {
+ if (container.getID() == loadLevelID) {
+ gameController.loadLevel(container);
+ break;
+ }
+ }
+ }
+ } else {
+ // load a new level
+ gameController.loadNewLevel(gameType, gameDifficulty);
+ }
+ }
+ }
+ } else {
+ gameController = savedInstanceState.getParcelable("gameController");
+ // in case we get the same object back
+ // because parceling the Object does not always parcel it. Only if needed.
+ if(gameController != null) {
+ gameController.removeAllListeners();
+ gameController.setContextAndSettings(getApplicationContext(), sharedPref);
+ } else {
+ // Error: no game could be restored. Go back to main menu.
+ Intent intent = new Intent(this, MainActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(intent);
+ finish();
+ overridePendingTransition(0, 0);
+ }
+ gameSolved = savedInstanceState.getInt("gameSolved") == 1;
+ }
+
+
+ setContentView(R.layout.activity_create_sudoku);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+ //toolbar.addView();
+
+ if(gameSolved) {
+ disableReset();
+ }
+
+ //Create new GameField
+ layout = (SudokuFieldLayout)findViewById(R.id.sudokuLayout);
+ gameController.registerGameSolvedListener(this);
+ gameController.registerTimerListener(this);
+ statistics.setGameController(gameController);
+
+ layout.setSettingsAndGame(sharedPref, gameController);
+
+ //set KeyBoard
+ keyboard = (SudokuKeyboardLayout) findViewById(R.id.sudokuKeyboardLayout);
+ keyboard.removeAllViews();
+ keyboard.setGameController(gameController);
+ //keyboard.setColumnCount((gameController.getSize() / 2) + 1);
+ //keyboard.setRowCount(2);
+ Point p = new Point();
+ getWindowManager().getDefaultDisplay().getSize(p);
+
+ // set keyboard orientation
+ int orientation = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ?
+ LinearLayout.HORIZONTAL : LinearLayout.VERTICAL;
+
+ keyboard.setKeyBoard(gameController.getSize(), p.x,layout.getHeight()-p.y, orientation);
+
+
+ //set Special keys
+ CreateSudokuSpecialButtonLayout createSudokuSpecialButtonLayout = (CreateSudokuSpecialButtonLayout) findViewById(R.id.createSudokuLayout);
+ createSudokuSpecialButtonLayout.setButtons(p.x, gameController, keyboard, getFragmentManager(), orientation, org.secuso.privacyfriendlysudoku.ui.CreateGameActivity.this);
+
+
+ //set GameName
+ viewName = (TextView) findViewById(R.id.gameModeText);
+ viewName.setText(getString(gameController.getGameType().getStringResID()));
+
+ //set Rating bar
+ List difficutyList = GameDifficulty.getValidDifficultyList();
+ int numberOfStarts = difficutyList.size();
+ ratingBar = (RatingBar) findViewById(R.id.gameModeStar);
+
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+ this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
+ drawer.setDrawerListener(toggle);
+ toggle.syncState();
+
+ NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
+ navigationView.setNavigationItemSelectedListener(this);
+
+ if(gameSolved) {
+ layout.setEnabled(false);
+ keyboard.setButtonsEnabled(false);
+ specialButtonLayout.setButtonsEnabled(false);
+ }
+
+ gameController.notifyHighlightChangedListeners();
+ gameController.notifyTimerListener(gameController.getTime());
+
+ // run this so the error list gets build again.
+ gameController.onModelChange(null);
+
+ overridePendingTransition(0, 0);
+ }
+
+ @Override
+ public void onPause(){
+ super.onPause();
+ if(!gameSolved && startGame) {
+ gameController.saveGame(this);
+ }
+ gameController.deleteTimer();
+ }
+
+ @Override
+ public void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ startActivity(intent);
+ finish();
+ }
+
+ @Override
+ public void onResume(){
+ super.onResume();
+
+ View mainContent = findViewById(R.id.main_content);
+ if (mainContent != null) {
+ mainContent.animate().alpha(1).setDuration(MAIN_CONTENT_FADEOUT_DURATION);
+ }
+
+ gameController.initTimer();
+
+ if(!gameSolved) {
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ gameController.startTimer();
+ }
+ }, MAIN_CONTENT_FADEIN_DURATION);
+ }
+
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+ Symbol s;
+ try {
+ s = Symbol.valueOf(sharedPref.getString("pref_symbols", Symbol.Default.name()));
+ } catch(IllegalArgumentException e) {
+ s = Symbol.Default;
+ }
+ layout.setSymbols(s);
+ keyboard.setSymbols(s);
+ }
+
+
+ @Override
+ public void onBackPressed() {
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ if (drawer.isDrawerOpen(GravityCompat.START)) {
+ drawer.closeDrawer(GravityCompat.START);
+ } else {
+ finish();
+ super.onBackPressed();
+ }
+ }
+
+ /*@Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.game_view, menu);
+ return true;
+ }*/
+
+ @SuppressWarnings("StatementWithEmptyBody")
+ @Override
+ public boolean onNavigationItemSelected(MenuItem item) {
+ // Handle navigation view item clicks here.
+ int id = item.getItemId();
+
+ Intent intent = null;
+
+ switch(id) {
+ case R.id.menu_reset:
+ org.secuso.privacyfriendlysudoku.ui.GameActivity.ResetConfirmationDialog resetDialog = new org.secuso.privacyfriendlysudoku.ui.GameActivity.ResetConfirmationDialog();
+ resetDialog.show(getFragmentManager(), "ResetDialogFragment");
+ break;
+
+ case R.id.menu_share:
+ String codeForClipboard = "sudoku://" + gameController.getCodeOfField();
+ String codeForClipboard1 = "http://sudoku" + gameController.getCodeOfField();
+ org.secuso.privacyfriendlysudoku.ui.GameActivity.ShareBoardDialog shareDialog = new org.secuso.privacyfriendlysudoku.ui.GameActivity.ShareBoardDialog();
+ shareDialog.setDisplayCode(codeForClipboard);
+ shareDialog.setCopyClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // remember to include alternate code for older android versions
+ ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+
+ if (clipboard != null) {
+ ClipData clip = ClipData.newPlainText("BoardCode", codeForClipboard);
+ clipboard.setPrimaryClip(clip);
+ Toast.makeText(org.secuso.privacyfriendlysudoku.ui.CreateGameActivity.this, R.string.copy_code_confirmation_toast,
+ Toast.LENGTH_LONG).show();
+ } else {
+ Toast.makeText(org.secuso.privacyfriendlysudoku.ui.CreateGameActivity.this, R.string.copy_code_error_toast,
+ Toast.LENGTH_LONG).show();
+ }
+ }
+ });
+ shareDialog.show(getFragmentManager(), "ShareDialogFragment");
+
+ break;
+
+ case R.id.nav_newgame:
+ //create new game
+ intent = new Intent(this, MainActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ finish();
+ break;
+
+ 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 );
+ break;
+
+ case R.id.nav_highscore:
+ // see highscore list
+ intent = new Intent(this, StatsActivity.class);
+ break;
+
+ case R.id.menu_about:
+ //open about page
+ intent = new Intent(this, AboutActivity.class);
+ break;
+
+ case R.id.menu_help:
+ //open about page
+ intent = new Intent(this, HelpActivity.class);
+ break;
+ default:
+ }
+
+ if(intent != null) {
+
+ final Intent i = intent;
+ // fade out the active activity
+ View mainContent = findViewById(R.id.main_content);
+ if (mainContent != null) {
+ mainContent.animate().alpha(0).setDuration(MAIN_CONTENT_FADEOUT_DURATION);
+ }
+
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ startActivity(i);
+ overridePendingTransition(0, 0);
+ }
+ }, NAVDRAWER_LAUNCH_DELAY);
+
+ }
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ drawer.closeDrawer(GravityCompat.START);
+ return true;
+ }
+
+
+ @Override
+ public void onSolved() {
+ gameSolved = true;
+
+ gameController.pauseTimer();
+ gameController.deleteGame(this);
+ disableReset();
+
+ //Save solved sudoku, if it happens to be a daily sudoku, to daily sudoku database
+ if(gameController.getGameID() == GameController.DAILY_SUDOKU_ID) {
+ gameController.saveDailySudoku(org.secuso.privacyfriendlysudoku.ui.CreateGameActivity.this);
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putBoolean("finishedForToday", true);
+ editor.apply();
+ }
+
+ //Show time hints new plus old best time
+
+ statistics.saveGameStats();
+
+ boolean isNewBestTime = gameController.getUsedHints() == 0
+ && statistics.loadStats(gameController.getGameType(),gameController.getDifficulty()).getMinTime() >= gameController.getTime();
+
+ dialog = new WinDialog(this, R.style.WinDialog , timeToString(gameController.getTime()), String.valueOf(gameController.getUsedHints()), isNewBestTime);
+
+ dialog.getWindow().setContentView(R.layout.win_screen_layout);
+ //dialog.setContentView(getLayoutInflater().inflate(R.layout.win_screen_layout,null));
+ //dialog.setContentView(R.layout.win_screen_layout);
+ dialog.getWindow().setGravity(Gravity.CENTER_HORIZONTAL);
+ dialog.getWindow().setBackgroundDrawableResource(R.color.transparent);
+
+ //((TextView)dialog.findViewById(R.id.win_hints)).setText(gameController.getUsedHints());
+ //((TextView)dialog.findViewById(R.id.win_time)).setText(timeToString(gameController.getTime()));
+
+ dialog.show();
+
+ final Activity activity = this;
+ ((Button)dialog.findViewById(R.id.win_continue_button)).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ dialog.dismiss();
+ Intent intent = new Intent(activity, MainActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(intent);
+ overridePendingTransition(0, 0);
+ activity.finish();
+ }
+ });
+ ((Button)dialog.findViewById(R.id.win_showGame_button)).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ dialog.dismiss();
+ }
+ });
+
+
+ layout.setEnabled(false);
+ keyboard.setButtonsEnabled(false);
+ specialButtonLayout.setButtonsEnabled(false);
+ }
+
+ public static String timeToString(int time) {
+ int seconds = time % 60;
+ int minutes = ((time - seconds) / 60) % 60;
+ int hours = (time - minutes - seconds) / (3600);
+ String h, m, s;
+ s = (seconds < 10) ? "0" + String.valueOf(seconds) : String.valueOf(seconds);
+ m = (minutes < 10) ? "0" + String.valueOf(minutes) : String.valueOf(minutes);
+ h = (hours < 10) ? "0" + String.valueOf(hours) : String.valueOf(hours);
+ return h + ":" + m + ":" + s;
+ }
+
+
+ private void disableReset(){
+ NavigationView navView = (NavigationView)findViewById(R.id.nav_view);
+ Menu navMenu = navView.getMenu();
+ navMenu.findItem(R.id.menu_reset).setEnabled(false);
+ }
+ @Override
+ public void onTick(int time) {
+
+ // display the time
+
+ if(gameSolved || !startGame) return;
+ // save time
+ gameController.saveGame(this);
+ }
+
+ @Override
+ public void onHintDialogPositiveClick() {
+ gameController.hint();
+ }
+
+ @Override
+ public void onResetDialogPositiveClick() {
+ gameController.resetLevel();
+ }
+
+ @Override
+ public void onShareDialogPositiveClick(String input) {
+ Intent sendBoardIntent = new Intent();
+ sendBoardIntent.setAction(Intent.ACTION_SEND);
+ sendBoardIntent.putExtra(Intent.EXTRA_TEXT, input);
+ sendBoardIntent.setType("text/plain");
+
+ Intent shareBoardIntent = Intent.createChooser(sendBoardIntent, null);
+ startActivity(shareBoardIntent);
+ }
+
+ @Override
+ public void onDialogNegativeClick() {
+ // do nothing
+ }
+
+ public static class ShareBoardDialog extends DialogFragment {
+ private LinkedList listeners = new LinkedList<>();
+
+ /*declare empty display code and click listener in case anyone
+ * tries to call the ShareBoardDialog without setting those attributes first
+ */
+
+ private String displayCode = "";
+ private View.OnClickListener copyClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ }
+ };
+
+ public void setDisplayCode(String displayCode) {
+ this.displayCode = displayCode;
+ }
+
+ public void setCopyClickListener(View.OnClickListener listener) {
+ copyClickListener = listener;
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ // Verify that the host activity implements the callback interface
+ if(activity instanceof IShareDialogFragmentListener) {
+ listeners.add((IShareDialogFragmentListener) activity);
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppTheme_Dialog);
+
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ DialogFragmentShareBoardBinding binding = DialogFragmentShareBoardBinding.inflate(inflater);
+
+ binding.ver3DisplaySudokuTextView.setText(displayCode);
+ binding.ver3CopySudokuToClipboardButton.setOnClickListener(copyClickListener);
+ builder.setView(binding.getRoot());
+
+ builder.setPositiveButton(R.string.share_confirmation_confirm, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ for(IShareDialogFragmentListener l : listeners) {
+ l.onShareDialogPositiveClick(binding.ver3DisplaySudokuTextView.getText().toString());
+ }
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User cancelled the dialog
+ }
+ });
+ return builder.create();
+ }
+ }
+
+ public static class ResetConfirmationDialog extends DialogFragment {
+
+ LinkedList listeners = new LinkedList<>();
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ // Verify that the host activity implements the callback interface
+ if(activity instanceof IResetDialogFragmentListener) {
+ listeners.add((IResetDialogFragmentListener) activity);
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // Use the Builder class for convenient dialog construction
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppTheme_Dialog);
+ builder.setMessage(R.string.reset_confirmation)
+ .setPositiveButton(R.string.reset_confirmation_confirm, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ for(IResetDialogFragmentListener l : listeners) {
+ l.onResetDialogPositiveClick();
+ }
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User cancelled the dialog
+ }
+ });
+ return builder.create();
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle savedInstanceState) {
+ // Save the user's current game state
+
+ savedInstanceState.putParcelable("gameController", gameController);
+ savedInstanceState.putInt("gameSolved", gameSolved ? 1 : 0);
+
+ // Always call the superclass so it can save the view hierarchy state
+ super.onSaveInstanceState(savedInstanceState);
+ }
+
+ @Override
+ public void onRestoreInstanceState(Bundle savedInstanceState) {
+ //super.onRestoreInstanceState(savedInstanceState);
+ }
+
+}
diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/DailySudokuActivity.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/DailySudokuActivity.java
similarity index 96%
rename from app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/DailySudokuActivity.java
rename to app/src/main/java/org/secuso/privacyfriendlysudoku/ui/DailySudokuActivity.java
index d8800a1..43aa30a 100644
--- a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/DailySudokuActivity.java
+++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/DailySudokuActivity.java
@@ -1,4 +1,4 @@
-package org.secuso.privacyfriendlysudoku.ui.view;
+package org.secuso.privacyfriendlysudoku.ui;
import android.content.Context;
import android.content.Intent;
@@ -18,20 +18,17 @@ import android.view.View;
import android.widget.RatingBar;
import android.widget.Toast;
import org.secuso.privacyfriendlysudoku.controller.GameController;
-import org.secuso.privacyfriendlysudoku.controller.GameStateManager;
import org.secuso.privacyfriendlysudoku.controller.NewLevelManager;
import org.secuso.privacyfriendlysudoku.controller.database.DatabaseHelper;
import org.secuso.privacyfriendlysudoku.controller.database.model.DailySudoku;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import org.secuso.privacyfriendlysudoku.controller.SaveLoadStatistics;
-import org.secuso.privacyfriendlysudoku.controller.helper.GameInfoContainer;
import org.secuso.privacyfriendlysudoku.controller.qqwing.QQWing;
import org.secuso.privacyfriendlysudoku.game.GameDifficulty;
import org.secuso.privacyfriendlysudoku.game.GameType;
-import org.secuso.privacyfriendlysudoku.ui.GameActivity;
-import org.secuso.privacyfriendlysudoku.ui.SettingsActivity;
-import org.secuso.privacyfriendlysudoku.ui.StatsActivity;
+import org.secuso.privacyfriendlysudoku.ui.view.R;
+
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
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 4e5982c..6a504e8 100644
--- a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/GameActivity.java
+++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/GameActivity.java
@@ -17,6 +17,8 @@ import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import com.google.android.material.navigation.NavigationView;
+
+import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle;
@@ -96,6 +98,12 @@ public class GameActivity extends BaseActivity implements NavigationView.OnNavig
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+ if (sharedPref.getBoolean("pref_dark_mode_setting", false )) {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
+ } else {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
+ }
+
if(sharedPref.getBoolean("pref_keep_screen_on", true)) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
@@ -115,8 +123,13 @@ public class GameActivity extends BaseActivity implements NavigationView.OnNavig
(extras.containsKey("gameType") || extras.containsKey("loadLevel"));
if (data != null && !intentReceivedFromMainActivity) {
- String input = data.toString();
- input = input.replace("sudoku://", "");
+ String input = "";
+ if (data.getScheme().equals("sudoku")){
+ input = data.getHost();
+ } else if (data.getScheme().equals("http") && data.getHost().equals("sudoku")){
+ input = data.getPath();
+ input =input.replace("/", "");
+ }
int sectionSize = (int)Math.sqrt(input.length());
int boardSize = sectionSize * sectionSize;
@@ -372,6 +385,7 @@ public class GameActivity extends BaseActivity implements NavigationView.OnNavig
case R.id.menu_share:
String codeForClipboard = "sudoku://" + gameController.getCodeOfField();
+ String codeForClipboard1 = "http://sudoku" + gameController.getCodeOfField();
ShareBoardDialog shareDialog = new ShareBoardDialog();
shareDialog.setDisplayCode(codeForClipboard);
shareDialog.setCopyClickListener(new View.OnClickListener() {
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 4a378c4..7973ad6 100644
--- a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/MainActivity.java
+++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/MainActivity.java
@@ -2,10 +2,13 @@ package org.secuso.privacyfriendlysudoku.ui;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.media.audiofx.Equalizer;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import com.google.android.material.navigation.NavigationView;
+
+import androidx.appcompat.app.AppCompatDelegate;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
@@ -13,7 +16,6 @@ import androidx.core.view.GravityCompat;
import androidx.viewpager.widget.ViewPager;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle;
-import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.MenuItem;
@@ -30,7 +32,6 @@ import org.secuso.privacyfriendlysudoku.controller.NewLevelManager;
import org.secuso.privacyfriendlysudoku.controller.helper.GameInfoContainer;
import org.secuso.privacyfriendlysudoku.game.GameDifficulty;
import org.secuso.privacyfriendlysudoku.game.GameType;
-import org.secuso.privacyfriendlysudoku.ui.view.DailySudokuActivity;
import org.secuso.privacyfriendlysudoku.ui.view.R;
import java.util.LinkedList;
@@ -56,8 +57,22 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
+
settings = PreferenceManager.getDefaultSharedPreferences(this);
+ if (settings.getBoolean("pref_dark_mode_setting", false )) {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
+
+ } else if (settings.getBoolean("pref_dark_mode_automatically_by_system", false)) {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
+
+ } else if(settings.getBoolean("pref_dark_mode_automatically_by_battery", false)){
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
+ } else {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
+ }
+
NewLevelManager newLevelManager = NewLevelManager.getInstance(getApplicationContext(), settings);
// check if we need to pre generate levels.
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 448b560..f6c20fd 100644
--- a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/SettingsActivity.java
+++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/SettingsActivity.java
@@ -3,6 +3,8 @@ package org.secuso.privacyfriendlysudoku.ui;
import android.annotation.TargetApi;
import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
@@ -10,14 +12,19 @@ import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatDelegate;
+
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.view.MenuItem;
import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.Switch;
import org.secuso.privacyfriendlysudoku.ui.view.R;
import java.util.List;
+import java.util.Map;
/**
* A {@link PreferenceActivity} that presents a set of application settings. On
@@ -43,12 +50,51 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
mainContent.setAlpha(0);
mainContent.animate().alpha(1).setDuration(BaseActivity.MAIN_CONTENT_FADEIN_DURATION);
}
+ /**
+ * Set up the {@link android.app.ActionBar}, if the API is available.
+ */
+
+ SharedPreferences preferenceManager = PreferenceManager
+ .getDefaultSharedPreferences(this);
+
+ SharedPreferences.OnSharedPreferenceChangeListener x = new SharedPreferences.OnSharedPreferenceChangeListener() {
+
+
+ public void recheckNightModeProperties(SharedPreferences sharedPreferences){
+ if (sharedPreferences.getBoolean("pref_dark_mode_setting", false )) {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
+ restartActivity();
+
+ } else if (sharedPreferences.getBoolean("pref_dark_mode_automatically_by_system", false)) {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
+ restartActivity();
+ } else if(sharedPreferences.getBoolean("pref_dark_mode_automatically_by_battery", false)){
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
+ restartActivity();
+ } else {
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
+ restartActivity();
+ }
+
+ }
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (key.equals("pref_dark_mode_setting")|| key.equals("pref_dark_mode_automatically_by_system")||key.equals("pref_dark_mode_automatically_by_battery")) {
+ recheckNightModeProperties(sharedPreferences);
+ }
+ }
+ };
+ preferenceManager.registerOnSharedPreferenceChangeListener(x);
+
}
- /**
- * Set up the {@link android.app.ActionBar}, if the API is available.
- */
- private void setupActionBar() {
+ public void restartActivity() {
+ Intent i = new Intent(getApplicationContext(), MainActivity.class);
+ finish();
+ startActivity(i);
+ }
+
+ private void setupActionBar () {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
// Show the Up button in the action bar.
@@ -69,7 +115,6 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
return super.onMenuItemSelected(featureId, item);
}
-
/**
* {@inheritDoc}
*/
diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/CreateSudokuButtonType.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/CreateSudokuButtonType.java
new file mode 100644
index 0000000..ab4c276
--- /dev/null
+++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/CreateSudokuButtonType.java
@@ -0,0 +1,56 @@
+package org.secuso.privacyfriendlysudoku.ui.view;
+
+import androidx.annotation.DrawableRes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Chris on 15.11.2015.
+ */
+public enum CreateSudokuButtonType {
+ Unspecified(R.drawable.ic_accessibility_black_48dp),// placeholder
+ Value(R.drawable.ic_accessibility_black_48dp), // should be non picture
+ Do(R.drawable.ic_redo_black_48dp),
+ Undo(R.drawable.ic_undo_black_48dp),
+ NoteToggle(R.drawable.ic_create_black_48dp),
+ Spacer(R.drawable.ic_accessibility_black_48dp),//placeholder
+ Delete(R.drawable.ic_delete_black_48dp),
+ Finalize(R.drawable.ic_finalize),
+ Reset(R.drawable.ic_settings_backup_restore_black_48dp);
+
+
+ private int resID;
+
+ CreateSudokuButtonType(@DrawableRes int res){
+ this.resID = res;
+ }
+
+ public int getResID() {
+ return resID;
+ }
+
+ public static List getSpecialButtons() {
+ ArrayList result = new ArrayList();
+ result.add(Undo);
+ result.add(Do);
+ result.add(Finalize);
+ //result.add(Spacer);
+ result.add(Delete);
+ result.add(NoteToggle);
+ return result;
+ }
+ public static String getName(CreateSudokuButtonType type) {
+ switch (type) {
+ case Do: return "Do";
+ case Undo: return "Un";
+ case Finalize: return "Fi";
+ case NoteToggle: return "On";
+ case Spacer: return "";
+ case Delete: return "Del";
+ default:return "NotSet";
+ }
+ }
+}
+
+
diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/CreateSudokuSpecialButton.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/CreateSudokuSpecialButton.java
new file mode 100644
index 0000000..6d93e6e
--- /dev/null
+++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/CreateSudokuSpecialButton.java
@@ -0,0 +1,23 @@
+package org.secuso.privacyfriendlysudoku.ui.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ImageButton;
+
+/**
+ * Created by TMZ_LToP on 07.12.2015.
+ */
+public class CreateSudokuSpecialButton extends ImageButton {
+ private int value = -1;
+ private CreateSudokuButtonType type = CreateSudokuButtonType.Unspecified;
+
+ public CreateSudokuSpecialButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void setValue(int value) { this.value = value; }
+ public void setType(CreateSudokuButtonType type) { this.type = type; }
+ public int getValue () { return value; }
+ public CreateSudokuButtonType getType() { return type; }
+
+}
diff --git a/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/CreateSudokuSpecialButtonLayout.java b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/CreateSudokuSpecialButtonLayout.java
new file mode 100644
index 0000000..3fe8168
--- /dev/null
+++ b/app/src/main/java/org/secuso/privacyfriendlysudoku/ui/view/CreateSudokuSpecialButtonLayout.java
@@ -0,0 +1,224 @@
+package org.secuso.privacyfriendlysudoku.ui.view;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+import androidx.core.content.ContextCompat;
+
+import org.secuso.privacyfriendlysudoku.controller.GameController;
+import org.secuso.privacyfriendlysudoku.game.listener.IHighlightChangedListener;
+import org.secuso.privacyfriendlysudoku.ui.GameActivity;
+import org.secuso.privacyfriendlysudoku.ui.listener.IHintDialogFragmentListener;
+
+import java.util.LinkedList;
+
+import static org.secuso.privacyfriendlysudoku.ui.view.CreateSudokuButtonType.Spacer;
+import static org.secuso.privacyfriendlysudoku.ui.view.CreateSudokuButtonType.getSpecialButtons;
+
+/**
+ * Created by TMZ_LToP on 17.11.2015.
+ */
+public class CreateSudokuSpecialButtonLayout extends LinearLayout implements IHighlightChangedListener {
+
+
+ CreateSudokuSpecialButton[] fixedButtons;
+ public int fixedButtonsCount = getSpecialButtons().size();
+ GameController gameController;
+ SudokuKeyboardLayout keyboard;
+ Bitmap bitMap,bitResult;
+ Canvas canvas;
+ FragmentManager fragmentManager;
+ Context context;
+
+ OnClickListener listener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(v instanceof CreateSudokuSpecialButton) {
+ CreateSudokuSpecialButton btn = (CreateSudokuSpecialButton)v;
+
+ //int row = gameController.getSelectedRow();
+ //int col = gameController.getSelectedCol();
+
+ switch(btn.getType()) {
+ case Delete:
+ gameController.deleteSelectedCellsValue();
+ break;
+ case NoteToggle:
+ // rotates the Drawable
+ gameController.setNoteStatus(!gameController.getNoteStatus());
+ keyboard.updateNotesEnabled();
+ onHighlightChanged();
+ break;
+ case Do:
+ gameController.ReDo();
+ break;
+ case Undo:
+ gameController.UnDo();
+ break;
+ case Finalize:
+ default:
+ break;
+ }
+ }
+ }
+ };
+
+
+ public CreateSudokuSpecialButtonLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setWeightSum(fixedButtonsCount);
+ this.context = context;
+ }
+
+ public void setButtonsEnabled(boolean enabled) {
+ for(CreateSudokuSpecialButton b : fixedButtons) {
+ b.setEnabled(enabled);
+ }
+ }
+
+ public void setButtons(int width, GameController gc, SudokuKeyboardLayout key, FragmentManager fm, int orientation, Context cxt) {
+ fragmentManager = fm;
+ keyboard=key;
+ gameController = gc;
+ context = cxt;
+ if(gameController != null) {
+ gameController.registerHighlightChangedListener(this);
+ }
+ fixedButtons = new CreateSudokuSpecialButton[fixedButtonsCount];
+ LayoutParams p;
+ int i = 0;
+ //ArrayList type = (ArrayList) SudokuButtonType.getSpecialButtons();
+ for (CreateSudokuButtonType t : getSpecialButtons()){
+ fixedButtons[i] = new CreateSudokuSpecialButton(getContext(),null);
+ if(orientation == LinearLayout.HORIZONTAL) {
+ p = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1);
+ } else {
+ p = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1);
+ fixedButtons[i].setPadding(25, 0, 25, 0);
+ }
+ p.setMargins(5, 5, 5, 5);
+
+ //int width2 =width/(fixedButtonsCount);
+ //p.width= width2-15;
+ if(t == Spacer) {
+ fixedButtons[i].setVisibility(View.INVISIBLE);
+ }
+ /*if(t == SudokuButtonType.Do && !gameController.isRedoAvailable()) {
+ fixedButtons[i].setEnabled(false);
+ }
+ if(t == SudokuButtonType.Undo && !gameController.isUndoAvailable()) {
+ fixedButtons[i].setEnabled(false);
+ }*/
+ fixedButtons[i].setLayoutParams(p);
+ fixedButtons[i].setType(t);
+ fixedButtons[i].setImageDrawable(getResources().getDrawable(t.getResID()));
+ // fixedButtons[i].setText(SudokuButtonType.getName(t));
+ fixedButtons[i].setScaleType(ImageView.ScaleType.CENTER);
+ fixedButtons[i].setAdjustViewBounds(true);
+ fixedButtons[i].setOnClickListener(listener);
+ fixedButtons[i].setBackgroundResource(R.drawable.numpad_highlighted_four);
+ addView(fixedButtons[i]);
+
+ if(fixedButtons[i].getVisibility() == View.VISIBLE) {
+ Drawable drawable = ContextCompat.getDrawable(context, fixedButtons[i].getType().getResID());
+ setUpVectorDrawable(drawable);
+ drawable.draw(canvas);
+ fixedButtons[i].setImageBitmap(bitResult);
+ }
+ i++;
+ }
+
+ }
+
+ @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;
+ case NoteToggle:
+ Drawable drawable = ContextCompat.getDrawable(context, fixedButtons[i].getType().getResID());
+ setUpVectorDrawable(drawable);
+
+ canvas.rotate(gameController.getNoteStatus() ? 45.0f : 0.0f, bitMap.getWidth()/2, bitMap.getHeight()/2);
+ canvas.drawBitmap(bitMap, 0, 0, null);
+ drawable.draw(canvas);
+
+ fixedButtons[i].setImageBitmap(bitResult);
+ fixedButtons[i].setBackgroundResource(gameController.getNoteStatus() ? R.drawable.numpad_highlighted_three : R.drawable.numpad_highlighted_four);
+
+ keyboard.updateNotesEnabled();
+
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private void setUpVectorDrawable(Drawable drawable) {
+ drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+ bitMap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
+ drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ bitResult = Bitmap.createBitmap(bitMap.getWidth(), bitMap.getHeight(), Bitmap.Config.ARGB_8888);
+
+ canvas = new Canvas(bitResult);
+ }
+ /*
+ public static class HintConfirmationDialog extends DialogFragment {
+
+ LinkedList listeners = new LinkedList<>();
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ // Verify that the host activity implements the callback interface
+ if(activity instanceof IHintDialogFragmentListener) {
+ listeners.add((IHintDialogFragmentListener) activity);
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // Use the Builder class for convenient dialog construction
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppTheme_Dialog);
+ builder.setMessage(R.string.hint_confirmation)
+ .setPositiveButton(R.string.hint_confirmation_confirm, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ for(IHintDialogFragmentListener l : listeners) {
+ l.onHintDialogPositiveClick();
+ }
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User cancelled the dialog
+ }
+ });
+ return builder.create();
+ }
+ }
+ */
+}
diff --git a/app/src/main/res/drawable/ic_finalize.xml b/app/src/main/res/drawable/ic_finalize.xml
new file mode 100644
index 0000000..e57a943
--- /dev/null
+++ b/app/src/main/res/drawable/ic_finalize.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_create_sudoku.xml b/app/src/main/res/layout/activity_create_sudoku.xml
new file mode 100644
index 0000000..4763ba5
--- /dev/null
+++ b/app/src/main/res/layout/activity_create_sudoku.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_game_view_create_sudoku.xml b/app/src/main/res/layout/content_game_view_create_sudoku.xml
new file mode 100644
index 0000000..ff2d71c
--- /dev/null
+++ b/app/src/main/res/layout/content_game_view_create_sudoku.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/tutorial_slide1.xml b/app/src/main/res/layout/tutorial_slide1.xml
index c24dd62..880eea7 100644
--- a/app/src/main/res/layout/tutorial_slide1.xml
+++ b/app/src/main/res/layout/tutorial_slide1.xml
@@ -2,7 +2,7 @@
+ android:background="?attr/backgroundTutorialSlide">
+ android:background="?attr/backgroundTutorialSlide">
+ android:background="?attr/backgroundTutorialSlide">
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 1285f24..05fbbd2 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -10,6 +10,9 @@
Einstellungen
+ Nachtmodus
+ Nachtmodus
+ Wechsel zwischen Tages und Nacht Modus
In Zusammenarbeit mit:
diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml
index 5ca9ee4..81dbff3 100644
--- a/app/src/main/res/values-night/styles.xml
+++ b/app/src/main/res/values-night/styles.xml
@@ -20,6 +20,8 @@
- @color/middlegrey
- @color/yellow
- @color/cardview_dark_background
+ - @color/colorPrimaryDark
+ - @color/colorPrimaryDark