Cherish: Add ColorSelectPreference
pulled from Omnilib repo from omnirom for history/authors check https://github.com/omnirom/android_packages_apps_OmniLib/commits/android-10 Change-Id: I5999c551ce0273f5c3b25ff45179a10a9969bbe8
This commit is contained in:
committed by
Hưng Phan
parent
0d3f02daee
commit
e02805e3aa
76
res/layout/dialog_battery_settings.xml
Normal file
76
res/layout/dialog_battery_settings.xml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2010 Daniel Nilsson
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="@dimen/alert_dialog_padding_material"
|
||||||
|
android:paddingStart="@dimen/alert_dialog_padding_material"
|
||||||
|
android:paddingEnd="@dimen/alert_dialog_padding_material" >
|
||||||
|
<com.cherish.settings.ui.ColorPickerView
|
||||||
|
android:id="@+id/color_picker_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="10dp"
|
||||||
|
android:layout_marginStart="10dp" />
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/color_panel_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_marginEnd="10dp"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/hex_color_input"
|
||||||
|
android:layout_width="0px"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.5"
|
||||||
|
android:digits="0123456789ABCDEFabcdef"
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
|
android:maxLength="6" />
|
||||||
|
<com.cherish.settings.ui.ColorPanelView
|
||||||
|
android:id="@+id/color_panel"
|
||||||
|
android:layout_width="0px"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_weight="0.5" />
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/color_list_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="10dp"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/color_list_spinner"
|
||||||
|
android:layout_width="0px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_weight="0.5" />
|
||||||
|
<com.cherish.settings.ui.ColorPanelView
|
||||||
|
android:id="@+id/color_list_panel"
|
||||||
|
android:layout_width="0px"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_weight="0.5" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
11
res/layout/led_color_item.xml
Normal file
11
res/layout/led_color_item.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/textViewName"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:paddingEnd="4dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium" >
|
||||||
|
|
||||||
|
</TextView>
|
||||||
81
res/layout/preference_color_select.xml
Normal file
81
res/layout/preference_color_select.xml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2014 The Android Open Source 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.
|
||||||
|
-->
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:clipToPadding="false" >
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/icon_frame"
|
||||||
|
style="@style/preference_icon_frame"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="start|center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
|
android:paddingTop="4dp"
|
||||||
|
android:paddingBottom="4dp">
|
||||||
|
<com.android.internal.widget.PreferenceImageView
|
||||||
|
android:id="@android:id/icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:maxWidth="48dp"
|
||||||
|
android:maxHeight="48dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingBottom="12dp">
|
||||||
|
|
||||||
|
<TextView android:id="@android:id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:fadingEdge="horizontal" />
|
||||||
|
|
||||||
|
<TextView android:id="@android:id/summary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@android:id/title"
|
||||||
|
android:layout_alignStart="@android:id/title"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:maxLines="1" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="8dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/light_color"
|
||||||
|
android:layout_width="@dimen/color_preference_width"
|
||||||
|
android:layout_height="@dimen/color_preference_height"
|
||||||
|
android:layout_gravity="center" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
@@ -613,4 +613,14 @@
|
|||||||
<item>2</item>
|
<item>2</item>
|
||||||
<item>3</item>
|
<item>3</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="entries_led_colors" translatable="false">
|
||||||
|
<item>@string/led_color_green</item>
|
||||||
|
<item>@string/led_color_red</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="values_led_colors" translatable="false">
|
||||||
|
<item>#FF00FF00</item>
|
||||||
|
<item>#FFFF0000</item>
|
||||||
|
</string-array>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -28,4 +28,10 @@
|
|||||||
<attr name="ledPreview" format="boolean" />
|
<attr name="ledPreview" format="boolean" />
|
||||||
<attr name="alphaSlider" format="boolean" />
|
<attr name="alphaSlider" format="boolean" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
|
<declare-styleable name="ColorSelectPreference">
|
||||||
|
<attr name="ledPreview" format="boolean" />
|
||||||
|
<attr name="multiColor" format="boolean" />
|
||||||
|
<attr name="withAlpha" format="boolean" />
|
||||||
|
</declare-styleable>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -16,8 +16,12 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
|
<!-- Color Picker -->
|
||||||
<dimen name="picker_circle_preview_size">26dp</dimen>
|
<dimen name="picker_circle_preview_size">26dp</dimen>
|
||||||
|
<dimen name="oval_notification_size">26dp</dimen>
|
||||||
<dimen name="alert_dialog_padding_material">20dp</dimen>
|
<dimen name="alert_dialog_padding_material">20dp</dimen>
|
||||||
|
<dimen name="color_preference_width">18dip</dimen>
|
||||||
|
<dimen name="color_preference_height">18dip</dimen>
|
||||||
|
|
||||||
<dimen name="fod_picker_item_margin">20dp</dimen>
|
<dimen name="fod_picker_item_margin">20dp</dimen>
|
||||||
<dimen name="fod_picker_item_size">100dp</dimen>
|
<dimen name="fod_picker_item_size">100dp</dimen>
|
||||||
|
|||||||
@@ -58,6 +58,8 @@
|
|||||||
<string name="hex_hint">#ff000000</string>
|
<string name="hex_hint">#ff000000</string>
|
||||||
<string name="set">Set</string>
|
<string name="set">Set</string>
|
||||||
<string name="color_default">Default</string>
|
<string name="color_default">Default</string>
|
||||||
|
<string name="led_color_green">Green</string>
|
||||||
|
<string name="led_color_red">Red</string>
|
||||||
|
|
||||||
<!-- Lockscreen battery info indicator -->
|
<!-- Lockscreen battery info indicator -->
|
||||||
<string name="lockscreen_battery_info_title">Lockscreen charging info</string>
|
<string name="lockscreen_battery_info_title">Lockscreen charging info</string>
|
||||||
@@ -722,5 +724,9 @@
|
|||||||
<string name="pulse_custom_div">Bar spacing</string>
|
<string name="pulse_custom_div">Bar spacing</string>
|
||||||
<string name="pulse_filled_block_size">Block size</string>
|
<string name="pulse_filled_block_size">Block size</string>
|
||||||
<string name="pulse_empty_block_size">Block spacing</string>
|
<string name="pulse_empty_block_size">Block spacing</string>
|
||||||
|
|
||||||
|
<!-- does the device have multi color led support or only
|
||||||
|
a fixed set of led colors -->
|
||||||
|
<bool name="config_has_multi_color_led">true</bool>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
330
src/com/cherish/settings/preferences/ColorSelectDialog.java
Normal file
330
src/com/cherish/settings/preferences/ColorSelectDialog.java
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Daniel Nilsson
|
||||||
|
* 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.cherish.settings.preferences;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.PixelFormat;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.text.InputFilter;
|
||||||
|
import android.text.InputFilter.LengthFilter;
|
||||||
|
import android.util.Pair;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnFocusChangeListener;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.SpinnerAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.cherish.settings.R;
|
||||||
|
import com.cherish.settings.ui.ColorPanelView;
|
||||||
|
import com.cherish.settings.ui.ColorPickerView;
|
||||||
|
import com.cherish.settings.ui.ColorPickerView.OnColorChangedListener;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.IllegalFormatException;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class ColorSelectDialog extends AlertDialog implements
|
||||||
|
ColorPickerView.OnColorChangedListener, TextWatcher, OnFocusChangeListener {
|
||||||
|
|
||||||
|
private static final String TAG = "ColorSelectDialog";
|
||||||
|
private final static String STATE_KEY_COLOR = "BatteryLightDialog:color";
|
||||||
|
|
||||||
|
private ColorPickerView mColorPicker;
|
||||||
|
|
||||||
|
private EditText mHexColorInput;
|
||||||
|
private ColorPanelView mNewColor;
|
||||||
|
private LayoutInflater mInflater;
|
||||||
|
private boolean mMultiColor = true;
|
||||||
|
private Spinner mColorList;
|
||||||
|
private LinearLayout mColorListView;
|
||||||
|
private LinearLayout mColorPanelView;
|
||||||
|
private ColorPanelView mNewListColor;
|
||||||
|
private LedColorAdapter mLedColorAdapter;
|
||||||
|
private boolean mWithAlpha;
|
||||||
|
|
||||||
|
private boolean mShowLedPreview;
|
||||||
|
private boolean mShowMultiColor;
|
||||||
|
private NotificationManager mNoMan;
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
protected ColorSelectDialog(Context context, int initialColor, boolean showMultiColor, boolean showLedPreview, boolean withAlpha) {
|
||||||
|
super(context);
|
||||||
|
mContext = context;
|
||||||
|
mShowLedPreview = showLedPreview;
|
||||||
|
mWithAlpha = withAlpha;
|
||||||
|
mShowMultiColor = showMultiColor;
|
||||||
|
mMultiColor =
|
||||||
|
(getContext().getResources().getBoolean(R.bool.config_has_multi_color_led) || mShowMultiColor);
|
||||||
|
init(initialColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(int color) {
|
||||||
|
// To fight color banding.
|
||||||
|
getWindow().setFormat(PixelFormat.RGBA_8888);
|
||||||
|
setUp(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function sets up the dialog with the proper values. If the speedOff parameters
|
||||||
|
* has a -1 value disable both spinners
|
||||||
|
*
|
||||||
|
* @param color - the color to set
|
||||||
|
* @param speedOn - the flash time in ms
|
||||||
|
* @param speedOff - the flash length in ms
|
||||||
|
*/
|
||||||
|
private void setUp(int color) {
|
||||||
|
mInflater = (LayoutInflater) getContext()
|
||||||
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
View layout = mInflater.inflate(R.layout.dialog_battery_settings, null);
|
||||||
|
|
||||||
|
mNoMan = (NotificationManager)
|
||||||
|
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
|
||||||
|
mHexColorInput = (EditText) layout.findViewById(R.id.hex_color_input);
|
||||||
|
mNewColor = (ColorPanelView) layout.findViewById(R.id.color_panel);
|
||||||
|
mColorPanelView = (LinearLayout) layout.findViewById(R.id.color_panel_view);
|
||||||
|
|
||||||
|
mColorListView = (LinearLayout) layout.findViewById(R.id.color_list_view);
|
||||||
|
mColorList = (Spinner) layout.findViewById(R.id.color_list_spinner);
|
||||||
|
mNewListColor = (ColorPanelView) layout.findViewById(R.id.color_list_panel);
|
||||||
|
|
||||||
|
mColorPicker.setOnColorChangedListener(this);
|
||||||
|
mHexColorInput.setOnFocusChangeListener(this);
|
||||||
|
setAlphaSliderVisible(mWithAlpha);
|
||||||
|
mColorPicker.setColor(color, true);
|
||||||
|
showLed(color);
|
||||||
|
|
||||||
|
mColorList = (Spinner) layout.findViewById(R.id.color_list_spinner);
|
||||||
|
mLedColorAdapter = new LedColorAdapter(
|
||||||
|
R.array.entries_led_colors,
|
||||||
|
R.array.values_led_colors);
|
||||||
|
mColorList.setAdapter(mLedColorAdapter);
|
||||||
|
mColorList.setSelection(mLedColorAdapter.getColorPosition(color));
|
||||||
|
mColorList.setOnItemSelectedListener(mColorListListener);
|
||||||
|
|
||||||
|
setView(layout);
|
||||||
|
|
||||||
|
// show and hide the correct UI depending if we have multi-color led or not
|
||||||
|
if (mMultiColor){
|
||||||
|
mColorListView.setVisibility(View.GONE);
|
||||||
|
mColorPicker.setVisibility(View.VISIBLE);
|
||||||
|
mColorPanelView.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
mColorListView.setVisibility(View.VISIBLE);
|
||||||
|
mColorPicker.setVisibility(View.GONE);
|
||||||
|
mColorPanelView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private AdapterView.OnItemSelectedListener mColorListListener = new AdapterView.OnItemSelectedListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
int color = mLedColorAdapter.getColor(position);
|
||||||
|
mNewListColor.setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle onSaveInstanceState() {
|
||||||
|
Bundle state = super.onSaveInstanceState();
|
||||||
|
state.putInt(STATE_KEY_COLOR, getColor());
|
||||||
|
switchOffLed();
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRestoreInstanceState(Bundle state) {
|
||||||
|
super.onRestoreInstanceState(state);
|
||||||
|
mColorPicker.setColor(state.getInt(STATE_KEY_COLOR), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onColorChanged(int color) {
|
||||||
|
final boolean hasAlpha = mWithAlpha;
|
||||||
|
final String format = hasAlpha ? "%08x" : "%06x";
|
||||||
|
final int mask = hasAlpha ? 0xFFFFFFFF : 0x00FFFFFF;
|
||||||
|
|
||||||
|
mNewColor.setColor(color);
|
||||||
|
mHexColorInput.setText(String.format(Locale.US, format, color & mask));
|
||||||
|
|
||||||
|
showLed(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showLed(int color) {
|
||||||
|
if (mShowLedPreview) {
|
||||||
|
if (color == 0xFFFFFFFF) {
|
||||||
|
// argb white doesn't work
|
||||||
|
color = 0xffffff;
|
||||||
|
}
|
||||||
|
mNoMan.forceShowLedLight(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void switchOffLed() {
|
||||||
|
if (mShowLedPreview) {
|
||||||
|
mNoMan.forceShowLedLight(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
switchOffLed();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlphaSliderVisible(boolean visible) {
|
||||||
|
mHexColorInput.setFilters(new InputFilter[] { new InputFilter.LengthFilter(visible ? 8 : 6) } );
|
||||||
|
mColorPicker.setAlphaSliderVisible(visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColor() {
|
||||||
|
if (mMultiColor){
|
||||||
|
return mColorPicker.getColor();
|
||||||
|
} else {
|
||||||
|
return mNewListColor.getColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LedColorAdapter extends BaseAdapter implements SpinnerAdapter {
|
||||||
|
private ArrayList<Pair<String, Integer>> mColors;
|
||||||
|
|
||||||
|
public LedColorAdapter(int ledColorResource, int ledValueResource) {
|
||||||
|
mColors = new ArrayList<Pair<String, Integer>>();
|
||||||
|
|
||||||
|
String[] color_names = getContext().getResources().getStringArray(ledColorResource);
|
||||||
|
String[] color_values = getContext().getResources().getStringArray(ledValueResource);
|
||||||
|
|
||||||
|
for(int i = 0; i < color_values.length; ++i) {
|
||||||
|
try {
|
||||||
|
int color = Color.parseColor(color_values[i]);
|
||||||
|
mColors.add(new Pair<String, Integer>(color_names[i], color));
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
// Number format is incorrect, ignore entry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will return the position of the spinner entry with the specified
|
||||||
|
* color. Returns 0 if there is no such entry.
|
||||||
|
*/
|
||||||
|
public int getColorPosition(int color) {
|
||||||
|
for (int position = 0; position < getCount(); ++position) {
|
||||||
|
if (getItem(position).second.equals(color)) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColor(int position) {
|
||||||
|
Pair<String, Integer> item = getItem(position);
|
||||||
|
if (item != null){
|
||||||
|
return item.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -1 is white
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return mColors.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pair<String, Integer> getItem(int position) {
|
||||||
|
return mColors.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View view, ViewGroup parent) {
|
||||||
|
if (view == null) {
|
||||||
|
view = mInflater.inflate(R.layout.led_color_item, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair<String, Integer> entry = getItem(position);
|
||||||
|
((TextView) view.findViewById(R.id.textViewName)).setText(entry.first);
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
String hexColor = mHexColorInput.getText().toString();
|
||||||
|
if (!hexColor.isEmpty()) {
|
||||||
|
try {
|
||||||
|
int color = Color.parseColor('#' + hexColor);
|
||||||
|
if (!mWithAlpha) {
|
||||||
|
color |= 0xFF000000; // set opaque
|
||||||
|
}
|
||||||
|
mColorPicker.setColor(color);
|
||||||
|
mNewColor.setColor(color);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
// Number format is incorrect, ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFocusChange(View v, boolean hasFocus) {
|
||||||
|
if (!hasFocus) {
|
||||||
|
mHexColorInput.removeTextChangedListener(this);
|
||||||
|
InputMethodManager inputMethodManager = (InputMethodManager) getContext()
|
||||||
|
.getSystemService(Activity.INPUT_METHOD_SERVICE);
|
||||||
|
inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
|
||||||
|
} else {
|
||||||
|
mHexColorInput.addTextChangedListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
188
src/com/cherish/settings/preferences/ColorSelectPreference.java
Normal file
188
src/com/cherish/settings/preferences/ColorSelectPreference.java
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* 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.cherish.settings.preferences;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.drawable.ShapeDrawable;
|
||||||
|
import android.graphics.drawable.shapes.RectShape;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceViewHolder;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import com.cherish.settings.R;
|
||||||
|
|
||||||
|
public class ColorSelectPreference extends Preference implements DialogInterface.OnDismissListener {
|
||||||
|
|
||||||
|
private static String TAG = "ColorSelectPreference";
|
||||||
|
public static final int DEFAULT_COLOR = 0xFFFFFF; //White
|
||||||
|
|
||||||
|
private ImageView mLightColorView;
|
||||||
|
private Resources mResources;
|
||||||
|
private int mColorValue;
|
||||||
|
private Dialog mDialog;
|
||||||
|
|
||||||
|
private boolean mShowLedPreview;
|
||||||
|
private boolean mShowMultiColor;
|
||||||
|
private boolean mWithAlpha;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context
|
||||||
|
* @param attrs
|
||||||
|
*/
|
||||||
|
public ColorSelectPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
mColorValue = DEFAULT_COLOR;
|
||||||
|
init(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorSelectPreference(Context context, int color) {
|
||||||
|
super(context, null);
|
||||||
|
mColorValue = color;
|
||||||
|
init(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorSelectPreference(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
mColorValue = DEFAULT_COLOR;
|
||||||
|
init(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context, AttributeSet attrs) {
|
||||||
|
setLayoutResource(R.layout.preference_color_select);
|
||||||
|
mResources = getContext().getResources();
|
||||||
|
if (attrs != null) {
|
||||||
|
final TypedArray attributes = context.obtainStyledAttributes(attrs,
|
||||||
|
R.styleable.ColorSelectPreference);
|
||||||
|
final TypedValue useWithAlpha = attributes.peekValue(
|
||||||
|
R.styleable.ColorSelectPreference_withAlpha);
|
||||||
|
if (useWithAlpha != null) {
|
||||||
|
mWithAlpha = (useWithAlpha.type == TypedValue.TYPE_INT_BOOLEAN
|
||||||
|
&& useWithAlpha.data != 0);
|
||||||
|
}
|
||||||
|
final TypedValue useLedPreview = attributes.peekValue(
|
||||||
|
R.styleable.ColorSelectPreference_ledPreview);
|
||||||
|
if (useLedPreview != null) {
|
||||||
|
mShowLedPreview = (useLedPreview.type == TypedValue.TYPE_INT_BOOLEAN
|
||||||
|
&& useLedPreview.data != 0);
|
||||||
|
}
|
||||||
|
final TypedValue useMultiColor = attributes.peekValue(
|
||||||
|
R.styleable.ColorSelectPreference_multiColor);
|
||||||
|
if (useMultiColor != null) {
|
||||||
|
mShowMultiColor = (useMultiColor.type == TypedValue.TYPE_INT_BOOLEAN
|
||||||
|
&& useMultiColor.data != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColor(int color) {
|
||||||
|
mColorValue = color;
|
||||||
|
updatePreferenceViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColor() {
|
||||||
|
return mColorValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(PreferenceViewHolder holder) {
|
||||||
|
super.onBindViewHolder(holder);
|
||||||
|
|
||||||
|
mLightColorView = (ImageView) holder.findViewById(R.id.light_color);
|
||||||
|
|
||||||
|
updatePreferenceViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePreferenceViews() {
|
||||||
|
final int width = (int) mResources.getDimension(R.dimen.color_preference_width);
|
||||||
|
final int height = (int) mResources.getDimension(R.dimen.color_preference_height);
|
||||||
|
|
||||||
|
if (mLightColorView != null) {
|
||||||
|
mLightColorView.setEnabled(true);
|
||||||
|
mLightColorView.setImageDrawable(createRectShape(width, height, 0xFF000000 | mColorValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
if (mDialog != null && mDialog.isShowing()) return;
|
||||||
|
mDialog = getDialog();
|
||||||
|
mDialog.setOnDismissListener(this);
|
||||||
|
mDialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dialog getDialog() {
|
||||||
|
final ColorSelectDialog d = new ColorSelectDialog(getContext(),
|
||||||
|
0xFF000000 | mColorValue, mShowMultiColor, mShowLedPreview, mWithAlpha);
|
||||||
|
|
||||||
|
d.setButton(AlertDialog.BUTTON_POSITIVE, mResources.getString(android.R.string.ok),
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
if (mShowLedPreview) {
|
||||||
|
mColorValue = d.getColor() & 0x00FFFFFF; // strip alpha, led does not support it
|
||||||
|
d.switchOffLed();
|
||||||
|
} else {
|
||||||
|
mColorValue = d.getColor();
|
||||||
|
}
|
||||||
|
updatePreferenceViews();
|
||||||
|
callChangeListener(new Integer(mColorValue));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
d.setButton(AlertDialog.BUTTON_NEGATIVE, mResources.getString(android.R.string.cancel),
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
d.switchOffLed();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ShapeDrawable createRectShape(int width, int height, int color) {
|
||||||
|
ShapeDrawable shape = new ShapeDrawable(new RectShape());
|
||||||
|
shape.setIntrinsicHeight(height);
|
||||||
|
shape.setIntrinsicWidth(width);
|
||||||
|
shape.getPaint().setColor(color);
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
mDialog = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWithAlpha(boolean value) {
|
||||||
|
mWithAlpha = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWithLedPreview(boolean value) {
|
||||||
|
mShowLedPreview = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWithMultiColor(boolean value) {
|
||||||
|
mShowMultiColor = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
125
src/com/cherish/settings/ui/AlphaPatternDrawable.java
Normal file
125
src/com/cherish/settings/ui/AlphaPatternDrawable.java
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Daniel Nilsson
|
||||||
|
* 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.cherish.settings.ui;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.ColorFilter;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Bitmap.Config;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This drawable that draws a simple white and gray chess board pattern. It's
|
||||||
|
* pattern you will often see as a background behind a partly transparent image
|
||||||
|
* in many applications.
|
||||||
|
*
|
||||||
|
* @author Daniel Nilsson
|
||||||
|
*/
|
||||||
|
public class AlphaPatternDrawable extends Drawable {
|
||||||
|
|
||||||
|
private int mRectangleSize = 10;
|
||||||
|
|
||||||
|
private Paint mPaint = new Paint();
|
||||||
|
private Paint mPaintWhite = new Paint();
|
||||||
|
private Paint mPaintGray = new Paint();
|
||||||
|
|
||||||
|
private int numRectanglesHorizontal;
|
||||||
|
private int numRectanglesVertical;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bitmap in which the pattern will be cached.
|
||||||
|
*/
|
||||||
|
private Bitmap mBitmap;
|
||||||
|
|
||||||
|
public AlphaPatternDrawable(int rectangleSize) {
|
||||||
|
mRectangleSize = rectangleSize;
|
||||||
|
mPaintWhite.setColor(0xffffffff);
|
||||||
|
mPaintGray.setColor(0xffcbcbcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
if (mBitmap != null) {
|
||||||
|
canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacity() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlpha(int alpha) {
|
||||||
|
throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColorFilter(ColorFilter cf) {
|
||||||
|
throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBoundsChange(Rect bounds) {
|
||||||
|
super.onBoundsChange(bounds);
|
||||||
|
|
||||||
|
int height = bounds.height();
|
||||||
|
int width = bounds.width();
|
||||||
|
|
||||||
|
numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
|
||||||
|
numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
|
||||||
|
|
||||||
|
generatePatternBitmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will generate a bitmap with the pattern as big as the rectangle we
|
||||||
|
* were allow to draw on. We do this to cache the bitmap so we don't need
|
||||||
|
* to recreate it each time draw() is called since it takes a few
|
||||||
|
* milliseconds.
|
||||||
|
*/
|
||||||
|
private void generatePatternBitmap() {
|
||||||
|
|
||||||
|
if (getBounds().width() <= 0 || getBounds().height() <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
|
||||||
|
Canvas canvas = new Canvas(mBitmap);
|
||||||
|
|
||||||
|
Rect r = new Rect();
|
||||||
|
boolean verticalStartWhite = true;
|
||||||
|
for (int i = 0; i <= numRectanglesVertical; i++) {
|
||||||
|
boolean isWhite = verticalStartWhite;
|
||||||
|
for (int j = 0; j <= numRectanglesHorizontal; j++) {
|
||||||
|
r.top = i * mRectangleSize;
|
||||||
|
r.left = j * mRectangleSize;
|
||||||
|
r.bottom = r.top + mRectangleSize;
|
||||||
|
r.right = r.left + mRectangleSize;
|
||||||
|
|
||||||
|
canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
|
||||||
|
|
||||||
|
isWhite = !isWhite;
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalStartWhite = !verticalStartWhite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
170
src/com/cherish/settings/ui/ColorPanelView.java
Normal file
170
src/com/cherish/settings/ui/ColorPanelView.java
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Daniel Nilsson
|
||||||
|
* 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.cherish.settings.ui;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class draws a panel which which will be filled with a color which can be
|
||||||
|
* set. It can be used to show the currently selected color which you will get
|
||||||
|
* from the {@link ColorPickerView}.
|
||||||
|
*
|
||||||
|
* @author Daniel Nilsson
|
||||||
|
*/
|
||||||
|
public class ColorPanelView extends View {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The width in pixels of the border surrounding the color panel.
|
||||||
|
*/
|
||||||
|
private final static float BORDER_WIDTH_PX = 1;
|
||||||
|
|
||||||
|
private static float mDensity = 1f;
|
||||||
|
|
||||||
|
private int mBorderColor = 0xff6E6E6E;
|
||||||
|
private int mColor = 0xff000000;
|
||||||
|
|
||||||
|
private Paint mBorderPaint;
|
||||||
|
private Paint mColorPaint;
|
||||||
|
|
||||||
|
private RectF mDrawingRect;
|
||||||
|
private RectF mColorRect;
|
||||||
|
|
||||||
|
private AlphaPatternDrawable mAlphaPattern;
|
||||||
|
|
||||||
|
public ColorPanelView(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorPanelView(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorPanelView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
mBorderPaint = new Paint();
|
||||||
|
mColorPaint = new Paint();
|
||||||
|
mDensity = getContext().getResources().getDisplayMetrics().density;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
|
||||||
|
final RectF rect = mColorRect;
|
||||||
|
|
||||||
|
if (BORDER_WIDTH_PX > 0) {
|
||||||
|
mBorderPaint.setColor(mBorderColor);
|
||||||
|
canvas.drawRect(mDrawingRect, mBorderPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mAlphaPattern != null) {
|
||||||
|
mAlphaPattern.draw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
mColorPaint.setColor(mColor);
|
||||||
|
|
||||||
|
canvas.drawRect(rect, mColorPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
|
||||||
|
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
|
int height = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
|
||||||
|
setMeasuredDimension(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||||
|
super.onSizeChanged(w, h, oldw, oldh);
|
||||||
|
|
||||||
|
mDrawingRect = new RectF();
|
||||||
|
mDrawingRect.left = getPaddingLeft();
|
||||||
|
mDrawingRect.right = w - getPaddingRight();
|
||||||
|
mDrawingRect.top = getPaddingTop();
|
||||||
|
mDrawingRect.bottom = h - getPaddingBottom();
|
||||||
|
|
||||||
|
setUpColorRect();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpColorRect() {
|
||||||
|
final RectF dRect = mDrawingRect;
|
||||||
|
|
||||||
|
float left = dRect.left + BORDER_WIDTH_PX;
|
||||||
|
float top = dRect.top + BORDER_WIDTH_PX;
|
||||||
|
float bottom = dRect.bottom - BORDER_WIDTH_PX;
|
||||||
|
float right = dRect.right - BORDER_WIDTH_PX;
|
||||||
|
|
||||||
|
mColorRect = new RectF(left, top, right, bottom);
|
||||||
|
|
||||||
|
mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
|
||||||
|
|
||||||
|
mAlphaPattern.setBounds(Math.round(mColorRect.left),
|
||||||
|
Math.round(mColorRect.top),
|
||||||
|
Math.round(mColorRect.right),
|
||||||
|
Math.round(mColorRect.bottom));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color that should be shown by this view.
|
||||||
|
*
|
||||||
|
* @param color
|
||||||
|
*/
|
||||||
|
public void setColor(int color) {
|
||||||
|
mColor = color;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the color currently show by this view.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getColor() {
|
||||||
|
return mColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color of the border surrounding the panel.
|
||||||
|
*
|
||||||
|
* @param color
|
||||||
|
*/
|
||||||
|
public void setBorderColor(int color) {
|
||||||
|
mBorderColor = color;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the color of the border surrounding the panel.
|
||||||
|
*/
|
||||||
|
public int getBorderColor() {
|
||||||
|
return mBorderColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
841
src/com/cherish/settings/ui/ColorPickerView.java
Normal file
841
src/com/cherish/settings/ui/ColorPickerView.java
Normal file
@@ -0,0 +1,841 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Daniel Nilsson
|
||||||
|
* 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.cherish.settings.ui;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.ComposeShader;
|
||||||
|
import android.graphics.LinearGradient;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.graphics.PorterDuff.Mode;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.graphics.Shader;
|
||||||
|
import android.graphics.Paint.Align;
|
||||||
|
import android.graphics.Paint.Style;
|
||||||
|
import android.graphics.Shader.TileMode;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a color picker to the user and allow them to select a color. A
|
||||||
|
* slider for the alpha channel is also available. Enable it by setting
|
||||||
|
* setAlphaSliderVisible(boolean) to true.
|
||||||
|
*
|
||||||
|
* @author Daniel Nilsson
|
||||||
|
*/
|
||||||
|
public class ColorPickerView extends View {
|
||||||
|
|
||||||
|
public interface OnColorChangedListener {
|
||||||
|
public void onColorChanged(int color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static int PANEL_SAT_VAL = 0;
|
||||||
|
private final static int PANEL_HUE = 1;
|
||||||
|
private final static int PANEL_ALPHA = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The width in pixels of the border surrounding all color panels.
|
||||||
|
*/
|
||||||
|
private final static float BORDER_WIDTH_PX = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The width in dp of the hue panel.
|
||||||
|
*/
|
||||||
|
private float HUE_PANEL_WIDTH = 30f;
|
||||||
|
/**
|
||||||
|
* The height in dp of the alpha panel
|
||||||
|
*/
|
||||||
|
private float ALPHA_PANEL_HEIGHT = 20f;
|
||||||
|
/**
|
||||||
|
* The distance in dp between the different color panels.
|
||||||
|
*/
|
||||||
|
private float PANEL_SPACING = 10f;
|
||||||
|
/**
|
||||||
|
* The radius in dp of the color palette tracker circle.
|
||||||
|
*/
|
||||||
|
private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
|
||||||
|
/**
|
||||||
|
* The dp which the tracker of the hue or alpha panel will extend outside of
|
||||||
|
* its bounds.
|
||||||
|
*/
|
||||||
|
private float RECTANGLE_TRACKER_OFFSET = 2f;
|
||||||
|
|
||||||
|
private static float mDensity = 1f;
|
||||||
|
|
||||||
|
private OnColorChangedListener mListener;
|
||||||
|
|
||||||
|
private Paint mSatValPaint;
|
||||||
|
private Paint mSatValTrackerPaint;
|
||||||
|
|
||||||
|
private Paint mHuePaint;
|
||||||
|
private Paint mHueTrackerPaint;
|
||||||
|
|
||||||
|
private Paint mAlphaPaint;
|
||||||
|
private Paint mAlphaTextPaint;
|
||||||
|
|
||||||
|
private Paint mBorderPaint;
|
||||||
|
|
||||||
|
private Shader mValShader;
|
||||||
|
private Shader mSatShader;
|
||||||
|
private Shader mHueShader;
|
||||||
|
private Shader mAlphaShader;
|
||||||
|
|
||||||
|
private int mAlpha = 0xff;
|
||||||
|
private float mHue = 360f;
|
||||||
|
private float mSat = 0f;
|
||||||
|
private float mVal = 0f;
|
||||||
|
|
||||||
|
private String mAlphaSliderText = "Alpha";
|
||||||
|
private int mSliderTrackerColor = 0xff1c1c1c;
|
||||||
|
private int mBorderColor = 0xff6E6E6E;
|
||||||
|
private boolean mShowAlphaPanel = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To remember which panel that has the "focus" when processing hardware
|
||||||
|
* button data.
|
||||||
|
*/
|
||||||
|
private int mLastTouchedPanel = PANEL_SAT_VAL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offset from the edge we must have or else the finger tracker will get
|
||||||
|
* clipped when it is drawn outside of the view.
|
||||||
|
*/
|
||||||
|
private float mDrawingOffset;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Distance form the edges of the view of where we are allowed to draw.
|
||||||
|
*/
|
||||||
|
private RectF mDrawingRect;
|
||||||
|
|
||||||
|
private RectF mSatValRect;
|
||||||
|
private RectF mHueRect;
|
||||||
|
private RectF mAlphaRect;
|
||||||
|
|
||||||
|
private AlphaPatternDrawable mAlphaPattern;
|
||||||
|
|
||||||
|
private Point mStartTouchPoint = null;
|
||||||
|
|
||||||
|
public ColorPickerView(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorPickerView(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
mDensity = getContext().getResources().getDisplayMetrics().density;
|
||||||
|
PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
|
||||||
|
RECTANGLE_TRACKER_OFFSET *= mDensity;
|
||||||
|
HUE_PANEL_WIDTH *= mDensity;
|
||||||
|
ALPHA_PANEL_HEIGHT *= mDensity;
|
||||||
|
PANEL_SPACING = PANEL_SPACING * mDensity;
|
||||||
|
|
||||||
|
mDrawingOffset = calculateRequiredOffset();
|
||||||
|
initPaintTools();
|
||||||
|
|
||||||
|
// Needed for receiving track ball motion events.
|
||||||
|
setFocusableInTouchMode(true);
|
||||||
|
setFocusable(true);
|
||||||
|
setClickable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPaintTools() {
|
||||||
|
mSatValPaint = new Paint();
|
||||||
|
mSatValTrackerPaint = new Paint();
|
||||||
|
mHuePaint = new Paint();
|
||||||
|
mHueTrackerPaint = new Paint();
|
||||||
|
mAlphaPaint = new Paint();
|
||||||
|
mAlphaTextPaint = new Paint();
|
||||||
|
mBorderPaint = new Paint();
|
||||||
|
|
||||||
|
mSatValTrackerPaint.setStyle(Style.STROKE);
|
||||||
|
mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
|
||||||
|
mSatValTrackerPaint.setAntiAlias(true);
|
||||||
|
|
||||||
|
mHueTrackerPaint.setColor(mSliderTrackerColor);
|
||||||
|
mHueTrackerPaint.setStyle(Style.STROKE);
|
||||||
|
mHueTrackerPaint.setStrokeWidth(2f * mDensity);
|
||||||
|
mHueTrackerPaint.setAntiAlias(true);
|
||||||
|
|
||||||
|
mAlphaTextPaint.setColor(0xff1c1c1c);
|
||||||
|
mAlphaTextPaint.setTextSize(14f * mDensity);
|
||||||
|
mAlphaTextPaint.setAntiAlias(true);
|
||||||
|
mAlphaTextPaint.setTextAlign(Align.CENTER);
|
||||||
|
mAlphaTextPaint.setFakeBoldText(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float calculateRequiredOffset() {
|
||||||
|
float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
|
||||||
|
offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
|
||||||
|
|
||||||
|
return offset * 1.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] buildHueColorArray() {
|
||||||
|
int[] hue = new int[361];
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
for (int i = hue.length - 1; i >= 0; i--, count++) {
|
||||||
|
hue[count] = Color.HSVToColor(new float[] {
|
||||||
|
i, 1f, 1f
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return hue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
drawSatValPanel(canvas);
|
||||||
|
drawHuePanel(canvas);
|
||||||
|
drawAlphaPanel(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawSatValPanel(Canvas canvas) {
|
||||||
|
final RectF rect = mSatValRect;
|
||||||
|
int rgb = Color.HSVToColor(new float[] {
|
||||||
|
mHue, 1f, 1f
|
||||||
|
});
|
||||||
|
|
||||||
|
if (BORDER_WIDTH_PX > 0) {
|
||||||
|
mBorderPaint.setColor(mBorderColor);
|
||||||
|
canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX,
|
||||||
|
rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// On Honeycomb+ we need to use software rendering to create the shader properly
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||||
|
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the overlaying gradients ready and create the ComposeShader
|
||||||
|
if (mValShader == null) {
|
||||||
|
mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
|
||||||
|
0xffffffff, 0xff000000, TileMode.CLAMP);
|
||||||
|
}
|
||||||
|
mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
|
||||||
|
0xffffffff, rgb, TileMode.CLAMP);
|
||||||
|
ComposeShader mShader = new ComposeShader(mValShader, mSatShader, Mode.MULTIPLY);
|
||||||
|
mSatValPaint.setShader(mShader);
|
||||||
|
canvas.drawRect(rect, mSatValPaint);
|
||||||
|
|
||||||
|
Point p = satValToPoint(mSat, mVal);
|
||||||
|
mSatValTrackerPaint.setColor(0xff000000);
|
||||||
|
canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity,
|
||||||
|
mSatValTrackerPaint);
|
||||||
|
|
||||||
|
mSatValTrackerPaint.setColor(0xffdddddd);
|
||||||
|
canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawHuePanel(Canvas canvas) {
|
||||||
|
final RectF rect = mHueRect;
|
||||||
|
|
||||||
|
if (BORDER_WIDTH_PX > 0) {
|
||||||
|
mBorderPaint.setColor(mBorderColor);
|
||||||
|
canvas.drawRect(rect.left - BORDER_WIDTH_PX,
|
||||||
|
rect.top - BORDER_WIDTH_PX,
|
||||||
|
rect.right + BORDER_WIDTH_PX,
|
||||||
|
rect.bottom + BORDER_WIDTH_PX,
|
||||||
|
mBorderPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mHueShader == null) {
|
||||||
|
mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
|
||||||
|
buildHueColorArray(), null, TileMode.CLAMP);
|
||||||
|
mHuePaint.setShader(mHueShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.drawRect(rect, mHuePaint);
|
||||||
|
|
||||||
|
float rectHeight = 4 * mDensity / 2;
|
||||||
|
|
||||||
|
Point p = hueToPoint(mHue);
|
||||||
|
|
||||||
|
RectF r = new RectF();
|
||||||
|
r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
|
||||||
|
r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
|
||||||
|
r.top = p.y - rectHeight;
|
||||||
|
r.bottom = p.y + rectHeight;
|
||||||
|
|
||||||
|
canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawAlphaPanel(Canvas canvas) {
|
||||||
|
if (!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final RectF rect = mAlphaRect;
|
||||||
|
|
||||||
|
if (BORDER_WIDTH_PX > 0) {
|
||||||
|
mBorderPaint.setColor(mBorderColor);
|
||||||
|
canvas.drawRect(rect.left - BORDER_WIDTH_PX,
|
||||||
|
rect.top - BORDER_WIDTH_PX,
|
||||||
|
rect.right + BORDER_WIDTH_PX,
|
||||||
|
rect.bottom + BORDER_WIDTH_PX,
|
||||||
|
mBorderPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
mAlphaPattern.draw(canvas);
|
||||||
|
|
||||||
|
float[] hsv = new float[] {
|
||||||
|
mHue, mSat, mVal
|
||||||
|
};
|
||||||
|
int color = Color.HSVToColor(hsv);
|
||||||
|
int acolor = Color.HSVToColor(0, hsv);
|
||||||
|
|
||||||
|
mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
|
||||||
|
color, acolor, TileMode.CLAMP);
|
||||||
|
|
||||||
|
mAlphaPaint.setShader(mAlphaShader);
|
||||||
|
|
||||||
|
canvas.drawRect(rect, mAlphaPaint);
|
||||||
|
|
||||||
|
if (mAlphaSliderText != null && mAlphaSliderText != "") {
|
||||||
|
canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity,
|
||||||
|
mAlphaTextPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
float rectWidth = 4 * mDensity / 2;
|
||||||
|
Point p = alphaToPoint(mAlpha);
|
||||||
|
|
||||||
|
RectF r = new RectF();
|
||||||
|
r.left = p.x - rectWidth;
|
||||||
|
r.right = p.x + rectWidth;
|
||||||
|
r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
|
||||||
|
r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
|
||||||
|
|
||||||
|
canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point hueToPoint(float hue) {
|
||||||
|
final RectF rect = mHueRect;
|
||||||
|
final float height = rect.height();
|
||||||
|
|
||||||
|
Point p = new Point();
|
||||||
|
p.y = (int) (height - (hue * height / 360f) + rect.top);
|
||||||
|
p.x = (int) rect.left;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point satValToPoint(float sat, float val) {
|
||||||
|
|
||||||
|
final RectF rect = mSatValRect;
|
||||||
|
final float height = rect.height();
|
||||||
|
final float width = rect.width();
|
||||||
|
|
||||||
|
Point p = new Point();
|
||||||
|
|
||||||
|
p.x = (int) (sat * width + rect.left);
|
||||||
|
p.y = (int) ((1f - val) * height + rect.top);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point alphaToPoint(int alpha) {
|
||||||
|
final RectF rect = mAlphaRect;
|
||||||
|
final float width = rect.width();
|
||||||
|
|
||||||
|
Point p = new Point();
|
||||||
|
p.x = (int) (width - (alpha * width / 0xff) + rect.left);
|
||||||
|
p.y = (int) rect.top;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float[] pointToSatVal(float x, float y) {
|
||||||
|
final RectF rect = mSatValRect;
|
||||||
|
float[] result = new float[2];
|
||||||
|
float width = rect.width();
|
||||||
|
float height = rect.height();
|
||||||
|
|
||||||
|
if (x < rect.left) {
|
||||||
|
x = 0f;
|
||||||
|
} else if (x > rect.right) {
|
||||||
|
x = width;
|
||||||
|
} else {
|
||||||
|
x = x - rect.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y < rect.top) {
|
||||||
|
y = 0f;
|
||||||
|
} else if (y > rect.bottom) {
|
||||||
|
y = height;
|
||||||
|
} else {
|
||||||
|
y = y - rect.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
result[0] = 1.f / width * x;
|
||||||
|
result[1] = 1.f - (1.f / height * y);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float pointToHue(float y) {
|
||||||
|
final RectF rect = mHueRect;
|
||||||
|
float height = rect.height();
|
||||||
|
|
||||||
|
if (y < rect.top) {
|
||||||
|
y = 0f;
|
||||||
|
} else if (y > rect.bottom) {
|
||||||
|
y = height;
|
||||||
|
} else {
|
||||||
|
y = y - rect.top;
|
||||||
|
}
|
||||||
|
return 360f - (y * 360f / height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int pointToAlpha(int x) {
|
||||||
|
final RectF rect = mAlphaRect;
|
||||||
|
final int width = (int) rect.width();
|
||||||
|
|
||||||
|
if (x < rect.left) {
|
||||||
|
x = 0;
|
||||||
|
} else if (x > rect.right) {
|
||||||
|
x = width;
|
||||||
|
} else {
|
||||||
|
x = x - (int) rect.left;
|
||||||
|
}
|
||||||
|
return 0xff - (x * 0xff / width);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTrackballEvent(MotionEvent event) {
|
||||||
|
float x = event.getX();
|
||||||
|
float y = event.getY();
|
||||||
|
boolean update = false;
|
||||||
|
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||||
|
switch (mLastTouchedPanel) {
|
||||||
|
case PANEL_SAT_VAL:
|
||||||
|
float sat,
|
||||||
|
val;
|
||||||
|
sat = mSat + x / 50f;
|
||||||
|
val = mVal - y / 50f;
|
||||||
|
if (sat < 0f) {
|
||||||
|
sat = 0f;
|
||||||
|
} else if (sat > 1f) {
|
||||||
|
sat = 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val < 0f) {
|
||||||
|
val = 0f;
|
||||||
|
} else if (val > 1f) {
|
||||||
|
val = 1f;
|
||||||
|
}
|
||||||
|
mSat = sat;
|
||||||
|
mVal = val;
|
||||||
|
update = true;
|
||||||
|
break;
|
||||||
|
case PANEL_HUE:
|
||||||
|
float hue = mHue - y * 10f;
|
||||||
|
if (hue < 0f) {
|
||||||
|
hue = 0f;
|
||||||
|
} else if (hue > 360f) {
|
||||||
|
hue = 360f;
|
||||||
|
}
|
||||||
|
mHue = hue;
|
||||||
|
update = true;
|
||||||
|
break;
|
||||||
|
case PANEL_ALPHA:
|
||||||
|
if (!mShowAlphaPanel || mAlphaRect == null) {
|
||||||
|
update = false;
|
||||||
|
} else {
|
||||||
|
int alpha = (int) (mAlpha - x * 10);
|
||||||
|
if (alpha < 0) {
|
||||||
|
alpha = 0;
|
||||||
|
} else if (alpha > 0xff) {
|
||||||
|
alpha = 0xff;
|
||||||
|
}
|
||||||
|
mAlpha = alpha;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update) {
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
|
||||||
|
mHue, mSat, mVal
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onTrackballEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
boolean update = false;
|
||||||
|
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
|
||||||
|
update = moveTrackersIfNeeded(event);
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
update = moveTrackersIfNeeded(event);
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
mStartTouchPoint = null;
|
||||||
|
update = moveTrackersIfNeeded(event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update) {
|
||||||
|
requestFocus();
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
|
||||||
|
mHue, mSat, mVal
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean moveTrackersIfNeeded(MotionEvent event) {
|
||||||
|
|
||||||
|
if (mStartTouchPoint == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boolean update = false;
|
||||||
|
int startX = mStartTouchPoint.x;
|
||||||
|
int startY = mStartTouchPoint.y;
|
||||||
|
|
||||||
|
if (mHueRect.contains(startX, startY)) {
|
||||||
|
mLastTouchedPanel = PANEL_HUE;
|
||||||
|
mHue = pointToHue(event.getY());
|
||||||
|
update = true;
|
||||||
|
} else if (mSatValRect.contains(startX, startY)) {
|
||||||
|
mLastTouchedPanel = PANEL_SAT_VAL;
|
||||||
|
float[] result = pointToSatVal(event.getX(), event.getY());
|
||||||
|
mSat = result[0];
|
||||||
|
mVal = result[1];
|
||||||
|
update = true;
|
||||||
|
} else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) {
|
||||||
|
mLastTouchedPanel = PANEL_ALPHA;
|
||||||
|
mAlpha = pointToAlpha((int) event.getX());
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
|
||||||
|
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||||
|
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||||
|
|
||||||
|
int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
|
int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
|
||||||
|
widthAllowed = chooseWidth(widthMode, widthAllowed);
|
||||||
|
heightAllowed = chooseHeight(heightMode, heightAllowed);
|
||||||
|
|
||||||
|
if (!mShowAlphaPanel) {
|
||||||
|
height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
|
||||||
|
|
||||||
|
// If calculated height (based on the width) is more than the
|
||||||
|
// allowed height.
|
||||||
|
if (height > heightAllowed && heightMode != MeasureSpec.UNSPECIFIED) {
|
||||||
|
height = heightAllowed;
|
||||||
|
width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
|
||||||
|
} else {
|
||||||
|
width = widthAllowed;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
|
||||||
|
|
||||||
|
if (width > widthAllowed && widthMode != MeasureSpec.UNSPECIFIED) {
|
||||||
|
width = widthAllowed;
|
||||||
|
height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
|
||||||
|
} else {
|
||||||
|
height = heightAllowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setMeasuredDimension(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int chooseWidth(int mode, int size) {
|
||||||
|
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
|
||||||
|
return size;
|
||||||
|
} else { // (mode == MeasureSpec.UNSPECIFIED)
|
||||||
|
return getPrefferedWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int chooseHeight(int mode, int size) {
|
||||||
|
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
|
||||||
|
return size;
|
||||||
|
} else { // (mode == MeasureSpec.UNSPECIFIED)
|
||||||
|
return getPrefferedHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getPrefferedWidth() {
|
||||||
|
int width = getPrefferedHeight();
|
||||||
|
if (mShowAlphaPanel) {
|
||||||
|
width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
|
||||||
|
}
|
||||||
|
return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getPrefferedHeight() {
|
||||||
|
int height = (int) (200 * mDensity);
|
||||||
|
if (mShowAlphaPanel) {
|
||||||
|
height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
|
||||||
|
}
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||||
|
super.onSizeChanged(w, h, oldw, oldh);
|
||||||
|
|
||||||
|
mDrawingRect = new RectF();
|
||||||
|
mDrawingRect.left = mDrawingOffset + getPaddingLeft();
|
||||||
|
mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
|
||||||
|
mDrawingRect.top = mDrawingOffset + getPaddingTop();
|
||||||
|
mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
|
||||||
|
|
||||||
|
setUpSatValRect();
|
||||||
|
setUpHueRect();
|
||||||
|
setUpAlphaRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpSatValRect() {
|
||||||
|
final RectF dRect = mDrawingRect;
|
||||||
|
float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
|
||||||
|
|
||||||
|
if (mShowAlphaPanel) {
|
||||||
|
panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
float left = dRect.left + BORDER_WIDTH_PX;
|
||||||
|
float top = dRect.top + BORDER_WIDTH_PX;
|
||||||
|
float bottom = top + panelSide;
|
||||||
|
float right = left + panelSide;
|
||||||
|
mSatValRect = new RectF(left, top, right, bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpHueRect() {
|
||||||
|
final RectF dRect = mDrawingRect;
|
||||||
|
|
||||||
|
float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
|
||||||
|
float top = dRect.top + BORDER_WIDTH_PX;
|
||||||
|
float bottom = dRect.bottom - BORDER_WIDTH_PX
|
||||||
|
- (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0);
|
||||||
|
float right = dRect.right - BORDER_WIDTH_PX;
|
||||||
|
|
||||||
|
mHueRect = new RectF(left, top, right, bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpAlphaRect() {
|
||||||
|
if (!mShowAlphaPanel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final RectF dRect = mDrawingRect;
|
||||||
|
float left = dRect.left + BORDER_WIDTH_PX;
|
||||||
|
float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
|
||||||
|
float bottom = dRect.bottom - BORDER_WIDTH_PX;
|
||||||
|
float right = dRect.right - BORDER_WIDTH_PX;
|
||||||
|
|
||||||
|
mAlphaRect = new RectF(left, top, right, bottom);
|
||||||
|
mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
|
||||||
|
mAlphaPattern.setBounds(Math.round(mAlphaRect.left), Math
|
||||||
|
.round(mAlphaRect.top), Math.round(mAlphaRect.right), Math
|
||||||
|
.round(mAlphaRect.bottom));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a OnColorChangedListener to get notified when the color selected by
|
||||||
|
* the user has changed.
|
||||||
|
*
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
public void setOnColorChangedListener(OnColorChangedListener listener) {
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color of the border surrounding all panels.
|
||||||
|
*
|
||||||
|
* @param color
|
||||||
|
*/
|
||||||
|
public void setBorderColor(int color) {
|
||||||
|
mBorderColor = color;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the color of the border surrounding all panels.
|
||||||
|
*/
|
||||||
|
public int getBorderColor() {
|
||||||
|
return mBorderColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current color this view is showing.
|
||||||
|
*
|
||||||
|
* @return the current color.
|
||||||
|
*/
|
||||||
|
public int getColor() {
|
||||||
|
return Color.HSVToColor(mAlpha, new float[] {
|
||||||
|
mHue, mSat, mVal
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color the view should show.
|
||||||
|
*
|
||||||
|
* @param color The color that should be selected.
|
||||||
|
*/
|
||||||
|
public void setColor(int color) {
|
||||||
|
setColor(color, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color this view should show.
|
||||||
|
*
|
||||||
|
* @param color The color that should be selected.
|
||||||
|
* @param callback If you want to get a callback to your
|
||||||
|
* OnColorChangedListener.
|
||||||
|
*/
|
||||||
|
public void setColor(int color, boolean callback) {
|
||||||
|
int alpha = Color.alpha(color);
|
||||||
|
int red = Color.red(color);
|
||||||
|
int blue = Color.blue(color);
|
||||||
|
int green = Color.green(color);
|
||||||
|
float[] hsv = new float[3];
|
||||||
|
|
||||||
|
Color.RGBToHSV(red, green, blue, hsv);
|
||||||
|
mAlpha = alpha;
|
||||||
|
mHue = hsv[0];
|
||||||
|
mSat = hsv[1];
|
||||||
|
mVal = hsv[2];
|
||||||
|
|
||||||
|
if (callback && mListener != null) {
|
||||||
|
mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
|
||||||
|
mHue, mSat, mVal
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the drawing offset of the color picker view. The drawing offset is
|
||||||
|
* the distance from the side of a panel to the side of the view minus the
|
||||||
|
* padding. Useful if you want to have your own panel below showing the
|
||||||
|
* currently selected color and want to align it perfectly.
|
||||||
|
*
|
||||||
|
* @return The offset in pixels.
|
||||||
|
*/
|
||||||
|
public float getDrawingOffset() {
|
||||||
|
return mDrawingOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if the user is allowed to adjust the alpha panel. Default is false.
|
||||||
|
* If it is set to false no alpha will be set.
|
||||||
|
*
|
||||||
|
* @param visible
|
||||||
|
*/
|
||||||
|
public void setAlphaSliderVisible(boolean visible) {
|
||||||
|
if (mShowAlphaPanel != visible) {
|
||||||
|
mShowAlphaPanel = visible;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset all shader to force a recreation. Otherwise they will not
|
||||||
|
* look right after the size of the view has changed.
|
||||||
|
*/
|
||||||
|
mValShader = null;
|
||||||
|
mSatShader = null;
|
||||||
|
mHueShader = null;
|
||||||
|
mAlphaShader = null;
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAlphaSliderVisible() {
|
||||||
|
return mShowAlphaPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSliderTrackerColor(int color) {
|
||||||
|
mSliderTrackerColor = color;
|
||||||
|
mHueTrackerPaint.setColor(mSliderTrackerColor);
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSliderTrackerColor() {
|
||||||
|
return mSliderTrackerColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the text that should be shown in the alpha slider. Set to null to
|
||||||
|
* disable text.
|
||||||
|
*
|
||||||
|
* @param res string resource id.
|
||||||
|
*/
|
||||||
|
public void setAlphaSliderText(int res) {
|
||||||
|
String text = getContext().getString(res);
|
||||||
|
setAlphaSliderText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the text that should be shown in the alpha slider. Set to null to
|
||||||
|
* disable text.
|
||||||
|
*
|
||||||
|
* @param text Text that should be shown.
|
||||||
|
*/
|
||||||
|
public void setAlphaSliderText(String text) {
|
||||||
|
mAlphaSliderText = text;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current value of the text that will be shown in the alpha slider.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getAlphaSliderText() {
|
||||||
|
return mAlphaSliderText;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user