1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.gallery3d.filtershow.editors;
17
18import android.content.Context;
19import android.graphics.Bitmap;
20import android.os.Handler;
21import android.view.LayoutInflater;
22import android.view.MenuItem;
23import android.view.View;
24import android.view.View.OnClickListener;
25import android.view.ViewGroup;
26import android.widget.LinearLayout;
27import android.widget.PopupMenu;
28import android.widget.SeekBar;
29import android.widget.SeekBar.OnSeekBarChangeListener;
30
31import android.widget.TextView;
32import com.android.gallery3d.R;
33import com.android.gallery3d.filtershow.FilterShowActivity;
34import com.android.gallery3d.filtershow.controller.BasicParameterStyle;
35import com.android.gallery3d.filtershow.controller.BitmapCaller;
36import com.android.gallery3d.filtershow.controller.FilterView;
37import com.android.gallery3d.filtershow.controller.Parameter;
38import com.android.gallery3d.filtershow.filters.FilterBasicRepresentation;
39import com.android.gallery3d.filtershow.filters.FilterChanSatRepresentation;
40import com.android.gallery3d.filtershow.filters.FilterRepresentation;
41import com.android.gallery3d.filtershow.imageshow.MasterImage;
42import com.android.gallery3d.filtershow.pipeline.ImagePreset;
43
44public class EditorChanSat extends ParametricEditor implements OnSeekBarChangeListener, FilterView {
45    public static final int ID = R.id.editorChanSat;
46    private final String LOGTAG = "EditorGrunge";
47    private SwapButton mButton;
48    private final Handler mHandler = new Handler();
49
50    private SeekBar mMainBar;
51    private SeekBar mRedBar;
52    private SeekBar mYellowBar;
53    private SeekBar mGreenBar;
54    private SeekBar mCyanBar;
55    private SeekBar mBlueBar;
56    private SeekBar mMagentaBar;
57    private TextView mMainValue;
58    private TextView mRedValue;
59    private TextView mYellowValue;
60    private TextView mGreenValue;
61    private TextView mCyanValue;
62    private TextView mBlueValue;
63    private TextView mMagentaValue;
64
65    int[] mMenuStrings = {
66            R.string.editor_chan_sat_main,
67            R.string.editor_chan_sat_red,
68            R.string.editor_chan_sat_yellow,
69            R.string.editor_chan_sat_green,
70            R.string.editor_chan_sat_cyan,
71            R.string.editor_chan_sat_blue,
72            R.string.editor_chan_sat_magenta
73    };
74
75    String mCurrentlyEditing = null;
76
77    public EditorChanSat() {
78        super(ID, R.layout.filtershow_default_editor, R.id.basicEditor);
79    }
80
81    @Override
82    public String calculateUserMessage(Context context, String effectName, Object parameterValue) {
83        FilterRepresentation rep = getLocalRepresentation();
84        if (rep == null || !(rep instanceof FilterChanSatRepresentation)) {
85            return "";
86        }
87        FilterChanSatRepresentation csrep = (FilterChanSatRepresentation) rep;
88        int mode = csrep.getParameterMode();
89        String paramString;
90
91        paramString = mContext.getString(mMenuStrings[mode]);
92
93        int val = csrep.getCurrentParameter();
94        return paramString + ((val > 0) ? " +" : " ") + val;
95    }
96
97    @Override
98    public void openUtilityPanel(final LinearLayout accessoryViewList) {
99        mButton = (SwapButton) accessoryViewList.findViewById(R.id.applyEffect);
100        mButton.setText(mContext.getString(R.string.editor_chan_sat_main));
101
102        if (useCompact(mContext)) {
103            final PopupMenu popupMenu = new PopupMenu(mImageShow.getActivity(), mButton);
104
105            popupMenu.getMenuInflater().inflate(R.menu.filtershow_menu_chan_sat,
106                    popupMenu.getMenu());
107
108            popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
109                @Override
110                public boolean onMenuItemClick(MenuItem item) {
111                    selectMenuItem(item);
112                    return true;
113                }
114            });
115            mButton.setOnClickListener(new OnClickListener() {
116                @Override
117                public void onClick(View arg0) {
118                    popupMenu.show();
119                    ((FilterShowActivity)mContext).onShowMenu(popupMenu);
120                }
121            });
122            mButton.setListener(this);
123
124            FilterChanSatRepresentation csrep = getChanSatRep();
125            String menuString = mContext.getString(mMenuStrings[0]);
126            switchToMode(csrep, FilterChanSatRepresentation.MODE_MASTER, menuString);
127        } else {
128            mButton.setText(mContext.getString(R.string.saturation));
129        }
130    }
131
132    @Override
133    public void reflectCurrentFilter() {
134        if (useCompact(mContext)) {
135            super.reflectCurrentFilter();
136            updateText();
137            return;
138        }
139        mLocalRepresentation = null;
140        if (getLocalRepresentation() != null
141                && getLocalRepresentation() instanceof FilterChanSatRepresentation) {
142            FilterChanSatRepresentation rep =
143                    (FilterChanSatRepresentation) getLocalRepresentation();
144            int value = rep.getValue(FilterChanSatRepresentation.MODE_MASTER);
145            mMainBar.setProgress(value + 100);
146            mMainValue.setText("" + value);
147            value = rep.getValue(FilterChanSatRepresentation.MODE_RED);
148            mRedBar.setProgress(value + 100);
149            mRedValue.setText("" + value);
150            value = rep.getValue(FilterChanSatRepresentation.MODE_YELLOW);
151            mYellowBar.setProgress(value + 100);
152            mYellowValue.setText("" + value);
153            value = rep.getValue(FilterChanSatRepresentation.MODE_GREEN);
154            mGreenBar.setProgress(value + 100);
155            mGreenValue.setText("" + value);
156            value = rep.getValue(FilterChanSatRepresentation.MODE_CYAN);
157            mCyanBar.setProgress(value + 100);
158            mCyanValue.setText("" + value);
159            value = rep.getValue(FilterChanSatRepresentation.MODE_BLUE);
160            mBlueBar.setProgress(value + 100);
161            mBlueValue.setText("" + value);
162            value = rep.getValue(FilterChanSatRepresentation.MODE_MAGENTA);
163            mMagentaBar.setProgress(value + 100);
164            mMagentaValue.setText("" + value);
165            String text = mContext.getString(rep.getTextId()).toUpperCase();
166            mFilterTitle.setText(text);
167            updateText();
168        }
169    }
170
171    @Override
172    public void setUtilityPanelUI(View actionButton, View editControl) {
173        if (useCompact(mContext)) {
174            super.setUtilityPanelUI(actionButton, editControl);
175            return;
176        }
177        mActionButton = actionButton;
178        mEditControl = editControl;
179        mEditTitle.setCompoundDrawables(null, null, null, null);
180        LinearLayout group = (LinearLayout) editControl;
181        LayoutInflater inflater =
182                (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
183        LinearLayout controls = (LinearLayout) inflater.inflate(
184                R.layout.filtershow_saturation_controls, group, false);
185        ViewGroup.LayoutParams lp = new LinearLayout.LayoutParams(
186                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
187        controls.setLayoutParams(lp);
188        group.removeAllViews();
189        group.addView(controls);
190        mMainBar = (SeekBar) controls.findViewById(R.id.mainSeekbar);
191        mMainBar.setMax(200);
192        mMainBar.setOnSeekBarChangeListener(this);
193        mMainValue = (TextView) controls.findViewById(R.id.mainValue);
194        mRedBar = (SeekBar) controls.findViewById(R.id.redSeekBar);
195        mRedBar.setMax(200);
196        mRedBar.setOnSeekBarChangeListener(this);
197        mRedValue = (TextView) controls.findViewById(R.id.redValue);
198        mYellowBar = (SeekBar) controls.findViewById(R.id.yellowSeekBar);
199        mYellowBar.setMax(200);
200        mYellowBar.setOnSeekBarChangeListener(this);
201        mYellowValue = (TextView) controls.findViewById(R.id.yellowValue);
202        mGreenBar = (SeekBar) controls.findViewById(R.id.greenSeekBar);
203        mGreenBar.setMax(200);
204        mGreenBar.setOnSeekBarChangeListener(this);
205        mGreenValue = (TextView) controls.findViewById(R.id.greenValue);
206        mCyanBar = (SeekBar) controls.findViewById(R.id.cyanSeekBar);
207        mCyanBar.setMax(200);
208        mCyanBar.setOnSeekBarChangeListener(this);
209        mCyanValue = (TextView) controls.findViewById(R.id.cyanValue);
210        mBlueBar = (SeekBar) controls.findViewById(R.id.blueSeekBar);
211        mBlueBar.setMax(200);
212        mBlueBar.setOnSeekBarChangeListener(this);
213        mBlueValue = (TextView) controls.findViewById(R.id.blueValue);
214        mMagentaBar = (SeekBar) controls.findViewById(R.id.magentaSeekBar);
215        mMagentaBar.setMax(200);
216        mMagentaBar.setOnSeekBarChangeListener(this);
217        mMagentaValue = (TextView) controls.findViewById(R.id.magentaValue);
218    }
219
220    public int getParameterIndex(int id) {
221        switch (id) {
222            case R.id.editor_chan_sat_main:
223                return FilterChanSatRepresentation.MODE_MASTER;
224            case R.id.editor_chan_sat_red:
225                return FilterChanSatRepresentation.MODE_RED;
226            case R.id.editor_chan_sat_yellow:
227                return FilterChanSatRepresentation.MODE_YELLOW;
228            case R.id.editor_chan_sat_green:
229                return FilterChanSatRepresentation.MODE_GREEN;
230            case R.id.editor_chan_sat_cyan:
231                return FilterChanSatRepresentation.MODE_CYAN;
232            case R.id.editor_chan_sat_blue:
233                return FilterChanSatRepresentation.MODE_BLUE;
234            case R.id.editor_chan_sat_magenta:
235                return FilterChanSatRepresentation.MODE_MAGENTA;
236        }
237        return -1;
238    }
239
240    @Override
241    public void detach() {
242        if (mButton == null) {
243            return;
244        }
245        mButton.setListener(null);
246        mButton.setOnClickListener(null);
247    }
248
249    private void updateSeekBar(FilterChanSatRepresentation rep) {
250        mControl.updateUI();
251    }
252
253    @Override
254    protected Parameter getParameterToEdit(FilterRepresentation rep) {
255        if (rep instanceof FilterChanSatRepresentation) {
256            FilterChanSatRepresentation csrep = (FilterChanSatRepresentation) rep;
257            Parameter param = csrep.getFilterParameter(csrep.getParameterMode());
258            if (param instanceof BasicParameterStyle) {
259                param.setFilterView(EditorChanSat.this);
260            }
261            return param;
262        }
263        return null;
264    }
265
266    private FilterChanSatRepresentation getChanSatRep() {
267        FilterRepresentation rep = getLocalRepresentation();
268        if (rep != null
269                && rep instanceof FilterChanSatRepresentation) {
270            FilterChanSatRepresentation csrep = (FilterChanSatRepresentation) rep;
271            return csrep;
272        }
273        return null;
274    }
275
276    @Override
277    public void computeIcon(int n, BitmapCaller caller) {
278        FilterChanSatRepresentation rep = getChanSatRep();
279        if (rep == null) return;
280        rep = (FilterChanSatRepresentation) rep.copy();
281        ImagePreset preset = new ImagePreset();
282        preset.addFilter(rep);
283        Bitmap src = MasterImage.getImage().getThumbnailBitmap();
284        caller.available(src);
285    }
286
287    protected void selectMenuItem(MenuItem item) {
288        if (getLocalRepresentation() != null
289                && getLocalRepresentation() instanceof FilterChanSatRepresentation) {
290            FilterChanSatRepresentation csrep =
291                    (FilterChanSatRepresentation) getLocalRepresentation();
292
293            switchToMode(csrep, getParameterIndex(item.getItemId()), item.getTitle().toString());
294
295        }
296    }
297
298    protected void switchToMode(FilterChanSatRepresentation csrep, int mode, String title) {
299        if (csrep == null) {
300            return;
301        }
302        csrep.setParameterMode(mode);
303        mCurrentlyEditing = title;
304        mButton.setText(mCurrentlyEditing);
305        {
306            Parameter param = getParameterToEdit(csrep);
307
308            control(param, mEditControl);
309        }
310        updateSeekBar(csrep);
311        mView.invalidate();
312    }
313
314    @Override
315    public void onProgressChanged(SeekBar sbar, int progress, boolean arg2) {
316        FilterChanSatRepresentation rep = getChanSatRep();
317        int value = progress - 100;
318        switch (sbar.getId()) {
319            case R.id.mainSeekbar:
320                rep.setParameterMode(FilterChanSatRepresentation.MODE_MASTER);
321                mMainValue.setText("" + value);
322                break;
323            case R.id.redSeekBar:
324                rep.setParameterMode(FilterChanSatRepresentation.MODE_RED);
325                mRedValue.setText("" + value);
326                break;
327            case R.id.yellowSeekBar:
328                rep.setParameterMode(FilterChanSatRepresentation.MODE_YELLOW);
329                mYellowValue.setText("" + value);
330                break;
331            case R.id.greenSeekBar:
332                rep.setParameterMode(FilterChanSatRepresentation.MODE_GREEN);
333                mGreenValue.setText("" + value);
334                break;
335            case R.id.cyanSeekBar:
336                rep.setParameterMode(FilterChanSatRepresentation.MODE_CYAN);
337                mCyanValue.setText("" + value);
338                break;
339            case R.id.blueSeekBar:
340                rep.setParameterMode(FilterChanSatRepresentation.MODE_BLUE);
341                mBlueValue.setText("" + value);
342                break;
343            case R.id.magentaSeekBar:
344                rep.setParameterMode(FilterChanSatRepresentation.MODE_MAGENTA);
345                mMagentaValue.setText("" + value);
346                break;
347        }
348        rep.setCurrentParameter(value);
349        commitLocalRepresentation();
350    }
351
352    @Override
353    public void swapLeft(MenuItem item) {
354        super.swapLeft(item);
355        mButton.setTranslationX(0);
356        mButton.animate().translationX(mButton.getWidth()).setDuration(SwapButton.ANIM_DURATION);
357        Runnable updateButton = new Runnable() {
358            @Override
359            public void run() {
360                mButton.animate().cancel();
361                mButton.setTranslationX(0);
362            }
363        };
364        mHandler.postDelayed(updateButton, SwapButton.ANIM_DURATION);
365        selectMenuItem(item);
366    }
367
368    @Override
369    public void swapRight(MenuItem item) {
370        super.swapRight(item);
371        mButton.setTranslationX(0);
372        mButton.animate().translationX(-mButton.getWidth()).setDuration(SwapButton.ANIM_DURATION);
373        Runnable updateButton = new Runnable() {
374            @Override
375            public void run() {
376                mButton.animate().cancel();
377                mButton.setTranslationX(0);
378            }
379        };
380        mHandler.postDelayed(updateButton, SwapButton.ANIM_DURATION);
381        selectMenuItem(item);
382    }
383}
384