/* * Copyright (C) 2014 Clark Scheff * * Licensed 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless 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. */ package com.scheffsblend.iconfilters; import android.content.Context; import android.content.DialogInterface; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; import java.util.ArrayList; import java.util.HashMap; class FilterListAdapter extends BaseAdapter { public static final int FILTER_TYPE_HUE = 0; public static final int FILTER_TYPE_SATURATION = 1; public static final int FILTER_TYPE_BRIGHTNESS = 2; public static final int FILTER_TYPE_CONTRAST = 3; public static final int FILTER_TYPE_ALPHA = 4; public static final int FILTER_TYPE_INVERT = 5; public static final int FILTER_TYPE_TINT = 6; final int INVALID_ID = -1; ArrayList<FilterItem> mFilterItems = new ArrayList<FilterItem>(); LayoutInflater mInflater; HashMap<FilterItem, Integer> mIdMap = new HashMap<FilterItem, Integer>(); Context mContext; class FilterItem { int filterType; String label; public FilterItem(int type, String label) { filterType = type; this.label = label; } } class AdjustableFilter extends FilterItem { int min = 0; int max = 100; int current = 0; public AdjustableFilter(int type, int min, int max, int defValue, String label) { super(type, label); this.min = min; this.max = max; this.current = defValue; } } class ToggleableFilter extends FilterItem { boolean enabled = false; public ToggleableFilter(int type, String label) { super(type, label); } } class ValueFilter extends FilterItem { int value; public ValueFilter(int type, String label) { super(type, label); } } public FilterListAdapter(Context context) { mContext = context; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return mFilterItems.size(); } @Override public Object getItem(int i) { return mFilterItems.get(i); } @Override public long getItemId(int position) { if (position < 0 || position >= mIdMap.size()) { return INVALID_ID; } FilterItem item = (FilterItem) getItem(position); return mIdMap.get(item); } @Override public View getView(int i, View convertView, ViewGroup parent) { switch(mFilterItems.get(i).filterType) { case FILTER_TYPE_HUE: case FILTER_TYPE_SATURATION: case FILTER_TYPE_BRIGHTNESS: case FILTER_TYPE_CONTRAST: case FILTER_TYPE_ALPHA: convertView = newAdjustableView(parent); bindAdjustableView(i, convertView); break; case FILTER_TYPE_INVERT: convertView = newToggleableView(parent); bindToggleableView(i, convertView); break; case FILTER_TYPE_TINT: convertView = newTintView(parent); bindTintView(i, convertView); break; } View removeFilter = convertView.findViewById(R.id.remove_filter); removeFilter.setTag(mFilterItems.get(i)); removeFilter.setOnClickListener(mRemoveFilterClickListener); return convertView; } @Override public boolean hasStableIds() { return true; } private View newAdjustableView(ViewGroup parent) { View v = mInflater.inflate(R.layout.adjustable_filter_item, parent, false); return v; } private void bindAdjustableView(int i, View v) { AdjustableFilter f = (AdjustableFilter) mFilterItems.get(i); SeekBar sb = (SeekBar) v.findViewById(R.id.seekbar); sb.setMax(f.max - f.min); sb.setProgress(f.current - f.min); TextView min = (TextView) v.findViewById(R.id.min_value); min.setText("" + f.min); TextView max = (TextView) v.findViewById(R.id.max_value); max.setText("" + f.max); TextView current = (TextView) v.findViewById(R.id.current_value); current.setText("" + f.current); TextView title = (TextView) v.findViewById(R.id.title); title.setText(f.label); current.setTag(f); sb.setTag(current); sb.setOnSeekBarChangeListener(mSeekBarChangeListener); } private View newToggleableView(ViewGroup parent) { View v = mInflater.inflate(R.layout.toggleable_filter_item, parent, false); return v; } private void bindToggleableView(int i, View v) { ToggleableFilter f = (ToggleableFilter) mFilterItems.get(i); TextView title = (TextView) v.findViewById(R.id.title); title.setText(f.label); CheckBox cb = (CheckBox) v.findViewById(R.id.toggle); cb.setChecked(f.enabled); cb.setTag(f); cb.setOnCheckedChangeListener(mCheckChangedListener); } private View newTintView(ViewGroup parent) { View v = mInflater.inflate(R.layout.color_filter_item, parent, false); return v; } private void bindTintView(int i, View v) { final ValueFilter f = (ValueFilter) mFilterItems.get(i); TextView title = (TextView) v.findViewById(R.id.title); title.setText(f.label); final View color = v.findViewById(R.id.color); color.setBackgroundColor(f.value); color.setTag(f); color.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { final ColorPickerDialog cpd = new ColorPickerDialog(mContext, f.value); cpd.setTitle(R.string.color_picker_dialog_title); cpd.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getString(R.string.ok), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { ValueFilter f = (ValueFilter) color.getTag(); f.value = cpd.getColor(); color.setBackgroundColor(f.value); notifyDataSetChanged(); } }); cpd.setButton(DialogInterface.BUTTON_NEGATIVE, mContext.getString(R.string.cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { // nothing to do here } }); cpd.setAlphaSliderVisible(true); cpd.show(); } }); } @Override public int getViewTypeCount() { return 3; } @Override public int getItemViewType(int position) { FilterItem item = mFilterItems.get(position); switch (item.filterType) { case FILTER_TYPE_HUE: case FILTER_TYPE_SATURATION: case FILTER_TYPE_BRIGHTNESS: case FILTER_TYPE_CONTRAST: case FILTER_TYPE_ALPHA: return 0; case FILTER_TYPE_INVERT: return 1; case FILTER_TYPE_TINT: return 2; default: throw new IllegalArgumentException("Invalid filter type"); } } @Override public void notifyDataSetChanged() { if (mContext instanceof FilterDesignerActivity) { ColorFilterUtils.Builder b = new ColorFilterUtils.Builder(); for (FilterItem f : mFilterItems) { switch (f.filterType) { case FILTER_TYPE_HUE: b.hue(((AdjustableFilter) f).current); break; case FILTER_TYPE_SATURATION: b.saturate(((AdjustableFilter) f).current); break; case FILTER_TYPE_BRIGHTNESS: b.brightness(((AdjustableFilter) f).current); break; case FILTER_TYPE_CONTRAST: b.contrast(((AdjustableFilter) f).current); break; case FILTER_TYPE_ALPHA: b.alpha(((AdjustableFilter) f).current); break; case FILTER_TYPE_INVERT: if (((ToggleableFilter) f).enabled) { b.invertColors(); } break; case FILTER_TYPE_TINT: b.tint(((ValueFilter) f).value); break; } } ((FilterDesignerActivity) mContext).updateColorFilter(b.build()); } super.notifyDataSetChanged(); } public void addFilter(int type) { FilterItem f = null; switch (type) { case FILTER_TYPE_HUE: f = new AdjustableFilter(type, -180, 180, 0, mContext.getString(R.string.filter_hue)); break; case FILTER_TYPE_SATURATION: f = new AdjustableFilter(type, 0, 200, 100, mContext.getString(R.string.filter_saturation)); break; case FILTER_TYPE_BRIGHTNESS: f = new AdjustableFilter(type, 0, 200, 100, mContext.getString(R.string.filter_brightness)); break; case FILTER_TYPE_CONTRAST: f = new AdjustableFilter(type, -100, 100, 0, mContext.getString(R.string.filter_contrast)); break; case FILTER_TYPE_ALPHA: f = new AdjustableFilter(type, 0, 100, 100, mContext.getString(R.string.filter_alpha)); break; case FILTER_TYPE_INVERT: f = new ToggleableFilter(type, mContext.getString(R.string.filter_invert)); break; case FILTER_TYPE_TINT: f = new ValueFilter(type, mContext.getString(R.string.filter_tint)); ((ValueFilter) f).value = 0xff000000; break; } if (f != null) { mIdMap.put(f, mFilterItems.size()); mFilterItems.add(f); notifyDataSetChanged(); } } public ArrayList<FilterItem> getFilterList() { return mFilterItems; } private OnSeekBarChangeListener mSeekBarChangeListener = new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int i, boolean b) { TextView tv = (TextView) seekBar.getTag(); AdjustableFilter f = (AdjustableFilter) tv.getTag(); f.current = i + f.min; tv.setText("" + f.current); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { notifyDataSetChanged(); } }; private OnCheckedChangeListener mCheckChangedListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { ToggleableFilter f = (ToggleableFilter) compoundButton.getTag(); f.enabled = b; notifyDataSetChanged(); } }; private View.OnClickListener mRemoveFilterClickListener = new View.OnClickListener() { @Override public void onClick(View view) { FilterItem f = (FilterItem) view.getTag(); if (f != null) mFilterItems.remove(f); mIdMap.clear(); for (int i = 0; i < mFilterItems.size(); i++) { mIdMap.put(mFilterItems.get(i), i); } notifyDataSetChanged(); } }; }