Skip to content

Commit

Permalink
Add an optionnal name to the color items.
Browse files Browse the repository at this point in the history
The user can edit the name of a color item from the ColorDetailActivity.
In the ColorItemAdapter, if a color item does not have a name then its hexadecimal code will be used.
  • Loading branch information
vbarthel-fr committed May 21, 2015
1 parent 97b1bfb commit 97bf89f
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@
import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
Expand All @@ -31,9 +34,11 @@
import fr.tvbarthel.apps.cameracolorpicker.data.ColorItem;
import fr.tvbarthel.apps.cameracolorpicker.data.ColorItems;
import fr.tvbarthel.apps.cameracolorpicker.fragments.DeleteColorDialogFragment;
import fr.tvbarthel.apps.cameracolorpicker.fragments.EditTextDialogFragment;
import fr.tvbarthel.apps.cameracolorpicker.utils.ClipDatas;

public class ColorDetailActivity extends AppCompatActivity implements View.OnClickListener, DeleteColorDialogFragment.Callback {
public class ColorDetailActivity extends AppCompatActivity implements View.OnClickListener,
DeleteColorDialogFragment.Callback, EditTextDialogFragment.Callback {

/**
* A key for passing a color item as extra.
Expand Down Expand Up @@ -77,6 +82,11 @@ public class ColorDetailActivity extends AppCompatActivity implements View.OnCli
*/
private static final String FILE_PROVIDER_AUTHORITY = "fr.tvbarthel.apps.cameracolorpicker.fileprovider";

/**
* A request code to use in {@link EditTextDialogFragment#newInstance(int, int, int, int, int, String)}.
*/
private static final int REQUEST_CODE_EDIT_COLOR_ITEM_NAME = 15;

public static void startWithColorItem(Context context, ColorItem colorItem, View colorPreviewClicked,
boolean canBeDeleted) {
final boolean isActivity = context instanceof Activity;
Expand Down Expand Up @@ -161,6 +171,13 @@ protected void onCreate(Bundle savedInstanceState) {
final Rect startBounds = intent.getParcelableExtra(EXTRA_START_BOUNDS);
mCanBeDeleted = intent.getBooleanExtra(EXTRA_CAN_BE_DELETED, true);

// Set the title of the activity with the name of the color, if not null.
if (!TextUtils.isEmpty(mColorItem.getName())) {
setTitle(mColorItem.getName());
} else {
setTitle(mColorItem.getHexString());
}

// Create a rect that will be used to retrieve the stop bounds.
final Rect stopBounds = new Rect();

Expand Down Expand Up @@ -266,6 +283,13 @@ public boolean onOptionsItemSelected(MenuItem item) {
finish();
} else if (id == R.id.menu_color_detail_action_share) {
return handleActionShare();
} else if (id == R.id.menu_color_detail_action_edit) {
EditTextDialogFragment.newInstance(REQUEST_CODE_EDIT_COLOR_ITEM_NAME,
R.string.activity_color_detail_edit_text_dialog_fragment_title,
R.string.activity_color_detail_edit_text_dialog_fragment_positive_button,
android.R.string.cancel,
mColorItem.getHexString(),
mColorItem.getName(), true).show(getSupportFragmentManager(), null);
}

return super.onOptionsItemSelected(item);
Expand Down Expand Up @@ -300,6 +324,25 @@ public void onColorDeletionConfirmed(@NonNull ColorItem colorItemToDelete) {
}
}

@Override
public void onEditTextDialogFragmentPositiveButtonClick(int requestCode, String text) {
if (requestCode == REQUEST_CODE_EDIT_COLOR_ITEM_NAME) {
if (TextUtils.isEmpty(text)) {
setTitle(mColorItem.getHexString());
} else {
setTitle(text);
}

mColorItem.setName(text);
ColorItems.saveColorItem(this, mColorItem);
}
}

@Override
public void onEditTextDialogFragmentNegativeButtonClick(int requestCode) {
// nothing to do here.
}


protected void clipColor(int labelResourceId, CharSequence colorString) {
ClipDatas.clipPainText(this, getString(labelResourceId), colorString);
Expand Down Expand Up @@ -379,5 +422,4 @@ private boolean handleActionShare() {

return handled;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void onClick(View v) {
R.string.activity_palette_creation_edit_text_dialog_fragment_title,
R.string.activity_palette_creation_edit_text_dialog_fragment_positive_button,
android.R.string.cancel,
R.string.activity_palette_creation_edit_text_dialog_fragment_hint,
getString(R.string.activity_palette_creation_edit_text_dialog_fragment_hint),
null);
editTextDialogFragment.show(getSupportFragmentManager(), null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ private boolean handleActionEditName() {
R.string.activity_palette_detail_edit_palette_name_dialog_title,
R.string.activity_palette_detail_edit_palette_name_dialog_positive_action,
android.R.string.cancel,
R.string.activity_palette_detail_edit_palette_name_dialog_hint,
getString(R.string.activity_palette_detail_edit_palette_name_dialog_hint),
mPalette.getName()).show(getSupportFragmentManager(), null);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.content.Context;
import android.graphics.PorterDuff;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
Expand Down Expand Up @@ -59,7 +60,11 @@ protected View createView(ViewGroup parent) {
protected void bindViewHolder(ViewHolder viewHolder, int position) {
final ColorItem colorItem = getItem(position);
viewHolder.mColorPreview.getBackground().setColorFilter(colorItem.getColor(), PorterDuff.Mode.MULTIPLY);
viewHolder.mColorText.setText(colorItem.getHexString());
if (!TextUtils.isEmpty(colorItem.getName())) {
viewHolder.mColorText.setText(colorItem.getName());
} else {
viewHolder.mColorText.setText(colorItem.getHexString());
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public class ColorItem implements Parcelable {
*/
protected int mColor;

/**
* An optional name that the user can give to a color.
*/
protected String mName;

/**
* A long representing the creation time of the color. (In milliseconds).
*/
Expand Down Expand Up @@ -63,6 +68,7 @@ private ColorItem(Parcel in) {
this.mId = in.readLong();
this.mColor = in.readInt();
this.mCreationTime = in.readLong();
this.mName = in.readString();
}

/**
Expand Down Expand Up @@ -154,6 +160,24 @@ public String getHsvString() {
return mHsvString;
}

/**
* Get the name of the color.
*
* @return the name of the color.
*/
public String getName() {
return mName;
}

/**
* Set the name of the color.
*
* @param name the new name of the color.
*/
public void setName(String name) {
mName = name;
}

/**
* Make a human readable representation of the hexadecimal value of a color.
*
Expand Down Expand Up @@ -197,6 +221,7 @@ public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.mId);
dest.writeInt(this.mColor);
dest.writeLong(this.mCreationTime);
dest.writeString(this.mName);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,26 @@ public static boolean saveColorItem(Context context, ColorItem colorToSave) {
final List<ColorItem> savedColorsItems = getSavedColorItems(context);
final SharedPreferences.Editor editor = getPreferences(context).edit();
final List<ColorItem> colorItems = new ArrayList<>(savedColorsItems.size() + 1);
colorItems.addAll(savedColorsItems);

// Add the saved color items except the one with the same ID. It will be overridden.
final int size = savedColorsItems.size();
for (int i = 0; i < size; i++) {
final ColorItem candidate = savedColorsItems.get(i);
if (candidate.getId() != colorToSave.getId()) {
colorItems.add(candidate);
}
}

// Add the new color to save
colorItems.add(colorToSave);

editor.putString(KEY_SAVED_COLOR_ITEMS, GSON.toJson(colorItems));

return editor.commit();
}



/**
* Delete a {@link fr.tvbarthel.apps.cameracolorpicker.data.ColorItem}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,38 +55,67 @@ public class EditTextDialogFragment extends DialogFragment {
/**
* A key for passing the resource id of the hint text.
*/
private static final String ARG_EDIT_TEXT_HINT_RESOURCE_ID = "EditTextDialogFragment.Args.ARG_EDIT_TEXT_HINT_RESOURCE_ID";
private static final String ARG_EDIT_TEXT_HINT = "EditTextDialogFragment.Args.ARG_EDIT_TEXT_HINT";

/**
* A key for passing the initial text value.
*/
private static final String ARG_EDIT_TEXT_INITIAL_TEXT = "EditTextDialogFragment.Args.ARG_EDIT_TEXT_INITIAL_TEXT";

/**
* A key for allowing empty string.
*/
private static final String ARG_ALLOW_EMPTY_STRING = "EditTextDialogFragment.Args.ARG_ALLOW_EMPTY_STRING";

/**
* Create a new instance of a {@link EditTextDialogFragment} to ask the user to define the name of a {@link Palette}.
*
* @param requestCode the request code
* @param titleResourceId the resource id of the title.
* @param positiveButtonResourceId the resource id of the positive button.
* @param negativeButtonResourceId the resource id of the negative button.
* @param editTextHintResourceId the resource id of the edit text hint.
* @param editTextHint the edit text hint.
* @param editTextInitialText the initial text of the edit text.
* @return the newly created {@link EditTextDialogFragment}.
*/
public static EditTextDialogFragment newInstance(int requestCode,
@StringRes int titleResourceId,
@StringRes int positiveButtonResourceId,
@StringRes int negativeButtonResourceId,
@StringRes int editTextHintResourceId,
String editTextHint,
String editTextInitialText) {
return newInstance(requestCode, titleResourceId, positiveButtonResourceId,
negativeButtonResourceId, editTextHint, editTextInitialText, false);
}

/**
* Create a new instance of a {@link EditTextDialogFragment} to ask the user to define the name of a {@link Palette}.
*
* @param requestCode the request code
* @param titleResourceId the resource id of the title.
* @param positiveButtonResourceId the resource id of the positive button.
* @param negativeButtonResourceId the resource id of the negative button.
* @param editTextHint the edit text hint.
* @param editTextInitialText the initial text of the edit text.
* @param allowEmptyString if true empty string will be allowed, otherwise a 'nope' animation will be played if the user tries to validate an empty string.
* @return the newly created {@link EditTextDialogFragment}.
*/
public static EditTextDialogFragment newInstance(int requestCode,
@StringRes int titleResourceId,
@StringRes int positiveButtonResourceId,
@StringRes int negativeButtonResourceId,
String editTextHint,
String editTextInitialText,
boolean allowEmptyString) {
final EditTextDialogFragment instance = new EditTextDialogFragment();
final Bundle args = new Bundle();
args.putInt(ARG_REQUEST_CODE, requestCode);
args.putInt(ARG_TITLE_RESOURCE_ID, titleResourceId);
args.putInt(ARG_POSITIVE_BUTTON_RESOURCE_ID, positiveButtonResourceId);
args.putInt(ARG_NEGATIVE_BUTTON_RESOURCE_ID, negativeButtonResourceId);
args.putInt(ARG_EDIT_TEXT_HINT_RESOURCE_ID, editTextHintResourceId);
args.putString(ARG_EDIT_TEXT_HINT, editTextHint);
args.putString(ARG_EDIT_TEXT_INITIAL_TEXT, editTextInitialText);
args.putBoolean(ARG_ALLOW_EMPTY_STRING, allowEmptyString);
instance.setArguments(args);
return instance;
}
Expand All @@ -96,12 +125,27 @@ public static EditTextDialogFragment newInstance(int requestCode,
*/
private Callback mCallback;

/**
* The {@link EditText}
*/
private EditText mEditText;

/**
* An {@link ObjectAnimator} for playing a nope animation when the users tries to validate an empty string,
* and mAllowEmptyString is false.
*/
private ObjectAnimator mNopeAnimator;

/**
* The request code.
*/
private int mRequestCode;

/**
* If true the users can validate empty string.
*/
private boolean mAllowEmptyString;

/**
* Default Constructor.
* <p/>
Expand Down Expand Up @@ -138,26 +182,27 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {

// Extract the arguments
mRequestCode = args.getInt(ARG_REQUEST_CODE);
mAllowEmptyString= args.getBoolean(ARG_ALLOW_EMPTY_STRING);
final int titleResourceId = args.getInt(ARG_TITLE_RESOURCE_ID);
final int positiveButtonResourceId = args.getInt(ARG_POSITIVE_BUTTON_RESOURCE_ID);
final int negativeButtonResourceId = args.getInt(ARG_NEGATIVE_BUTTON_RESOURCE_ID);
final int editTextHintResourceId = args.getInt(ARG_EDIT_TEXT_HINT_RESOURCE_ID);
final String editTextHint = args.getString(ARG_EDIT_TEXT_HINT);
final String editTextInitialText = args.getString(ARG_EDIT_TEXT_INITIAL_TEXT);

final Context context = getActivity();
final View view = LayoutInflater.from(context).inflate(R.layout.fragment_dialog_edit_text, null);

mEditText = (EditText) view.findViewById(R.id.fragment_dialog_edit_text_edit_text);
mEditText.setHint(editTextHintResourceId);
mEditText.setHint(editTextHint);
mEditText.setText(editTextInitialText);
mNopeAnimator = Views.nopeAnimation(mEditText, mEditText.getPaddingLeft());

final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setView(view)
.setTitle(titleResourceId)
.setCancelable(true)
// We don't want the positive button to always dismiss the alert dialog.
// The onClickListener is set in an OnShowListener bellow.
// We don't want the positive button to always dismiss the alert dialog.
// The onClickListener is set in an OnShowListener bellow.
.setPositiveButton(positiveButtonResourceId, null)
.setNegativeButton(negativeButtonResourceId, new DialogInterface.OnClickListener() {
@Override
Expand Down Expand Up @@ -199,7 +244,7 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

private void handlePositiveClick() {
final String text = mEditText.getText().toString();
if (TextUtils.isEmpty(text)) {
if (TextUtils.isEmpty(text) && !mAllowEmptyString) {
if (mNopeAnimator.isRunning()) {
mNopeAnimator.cancel();
}
Expand Down Expand Up @@ -240,13 +285,17 @@ private void ensureSaneArgs(Bundle args) {
throw new IllegalArgumentException("Missing negative button resource id. Please use EditTextDialogFragment#newInstance()");
}

if (!args.containsKey(ARG_EDIT_TEXT_HINT_RESOURCE_ID)) {
if (!args.containsKey(ARG_EDIT_TEXT_HINT)) {
throw new IllegalArgumentException("Missing edit text hint resource id. Please use EditTextDialogFragment#newInstance()");
}

if (!args.containsKey(ARG_EDIT_TEXT_INITIAL_TEXT)) {
throw new IllegalArgumentException("Missing edit text initial text. Please use EditTextDialogFragment#newInstance()");
}

if (!args.containsKey(ARG_ALLOW_EMPTY_STRING)) {
throw new IllegalArgumentException("Missing edit text initial text. Please use EditTextDialogFragment#newInstance()");
}
}

/**
Expand All @@ -257,15 +306,15 @@ public interface Callback {
/**
* Called when the user has just clicked on the positive button.
*
* @param requestCode the request code passed in the {@link EditTextDialogFragment#newInstance(int, int, int, int, int, String)} method.
* @param requestCode the request code passed in the {@link EditTextDialogFragment#newInstance(int, int, int, int, String, String)} method.
* @param text the text of the edit text.
*/
void onEditTextDialogFragmentPositiveButtonClick(int requestCode, String text);

/**
* Called when the user has just clicked the negative button.
*
* @param requestCode the request code passed in the {@link EditTextDialogFragment#newInstance(int, int, int, int, int, String)} method.
* @param requestCode the request code passed in the {@link EditTextDialogFragment#newInstance(int, int, int, int, String, String)} method.
*/
void onEditTextDialogFragmentNegativeButtonClick(int requestCode);
}
Expand Down
Loading

0 comments on commit 97bf89f

Please sign in to comment.