Updated app to use Kotlin!
This commit is contained in:
parent
093d3e7499
commit
3c77b37cd7
|
@ -2,6 +2,7 @@
|
|||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/tasks.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
|
@ -11,3 +12,4 @@ gradle*
|
|||
/gradle
|
||||
/app/build
|
||||
keystore.properties
|
||||
/app/release
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
QUOZ
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="WizardSettings">
|
||||
<option name="children">
|
||||
<map>
|
||||
<entry key="imageWizard">
|
||||
<value>
|
||||
<PersistentState />
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
Binary file not shown.
|
@ -0,0 +1,29 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<Objective-C-extensions>
|
||||
<file>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||
</file>
|
||||
<class>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||
</class>
|
||||
<extensions>
|
||||
<pair source="cpp" header="h" fileNamingConvention="NONE" />
|
||||
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||
</extensions>
|
||||
</Objective-C-extensions>
|
||||
</code_scheme>
|
||||
</component>
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
<entry name="!?*.aj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
|
@ -1,3 +0,0 @@
|
|||
<component name="CopyrightManager">
|
||||
<settings default="" />
|
||||
</component>
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="PROJECT" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
|
@ -1,18 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="NullableNotNullManager">
|
||||
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||
<option name="myNullables">
|
||||
<value>
|
||||
<list size="4">
|
||||
<list size="5">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
|
@ -27,17 +25,7 @@
|
|||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -1,46 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="NullableNotNullManager">
|
||||
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||
<option name="myNullables">
|
||||
<value>
|
||||
<list size="4">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myNotNulls">
|
||||
<value>
|
||||
<list size="4">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
File diff suppressed because it is too large
Load Diff
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package nonphatic.quoz;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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<ImageView>(R.id.nonphatic_logo)
|
||||
nonphaticLogo.setOnLongClickListener {
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.data = Uri.parse("https://github.com/nonphatic")
|
||||
context.startActivity(intent)
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
* <p/>
|
||||
* See <a href="http://developer.android.com/design/patterns/settings.html">
|
||||
* Android Design: Settings</a> for design guidelines and the <a
|
||||
* href="http://developer.android.com/guide/topics/ui/settings.html">Settings
|
||||
* API Guide</a> 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 51 KiB |
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
|
@ -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">
|
||||
</ImageView>
|
||||
</LinearLayout>
|
|
@ -1,24 +1,13 @@
|
|||
<resources>
|
||||
<string name="app_name">QUOZ</string>
|
||||
|
||||
<string name="dummy_button">Dummy Button</string>
|
||||
<string name="dummy_content">DUMMY\nCONTENT</string>
|
||||
<string name="title_activity_settings">Settings</string>
|
||||
|
||||
<string name="phiRecip">0.618033988748984848</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_copied">Copied to clipboard.</string>
|
||||
<string name="toast_reset">Settings reset.</string>
|
||||
|
||||
<!-- Strings related to Settings -->
|
||||
<string-array name="preferences_colour_title">
|
||||
<item>Pastel</item>
|
||||
<item>Pastel neon</item>
|
||||
<item>Neon</item>
|
||||
</string-array>
|
||||
<string-array name="preferences_colour_values">
|
||||
<item>0.3</item>
|
||||
<item>0.5</item>
|
||||
<item>0.7</item>
|
||||
</string-array>
|
||||
|
||||
<string name="preferences_mode_key">change_mode</string>
|
||||
<string-array name="preferences_mode_title">
|
||||
<item>Tap</item>
|
||||
<item>Cycle</item>
|
||||
|
@ -31,4 +20,10 @@
|
|||
<item>leekspin</item>
|
||||
<item>nyan</item>
|
||||
</string-array>
|
||||
<string name="preferences_mode_default">tap</string>
|
||||
|
||||
<string name="preferences_colour_key">saturation</string>
|
||||
<integer name="preferences_colour_default">30</integer>
|
||||
|
||||
<string name="preferences_reset_key">reset_button</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<SeekBarPreference
|
||||
android:key="saturation"
|
||||
android:key="@string/preferences_colour_key"
|
||||
android:title="Saturation"
|
||||
android:summary="Set saturation"
|
||||
android:max="100"
|
||||
android:defaultValue="30">
|
||||
android:defaultValue="@integer/preferences_colour_default">
|
||||
</SeekBarPreference>
|
||||
<ListPreference
|
||||
android:title="Change mode"
|
||||
android:key="change_mode"
|
||||
android:defaultValue="tap"
|
||||
android:key="@string/preferences_mode_key"
|
||||
android:defaultValue="@string/preferences_mode_default"
|
||||
android:entries="@array/preferences_mode_title"
|
||||
android:entryValues="@array/preferences_mode_values">
|
||||
</ListPreference>
|
||||
<Preference
|
||||
android:title="Reset settings"
|
||||
android:key="reset_button" />
|
||||
android:key="@string/preferences_reset_key" />
|
||||
<nonphatic.quoz.preferences.AboutDialogPreference
|
||||
android:title="About"
|
||||
android:key="about"
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
package nonphatic.quoz;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* To work on unit tests, switch the Test Artifact in the Build Variants view.
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() throws Exception {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.2.41'
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.2.0'
|
||||
classpath 'com.android.tools.build:gradle:3.1.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
@ -15,6 +18,7 @@ buildscript {
|
|||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue