Browse Source

feat: update color picker dialog

main
Distopico Vegan 3 years ago
parent
commit
c1a2380d2c
No known key found for this signature in database GPG Key ID: 98093A8072546BF3
13 changed files with 384 additions and 27 deletions
  1. +5
    -1
      .gitignore
  2. +0
    -3
      .gitmodules
  3. +14
    -6
      app/build.gradle
  4. +157
    -0
      app/src/main/java/org/dystopia/email/ColorDialogFragment.java
  5. +14
    -14
      app/src/main/java/org/dystopia/email/FragmentAccount.java
  6. +118
    -0
      app/src/main/java/org/dystopia/email/ViewButtonColor.java
  7. +45
    -0
      app/src/main/java/org/dystopia/email/ViewHelper.java
  8. +23
    -1
      app/src/main/res/layout/fragment_account.xml
  9. +2
    -0
      app/src/main/res/values-en/strings.xml
  10. +2
    -0
      app/src/main/res/values/strings.xml
  11. +1
    -1
      build.gradle
  12. +2
    -0
      gradle.properties
  13. +1
    -1
      gradle/wrapper/gradle-wrapper.properties

+ 5
- 1
.gitignore View File

@ -36,4 +36,8 @@ proguard/
*.el
.DS_Store
.externalNativeBuild
.externalNativeBuild
# Node
node_modules
package-lock.json

+ 0
- 3
.gitmodules View File

@ -1,3 +0,0 @@
[submodule "colorpicker"]
path = colorpicker
url = https://github.com/M66B/colorpicker.git

+ 14
- 6
app/build.gradle View File

@ -1,14 +1,14 @@
apply plugin: "com.android.application"
apply plugin: "kotlin-android-extensions"
apply plugin: "kotlin-android"
apply plugin: "kotlin-android-extensions"
apply from: "${rootDir}/jdee.gradle"
android {
compileSdkVersion 28
compileSdkVersion 30
defaultConfig {
applicationId "org.dystopia.email"
minSdkVersion 23
targetSdkVersion 28
minSdkVersion 21
targetSdkVersion 30
versionCode 115
versionName "1.3.0"
archivesBaseName = "SimpleEmail-v$versionName"
@ -58,6 +58,9 @@ repositories {
jcenter()
maven {
url "https://repo1.maven.org/maven2/"
}
maven {
url "https://jitpack.io"
}
}
@ -69,6 +72,8 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
def androidx_version = "1.0.0"
def appcompat_version = "1.2.0"
def fragment_version = "1.3.0-beta01"
def constraintlayout_version = "1.1.3"
def lifecycle_version = "2.0.0"
def room_version = "2.0.0"
@ -78,9 +83,12 @@ dependencies {
def jcharset_version = "2.0"
def dnsjava_version = "2.1.8"
def openpgp_version = "12.0"
def colorpicker_version = "0.0.15"
// https://mvnrepository.com/artifact/androidx.appcompat/appcompat
implementation "androidx.appcompat:appcompat:$androidx_version"
implementation "androidx.appcompat:appcompat:$appcompat_version"
// https://mvnrepository.com/artifact/androidx.fragment/fragment
implementation "androidx.fragment:fragment:$fragment_version"
// https://mvnrepository.com/artifact/androidx.annotation/annotation
implementation "androidx.annotation:annotation:$androidx_version"
// https://mvnrepository.com/artifact/androidx.recyclerview/recyclerview
@ -122,7 +130,7 @@ dependencies {
implementation "org.sufficientlysecure:openpgp-api:$openpgp_version"
// https://android.googlesource.com/platform/frameworks/opt/colorpicker
implementation project(path: ':colorpicker', configuration: 'default')
implementation "com.github.QuadFlask:colorpicker:$colorpicker_version"
// Kotlin support
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"


+ 157
- 0
app/src/main/java/org/dystopia/email/ColorDialogFragment.java View File

@ -0,0 +1,157 @@
package org.dystopia.email;
/*
This file is part of SimpleEmail.
SimpleEmail is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
SimpleEmail is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SimpleEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018, Distopico (dystopia project) <distopico@riseup.net> and contributors
*/
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentResultListener;
import com.flask.colorpicker.ColorPickerView;
import com.flask.colorpicker.OnColorChangedListener;
import com.flask.colorpicker.builder.ColorPickerClickListener;
import com.flask.colorpicker.builder.ColorPickerDialogBuilder;
import static android.app.Activity.RESULT_OK;
public class ColorDialogFragment extends DialogFragment {
private static int requestSequence = 0;
private boolean sent = false;
private String requestKey = null;
private String targetRequestKey;
private int targetRequestCode;
private int color;
public String getRequestKey() {
if (requestKey == null)
requestKey = getClass().getName() + "_" + (++requestSequence);
return requestKey;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
requestKey = savedInstanceState.getString("dialog:request");
targetRequestKey = savedInstanceState.getString("dialog:key");
targetRequestCode = savedInstanceState.getInt("dialog:code");
}
getParentFragmentManager().setFragmentResultListener(getRequestKey(), this, new FragmentResultListener() {
@Override
public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle result) {
try {
result.setClassLoader(ApplicationEx.class.getClassLoader());
int requestCode = result.getInt("requestCode");
int resultCode = result.getInt("resultCode");
Intent data = new Intent();
data.putExtra("args", result);
onActivityResult(requestCode, resultCode, data);
} catch (Throwable ex) {
// LOg
}
}
});
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putInt("dialog:color", color);
outState.putString("dialog:request", requestKey);
outState.putString("dialog:key", targetRequestKey);
outState.putInt("dialog:code", targetRequestCode);
super.onSaveInstanceState(outState);
}
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Bundle args = getArguments();
color = savedInstanceState == null ? args.getInt("color") : savedInstanceState.getInt("dialog:color");
String title = args.getString("title");
boolean reset = args.getBoolean("reset", false);
Context context = getContext();
int editTextColor = Helper.resolveColor(context, android.R.attr.editTextColor);
ColorPickerDialogBuilder builder = ColorPickerDialogBuilder
.with(context)
.setTitle(title)
.showColorEdit(true)
.setColorEditTextColor(editTextColor)
.wheelType(ColorPickerView.WHEEL_TYPE.FLOWER)
.density(6)
.lightnessSliderOnly()
.setOnColorChangedListener(new OnColorChangedListener() {
@Override
public void onColorChanged(int selectedColor) {
color = selectedColor;
}
})
.setPositiveButton(android.R.string.ok, new ColorPickerClickListener() {
@Override
public void onClick(DialogInterface dialog, int selectedColor, Integer[] allColors) {
getArguments().putInt("color", selectedColor);
sendResult(RESULT_OK);
}
});
if (color != Color.TRANSPARENT) {
builder.initialColor(color);
}
if (reset) {
builder.setNegativeButton(R.string.title_reset, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
getArguments().putInt("color", Color.TRANSPARENT);
sendResult(RESULT_OK);
}
});
}
return builder.build();
}
protected void sendResult(int resultCode) {
if (sent) {
return;
}
sent = true;
if (targetRequestKey != null) {
Bundle args = getArguments();
if (args == null) {
args = new Bundle();
}
args.putInt("requestCode", targetRequestCode);
args.putInt("resultCode", resultCode);
getParentFragmentManager().setFragmentResult(targetRequestKey, args);
}
}
}

+ 14
- 14
app/src/main/java/org/dystopia/email/FragmentAccount.java View File

@ -64,8 +64,6 @@ import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.Group;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.Observer;
import com.android.colorpicker.ColorPickerDialog;
import com.android.colorpicker.ColorPickerSwatch;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout;
import com.sun.mail.imap.IMAPFolder;
@ -107,6 +105,8 @@ public class FragmentAccount extends FragmentEx {
private TextView tvName;
private EditText etName;
private ViewButtonColor btnColor;
private View vwColor;
private ImageView ibColorDefault;
private EditText etSignature;
@ -141,6 +141,8 @@ public class FragmentAccount extends FragmentEx {
private int color = Color.TRANSPARENT;
private String authorized = null;
private static final int REQUEST_COLOR = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -181,6 +183,7 @@ public class FragmentAccount extends FragmentEx {
btnAdvanced = view.findViewById(R.id.btnAdvanced);
etName = view.findViewById(R.id.etName);
btnColor = view.findViewById(R.id.btnColor);
tvName = view.findViewById(R.id.tvName);
vwColor = view.findViewById(R.id.vwColor);
ibColorDefault = view.findViewById(R.id.ibColorDefault);
@ -374,18 +377,15 @@ public class FragmentAccount extends FragmentEx {
new View.OnClickListener() {
@Override
public void onClick(View v) {
int[] colors = getContext().getResources().getIntArray(R.array.colorPicker);
ColorPickerDialog colorPickerDialog = new ColorPickerDialog();
colorPickerDialog.initialize(
R.string.title_account_color, colors, color, 4, colors.length);
colorPickerDialog.setOnColorSelectedListener(
new ColorPickerSwatch.OnColorSelectedListener() {
@Override
public void onColorSelected(int color) {
setColor(color);
}
});
colorPickerDialog.show(getFragmentManager(), "colorpicker");
Bundle args = new Bundle();
args.putInt("color", btnColor.getColor());
args.putString("title", getString(R.string.title_color));
args.putBoolean("reset", true);
ColorDialogFragment fragment = new ColorDialogFragment();
fragment.setArguments(args);
fragment.setTargetFragment(FragmentAccount.this, REQUEST_COLOR);
fragment.show(getParentFragmentManager(), "account:color");
}
});


+ 118
- 0
app/src/main/java/org/dystopia/email/ViewButtonColor.java View File

@ -0,0 +1,118 @@
package org.dystopia.email;
/*
This file is part of SimpleEmail.
SimpleEmail is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
SimpleEmail is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SimpleEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018, Distopico (dystopia project) <distopico@riseup.net> and contributors
*/
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
import androidx.appcompat.widget.AppCompatButton;
import androidx.core.graphics.ColorUtils;
public class ViewButtonColor extends AppCompatButton {
private int color = Color.TRANSPARENT;
public ViewButtonColor(Context context) {
super(context);
}
public ViewButtonColor(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ViewButtonColor(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
return new SavedState(superState, this.color);
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
setColor(savedState.getColor());
}
void setColor(Integer color) {
if (color == null)
color = Color.TRANSPARENT;
this.color = color;
GradientDrawable background = new GradientDrawable();
background.setColor(color);
background.setStroke(
ViewHelper.dp2px(getContext(), 1),
Helper.resolveColor(getContext(), R.attr.colorSeparator));
setBackground(background);
if (color == Color.TRANSPARENT)
setTextColor(Helper.resolveColor(getContext(), android.R.attr.textColorPrimary));
else {
double lum = ColorUtils.calculateLuminance(color);
setTextColor(lum < 0.5 ? Color.WHITE : Color.BLACK);
}
}
int getColor() {
return this.color;
}
static class SavedState extends View.BaseSavedState {
private int color;
private SavedState(Parcelable superState, int color) {
super(superState);
this.color = color;
}
private SavedState(Parcel in) {
super(in);
color = in.readInt();
}
public int getColor() {
return this.color;
}
@Override
public void writeToParcel(Parcel destination, int flags) {
super.writeToParcel(destination, flags);
destination.writeInt(color);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}

+ 45
- 0
app/src/main/java/org/dystopia/email/ViewHelper.java View File

@ -0,0 +1,45 @@
package org.dystopia.email;
/*
This file is part of SimpleEmail.
SimpleEmail is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
SimpleEmail is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SimpleEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018, Distopico (dystopia project) <distopico@riseup.net> and contributors
*/
import android.content.Context;
public class ViewHelper {
/**
* Convert density-independent pixels units to pixel units.
* @param context - android content context to get density
* @param dp - density-independent pixel value
*/
static int dp2px(Context context, int dp) {
float scale = context.getResources().getDisplayMetrics().density;
return Math.round(dp * scale);
}
/**
* Convert pixel units to density-independent pixels units.
* @param context - android content context to get density
* @param px - pixels value
*/
static int px2dp(Context context, float px) {
float scale = context.getResources().getDisplayMetrics().density;
return Math.round(px / scale);
}
}

+ 23
- 1
app/src/main/res/layout/fragment_account.xml View File

@ -240,7 +240,29 @@
app:layout_constraintBottom_toBottomOf="@id/vwColor"
app:layout_constraintStart_toEndOf="@id/vwColor"
app:layout_constraintTop_toBottomOf="@id/tilPassword" />
<TextView
android:id="@+id/tvColor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_color"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etName" />
<org.dystopia.email.ViewButtonColor
android:id="@+id/btnColor"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:paddingHorizontal="6dp"
android:tag="disable"
android:text="@string/title_select"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvColor" />
<Button
android:id="@+id/btnAdvanced"
style="@style/buttonStyleSmall"


+ 2
- 0
app/src/main/res/values-en/strings.xml View File

@ -260,4 +260,6 @@
<string name="title_show_details">See details</string>
<string name="title_no_accounts_yet">You don\'t have accounts configured yet</string>
<string name="title_no_identities_yet">You don\'t have identities configured yet</string>
<string name="title_reset">Reset</string>
<string name="title_color">Color</string>
</resources>

+ 2
- 0
app/src/main/res/values/strings.xml View File

@ -327,4 +327,6 @@
<string name="title_show_details">See details</string>
<string name="title_no_accounts_yet">You don\'t have accounts configured yet</string>
<string name="title_no_identities_yet">You don\'t have identities configured yet</string>
<string name="title_reset">Reset</string>
<string name="title_color">Color</string>
</resources>

+ 1
- 1
build.gradle View File

@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:3.4.0"
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}


+ 2
- 0
gradle.properties View File

@ -11,3 +11,5 @@ org.gradle.jvmargs=-Xmx1536m
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.useAndroidX=true
android.enableJetifier=true

+ 1
- 1
gradle/wrapper/gradle-wrapper.properties View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

Loading…
Cancel
Save