diff --git a/.gitignore b/.gitignore index a511bca..f21690d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .gradle /local.properties /.idea/workspace.xml +/.idea/tasks.xml /.idea/libraries .DS_Store /build @@ -10,4 +11,5 @@ gradle* /gradle /app/build -keystore.properties \ No newline at end of file +keystore.properties +/app/release diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 4dfc7f4..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -QUOZ \ No newline at end of file diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml new file mode 100644 index 0000000..2a9c5e0 --- /dev/null +++ b/.idea/assetWizardSettings.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser new file mode 100644 index 0000000..1c2d2c3 Binary files /dev/null and b/.idea/caches/build_file_checksums.ser differ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..2715a34 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 96cc43e..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3..0000000 --- a/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 97626ba..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 5d19981..99202cc 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,18 +1,16 @@ - - - @@ -27,17 +25,7 @@ - - - - - - - - - - - + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/QUOZ/QUOZ/.idea/misc.xml b/QUOZ/QUOZ/.idea/misc.xml deleted file mode 100644 index fbb6828..0000000 --- a/QUOZ/QUOZ/.idea/misc.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/QUOZ/QUOZ/.idea/workspace.xml b/QUOZ/QUOZ/.idea/workspace.xml deleted file mode 100644 index ffae75b..0000000 --- a/QUOZ/QUOZ/.idea/workspace.xml +++ /dev/null @@ -1,1921 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1470164634382 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 6c56efb..8e58bb3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,32 +1,20 @@ -apply plugin: 'com.android.application' - -def keystorePropertiesFile = rootProject.file("keystore.properties") -def keystoreProperties = new Properties() -keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +apply plugin: "com.android.application" +apply plugin: "kotlin-android" android { - signingConfigs { - config { - keyAlias 'AndroidKey' - keyPassword keystoreProperties['password'] - storeFile file('C:/Users/Jonathan/Documents/Projects/Keystores/android.jks') - storePassword keystoreProperties['password'] - } - } - compileSdkVersion 24 - buildToolsVersion "24.0.1" + compileSdkVersion 27 + buildToolsVersion "27.0.3" defaultConfig { applicationId "nonphatic.quoz" - minSdkVersion 19 - targetSdkVersion 24 + minSdkVersion 21 + targetSdkVersion 27 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - signingConfig signingConfigs.config + proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } debug { } @@ -34,9 +22,12 @@ android { } dependencies { - compile fileTree(include: ['*.jar'], dir: 'libs') - testCompile 'junit:junit:4.12' - compile 'com.android.support:appcompat-v7:24.1.1' - compile 'com.android.support:support-v4:24.1.1' - compile 'com.android.support:design:24.1.1' + implementation fileTree(include: ["*.jar"], dir: "libs") + implementation "com.android.support:appcompat-v7:27.1.1" + implementation "com.android.support:support-v4:27.1.1" + implementation "com.android.support:design:27.1.1" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} +repositories { + mavenCentral() } diff --git a/app/src/androidTest/java/nonphatic/quoz/ApplicationTest.java b/app/src/androidTest/java/nonphatic/quoz/ApplicationTest.java deleted file mode 100644 index dbc9c45..0000000 --- a/app/src/androidTest/java/nonphatic/quoz/ApplicationTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package nonphatic.quoz; - -import android.app.Application; -import android.test.ApplicationTestCase; - -/** - * Testing Fundamentals - */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); - } -} \ No newline at end of file diff --git a/app/src/main/java/nonphatic/quoz/MainActivity.java b/app/src/main/java/nonphatic/quoz/MainActivity.java deleted file mode 100644 index c8876aa..0000000 --- a/app/src/main/java/nonphatic/quoz/MainActivity.java +++ /dev/null @@ -1,336 +0,0 @@ -package nonphatic.quoz; - -import android.annotation.SuppressLint; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.graphics.Color; -import android.media.AudioManager; -import android.media.MediaPlayer; -import android.preference.PreferenceManager; -import android.support.design.widget.FloatingActionButton; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import android.os.Handler; -import android.view.MotionEvent; -import android.view.View; -import android.widget.TextView; -import android.widget.Toast; - -import nonphatic.quoz.preferences.SettingsActivity; - -import java.util.Random; -import java.util.Timer; -import java.util.TimerTask; - -/** - * An example full-screen activity that shows and hides the system UI (i.e. - * status bar and navigation/system bar) with user interaction. - */ -public class MainActivity extends AppCompatActivity { - /** - * Whether or not the system UI should be auto-hidden after - * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds. - */ - private static final boolean AUTO_HIDE = true; - - /** - * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after - * user interaction before hiding the system UI. - */ - private static final int AUTO_HIDE_DELAY_MILLIS = 3000; - - /** - * Some older devices needs a small delay between UI widget updates - * and a change of the status and navigation bar. - */ - private static final int UI_ANIMATION_DELAY = 300; - private final Handler mHideHandler = new Handler(); - private View mContentView; - private FloatingActionButton mFab; - private View mainView; - private Timer timer; - private TimerTask timerTask; - private MediaPlayer mediaPlayer; - private Random random; - - private int saturationPercent; - private String changeMode; - - private final Runnable mHidePart2Runnable = new Runnable() { - @SuppressLint("InlinedApi") - @Override - public void run() { - // Delayed removal of status and navigation bar - - // Note that some of these constants are new as of API 16 (Jelly Bean) - // and API 19 (KitKat). It is safe to use them, as they are inlined - // at compile-time and do nothing on earlier devices. - mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE - | View.SYSTEM_UI_FLAG_FULLSCREEN - | View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); - } - }; - private final Runnable mShowPart2Runnable = new Runnable() { - @Override - public void run() { - // Delayed display of UI elements - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.show(); - } - } - }; - private final Runnable mHideRunnable = new Runnable() { - @Override - public void run() { - hide(); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_main); - setVolumeControlStream(AudioManager.STREAM_MUSIC); - - getPreferences(); - mContentView = findViewById(R.id.fullscreen_content); - mFab = (FloatingActionButton)findViewById(R.id.fab); - mainView = findViewById(R.id.main_layout); - timer = new Timer(); - random = new Random(); - - // Set up the user interaction to manually show or hide the system UI. - mContentView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (!isSwiping) { - setBackgroundToRandomColour(); - } - } - }); - - mContentView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View view) { - ClipboardManager clipboardManager = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("QUOZ Colour", ((TextView)mContentView).getText()); - clipboardManager.setPrimaryClip(clip); - - Toast.makeText(getApplicationContext(), "Copied to clipboard", Toast.LENGTH_SHORT).show(); - return true; - } - }); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - - // Trigger the initial hide() shortly after the activity has been - // created, to briefly hint to the user that UI controls - // are available. - delayedHide(100); - } - - private void toggle(float yDelta) { - if (yDelta < 0) { - hide(); - } else { - show(); - } - } - - private void hide() { - // Hide UI first - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.hide(); - } - mFab.hide(); - - // Schedule a runnable to remove the status and navigation bar after a delay - mHideHandler.removeCallbacks(mShowPart2Runnable); - mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY); - } - - @SuppressLint("InlinedApi") - private void show() { - // Show the system bar - mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - mFab.show(); - - // Schedule a runnable to display UI elements after a delay - mHideHandler.removeCallbacks(mHidePart2Runnable); - mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY); - } - - /** - * Schedules a call to hide() in [delay] milliseconds, canceling any - * previously scheduled calls. - */ - private void delayedHide(int delayMillis) { - mHideHandler.removeCallbacks(mHideRunnable); - mHideHandler.postDelayed(mHideRunnable, delayMillis); - } - - - //region OVERRIDES - private float yPosOnDown; - private float yDelta; - private boolean isSwiping; - @Override - public boolean dispatchTouchEvent(MotionEvent event) { - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - yPosOnDown = event.getY(); - isSwiping = false; - break; - case MotionEvent.ACTION_UP: - if (isSwiping) { - toggle(yDelta); - } - break; - case MotionEvent.ACTION_MOVE: - float yPosCurr = event.getY(); - yDelta = yPosCurr - yPosOnDown; - if (Math.abs(yDelta) > 120) { - isSwiping = true; - return true; - } - break; - } - return super.dispatchTouchEvent(event); - } - - @Override - public void onResume() { - super.onResume(); - getPreferences(); - setBackgroundToRandomColour(); - setTimer(); - } - - @Override - public void onPause() { - super.onPause(); - if (mediaPlayer != null) { - mediaPlayer.stop(); - mediaPlayer.release(); - mediaPlayer = null; - } - } - //endregion - - //region HELPERS - public void getPreferences() { - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); - saturationPercent = preferences.getInt("saturation", 30); - changeMode = preferences.getString("change_mode", "tap"); - } - - public void resetPreferences(Context context) { - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - preferences.edit().clear().commit(); - PreferenceManager.setDefaultValues(context, R.xml.preferences, true); - Toast.makeText(getApplicationContext(), "Settings reset.", Toast.LENGTH_SHORT).show(); - } - - private void setBackgroundToRandomColour() { - float[] hsv = generateRandomColour(); - float[] hsvText = new float[] { 0, 0, hsv[1] / 2 + 0.25f }; - int randomColour = Color.HSVToColor(hsv); - int textColour = Color.HSVToColor(hsvText); - - mainView.setBackgroundColor(randomColour); - ((TextView)mContentView).setText(String.format("#%s", Integer.toHexString(randomColour).substring(2))); - ((TextView)mContentView).setTextColor(textColour); - } - - private float[] generateRandomColour() { - float phiRecip = Float.parseFloat(getResources().getText(R.string.phiRecip).toString()); - return new float[] { - (random.nextFloat() + phiRecip) % 1 * 360, // random, nicely-spaced hue - saturationPercent / 100f, // saturation - 1.0f // value - }; - } - - private void setTimer() { - if (timerTask != null) { - timerTask.cancel(); - } - - switch (changeMode) { - case "tap": - break; - case "cycle": - timerTask = new TimerTask() { - @Override - public void run() { - runOnUiThread(new Runnable() { - @Override - public void run() { - setBackgroundToRandomColour(); - } - }); - } - }; - timer.schedule(timerTask, 0, 1000); - break; - case "leekspin": - timerTask = new TimerTask() { - @Override - public void run() { - runOnUiThread(new Runnable() { - @Override - public void run() { - setBackgroundToRandomColour(); - } - }); - } - }; - timer.schedule(timerTask, 300, 550); - mediaPlayer = MediaPlayer.create(this, R.raw.ievan_polkka); - mediaPlayer.setLooping(true); - mediaPlayer.start(); - break; - case "nyan": - timerTask = new TimerTask() { - @Override - public void run() { - runOnUiThread(new Runnable() { - @Override - public void run() { - setBackgroundToRandomColour(); - } - }); - } - }; - timer.schedule(timerTask, 160, 420); - mediaPlayer = MediaPlayer.create(this, R.raw.nyan); - mediaPlayer.setLooping(true); - mediaPlayer.start(); - break; - } - } - //endregion - - //region ACTIVITIES - public void openSettings(View view) { - Intent intent = new Intent(this, SettingsActivity.class); - intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.PreferencesFragment.class.getName()); - intent.putExtra(SettingsActivity.EXTRA_NO_HEADERS, true); - startActivity(intent); - } - //endregion -} diff --git a/app/src/main/java/nonphatic/quoz/MainActivity.kt b/app/src/main/java/nonphatic/quoz/MainActivity.kt new file mode 100644 index 0000000..2797a52 --- /dev/null +++ b/app/src/main/java/nonphatic/quoz/MainActivity.kt @@ -0,0 +1,238 @@ +package nonphatic.quoz + +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.media.AudioManager +import android.media.MediaPlayer +import android.net.Uri +import android.preference.PreferenceManager +import android.support.design.widget.FloatingActionButton +import android.support.v7.app.AppCompatActivity +import android.os.Bundle +import android.os.Handler +import android.preference.PreferenceActivity +import android.view.MotionEvent +import android.view.View +import android.widget.TextView +import android.widget.Toast + +import nonphatic.quoz.preferences.SettingsActivity + +import java.util.Random +import java.util.Timer +import java.util.TimerTask + +class MainActivity : AppCompatActivity() { + private val mHideHandler: Handler = Handler() + private val random: Random = Random() + private val mediaPlayer: MediaPlayer = MediaPlayer() + private var timer: Timer = Timer() + + private lateinit var mContentView: View + private lateinit var mFab: FloatingActionButton + private lateinit var mainView: View + + private val saturationPercent + get() = PreferenceManager.getDefaultSharedPreferences(this) + .getInt(getString(R.string.preferences_colour_key), + resources.getInteger(R.integer.preferences_colour_default)) + private val changeMode + get() = PreferenceManager.getDefaultSharedPreferences(this) + .getString(getString(R.string.preferences_mode_key), + getString(R.string.preferences_mode_default)) + + private val mHidePart2Runnable = Runnable { + // Delayed removal of status and navigation bar + + // Note that some of these constants are new as of API 16 (Jelly Bean) + // and API 19 (KitKat). It is safe to use them, as they are inlined + // at compile-time and do nothing on earlier devices. + mContentView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LOW_PROFILE + or View.SYSTEM_UI_FLAG_FULLSCREEN + or View.SYSTEM_UI_FLAG_LAYOUT_STABLE + or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) + } + private val mShowPart2Runnable = Runnable { + // Delayed display of UI elements + val actionBar = supportActionBar + actionBar?.show() + } + private val mHideRunnable = Runnable { hide() } + + + //region OVERRIDES + private var yPosOnDown: Float = 0f + private var yDelta: Float = 0f + private var isSwiping: Boolean = false + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.activity_main) + volumeControlStream = AudioManager.STREAM_MUSIC + + mContentView = findViewById(R.id.fullscreen_content) + mFab = findViewById(R.id.fab) + mainView = findViewById(R.id.main_layout) + + // Set up the user interaction to manually show or hide the system UI. + mContentView.setOnClickListener { + if (!isSwiping) { + setColour() + } + } + + mContentView.setOnLongClickListener { + val clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText(getString(R.string.app_name), (mContentView as TextView).text) + clipboardManager.primaryClip = clip + + Toast.makeText(applicationContext, getString(R.string.toast_copied), Toast.LENGTH_SHORT).show() + true + } + } + + override fun onPostCreate(savedInstanceState: Bundle?) { + super.onPostCreate(savedInstanceState) + + // Trigger the initial hide() shortly after the activity has been + // created, to briefly hint to the user that UI controls + // are available. + mHideHandler.removeCallbacks(mHideRunnable) + mHideHandler.postDelayed(mHideRunnable, INIT_ANIMATION_DELAY) + } + + private fun show() { + // Show the system bar + mContentView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + mFab.show() + + // Schedule a runnable to display UI elements after a delay + mHideHandler.removeCallbacks(mHidePart2Runnable) + mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY) + } + + private fun hide() { + // Hide UI first + supportActionBar?.hide() + mFab.hide() + + // Schedule a runnable to remove the status and navigation bar after a delay + mHideHandler.removeCallbacks(mShowPart2Runnable) + mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY) + } + + override fun dispatchTouchEvent(event: MotionEvent): Boolean { + when (event.action) { + MotionEvent.ACTION_DOWN -> { + yPosOnDown = event.y + isSwiping = false + } + MotionEvent.ACTION_UP -> if (isSwiping) { + if (yDelta < 0) hide() else show() + } + MotionEvent.ACTION_MOVE -> { + val yPosCurr = event.y + yDelta = yPosCurr - yPosOnDown + if (Math.abs(yDelta) > SWIPE_MIN_DIST) { + isSwiping = true + return true + } + } + } + return super.dispatchTouchEvent(event) + } + + public override fun onResume() { + super.onResume() + setColour() + setLoop() + } + + public override fun onPause() { + super.onPause() + mediaPlayer.stop() + mediaPlayer.reset() + timer.cancel() + } + //endregion + + + //region HELPERS + private fun setColour(hsv: FloatArray = generateRandomColour()) { + val textHSV = floatArrayOf(0f, 0f, hsv[1] / 2 + 0.25f) + val backgroundColour = Color.HSVToColor(hsv) + val textColour = Color.HSVToColor(textHSV) + + mainView.setBackgroundColor(backgroundColour) + (mContentView as TextView).text = "#${Integer.toHexString(backgroundColour and HEX_MASK)}" + (mContentView as TextView).setTextColor(textColour) + } + + private fun generateRandomColour(): FloatArray = floatArrayOf( + (random.nextFloat() + PHI_RECIP) % 1 * 360, // random, nicely-spaced hue + saturationPercent / 100f, // saturation + 1f // value + ) + + private fun scheduleTimer(delay: Long, period: Long) { + timer = Timer().apply { + schedule(object : TimerTask() { + override fun run() { + runOnUiThread { + setColour() + } + } + }, delay, period) + } + } + + private fun playMedia(resId: Int) { + mediaPlayer.setDataSource(this, Uri.parse("android.resource://$packageName/$resId")) + mediaPlayer.prepare() + mediaPlayer.isLooping = true + mediaPlayer.start() + } + + private fun setLoop() { + when (changeMode) { + "tap" -> {} + "cycle" -> { + scheduleTimer(0, 1000) + } + "leekspin" -> { + scheduleTimer(300, 550) + playMedia(R.raw.ievan_polkka) + } + "nyan" -> { + scheduleTimer(160, 423) + playMedia(R.raw.nyan) + } + } + } + //endregion + + + //region ACTIVITIES + fun openSettings(view: View) { + val intent = Intent(this, SettingsActivity::class.java) + intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.PreferencesFragment::class.java.name) + intent.putExtra(PreferenceActivity.EXTRA_NO_HEADERS, true) + startActivity(intent) + } + //endregion + + + companion object { + private const val UI_ANIMATION_DELAY = 300L + private const val INIT_ANIMATION_DELAY = 100L + private const val SWIPE_MIN_DIST = 120 + private const val HEX_MASK = 0xFFFFFF + private const val PHI_RECIP = 0.6180339f + } +} diff --git a/app/src/main/java/nonphatic/quoz/preferences/AboutDialogPreference.java b/app/src/main/java/nonphatic/quoz/preferences/AboutDialogPreference.java deleted file mode 100644 index 751a51e..0000000 --- a/app/src/main/java/nonphatic/quoz/preferences/AboutDialogPreference.java +++ /dev/null @@ -1,57 +0,0 @@ -package nonphatic.quoz.preferences; - -import android.app.AlertDialog; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.preference.DialogPreference; -import android.util.AttributeSet; -import android.view.View; -import android.widget.ImageView; - -import nonphatic.quoz.R; - -/** - * Created by Jonathan on 2016-08-07. - */ -public class AboutDialogPreference extends DialogPreference { - public AboutDialogPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - public AboutDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public AboutDialogPreference(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public AboutDialogPreference(Context context) { - super(context); - } - - @Override - protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { - super.onPrepareDialogBuilder(builder); - builder.setNegativeButton(null, null); - builder.setPositiveButton(null, null); - builder.setTitle(null); - } - - @Override - protected void onBindDialogView(View view) { - super.onBindDialogView(view); - - ImageView nonphaticLogo = (ImageView)view.findViewById(R.id.nonphatic_logo); - nonphaticLogo.setOnLongClickListener(new View.OnLongClickListener() { - public boolean onLongClick(View view) { - Intent intent = new Intent(Intent.ACTION_VIEW); - //intent.setData(Uri.parse("market://search?q=pub:nonphatic")); - intent.setData(Uri.parse("https://github.com/nonphatic")); - getContext().startActivity(intent); - return true; - } - }); - } -} diff --git a/app/src/main/java/nonphatic/quoz/preferences/AboutDialogPreference.kt b/app/src/main/java/nonphatic/quoz/preferences/AboutDialogPreference.kt new file mode 100644 index 0000000..adcedd2 --- /dev/null +++ b/app/src/main/java/nonphatic/quoz/preferences/AboutDialogPreference.kt @@ -0,0 +1,44 @@ +package nonphatic.quoz.preferences + +import android.app.AlertDialog +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.preference.DialogPreference +import android.util.AttributeSet +import android.view.View +import android.widget.ImageView + +import nonphatic.quoz.R + +/** + * Created by Jonathan on 2016-08-07. + */ +class AboutDialogPreference : DialogPreference { + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {} + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {} + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {} + + constructor(context: Context) : super(context) {} + + override fun onPrepareDialogBuilder(builder: AlertDialog.Builder) { + super.onPrepareDialogBuilder(builder) + builder.setNegativeButton(null, null) + builder.setPositiveButton(null, null) + builder.setTitle(null) + } + + override fun onBindDialogView(view: View) { + super.onBindDialogView(view) + + val nonphaticLogo = view.findViewById(R.id.nonphatic_logo) + nonphaticLogo.setOnLongClickListener { + val intent = Intent(Intent.ACTION_VIEW) + intent.data = Uri.parse("https://github.com/nonphatic") + context.startActivity(intent) + true + } + } +} diff --git a/app/src/main/java/nonphatic/quoz/preferences/AppCompatPreferenceActivity.java b/app/src/main/java/nonphatic/quoz/preferences/AppCompatPreferenceActivity.java deleted file mode 100644 index 95c583a..0000000 --- a/app/src/main/java/nonphatic/quoz/preferences/AppCompatPreferenceActivity.java +++ /dev/null @@ -1,109 +0,0 @@ -package nonphatic.quoz.preferences; - -import android.content.res.Configuration; -import android.os.Bundle; -import android.preference.PreferenceActivity; -import android.support.annotation.LayoutRes; -import android.support.annotation.Nullable; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatDelegate; -import android.support.v7.widget.Toolbar; -import android.view.MenuInflater; -import android.view.View; -import android.view.ViewGroup; - -/** - * A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls - * to be used with AppCompat. - */ -public abstract class AppCompatPreferenceActivity extends PreferenceActivity { - - private AppCompatDelegate mDelegate; - - @Override - protected void onCreate(Bundle savedInstanceState) { - getDelegate().installViewFactory(); - getDelegate().onCreate(savedInstanceState); - super.onCreate(savedInstanceState); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - getDelegate().onPostCreate(savedInstanceState); - } - - public ActionBar getSupportActionBar() { - return getDelegate().getSupportActionBar(); - } - - public void setSupportActionBar(@Nullable Toolbar toolbar) { - getDelegate().setSupportActionBar(toolbar); - } - - @Override - public MenuInflater getMenuInflater() { - return getDelegate().getMenuInflater(); - } - - @Override - public void setContentView(@LayoutRes int layoutResID) { - getDelegate().setContentView(layoutResID); - } - - @Override - public void setContentView(View view) { - getDelegate().setContentView(view); - } - - @Override - public void setContentView(View view, ViewGroup.LayoutParams params) { - getDelegate().setContentView(view, params); - } - - @Override - public void addContentView(View view, ViewGroup.LayoutParams params) { - getDelegate().addContentView(view, params); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getDelegate().onPostResume(); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - super.onTitleChanged(title, color); - getDelegate().setTitle(title); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getDelegate().onConfigurationChanged(newConfig); - } - - @Override - protected void onStop() { - super.onStop(); - getDelegate().onStop(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - getDelegate().onDestroy(); - } - - public void invalidateOptionsMenu() { - getDelegate().invalidateOptionsMenu(); - } - - private AppCompatDelegate getDelegate() { - if (mDelegate == null) { - mDelegate = AppCompatDelegate.create(this, null); - } - return mDelegate; - } -} diff --git a/app/src/main/java/nonphatic/quoz/preferences/AppCompatPreferenceActivity.kt b/app/src/main/java/nonphatic/quoz/preferences/AppCompatPreferenceActivity.kt new file mode 100644 index 0000000..a1cd91d --- /dev/null +++ b/app/src/main/java/nonphatic/quoz/preferences/AppCompatPreferenceActivity.kt @@ -0,0 +1,96 @@ +package nonphatic.quoz.preferences + +import android.content.res.Configuration +import android.os.Bundle +import android.preference.PreferenceActivity +import android.support.annotation.LayoutRes +import android.support.v7.app.ActionBar +import android.support.v7.app.AppCompatDelegate +import android.support.v7.widget.Toolbar +import android.view.MenuInflater +import android.view.View +import android.view.ViewGroup + +/** + * A [android.preference.PreferenceActivity] which implements and proxies the necessary calls + * to be used with AppCompat. + */ +abstract class AppCompatPreferenceActivity : PreferenceActivity() { + + private var mDelegate: AppCompatDelegate? = null + + val supportActionBar: ActionBar? + get() = delegate?.supportActionBar + + private val delegate: AppCompatDelegate? + get() { + if (mDelegate == null) { + mDelegate = AppCompatDelegate.create(this, null) + } + return mDelegate + } + + override fun onCreate(savedInstanceState: Bundle?) { + delegate?.installViewFactory() + delegate?.onCreate(savedInstanceState) + super.onCreate(savedInstanceState) + } + + override fun onPostCreate(savedInstanceState: Bundle?) { + super.onPostCreate(savedInstanceState) + delegate?.onPostCreate(savedInstanceState) + } + + fun setSupportActionBar(toolbar: Toolbar?) { + delegate?.setSupportActionBar(toolbar) + } + + override fun getMenuInflater(): MenuInflater? { + return delegate?.menuInflater + } + + override fun setContentView(@LayoutRes layoutResID: Int) { + delegate?.setContentView(layoutResID) + } + + override fun setContentView(view: View) { + delegate?.setContentView(view) + } + + override fun setContentView(view: View, params: ViewGroup.LayoutParams) { + delegate?.setContentView(view, params) + } + + override fun addContentView(view: View, params: ViewGroup.LayoutParams) { + delegate?.addContentView(view, params) + } + + override fun onPostResume() { + super.onPostResume() + delegate?.onPostResume() + } + + override fun onTitleChanged(title: CharSequence, color: Int) { + super.onTitleChanged(title, color) + delegate?.setTitle(title) + } + + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + delegate?.onConfigurationChanged(newConfig) + } + + override fun onStop() { + super.onStop() + delegate?.onStop() + } + + override fun onDestroy() { + super.onDestroy() + delegate?.onDestroy() + } + + override fun invalidateOptionsMenu() { + delegate?.invalidateOptionsMenu() + } +} diff --git a/app/src/main/java/nonphatic/quoz/preferences/SettingsActivity.java b/app/src/main/java/nonphatic/quoz/preferences/SettingsActivity.java deleted file mode 100644 index 9dac628..0000000 --- a/app/src/main/java/nonphatic/quoz/preferences/SettingsActivity.java +++ /dev/null @@ -1,189 +0,0 @@ -package nonphatic.quoz.preferences; - - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.media.AudioManager; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.preference.DialogPreference; -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.view.MenuItem; -import android.widget.Toast; - -import nonphatic.quoz.R; - -/** - * 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 SettingsActivity extends AppCompatPreferenceActivity { - /** - * 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 { - // For all other preferences, set the summary to the value's - // simple string representation. - preference.setSummary(stringValue); - } - return true; - } - }; - - /** - * 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; - } - - /** - * 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. - try { - sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, - PreferenceManager - .getDefaultSharedPreferences(preference.getContext()) - .getString(preference.getKey(), "")); - } - catch (ClassCastException e) { - sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, - PreferenceManager - .getDefaultSharedPreferences(preference.getContext()) - .getInt(preference.getKey(), 0)); - } - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setupActionBar(); - setVolumeControlStream(AudioManager.STREAM_MUSIC); - } - - /** - * 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); - } - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - int id = item.getItemId(); - if (id == android.R.id.home) { - onBackPressed(); - return true; - } - return super.onMenuItemSelected(featureId, item); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean onIsMultiPane() { - return isXLargeTablet(this); - } - - /** - * 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) - || PreferencesFragment.class.getName().equals(fragmentName); - } - - /** - * This fragment shows colour type and change mode preferences. - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public static class PreferencesFragment extends PreferenceFragment { - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.preferences); - setHasOptionsMenu(true); - - Preference resetButton = findPreference("reset_button"); - resetButton.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - preferences.edit().clear().commit(); - PreferenceManager.setDefaultValues(getActivity().getApplicationContext(), R.xml.preferences, true); - onStop(); - onCreate(savedInstanceState); - Toast.makeText(getActivity().getApplicationContext(), "Settings reset.", Toast.LENGTH_SHORT).show(); - return true; - } - }); - - bindPreferenceSummaryToValue(findPreference("change_mode")); - bindPreferenceSummaryToValue(findPreference("saturation")); - } - - @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/nonphatic/quoz/preferences/SettingsActivity.kt b/app/src/main/java/nonphatic/quoz/preferences/SettingsActivity.kt new file mode 100644 index 0000000..67f42f5 --- /dev/null +++ b/app/src/main/java/nonphatic/quoz/preferences/SettingsActivity.kt @@ -0,0 +1,174 @@ +package nonphatic.quoz.preferences + + +import android.annotation.TargetApi +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.content.res.Configuration +import android.media.AudioManager +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.view.MenuItem +import android.widget.Toast + +import nonphatic.quoz.R + +/** + * A [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](http://developer.android.com/design/patterns/settings.html) for design guidelines and the [Settings + * API Guide](http://developer.android.com/guide/topics/ui/settings.html) for more information on developing a Settings UI. + */ +class SettingsActivity : AppCompatPreferenceActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setupActionBar() + volumeControlStream = AudioManager.STREAM_MUSIC + } + + /** + * Set up the [android.app.ActionBar], if the API is available. + */ + private fun setupActionBar() { + val actionBar = supportActionBar + actionBar?.setDisplayHomeAsUpEnabled(true) + } + + override fun onMenuItemSelected(featureId: Int, item: MenuItem): Boolean { + val id = item.itemId + if (id == android.R.id.home) { + onBackPressed() + return true + } + return super.onMenuItemSelected(featureId, item) + } + + /** + * {@inheritDoc} + */ + override fun onIsMultiPane(): Boolean { + return isXLargeTablet(this) + } + + /** + * This method stops fragment injection in malicious applications. + * Make sure to deny any unknown fragments here. + */ + override fun isValidFragment(fragmentName: String): Boolean { + return PreferenceFragment::class.java.name == fragmentName || PreferencesFragment::class.java.name == fragmentName + } + + /** + * This fragment shows colour type and change mode preferences. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + class PreferencesFragment : PreferenceFragment() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + addPreferencesFromResource(R.xml.preferences) + setHasOptionsMenu(true) + + val resetButton = findPreference(getString(R.string.preferences_reset_key)) + resetButton.onPreferenceClickListener = Preference.OnPreferenceClickListener { + val preferences = PreferenceManager.getDefaultSharedPreferences(activity.applicationContext) + preferences.edit().clear().commit() + PreferenceManager.setDefaultValues(activity.applicationContext, R.xml.preferences, true) + onStop() + onCreate(savedInstanceState) + Toast.makeText(activity.applicationContext, getString(R.string.toast_reset), Toast.LENGTH_SHORT).show() + true + } + + bindPreferenceSummaryToValue(findPreference(getString(R.string.preferences_mode_key))) + bindPreferenceSummaryToValue(findPreference(getString(R.string.preferences_colour_key))) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + val id = item.itemId + if (id == android.R.id.home) { + startActivity(Intent(activity, SettingsActivity::class.java)) + return true + } + return super.onOptionsItemSelected(item) + } + } + + companion object { + /** + * A preference value change listener that updates the preference's summary + * to reflect its new value. + */ + private val sBindPreferenceSummaryToValueListener = Preference.OnPreferenceChangeListener { preference, value -> + val stringValue = value.toString() + + if (preference is ListPreference) { + // For list preferences, look up the correct display value in + // the preference's 'entries' list. + val index = preference.findIndexOfValue(stringValue) + + // Set the summary to reflect the new value. + preference.setSummary( + if (index >= 0) + preference.entries[index] + else + null) + + } else { + // For all other preferences, set the summary to the value's + // simple string representation. + preference.summary = stringValue + } + true + } + + /** + * Helper method to determine if the device has an extra-large screen. For + * example, 10" tablets are extra-large. + */ + private fun isXLargeTablet(context: Context): Boolean { + return context.resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK >= Configuration.SCREENLAYOUT_SIZE_XLARGE + } + + /** + * 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 fun bindPreferenceSummaryToValue(preference: Preference) { + // Set the listener to watch for value changes. + preference.onPreferenceChangeListener = sBindPreferenceSummaryToValueListener + + // Trigger the listener immediately with the preference's + // current value. + try { + sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, + PreferenceManager + .getDefaultSharedPreferences(preference.context) + .getString(preference.key, "")) + } catch (e: ClassCastException) { + sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, + PreferenceManager + .getDefaultSharedPreferences(preference.context) + .getInt(preference.key, 0)) + } + + } + } +} diff --git a/app/src/main/res/drawable-v21/nonphatic_colour_light.png b/app/src/main/res/drawable-v21/nonphatic_colour_light.png deleted file mode 100644 index 06cfbb1..0000000 Binary files a/app/src/main/res/drawable-v21/nonphatic_colour_light.png and /dev/null differ diff --git a/app/src/main/res/drawable/nonphatic.png b/app/src/main/res/drawable/nonphatic.png new file mode 100644 index 0000000..f9cbd03 Binary files /dev/null and b/app/src/main/res/drawable/nonphatic.png differ diff --git a/app/src/main/res/layout/preference_about_dialog.xml b/app/src/main/res/layout/preference_about_dialog.xml index 815038b..c933a47 100644 --- a/app/src/main/res/layout/preference_about_dialog.xml +++ b/app/src/main/res/layout/preference_about_dialog.xml @@ -10,6 +10,6 @@ android:layout_height="wrap_content" android:scaleType="fitStart" android:adjustViewBounds="true" - android:src="@drawable/nonphatic_colour_light"> + android:src="@drawable/nonphatic"> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b9e9fc2..b5a6505 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,24 +1,13 @@ QUOZ - - Dummy Button - DUMMY\nCONTENT Settings - 0.618033988748984848 + + Copied to clipboard. + Settings reset. - - Pastel - Pastel neon - Neon - - - 0.3 - 0.5 - 0.7 - - + change_mode Tap Cycle @@ -31,4 +20,10 @@ leekspin nyan + tap + + saturation + 30 + + reset_button diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 4bfbbad..6333cf8 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -1,22 +1,22 @@ + android:defaultValue="@integer/preferences_colour_default"> + android:key="@string/preferences_reset_key" />