diff options
Diffstat (limited to 'src/com/android/settings')
5 files changed, 1216 insertions, 0 deletions
diff --git a/src/com/android/settings/cyanogenmod/DraggableGridView.java b/src/com/android/settings/cyanogenmod/DraggableGridView.java new file mode 100644 index 0000000..f2390b6 --- /dev/null +++ b/src/com/android/settings/cyanogenmod/DraggableGridView.java @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2011, Animoto Inc. + * Copyright (C) 2012 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 com.android.settings.cyanogenmod; + +import java.util.Collections; +import java.util.ArrayList; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Color; +import android.graphics.Point; +import android.graphics.PorterDuff.Mode; +import android.os.Handler; +import android.os.SystemClock; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.AnimationSet; +import android.view.animation.ScaleAnimation; +import android.view.animation.TranslateAnimation; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.settings.R; +import com.android.settings.cyanogenmod.QuickSettingsTiles.OnRearrangeListener; + +public class DraggableGridView extends ViewGroup implements + View.OnTouchListener, View.OnClickListener, View.OnLongClickListener { + + public static float childRatio = .95f; + protected int colCount, childSize, padding, dpi, scroll = 0; + protected float lastDelta = 0; + protected Handler handler = new Handler(); + protected int dragged = -1, lastX = -1, lastY = -1, lastTarget = -1; + protected boolean enabled = true, touching = false, isDelete = false; + public static int animT = 150; + protected ArrayList<Integer> newPositions = new ArrayList<Integer>(); + protected OnRearrangeListener onRearrangeListener; + protected OnClickListener secondaryOnClickListener; + private OnItemClickListener onItemClickListener; + + public DraggableGridView(Context context, AttributeSet attrs) { + super(context, attrs); + setListeners(); + handler.removeCallbacks(updateTask); + handler.postAtTime(updateTask, SystemClock.uptimeMillis() + 500); + setChildrenDrawingOrderEnabled(true); + DisplayMetrics metrics = new DisplayMetrics(); + ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metrics); + dpi = metrics.densityDpi; + } + + protected void setListeners() { + setOnTouchListener(this); + super.setOnClickListener(this); + setOnLongClickListener(this); + } + + @Override + public void setOnClickListener(OnClickListener l) { + secondaryOnClickListener = l; + } + + protected Runnable updateTask = new Runnable() { + public void run() { + if (dragged != -1) { + if (lastY < padding * 3 && scroll > 0) + scroll -= 20; + else if (lastY > getBottom() - getTop() - (padding * 3) + && scroll < getMaxScroll()) + scroll += 20; + } else if (lastDelta != 0 && !touching) { + scroll += lastDelta; + lastDelta *= .9; + if (Math.abs(lastDelta) < .25) + lastDelta = 0; + } + clampScroll(); + onLayout(true, getLeft(), getTop(), getRight(), getBottom()); + handler.postDelayed(this, 25); + } + }; + + @Override + public void addView(View child, int index) { + super.addView(child, index); + newPositions.add(-1); + } + + @Override + public void addView(View child) { + super.addView(child); + newPositions.add(-1); + }; + + @Override + public void removeViewAt(int index) { + super.removeViewAt(index); + newPositions.remove(index); + }; + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + // compute width of view, in dp + float w = (r - l) / (dpi / 160f); + + // determine number of columns, at least 2 + colCount = 3; + + // determine childSize and padding, in px + childSize = (r - l) / colCount; + childSize = Math.round(childSize * childRatio); + padding = ((r - l) - (childSize * colCount)) / (colCount + 1); + + for (int i = 0; i < getChildCount(); i++) { + if (i != dragged) { + Point xy = getCoorFromIndex(i); + getChildAt(i).layout(xy.x, xy.y, xy.x + childSize, + xy.y + childSize); + } + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // Calculate the cell width dynamically + int width = MeasureSpec.getSize(widthMeasureSpec); + int height = MeasureSpec.getSize(heightMeasureSpec); + int availableWidth = (int) (width - getPaddingLeft() + - getPaddingRight() - (3 - 1) * 0); + float cellWidth = (float) Math.ceil(((float) availableWidth) / 3); + + // Update each of the children's widths accordingly to the cell width + int N = getChildCount(); + int cellHeight = 0; + int cursor = 0; + for (int i = 0; i < N; ++i) { + // Update the child's width + View v = (View) getChildAt(i); + if (v.getVisibility() != View.GONE) { + ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) v + .getLayoutParams(); + int colSpan = 1; + lp.width = (int) ((colSpan * cellWidth) + (colSpan - 1) * 0); + + // Measure the child + int newWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, + MeasureSpec.EXACTLY); + int newHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, + MeasureSpec.EXACTLY); + v.measure(newWidthSpec, newHeightSpec); + + // Save the cell height + if (cellHeight <= 0) { + cellHeight = height; + } + cursor += colSpan; + } + } + + // Set the measured dimensions. We always fill the tray width, but wrap + // to the height of + // all the tiles. + int numRows = (int) Math.ceil((float) cursor / 3); + int newHeight = (int) ((numRows * cellHeight) + ((numRows - 1) * 0)) + + getPaddingTop() + getPaddingBottom(); + // setMeasuredDimension(width, newHeight); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + @Override + protected int getChildDrawingOrder(int childCount, int i) { + if (dragged == -1) + return i; + else if (i == childCount - 1) + return dragged; + else if (i >= dragged) + return i + 1; + return i; + } + + public int getIndexFromCoor(int x, int y) { + int col = getColOrRowFromCoor(x), row = getColOrRowFromCoor(y + scroll); + if (col == -1 || row == -1) // touch is between columns or rows + return -1; + int index = row * colCount + col; + if (index >= getChildCount()) + return -1; + return index; + } + + protected int getColOrRowFromCoor(int coor) { + coor -= padding; + for (int i = 0; coor > 0; i++) { + if (coor < childSize) + return i; + coor -= (childSize + padding); + } + return -1; + } + + protected int getTargetFromCoor(int x, int y) { + if (getColOrRowFromCoor(y + scroll) == -1) // touch is between rows + return -1; + + int leftPos = getIndexFromCoor(x - (childSize / 4), y); + int rightPos = getIndexFromCoor(x + (childSize / 4), y); + if (leftPos == -1 && rightPos == -1) // touch is in the middle of + // nowhere + return -1; + if (leftPos == rightPos) // touch is in the middle of a visual + return -1; + + int target = -1; + if (rightPos > -1) + target = rightPos; + else if (leftPos > -1) + target = leftPos + 1; + if (dragged < target) + return target - 1; + + return target; + } + + protected Point getCoorFromIndex(int index) { + int col = index % colCount; + int row = index / colCount; + return new Point(padding / 2 + (childSize + padding / 2) * col, padding + / 2 + (childSize + padding / 2) * row - scroll); + } + + public int getIndexOf(View child) { + for (int i = 0; i < getChildCount(); i++) + if (getChildAt(i) == child) + return i; + return -1; + } + + // EVENT HANDLERS + public void onClick(View view) { + if (enabled) { + if (secondaryOnClickListener != null) + secondaryOnClickListener.onClick(view); + if (onItemClickListener != null) + onItemClickListener.onItemClick(null, + getChildAt(getLastIndex()), getLastIndex(), + getLastIndex() / colCount); + } + } + + void toggleAddDelete(boolean delete) { + int resid = R.drawable.ic_menu_add; + int stringid = R.string.profiles_add; + if (delete) { + resid = R.drawable.ic_menu_delete_holo_dark; + stringid = R.string.dialog_delete_title; + } + TextView addDeleteTile = ((TextView) getChildAt(getChildCount() - 1).findViewById(R.id.qs_text)); + addDeleteTile.setCompoundDrawablesRelativeWithIntrinsicBounds(0, resid, 0, 0); + addDeleteTile.setText(stringid); + } + + public boolean onLongClick(View view) { + if (!enabled) + return false; + int index = getLastIndex(); + if (index != -1 && index != getChildCount() - 1) { + toggleAddDelete(true); + dragged = index; + animateDragged(); + return true; + } + return false; + } + + public boolean onTouch(View view, MotionEvent event) { + int action = event.getAction(); + switch (action & MotionEvent.ACTION_MASK) { + case MotionEvent.ACTION_DOWN: + enabled = true; + lastX = (int) event.getX(); + lastY = (int) event.getY(); + touching = true; + break; + case MotionEvent.ACTION_MOVE: + int delta = lastY - (int) event.getY(); + if (dragged != -1) { + // change draw location of dragged visual + int x = (int) event.getX(), y = (int) event.getY(); + int l = x - (3 * childSize / 4), t = y - (3 * childSize / 4); + getChildAt(dragged).layout(l, t, l + (childSize * 3 / 2), + t + (childSize * 3 / 2)); + + // check for new target hover + int target = getTargetFromCoor(x, y); + //Check if hovering over delete target + if (getIndexFromCoor(x, y) == getChildCount() - 1) { + getChildAt(dragged).setBackgroundColor(Color.RED); + isDelete = true; + break; + } else { + isDelete = false; + getChildAt(dragged).setBackgroundColor(Color.parseColor("#AA222222")); + } + if (lastTarget != target && target != getChildCount() - 1) { + if (target != -1) { + animateGap(target); + lastTarget = target; + } + } + } else { + scroll += delta; + clampScroll(); + if (Math.abs(delta) > 2) + enabled = false; + onLayout(true, getLeft(), getTop(), getRight(), getBottom()); + } + lastX = (int) event.getX(); + lastY = (int) event.getY(); + lastDelta = delta; + break; + case MotionEvent.ACTION_UP: + if (dragged != -1) { + toggleAddDelete(false); + View v = getChildAt(dragged); + if (lastTarget != -1 && !isDelete) + reorderChildren(true); + else { + Point xy = getCoorFromIndex(dragged); + v.layout(xy.x, xy.y, xy.x + childSize, xy.y + childSize); + } + v.clearAnimation(); + if (v instanceof ImageView) + ((ImageView) v).setAlpha(255); + if (isDelete) { + lastTarget = dragged; + removeViewAt(dragged); + onRearrangeListener.onDelete(dragged); + reorderChildren(false); + } + lastTarget = -1; + dragged = -1; + } + touching = false; + isDelete = false; + break; + } + if (dragged != -1) + return true; + return false; + } + + // EVENT HELPERS + protected void animateDragged() { + View v = getChildAt(dragged); + int x = getCoorFromIndex(dragged).x + childSize / 2, y = getCoorFromIndex(dragged).y + + childSize / 2; + int l = x - (3 * childSize / 4), t = y - (3 * childSize / 4); + v.layout(l, t, l + (childSize * 3 / 2), t + (childSize * 3 / 2)); + AnimationSet animSet = new AnimationSet(true); + ScaleAnimation scale = new ScaleAnimation(.667f, 1, .667f, 1, + childSize * 3 / 4, childSize * 3 / 4); + scale.setDuration(animT); + AlphaAnimation alpha = new AlphaAnimation(1, .5f); + alpha.setDuration(animT); + + animSet.addAnimation(scale); + animSet.addAnimation(alpha); + animSet.setFillEnabled(true); + animSet.setFillAfter(true); + + v.clearAnimation(); + v.startAnimation(animSet); + } + + protected void animateGap(int target) { + for (int i = 0; i < getChildCount(); i++) { + View v = getChildAt(i); + if (i == dragged) + continue; + int newPos = i; + if (dragged < target && i >= dragged + 1 && i <= target) + newPos--; + else if (target < dragged && i >= target && i < dragged) + newPos++; + + // animate + int oldPos = i; + if (newPositions.get(i) != -1) + oldPos = newPositions.get(i); + if (oldPos == newPos) + continue; + + Point oldXY = getCoorFromIndex(oldPos); + Point newXY = getCoorFromIndex(newPos); + Point oldOffset = new Point(oldXY.x - v.getLeft(), oldXY.y + - v.getTop()); + Point newOffset = new Point(newXY.x - v.getLeft(), newXY.y + - v.getTop()); + + TranslateAnimation translate = new TranslateAnimation( + Animation.ABSOLUTE, oldOffset.x, Animation.ABSOLUTE, + newOffset.x, Animation.ABSOLUTE, oldOffset.y, + Animation.ABSOLUTE, newOffset.y); + translate.setDuration(animT); + translate.setFillEnabled(true); + translate.setFillAfter(true); + v.clearAnimation(); + v.startAnimation(translate); + + newPositions.set(i, newPos); + } + } + + protected void reorderChildren(boolean notify) { + if (onRearrangeListener != null && notify) + onRearrangeListener.onRearrange(dragged, lastTarget); + ArrayList<View> children = new ArrayList<View>(); + for (int i = 0; i < getChildCount(); i++) { + getChildAt(i).clearAnimation(); + children.add(getChildAt(i)); + } + removeAllViews(); + while (dragged != lastTarget) + if (lastTarget == children.size()) // dragged and dropped to the + // right of the last element + { + children.add(children.remove(dragged)); + dragged = lastTarget; + } else if (dragged < lastTarget) // shift to the right + { + Collections.swap(children, dragged, dragged + 1); + dragged++; + } else if (dragged > lastTarget) // shift to the left + { + Collections.swap(children, dragged, dragged - 1); + dragged--; + } + for (int i = 0; i < children.size(); i++) { + newPositions.set(i, -1); + addView(children.get(i)); + } + onLayout(true, getLeft(), getTop(), getRight(), getBottom()); + } + + public void scrollToTop() { + scroll = 0; + } + + public void scrollToBottom() { + scroll = Integer.MAX_VALUE; + clampScroll(); + } + + protected void clampScroll() { + int stretch = 3, overreach = getHeight() / 2; + int max = getMaxScroll(); + max = Math.max(max, 0); + + if (scroll < -overreach) { + scroll = -overreach; + lastDelta = 0; + } else if (scroll > max + overreach) { + scroll = max + overreach; + lastDelta = 0; + } else if (scroll < 0) { + if (scroll >= -stretch) + scroll = 0; + else if (!touching) + scroll -= scroll / stretch; + } else if (scroll > max) { + if (scroll <= max + stretch) + scroll = max; + else if (!touching) + scroll += (max - scroll) / stretch; + } + } + + protected int getMaxScroll() { + int rowCount = (int) Math.ceil((double) getChildCount() / colCount), max = rowCount + * childSize + (rowCount + 1) * padding - getHeight(); + return max; + } + + public int getLastIndex() { + return getIndexFromCoor(lastX, lastY); + } + + public void setOnRearrangeListener(OnRearrangeListener l) { + this.onRearrangeListener = l; + } + + public void setOnItemClickListener(OnItemClickListener l) { + this.onItemClickListener = l; + } +} diff --git a/src/com/android/settings/cyanogenmod/QuickSettings.java b/src/com/android/settings/cyanogenmod/QuickSettings.java new file mode 100644 index 0000000..d17843c --- /dev/null +++ b/src/com/android/settings/cyanogenmod/QuickSettings.java @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2012 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 com.android.settings.cyanogenmod; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import android.app.ListFragment; +import android.content.ContentResolver; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.net.wimax.WimaxHelper; +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.PreferenceCategory; +import android.preference.PreferenceScreen; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.TextView; + +import com.android.internal.telephony.Phone; +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; + +public class QuickSettings extends SettingsPreferenceFragment implements OnPreferenceChangeListener { + + private static final String TAG = "QuickSettings"; + private static final String SEPARATOR = "OV=I=XseparatorX=I=VO"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.quick_settings_panel_settings); + } + + private static final String TILE_MODES_CATEGORY = "pref_tile_modes"; + private static final String SELECT_TILE_KEY_PREFIX = "pref_tile_"; + private static final String EXP_RING_MODE = "pref_ring_mode"; + + private static final String DYNAMIC_ALARM = "dynamic_alarm"; + private static final String DYNAMIC_BUGREPORT = "dynamic_bugreport"; + private static final String DYNAMIC_IME = "dynamic_ime"; + private static final String DYNAMIC_WIFI = "dynamic_wifi"; + + MultiSelectListPreference mRingMode; + CheckBoxPreference mDynamicAlarm; + CheckBoxPreference mDynamicBugReport; + CheckBoxPreference mDynamicWifi; + CheckBoxPreference mDynamicIme; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + PreferenceScreen prefSet = getPreferenceScreen(); + PackageManager pm = getPackageManager(); + ContentResolver resolver = getActivity().getApplicationContext().getContentResolver(); + + // Add the dynamic tiles checkboxes + mDynamicAlarm = (CheckBoxPreference) prefSet.findPreference(DYNAMIC_ALARM); + mDynamicAlarm.setChecked(Settings.System.getInt(resolver, Settings.System.QS_DYNAMIC_ALARM, 1) == 1); + mDynamicBugReport = (CheckBoxPreference) prefSet.findPreference(DYNAMIC_BUGREPORT); + mDynamicBugReport.setChecked(Settings.System.getInt(resolver, Settings.System.QS_DYNAMIC_BUGREPORT, 1) == 1); + mDynamicIme = (CheckBoxPreference) prefSet.findPreference(DYNAMIC_IME); + mDynamicIme.setChecked(Settings.System.getInt(resolver, Settings.System.QS_DYNAMIC_IME, 1) == 1); + mDynamicWifi = (CheckBoxPreference) prefSet.findPreference(DYNAMIC_WIFI); + mDynamicWifi.setChecked(Settings.System.getInt(resolver, Settings.System.QS_DYNAMIC_WIFI, 1) == 1); + + // Add the ring mode + mRingMode = (MultiSelectListPreference) prefSet.findPreference(EXP_RING_MODE); + String storedRingMode = Settings.System.getString(getActivity() + .getApplicationContext().getContentResolver(), + Settings.System.EXPANDED_RING_MODE); + if (storedRingMode != null) { + String[] ringModeArray = TextUtils.split(storedRingMode, SEPARATOR); + mRingMode.setValues(new HashSet<String>(Arrays.asList(ringModeArray))); + updateSummary(storedRingMode, mRingMode, R.string.pref_ring_mode_summary); + } + mRingMode.setOnPreferenceChangeListener(this); + + // Add the available mode tiles, incase they need to be removed later + PreferenceCategory prefTileModes = (PreferenceCategory) prefSet + .findPreference(TILE_MODES_CATEGORY); + + // get our list of Tiles + ArrayList<String> buttonList = QuickSettingsUtil.getTileListFromString(QuickSettingsUtil + .getCurrentTiles(getActivity().getApplicationContext())); + + // Don't show mobile data options if not supported + boolean isMobileData = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY); + if (!isMobileData) { + QuickSettingsUtil.TILES.remove(QuickSettingsUtil.TILE_MOBILEDATA); + } + } + + public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { + ContentResolver resolver = getActivity().getApplicationContext().getContentResolver(); + if (preference == mDynamicAlarm) { + Settings.System.putInt(resolver, Settings.System.QS_DYNAMIC_ALARM, + mDynamicAlarm.isChecked() ? 1 : 0); + return true; + } else if (preference == mDynamicBugReport) { + Settings.System.putInt(resolver, Settings.System.QS_DYNAMIC_BUGREPORT, + mDynamicBugReport.isChecked() ? 1 : 0); + return true; + } else if (preference == mDynamicIme) { + Settings.System.putInt(resolver, Settings.System.QS_DYNAMIC_IME, + mDynamicIme.isChecked() ? 1 : 0); + return true; + } else if (preference == mDynamicWifi) { + Settings.System.putInt(resolver, Settings.System.QS_DYNAMIC_WIFI, + mDynamicWifi.isChecked() ? 1 : 0); + return true; + } + return super.onPreferenceTreeClick(preferenceScreen, preference); + } + + private class MultiSelectListPreferenceComparator implements Comparator<String> { + private MultiSelectListPreference pref; + + MultiSelectListPreferenceComparator(MultiSelectListPreference p) { + pref = p; + } + + @Override + public int compare(String lhs, String rhs) { + return Integer.compare(pref.findIndexOfValue(lhs), + pref.findIndexOfValue(rhs)); + } + } + + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (preference == mRingMode) { + ArrayList<String> arrValue = new ArrayList<String>((Set<String>) newValue); + Collections.sort(arrValue, new MultiSelectListPreferenceComparator(mRingMode)); + Settings.System.putString(getActivity().getApplicationContext().getContentResolver(), + Settings.System.EXPANDED_RING_MODE, TextUtils.join(SEPARATOR, arrValue)); + updateSummary(TextUtils.join(SEPARATOR, arrValue), mRingMode, R.string.pref_ring_mode_summary); + } + return true; + } + + private void updateSummary(String val, MultiSelectListPreference pref, int defSummary) { + // Update summary message with current values + final String[] values = parseStoredValue(val); + if (values != null) { + final int length = values.length; + final CharSequence[] entries = pref.getEntries(); + StringBuilder summary = new StringBuilder(); + for (int i = 0; i < (length); i++) { + CharSequence entry = entries[Integer.parseInt(values[i])]; + if ((length - i) > 2) { + summary.append(entry).append(", "); + } else if ((length - i) == 2) { + summary.append(entry).append(" & "); + } else if ((length - i) == 1) { + summary.append(entry); + } + } + pref.setSummary(summary); + } else { + pref.setSummary(defSummary); + } + } + + public static String[] parseStoredValue(CharSequence val) { + if (TextUtils.isEmpty(val)) { + return null; + } else { + return val.toString().split(SEPARATOR); + } + } + +} diff --git a/src/com/android/settings/cyanogenmod/QuickSettingsEnabler.java b/src/com/android/settings/cyanogenmod/QuickSettingsEnabler.java new file mode 100644 index 0000000..5e0894c --- /dev/null +++ b/src/com/android/settings/cyanogenmod/QuickSettingsEnabler.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2012 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 com.android.settings.cyanogenmod; + +import android.provider.Settings; +import android.content.Context; +import android.widget.CompoundButton; +import android.widget.Switch; + +import com.android.settings.cyanogenmod.SwitchWidget; + +public class QuickSettingsEnabler extends SwitchWidget { + public QuickSettingsEnabler(Context context, Switch switch_) { + mContext = context; + mSwitch = switch_; + } + + public void resume() { + mSwitch.setOnCheckedChangeListener(this); + } + + public void pause() { + mSwitch.setOnCheckedChangeListener(null); + } + + public void setState(Switch switch_) { + boolean isEnabled = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.EXPANDED_VIEW_WIDGET, 0) == 1; + mSwitch.setChecked(isEnabled); + return; + } + + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + // Do nothing if called as a result of a state machine event + if (mStateMachineEvent) { + return; + } + Settings.System.putInt(mContext.getContentResolver(), Settings.System.EXPANDED_VIEW_WIDGET, + isChecked ? 1 : 0); + return; + } + + private void setSwitchChecked(boolean checked) { + if (checked != mSwitch.isChecked()) { + mStateMachineEvent = true; + mSwitch.setChecked(checked); + mStateMachineEvent = false; + } + } +} diff --git a/src/com/android/settings/cyanogenmod/QuickSettingsTiles.java b/src/com/android/settings/cyanogenmod/QuickSettingsTiles.java new file mode 100644 index 0000000..bc89cb5 --- /dev/null +++ b/src/com/android/settings/cyanogenmod/QuickSettingsTiles.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2012 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 com.android.settings.cyanogenmod; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Random; +import java.util.zip.Inflater; + +import android.app.AlertDialog; +import android.app.Fragment; +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.TextView; +import com.android.settings.R; +import com.android.settings.Utils; +import com.android.settings.cyanogenmod.QuickSettingsUtil.TileInfo; +public class QuickSettingsTiles extends Fragment { + + DraggableGridView mDragView; + private ViewGroup mContainer; + LayoutInflater mInflater; + Resources mSystemUiResources; + TileAdapter mTileAdapter; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + mDragView = new DraggableGridView(getActivity(), null); + mContainer = container; + mInflater = inflater; + PackageManager pm = getActivity().getPackageManager(); + if (pm != null) { + try { + mSystemUiResources = pm.getResourcesForApplication("com.android.systemui"); + } catch (Exception e) { + mSystemUiResources = null; + } + } + mTileAdapter = new TileAdapter(getActivity(), 0); + return mDragView; + } + + void genTiles() { + mDragView.removeAllViews(); + ArrayList<String> tiles = QuickSettingsUtil.getTileListFromString(QuickSettingsUtil.getCurrentTiles(getActivity())); + for (String tileindex : tiles) { + QuickSettingsUtil.TileInfo tile = QuickSettingsUtil.TILES.get(tileindex); + addTile(tile.getTitleResId(), tile.getIcon(), 0, false); + } + addTile(R.string.profiles_add, null, R.drawable.ic_menu_add, false); + } + + /** + * Adds a tile to the dragview + * @param titleId - string id for tile text in systemui + * @param iconSysId - resource id for icon in systemui + * @param iconRegId - resource id for icon in local package + * @param newTile - whether a new tile is being added by user + */ + void addTile(int titleId, String iconSysId, int iconRegId, boolean newTile) { + View v = (View) mInflater.inflate(R.layout.qs_tile, null, false); + final TextView name = (TextView) v.findViewById(R.id.qs_text); + name.setText(titleId); + if (mSystemUiResources != null && iconSysId != null) { + int resId = mSystemUiResources.getIdentifier(iconSysId, null, null); + if (resId > 0) { + try { + Drawable d = mSystemUiResources.getDrawable(resId); + name.setCompoundDrawablesRelativeWithIntrinsicBounds(null, d, null, null); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else { + name.setCompoundDrawablesRelativeWithIntrinsicBounds(0, iconRegId, 0, 0); + } + mDragView.addView(v, newTile ? mDragView.getChildCount() - 1 : mDragView.getChildCount()); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + genTiles(); + mDragView.setOnRearrangeListener(new OnRearrangeListener() { + public void onRearrange(int oldIndex, int newIndex) { + ArrayList<String> tiles = QuickSettingsUtil.getTileListFromString(QuickSettingsUtil.getCurrentTiles(getActivity())); + String oldTile = tiles.get(oldIndex); + tiles.remove(oldIndex); + tiles.add(newIndex, oldTile); + QuickSettingsUtil.saveCurrentTiles(getActivity(), QuickSettingsUtil.getTileStringFromList(tiles)); + } + @Override + public void onDelete(int index) { + ArrayList<String> tiles = QuickSettingsUtil.getTileListFromString(QuickSettingsUtil.getCurrentTiles(getActivity())); + tiles.remove(index); + QuickSettingsUtil.saveCurrentTiles(getActivity(), QuickSettingsUtil.getTileStringFromList(tiles)); + } + }); + mDragView.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { + if (arg2 != mDragView.getChildCount() - 1) return; + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.tile_choose_title) + .setAdapter(mTileAdapter, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, final int position) { + new Thread(new Runnable() { + @Override + public void run() { + ArrayList<String> curr = QuickSettingsUtil.getTileListFromString(QuickSettingsUtil.getCurrentTiles(getActivity())); + curr.add(mTileAdapter.getTileId(position)); + QuickSettingsUtil.saveCurrentTiles(getActivity(), QuickSettingsUtil.getTileStringFromList(curr)); + } + }).start(); + TileInfo info = QuickSettingsUtil.TILES.get(mTileAdapter.getTileId(position)); + addTile(info.getTitleResId(), info.getIcon(), 0, true); + } + }); + builder.create().show(); + } + }); + } + + @Override + public void onResume() { + super.onResume(); + if (Utils.isPhone(getActivity())) { + mContainer.setPadding(20, 0, 0, 0); + } + } + + @SuppressWarnings("rawtypes") + static class TileAdapter extends ArrayAdapter { + + String[] mTileKeys; + Resources mResources; + + public TileAdapter(Context context, int textViewResourceId) { + super(context, android.R.layout.simple_list_item_1); + mTileKeys = new String[getCount()]; + QuickSettingsUtil.TILES.keySet().toArray(mTileKeys); + mResources = context.getResources(); + } + + @Override + public int getCount() { + return QuickSettingsUtil.TILES.size(); + } + + @Override + public Object getItem(int position) { + int resid = QuickSettingsUtil.TILES.get(mTileKeys[position]) + .getTitleResId(); + return mResources.getString(resid); + } + + public String getTileId(int position) { + return QuickSettingsUtil.TILES.get(mTileKeys[position]) + .getId(); + } + + } + + public interface OnRearrangeListener { + public abstract void onRearrange(int oldIndex, int newIndex); + public abstract void onDelete(int index); + } +} diff --git a/src/com/android/settings/cyanogenmod/QuickSettingsUtil.java b/src/com/android/settings/cyanogenmod/QuickSettingsUtil.java new file mode 100644 index 0000000..dec91bb --- /dev/null +++ b/src/com/android/settings/cyanogenmod/QuickSettingsUtil.java @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2012 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 com.android.settings.cyanogenmod; + +import com.android.internal.telephony.PhoneConstants; +import com.android.settings.R; + +import android.content.Context; +import android.net.wimax.WimaxHelper; +import android.provider.Settings; +import android.telephony.TelephonyManager; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; + +/** + * THIS CLASS'S DATA MUST BE KEPT UP-TO-DATE WITH THE DATA IN + * com.android.systemui.statusbar.phone.QuickSettingsController + * IN THE SystemUI PACKAGE. + */ +public class QuickSettingsUtil { + /** + * START OF DATA MATCHING BLOCK + */ + public static final String TILE_USER = "toggleUser"; + public static final String TILE_BATTERY = "toggleBattery"; + public static final String TILE_SETTINGS = "toggleSettings"; + public static final String TILE_WIFI = "toggleWifi"; + public static final String TILE_GPS = "toggleGPS"; + public static final String TILE_BLUETOOTH = "toggleBluetooth"; + public static final String TILE_BRIGHTNESS = "toggleBrightness"; + public static final String TILE_SOUND = "toggleSound"; + public static final String TILE_SYNC = "toggleSync"; + public static final String TILE_WIFIAP = "toggleWifiAp"; + public static final String TILE_SCREENTIMEOUT = "toggleScreenTimeout"; + public static final String TILE_MOBILEDATA = "toggleMobileData"; + public static final String TILE_LOCKSCREEN = "toggleLockScreen"; + public static final String TILE_NETWORKMODE = "toggleNetworkMode"; + public static final String TILE_AUTOROTATE = "toggleAutoRotate"; + public static final String TILE_AIRPLANE = "toggleAirplane"; + public static final String TILE_FLASHLIGHT = "toggleFlashlight"; + public static final String TILE_SLEEP = "toggleSleepMode"; + public static final String TILE_MEDIA_PLAY_PAUSE = "toggleMediaPlayPause"; + public static final String TILE_MEDIA_PREVIOUS = "toggleMediaPrevious"; + public static final String TILE_MEDIA_NEXT = "toggleMediaNext"; + public static final String TILE_LTE = "toggleLte"; + public static final String TILE_WIMAX = "toggleWimax"; + + private static final String TILE_DELIMITER = "|"; + private static final String TILES_DEFAULT = TILE_USER + + TILE_DELIMITER + TILE_BRIGHTNESS + + TILE_DELIMITER + TILE_SETTINGS + + TILE_DELIMITER + TILE_WIFI + + TILE_DELIMITER + TILE_BLUETOOTH + + TILE_DELIMITER + TILE_SOUND; + /** + * END OF DATA MATCHING BLOCK + */ + + // Keep sorted according to titleResId's string value + public static final LinkedHashMap<String, TileInfo> TILES = new LinkedHashMap<String, TileInfo>(); + static { + TILES.put(TILE_AIRPLANE, new QuickSettingsUtil.TileInfo( + TILE_AIRPLANE, R.string.title_tile_airplane, + "com.android.systemui:drawable/stat_airplane_on")); + TILES.put(TILE_BATTERY, new QuickSettingsUtil.TileInfo( + TILE_BATTERY, R.string.title_tile_battery, + "com.android.systemui:drawable/ic_qs_battery_unknown")); + TILES.put(TILE_BLUETOOTH, new QuickSettingsUtil.TileInfo( + TILE_BLUETOOTH, R.string.title_tile_bluetooth, + "com.android.systemui:drawable/stat_bluetooth_on")); + TILES.put(TILE_BRIGHTNESS, new QuickSettingsUtil.TileInfo( + TILE_BRIGHTNESS, R.string.title_tile_brightness, + "com.android.systemui:drawable/stat_brightness_on")); + TILES.put(TILE_SLEEP, new QuickSettingsUtil.TileInfo( + TILE_SLEEP, R.string.title_tile_sleep, + "com.android.systemui:drawable/stat_sleep")); + TILES.put(TILE_GPS, new QuickSettingsUtil.TileInfo( + TILE_GPS, R.string.title_tile_gps, "com.android.systemui:drawable/stat_gps_on")); + TILES.put(TILE_LOCKSCREEN, new QuickSettingsUtil.TileInfo( + TILE_LOCKSCREEN, R.string.title_tile_lockscreen, + "com.android.systemui:drawable/stat_lock_screen_on")); + TILES.put(TILE_MOBILEDATA, new QuickSettingsUtil.TileInfo( + TILE_MOBILEDATA, R.string.title_tile_mobiledata, + "com.android.systemui:drawable/stat_data_on")); + TILES.put(TILE_AUTOROTATE, new QuickSettingsUtil.TileInfo( + TILE_AUTOROTATE, R.string.title_tile_autorotate, + "com.android.systemui:drawable/stat_orientation_on")); + TILES.put(TILE_SETTINGS, new QuickSettingsUtil.TileInfo( + TILE_SETTINGS, R.string.title_tile_settings, + "com.android.systemui:drawable/ic_qs_settings")); + TILES.put(TILE_SOUND, new QuickSettingsUtil.TileInfo( + TILE_SOUND, R.string.title_tile_sound, + "com.android.systemui:drawable/stat_ring_on")); + TILES.put(TILE_WIFI, new QuickSettingsUtil.TileInfo( + TILE_WIFI, R.string.title_tile_wifi, + "com.android.systemui:drawable/stat_wifi_on")); + TILES.put(TILE_USER, new QuickSettingsUtil.TileInfo( + TILE_USER, R.string.title_tile_user, + "com.android.systemui:drawable/ic_qs_default_user")); + +// These toggles are not available yet. Comment out for now +// TILES.put(TILE_FLASHLIGHT, new QuickSettingsUtil.TileInfo( +// TILE_FLASHLIGHT, R.string.title_tile_flashlight, +// "com.android.systemui:drawable/stat_flashlight_on")); +// TILES.put(TILE_NETWORKMODE, new QuickSettingsUtil.TileInfo( +// TILE_NETWORKMODE, R.string.title_tile_networkmode, +// "com.android.systemui:drawable/stat_2g3g_on")); +// TILES.put(TILE_SCREENTIMEOUT, new QuickSettingsUtil.TileInfo( +// TILE_SCREENTIMEOUT, R.string.title_tile_screentimeout, +// "com.android.systemui:drawable/stat_screen_timeout_on")); +// TILES.put(TILE_SYNC, new QuickSettingsUtil.TileInfo( +// TILE_SYNC, R.string.title_tile_sync, +// "com.android.systemui:drawable/stat_sync_on")); +// TILES.put(TILE_WIFIAP, new QuickSettingsUtil.TileInfo( +// TILE_WIFIAP, R.string.title_tile_wifiap, +// "com.android.systemui:drawable/stat_wifi_ap_on")); +// TILES.put(TILE_MEDIA_PREVIOUS, new QuickSettingsUtil.TileInfo( +// TILE_MEDIA_PREVIOUS, R.string.title_tile_media_previous, +// "com.android.systemui:drawable/stat_media_previous")); +// TILES.put(TILE_MEDIA_PLAY_PAUSE, new QuickSettingsUtil.TileInfo( +// TILE_MEDIA_PLAY_PAUSE, R.string.title_tile_media_play_pause, +// "com.android.systemui:drawable/stat_media_play")); +// TILES.put(TILE_MEDIA_NEXT, new QuickSettingsUtil.TileInfo( +// TILE_MEDIA_NEXT, R.string.title_tile_media_next, +// "com.android.systemui:drawable/stat_media_next")); +// if(PhoneConstants.LTE_ON_CDMA_TRUE == TelephonyManager.getDefault().getLteOnCdmaMode() || +// TelephonyManager.getDefault().getLteOnGsmMode() != 0) { +// TILES.put(TILE_LTE, new QuickSettingsUtil.TileInfo( +// TILE_LTE, R.string.title_tile_lte, +// "com.android.systemui:drawable/stat_lte_on")); +// } +// TILES.put(TILE_WIMAX, new QuickSettingsUtil.TileInfo( +// TILE_WIMAX, R.string.title_tile_wimax, +// "com.android.systemui:drawable/stat_wimax_on")); + } + + public static String getCurrentTiles(Context context) { + String tiles = Settings.System.getString(context.getContentResolver(), + Settings.System.QUICK_SETTINGS_TILES); + if (tiles == null) { + tiles = TILES_DEFAULT; + } + return tiles; + } + + public static void saveCurrentTiles(Context context, String tiles) { + Settings.System.putString(context.getContentResolver(), + Settings.System.QUICK_SETTINGS_TILES, tiles); + } + + public static String mergeInNewTileString(String oldString, String newString) { + ArrayList<String> oldList = getTileListFromString(oldString); + ArrayList<String> newList = getTileListFromString(newString); + ArrayList<String> mergedList = new ArrayList<String>(); + + // add any items from oldlist that are in new list + for (String tile : oldList) { + if (newList.contains(tile)) { + mergedList.add(tile); + } + } + + // append anything in newlist that isn't already in the merged list to + // the end of the list + for (String tile : newList) { + if (!mergedList.contains(tile)) { + mergedList.add(tile); + } + } + + // return merged list + return getTileStringFromList(mergedList); + } + + public static ArrayList<String> getTileListFromString(String tiles) { + return new ArrayList<String>(Arrays.asList(tiles.split("\\|"))); + } + + public static String getTileStringFromList(ArrayList<String> tiles) { + if (tiles == null || tiles.size() <= 0) { + return ""; + } else { + String s = tiles.get(0); + for (int i = 1; i < tiles.size(); i++) { + s += TILE_DELIMITER + tiles.get(i); + } + return s; + } + } + + public static class TileInfo { + private String mId; + private int mTitleResId; + private String mIcon; + + public TileInfo(String id, int titleResId, String icon) { + mId = id; + mTitleResId = titleResId; + mIcon = icon; + } + + public String getId() { + return mId; + } + + public int getTitleResId() { + return mTitleResId; + } + + public String getIcon() { + return mIcon; + } + } +} |