diff options
author | Jorge Ruesga <jorge@ruesga.com> | 2013-10-27 13:46:12 +0100 |
---|---|---|
committer | Jorge Ruesga <jorge@ruesga.com> | 2013-10-27 13:46:12 +0100 |
commit | a9b27719b9f448879fb5ac821ee7ac1cf22b33ce (patch) | |
tree | 935967d50d639244786802b849ad15d1af798dd4 /src/org/cyanogenmod/wallpapers/photophase/preferences | |
parent | 49cba5cf09cf0e4f3b533f163ea183b83e617986 (diff) | |
download | android_packages_wallpapers_PhotoPhase-a9b27719b9f448879fb5ac821ee7ac1cf22b33ce.tar.gz android_packages_wallpapers_PhotoPhase-a9b27719b9f448879fb5ac821ee7ac1cf22b33ce.tar.bz2 android_packages_wallpapers_PhotoPhase-a9b27719b9f448879fb5ac821ee7ac1cf22b33ce.zip |
Returns as a CyanogenMod project. Update author and Copyrights
Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
Diffstat (limited to 'src/org/cyanogenmod/wallpapers/photophase/preferences')
12 files changed, 2309 insertions, 0 deletions
diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/ChoosePicturesFragment.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/ChoosePicturesFragment.java new file mode 100644 index 0000000..6e41308 --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/ChoosePicturesFragment.java @@ -0,0 +1,496 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.database.Cursor; +import android.os.AsyncTask; +import android.os.AsyncTask.Status; +import android.os.Bundle; +import android.preference.PreferenceFragment; +import android.provider.MediaStore; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import org.cyanogenmod.wallpapers.photophase.R; +import org.cyanogenmod.wallpapers.photophase.animations.AlbumsFlip3dAnimationController; +import org.cyanogenmod.wallpapers.photophase.model.Album; +import org.cyanogenmod.wallpapers.photophase.preferences.PreferencesProvider.Preferences; +import org.cyanogenmod.wallpapers.photophase.widgets.AlbumInfo; +import org.cyanogenmod.wallpapers.photophase.widgets.AlbumPictures; +import org.cyanogenmod.wallpapers.photophase.widgets.CardLayout; +import org.cyanogenmod.wallpapers.photophase.widgets.VerticalEndlessScroller; +import org.cyanogenmod.wallpapers.photophase.widgets.VerticalEndlessScroller.OnEndScrollListener; + +import java.io.File; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * A fragment class for select the picture that will be displayed on the wallpaper + */ +public class ChoosePicturesFragment extends PreferenceFragment implements OnEndScrollListener { + + private static final String TAG = "ChoosePicturesFragment"; + + private static final boolean DEBUG = false; + + private static final int AMOUNT_OF_ADDED_STEPS = 5; + + private final AsyncTask<Void, Album, Void> mAlbumsLoaderTask = new AsyncTask<Void, Album, Void>() { + /** + * {@inheritDoc} + */ + @Override + protected Void doInBackground(Void... params) { + // Query all the external content and classify the pictures in albums and load the cards + DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); + Album album = null; + unregister(); + Cursor c = mContentResolver.query( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + new String[]{ MediaStore.MediaColumns.DATA }, + null, + null, + MediaStore.MediaColumns.DATA); + if (c != null) { + try { + long start = System.currentTimeMillis(); + if (DEBUG) Log.v(TAG, "Media library:"); + while (c.moveToNext()) { + // Only valid files (those i can read) + String p = c.getString(0); + if (DEBUG) Log.v(TAG, "\t" + p); + if (p != null) { + File f = new File(p); + if (f.isFile() && f.canRead()) { + File path = f.getParentFile(); + String name = path.getName(); + if (album == null || album.getPath().compareTo(path.getAbsolutePath()) != 0) { + if (album != null) { + mAlbums.add(album); + mOriginalAlbums.add((Album)album.clone()); + } + album = new Album(); + album.setPath(path.getAbsolutePath()); + album.setName(name); + album.setDate(df.format(new Date(path.lastModified()))); + album.setSelected(isSelectedItem(album.getPath())); + album.setItems(new ArrayList<String>()); + album.setSelectedItems(new ArrayList<String>()); + } + album.getItems().add(f.getAbsolutePath()); + if (isSelectedItem(f.getAbsolutePath())) { + album.getSelectedItems().add(f.getAbsolutePath()); + } + } + } + } + + // Add the last album + if (album != null) { + mAlbums.add(album); + mOriginalAlbums.add((Album)album.clone()); + } + long end = System.currentTimeMillis(); + if (DEBUG) Log.v(TAG, "Library loaded in " + (end - start) + " miliseconds"); + + } finally { + c.close(); + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + protected void onPostExecute(Void result) { + Resources res = getActivity().getResources(); + int size = (int)(res.getDimension(R.dimen.album_size) + + res.getDimension(R.dimen.small_margin)); + mScroller.setEndPadding(size * AMOUNT_OF_ADDED_STEPS); + int height = mScroller.getMeasuredHeight(); + int steps = (height / size) + AMOUNT_OF_ADDED_STEPS; + + // Create the views an force a redraw the items + mAlbumViews = new ArrayList<View>(mAlbums.size()); + for (Album item : mAlbums) { + mAlbumViews.add(createAlbumView(item)); + } + doEndScroll(steps, true); + + // We not need Hardware acceleration anymore (no more animations) + // Disable drawing cache + mScroller.setLayerType(View.LAYER_TYPE_SOFTWARE, null); + mScroller.setDrawingCacheEnabled(false); + mScroller.setSmoothScrollingEnabled(true); + } + }; + + /*package*/ ContentResolver mContentResolver; + + /*package*/ List<Album> mAlbums; + /*package*/ List<View> mAlbumViews; + /*package*/ List<Album> mOriginalAlbums; + /*package*/ List<AlbumsFlip3dAnimationController> mAnimationControllers; + + /*package*/ Set<String> mSelectedAlbums; + private Set<String> mOriginalSelectedAlbums; + + /*package*/ VerticalEndlessScroller mScroller; + private CardLayout mAlbumsPanel; + + /*package*/ boolean mSelectionChanged; + + /** + * {@inheritDoc} + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mContentResolver = getActivity().getContentResolver(); + + // Create an empty album + mAlbums = new ArrayList<Album>(); + mOriginalAlbums = new ArrayList<Album>(); + mAnimationControllers = new ArrayList<AlbumsFlip3dAnimationController>(); + + // Change the preference manager + getPreferenceManager().setSharedPreferencesName(PreferencesProvider.PREFERENCES_FILE); + getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE); + + // Load the albums user selection + mOriginalSelectedAlbums = Preferences.Media.getSelectedMedia(); + mSelectedAlbums = new HashSet<String>(mOriginalSelectedAlbums); + mSelectionChanged = false; + + setHasOptionsMenu(true); + } + + /** + * {@inheritDoc} + */ + @Override + public void onDestroy() { + super.onDestroy(); + if (mAlbumsLoaderTask.getStatus().compareTo(Status.PENDING) == 0) { + mAlbumsLoaderTask.cancel(true); + } + unbindDrawables(mAlbumsPanel); + unregister(); + + // Notify that the settings was changed + Intent intent = new Intent(PreferencesProvider.ACTION_SETTINGS_CHANGED); + if (mSelectionChanged) { + intent.putExtra(PreferencesProvider.EXTRA_FLAG_REDRAW, Boolean.TRUE); + intent.putExtra(PreferencesProvider.EXTRA_FLAG_EMPTY_TEXTURE_QUEUE, Boolean.TRUE); + intent.putExtra(PreferencesProvider.EXTRA_FLAG_MEDIA_RELOAD, Boolean.TRUE); + } + getActivity().sendBroadcast(intent); + } + + /*package*/ void unregister() { + mAlbums.clear(); + mOriginalAlbums.clear(); + mAnimationControllers.clear(); + } + + /** + * Method that unbind all the drawables for a view + * + * @param view The root view + */ + private void unbindDrawables(View view) { + if (view.getBackground() != null) { + view.getBackground().setCallback(null); + } + if (view instanceof ViewGroup) { + for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { + unbindDrawables(((ViewGroup) view).getChildAt(i)); + } + ((ViewGroup) view).removeAllViews(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + // Inflate the layout for this fragment + mScroller = + (VerticalEndlessScroller)inflater.inflate( + R.layout.choose_picture_fragment, container, false); + mScroller.setCallback(this); + mAlbumsPanel = (CardLayout)mScroller.findViewById(R.id.albums_panel); + + // Force Hardware acceleration + if (!mScroller.isHardwareAccelerated()) { + mScroller.setLayerType(View.LAYER_TYPE_HARDWARE, null); + } + if (!mAlbumsPanel.isHardwareAccelerated()) { + mAlbumsPanel.setLayerType(View.LAYER_TYPE_HARDWARE, null); + } + + // Load the albums + mAlbumsLoaderTask.execute(); + + return mScroller; + } + + /** + * {@inheritDoc} + */ + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.albums, menu); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.mnu_ok: + getActivity().finish(); + return true; + case R.id.mnu_restore: + restoreData(); + return true; + case R.id.mnu_invert_all: + invertAll(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + /** + * Method that restores the albums to its original state + */ + private void restoreData() { + // Restore and the albums the selection + mSelectedAlbums = new HashSet<String>(mOriginalSelectedAlbums); + mAlbums.clear(); + for (Album album : mOriginalAlbums) { + mAlbums.add((Album)album.clone()); + } + + // Update all the views + Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums); + updateAll(); + } + + /** + * Method that inverts the selection of all the albums + */ + private void invertAll() { + // Restore and the albums the selection + mSelectedAlbums = new HashSet<String>(); + for (Album album : mAlbums) { + album.setSelected(!album.isSelected()); + album.setSelectedItems(new ArrayList<String>()); + if (album.isSelected()) { + mSelectedAlbums.add(album.getPath()); + } else { + mSelectedAlbums.addAll(album.getSelectedItems()); + } + } + + // Update all the views + Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums); + updateAll(); + } + + /** + * Method that updates the current state of all the albums + */ + private void updateAll() { + // Update every view (albums and views should have the same size) + int count = mAlbumsPanel.getChildCount(); + for (int i = 0; i < count; i++) { + Album album = mAlbums.get(i); + View v = mAlbumsPanel.getChildAt(i); + AlbumInfo albumInfo = (AlbumInfo)v.findViewById(R.id.album_info); + AlbumPictures albumPictures = (AlbumPictures)v.findViewById(R.id.album_pictures); + albumInfo.updateView(album); + albumPictures.updateView(album, true); + } + + // Restore the preference + Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums); + mSelectionChanged = true; + + // Restore all the animations states + for (AlbumsFlip3dAnimationController controller : mAnimationControllers) { + controller.reset(); + } + } + + /** + * Method that creates a new album to the card layout + * + * @param album The album to create + * @return View The view create + */ + View createAlbumView(final Album album) { + LayoutInflater li = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + final View albumView = li.inflate(R.layout.album, mAlbumsPanel, false); + final AlbumInfo albumInfo = (AlbumInfo)albumView.findViewById(R.id.album_info); + final AlbumPictures albumPictures = (AlbumPictures)albumView.findViewById(R.id.album_pictures); + + // Load the album info + albumInfo.post(new Runnable() { + @Override + public void run() { + albumInfo.updateView(album); + } + }); + if (album.isSelected()) { + albumInfo.setSelected(true); + } + albumInfo.addCallBackListener(new AlbumInfo.CallbacksListener() { + @Override + public void onAlbumSelected(Album ref) { + // Remove all pictures of the album and add the album reference + removeAlbumItems(ref); + mSelectedAlbums.add(ref.getPath()); + ref.setSelected(true); + albumPictures.updateView(ref, true); + + Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums); + mSelectionChanged = true; + } + + @Override + public void onAlbumDeselected(Album ref) { + // Remove all pictures of the album + removeAlbumItems(ref); + ref.setSelected(false); + albumPictures.updateView(ref, true); + + Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums); + mSelectionChanged = true; + } + + + }); + + // Load the album picture data + albumPictures.updateView(album, false); + albumPictures.addCallBackListener(new AlbumPictures.CallbacksListener() { + @Override + public void onBackButtonClick(View v) { + // Ignored + } + + @Override + public void onSelectionChanged(Album ref) { + // Remove, add, and persist the selection + removeAlbumItems(ref); + mSelectedAlbums.addAll(ref.getSelectedItems()); + ref.setSelected(false); + albumInfo.updateView(ref); + + Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums); + mSelectionChanged = true; + } + }); + + // Register the animation controller + AlbumsFlip3dAnimationController controller = new AlbumsFlip3dAnimationController(albumInfo, albumPictures); + controller.register(); + mAnimationControllers.add(controller); + + return albumView; + } + + /** + * Method that checks if an item is selected + * + * @param item The item + * @return boolean if an item is selected + */ + /*package*/ boolean isSelectedItem(String item) { + Iterator<String> it = mSelectedAlbums.iterator(); + while (it.hasNext()) { + String albumPath = it.next(); + if (item.compareTo(albumPath) == 0) { + return true; + } + } + return false; + } + + /** + * Method that removes the reference to all the items and itself + * + * @param ref The album + */ + /*package*/ void removeAlbumItems(Album ref) { + Iterator<String> it = mSelectedAlbums.iterator(); + while (it.hasNext()) { + String item = it.next(); + String parent = new File(item).getParent(); + if (parent.compareTo(ref.getPath()) == 0) { + it.remove(); + } else if (item.compareTo(ref.getPath()) == 0) { + it.remove(); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void onEndScroll() { + doEndScroll(AMOUNT_OF_ADDED_STEPS, false); + } + + /** + * Method that performs a scroll creating new items + * + * @param amount The amount of items to create + * @param animate If the add should be animated + */ + /*package*/ synchronized void doEndScroll(int amount, boolean animate) { + for (int i = 0; i < amount; i++) { + //Add to the panel of cards + if (mAlbumViews == null || mAlbumViews.isEmpty()) { + break; + } + mAlbumsPanel.addCard(mAlbumViews.remove(0), animate); + } + } +} diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/DispositionFragment.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/DispositionFragment.java new file mode 100644 index 0000000..b0204c3 --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/DispositionFragment.java @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.preference.PreferenceFragment; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import org.cyanogenmod.wallpapers.photophase.R; +import org.cyanogenmod.wallpapers.photophase.model.Disposition; +import org.cyanogenmod.wallpapers.photophase.widgets.DispositionView; +import org.cyanogenmod.wallpapers.photophase.widgets.DispositionView.OnFrameSelectedListener; +import org.cyanogenmod.wallpapers.photophase.widgets.ResizeFrame; + +import java.util.List; + +/** + * An abstract fragment class that allow to choose the layout disposition of the wallpaper. + */ +public abstract class DispositionFragment + extends PreferenceFragment implements OnFrameSelectedListener { + + private Runnable mRedraw = new Runnable() { + @Override + public void run() { + if (getActivity() == null) return; + try { + mDispositionView.setDispositions(getUserDispositions(), getCols(), getRows()); + } catch (Exception ex) { + // Ignored + } + } + }; + + /*package*/ DispositionView mDispositionView; + + private MenuItem mDeleteMenu; + + /** + * Constructor of <code>DispositionFragment</code> + */ + public DispositionFragment() { + super(); + } + + /** + * Method that returns the current user preference for the disposition + * + * @return List<Disposition> The current user preference dispositions + */ + public abstract List<Disposition> getUserDispositions(); + + /** + * Method that returns the default preference for the disposition + * + * @return List<Disposition> The default preference dispositions + */ + public abstract List<Disposition> getDefaultDispositions(); + + /** + * Method that request to save the dispositions + * + * @param dispositions The dispositions to save + */ + public abstract void saveDispositions(List<Disposition> dispositions); + + /** + * Method that returns the number of rows to use + * + * @return int The number of rows + */ + public abstract int getRows(); + + /** + * Method that returns the number of cols to use + * + * @return int The number of cols + */ + public abstract int getCols(); + + /** + * {@inheritDoc} + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Change the preference manager + getPreferenceManager().setSharedPreferencesName(PreferencesProvider.PREFERENCES_FILE); + getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE); + + setHasOptionsMenu(true); + } + + /** + * {@inheritDoc} + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + // Inflate the layout for this fragment + ViewGroup v = (ViewGroup)inflater.inflate(R.layout.choose_disposition_fragment, container, false); + mDispositionView = (DispositionView)v.findViewById(R.id.disposition_view); + mDispositionView.setResizeFrame((ResizeFrame)v.findViewById(R.id.resize_frame)); + mDispositionView.setOnFrameSelectedListener(this); + mDispositionView.post(mRedraw); + return v; + } + + /** + * {@inheritDoc} + */ + @Override + public void onDestroyView() { + super.onDestroyView(); + if (mDispositionView != null) { + mDispositionView.removeCallbacks(mRedraw); + if (mDispositionView.isChanged()) { + saveDispositions(mDispositionView.getDispositions()); + } + } + + // Notify that the settings was changed + Intent intent = new Intent(PreferencesProvider.ACTION_SETTINGS_CHANGED); + if (mDispositionView.isChanged()) { + intent.putExtra(PreferencesProvider.EXTRA_FLAG_REDRAW, Boolean.TRUE); + intent.putExtra(PreferencesProvider.EXTRA_FLAG_RECREATE_WORLD, Boolean.TRUE); + } + getActivity().sendBroadcast(intent); + } + + /** + * {@inheritDoc} + */ + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.dispositions, menu); + mDeleteMenu = menu.findItem(R.id.mnu_delete); + if (mDeleteMenu != null) { + mDeleteMenu.setVisible(false); + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.mnu_ok: + getActivity().finish(); + return true; + case R.id.mnu_restore: + restoreData(); + return true; + case R.id.mnu_delete: + deleteFrame(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + /** + * Method that restores the disposition view to the default state + */ + private void restoreData() { + mDispositionView.setDispositions(getUserDispositions(), getCols(), getRows()); + } + + /** + * Method that restores the disposition view to the default state + */ + private void deleteFrame() { + mDispositionView.deleteCurrentFrame(); + } + + /** + * {@inheritDoc} + */ + @Override + public void onFrameSelectedListener(View v) { + if (mDeleteMenu != null) { + mDeleteMenu.setVisible(true); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void onFrameUnselectedListener() { + if (mDeleteMenu != null) { + mDeleteMenu.setVisible(false); + } + } +} diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/GeneralPreferenceFragment.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/GeneralPreferenceFragment.java new file mode 100644 index 0000000..4dd6da8 --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/GeneralPreferenceFragment.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.ListPreference; +import android.preference.MultiSelectListPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.PreferenceFragment; +import android.util.Log; + +import org.cyanogenmod.wallpapers.photophase.Colors; +import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil.GLColor; +import org.cyanogenmod.wallpapers.photophase.R; +import org.cyanogenmod.wallpapers.photophase.preferences.PreferencesProvider.Preferences; +import org.cyanogenmod.wallpapers.photophase.preferences.SeekBarProgressPreference.OnDisplayProgress; +import org.cyanogenmod.wallpapers.photophase.widgets.ColorPickerPreference; + +/** + * A fragment class with all the general settings + */ +public class GeneralPreferenceFragment extends PreferenceFragment { + + private static final String TAG = "GeneralPreferenceFragment"; + + private static final boolean DEBUG = false; + + private SeekBarProgressPreference mWallpaperDim; + private ColorPickerPreference mBackgroundColor; + private ListPreference mTouchActions; + private CheckBoxPreference mFixAspectRatio; + private MultiSelectListPreference mTransitionsTypes; + private SeekBarProgressPreference mTransitionsInterval; + private MultiSelectListPreference mEffectsTypes; + + boolean mRedrawFlag; + boolean mEmptyTextureQueueFlag; + + private final OnPreferenceChangeListener mOnChangeListener = new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(final Preference preference, Object newValue) { + String key = preference.getKey(); + if (DEBUG) Log.d(TAG, "Preference changed: " + key + "=" + newValue); + if (key.compareTo("ui_wallpaper_dim") == 0) { + mRedrawFlag = true; + } else if (key.compareTo("ui_background_color") == 0) { + mRedrawFlag = true; + int color = ((Integer)newValue).intValue(); + Colors.setBackground(new GLColor(color)); + } else if (key.compareTo("ui_fix_aspect_ratio") == 0) { + mRedrawFlag = true; + } else if (key.compareTo("ui_transition_types") == 0) { + mRedrawFlag = true; + } else if (key.compareTo("ui_transition_interval") == 0) { + mRedrawFlag = true; + } else if (key.compareTo("ui_effect_types") == 0) { + mRedrawFlag = true; + mEmptyTextureQueueFlag = true; + } + return true; + } + }; + + /** + * {@inheritDoc} + */ + @Override + public void onDestroy() { + super.onDestroy(); + + // Reload the settings + PreferencesProvider.reload(getActivity()); + + // Notify that the settings was changed + Intent intent = new Intent(PreferencesProvider.ACTION_SETTINGS_CHANGED); + if (mRedrawFlag) { + intent.putExtra(PreferencesProvider.EXTRA_FLAG_REDRAW, Boolean.TRUE); + } + if (mEmptyTextureQueueFlag) { + intent.putExtra(PreferencesProvider.EXTRA_FLAG_EMPTY_TEXTURE_QUEUE, Boolean.TRUE); + } + getActivity().sendBroadcast(intent); + } + + /** + * {@inheritDoc} + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Change the preference manager + getPreferenceManager().setSharedPreferencesName(PreferencesProvider.PREFERENCES_FILE); + getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE); + + final SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); + final Resources res = getActivity().getResources(); + + // Add the preferences + addPreferencesFromResource(R.xml.preferences_general); + + mWallpaperDim = (SeekBarProgressPreference)findPreference("ui_wallpaper_dim"); + mWallpaperDim.setFormat(getString(R.string.pref_general_settings_wallpaper_dim_format)); + mWallpaperDim.setOnPreferenceChangeListener(mOnChangeListener); + + mBackgroundColor = (ColorPickerPreference)findPreference("ui_background_color"); + mBackgroundColor.setOnPreferenceChangeListener(mOnChangeListener); + + mTouchActions = (ListPreference)findPreference("ui_touch_action"); + mTouchActions.setOnPreferenceChangeListener(mOnChangeListener); + + mFixAspectRatio = (CheckBoxPreference)findPreference("ui_fix_aspect_ratio"); + mFixAspectRatio.setOnPreferenceChangeListener(mOnChangeListener); + + mTransitionsTypes = (MultiSelectListPreference)findPreference("ui_transition_types"); + mTransitionsTypes.setOnPreferenceChangeListener(mOnChangeListener); + + final int[] transitionsIntervals = res.getIntArray(R.array.transitions_intervals_values); + mTransitionsInterval = (SeekBarProgressPreference)findPreference("ui_transition_interval"); + mTransitionsInterval.setFormat(getString(R.string.pref_general_transitions_interval_format)); + mTransitionsInterval.setMax(transitionsIntervals.length - 1); + int transitionInterval = prefs.getInt("ui_transition_interval", + Preferences.General.Transitions.DEFAULT_TRANSITION_INTERVAL_INDEX); + if (transitionInterval > (transitionsIntervals.length - 1)) { + mTransitionsInterval.setProgress( + Preferences.General.Transitions.DEFAULT_TRANSITION_INTERVAL_INDEX); + } + mTransitionsInterval.setOnDisplayProgress(new OnDisplayProgress() { + @Override + public String onDisplayProgress(int progress) { + return String.valueOf(transitionsIntervals[progress] / 1000); + } + }); + mTransitionsInterval.setOnPreferenceChangeListener(mOnChangeListener); + + mEffectsTypes = (MultiSelectListPreference)findPreference("ui_effect_types"); + mEffectsTypes.setOnPreferenceChangeListener(mOnChangeListener); + } + +} diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/LandscapeDispositionFragment.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/LandscapeDispositionFragment.java new file mode 100644 index 0000000..77267e6 --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/LandscapeDispositionFragment.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +import android.content.pm.ActivityInfo; +import android.os.Bundle; + +import org.cyanogenmod.wallpapers.photophase.preferences.PreferencesProvider.Preferences; +import org.cyanogenmod.wallpapers.photophase.model.Disposition; +import org.cyanogenmod.wallpapers.photophase.utils.DispositionUtil; + +import java.util.List; + +/** + * A fragment class that allow to choose the layout disposition of the wallpaper for landscape + * screen. + */ +public class LandscapeDispositionFragment extends DispositionFragment { + + /** + * Constructor of <code>LandscapeDispositionFragment</code> + */ + public LandscapeDispositionFragment() { + super(); + } + + /** + * {@inheritDoc} + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Disposition> getUserDispositions() { + return Preferences.Layout.getLandscapeDisposition(); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Disposition> getDefaultDispositions() { + return DispositionUtil.toDispositions( + Preferences.Layout.DEFAULT_LANDSCAPE_DISPOSITION); + } + + /** + * {@inheritDoc} + */ + @Override + public void saveDispositions(List<Disposition> dispositions) { + Preferences.Layout.setLandscapeDisposition(getActivity(), dispositions); + } + + /** + * {@inheritDoc} + */ + @Override + public int getRows() { + // inverted + return Preferences.Layout.getCols(); + } + + /** + * {@inheritDoc} + */ + @Override + public int getCols() { + // inverted + return Preferences.Layout.getRows(); + } +} diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/LayoutPreferenceFragment.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/LayoutPreferenceFragment.java new file mode 100644 index 0000000..564c425 --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/LayoutPreferenceFragment.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +import android.content.Context; +import android.os.Bundle; +import android.preference.PreferenceFragment; + +import org.cyanogenmod.wallpapers.photophase.R; + +/** + * A fragment class with the layout disposition + */ +public class LayoutPreferenceFragment extends PreferenceFragment { + + /** + * {@inheritDoc} + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Change the preference manager + getPreferenceManager().setSharedPreferencesName(PreferencesProvider.PREFERENCES_FILE); + getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE); + + // Add the preferences + addPreferencesFromResource(R.xml.preferences_layout); + } +} diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/MediaPreferenceFragment.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/MediaPreferenceFragment.java new file mode 100644 index 0000000..e03116e --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/MediaPreferenceFragment.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceFragment; +import android.util.Log; + +import org.cyanogenmod.wallpapers.photophase.R; +import org.cyanogenmod.wallpapers.photophase.preferences.PreferencesProvider.Preferences; + +/** + * A fragment class with all the media settings + */ +public class MediaPreferenceFragment extends PreferenceFragment { + + private static final String TAG = "MediaPreferenceFragment"; + + private static final boolean DEBUG = false; + + ListPreference mRefreshInterval; + Preference mRefreshNow; + + boolean mMediaIntevalChangedFlag; + + private final OnPreferenceChangeListener mOnChangeListener = new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(final Preference preference, Object newValue) { + String key = preference.getKey(); + if (DEBUG) Log.d(TAG, "Preference changed: " + key + "=" + newValue); + if (key.compareTo("ui_media_refresh_interval") == 0) { + setRefreshIntervalSummary(Integer.valueOf(String.valueOf(newValue)).intValue()); + mMediaIntevalChangedFlag = true; + } + return true; + } + }; + + /** + * {@inheritDoc} + */ + @Override + public void onDestroy() { + super.onDestroy(); + + // Reload the settings + PreferencesProvider.reload(getActivity()); + + // Notify that the settings was changed + Intent intent = new Intent(PreferencesProvider.ACTION_SETTINGS_CHANGED); + if (mMediaIntevalChangedFlag) { + intent.putExtra(PreferencesProvider.EXTRA_FLAG_MEDIA_INTERVAL_CHANGED, Boolean.TRUE); + } + getActivity().sendBroadcast(intent); + } + + /** + * {@inheritDoc} + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Change the preference manager + getPreferenceManager().setSharedPreferencesName(PreferencesProvider.PREFERENCES_FILE); + getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE); + + // Add the preferences + addPreferencesFromResource(R.xml.preferences_media); + + mRefreshInterval = (ListPreference)findPreference("ui_media_refresh_interval"); + setRefreshIntervalSummary(Preferences.Media.getRefreshFrecuency()); + mRefreshInterval.setOnPreferenceChangeListener(mOnChangeListener); + + mRefreshNow = findPreference("ui_media_refresh_now"); + mRefreshNow.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + // Request a refresh of the media data + Intent intent = new Intent(PreferencesProvider.ACTION_SETTINGS_CHANGED); + intent.putExtra(PreferencesProvider.EXTRA_FLAG_MEDIA_RELOAD, Boolean.TRUE); + intent.putExtra(PreferencesProvider.EXTRA_ACTION_MEDIA_USER_RELOAD_REQUEST, Boolean.TRUE); + getActivity().sendBroadcast(intent); + return true; + } + }); + } + + /** + * Method that set the refresh interval summary + * + * @param interval The interval value + */ + void setRefreshIntervalSummary(int interval) { + String v = String.valueOf(interval); + String[] labels = getResources().getStringArray(R.array.refresh_intervals_labels); + String[] values = getResources().getStringArray(R.array.refresh_intervals_values); + int cc = values.length; + for (int i = 0; i < cc; i++) { + if (values[i].compareTo(String.valueOf(v)) == 0) { + v = labels[i]; + break; + } + } + String summary = + (interval == 0) + ? getString(R.string.pref_media_settings_refresh_interval_disable) + : getString(R.string.pref_media_settings_refresh_interval_summary, v); + mRefreshInterval.setSummary(summary); + } +} diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/PhotoPhasePreferences.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/PhotoPhasePreferences.java new file mode 100644 index 0000000..4e8c46e --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/PhotoPhasePreferences.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +import android.app.ActionBar; +import android.os.Bundle; +import android.preference.PreferenceActivity; +import android.view.MenuItem; + +import org.cyanogenmod.wallpapers.photophase.R; + +import java.util.List; + +/** + * The PhotoPhase Live Wallpaper preferences. + */ +public class PhotoPhasePreferences extends PreferenceActivity { + + /** + * {@inheritDoc} + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + //Initialize action bars + initTitleActionBar(); + } + + /** + * Method that initializes the titlebar of the activity. + */ + private void initTitleActionBar() { + //Configure the action bar options + getActionBar().setDisplayOptions( + ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE); + getActionBar().setDisplayHomeAsUpEnabled(true); + } + + /** + * {@inheritDoc} + */ + @Override + public void onBuildHeaders(List<Header> target) { + loadHeadersFromResource(R.xml.preferences_headers, target); + + // Retrieve the about header + Header aboutHeader = target.get(target.size() - 1); + try { + String appver = + this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName; + aboutHeader.summary = getString(R.string.pref_about_summary, appver); + } catch (Exception e) { + aboutHeader.summary = getString(R.string.pref_about_summary, ""); //$NON-NLS-1$ + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } +} diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/PortraitDispositionFragment.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/PortraitDispositionFragment.java new file mode 100644 index 0000000..8763e1e --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/PortraitDispositionFragment.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +import android.content.pm.ActivityInfo; +import android.os.Bundle; + +import org.cyanogenmod.wallpapers.photophase.model.Disposition; +import org.cyanogenmod.wallpapers.photophase.preferences.PreferencesProvider.Preferences; +import org.cyanogenmod.wallpapers.photophase.utils.DispositionUtil; + +import java.util.List; + +/** + * A fragment class that allow to choose the layout disposition of the wallpaper for portrait + * screen. + */ +public class PortraitDispositionFragment extends DispositionFragment { + + /** + * Constructor of <code>PortraitDispositionFragment</code> + */ + public PortraitDispositionFragment() { + super(); + } + + /** + * {@inheritDoc} + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Disposition> getUserDispositions() { + return Preferences.Layout.getPortraitDisposition(); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Disposition> getDefaultDispositions() { + return DispositionUtil.toDispositions( + Preferences.Layout.DEFAULT_PORTRAIT_DISPOSITION); + } + + /** + * {@inheritDoc} + */ + @Override + public void saveDispositions(List<Disposition> dispositions) { + Preferences.Layout.setPortraitDisposition(getActivity(), dispositions); + } + + /** + * {@inheritDoc} + */ + @Override + public int getRows() { + return Preferences.Layout.getRows(); + } + + /** + * {@inheritDoc} + */ + @Override + public int getCols() { + return Preferences.Layout.getCols(); + } +} diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/PreferencesProvider.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/PreferencesProvider.java new file mode 100644 index 0000000..1bf8359 --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/PreferencesProvider.java @@ -0,0 +1,459 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.content.res.Resources; + +import org.cyanogenmod.wallpapers.photophase.R; +import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil.GLColor; +import org.cyanogenmod.wallpapers.photophase.effects.Effects.EFFECTS; +import org.cyanogenmod.wallpapers.photophase.model.Disposition; +import org.cyanogenmod.wallpapers.photophase.transitions.Transitions.TRANSITIONS; +import org.cyanogenmod.wallpapers.photophase.utils.DispositionUtil; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * A class that holds all the preferences of the wallpaper + */ +@SuppressWarnings("boxing") +public final class PreferencesProvider { + + /** + * Internal broadcast action to communicate that some setting was changed + * @see #EXTRA_FLAG_REDRAW + * {@hide} + */ + public static final String ACTION_SETTINGS_CHANGED = "org.cyanogenmod.wallpapers.photophase.actions.SETTINGS_CHANGED"; + + /** + * An extra setting that indicates that the changed setting request a whole recreation of the wallpaper world + * {@hide} + */ + public static final String EXTRA_FLAG_RECREATE_WORLD = "flag_recreate_world"; + + /** + * An extra setting that indicates that the changed setting request a redraw of the wallpaper + * {@hide} + */ + public static final String EXTRA_FLAG_REDRAW = "flag_redraw"; + + /** + * An extra setting that indicates that the changed setting request to empty the texture queue + * {@hide} + */ + public static final String EXTRA_FLAG_EMPTY_TEXTURE_QUEUE = "flag_empty_texture_queue"; + + /** + * An extra setting that indicates that the changed setting request a reload of the media data + * {@hide} + */ + public static final String EXTRA_FLAG_MEDIA_RELOAD = "flag_media_reload"; + + /** + * An extra setting that indicates that the changed setting notifies that the media + * interval was changed + * {@hide} + */ + public static final String EXTRA_FLAG_MEDIA_INTERVAL_CHANGED = "flag_media_interval_changed"; + + /** + * An extra setting that indicates that the media reload becomes from a user + * + * @see #EXTRA_FLAG_MEDIA_RELOAD + * {@hide} + */ + public static final String EXTRA_ACTION_MEDIA_USER_RELOAD_REQUEST = "action_media_user_reload_req"; + + /** + * The shared preferences file + */ + public static final String PREFERENCES_FILE = "org.cyanogenmod.wallpapers.photophase"; + + private static Map<String, ?> mPreferences = new HashMap<String, Object>(); + + /** + * @hide + */ + /*package*/ static int[] TRANSITIONS_INTERVALS; + + /** + * Method that loads the all the preferences of the application + * + * @param context The current context + */ + public static void reload(Context context) { + SharedPreferences preferences = + context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE); + mPreferences = preferences.getAll(); + + final Resources res = context.getResources(); + TRANSITIONS_INTERVALS = res.getIntArray(R.array.transitions_intervals_values); + } + + /** + * Method that returns a integer property value. + * + * @param key The preference key + * @param def The default value + * @return int The integer property value + */ + static int getInt(String key, int def) { + return mPreferences.containsKey(key) && mPreferences.get(key) instanceof Integer ? + (Integer) mPreferences.get(key) : def; + } + + /** + * Method that returns a long property value. + * + * @param key The preference key + * @param def The default value + * @return long The long property value + */ + static long getLong(String key, long def) { + return mPreferences.containsKey(key) && mPreferences.get(key) instanceof Long ? + (Long) mPreferences.get(key) : def; + } + + /** + * Method that returns a boolean property value. + * + * @param key The preference key + * @param def The default value + * @return boolean The boolean property value + */ + static boolean getBoolean(String key, boolean def) { + return mPreferences.containsKey(key) && mPreferences.get(key) instanceof Boolean ? + (Boolean) mPreferences.get(key) : def; + } + + /** + * Method that returns a string property value. + * + * @param key The preference key + * @param def The default value + * @return String The string property value + */ + static String getString(String key, String def) { + return mPreferences.containsKey(key) && mPreferences.get(key) instanceof String ? + (String) mPreferences.get(key) : def; + } + + /** + * Method that returns a string set property value. + * + * @param key The preference key + * @param def The default value + * @return Set<String> The string property value + */ + @SuppressWarnings("unchecked") + static Set<String> getStringSet(String key, Set<String> def) { + return mPreferences.containsKey(key) && mPreferences.get(key) instanceof Set<?> ? + (Set<String>) mPreferences.get(key) : def; + } + + /** + * A class for access to the preferences of the application + */ + public static class Preferences { + /** + * General preferences + */ + public static class General { + private static final GLColor DEFAULT_BACKGROUND_COLOR = new GLColor("#ff202020"); + + /** + * Method that returns the wallpaper dimmed value. + * + * @return float If the wallpaper dimmed value (0-black, 100-black) + */ + public static float getWallpaperDim() { + return getInt("ui_wallpaper_dim", 0); + } + + /** + * Method that returns the background color + * + * @return GLColor The background color + */ + public static GLColor getBackgroundColor() { + int color = getInt("ui_background_color", 0); + if (color == 0) { + return DEFAULT_BACKGROUND_COLOR; + } + return new GLColor(color); + } + + /** + * Return the current user preference of the action to do when a frame is tap. + * + * @return TouchAction The action (default NONE) + */ + public static TouchAction getTouchAction() { + return TouchAction.fromValue(Integer.valueOf(getString("ui_touch_action", "0"))); + } + + /** + * Return the current user preference about fix or not fix the aspect ratio + * of the image by cropping the image. + * + * @return boolean Indicates if the image should be cropped + */ + public static boolean isFixAspectRatio() { + return getBoolean("ui_fix_aspect_ratio", true); + } + + /** + * Transitions preferences + */ + public static class Transitions { + /** + * The default transition interval + */ + public static final int DEFAULT_TRANSITION_INTERVAL_INDEX = 2; + + /** + * Return the current user preference about the transition to apply to + * the pictures of the wallpaper. + * + * @return TRANSITIONS[] The transition to apply to the wallpaper's pictures + */ + public static TRANSITIONS[] getTransitionTypes() { + Set<String> set = getStringSet("ui_transition_types", new HashSet<String>()); + if (set.isEmpty()) { + // Return all the transitions if no one is selected + return TRANSITIONS.getValidTranstions(); + } + String[] values = set.toArray(new String[set.size()]); + int count = values.length; + TRANSITIONS[] transitions = new TRANSITIONS[count]; + for (int i = 0; i < count; i++) { + transitions[i] = TRANSITIONS.fromOrdinal(Integer.valueOf(values[i])); + } + return transitions; + } + + /** + * Method that returns how often the transitions are triggered. + * + * @return int The milliseconds in which the next transition will be triggered + */ + public static int getTransitionInterval() { + int interval = getInt("ui_transition_interval", + DEFAULT_TRANSITION_INTERVAL_INDEX); + return TRANSITIONS_INTERVALS[interval]; + } + } + + /** + * Effects preferences + */ + public static class Effects { + /** + * Return the current user preference about the effect to apply to + * the pictures of the wallpaper. + * + * @return EFFECTS[] The effects to apply to the wallpaper's pictures + */ + public static EFFECTS[] getEffectTypes() { + Set<String> defaults = new HashSet<String>(); + defaults.add(String.valueOf(EFFECTS.NO_EFFECT.ordinal())); + Set<String> set = getStringSet("ui_effect_types", defaults); + String[] values = set.toArray(new String[set.size()]); + int count = values.length; + EFFECTS[] effects = new EFFECTS[count]; + for (int i = 0; i < count; i++) { + effects[i] = EFFECTS.fromOrdinal(Integer.valueOf(values[i])); + } + return effects; + } + } + } + + /** + * Media preferences + */ + public static class Media { + /** + * Constant that indicates that the media reload is disabled + */ + public static final int MEDIA_RELOAD_DISABLED = 0; + + /** + * Method that returns the frequency with which the media is updated. + * + * @return int The interval in seconds between updates. 0 means that updates are disabled + */ + public static int getRefreshFrecuency() { + return Integer.valueOf(getString("ui_media_refresh_interval", String.valueOf(MEDIA_RELOAD_DISABLED))); + } + + /** + * Method that returns if the app must be select new albums when they are discovered. + * + * @return boolean If the app must be select new albums when they are discovered. + */ + public static boolean isAutoSelectNewAlbums() { + return getBoolean("ui_media_auto_select_new", Boolean.TRUE); + } + + // Internal settings (non-UI) + /** + * Method that returns the list of albums and pictures to be displayed + * + * @return Set<String> The list of albums and pictures to be displayed + */ + public static Set<String> getSelectedMedia() { + return getStringSet("media_selected_media", new HashSet<String>()); + } + + /** + * Method that returns the list of albums and pictures to be displayed + * + * @param context The current context + * @param selection The new list of albums and pictures to be displayed + */ + public static synchronized void setSelectedMedia(Context context, Set<String> selection) { + SharedPreferences preferences = + context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE); + Editor editor = preferences.edit(); + editor.putStringSet("media_selected_media", selection); + editor.commit(); + reload(context); + } + + /** + * Method that returns the list of the name of the albums seen by the + * last media discovery scan. + * + * @return Set<String> The list of albums and pictures to be displayed + */ + public static Set<String> getLastDiscorevedAlbums() { + return getStringSet("media_last_disvored_albums", new HashSet<String>()); + } + + /** + * Method that sets the list of the name of the albums seen by the + * last media discovery scan. + * + * @param context The current context + * @param albums The albums seen by the last media discovery scan + */ + public static synchronized void setLastDiscorevedAlbums(Context context, Set<String> albums) { + SharedPreferences preferences = + context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE); + Editor editor = preferences.edit(); + editor.putStringSet("media_last_disvored_albums", albums); + editor.commit(); + reload(context); + } + } + + /** + * Layout preferences + */ + public static class Layout { + + private static final int DEFAULT_COLS = 4; + private static final int DEFAULT_ROWS = 7; + public static final String DEFAULT_PORTRAIT_DISPOSITION = "0x0:2x1|0x2:1x3|0x4:3x6|2x2:3x3|3x0:3x0|3x1:3x1"; + public static final String DEFAULT_LANDSCAPE_DISPOSITION = "0x0:2x3|3x0:5x1|3x2:4x3|5x2:6x3|6x0:6x0|6x1:6x1"; + + /** + * Method that returns the rows of the wallpaper. + * + * @return int The rows of the wallpaper + */ + public static int getRows() { + return getInt("ui_layout_rows", DEFAULT_ROWS); + } + + /** + * Method that returns the columns of the wallpaper. + * + * @return int The columns of the wallpaper + */ + public static int getCols() { + return getInt("ui_layout_cols", DEFAULT_COLS); + } + + /** + * Returns the disposition of the photo frames in the wallpaper on portrait screen. The + * setting is stored as <code>0x0:1x2|2x2:3x4|...</code>, which it means (position x=0, y=0, + * 1 cells width, 2 cells height, ...). + * + * @return List<Disposition> The photo frames dispositions + */ + public static List<Disposition> getPortraitDisposition() { + return DispositionUtil.toDispositions( + getString("ui_layout_portrait_disposition", DEFAULT_PORTRAIT_DISPOSITION)); + } + + /** + * Sets the disposition of the photo frames in the wallpaper on landscape screen. + * + * @param context The current context + * @param dispositions The photo frames dispositions + */ + public static void setPortraitDisposition(Context context, List<Disposition> dispositions) { + SharedPreferences preferences = + context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE); + Editor editor = preferences.edit(); + editor.putString("ui_layout_portrait_disposition", + DispositionUtil.fromDispositions(dispositions)); + editor.commit(); + reload(context); + } + + /** + * Returns the disposition of the photo frames in the wallpaper on landscape screen. The + * setting is stored as <code>0x0:1x2|2x2:3x4|...</code>, which it means (position x=0, y=0, + * 1 cells width, 2 cells height, ...). + * + * @return List<Disposition> The photo frames dispositions + */ + public static List<Disposition> getLandscapeDisposition() { + return DispositionUtil.toDispositions( + getString("ui_layout_landscape_disposition", DEFAULT_LANDSCAPE_DISPOSITION)); + } + + /** + * Sets the disposition of the photo frames in the wallpaper on landscape screen. + * + * @param context The current context + * @param dispositions The photo frames dispositions + */ + public static void setLandscapeDisposition(Context context, List<Disposition> dispositions) { + SharedPreferences preferences = + context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE); + Editor editor = preferences.edit(); + editor.putString("ui_layout_landscape_disposition", + DispositionUtil.fromDispositions(dispositions)); + editor.commit(); + reload(context); + } + } + + } +} diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/SeekBarPreference.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/SeekBarPreference.java new file mode 100644 index 0000000..e8b6d2e --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/SeekBarPreference.java @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +import android.content.Context; +import android.content.res.TypedArray; +import android.os.Parcel; +import android.os.Parcelable; +import android.preference.Preference; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.view.View; +import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; + +import org.cyanogenmod.wallpapers.photophase.R; + +/** + * A preference with a seekbar widget + */ +public class SeekBarPreference extends Preference implements OnSeekBarChangeListener { + + private int mProgress; + private int mMax; + private boolean mTrackingTouch; + + /** + * Constructor of <code>SeekBarPreference</code> + * + * @param context The current context + * @param attrs The attributes of the view + * @param defStyle The resource with the style + */ + public SeekBarPreference( + Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setMax(100); + setLayoutResource(R.layout.preference_widget_seekbar); + } + + /** + * Constructor of <code>SeekBarPreference</code> + * + * @param context The current context + * @param attrs The attributes of the view + */ + public SeekBarPreference(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + /** + * Constructor of <code>SeekBarPreference</code> + * + * @param context The current context + */ + public SeekBarPreference(Context context) { + this(context, null); + } + + /** + * {@inheritDoc} + */ + @Override + protected void onBindView(View view) { + super.onBindView(view); + SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekbar); + seekBar.setOnSeekBarChangeListener(this); + seekBar.setMax(mMax); + seekBar.setProgress(mProgress); + seekBar.setEnabled(isEnabled()); + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("boxing") + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + setProgress(restoreValue ? getPersistedInt(mProgress) : (Integer) defaultValue); + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("boxing") + protected Object onGetDefaultValue(TypedArray a, int index) { + return a.getInt(index, 0); + } + + /** + * Allows a Preference to intercept key events without having focus. + * For example, SeekBarPreference uses this to intercept +/- to adjust + * the progress. + * + * @param v The view + * @param keyCode The key code + * @param event The key event + * @return True if the Preference handled the key. Returns false by default. + */ + public boolean onKey(View v, int keyCode, KeyEvent event) { + if (event.getAction() != KeyEvent.ACTION_UP) { + if (keyCode == KeyEvent.KEYCODE_PLUS + || keyCode == KeyEvent.KEYCODE_EQUALS) { + setProgress(getProgress() + 1); + return true; + } + if (keyCode == KeyEvent.KEYCODE_MINUS) { + setProgress(getProgress() - 1); + return true; + } + } + return false; + } + + /** + * Method that set the maximum progress + * + * @param max The maximum progress + */ + public void setMax(int max) { + if (max != mMax) { + mMax = max; + notifyChanged(); + } + } + + /** + * Method that set the actual progress + * + * @param progress The actual progress + */ + public void setProgress(int progress) { + setProgress(progress, true); + } + + /** + * Method that set the actual progress + * + * @param progress The actual progress + * @param notifyChanged Whether notify if the progress was changed + */ + protected void setProgress(int progress, boolean notifyChanged) { + int p = progress; + if (p > mMax) { + p = mMax; + } + if (p < 0) { + p = 0; + } + if (p != mProgress) { + mProgress = p; + persistInt(p); + if (notifyChanged) { + notifyChanged(); + } + } + } + + /** + * Method that returns the current progress + * + * @return int The current progress + */ + public int getProgress() { + return mProgress; + } + + /** + * Persist the seekBar's progress value if callChangeListener + * + * returns boolean True, otherwise set the seekBar's progress to the stored value + */ + @SuppressWarnings("boxing") + void syncProgress(SeekBar seekBar) { + int progress = seekBar.getProgress(); + if (progress != mProgress) { + if (callChangeListener(progress)) { + setProgress(progress, false); + } else { + seekBar.setProgress(mProgress); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (fromUser && !mTrackingTouch) { + syncProgress(seekBar); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + mTrackingTouch = true; + } + + /** + * {@inheritDoc} + */ + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + mTrackingTouch = false; + if (seekBar.getProgress() != mProgress) { + syncProgress(seekBar); + } + } + + /** + * {@inheritDoc} + */ + @Override + protected Parcelable onSaveInstanceState() { + /* + * Suppose a client uses this preference type without persisting. We + * must save the instance state so it is able to, for example, survive + * orientation changes. + */ + + final Parcelable superState = super.onSaveInstanceState(); + if (isPersistent()) { + // No need to save instance state since it's persistent + return superState; + } + + // Save the instance state + final SavedState myState = new SavedState(superState); + myState.progress = mProgress; + myState.max = mMax; + return myState; + } + + /** + * {@inheritDoc} + */ + @Override + protected void onRestoreInstanceState(Parcelable state) { + if (!state.getClass().equals(SavedState.class)) { + // Didn't save state for us in onSaveInstanceState + super.onRestoreInstanceState(state); + return; + } + + // Restore the instance state + SavedState myState = (SavedState) state; + super.onRestoreInstanceState(myState.getSuperState()); + mProgress = myState.progress; + mMax = myState.max; + notifyChanged(); + } + + /** + * SavedState, a subclass of {@link BaseSavedState}, will store the state + * of MyPreference, a subclass of Preference. + * <p> + * It is important to always call through to super methods. + */ + private static class SavedState extends BaseSavedState { + int progress; + int max; + + public SavedState(Parcel source) { + super(source); + + // Restore the click counter + progress = source.readInt(); + max = source.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + + // Save the click counter + dest.writeInt(progress); + dest.writeInt(max); + } + + public SavedState(Parcelable superState) { + super(superState); + } + + @SuppressWarnings({"unused", "hiding"}) + public static final Parcelable.Creator<SavedState> CREATOR = + new Parcelable.Creator<SavedState>() { + @Override + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + @Override + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } +} diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/SeekBarProgressPreference.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/SeekBarProgressPreference.java new file mode 100644 index 0000000..64b9b90 --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/SeekBarProgressPreference.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.TextView; + +import org.cyanogenmod.wallpapers.photophase.R; + +/** + * A preference with a seekbar widget that display the progress + */ +public class SeekBarProgressPreference extends SeekBarPreference { + + /** + * Interface to intercept the progress value to display on screen + */ + public interface OnDisplayProgress { + /** + * Method invoked when a progress value is going to display on screen + * + * @param progress The real progress + * @return The progress to display + */ + String onDisplayProgress(int progress); + } + + private String mFormat; + private OnDisplayProgress mOnDisplayProgress; + + TextView mTextView; + + /** + * Constructor of <code>SeekBarProgressPreference</code> + * + * @param context The current context + * @param attrs The attributes of the view + * @param defStyle The resource with the style + */ + public SeekBarProgressPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + /** + * Constructor of <code>SeekBarProgressPreference</code> + * + * @param context The current context + * @param attrs The attributes of the view + */ + public SeekBarProgressPreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + /** + * Constructor of <code>SeekBarProgressPreference</code> + * + * @param context The current context + */ + public SeekBarProgressPreference(Context context) { + super(context); + init(); + } + + /** + * Method that initializes the preference + */ + void init() { + mFormat = "%s"; + mOnDisplayProgress = null; + setWidgetLayoutResource(R.layout.preference_widget_seekbar_progress); + } + + /** + * {@inheritDoc} + */ + @Override + protected void onBindView(View view) { + super.onBindView(view); + mTextView = (TextView) view.findViewById(R.id.text); + setText(); + } + + /** + * Method that set the actual progress + * + * @param progress The actual progress + * @param notifyChanged Whether notify if the progress was changed + */ + @Override + protected void setProgress(int progress, boolean notifyChanged) { + super.setProgress(progress, notifyChanged); + setText(); + } + + /** + * Method that displays the progress value + */ + private void setText() { + if (mTextView != null) { + String value = String.valueOf(getProgress()); + if (mOnDisplayProgress != null) { + value = mOnDisplayProgress.onDisplayProgress(getProgress()); + } + mTextView.setText(String.format(mFormat, value)); + } + } + + /** + * Method that sets the callback to intercept the progress value before it will be + * displayed on screen. + * + * @param onDisplayProgress The callback + */ + public void setOnDisplayProgress(OnDisplayProgress onDisplayProgress) { + this.mOnDisplayProgress = onDisplayProgress; + } + + /** + * Method that set the format of the progress + * + * @param format The format of the string progress + */ + public void setFormat(String format) { + mFormat = format; + } +} diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/TouchAction.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/TouchAction.java new file mode 100644 index 0000000..498c1bd --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/TouchAction.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2013 The CyanogenMod Project + * + * 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 org.cyanogenmod.wallpapers.photophase.preferences; + +/** + * An enumeration with all the touch actions supported + */ +public enum TouchAction { + /** + * No action + */ + NONE(0), + /** + * Force transition of the frame + */ + TRANSITION(1), + /** + * Open the picture of the frame + */ + OPEN(2), + /** + * Share/send the picture of the frame + */ + SHARE(3); + + private final int mValue; + + /** + * Constructor of <code>TouchAction</code> + * + * @param id The unique identifier + */ + private TouchAction(int value) { + mValue = value; + } + + /** + * Method that returns the value + * + * @return int The value + */ + public int getValue() { + return mValue; + } + + /** + * Method that gets the reference of a TouchAction from its value + * + * @param value The value + * @return TouchAction The reference + */ + public static final TouchAction fromValue(int value) { + if (value == TRANSITION.mValue) return TRANSITION; + if (value == OPEN.mValue) return OPEN; + if (value == SHARE.mValue) return SHARE; + return NONE; + } +} |