1 /* 2 * Copyright (C) 2012 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 */ 16 17 package com.android.gallery3d.filtershow.editors; 18 19 import android.content.Context; 20 import android.content.res.Configuration; 21 import android.util.AttributeSet; 22 import android.util.Log; 23 import android.view.LayoutInflater; 24 import android.view.Menu; 25 import android.view.MenuItem; 26 import android.view.View; 27 import android.view.ViewGroup; 28 import android.widget.Button; 29 import android.widget.FrameLayout; 30 import android.widget.LinearLayout; 31 import android.widget.PopupMenu; 32 import android.widget.SeekBar; 33 import android.widget.SeekBar.OnSeekBarChangeListener; 34 35 import com.android.gallery3d.R; 36 import com.android.gallery3d.filtershow.controller.Control; 37 import com.android.gallery3d.filtershow.filters.FilterRepresentation; 38 import com.android.gallery3d.filtershow.imageshow.ImageShow; 39 import com.android.gallery3d.filtershow.imageshow.MasterImage; 40 import com.android.gallery3d.filtershow.pipeline.ImagePreset; 41 42 import java.util.ArrayList; 43 import java.util.Collection; 44 45 /** 46 * Base class for Editors Must contain a mImageShow and a top level view 47 */ 48 public class Editor implements OnSeekBarChangeListener, SwapButton.SwapButtonListener { 49 protected Context mContext; 50 protected View mView; 51 protected ImageShow mImageShow; 52 protected FrameLayout mFrameLayout; 53 protected SeekBar mSeekBar; 54 Button mEditTitle; 55 protected Button mFilterTitle; 56 protected int mID; 57 private final String LOGTAG = "Editor"; 58 protected boolean mChangesGeometry = false; 59 protected FilterRepresentation mLocalRepresentation = null; 60 protected byte mShowParameter = SHOW_VALUE_UNDEFINED; 61 private Button mButton; 62 public static byte SHOW_VALUE_UNDEFINED = -1; 63 public static byte SHOW_VALUE_OFF = 0; 64 public static byte SHOW_VALUE_INT = 1; 65 66 public static void hackFixStrings(Menu menu) { 67 int count = menu.size(); 68 for (int i = 0; i < count; i++) { 69 MenuItem item = menu.getItem(i); 70 item.setTitle(item.getTitle().toString().toUpperCase()); 71 } 72 } 73 74 public String calculateUserMessage(Context context, String effectName, Object parameterValue) { 75 return effectName.toUpperCase() + " " + parameterValue; 76 } 77 78 protected Editor(int id) { 79 mID = id; 80 } 81 82 public int getID() { 83 return mID; 84 } 85 86 public byte showParameterValue() { 87 return mShowParameter; 88 } 89 90 public boolean showsSeekBar() { 91 return true; 92 } 93 94 public void setUpEditorUI(View actionButton, View editControl, 95 Button editTitle, Button stateButton) { 96 mEditTitle = editTitle; 97 mFilterTitle = stateButton; 98 mButton = editTitle; 99 MasterImage.getImage().resetGeometryImages(false); 100 setUtilityPanelUI(actionButton, editControl); 101 } 102 103 public boolean showsPopupIndicator() { 104 return false; 105 } 106 107 /** 108 * @param actionButton the would be the area for menu etc 109 * @param editControl this is the black area for sliders etc 110 */ 111 public void setUtilityPanelUI(View actionButton, View editControl) { 112 113 AttributeSet aset; 114 Context context = editControl.getContext(); 115 LayoutInflater inflater = 116 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 117 LinearLayout lp = (LinearLayout) inflater.inflate( 118 R.layout.filtershow_seekbar, (ViewGroup) editControl, true); 119 mSeekBar = (SeekBar) lp.findViewById(R.id.primarySeekBar); 120 mSeekBar.setOnSeekBarChangeListener(this); 121 mSeekBar.setVisibility(View.GONE); 122 if (context.getResources().getConfiguration().orientation 123 == Configuration.ORIENTATION_PORTRAIT) { 124 if (showsSeekBar()) { 125 mSeekBar.setVisibility(View.VISIBLE); 126 } 127 } 128 129 if (mButton != null) { 130 setMenuIcon(showsPopupIndicator()); 131 } 132 } 133 134 @Override 135 public void onProgressChanged(SeekBar sbar, int progress, boolean arg2) { 136 137 } 138 139 public void setPanel() { 140 141 } 142 143 public void createEditor(Context context, FrameLayout frameLayout) { 144 mContext = context; 145 mFrameLayout = frameLayout; 146 mLocalRepresentation = null; 147 } 148 149 protected void unpack(int viewid, int layoutid) { 150 151 if (mView == null) { 152 mView = mFrameLayout.findViewById(viewid); 153 if (mView == null) { 154 LayoutInflater inflater = (LayoutInflater) mContext.getSystemService 155 (Context.LAYOUT_INFLATER_SERVICE); 156 mView = inflater.inflate(layoutid, mFrameLayout, false); 157 mFrameLayout.addView(mView, mView.getLayoutParams()); 158 } 159 } 160 mImageShow = findImageShow(mView); 161 } 162 163 private ImageShow findImageShow(View view) { 164 if (view instanceof ImageShow) { 165 return (ImageShow) view; 166 } 167 if (!(view instanceof ViewGroup)) { 168 return null; 169 } 170 ViewGroup vg = (ViewGroup) view; 171 int n = vg.getChildCount(); 172 for (int i = 0; i < n; i++) { 173 View v = vg.getChildAt(i); 174 if (v instanceof ImageShow) { 175 return (ImageShow) v; 176 } else if (v instanceof ViewGroup) { 177 return findImageShow(v); 178 } 179 } 180 return null; 181 } 182 183 public View getTopLevelView() { 184 return mView; 185 } 186 187 public ImageShow getImageShow() { 188 return mImageShow; 189 } 190 191 public void setVisibility(int visible) { 192 mView.setVisibility(visible); 193 } 194 195 public FilterRepresentation getLocalRepresentation() { 196 if (mLocalRepresentation == null) { 197 ImagePreset preset = MasterImage.getImage().getPreset(); 198 FilterRepresentation filterRepresentation = MasterImage.getImage().getCurrentFilterRepresentation(); 199 mLocalRepresentation = preset.getFilterRepresentationCopyFrom(filterRepresentation); 200 if (mShowParameter == SHOW_VALUE_UNDEFINED && filterRepresentation != null) { 201 boolean show = filterRepresentation.showParameterValue(); 202 mShowParameter = show ? SHOW_VALUE_INT : SHOW_VALUE_OFF; 203 } 204 205 } 206 return mLocalRepresentation; 207 } 208 209 /** 210 * Call this to update the preset in MasterImage with the current representation 211 * returned by getLocalRepresentation. This causes the preview bitmap to be 212 * regenerated. 213 */ 214 public void commitLocalRepresentation() { 215 commitLocalRepresentation(getLocalRepresentation()); 216 } 217 218 /** 219 * Call this to update the preset in MasterImage with a given representation. 220 * This causes the preview bitmap to be regenerated. 221 */ 222 public void commitLocalRepresentation(FilterRepresentation rep) { 223 ArrayList<FilterRepresentation> filter = new ArrayList<FilterRepresentation>(1); 224 filter.add(rep); 225 commitLocalRepresentation(filter); 226 } 227 228 /** 229 * Call this to update the preset in MasterImage with a collection of FilterRepresentations. 230 * This causes the preview bitmap to be regenerated. 231 */ 232 public void commitLocalRepresentation(Collection<FilterRepresentation> reps) { 233 ImagePreset preset = MasterImage.getImage().getPreset(); 234 preset.updateFilterRepresentations(reps); 235 if (mButton != null) { 236 updateText(); 237 } 238 if (mChangesGeometry) { 239 // Regenerate both the filtered and the geometry-only bitmaps 240 MasterImage.getImage().resetGeometryImages(true); 241 } 242 // Regenerate the filtered bitmap. 243 MasterImage.getImage().invalidateFiltersOnly(); 244 preset.fillImageStateAdapter(MasterImage.getImage().getState()); 245 } 246 247 /** 248 * This is called in response to a click to apply and leave the editor. 249 */ 250 public void finalApplyCalled() { 251 commitLocalRepresentation(); 252 } 253 254 protected void updateText() { 255 String s = ""; 256 if (mLocalRepresentation != null) { 257 s = mContext.getString(mLocalRepresentation.getTextId()); 258 } 259 mButton.setText(calculateUserMessage(mContext, s, "")); 260 } 261 262 /** 263 * called after the filter is set and the select is called 264 */ 265 public void reflectCurrentFilter() { 266 mLocalRepresentation = null; 267 FilterRepresentation representation = getLocalRepresentation(); 268 if (representation != null && mFilterTitle != null && representation.getTextId() != 0) { 269 String text = mContext.getString(representation.getTextId()).toUpperCase(); 270 mFilterTitle.setText(text); 271 updateText(); 272 } 273 } 274 275 public boolean useUtilityPanel() { 276 return true; 277 } 278 279 public void openUtilityPanel(LinearLayout mAccessoryViewList) { 280 setMenuIcon(showsPopupIndicator()); 281 if (mImageShow != null) { 282 mImageShow.openUtilityPanel(mAccessoryViewList); 283 } 284 } 285 286 protected void setMenuIcon(boolean on) { 287 mEditTitle.setCompoundDrawablesRelativeWithIntrinsicBounds( 288 0, 0, on ? R.drawable.filtershow_menu_marker_rtl : 0, 0); 289 } 290 291 protected void createMenu(int[] strId, View button) { 292 PopupMenu pmenu = new PopupMenu(mContext, button); 293 Menu menu = pmenu.getMenu(); 294 for (int i = 0; i < strId.length; i++) { 295 menu.add(Menu.NONE, Menu.FIRST + i, 0, mContext.getString(strId[i])); 296 } 297 setMenuIcon(true); 298 299 } 300 301 public Control[] getControls() { 302 return null; 303 } 304 305 @Override 306 public void onStartTrackingTouch(SeekBar arg0) { 307 308 } 309 310 @Override 311 public void onStopTrackingTouch(SeekBar arg0) { 312 313 } 314 315 @Override 316 public void swapLeft(MenuItem item) { 317 318 } 319 320 @Override 321 public void swapRight(MenuItem item) { 322 323 } 324 325 public void detach() { 326 if (mImageShow != null) { 327 mImageShow.detach(); 328 } 329 } 330 } 331