Rewrite in Kotlin

This commit is contained in:
Nikola Trubitsyn 2017-10-22 16:37:36 +03:00
parent 122d2e3c2f
commit 46a46c735e
64 changed files with 1072 additions and 2077 deletions

View File

@ -1,14 +1,15 @@
apply plugin: 'com.android.application'
apply plugin: 'android-apt'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
compileSdkVersion 26
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "com.simplemobiletools.calculator"
minSdkVersion 16
targetSdkVersion 25
targetSdkVersion 26
versionCode 12
versionName "1.12"
@ -29,21 +30,17 @@ android {
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.jakewharton:butterknife:8.0.1'
compile 'com.simplemobiletools:commons:2.35.4'
compile 'me.grantland:autofittextview:0.2.1'
compile 'com.github.yukuku:ambilwarna:2.0.1'
apt 'com.jakewharton:butterknife-compiler:8.0.1'
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.3.2'
androidTestCompile 'com.android.support:support-annotations:25.3.1'
androidTestCompile 'com.android.support:support-annotations:26.0.2'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
}
def Properties props = new Properties()
@ -65,3 +62,7 @@ if (propFile.canRead()) {
println 'signing.properties not found'
android.buildTypes.release.signingConfig = null
}
repositories {
mavenCentral()
maven { url "https://jitpack.io" }
}

View File

@ -1,10 +0,0 @@
package com.simplemobiletools.calculator;
import android.app.Application;
import android.test.ApplicationTestCase;
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

View File

@ -0,0 +1,6 @@
package com.simplemobiletools.calculator
import android.app.Application
import android.test.ApplicationTestCase
class ApplicationTest : ApplicationTestCase<Application>(Application::class.java)

View File

@ -28,20 +28,25 @@
</activity>
<activity
android:name=".activities.AboutActivity"
android:name="com.simplemobiletools.commons.activities.AboutActivity"
android:label="@string/about"
android:parentActivityName=".activities.MainActivity"/>
<activity
android:name=".activities.LicenseActivity"
android:name="com.simplemobiletools.commons.activities.LicenseActivity"
android:label="@string/third_party_licences"
android:parentActivityName=".activities.AboutActivity"/>
android:parentActivityName="com.simplemobiletools.commons.activities.AboutActivity"/>
<activity
android:name=".activities.SettingsActivity"
android:label="@string/settings"
android:parentActivityName=".activities.MainActivity"/>
<activity
android:name="com.simplemobiletools.commons.activities.CustomizationActivity"
android:label="@string/customize_colors"
android:parentActivityName=".activities.SettingsActivity"/>
<receiver
android:name=".MyWidgetProvider"
android:icon="@mipmap/widget_preview">

View File

@ -1,9 +0,0 @@
package com.simplemobiletools.calculator;
public interface Calculator {
void setValue(String value);
void setValueDouble(double d);
void setFormula(String value);
}

View File

@ -0,0 +1,9 @@
package com.simplemobiletools.calculator
interface Calculator {
fun setValue(value: String)
fun setValueDouble(d: Double)
fun setFormula(value: String)
}

View File

@ -1,253 +0,0 @@
package com.simplemobiletools.calculator;
import com.simplemobiletools.calculator.operation.OperationFactory;
import com.simplemobiletools.calculator.operation.base.Operation;
public class CalculatorImpl {
private String mDisplayedValue;
private String mDisplayedFormula;
private String mLastKey;
private String mLastOperation;
private Calculator mCallback;
private boolean mIsFirstOperation;
private boolean mResetValue;
private double mBaseValue;
private double mSecondValue;
public CalculatorImpl(Calculator calculator) {
mCallback = calculator;
resetValues();
setValue("0");
setFormula("");
}
public CalculatorImpl(Calculator calculatorInterface, String value) {
mCallback = calculatorInterface;
resetValues();
mDisplayedValue = value;
setFormula("");
}
private void resetValueIfNeeded() {
if (mResetValue)
mDisplayedValue = "0";
mResetValue = false;
}
private void resetValues() {
mBaseValue = 0;
mSecondValue = 0;
mResetValue = false;
mLastKey = "";
mLastOperation = "";
mDisplayedValue = "";
mDisplayedFormula = "";
mIsFirstOperation = true;
}
public void setValue(String value) {
mCallback.setValue(value);
mDisplayedValue = value;
}
private void setFormula(String value) {
mCallback.setFormula(value);
mDisplayedFormula = value;
}
private void updateFormula() {
final String first = Formatter.doubleToString(mBaseValue);
final String second = Formatter.doubleToString(mSecondValue);
final String sign = getSign(mLastOperation);
if (sign.equals("")) {
setFormula(sign + first);
} else if (!sign.isEmpty()) {
setFormula(first + sign + second);
}
}
public void setLastKey(String mLastKey) {
this.mLastKey = mLastKey;
}
public void addDigit(int number) {
final String currentValue = getDisplayedNumber();
final String newValue = formatString(currentValue + number);
setValue(newValue);
}
private String formatString(String str) {
// if the number contains a decimal, do not try removing the leading zero anymore, nor add group separator
// it would prevent writing values like 1.02
if (str.contains("."))
return str;
final double doubleValue = Formatter.stringToDouble(str);
return Formatter.doubleToString(doubleValue);
}
private void updateResult(double value) {
setValue(Formatter.doubleToString(value));
mBaseValue = value;
}
public String getDisplayedNumber() {
return mDisplayedValue;
}
public double getDisplayedNumberAsDouble() {
return Formatter.stringToDouble(getDisplayedNumber());
}
public String getDisplayedFormula() {
return mDisplayedFormula;
}
public void handleResult() {
mSecondValue = getDisplayedNumberAsDouble();
calculateResult();
mBaseValue = getDisplayedNumberAsDouble();
}
public void calculateResult() {
if (!mIsFirstOperation) {
updateFormula();
}
Operation operation = OperationFactory.forId(mLastOperation, mBaseValue, mSecondValue);
if (operation != null) {
updateResult(operation.getResult());
}
mIsFirstOperation = false;
}
public void handleOperation(String operation) {
if (mLastKey.equals(Constants.DIGIT))
handleResult();
mResetValue = true;
mLastKey = operation;
mLastOperation = operation;
if (operation.equals(Constants.ROOT))
calculateResult();
}
public void handleClear() {
final String oldValue = getDisplayedNumber();
String newValue = "0";
final int len = oldValue.length();
int minLen = 1;
if (oldValue.contains("-"))
minLen++;
if (len > minLen)
newValue = oldValue.substring(0, len - 1);
newValue = newValue.replaceAll("\\.$", "");
newValue = formatString(newValue);
setValue(newValue);
mBaseValue = Formatter.stringToDouble(newValue);
}
public void handleReset() {
resetValues();
setValue("0");
setFormula("");
}
public void handleEquals() {
if (mLastKey.equals(Constants.EQUALS))
calculateResult();
if (!mLastKey.equals(Constants.DIGIT))
return;
mSecondValue = getDisplayedNumberAsDouble();
calculateResult();
mLastKey = Constants.EQUALS;
}
public void decimalClicked() {
String value = getDisplayedNumber();
if (!value.contains("."))
value += ".";
setValue(value);
}
public void zeroClicked() {
String value = getDisplayedNumber();
if (!value.equals("0"))
addDigit(0);
}
private String getSign(String lastOperation) {
switch (lastOperation) {
case Constants.PLUS:
return "+";
case Constants.MINUS:
return "-";
case Constants.MULTIPLY:
return "*";
case Constants.DIVIDE:
return "/";
case Constants.MODULO:
return "%";
case Constants.POWER:
return "^";
case Constants.ROOT:
return "";
}
return "";
}
public void numpadClicked(int id) {
if (mLastKey.equals(Constants.EQUALS))
mLastOperation = Constants.EQUALS;
mLastKey = Constants.DIGIT;
resetValueIfNeeded();
switch (id) {
case R.id.btn_decimal:
decimalClicked();
break;
case R.id.btn_0:
zeroClicked();
break;
case R.id.btn_1:
addDigit(1);
break;
case R.id.btn_2:
addDigit(2);
break;
case R.id.btn_3:
addDigit(3);
break;
case R.id.btn_4:
addDigit(4);
break;
case R.id.btn_5:
addDigit(5);
break;
case R.id.btn_6:
addDigit(6);
break;
case R.id.btn_7:
addDigit(7);
break;
case R.id.btn_8:
addDigit(8);
break;
case R.id.btn_9:
addDigit(9);
break;
default:
break;
}
}
}

View File

@ -0,0 +1,212 @@
package com.simplemobiletools.calculator
import com.simplemobiletools.calculator.operation.OperationFactory
class CalculatorImpl {
var displayedNumber: String? = null
var displayedFormula: String? = null
private var mLastKey: String? = null
private var mLastOperation: String? = null
private var mCallback: Calculator? = null
private var mIsFirstOperation = false
private var mResetValue = false
private var mBaseValue = 0.0
private var mSecondValue = 0.0
constructor(calculator: Calculator) {
mCallback = calculator
resetValues()
setValue("0")
setFormula("")
}
constructor(calculatorInterface: Calculator, value: String) {
mCallback = calculatorInterface
resetValues()
displayedNumber = value
setFormula("")
}
private fun resetValueIfNeeded() {
if (mResetValue)
displayedNumber = "0"
mResetValue = false
}
private fun resetValues() {
mBaseValue = 0.0
mSecondValue = 0.0
mResetValue = false
mLastKey = ""
mLastOperation = ""
displayedNumber = ""
displayedFormula = ""
mIsFirstOperation = true
}
fun setValue(value: String) {
mCallback!!.setValue(value)
displayedNumber = value
}
private fun setFormula(value: String) {
mCallback!!.setFormula(value)
displayedFormula = value
}
private fun updateFormula() {
val first = Formatter.doubleToString(mBaseValue)
val second = Formatter.doubleToString(mSecondValue)
val sign = getSign(mLastOperation)
if (sign == "") {
setFormula(sign + first)
} else if (!sign.isEmpty()) {
setFormula(first + sign + second)
}
}
fun setLastKey(mLastKey: String) {
this.mLastKey = mLastKey
}
fun addDigit(number: Int) {
val currentValue = displayedNumber
val newValue = formatString(currentValue!! + number)
setValue(newValue)
}
private fun formatString(str: String): String {
// if the number contains a decimal, do not try removing the leading zero anymore, nor add group separator
// it would prevent writing values like 1.02
if (str.contains("."))
return str
val doubleValue = Formatter.stringToDouble(str)
return Formatter.doubleToString(doubleValue)
}
private fun updateResult(value: Double) {
setValue(Formatter.doubleToString(value))
mBaseValue = value
}
val displayedNumberAsDouble: Double
get() = Formatter.stringToDouble(displayedNumber!!)
fun handleResult() {
mSecondValue = displayedNumberAsDouble
calculateResult()
mBaseValue = displayedNumberAsDouble
}
fun calculateResult() {
if (!mIsFirstOperation) {
updateFormula()
}
val operation = OperationFactory.forId(mLastOperation!!, mBaseValue, mSecondValue)
if (operation != null) {
updateResult(operation.getResult())
}
mIsFirstOperation = false
}
fun handleOperation(operation: String) {
if (mLastKey == DIGIT)
handleResult()
mResetValue = true
mLastKey = operation
mLastOperation = operation
if (operation == ROOT)
calculateResult()
}
fun handleClear() {
val oldValue = displayedNumber
var newValue = "0"
val len = oldValue!!.length
var minLen = 1
if (oldValue.contains("-"))
minLen++
if (len > minLen)
newValue = oldValue.substring(0, len - 1)
newValue = newValue.replace("\\.$".toRegex(), "")
newValue = formatString(newValue)
setValue(newValue)
mBaseValue = Formatter.stringToDouble(newValue)
}
fun handleReset() {
resetValues()
setValue("0")
setFormula("")
}
fun handleEquals() {
if (mLastKey == EQUALS)
calculateResult()
if (mLastKey != DIGIT)
return
mSecondValue = displayedNumberAsDouble
calculateResult()
mLastKey = EQUALS
}
fun decimalClicked() {
var value = displayedNumber
if (!value!!.contains("."))
value += "."
setValue(value)
}
fun zeroClicked() {
val value = displayedNumber
if (value != "0")
addDigit(0)
}
private fun getSign(lastOperation: String?): String {
return when (lastOperation) {
PLUS -> "+"
MINUS -> "-"
MULTIPLY -> "*"
DIVIDE -> "/"
MODULO -> "%"
POWER -> "^"
ROOT -> ""
else -> ""
}
}
fun numpadClicked(id: Int) {
if (mLastKey == EQUALS)
mLastOperation = EQUALS
mLastKey = DIGIT
resetValueIfNeeded()
when (id) {
R.id.btn_decimal -> decimalClicked()
R.id.btn_0 -> zeroClicked()
R.id.btn_1 -> addDigit(1)
R.id.btn_2 -> addDigit(2)
R.id.btn_3 -> addDigit(3)
R.id.btn_4 -> addDigit(4)
R.id.btn_5 -> addDigit(5)
R.id.btn_6 -> addDigit(6)
R.id.btn_7 -> addDigit(7)
R.id.btn_8 -> addDigit(8)
R.id.btn_9 -> addDigit(9)
}
}
}

View File

@ -1,32 +0,0 @@
package com.simplemobiletools.calculator;
import android.content.Context;
import android.content.SharedPreferences;
public class Config {
private SharedPreferences mPrefs;
public static Config newInstance(Context context) {
return new Config(context);
}
public Config(Context context) {
mPrefs = context.getSharedPreferences(Constants.PREFS_KEY, Context.MODE_PRIVATE);
}
public boolean getIsFirstRun() {
return mPrefs.getBoolean(Constants.IS_FIRST_RUN, true);
}
public void setIsFirstRun(boolean firstRun) {
mPrefs.edit().putBoolean(Constants.IS_FIRST_RUN, firstRun).apply();
}
public boolean getIsDarkTheme() {
return mPrefs.getBoolean(Constants.IS_DARK_THEME, false);
}
public void setIsDarkTheme(boolean isDarkTheme) {
mPrefs.edit().putBoolean(Constants.IS_DARK_THEME, isDarkTheme).apply();
}
}

View File

@ -1,34 +0,0 @@
package com.simplemobiletools.calculator;
public class Constants {
public static final String DIGIT = "digit";
public static final String EQUALS = "equals";
public static final String PLUS = "plus";
public static final String MINUS = "minus";
public static final String MULTIPLY = "multiply";
public static final String DIVIDE = "divide";
public static final String MODULO = "modulo";
public static final String POWER = "power";
public static final String ROOT = "root";
public static final String DECIMAL = "decimal";
public static final String CLEAR = "clear";
public static final String RESET = "reset";
public static final String ZERO = "zero";
public static final String ONE = "one";
public static final String TWO = "two";
public static final String THREE = "three";
public static final String FOUR = "four";
public static final String FIVE = "five";
public static final String SIX = "six";
public static final String SEVEN = "seven";
public static final String EIGHT = "eight";
public static final String NINE = "nine";
// shared preferences
public static final String PREFS_KEY = "Calculator";
public static final String IS_FIRST_RUN = "is_first_run";
public static final String IS_DARK_THEME = "is_dark_theme";
public static final String WIDGET_BG_COLOR = "widget_bg_color";
public static final String WIDGET_TEXT_COLOR = "widget_text_color";
}

View File

@ -0,0 +1,32 @@
package com.simplemobiletools.calculator
val DIGIT = "digit"
val EQUALS = "equals"
val PLUS = "plus"
val MINUS = "minus"
val MULTIPLY = "multiply"
val DIVIDE = "divide"
val MODULO = "modulo"
val POWER = "power"
val ROOT = "root"
val DECIMAL = "decimal"
val CLEAR = "clear"
val RESET = "reset"
val ZERO = "zero"
val ONE = "one"
val TWO = "two"
val THREE = "three"
val FOUR = "four"
val FIVE = "five"
val SIX = "six"
val SEVEN = "seven"
val EIGHT = "eight"
val NINE = "nine"
// shared preferences
val PREFS_KEY = "Calculator"
val IS_FIRST_RUN = "is_first_run"
val IS_DARK_THEME = "is_dark_theme"
val WIDGET_BG_COLOR = "widget_bg_color"
val WIDGET_TEXT_COLOR = "widget_text_color"

View File

@ -1,24 +0,0 @@
package com.simplemobiletools.calculator;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
public class Formatter {
public static String doubleToString(double d) {
final DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US);
symbols.setDecimalSeparator('.');
symbols.setGroupingSeparator(',');
final DecimalFormat formatter = new DecimalFormat();
formatter.setMaximumFractionDigits(12);
formatter.setDecimalFormatSymbols(symbols);
formatter.setGroupingUsed(true);
return formatter.format(d);
}
public static Double stringToDouble(String str) {
str = str.replaceAll(",", "");
return Double.parseDouble(str);
}
}

View File

@ -0,0 +1,23 @@
package com.simplemobiletools.calculator
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import java.util.*
object Formatter {
fun doubleToString(d: Double): String {
val symbols = DecimalFormatSymbols(Locale.US)
symbols.decimalSeparator = '.'
symbols.groupingSeparator = ','
val formatter = DecimalFormat()
formatter.maximumFractionDigits = 12
formatter.decimalFormatSymbols = symbols
formatter.isGroupingUsed = true
return formatter.format(d)
}
fun stringToDouble(str: String): Double {
return str.replace(",".toRegex(), "").toDouble()
}
}

View File

@ -1,235 +0,0 @@
package com.simplemobiletools.calculator;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.view.View;
import android.widget.RemoteViews;
import com.simplemobiletools.calculator.activities.MainActivity;
public class MyWidgetProvider extends AppWidgetProvider implements Calculator {
private static RemoteViews mRemoteViews;
private static CalculatorImpl mCalc;
private static AppWidgetManager mWidgetManager;
private static Intent mIntent;
private static Context mContext;
private static SharedPreferences mPrefs;
private static int[] mWidgetIds;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
initVariables(context);
mIntent = new Intent(context, MyWidgetProvider.class);
setupIntent(Constants.DECIMAL, R.id.btn_decimal);
setupIntent(Constants.ZERO, R.id.btn_0);
setupIntent(Constants.ONE, R.id.btn_1);
setupIntent(Constants.TWO, R.id.btn_2);
setupIntent(Constants.THREE, R.id.btn_3);
setupIntent(Constants.FOUR, R.id.btn_4);
setupIntent(Constants.FIVE, R.id.btn_5);
setupIntent(Constants.SIX, R.id.btn_6);
setupIntent(Constants.SEVEN, R.id.btn_7);
setupIntent(Constants.EIGHT, R.id.btn_8);
setupIntent(Constants.NINE, R.id.btn_9);
setupIntent(Constants.EQUALS, R.id.btn_equals);
setupIntent(Constants.PLUS, R.id.btn_plus);
setupIntent(Constants.MINUS, R.id.btn_minus);
setupIntent(Constants.MULTIPLY, R.id.btn_multiply);
setupIntent(Constants.DIVIDE, R.id.btn_divide);
setupIntent(Constants.MODULO, R.id.btn_modulo);
setupIntent(Constants.POWER, R.id.btn_power);
setupIntent(Constants.ROOT, R.id.btn_root);
setupIntent(Constants.CLEAR, R.id.btn_clear);
setupIntent(Constants.RESET, R.id.btn_reset);
setupAppOpenIntent(R.id.formula);
setupAppOpenIntent(R.id.result);
updateWidget();
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
private void setupIntent(String action, int id) {
mIntent.setAction(action);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, mIntent, 0);
mRemoteViews.setOnClickPendingIntent(id, pendingIntent);
}
private void setupAppOpenIntent(int id) {
final Intent intent = new Intent(mContext, MainActivity.class);
final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
mRemoteViews.setOnClickPendingIntent(id, pendingIntent);
}
private void initVariables(Context context) {
mContext = context;
updateWidgetIds();
mPrefs = initPrefs(mContext);
final int defaultColor = mContext.getResources().getColor(R.color.text_grey);
final int newBgColor = mPrefs.getInt(Constants.WIDGET_BG_COLOR, defaultColor);
final int newTextColor = mPrefs.getInt(Constants.WIDGET_TEXT_COLOR, Color.WHITE);
mRemoteViews = new RemoteViews(mContext.getPackageName(), R.layout.activity_main);
mRemoteViews.setViewVisibility(R.id.btn_reset, View.VISIBLE);
mRemoteViews.setInt(R.id.calculator_holder, "setBackgroundColor", newBgColor);
updateTextColors(newTextColor);
mWidgetManager = AppWidgetManager.getInstance(mContext);
final String displayValue = "0";
mCalc = new CalculatorImpl(this, displayValue);
}
private void updateWidgetIds() {
final ComponentName component = new ComponentName(mContext, MyWidgetProvider.class);
mWidgetManager = AppWidgetManager.getInstance(mContext);
mWidgetIds = mWidgetManager.getAppWidgetIds(component);
}
private void updateWidget() {
for (int widgetId : mWidgetIds) {
mWidgetManager.updateAppWidget(widgetId, mRemoteViews);
}
}
private SharedPreferences initPrefs(Context context) {
return context.getSharedPreferences(Constants.PREFS_KEY, Context.MODE_PRIVATE);
}
private void updateTextColors(int color) {
final int[] viewIds =
new int[]{R.id.formula, R.id.result, R.id.btn_0, R.id.btn_1, R.id.btn_2, R.id.btn_3, R.id.btn_4, R.id.btn_5, R.id.btn_6,
R.id.btn_7, R.id.btn_8, R.id.btn_9, R.id.btn_modulo, R.id.btn_power, R.id.btn_root, R.id.btn_clear, R.id.btn_reset,
R.id.btn_divide, R.id.btn_multiply, R.id.btn_minus, R.id.btn_plus, R.id.btn_decimal, R.id.btn_equals};
for (int i : viewIds) {
mRemoteViews.setInt(i, "setTextColor", color);
}
}
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
switch (action) {
case Constants.DECIMAL:
case Constants.ZERO:
case Constants.ONE:
case Constants.TWO:
case Constants.THREE:
case Constants.FOUR:
case Constants.FIVE:
case Constants.SIX:
case Constants.SEVEN:
case Constants.EIGHT:
case Constants.NINE:
case Constants.EQUALS:
case Constants.CLEAR:
case Constants.RESET:
case Constants.PLUS:
case Constants.MINUS:
case Constants.MULTIPLY:
case Constants.DIVIDE:
case Constants.MODULO:
case Constants.POWER:
case Constants.ROOT:
myAction(action, context);
break;
default:
super.onReceive(context, intent);
}
}
private void myAction(String action, Context context) {
if (mCalc == null || mRemoteViews == null || mWidgetManager == null || mPrefs == null || mContext == null) {
initVariables(context);
}
switch (action) {
case Constants.DECIMAL:
mCalc.numpadClicked(R.id.btn_decimal);
break;
case Constants.ZERO:
mCalc.numpadClicked(R.id.btn_0);
break;
case Constants.ONE:
mCalc.numpadClicked(R.id.btn_1);
break;
case Constants.TWO:
mCalc.numpadClicked(R.id.btn_2);
break;
case Constants.THREE:
mCalc.numpadClicked(R.id.btn_3);
break;
case Constants.FOUR:
mCalc.numpadClicked(R.id.btn_4);
break;
case Constants.FIVE:
mCalc.numpadClicked(R.id.btn_5);
break;
case Constants.SIX:
mCalc.numpadClicked(R.id.btn_6);
break;
case Constants.SEVEN:
mCalc.numpadClicked(R.id.btn_7);
break;
case Constants.EIGHT:
mCalc.numpadClicked(R.id.btn_8);
break;
case Constants.NINE:
mCalc.numpadClicked(R.id.btn_9);
break;
case Constants.EQUALS:
mCalc.handleEquals();
break;
case Constants.CLEAR:
mCalc.handleClear();
break;
case Constants.RESET:
mCalc.handleReset();
break;
case Constants.PLUS:
case Constants.MINUS:
case Constants.MULTIPLY:
case Constants.DIVIDE:
case Constants.MODULO:
case Constants.POWER:
case Constants.ROOT:
mCalc.handleOperation(action);
break;
default:
break;
}
}
@Override
public void setValue(String value) {
mRemoteViews.setTextViewText(R.id.result, value);
updateWidget();
}
@Override
public void setValueDouble(double d) {
}
public void setFormula(String value) {
mRemoteViews.setTextViewText(R.id.formula, value);
updateWidget();
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
if (mContext != null)
updateWidgetIds();
}
}

View File

@ -0,0 +1,171 @@
package com.simplemobiletools.calculator
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Color
import android.view.View
import android.widget.RemoteViews
import com.simplemobiletools.calculator.activities.MainActivity
class MyWidgetProvider : AppWidgetProvider(), Calculator {
companion object {
private var mRemoteViews: RemoteViews? = null
private var mCalc: CalculatorImpl? = null
private var mWidgetManager: AppWidgetManager? = null
private var mIntent: Intent? = null
private var mContext: Context? = null
private var mPrefs: SharedPreferences? = null
private var mWidgetIds: IntArray? = null
}
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
initVariables(context)
mIntent = Intent(context, MyWidgetProvider::class.java)
setupIntent(DECIMAL, R.id.btn_decimal)
setupIntent(ZERO, R.id.btn_0)
setupIntent(ONE, R.id.btn_1)
setupIntent(TWO, R.id.btn_2)
setupIntent(THREE, R.id.btn_3)
setupIntent(FOUR, R.id.btn_4)
setupIntent(FIVE, R.id.btn_5)
setupIntent(SIX, R.id.btn_6)
setupIntent(SEVEN, R.id.btn_7)
setupIntent(EIGHT, R.id.btn_8)
setupIntent(NINE, R.id.btn_9)
setupIntent(EQUALS, R.id.btn_equals)
setupIntent(PLUS, R.id.btn_plus)
setupIntent(MINUS, R.id.btn_minus)
setupIntent(MULTIPLY, R.id.btn_multiply)
setupIntent(DIVIDE, R.id.btn_divide)
setupIntent(MODULO, R.id.btn_modulo)
setupIntent(POWER, R.id.btn_power)
setupIntent(ROOT, R.id.btn_root)
setupIntent(CLEAR, R.id.btn_clear)
setupIntent(RESET, R.id.btn_reset)
setupAppOpenIntent(R.id.formula)
setupAppOpenIntent(R.id.result)
updateWidget()
super.onUpdate(context, appWidgetManager, appWidgetIds)
}
private fun setupIntent(action: String, id: Int) {
mIntent!!.action = action
val pendingIntent = PendingIntent.getBroadcast(mContext, 0, mIntent, 0)
mRemoteViews!!.setOnClickPendingIntent(id, pendingIntent)
}
private fun setupAppOpenIntent(id: Int) {
val intent = Intent(mContext, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0)
mRemoteViews!!.setOnClickPendingIntent(id, pendingIntent)
}
private fun initVariables(context: Context) {
mContext = context
updateWidgetIds()
mPrefs = initPrefs(mContext)
val defaultColor = mContext!!.resources.getColor(R.color.text_grey)
val newBgColor = mPrefs!!.getInt(WIDGET_BG_COLOR, defaultColor)
val newTextColor = mPrefs!!.getInt(WIDGET_TEXT_COLOR, Color.WHITE)
mRemoteViews = RemoteViews(mContext!!.packageName, R.layout.activity_main)
mRemoteViews!!.setViewVisibility(R.id.btn_reset, View.VISIBLE)
mRemoteViews!!.setInt(R.id.calculator_holder, "setBackgroundColor", newBgColor)
updateTextColors(newTextColor)
mWidgetManager = AppWidgetManager.getInstance(mContext)
val displayValue = "0"
mCalc = CalculatorImpl(this, displayValue)
}
private fun updateWidgetIds() {
val component = ComponentName(mContext!!, MyWidgetProvider::class.java)
mWidgetManager = AppWidgetManager.getInstance(mContext)
mWidgetIds = mWidgetManager!!.getAppWidgetIds(component)
}
private fun updateWidget() {
for (widgetId in mWidgetIds!!) {
mWidgetManager!!.updateAppWidget(widgetId, mRemoteViews)
}
}
private fun initPrefs(context: Context?): SharedPreferences {
return context!!.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
}
private fun updateTextColors(color: Int) {
val viewIds = intArrayOf(R.id.formula, R.id.result, R.id.btn_0, R.id.btn_1, R.id.btn_2, R.id.btn_3, R.id.btn_4, R.id.btn_5, R.id.btn_6, R.id.btn_7, R.id.btn_8, R.id.btn_9, R.id.btn_modulo, R.id.btn_power, R.id.btn_root, R.id.btn_clear, R.id.btn_reset, R.id.btn_divide, R.id.btn_multiply, R.id.btn_minus, R.id.btn_plus, R.id.btn_decimal, R.id.btn_equals)
for (i in viewIds) {
mRemoteViews!!.setInt(i, "setTextColor", color)
}
}
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
when (action) {
DECIMAL, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, EQUALS, CLEAR, RESET, PLUS, MINUS, MULTIPLY, DIVIDE, MODULO, POWER, ROOT -> myAction(action, context)
else -> super.onReceive(context, intent)
}
}
private fun myAction(action: String, context: Context) {
if (mCalc == null || mRemoteViews == null || mWidgetManager == null || mPrefs == null || mContext == null) {
initVariables(context)
}
when (action) {
DECIMAL -> mCalc!!.numpadClicked(R.id.btn_decimal)
ZERO -> mCalc!!.numpadClicked(R.id.btn_0)
ONE -> mCalc!!.numpadClicked(R.id.btn_1)
TWO -> mCalc!!.numpadClicked(R.id.btn_2)
THREE -> mCalc!!.numpadClicked(R.id.btn_3)
FOUR -> mCalc!!.numpadClicked(R.id.btn_4)
FIVE -> mCalc!!.numpadClicked(R.id.btn_5)
SIX -> mCalc!!.numpadClicked(R.id.btn_6)
SEVEN -> mCalc!!.numpadClicked(R.id.btn_7)
EIGHT -> mCalc!!.numpadClicked(R.id.btn_8)
NINE -> mCalc!!.numpadClicked(R.id.btn_9)
EQUALS -> mCalc!!.handleEquals()
CLEAR -> mCalc!!.handleClear()
RESET -> mCalc!!.handleReset()
PLUS, MINUS, MULTIPLY, DIVIDE, MODULO, POWER, ROOT -> mCalc!!.handleOperation(action)
else -> {
}
}
}
override fun setValue(value: String) {
mRemoteViews!!.setTextViewText(R.id.result, value)
updateWidget()
}
override fun setValueDouble(d: Double) {
}
override fun setFormula(value: String) {
mRemoteViews!!.setTextViewText(R.id.formula, value)
updateWidget()
}
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
super.onDeleted(context, appWidgetIds)
if (mContext != null)
updateWidgetIds()
}
}

View File

@ -1,10 +0,0 @@
package com.simplemobiletools.calculator;
import android.content.Context;
import android.widget.Toast;
public class Utils {
public static void showToast(Context context, int resId) {
Toast.makeText(context, context.getResources().getString(resId), Toast.LENGTH_SHORT).show();
}
}

View File

@ -1,110 +0,0 @@
package com.simplemobiletools.calculator.activities;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.widget.TextView;
import com.simplemobiletools.calculator.BuildConfig;
import com.simplemobiletools.calculator.Config;
import com.simplemobiletools.calculator.R;
import java.util.Calendar;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class AboutActivity extends SimpleActivity {
@BindView(R.id.about_copyright) TextView mCopyright;
@BindView(R.id.about_email) TextView mEmailTV;
@BindView(R.id.about_rate_us) View mRateUs;
private static Resources mRes;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
ButterKnife.bind(this);
mRes = getResources();
setupEmail();
setupCopyright();
setupRateUs();
}
private void setupEmail() {
final String email = mRes.getString(R.string.email);
final String appName = mRes.getString(R.string.app_name);
final String href = "<a href=\"mailto:" + email + "?subject=" + appName + "\">" + email + "</a>";
mEmailTV.setText(Html.fromHtml(href));
mEmailTV.setMovementMethod(LinkMovementMethod.getInstance());
}
private void setupCopyright() {
final String versionName = BuildConfig.VERSION_NAME;
final int year = Calendar.getInstance().get(Calendar.YEAR);
final String copyrightText = String.format(mRes.getString(R.string.copyright), versionName, year);
mCopyright.setText(copyrightText);
}
private void setupRateUs() {
if (Config.newInstance(getApplicationContext()).getIsFirstRun()) {
mRateUs.setVisibility(View.GONE);
}
}
@OnClick(R.id.about_invite)
public void inviteFriend() {
final Intent intent = new Intent();
final String text = String.format(getString(R.string.share_text), getString(R.string.app_name), getStoreUrl());
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name));
intent.putExtra(Intent.EXTRA_TEXT, text);
intent.setType("text/plain");
startActivity(Intent.createChooser(intent, getString(R.string.invite_via)));
}
@OnClick(R.id.about_rate_us)
public void rateUsClicked() {
final Uri uri = Uri.parse("market://details?id=" + getPackageName());
try {
startActivity(new Intent(Intent.ACTION_VIEW, uri));
} catch (ActivityNotFoundException ignored) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getStoreUrl())));
}
}
@OnClick(R.id.about_license)
public void licenseClicked() {
final Intent intent = new Intent(getApplicationContext(), LicenseActivity.class);
startActivity(intent);
}
@OnClick(R.id.about_facebook)
public void facebookClicked() {
String link = "https://www.facebook.com/simplemobiletools";
try {
getPackageManager().getPackageInfo("com.facebook.katana", 0);
link = "fb://page/150270895341774";
} catch (Exception ignored) {
}
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(link)));
}
@OnClick(R.id.about_gplus)
public void googlePlusClicked() {
final String link = "https://plus.google.com/communities/104880861558693868382";
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(link)));
}
private String getStoreUrl() {
return "https://play.google.com/store/apps/details?id=" + getPackageName();
}
}

View File

@ -1,51 +0,0 @@
package com.simplemobiletools.calculator.activities;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import com.simplemobiletools.calculator.R;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class LicenseActivity extends SimpleActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_license);
ButterKnife.bind(this);
}
@OnClick(R.id.license_butterknife_title)
public void butterKnifeClicked() {
openUrl(R.string.butterknife_url);
}
@OnClick(R.id.license_ambilwarna_title)
public void ambilwarnaClicked() {
openUrl(R.string.ambilwarna_url);
}
@OnClick(R.id.license_autofittextview_title)
public void autofittextviewClicked() {
openUrl(R.string.autofittextview_url);
}
@OnClick(R.id.license_robolectric_title)
public void robolectricClicked() {
openUrl(R.string.robolectric_url);
}
@OnClick(R.id.license_espresso_title)
public void espressoClicked() {
openUrl(R.string.espresso_url);
}
private void openUrl(int id) {
final String url = getResources().getString(id);
final Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
}
}

View File

@ -1,175 +0,0 @@
package com.simplemobiletools.calculator.activities;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.simplemobiletools.calculator.Calculator;
import com.simplemobiletools.calculator.CalculatorImpl;
import com.simplemobiletools.calculator.Config;
import com.simplemobiletools.calculator.Constants;
import com.simplemobiletools.calculator.Formatter;
import com.simplemobiletools.calculator.R;
import com.simplemobiletools.calculator.Utils;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnLongClick;
import me.grantland.widget.AutofitHelper;
public class MainActivity extends SimpleActivity implements Calculator {
@BindView(R.id.result) TextView mResult;
@BindView(R.id.formula) TextView mFormula;
private static CalculatorImpl mCalc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mCalc = new CalculatorImpl(this);
AutofitHelper.create(mResult);
AutofitHelper.create(mFormula);
}
@Override
protected void onDestroy() {
super.onDestroy();
Config.newInstance(getApplicationContext()).setIsFirstRun(false);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
return true;
case R.id.about:
startActivity(new Intent(getApplicationContext(), AboutActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@OnClick(R.id.btn_plus)
public void plusClicked() {
mCalc.handleOperation(Constants.PLUS);
}
@OnClick(R.id.btn_minus)
public void minusClicked() {
mCalc.handleOperation(Constants.MINUS);
}
@OnClick(R.id.btn_multiply)
public void multiplyClicked() {
mCalc.handleOperation(Constants.MULTIPLY);
}
@OnClick(R.id.btn_divide)
public void divideClicked() {
mCalc.handleOperation(Constants.DIVIDE);
}
@OnClick(R.id.btn_modulo)
public void moduloClicked() {
mCalc.handleOperation(Constants.MODULO);
}
@OnClick(R.id.btn_power)
public void powerClicked() {
mCalc.handleOperation(Constants.POWER);
}
@OnClick(R.id.btn_root)
public void rootClicked() {
mCalc.handleOperation(Constants.ROOT);
}
@OnClick(R.id.btn_clear)
public void clearClicked() {
mCalc.handleClear();
}
@OnLongClick(R.id.btn_clear)
public boolean clearLongClicked() {
mCalc.handleReset();
return true;
}
@OnClick(R.id.btn_equals)
public void equalsClicked() {
mCalc.handleEquals();
}
@OnClick({R.id.btn_decimal, R.id.btn_0, R.id.btn_1, R.id.btn_2, R.id.btn_3, R.id.btn_4, R.id.btn_5, R.id.btn_6, R.id.btn_7, R.id.btn_8,
R.id.btn_9})
public void numpadClick(View view) {
numpadClicked(view.getId());
}
public void numpadClicked(int id) {
mCalc.numpadClicked(id);
}
@OnLongClick(R.id.formula)
public boolean formulaLongPressed() {
return copyToClipboard(false);
}
@OnLongClick(R.id.result)
public boolean resultLongPressed() {
return copyToClipboard(true);
}
private boolean copyToClipboard(boolean copyResult) {
String value = mFormula.getText().toString().trim();
if (copyResult) {
value = mResult.getText().toString().trim();
}
if (value.isEmpty())
return false;
final ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
final ClipData clip = ClipData.newPlainText(getResources().getString(R.string.app_name), value);
clipboard.setPrimaryClip(clip);
Utils.showToast(getApplicationContext(), R.string.copied_to_clipboard);
return true;
}
@Override
public void setValue(String value) {
mResult.setText(value);
}
// used only by Robolectric
@Override
public void setValueDouble(double d) {
mCalc.setValue(Formatter.doubleToString(d));
mCalc.setLastKey(Constants.DIGIT);
}
public void setFormula(String value) {
mFormula.setText(value);
}
public CalculatorImpl getCalc() {
return mCalc;
}
}

View File

@ -0,0 +1,101 @@
package com.simplemobiletools.calculator.activities
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import com.simplemobiletools.calculator.*
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.extensions.value
import com.simplemobiletools.commons.helpers.LICENSE_AUTOFITTEXTVIEW
import com.simplemobiletools.commons.helpers.LICENSE_ESPRESSO
import com.simplemobiletools.commons.helpers.LICENSE_KOTLIN
import com.simplemobiletools.commons.helpers.LICENSE_ROBOLECTRIC
import kotlinx.android.synthetic.main.activity_main.*
import me.grantland.widget.AutofitHelper
class MainActivity : SimpleActivity(), Calculator {
companion object {
private lateinit var mCalc: CalculatorImpl
}
val calc: CalculatorImpl?
get() = mCalc
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_plus.setOnClickListener { mCalc.handleOperation(PLUS) }
btn_minus.setOnClickListener { mCalc.handleOperation(MINUS) }
btn_multiply.setOnClickListener { mCalc.handleOperation(MULTIPLY) }
btn_divide.setOnClickListener { mCalc.handleOperation(DIVIDE) }
btn_modulo.setOnClickListener { mCalc.handleOperation(MODULO) }
btn_power.setOnClickListener { mCalc.handleOperation(POWER) }
btn_root.setOnClickListener { mCalc.handleOperation(ROOT) }
btn_clear.setOnClickListener { mCalc.handleClear() }
btn_clear.setOnLongClickListener { mCalc.handleReset(); true }
arrayOf(btn_decimal, btn_0, btn_1, btn_2, btn_3, btn_4, btn_5, btn_6, btn_7, btn_8, btn_9).forEach {
it.setOnClickListener { mCalc.numpadClicked(it.id) }
}
btn_equals.setOnClickListener { mCalc.handleEquals() }
formula.setOnLongClickListener { copyToClipboard(false) }
result.setOnLongClickListener { copyToClipboard(true) }
mCalc = CalculatorImpl(this)
AutofitHelper.create(result)
AutofitHelper.create(formula)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.settings -> startActivity(Intent(applicationContext, SettingsActivity::class.java))
R.id.about -> startAboutActivity(R.string.app_name, LICENSE_KOTLIN or LICENSE_AUTOFITTEXTVIEW or LICENSE_ROBOLECTRIC or LICENSE_ESPRESSO, BuildConfig.VERSION_NAME)
else -> return super.onOptionsItemSelected(item)
}
return true
}
private fun copyToClipboard(copyResult: Boolean): Boolean {
var value = formula.value
if (copyResult) {
value = result.value
}
if (value.isEmpty())
return false
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText(resources.getString(R.string.app_name), value)
clipboard.primaryClip = clip
toast(R.string.copied_to_clipboard)
return true
}
override fun setValue(value: String) {
result.text = value
}
// used only by Robolectric
override fun setValueDouble(d: Double) {
mCalc.setValue(Formatter.doubleToString(d))
mCalc.setLastKey(DIGIT)
}
override fun setFormula(value: String) {
formula.text = value
}
}

View File

@ -1,43 +0,0 @@
package com.simplemobiletools.calculator.activities;
import android.os.Bundle;
import android.support.v4.app.TaskStackBuilder;
import android.support.v7.widget.SwitchCompat;
import com.simplemobiletools.calculator.Config;
import com.simplemobiletools.calculator.R;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class SettingsActivity extends SimpleActivity {
@BindView(R.id.settings_dark_theme) SwitchCompat mDarkThemeSwitch;
private static Config mConfig;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
mConfig = Config.newInstance(getApplicationContext());
ButterKnife.bind(this);
setupDarkTheme();
}
private void setupDarkTheme() {
mDarkThemeSwitch.setChecked(mConfig.getIsDarkTheme());
}
@OnClick(R.id.settings_dark_theme_holder)
public void handleDarkTheme() {
mDarkThemeSwitch.setChecked(!mDarkThemeSwitch.isChecked());
mConfig.setIsDarkTheme(mDarkThemeSwitch.isChecked());
restartActivity();
}
private void restartActivity() {
TaskStackBuilder.create(getApplicationContext()).addNextIntentWithParentStack(getIntent()).startActivities();
}
}

View File

@ -0,0 +1,21 @@
package com.simplemobiletools.calculator.activities
import android.os.Bundle
import com.simplemobiletools.calculator.R
import kotlinx.android.synthetic.main.activity_settings.*
class SettingsActivity : SimpleActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)
setupCustomizeColors()
}
private fun setupCustomizeColors() {
settings_customize_colors_holder.setOnClickListener {
startCustomizationActivity()
}
}
}

View File

@ -1,31 +0,0 @@
package com.simplemobiletools.calculator.activities;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import com.simplemobiletools.calculator.Config;
import com.simplemobiletools.calculator.R;
public class SimpleActivity extends AppCompatActivity {
protected Config mConfig;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mConfig = Config.newInstance(getApplicationContext());
setTheme(mConfig.getIsDarkTheme() ? R.style.AppTheme_Dark : R.style.AppTheme);
super.onCreate(savedInstanceState);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}

View File

@ -0,0 +1,5 @@
package com.simplemobiletools.calculator.activities
import com.simplemobiletools.commons.activities.BaseSimpleActivity
open class SimpleActivity : BaseSimpleActivity()

View File

@ -1,193 +0,0 @@
package com.simplemobiletools.calculator.activities;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.RemoteViews;
import android.widget.SeekBar;
import android.widget.TextView;
import com.simplemobiletools.calculator.Constants;
import com.simplemobiletools.calculator.MyWidgetProvider;
import com.simplemobiletools.calculator.R;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import yuku.ambilwarna.AmbilWarnaDialog;
public class WidgetConfigureActivity extends AppCompatActivity {
@BindView(R.id.btn_reset) View mResetBtn;
@BindView(R.id.config_bg_color) View mBgColorPicker;
@BindView(R.id.config_bg_seekbar) SeekBar mBgSeekBar;
@BindView(R.id.config_text_color) View mTextColorPicker;
@BindView(R.id.config_calc) View mBackground;
@BindView(R.id.config_save) Button mSaveBtn;
@BindView(R.id.result) TextView mResult;
@BindView(R.id.formula) TextView mFormula;
private int mBgColor;
private int mBgColorWithoutTransparency;
private int mWidgetId;
private int mTextColor;
private float mBgAlpha;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setResult(RESULT_CANCELED);
setContentView(R.layout.widget_config);
ButterKnife.bind(this);
initVariables();
final Intent intent = getIntent();
final Bundle extras = intent.getExtras();
if (extras != null)
mWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
if (mWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID)
finish();
}
private void initVariables() {
final SharedPreferences prefs = getSharedPreferences(Constants.PREFS_KEY, Context.MODE_PRIVATE);
mBgColor = prefs.getInt(Constants.WIDGET_BG_COLOR, 1);
if (mBgColor == 1) {
mBgColor = Color.BLACK;
mBgAlpha = .2f;
} else {
mBgAlpha = Color.alpha(mBgColor) / (float) 255;
}
mResetBtn.setVisibility(View.VISIBLE);
mBgColorWithoutTransparency = Color.rgb(Color.red(mBgColor), Color.green(mBgColor), Color.blue(mBgColor));
mBgSeekBar.setOnSeekBarChangeListener(bgSeekbarChangeListener);
mBgSeekBar.setProgress((int) (mBgAlpha * 100));
updateBackgroundColor();
mTextColor = prefs.getInt(Constants.WIDGET_TEXT_COLOR, getResources().getColor(R.color.colorPrimary));
updateTextColor();
mFormula.setText("15,937*5");
mResult.setText("79,685");
}
@OnClick(R.id.config_save)
public void saveConfig() {
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
final RemoteViews views = new RemoteViews(getPackageName(), R.layout.activity_main);
views.setInt(R.id.calculator_holder, "setBackgroundColor", mBgColor);
appWidgetManager.updateAppWidget(mWidgetId, views);
storeWidgetBackground();
requestWidgetUpdate();
final Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
private void storeWidgetBackground() {
final SharedPreferences prefs = getSharedPreferences(Constants.PREFS_KEY, Context.MODE_PRIVATE);
prefs.edit().putInt(Constants.WIDGET_BG_COLOR, mBgColor).apply();
prefs.edit().putInt(Constants.WIDGET_TEXT_COLOR, mTextColor).apply();
}
private void requestWidgetUpdate() {
final Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidgetProvider.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[]{mWidgetId});
sendBroadcast(intent);
}
private void updateBackgroundColor() {
mBgColor = adjustAlpha(mBgColorWithoutTransparency, mBgAlpha);
mBackground.setBackgroundColor(mBgColor);
mBgColorPicker.setBackgroundColor(mBgColor);
mSaveBtn.setBackgroundColor(mBgColor);
}
private void updateTextColor() {
mTextColorPicker.setBackgroundColor(mTextColor);
mSaveBtn.setTextColor(mTextColor);
int[] viewIds =
new int[]{R.id.btn_0, R.id.btn_1, R.id.btn_2, R.id.btn_3, R.id.btn_4, R.id.btn_5, R.id.btn_6, R.id.btn_7, R.id.btn_8,
R.id.btn_9, R.id.btn_modulo, R.id.btn_power, R.id.btn_root, R.id.btn_clear, R.id.btn_reset, R.id.btn_divide,
R.id.btn_multiply, R.id.btn_minus, R.id.btn_plus, R.id.btn_decimal, R.id.btn_equals};
mResult.setTextColor(mTextColor);
mFormula.setTextColor(mTextColor);
Button btn;
for (int i : viewIds) {
btn = (Button) findViewById(i);
btn.setTextColor(mTextColor);
}
}
@OnClick(R.id.config_bg_color)
public void pickBackgroundColor() {
AmbilWarnaDialog dialog = new AmbilWarnaDialog(this, mBgColorWithoutTransparency, new AmbilWarnaDialog.OnAmbilWarnaListener() {
@Override
public void onCancel(AmbilWarnaDialog dialog) {
}
@Override
public void onOk(AmbilWarnaDialog dialog, int color) {
mBgColorWithoutTransparency = color;
updateBackgroundColor();
}
});
dialog.show();
}
@OnClick(R.id.config_text_color)
public void pickTextColor() {
AmbilWarnaDialog dialog = new AmbilWarnaDialog(this, mTextColor, new AmbilWarnaDialog.OnAmbilWarnaListener() {
@Override
public void onCancel(AmbilWarnaDialog dialog) {
}
@Override
public void onOk(AmbilWarnaDialog dialog, int color) {
mTextColor = color;
updateTextColor();
}
});
dialog.show();
}
private SeekBar.OnSeekBarChangeListener bgSeekbarChangeListener = new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mBgAlpha = (float) progress / (float) 100;
updateBackgroundColor();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
};
private int adjustAlpha(int color, float factor) {
final int alpha = Math.round(Color.alpha(color) * factor);
final int red = Color.red(color);
final int green = Color.green(color);
final int blue = Color.blue(color);
return Color.argb(alpha, red, green, blue);
}
}

View File

@ -0,0 +1,155 @@
package com.simplemobiletools.calculator.activities
import android.app.Activity
import android.appwidget.AppWidgetManager
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.View
import android.widget.Button
import android.widget.RemoteViews
import android.widget.SeekBar
import com.simplemobiletools.calculator.*
import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.widget_config.*
class WidgetConfigureActivity : AppCompatActivity() {
private var mBgColor: Int = 0
private var mBgColorWithoutTransparency: Int = 0
private var mWidgetId: Int = 0
private var mTextColor: Int = 0
private var mBgAlpha: Float = 0.toFloat()
private val bgSeekbarChangeListener = object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
mBgAlpha = progress.toFloat() / 100.toFloat()
updateBackgroundColor()
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
}
}
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setResult(Activity.RESULT_CANCELED)
setContentView(R.layout.widget_config)
config_save.setOnClickListener { saveConfig() }
config_bg_color.setOnClickListener { pickBackgroundColor() }
config_text_color.setOnClickListener { pickTextColor() }
initVariables()
val intent = intent
val extras = intent.extras
if (extras != null)
mWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
if (mWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID)
finish()
}
private fun initVariables() {
val prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
mBgColor = prefs.getInt(WIDGET_BG_COLOR, 1)
if (mBgColor == 1) {
mBgColor = Color.BLACK
mBgAlpha = .2f
} else {
mBgAlpha = Color.alpha(mBgColor) / 255.toFloat()
}
btn_reset.visibility = View.VISIBLE
mBgColorWithoutTransparency = Color.rgb(Color.red(mBgColor), Color.green(mBgColor), Color.blue(mBgColor))
config_bg_seekbar.setOnSeekBarChangeListener(bgSeekbarChangeListener)
config_bg_seekbar.progress = (mBgAlpha * 100).toInt()
updateBackgroundColor()
mTextColor = prefs.getInt(WIDGET_TEXT_COLOR, resources.getColor(R.color.colorPrimary))
updateTextColor()
formula.text = "15,937*5"
result.text = "79,685"
}
fun saveConfig() {
val appWidgetManager = AppWidgetManager.getInstance(this)
val views = RemoteViews(packageName, R.layout.activity_main)
views.setInt(R.id.calculator_holder, "setBackgroundColor", mBgColor)
appWidgetManager.updateAppWidget(mWidgetId, views)
storeWidgetBackground()
requestWidgetUpdate()
val resultValue = Intent()
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId)
setResult(Activity.RESULT_OK, resultValue)
finish()
}
private fun storeWidgetBackground() {
val prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
prefs.edit().putInt(WIDGET_BG_COLOR, mBgColor).apply()
prefs.edit().putInt(WIDGET_TEXT_COLOR, mTextColor).apply()
}
private fun requestWidgetUpdate() {
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidgetProvider::class.java)
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(mWidgetId))
sendBroadcast(intent)
}
private fun updateBackgroundColor() {
mBgColor = adjustAlpha(mBgColorWithoutTransparency, mBgAlpha)
config_calc.setBackgroundColor(mBgColor)
config_bg_color.setBackgroundColor(mBgColor)
config_save.setBackgroundColor(mBgColor)
}
private fun updateTextColor() {
config_text_color.setBackgroundColor(mTextColor)
config_save.setTextColor(mTextColor)
val viewIds = intArrayOf(R.id.btn_0, R.id.btn_1, R.id.btn_2, R.id.btn_3, R.id.btn_4, R.id.btn_5, R.id.btn_6, R.id.btn_7, R.id.btn_8, R.id.btn_9, R.id.btn_modulo, R.id.btn_power, R.id.btn_root, R.id.btn_clear, R.id.btn_reset, R.id.btn_divide, R.id.btn_multiply, R.id.btn_minus, R.id.btn_plus, R.id.btn_decimal, R.id.btn_equals)
result.setTextColor(mTextColor)
formula.setTextColor(mTextColor)
var btn: Button
for (i in viewIds) {
btn = findViewById<Button>(i)
btn.setTextColor(mTextColor)
}
}
fun pickBackgroundColor() {
ColorPickerDialog(this, mBgColorWithoutTransparency) {
mBgColorWithoutTransparency = it
updateBackgroundColor()
}
}
fun pickTextColor() {
ColorPickerDialog(this, mTextColor) {
mTextColor = it
updateTextColor()
}
}
private fun adjustAlpha(color: Int, factor: Float): Int {
val alpha = Math.round(Color.alpha(color) * factor)
val red = Color.red(color)
val green = Color.green(color)
val blue = Color.blue(color)
return Color.argb(alpha, red, green, blue)
}
}

View File

@ -1,20 +0,0 @@
package com.simplemobiletools.calculator.operation;
import com.simplemobiletools.calculator.operation.base.BinaryOperation;
import com.simplemobiletools.calculator.operation.base.Operation;
public class DivideOperation extends BinaryOperation implements Operation {
public DivideOperation(double baseValue, double secondValue) {
super(baseValue, secondValue);
}
@Override
public double getResult() {
double result = 0;
if (secondValue != 0) {
result = baseValue / secondValue;
}
return result;
}
}

View File

@ -0,0 +1,15 @@
package com.simplemobiletools.calculator.operation
import com.simplemobiletools.calculator.operation.base.BinaryOperation
import com.simplemobiletools.calculator.operation.base.Operation
class DivideOperation(baseValue: Double, secondValue: Double) : BinaryOperation(baseValue, secondValue), Operation {
override fun getResult(): Double {
var result = 0.0
if (secondValue != 0.0) {
result = baseValue / secondValue
}
return result
}
}

View File

@ -1,15 +0,0 @@
package com.simplemobiletools.calculator.operation;
import com.simplemobiletools.calculator.operation.base.BinaryOperation;
import com.simplemobiletools.calculator.operation.base.Operation;
public class MinusOperation extends BinaryOperation implements Operation {
protected MinusOperation(double baseValue, double secondValue) {
super(baseValue, secondValue);
}
@Override
public double getResult() {
return baseValue - secondValue;
}
}

View File

@ -0,0 +1,11 @@
package com.simplemobiletools.calculator.operation
import com.simplemobiletools.calculator.operation.base.BinaryOperation
import com.simplemobiletools.calculator.operation.base.Operation
class MinusOperation(baseValue: Double, secondValue: Double) : BinaryOperation(baseValue, secondValue), Operation {
override fun getResult(): Double {
return baseValue - secondValue
}
}

View File

@ -1,19 +0,0 @@
package com.simplemobiletools.calculator.operation;
import com.simplemobiletools.calculator.operation.base.BinaryOperation;
import com.simplemobiletools.calculator.operation.base.Operation;
public class ModuloOperation extends BinaryOperation implements Operation {
protected ModuloOperation(double baseValue, double secondValue) {
super(baseValue, secondValue);
}
@Override
public double getResult() {
double result = 0;
if (secondValue != 0) {
result = baseValue % secondValue;
}
return result;
}
}

View File

@ -0,0 +1,15 @@
package com.simplemobiletools.calculator.operation
import com.simplemobiletools.calculator.operation.base.BinaryOperation
import com.simplemobiletools.calculator.operation.base.Operation
class ModuloOperation(baseValue: Double, secondValue: Double) : BinaryOperation(baseValue, secondValue), Operation {
override fun getResult(): Double {
var result = 0.0
if (secondValue != 0.0) {
result = baseValue % secondValue
}
return result
}
}

View File

@ -1,15 +0,0 @@
package com.simplemobiletools.calculator.operation;
import com.simplemobiletools.calculator.operation.base.BinaryOperation;
import com.simplemobiletools.calculator.operation.base.Operation;
public class MultiplyOperation extends BinaryOperation implements Operation {
protected MultiplyOperation(double baseValue, double secondValue) {
super(baseValue, secondValue);
}
@Override
public double getResult() {
return baseValue * secondValue;
}
}

View File

@ -0,0 +1,11 @@
package com.simplemobiletools.calculator.operation
import com.simplemobiletools.calculator.operation.base.BinaryOperation
import com.simplemobiletools.calculator.operation.base.Operation
class MultiplyOperation(baseValue: Double, secondValue: Double) : BinaryOperation(baseValue, secondValue), Operation {
override fun getResult(): Double {
return baseValue * secondValue
}
}

View File

@ -1,31 +0,0 @@
package com.simplemobiletools.calculator.operation;
import android.support.annotation.Nullable;
import com.simplemobiletools.calculator.Constants;
import com.simplemobiletools.calculator.operation.base.Operation;
public class OperationFactory {
@Nullable
public static Operation forId(String id, double baseValue, double secondValue) {
switch (id) {
case Constants.PLUS:
return new PlusOperation(baseValue, secondValue);
case Constants.MINUS:
return new MinusOperation(baseValue, secondValue);
case Constants.DIVIDE:
return new DivideOperation(baseValue, secondValue);
case Constants.MULTIPLY:
return new MultiplyOperation(baseValue, secondValue);
case Constants.MODULO:
return new ModuloOperation(baseValue, secondValue);
case Constants.POWER:
return new PowerOperation(baseValue, secondValue);
case Constants.ROOT:
return new RootOperation(baseValue);
default:
return null;
}
}
}

View File

@ -0,0 +1,20 @@
package com.simplemobiletools.calculator.operation
import com.simplemobiletools.calculator.*
import com.simplemobiletools.calculator.operation.base.Operation
object OperationFactory {
fun forId(id: String, baseValue: Double, secondValue: Double): Operation? {
when (id) {
PLUS -> return PlusOperation(baseValue, secondValue)
MINUS -> return MinusOperation(baseValue, secondValue)
DIVIDE -> return DivideOperation(baseValue, secondValue)
MULTIPLY -> return MultiplyOperation(baseValue, secondValue)
MODULO -> return ModuloOperation(baseValue, secondValue)
POWER -> return PowerOperation(baseValue, secondValue)
ROOT -> return RootOperation(baseValue)
else -> return null
}
}
}

View File

@ -1,16 +0,0 @@
package com.simplemobiletools.calculator.operation;
import com.simplemobiletools.calculator.operation.base.BinaryOperation;
import com.simplemobiletools.calculator.operation.base.Operation;
public class PlusOperation extends BinaryOperation implements Operation {
protected PlusOperation(double baseValue, double secondValue) {
super(baseValue, secondValue);
}
@Override
public double getResult() {
return baseValue + secondValue;
}
}

View File

@ -0,0 +1,11 @@
package com.simplemobiletools.calculator.operation
import com.simplemobiletools.calculator.operation.base.BinaryOperation
import com.simplemobiletools.calculator.operation.base.Operation
class PlusOperation(baseValue: Double, secondValue: Double) : BinaryOperation(baseValue, secondValue), Operation {
override fun getResult(): Double {
return baseValue + secondValue
}
}

View File

@ -1,20 +0,0 @@
package com.simplemobiletools.calculator.operation;
import com.simplemobiletools.calculator.operation.base.BinaryOperation;
import com.simplemobiletools.calculator.operation.base.Operation;
import com.simplemobiletools.calculator.operation.base.UnaryOperation;
public class PowerOperation extends BinaryOperation implements Operation {
protected PowerOperation(double baseValue, double secondValue) {
super(baseValue, secondValue);
}
@Override
public double getResult() {
double result = Math.pow(baseValue, secondValue);
if (Double.isInfinite(result) || Double.isNaN(result))
result = 0;
return result;
}
}

View File

@ -0,0 +1,14 @@
package com.simplemobiletools.calculator.operation
import com.simplemobiletools.calculator.operation.base.BinaryOperation
import com.simplemobiletools.calculator.operation.base.Operation
class PowerOperation(baseValue: Double, secondValue: Double) : BinaryOperation(baseValue, secondValue), Operation {
override fun getResult(): Double {
var result = Math.pow(baseValue, secondValue)
if (java.lang.Double.isInfinite(result) || java.lang.Double.isNaN(result))
result = 0.0
return result
}
}

View File

@ -1,16 +0,0 @@
package com.simplemobiletools.calculator.operation;
import com.simplemobiletools.calculator.operation.base.Operation;
import com.simplemobiletools.calculator.operation.base.UnaryOperation;
public class RootOperation extends UnaryOperation implements Operation {
protected RootOperation(double value) {
super(value);
}
@Override
public double getResult() {
return Math.sqrt(value);
}
}

View File

@ -0,0 +1,11 @@
package com.simplemobiletools.calculator.operation
import com.simplemobiletools.calculator.operation.base.Operation
import com.simplemobiletools.calculator.operation.base.UnaryOperation
class RootOperation(value: Double) : UnaryOperation(value), Operation {
override fun getResult(): Double {
return Math.sqrt(value)
}
}

View File

@ -1,11 +0,0 @@
package com.simplemobiletools.calculator.operation.base;
public class BinaryOperation {
protected double baseValue;
protected double secondValue;
protected BinaryOperation(double baseValue, double secondValue) {
this.baseValue = baseValue;
this.secondValue = secondValue;
}
}

View File

@ -0,0 +1,3 @@
package com.simplemobiletools.calculator.operation.base
open class BinaryOperation protected constructor(protected var baseValue: Double, protected var secondValue: Double)

View File

@ -1,5 +0,0 @@
package com.simplemobiletools.calculator.operation.base;
public interface Operation {
double getResult();
}

View File

@ -0,0 +1,5 @@
package com.simplemobiletools.calculator.operation.base
interface Operation {
fun getResult(): Double
}

View File

@ -1,10 +0,0 @@
package com.simplemobiletools.calculator.operation.base;
public class UnaryOperation {
protected double value;
protected UnaryOperation(double value) {
this.value = value;
}
}

View File

@ -0,0 +1,3 @@
package com.simplemobiletools.calculator.operation.base
open class UnaryOperation protected constructor(protected var value: Double)

View File

@ -1,105 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:id="@+id/about_scrollview"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<RelativeLayout
android:id="@+id/about_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin">
<TextView
android:id="@+id/about_website"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="web"
android:text="@string/website"/>
<TextView
android:id="@+id/about_email_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/about_website"
android:layout_marginTop="@dimen/activity_margin"
android:text="@string/email_label"/>
<TextView
android:id="@+id/about_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/about_email_label"
android:paddingBottom="@dimen/activity_margin"
android:text="@string/email"/>
<TextView
android:id="@+id/about_invite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/about_email"
android:paddingBottom="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:text="@string/invite_friends_underlined"
android:textColor="@color/colorPrimary"/>
<TextView
android:id="@+id/about_rate_us"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/about_invite"
android:paddingBottom="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:text="@string/rate_us_underlined"
android:textColor="@color/colorPrimary"/>
<TextView
android:id="@+id/about_license"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/about_rate_us"
android:paddingBottom="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:text="@string/third_party_licences_underlined"
android:textColor="@color/colorPrimary"/>
<TextView
android:id="@+id/about_follow_us"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/about_license"
android:paddingBottom="@dimen/social_padding"
android:paddingTop="@dimen/activity_margin"
android:text="@string/follow_us"/>
<ImageView
android:id="@+id/about_facebook"
android:layout_width="@dimen/social_logo"
android:layout_height="@dimen/social_logo"
android:layout_below="@+id/about_follow_us"
android:src="@mipmap/facebook"/>
<ImageView
android:id="@+id/about_gplus"
android:layout_width="@dimen/social_logo"
android:layout_height="@dimen/social_logo"
android:layout_below="@+id/about_follow_us"
android:layout_marginLeft="@dimen/social_padding"
android:layout_toRightOf="@+id/about_facebook"
android:src="@mipmap/gplus"/>
<TextView
android:id="@+id/about_copyright"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_below="@+id/about_gplus"
android:gravity="center_horizontal|bottom"
android:paddingTop="@dimen/activity_margin"
android:text="v1.0\nCopyright © Simple Mobile Tools 2016"/>
</RelativeLayout>
</ScrollView>

View File

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:id="@+id/license_holder"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/license"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/activity_margin">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/notice"/>
<TextView
android:id="@+id/license_butterknife_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
android:text="@string/butterknife_title"
android:textColor="@color/colorPrimary"/>
<TextView
android:id="@+id/license_butterknife_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/butterknife_text"/>
<TextView
android:id="@+id/license_ambilwarna_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
android:text="@string/ambilwarna_title"
android:textColor="@color/colorPrimary"/>
<TextView
android:id="@+id/license_ambilwarna_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ambilwarna_text"/>
<TextView
android:id="@+id/license_autofittextview_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
android:text="@string/autofittextview_title"
android:textColor="@color/colorPrimary"/>
<TextView
android:id="@+id/license_autofittextview_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/autofittextview_text"/>
<TextView
android:id="@+id/license_robolectric_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
android:text="@string/robolectric_title"
android:textColor="@color/colorPrimary"/>
<TextView
android:id="@+id/license_robolectric_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/robolectric_text"/>
<TextView
android:id="@+id/license_espresso_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
android:text="@string/espresso_title"
android:textColor="@color/colorPrimary"/>
<TextView
android:id="@+id/license_espresso_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/espresso_text"/>
</LinearLayout>
</ScrollView>

View File

@ -12,28 +12,21 @@
android:orientation="vertical">
<RelativeLayout
android:id="@+id/settings_dark_theme_holder"
android:id="@+id/settings_customize_colors_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/settings_padding"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/activity_margin">
<TextView
android:id="@+id/settings_dark_theme_label"
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/settings_customize_colors_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="@dimen/settings_padding"
android:text="@string/dark_theme"/>
<android.support.v7.widget.SwitchCompat
android:id="@+id/settings_dark_theme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@null"
android:clickable="false"/>
android:paddingLeft="@dimen/medium_margin"
android:paddingStart="@dimen/medium_margin"
android:text="@string/customize_colors"/>
</RelativeLayout>
</LinearLayout>

View File

@ -3,31 +3,6 @@
<string name="app_launcher_name">Rechner</string>
<string name="copied_to_clipboard">Wert in Zwischenablage kopiert</string>
<!-- About -->
<string name="about">Über</string>
<string name="website">Weitere einfache Apps und Quellcode findest du auf:\nhttp://simplemobiletools.com</string>
<string name="email_label">Sende Vorschläge und Feedback an:</string>
<string name="third_party_licences_underlined"><u>Drittanbieterlizenzen</u></string>
<string name="invite_friends_underlined"><u>Lade Freunde ein</u></string>
<string name="share_text">Hey, wirf mal einen Blick auf %1$s: %2$s</string>
<string name="invite_via">Einladen via</string>
<string name="rate_us_underlined"><u>Bewerte uns im Play Store</u></string>
<string name="follow_us">Folge uns:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!-- Settings -->
<string name="settings">Einstellungen</string>
<string name="dark_theme">Dunkles Design</string>
<!-- License -->
<string name="notice">Diese App nutzt folgende Drittanbieterbibliotheken, die mein Leben einfacher machen. Danke.</string>
<string name="third_party_licences">Drittanbieterlizenzen</string>
<string name="butterknife_title"><u>Butter Knife (View Injector)</u></string>
<string name="ambilwarna_title"><u>AmbilWarna (Color Picker)</u></string>
<string name="autofittextview_title"><u>AutoFitTextView (Autoresizing Textview)</u></string>
<string name="robolectric_title"><u>Robolectric (Unit Testing Framework)</u></string>
<string name="espresso_title"><u>Espresso (UI Testing Framework)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">Ein Taschenrechner mit grundlegenden Funktionen und einem anpassbaren Widget.</string>
<string name="app_long_description">

View File

@ -3,31 +3,6 @@
<string name="app_launcher_name">Calculadora</string>
<string name="copied_to_clipboard">Valor copiado en el portapapeles</string>
<!-- About -->
<string name="about">Acerca de Simple Calculator</string>
<string name="website">Más aplicaciones simples y su código fuente en:\nhttp://simplemobiletools.com</string>
<string name="email_label">Envíe sus comentarios y sugerencias a:</string>
<string name="third_party_licences_underlined"><u>Licencias de terceros</u></string>
<string name="invite_friends_underlined"><u>Invitar a amigos</u></string>
<string name="share_text">Hola, venga y échele un vistazo a %1$s en %2$s</string>
<string name="invite_via">Invitar vía</string>
<string name="rate_us_underlined"><u>Evalúenos en Google Play Store</u></string>
<string name="follow_us">Síganos:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!-- Settings -->
<string name="settings">Opciones</string>
<string name="dark_theme">Tema oscuro</string>
<!-- License -->
<string name="notice">Esta aplicación usa las siguientes librerías de terceros para hacerme la vida más fácil. Gracias.</string>
<string name="third_party_licences">Licencias de terceros</string>
<string name="butterknife_title"><u>Butter Knife (Inyector de vistas)</u></string>
<string name="ambilwarna_title"><u>AmbilWarna (Selector de colores)</u></string>
<string name="autofittextview_title"><u>AutoFitTextView (ajuste automático de texto)</u></string>
<string name="robolectric_title"><u>Robolectric (framework de testeo de unidades)</u></string>
<string name="espresso_title"><u>Espresso (framework de testeo de interfaz de usuario)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">Una calculadora con funciones básicas y un widget personalizable.</string>
<string name="app_long_description">

View File

@ -3,31 +3,6 @@
<string name="app_launcher_name">Calculette</string>
<string name="copied_to_clipboard">Valeur copiée dans le presse-papier</string>
<!-- About -->
<string name="about">À propos</string>
<string name="website">Plus d\'applications et de code source sur : http://simplemobiletools.com</string>
<string name="email_label">Envoyez vos remarques et suggestions à :</string>
<string name="third_party_licences_underlined"><u>Licences tierces</u></string>
<string name="invite_friends_underlined"><u>Inviter des amis</u></string>
<string name="share_text">Hey, allez voir %1$s sur %2$s</string>
<string name="invite_via">Inviter via</string>
<string name="rate_us_underlined"><u>Notez-nous dans le Play Store</u></string>
<string name="follow_us">Suivez-nous :</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!-- Settings -->
<string name="settings">Paramètres</string>
<string name="dark_theme">Thème sombre</string>
<!-- License -->
<string name="notice">Cette application utilise les bibliothèques tierces suivantes pour me simplifier la vie. Merci.</string>
<string name="third_party_licences">Licences tierces</string>
<string name="butterknife_title"><u>Butter Knife (injecteur de vue)</u></string>
<string name="ambilwarna_title"><u>AmbilWarna (sélecteur de couleur)</u></string>
<string name="autofittextview_title"><u>AutoFitTextView (taille de texte automatique)</u></string>
<string name="robolectric_title"><u>Robolectric (test unitaire)</u></string>
<string name="espresso_title"><u>Espresso (testeur d\'interface utilisateur)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">Une calculette avec les fonctions de base et un widget customisable.</string>
<string name="app_long_description">Pas de conversion d\'unité, restez appuyé sur le résultat d\'une formule pour le copier. La couleur du texte, du fond et la transparence peuvent être modifiés. Appuyez sur le résultat ou la formule du widget pour ouvrir l\'application. Pas de pub ou d\'autorisations inutiles. Complètement opensource et fournit un thème sombre. Cette application fait partie d\'une collection, disponibles sur http://www.simplemobiletools.com</string>

View File

@ -3,31 +3,6 @@
<string name="app_launcher_name">Calculator</string>
<string name="copied_to_clipboard">Valore copiato negli appunti</string>
<!-- About -->
<string name="about">Informazioni</string>
<string name="website">Altre semplici app e codici sorgenti in:\nhttp://simplemobiletools.com</string>
<string name="email_label">Invia la tua opinione o i tuoi suggerimenti a:</string>
<string name="third_party_licences_underlined"><u>Licenze di terze parti</u></string>
<string name="invite_friends_underlined"><u>Invite friends</u></string>
<string name="share_text">Hey, come check out %1$s at %2$s</string>
<string name="invite_via">Invite via</string>
<string name="rate_us_underlined"><u>Dacci un voto sul Play Store</u></string>
<string name="follow_us">Seguici:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!-- Settings -->
<string name="settings">Impostazioni</string>
<string name="dark_theme">Tema scuro</string>
<!-- License -->
<string name="notice">Questa app usa le seguenti librerie di terze parti per semplificarmi la vita. Grazie.</string>
<string name="third_party_licences">Licenze di terze parti</string>
<string name="butterknife_title"><u>Butter Knife (view injector)</u></string>
<string name="ambilwarna_title"><u>AmbilWarna (color picker)</u></string>
<string name="autofittextview_title"><u>AutoFitTextView (autoresizing textview)</u></string>
<string name="robolectric_title"><u>Robolectric (unit testing framework)</u></string>
<string name="espresso_title"><u>Espresso (UI testing framework)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">A calculator with the basic functions and a customizable widget.</string>
<string name="app_long_description">

View File

@ -3,31 +3,6 @@
<string name="app_launcher_name">電卓</string>
<string name="copied_to_clipboard">値をクリップボードにコピーしました</string>
<!-- About -->
<string name="about">アプリについて</string>
<string name="website">もっとシンプルなアプリとソースコードは:\nhttp://simplemobiletools.com</string>
<string name="email_label">ご意見やご提案をお送りください:</string>
<string name="third_party_licences_underlined"><u>サードパーティー ライセンス</u></string>
<string name="invite_friends_underlined"><u>友達を招待</u></string>
<string name="share_text">%2$s で %1$s を確認してください</string>
<string name="invite_via">招待...</string>
<string name="rate_us_underlined"><u>Play ストアで評価してください</u></string>
<string name="follow_us">フォローしてください:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!-- Settings -->
<string name="settings">設定</string>
<string name="dark_theme">ダークテーマ</string>
<!-- License -->
<string name="notice">このアプリは、私の暮らしにゆとりを持たせるために、次のサードパーティのライブラリーを使用しています。 ありがとうございます。</string>
<string name="third_party_licences">サードパーティー ライセンス</string>
<string name="butterknife_title"><u>Butter Knife (ビュー インジェクター)</u></string>
<string name="ambilwarna_title"><u>AmbilWarna (カラー ピッカー)</u></string>
<string name="autofittextview_title"><u>AutoFitTextView (自動リサイズ テキストビュー)</u></string>
<string name="robolectric_title"><u>Robolectric (ユニットテスト フレームワーク)</u></string>
<string name="espresso_title"><u>Espresso (UI テスト フレームワーク)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">基本機能とカスタマイズ可能なウィジェットを備えた電卓。</string>
<string name="app_long_description">

View File

@ -3,31 +3,6 @@
<string name="app_launcher_name">Calculadora</string>
<string name="copied_to_clipboard">Valor copiado para a área de transferência</string>
<!-- About -->
<string name="about">Acerca</string>
<string name="website">Mais aplicações Simple e código fonte em:\nhttp://simplemobiletools.com</string>
<string name="email_label">Envie os seus comentários ou sugestões para:</string>
<string name="third_party_licences_underlined"><u>Licenças de terceiros</u></string>
<string name="invite_friends_underlined"><u>Convidar amigos</u></string>
<string name="share_text">Olá, experimenta %1$s em %2$s</string>
<string name="invite_via">Convidar via</string>
<string name="rate_us_underlined"><u>Classifique-nos na Play Store</u></string>
<string name="follow_us">Siga-nos:</string>
<string name="copyright">V %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!-- Settings -->
<string name="settings">Definições</string>
<string name="dark_theme">Tema escuro</string>
<!-- License -->
<string name="notice">Esta aplicação usa as seguintes bibliotecas de terceiros para facilitar a minha vida. Obrigado.</string>
<string name="third_party_licences">Licenças de terceiros</string>
<string name="butterknife_title"><u>Butter Knife (injetor de vistas)</u></string>
<string name="ambilwarna_title"><u>AmbilWarna (seletor de cores)</u></string>
<string name="autofittextview_title"><u>AutoFitTextView (ajuste automático de texto)</u></string>
<string name="robolectric_title"><u>Robolectric (infraestrutura de teste de unidades)</u></string>
<string name="espresso_title"><u>Espresso (infraestrutura de testes da interface)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">Uma calculadora com funções básicas e um widget personalizável.</string>
<string name="app_long_description">

View File

@ -3,31 +3,6 @@
<string name="app_launcher_name">Калькулятор</string>
<string name="copied_to_clipboard">Значение скопировано в буфер обмена</string>
<!-- About -->
<string name="about">About</string>
<string name="website">More simple apps and source code at:\nhttp://simplemobiletools.com</string>
<string name="email_label">Send your feedback or suggestions to:</string>
<string name="third_party_licences_underlined"><u>Third party licences</u></string>
<string name="invite_friends_underlined"><u>Invite friends</u></string>
<string name="share_text">Hey, come check out %1$s at %2$s</string>
<string name="invite_via">Invite via</string>
<string name="rate_us_underlined"><u>Rate us in the Play Store</u></string>
<string name="follow_us">Follow us:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!-- Settings -->
<string name="settings">Settings</string>
<string name="dark_theme">Dark theme</string>
<!-- License -->
<string name="notice">This app uses the following third party libraries to make my life easier. Thank you.</string>
<string name="third_party_licences">Third party licences</string>
<string name="butterknife_title"><u>Butter Knife (view injector)</u></string>
<string name="ambilwarna_title"><u>AmbilWarna (color picker)</u></string>
<string name="autofittextview_title"><u>AutoFitTextView (autoresizing textview)</u></string>
<string name="robolectric_title"><u>Robolectric (unit testing framework)</u></string>
<string name="espresso_title"><u>Espresso (UI testing framework)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">Калькулятор с базовым функционалом и настраиваемым виджетом.</string>
<string name="app_long_description">

View File

@ -3,42 +3,6 @@
<string name="app_launcher_name">Kalkulačka</string>
<string name="copied_to_clipboard">Hodnota bola skopírovaná do schránky</string>
<!-- About -->
<string name="about">O aplikácii</string>
<string name="website">Viac jednoduchých aplikácií a zdrojového kódu na:\nhttp://simplemobiletools.com</string>
<string name="email_label">Odošlite svoje pripomienky alebo návrhy:</string>
<string name="email" translatable="false">hello@simplemobiletools.com</string>
<string name="third_party_licences_underlined"><u>Licencie tretích strán</u></string>
<string name="invite_friends_underlined"><u>Pozvať priateľov</u></string>
<string name="share_text">Hej, príďte vyskúšať %1$s na %2$s</string>
<string name="invite_via">Pozvať cez</string>
<string name="rate_us_underlined"><u>Ohodnoťte nás v obchode Play</u></string>
<string name="follow_us">Nasleduj nás:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!-- Settings -->
<string name="settings">Nastavenia</string>
<string name="dark_theme">Tmavá téma</string>
<!-- License -->
<string name="notice">Táto aplikácia využíva nasledujúce knižnice tretích strán, aby mi uľahčili život. Ďakujem.</string>
<string name="third_party_licences">Licencie tretích strán</string>
<string name="butterknife_title"><u>Butter Knife (view injector)</u></string>
<string name="butterknife_text" translatable="false">Copyright 2013 Jake Wharton\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions and limitations under the License.</string>
<string name="butterknife_url" translatable="false">https://github.com/JakeWharton/butterknife</string>
<string name="ambilwarna_title"><u>AmbilWarna (color picker)</u></string>
<string name="ambilwarna_text" translatable="false">Copyright 2009-2015 Yuku\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</string>
<string name="ambilwarna_url" translatable="false">https://github.com/yukuku/ambilwarna</string>
<string name="autofittextview_title"><u>AutoFitTextView (autoresizing textview)</u></string>
<string name="autofittextview_text" translatable="false">Copyright 2014 Grantland Chew\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</string>
<string name="autofittextview_url" translatable="false">https://github.com/grantland/android-autofittextview</string>
<string name="robolectric_title"><u>Robolectric (unit testing framework)</u></string>
<string name="robolectric_text" translatable="false">The MIT License\n\nCopyright (c) 2010 Xtreme Labs and Pivotal Labs\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</string>
<string name="robolectric_url" translatable="false">https://github.com/robolectric/robolectric</string>
<string name="espresso_title"><u>Espresso (UI testing framework)</u></string>
<string name="espresso_text" translatable="false">Copyright 2014 The Android Open Source Project\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</string>
<string name="espresso_url" translatable="false">https://google.github.io/android-testing-support-library/docs/espresso/index.html</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">Kalkulačka so základnými funkciami a prispôsobiteľným widgetom.</string>
<string name="app_long_description">

View File

@ -3,31 +3,6 @@
<string name="app_launcher_name">Kalkylator</string>
<string name="copied_to_clipboard">Värdet kopierat till urklippet</string>
<!-- About -->
<string name="about">Om</string>
<string name="website">Fler enkla appar och källkod här:\nhttp://simplemobiletools.com</string>
<string name="email_label">Skicka feedback och förslag till:</string>
<string name="third_party_licences_underlined"><u>Tredjepartslicenser</u></string>
<string name="invite_friends_underlined"><u>Bjud in vänner</u></string>
<string name="share_text">Hej, läs om %1$s på %2$s</string>
<string name="invite_via">Bjud in via</string>
<string name="rate_us_underlined"><u>Betygsätt oss i Play Butiken</u></string>
<string name="follow_us">Följ oss:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!-- Settings -->
<string name="settings">Inställningar</string>
<string name="dark_theme">Mörkt tema</string>
<!-- License -->
<string name="notice">Denna app använder följande tredjepartsbibliotek för att göra mitt liv enklare. Tack.</string>
<string name="third_party_licences">Tredjepartslicenser</string>
<string name="butterknife_title"><u>Butter Knife (vyinjektor)</u></string>
<string name="ambilwarna_title"><u>AmbilWarna (färgväljare)</u></string>
<string name="autofittextview_title"><u>AutoFitTextView (textvy med automatisk storleksändring)</u></string>
<string name="robolectric_title"><u>Robolectric (ramverk för enhetstestning)</u></string>
<string name="espresso_title"><u>Espresso (ramverk för användargränssnittstestning)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">En kalkylator med grundläggande funktioner och en anpassningsbar widget.</string>
<string name="app_long_description">

View File

@ -3,42 +3,6 @@
<string name="app_launcher_name">Calculator</string>
<string name="copied_to_clipboard">Value copied to clipboard</string>
<!-- About -->
<string name="about">About</string>
<string name="website">More simple apps and source code at:\nhttp://simplemobiletools.com</string>
<string name="email_label">Send your feedback or suggestions to:</string>
<string name="email" translatable="false">hello@simplemobiletools.com</string>
<string name="third_party_licences_underlined"><u>Third party licenses</u></string>
<string name="invite_friends_underlined"><u>Invite friends</u></string>
<string name="share_text">Hey, come check out %1$s at %2$s</string>
<string name="invite_via">Invite via</string>
<string name="rate_us_underlined"><u>Rate us in the Play Store</u></string>
<string name="follow_us">Follow us:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!-- Settings -->
<string name="settings">Settings</string>
<string name="dark_theme">Dark theme</string>
<!-- License -->
<string name="notice">This app uses the following third party libraries to make my life easier. Thank you.</string>
<string name="third_party_licences">Third party licenses</string>
<string name="butterknife_title"><u>Butter Knife (view injector)</u></string>
<string name="butterknife_text" translatable="false">Copyright 2013 Jake Wharton\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</string>
<string name="butterknife_url" translatable="false">https://github.com/JakeWharton/butterknife</string>
<string name="ambilwarna_title"><u>AmbilWarna (color picker)</u></string>
<string name="ambilwarna_text" translatable="false">Copyright 2009-2015 Yuku\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</string>
<string name="ambilwarna_url" translatable="false">https://github.com/yukuku/ambilwarna</string>
<string name="autofittextview_title"><u>AutoFitTextView (autoresizing textview)</u></string>
<string name="autofittextview_text" translatable="false">Copyright 2014 Grantland Chew\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</string>
<string name="autofittextview_url" translatable="false">https://github.com/grantland/android-autofittextview</string>
<string name="robolectric_title"><u>Robolectric (unit testing framework)</u></string>
<string name="robolectric_text" translatable="false">The MIT License\n\nCopyright (c) 2010 Xtreme Labs and Pivotal Labs\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</string>
<string name="robolectric_url" translatable="false">https://github.com/robolectric/robolectric</string>
<string name="espresso_title"><u>Espresso (UI testing framework)</u></string>
<string name="espresso_text" translatable="false">Copyright 2014 The Android Open Source Project\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</string>
<string name="espresso_url" translatable="false">https://google.github.io/android-testing-support-library/docs/espresso/index.html</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">A calculator with the basic functions and a customizable widget.</string>
<string name="app_long_description">

View File

@ -1,193 +0,0 @@
package com.simplemobiletools.calculator;
import com.simplemobiletools.calculator.activities.MainActivity;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import butterknife.ButterKnife;
import static junit.framework.Assert.assertEquals;
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class MainActivityTest {
MainActivity activity;
@Before
public void setUp() {
activity = Robolectric.setupActivity(MainActivity.class);
ButterKnife.bind(activity);
}
@Test
public void addSimpleDigit() {
activity.getCalc().addDigit(2);
assertEquals("2", getDisplayedNumber());
}
@Test
public void removeLeadingZero() {
activity.getCalc().addDigit(0);
activity.getCalc().addDigit(5);
assertEquals("5", getDisplayedNumber());
}
@Test
public void additionTest() {
String res = calcResult(-1.2, Constants.PLUS, 3.4);
assertEquals("2.2", res);
checkFormula("-1.2+3.4");
}
@Test
public void subtractionTest() {
String res = calcResult(7.8, Constants.MINUS, 2.5);
assertEquals("5.3", res);
checkFormula("7.8-2.5");
}
@Test
public void multiplyTest() {
String res = calcResult(-3.2, Constants.MULTIPLY, 6.6);
assertEquals("-21.12", res);
checkFormula("-3.2*6.6");
}
@Test
public void divisionTest() {
String res = calcResult(18.25, Constants.DIVIDE, 5);
assertEquals("3.65", res);
checkFormula("18.25/5");
}
@Test
public void divisionByZero_returnsZero() {
String res = calcResult(6, Constants.DIVIDE, 0);
assertEquals("0", res);
checkFormula("6/0");
}
@Test
public void moduloTest() {
String res = calcResult(6.5, Constants.MODULO, 3);
assertEquals("0.5", res);
checkFormula("6.5%3");
}
@Test
public void powerTest() {
String res = calcResult(3, Constants.POWER, 6);
assertEquals("729", res);
checkFormula("3^6");
}
@Test
public void rootTest() {
setDouble(16);
handleOperation(Constants.ROOT);
assertEquals("4", getDisplayedNumber());
checkFormula("√16");
}
@Test
public void clearBtnSimpleTest() {
setDouble(156);
activity.getCalc().handleClear();
assertEquals("15", getDisplayedNumber());
}
@Test
public void clearBtnComplexTest() {
setDouble(-26);
activity.getCalc().handleClear();
assertEquals("-2", getDisplayedNumber());
activity.getCalc().handleClear();
assertEquals("0", getDisplayedNumber());
}
@Test
public void clearBtnLongClick_resetsEverything() {
calcResult(-1.2, Constants.PLUS, 3.4);
activity.getCalc().handleReset();
handleOperation(Constants.PLUS);
setDouble(3);
activity.getCalc().handleResult();
assertEquals("3", getDisplayedNumber());
checkFormula("");
}
@Test
public void complexTest() {
setDouble(-12.2);
handleOperation(Constants.PLUS);
setDouble(21);
handleOperation(Constants.MINUS);
assertEquals("8.8", getDisplayedNumber());
checkFormula("-12.2+21");
setDouble(1.6);
activity.getCalc().handleEquals();
assertEquals("7.2", getDisplayedNumber());
checkFormula("8.8-1.6");
activity.getCalc().handleEquals();
assertEquals("5.6", getDisplayedNumber());
checkFormula("7.2-1.6");
handleOperation(Constants.MULTIPLY);
setDouble(5);
handleOperation(Constants.DIVIDE);
assertEquals("28", getDisplayedNumber());
checkFormula("5.6*5");
setDouble(4);
handleOperation(Constants.MODULO);
assertEquals("7", getDisplayedNumber());
checkFormula("28/4");
setDouble(5);
handleOperation(Constants.POWER);
assertEquals("2", getDisplayedNumber());
checkFormula("7%5");
setDouble(8);
handleOperation(Constants.ROOT);
assertEquals("16", getDisplayedNumber());
checkFormula("√256");
activity.getCalc().handleClear();
assertEquals("1", getDisplayedNumber());
}
private void setDouble(double d) {
activity.setValueDouble(d);
}
private void handleOperation(String operation) {
activity.getCalc().handleOperation(operation);
}
private void checkFormula(String desired) {
assertEquals(desired, getDisplayedFormula());
}
private String calcResult(double baseValue, String operation, double secondValue) {
setDouble(baseValue);
handleOperation(operation);
setDouble(secondValue);
activity.getCalc().handleResult();
return getDisplayedNumber();
}
private String getDisplayedNumber() {
return activity.getCalc().getDisplayedNumber();
}
private String getDisplayedFormula() {
return activity.getCalc().getDisplayedFormula();
}
}

View File

@ -0,0 +1,186 @@
package com.simplemobiletools.calculator
import com.simplemobiletools.calculator.activities.MainActivity
import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = intArrayOf(21))
class MainActivityTest {
internal lateinit var activity: MainActivity
private val displayedNumber: String?
get() = activity.calc!!.displayedNumber
private val displayedFormula: String?
get() = activity.calc!!.displayedFormula
@Before
fun setUp() {
activity = Robolectric.setupActivity(MainActivity::class.java)
}
@Test
fun addSimpleDigit() {
activity.calc!!.addDigit(2)
assertEquals("2", displayedNumber)
}
@Test
fun removeLeadingZero() {
activity.calc!!.addDigit(0)
activity.calc!!.addDigit(5)
assertEquals("5", displayedNumber)
}
@Test
fun additionTest() {
val res = calcResult(-1.2, PLUS, 3.4)
assertEquals("2.2", res)
checkFormula("-1.2+3.4")
}
@Test
fun subtractionTest() {
val res = calcResult(7.8, MINUS, 2.5)
assertEquals("5.3", res)
checkFormula("7.8-2.5")
}
@Test
fun multiplyTest() {
val res = calcResult(-3.2, MULTIPLY, 6.6)
assertEquals("-21.12", res)
checkFormula("-3.2*6.6")
}
@Test
fun divisionTest() {
val res = calcResult(18.25, DIVIDE, 5.0)
assertEquals("3.65", res)
checkFormula("18.25/5")
}
@Test
fun divisionByZero_returnsZero() {
val res = calcResult(6.0, DIVIDE, 0.0)
assertEquals("0", res)
checkFormula("6/0")
}
@Test
fun moduloTest() {
val res = calcResult(6.5, MODULO, 3.0)
assertEquals("0.5", res)
checkFormula("6.5%3")
}
@Test
fun powerTest() {
val res = calcResult(3.0, POWER, 6.0)
assertEquals("729", res)
checkFormula("3^6")
}
@Test
fun rootTest() {
setDouble(16.0)
handleOperation(ROOT)
assertEquals("4", displayedNumber)
checkFormula("√16")
}
@Test
fun clearBtnSimpleTest() {
setDouble(156.0)
activity.calc!!.handleClear()
assertEquals("15", displayedNumber)
}
@Test
fun clearBtnComplexTest() {
setDouble(-26.0)
activity.calc!!.handleClear()
assertEquals("-2", displayedNumber)
activity.calc!!.handleClear()
assertEquals("0", displayedNumber)
}
@Test
fun clearBtnLongClick_resetsEverything() {
calcResult(-1.2, PLUS, 3.4)
activity.calc!!.handleReset()
handleOperation(PLUS)
setDouble(3.0)
activity.calc!!.handleResult()
assertEquals("3", displayedNumber)
checkFormula("")
}
@Test
fun complexTest() {
setDouble(-12.2)
handleOperation(PLUS)
setDouble(21.0)
handleOperation(MINUS)
assertEquals("8.8", displayedNumber)
checkFormula("-12.2+21")
setDouble(1.6)
activity.calc!!.handleEquals()
assertEquals("7.2", displayedNumber)
checkFormula("8.8-1.6")
activity.calc!!.handleEquals()
assertEquals("5.6", displayedNumber)
checkFormula("7.2-1.6")
handleOperation(MULTIPLY)
setDouble(5.0)
handleOperation(DIVIDE)
assertEquals("28", displayedNumber)
checkFormula("5.6*5")
setDouble(4.0)
handleOperation(MODULO)
assertEquals("7", displayedNumber)
checkFormula("28/4")
setDouble(5.0)
handleOperation(POWER)
assertEquals("2", displayedNumber)
checkFormula("7%5")
setDouble(8.0)
handleOperation(ROOT)
assertEquals("16", displayedNumber)
checkFormula("√256")
activity.calc!!.handleClear()
assertEquals("1", displayedNumber)
}
private fun setDouble(d: Double) {
activity.setValueDouble(d)
}
private fun handleOperation(operation: String) {
activity.calc!!.handleOperation(operation)
}
private fun checkFormula(desired: String) {
assertEquals(desired, displayedFormula)
}
private fun calcResult(baseValue: Double, operation: String, secondValue: Double): String? {
setDouble(baseValue)
handleOperation(operation)
setDouble(secondValue)
activity.calc!!.handleResult()
return displayedNumber
}
}

View File

@ -1,12 +1,14 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.1.51'
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
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
@ -16,6 +18,9 @@ buildscript {
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
}
}