Implemented color picker

This commit is contained in:
Akash Yadav
2021-12-29 11:32:16 +05:30
parent ab7fac584c
commit 7e0d0baac8
8 changed files with 203 additions and 26 deletions
+2 -1
View File
@@ -6,7 +6,8 @@
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/drawable/ic_github.xml" value="0.21837606837606838" />
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/layout/activity_about.xml" value="0.2" />
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/layout/layout_about_items.xml" value="0.20512820512820512" />
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/common/src/main/res/layout/layout_color_picker.xml" value="0.20512820512820512" />
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/menu/menu_editor_nav.xml" value="0.20512820512820512" />
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/common/src/main/res/layout/layout_color_picker.xml" value="0.264" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/drawable-mdpi/bg_widgets_list.xml" value="0.3105485232067511" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/drawable-mdpi/ic_widget_progress.xml" value="0.3071729957805907" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/drawable/bg_design_container_background.xml" value="0.3105485232067511" />
+2 -1
View File
@@ -36,7 +36,8 @@
</activity>
<activity
android:name=".DesignerActivity"
android:configChanges="orientation|screenSize|uiMode">
android:configChanges="orientation|screenSize|uiMode"
android:windowSoftInputMode="adjustResize">
</activity>
<activity
android:name=".DownloadActivity"
@@ -73,7 +73,7 @@ public class IDEPreferences extends BasePreferenceFragment {
final Preference editor = new Preference(getContext());
final Preference build = new Preference(getContext());
final Preference telegram = new Preference(getContext());
final Preference issueTracker = new Preference(getContext());
final Preference github = new Preference(getContext());
final Preference changelog = new Preference(getContext());
final Preference about = new Preference(getContext());
@@ -92,9 +92,9 @@ public class IDEPreferences extends BasePreferenceFragment {
build.setFragment(getBuildFrag().getClass().getName());
build.setTitle(R.string.idepref_build_title);
issueTracker.setKey(KEY_ISSUES);
issueTracker.setIconSpaceReserved(false);
issueTracker.setTitle(R.string.user_suggestions);
github.setKey(KEY_ISSUES);
github.setIconSpaceReserved(false);
github.setTitle(R.string.title_github);
telegram.setKey(KEY_TELEGRAM);
telegram.setIconSpaceReserved(false);
@@ -111,13 +111,13 @@ public class IDEPreferences extends BasePreferenceFragment {
screen.addPreference(general);
screen.addPreference(editor);
screen.addPreference(build);
screen.addPreference(issueTracker);
screen.addPreference(github);
screen.addPreference(telegram);
screen.addPreference(changelog);
screen.addPreference(about);
final Preference.OnPreferenceClickListener listener = getListener();
issueTracker.setOnPreferenceClickListener(listener);
github.setOnPreferenceClickListener(listener);
telegram.setOnPreferenceClickListener(listener);
changelog.setOnPreferenceClickListener(listener);
about.setOnPreferenceClickListener(listener);
@@ -18,6 +18,7 @@
package com.itsaky.androidide.fragments.sheets;
import static com.itsaky.attrinfo.models.Attr.BOOLEAN;
import static com.itsaky.attrinfo.models.Attr.COLOR;
import static com.itsaky.attrinfo.models.Attr.DIMENSION;
import static com.itsaky.attrinfo.models.Attr.ENUM;
import static com.itsaky.attrinfo.models.Attr.FLAG;
@@ -164,6 +165,10 @@ public class AttrEditorSheet extends BottomSheetDialogFragment implements Simple
dialog = enumEditor (values, attribute.getValue (), onDone);
} else if (attribute.hasFormat (FLAG)) {
dialog = flagEditor (values, attribute.getValue (), onDone);
} else if (attribute.hasFormat (COLOR)) {
// TODO Implement something to allow values from colors.xml or ColorStateLists
// Make this color picker optional
dialog = colorPicker ();
}
if (dialog != null) {
@@ -24,12 +24,14 @@ import android.content.DialogInterface;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import com.itsaky.androidide.R;
import com.itsaky.androidide.app.StudioApp;
import com.itsaky.androidide.colorpicker.ColorPickerView;
import com.itsaky.androidide.databinding.LayoutDimensionAttrEditorBinding;
import com.itsaky.androidide.databinding.LayoutTextAttrEditorBinding;
import com.itsaky.toaster.Toaster;
@@ -50,6 +52,8 @@ public class AttributeDialogs {
private static final String DIMENSION_MATCH = "match_parent";
private static final String DIMENSION_WRAP = "wrap_content";
private static final Logger LOG = Logger.instance ("AttributeDialogs");
/**
* Context that will be used for creating dialogs.
* This must be initialized by calling {@link #init(Context)}
@@ -264,6 +268,19 @@ public class AttributeDialogs {
return builder.create ();
}
@NonNull
public static AlertDialog colorPicker () {
final var view = new ColorPickerView (mContext);
view.setOnPickListener ((color, hexCode) -> LOG.debug ("Picked color:", color, hexCode));
final var builder = newMaterialDialogBuilder (mContext);
builder.setView (view);
final var dialog = builder.create ();
dialog.getWindow ().setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
return dialog;
}
public interface OnClickListener {
void onClick (DialogInterface dialog, int which, String newValue);
}
+2 -2
View File
@@ -24,8 +24,8 @@
android:title="@string/discussions_on_telegram"/>
<item
android:id="@+id/editornav_suggest"
android:icon="@drawable/ic_bug"
android:title="@string/user_suggestions"/>
android:icon="@drawable/ic_github"
android:title="@string/title_github"/>
<item
android:id="@+id/editornav_needHelp"
android:icon="@drawable/ic_help"
@@ -17,11 +17,16 @@
package com.itsaky.androidide.colorpicker;
import static android.graphics.Color.*;
import static android.graphics.Color.alpha;
import static android.graphics.Color.argb;
import static android.graphics.Color.blue;
import static android.graphics.Color.green;
import static android.graphics.Color.parseColor;
import static android.graphics.Color.red;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -31,11 +36,13 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.google.android.material.slider.Slider;
import com.itsaky.androidide.common.R;
import com.itsaky.androidide.common.databinding.LayoutColorPickerBinding;
import com.itsaky.androidide.utils.Logger;
/**
* A color picker dialog.
* A color picker view.
*
* @author Akash Yadav
*/
@@ -46,10 +53,32 @@ public class ColorPickerView extends LinearLayout {
private int green;
private int blue;
private OnPickListener mPickListener;
private final LayoutColorPickerBinding binding;
private final int DEFAULT_COLOR;
private static final Logger LOG = Logger.instance ("ColorPickerView");
private final Slider.OnChangeListener mValueChangeListener = (slider, value, fromUser) -> {
// If it's not from user, then the values have already been updated
if (fromUser) {
final var id = slider.getId ();
final var intVal = (int) value;
if (id == R.id.alpha_slider) {
alpha = intVal;
} else if (id == R.id.red_slider) {
red = intVal;
} else if (id == R.id.green_slider){
green = intVal;
} else if (id == R.id.blue_slider) {
blue = intVal;
}
updatePreview ();
}
};
public ColorPickerView (Context context) {
this (context, null);
}
@@ -75,18 +104,124 @@ public class ColorPickerView extends LinearLayout {
init ();
}
/**
* Set a listener that will be notified when the user picks a color.
* @param listener The listener to set.
*/
public void setOnPickListener (OnPickListener listener) {
this.mPickListener = listener;
}
private void init () {
final var color = this.DEFAULT_COLOR;
setColor (DEFAULT_COLOR);
this.binding.alphaSlider.addOnChangeListener (mValueChangeListener);
this.binding.redSlider.addOnChangeListener (mValueChangeListener);
this.binding.greenSlider.addOnChangeListener (mValueChangeListener);
this.binding.blueSlider.addOnChangeListener (mValueChangeListener);
this.binding.hexField.getEditText ().addTextChangedListener (new ColorTextWatcher ());
this.binding.pick.setOnClickListener (v -> {
if (mPickListener != null) {
mPickListener.onPick (getColor (), getHexColor ());
}
});
}
/**
* Get the hex color code of the current color value.
* @return The hex color code of the current color value.
*/
@NonNull
public String getHexColor () {
return Integer.toHexString (getColor ());
}
/**
* Set the color value of this picker to the given hex color code.
* @param hexCode The hex color code.
* @see #setColor(int)
*/
public void setColor (final String hexCode) {
setColor (parseColor (hexCode));
}
/**
* Set the color value for this color picker.
* this will in turn update value of the sliders
* and the color preview.
* @param color The new color value.
*/
public void setColor (int color) {
this.alpha = alpha (color);
this.red = red (color);
this.green = green(color);
this.blue = blue (color);
this.binding.alphaSlider.setValue (alpha);
this.binding.redSlider.setValue (red);
this.binding.greenSlider.setValue (green);
this.binding.blueSlider.setValue (blue);
this.binding.colorPreview.setBackgroundColor (color);
updatePreview ();
}
/**
* Get the int value of the color from the current
* values of alpha, red, green and blue color values.
* @return The int color value.
*/
public int getColor () {
return argb (alpha, red, green, blue);
}
/**
* Call this method to update the preview of the current color.
*/
private void updatePreview () {
this.binding.colorPreview.setBackgroundColor (getColor ());
}
/**
* A listener that can be used to get notified when the user picks a color.
*
* @author Akash Yadav
*/
public interface OnPickListener {
/**
* Called when the user picks a color using the 'Pick' button.
* @param color The integer value of the color.
* @param hexCode The hex color code of the color.
*/
void onPick (int color, String hexCode);
}
/**
* A TextWatcher that is used to listen for text updates in the
* hex color input field.
*/
private class ColorTextWatcher implements TextWatcher {
@Override
public void beforeTextChanged (CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged (Editable s) {
}
@Override
public void onTextChanged (CharSequence s, int start, int before, int count) {
try {
final var color = parseColor ("#" + s);
setColor (color);
} catch (Exception e) {
// May happen due to invalid color values
// Simply ignore
}
}
}
}
@@ -17,7 +17,8 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:paddingBottom="16dp">
<View
android:id="@+id/color_preview"
@@ -34,9 +35,13 @@
android:layout_height="wrap_content"
android:valueFrom="0"
android:valueTo="255"
android:stepSize="1"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
app:thumbColor="@android:color/white"
app:trackColorActive="@android:color/white"
app:tickVisible="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/color_preview"/>
@@ -47,9 +52,13 @@
android:layout_height="wrap_content"
android:valueFrom="0"
android:valueTo="255"
android:stepSize="1"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:layout_marginTop="8dp"
app:thumbColor="@android:color/holo_red_light"
app:trackColorActive="@android:color/holo_red_light"
app:tickVisible="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/alpha_slider"/>
@@ -60,9 +69,13 @@
android:layout_height="wrap_content"
android:valueFrom="0"
android:valueTo="255"
android:stepSize="1"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:layout_marginTop="8dp"
app:thumbColor="@android:color/holo_green_light"
app:trackColorActive="@android:color/holo_green_light"
app:tickVisible="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/red_slider"/>
@@ -74,9 +87,13 @@
android:layout_height="wrap_content"
android:valueFrom="0"
android:valueTo="255"
android:stepSize="1"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:layout_marginTop="8dp"
app:thumbColor="@android:color/holo_blue_dark"
app:trackColorActive="@android:color/holo_blue_dark"
app:tickVisible="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/green_slider"/>
@@ -86,9 +103,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/msg_color_picker_pick"
android:layout_marginTop="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:textColor="@android:color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/blue_slider"/>
@@ -99,17 +117,17 @@
android:hint="@string/msg_hex_color_code"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:layout_marginTop="8dp"
android:minWidth="100dp"
app:startIconDrawable="@drawable/ic_hex_icon"
app:counterMaxLength="8"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/pick"
app:layout_constraintTop_toBottomOf="@id/blue_slider">
<com.google.android.material.textfield.TextInputEditText
android:digits="abcdef0123456789"
android:layout_width="wrap_content"
android:maxLength="8"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>