mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-27 11:42:16 -05:00
Add (heavily modified) HoloColorPicker
This commit is contained in:
parent
3898a9920a
commit
ffda532612
16
build.xml
16
build.xml
@ -316,8 +316,22 @@
|
|||||||
</else>
|
</else>
|
||||||
</if.contrib>
|
</if.contrib>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
<target name="-update-hcp">
|
||||||
|
<if.contrib>
|
||||||
|
<resourceexists>
|
||||||
|
<file file="plugins/HoloColorPicker/build.xml" />
|
||||||
|
</resourceexists>
|
||||||
|
<else>
|
||||||
|
<echo message="android update lib-project -p plugins/HoloColorPicker/" />
|
||||||
|
<exec executable="${sdk.dir}/tools/${android.executable}" failonerror="true">
|
||||||
|
<arg line="update lib-project -p plugins/HoloColorPicker/" />
|
||||||
|
</exec>
|
||||||
|
</else>
|
||||||
|
</if.contrib>
|
||||||
|
</target>
|
||||||
|
|
||||||
<target name="init" depends="-update-abs, -update-ptr, -update-cl"
|
<target name="init" depends="-update-abs, -update-ptr, -update-cl, -update-hcp"
|
||||||
description="Initialize environment for building" />
|
description="Initialize environment for building" />
|
||||||
|
|
||||||
<!-- overrides default "debug" target" -->
|
<!-- overrides default "debug" target" -->
|
||||||
|
24
plugins/HoloColorPicker/.gitignore
vendored
Normal file
24
plugins/HoloColorPicker/.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#Android generated
|
||||||
|
bin
|
||||||
|
gen
|
||||||
|
|
||||||
|
#Eclipse
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.settings
|
||||||
|
|
||||||
|
#IntelliJ IDEA
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
classes
|
||||||
|
|
||||||
|
#Command line
|
||||||
|
build.xml
|
||||||
|
proguard-project.txt
|
||||||
|
|
||||||
|
#Mac specific
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
#User specific
|
||||||
|
local.properties
|
||||||
|
sample/src/com/cyrilmottier/android/polarissample/util/LocalConfig.java
|
11
plugins/HoloColorPicker/AndroidManifest.xml
Normal file
11
plugins/HoloColorPicker/AndroidManifest.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.larswerkman.colorpicker"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0" >
|
||||||
|
|
||||||
|
<uses-sdk
|
||||||
|
android:minSdkVersion="8"
|
||||||
|
android:targetSdkVersion="16" />
|
||||||
|
|
||||||
|
</manifest>
|
202
plugins/HoloColorPicker/LICENSE
Normal file
202
plugins/HoloColorPicker/LICENSE
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [2012] Lars Werkmann
|
||||||
|
|
||||||
|
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.
|
46
plugins/HoloColorPicker/README.md
Normal file
46
plugins/HoloColorPicker/README.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<h1>Android Holo ColorPicker</h1>
|
||||||
|
|
||||||
|
A Holo themed colorpicker designed by Marie Schweiz and Nick Butcher.
|
||||||
|
|
||||||
|
![image](https://lh3.googleusercontent.com/-RzpEyLl-1xM/UOMyztql1gI/AAAAAAAAATs/UKBuqZZtaZw//HoloColorPickerFramed1.png)
|
||||||
|
![image](https://lh4.googleusercontent.com/-sXAPd8onJ_8/UOMyzjA6c4I/AAAAAAAAATo/DY4kIzo7TtU//HoloColorPickerFramed2.png)
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Documentation</h2>
|
||||||
|
Add this to your xml
|
||||||
|
|
||||||
|
<com.larswerkman.colorpicker.ColorPicker
|
||||||
|
android:id="@+id/picker"
|
||||||
|
android:layout_width="285dp"
|
||||||
|
android:layout_height="290dp"/>
|
||||||
|
|
||||||
|
To change the thickness of the wheel and the pointer you can add this.
|
||||||
|
|
||||||
|
app:wheel_size="2"
|
||||||
|
app:pointer_size="4"
|
||||||
|
|
||||||
|
To get the color of the colorpicker
|
||||||
|
|
||||||
|
ColorPicker picker = (ColorPicker) findViewById(R.id.picker);
|
||||||
|
|
||||||
|
picker.getColor();
|
||||||
|
|
||||||
|
<H2>License</H2>
|
||||||
|
|
||||||
|
Copyright 2012 Lars Werkman
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Devoleped By</h2>
|
||||||
|
**Lars Werkman**
|
BIN
plugins/HoloColorPicker/libs/android-support-v4.jar
Normal file
BIN
plugins/HoloColorPicker/libs/android-support-v4.jar
Normal file
Binary file not shown.
15
plugins/HoloColorPicker/project.properties
Normal file
15
plugins/HoloColorPicker/project.properties
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# This file is automatically generated by Android Tools.
|
||||||
|
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||||
|
#
|
||||||
|
# This file must be checked in Version Control Systems.
|
||||||
|
#
|
||||||
|
# To customize properties used by the Ant build system edit
|
||||||
|
# "ant.properties", and override values to adapt the script to your
|
||||||
|
# project structure.
|
||||||
|
#
|
||||||
|
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||||
|
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||||
|
|
||||||
|
# Project target.
|
||||||
|
target=android-17
|
||||||
|
android.library=true
|
7
plugins/HoloColorPicker/res/values/attrs.xml
Normal file
7
plugins/HoloColorPicker/res/values/attrs.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<declare-styleable name="ColorPicker">
|
||||||
|
<attr name="wheel_size" format="integer" />
|
||||||
|
<attr name="pointer_size" format="integer" />
|
||||||
|
</declare-styleable>
|
||||||
|
</resources>
|
@ -0,0 +1,486 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Lars Werkman
|
||||||
|
*
|
||||||
|
* 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.larswerkman.colorpicker;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.graphics.Shader;
|
||||||
|
import android.graphics.SweepGradient;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a holo-themed color picker.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Use {@link #getColor()} to retrieve the selected color.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public class ColorPicker extends View {
|
||||||
|
/*
|
||||||
|
* Constants used to save/restore the instance state.
|
||||||
|
*/
|
||||||
|
private static final String STATE_PARENT = "parent";
|
||||||
|
private static final String STATE_ANGLE = "angle";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Colors to construct the color wheel using {@link SweepGradient}.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note: The algorithm in {@link #normalizeColor(int)} highly depends on these exact values. Be
|
||||||
|
* aware that {@link #setColor(int)} might break if you change this array.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
private static final int[] COLORS = new int[] { 0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF,
|
||||||
|
0xFF00FF00, 0xFFFFFF00, 0xFFFF0000 };
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code Paint} instance used to draw the color wheel.
|
||||||
|
*/
|
||||||
|
private Paint mColorWheelPaint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code Paint} instance used to draw the pointer's "halo".
|
||||||
|
*/
|
||||||
|
private Paint mPointerHaloPaint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code Paint} instance used to draw the pointer (the selected color).
|
||||||
|
*/
|
||||||
|
private Paint mPointerColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The stroke width used to paint the color wheel (in pixels).
|
||||||
|
*/
|
||||||
|
private int mColorWheelStrokeWidth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The radius of the pointer (in pixels).
|
||||||
|
*/
|
||||||
|
private int mPointerRadius;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rectangle enclosing the color wheel.
|
||||||
|
*/
|
||||||
|
private RectF mColorWheelRectangle = new RectF();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code true} if the user clicked on the pointer to start the move mode. {@code false} once
|
||||||
|
* the user stops touching the screen.
|
||||||
|
*
|
||||||
|
* @see #onTouchEvent(MotionEvent)
|
||||||
|
*/
|
||||||
|
private boolean mUserIsMovingPointer = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ARGB value of the currently selected color.
|
||||||
|
*/
|
||||||
|
private int mColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of pixels the origin of this view is moved in X- and Y-direction.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* We use the center of this (quadratic) View as origin of our internal coordinate system.
|
||||||
|
* Android uses the upper left corner as origin for the View-specific coordinate system. So this
|
||||||
|
* is the value we use to translate from one coordinate system to the other.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>Note: (Re)calculated in {@link #onMeasure(int, int)}.</p>
|
||||||
|
*
|
||||||
|
* @see #onDraw(Canvas)
|
||||||
|
*/
|
||||||
|
private float mTranslationOffset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Radius of the color wheel in pixels.
|
||||||
|
*
|
||||||
|
* <p>Note: (Re)calculated in {@link #onMeasure(int, int)}.</p>
|
||||||
|
*/
|
||||||
|
private float mColorWheelRadius;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pointer's position expressed as angle (in rad).
|
||||||
|
*/
|
||||||
|
private float mAngle;
|
||||||
|
|
||||||
|
|
||||||
|
public ColorPicker(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(null, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorPicker(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init(attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorPicker(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
init(attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(AttributeSet attrs, int defStyle) {
|
||||||
|
final TypedArray a = getContext().obtainStyledAttributes(attrs,
|
||||||
|
R.styleable.ColorPicker, defStyle, 0);
|
||||||
|
|
||||||
|
mColorWheelStrokeWidth = a.getInteger(R.styleable.ColorPicker_wheel_size, 16);
|
||||||
|
mPointerRadius = a.getInteger(R.styleable.ColorPicker_pointer_size, 48);
|
||||||
|
|
||||||
|
a.recycle();
|
||||||
|
|
||||||
|
Shader s = new SweepGradient(0, 0, COLORS, null);
|
||||||
|
|
||||||
|
mColorWheelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mColorWheelPaint.setShader(s);
|
||||||
|
mColorWheelPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
mColorWheelPaint.setStrokeWidth(mColorWheelStrokeWidth);
|
||||||
|
|
||||||
|
mPointerHaloPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mPointerHaloPaint.setColor(Color.BLACK);
|
||||||
|
mPointerHaloPaint.setStrokeWidth(5);
|
||||||
|
mPointerHaloPaint.setAlpha(0x60);
|
||||||
|
|
||||||
|
mPointerColor = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mPointerColor.setStrokeWidth(5);
|
||||||
|
|
||||||
|
mAngle = (float) (-Math.PI / 2);
|
||||||
|
mPointerColor.setColor(calculateColor(mAngle));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
// All of our positions are using our internal coordinate system. Instead of translating
|
||||||
|
// them we let Canvas do the work for us.
|
||||||
|
canvas.translate(mTranslationOffset, mTranslationOffset);
|
||||||
|
|
||||||
|
// Draw the color wheel.
|
||||||
|
canvas.drawOval(mColorWheelRectangle, mColorWheelPaint);
|
||||||
|
|
||||||
|
float[] pointerPosition = calculatePointerPosition(mAngle);
|
||||||
|
|
||||||
|
// Draw the pointer's "halo"
|
||||||
|
canvas.drawCircle(pointerPosition[0], pointerPosition[1], mPointerRadius, mPointerHaloPaint);
|
||||||
|
|
||||||
|
// Draw the pointer (the currently selected color) slightly smaller on top.
|
||||||
|
canvas.drawCircle(pointerPosition[0], pointerPosition[1],
|
||||||
|
(float) (mPointerRadius / 1.2), mPointerColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
int height = getDefaultSize(getSuggestedMinimumHeight(),
|
||||||
|
heightMeasureSpec);
|
||||||
|
int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
|
||||||
|
int min = Math.min(width, height);
|
||||||
|
setMeasuredDimension(min, min);
|
||||||
|
|
||||||
|
mTranslationOffset = min * 0.5f;
|
||||||
|
mColorWheelRadius = mTranslationOffset - mPointerRadius;
|
||||||
|
|
||||||
|
mColorWheelRectangle.set(-mColorWheelRadius, -mColorWheelRadius, mColorWheelRadius,
|
||||||
|
mColorWheelRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int ave(int s, int d, float p) {
|
||||||
|
return s + java.lang.Math.round(p * (d - s));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the color using the supplied angle.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* The selected color's position expressed as angle (in rad).
|
||||||
|
*
|
||||||
|
* @return The ARGB value of the color on the color wheel at the specified angle.
|
||||||
|
*/
|
||||||
|
private int calculateColor(float angle) {
|
||||||
|
float unit = (float) (angle / (2 * Math.PI));
|
||||||
|
if (unit < 0) {
|
||||||
|
unit += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unit <= 0) {
|
||||||
|
return COLORS[0];
|
||||||
|
}
|
||||||
|
if (unit >= 1) {
|
||||||
|
return COLORS[COLORS.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
float p = unit * (COLORS.length - 1);
|
||||||
|
int i = (int) p;
|
||||||
|
p -= i;
|
||||||
|
|
||||||
|
int c0 = COLORS[i];
|
||||||
|
int c1 = COLORS[i + 1];
|
||||||
|
int a = ave(Color.alpha(c0), Color.alpha(c1), p);
|
||||||
|
int r = ave(Color.red(c0), Color.red(c1), p);
|
||||||
|
int g = ave(Color.green(c0), Color.green(c1), p);
|
||||||
|
int b = ave(Color.blue(c0), Color.blue(c1), p);
|
||||||
|
|
||||||
|
mColor = Color.argb(a, r, g, b);
|
||||||
|
return Color.argb(a, r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the currently selected color.
|
||||||
|
*
|
||||||
|
* @return The ARGB value of the currently selected color.
|
||||||
|
*/
|
||||||
|
public int getColor() {
|
||||||
|
return mColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color to be highlighted by the pointer.
|
||||||
|
*
|
||||||
|
* @param color
|
||||||
|
* The RGB value of the color to highlight. If this is not a color displayed on the
|
||||||
|
* color wheel a very simple algorithm is used to map it to the color wheel. The
|
||||||
|
* resulting color often won't look close to the original color. This is especially true
|
||||||
|
* for shades of grey. You have been warned!
|
||||||
|
*/
|
||||||
|
public void setColor(int color) {
|
||||||
|
mAngle = colorToAngle(color);
|
||||||
|
mPointerColor.setColor(calculateColor(mAngle));
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a color to an angle.
|
||||||
|
*
|
||||||
|
* @param color
|
||||||
|
* The RGB value of the color to "find" on the color wheel. {@link #normalizeColor(int)}
|
||||||
|
* will be used to map this color to one on the color wheel if necessary.
|
||||||
|
*
|
||||||
|
* @return The angle (in rad) the "normalized" color is displayed on the color wheel.
|
||||||
|
*/
|
||||||
|
private float colorToAngle(int color) {
|
||||||
|
int[] colorInfo = normalizeColor(color);
|
||||||
|
int normColor = colorInfo[0];
|
||||||
|
int colorMask = colorInfo[1];
|
||||||
|
int shiftValue = colorInfo[2];
|
||||||
|
|
||||||
|
int anchorColor = (normColor & ~colorMask);
|
||||||
|
|
||||||
|
// Find the "anchor" color in the COLORS array
|
||||||
|
for (int i = 0; i < COLORS.length - 1; i++) {
|
||||||
|
if (COLORS[i] == anchorColor) {
|
||||||
|
int nextValue = COLORS[i + 1];
|
||||||
|
|
||||||
|
double value;
|
||||||
|
double decimals = ((normColor >> shiftValue) & 0xFF) / 255D;
|
||||||
|
|
||||||
|
// Find out if the gradient our color belongs to goes from the element just found to
|
||||||
|
// the next element in the array.
|
||||||
|
if ((nextValue & colorMask) != (anchorColor & colorMask)) {
|
||||||
|
// Compute value depending of the gradient direction
|
||||||
|
if (nextValue < anchorColor) {
|
||||||
|
value = i + 1 - decimals;
|
||||||
|
} else {
|
||||||
|
value = i + decimals;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// It's a gradient from this element to the previous element in the array.
|
||||||
|
|
||||||
|
// Wrap to the end of the array if the "anchor" color is the first element.
|
||||||
|
int index = (i == 0) ? COLORS.length - 1 : i;
|
||||||
|
int prevValue = COLORS[index - 1];
|
||||||
|
|
||||||
|
// Compute value depending of the gradient direction
|
||||||
|
if (prevValue < anchorColor) {
|
||||||
|
value = index - 1 + decimals;
|
||||||
|
} else {
|
||||||
|
value = index - decimals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the angle in rad (from -PI to PI)
|
||||||
|
float angle = (float) (2 * Math.PI * value / (COLORS.length - 1));
|
||||||
|
if (angle > Math.PI) {
|
||||||
|
angle -= 2 * Math.PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This shouldn't happen
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Normalize" the supplied color.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This will set the lowest value of R,G,B to 0, the highest to 255, and will keep the middle
|
||||||
|
* value.<br>
|
||||||
|
* For values close to those on the color wheel this will result in close matches. For other
|
||||||
|
* values, especially shades of grey this will produce funny results.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param color
|
||||||
|
* The color to "normalize".
|
||||||
|
*
|
||||||
|
* @return An {@code int} array with the following contents:
|
||||||
|
* <ol>
|
||||||
|
* <li>The ARGB value of the "normalized" color.</li>
|
||||||
|
* <li>A mask with all bits {@code 0} but those for the byte representing the
|
||||||
|
* "middle value" that remains unchanged in the "normalized" color.</li>
|
||||||
|
* <li>The number of bits the "normalized" color has to be shifted to the right so the
|
||||||
|
* "middle value" is in the lower 8 bits.</li>
|
||||||
|
* </ol>
|
||||||
|
*/
|
||||||
|
private int[] normalizeColor(int color) {
|
||||||
|
int red = Color.red(color);
|
||||||
|
int green = Color.green(color);
|
||||||
|
int blue = Color.blue(color);
|
||||||
|
|
||||||
|
int newRed = red;
|
||||||
|
int newGreen = green;
|
||||||
|
int newBlue = blue;
|
||||||
|
|
||||||
|
int maskRed = 0;
|
||||||
|
int maskGreen = 0;
|
||||||
|
int maskBlue = 0;
|
||||||
|
int shiftValue;
|
||||||
|
|
||||||
|
if (red < green && red < blue) {
|
||||||
|
// Red is the smallest component
|
||||||
|
newRed = 0;
|
||||||
|
if (green > blue) {
|
||||||
|
// Green is the largest component
|
||||||
|
shiftValue = 0;
|
||||||
|
maskBlue = 0xFF;
|
||||||
|
newGreen = 0xFF;
|
||||||
|
} else {
|
||||||
|
// We make blue the largest component
|
||||||
|
shiftValue = 8;
|
||||||
|
maskGreen = 0xFF;
|
||||||
|
newBlue = 0xFF;
|
||||||
|
}
|
||||||
|
} else if (green < red && green < blue) {
|
||||||
|
// Green is the smallest component
|
||||||
|
newGreen = 0;
|
||||||
|
if (red > blue) {
|
||||||
|
// Red is the largest component
|
||||||
|
shiftValue = 0;
|
||||||
|
maskBlue = 0xFF;
|
||||||
|
newRed = 0xFF;
|
||||||
|
} else {
|
||||||
|
// We make blue the largest component
|
||||||
|
shiftValue = 16;
|
||||||
|
maskRed = 0xFF;
|
||||||
|
newBlue = 0xFF;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We make blue the smallest component
|
||||||
|
newBlue = 0;
|
||||||
|
if (red > green) {
|
||||||
|
// Red is the largest component
|
||||||
|
shiftValue = 8;
|
||||||
|
maskGreen = 0xFF;
|
||||||
|
newRed = 0xFF;
|
||||||
|
} else {
|
||||||
|
// We make green the largest component
|
||||||
|
shiftValue = 16;
|
||||||
|
maskRed = 0xFF;
|
||||||
|
newGreen = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int normColor = Color.argb(255, newRed, newGreen, newBlue);
|
||||||
|
int colorMask = Color.argb(0, maskRed, maskGreen, maskBlue);
|
||||||
|
|
||||||
|
return new int[] { normColor, colorMask, shiftValue };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
// Convert coordinates to our internal coordinate system
|
||||||
|
float x = event.getX() - mTranslationOffset;
|
||||||
|
float y = event.getY() - mTranslationOffset;
|
||||||
|
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
// Check whether the user pressed on (or near) the pointer
|
||||||
|
float[] pointerPosition = calculatePointerPosition(mAngle);
|
||||||
|
if (x >= (pointerPosition[0] - 48) && x <= (pointerPosition[0] + 48)
|
||||||
|
&& y >= (pointerPosition[1] - 48) && y <= (pointerPosition[1] + 48)) {
|
||||||
|
mUserIsMovingPointer = true;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
if (mUserIsMovingPointer) {
|
||||||
|
mAngle = (float) java.lang.Math.atan2(y, x);
|
||||||
|
mPointerColor.setColor(calculateColor(mAngle));
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
mUserIsMovingPointer = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the pointer's coordinates on the color wheel using the supplied angle.
|
||||||
|
*
|
||||||
|
* @param angle
|
||||||
|
* The position of the pointer expressed as angle (in rad).
|
||||||
|
*
|
||||||
|
* @return The coordinates of the pointer's center in our internal coordinate system.
|
||||||
|
*/
|
||||||
|
private float[] calculatePointerPosition(float angle) {
|
||||||
|
float x = (float) (mColorWheelRadius * Math.cos(angle));
|
||||||
|
float y = (float) (mColorWheelRadius * Math.sin(angle));
|
||||||
|
|
||||||
|
return new float[] { x, y };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Parcelable onSaveInstanceState() {
|
||||||
|
Parcelable superState = super.onSaveInstanceState();
|
||||||
|
|
||||||
|
Bundle state = new Bundle();
|
||||||
|
state.putParcelable(STATE_PARENT, superState);
|
||||||
|
state.putFloat(STATE_ANGLE, mAngle);
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(Parcelable state) {
|
||||||
|
Bundle savedState = (Bundle) state;
|
||||||
|
|
||||||
|
Parcelable superState = savedState.getParcelable(STATE_PARENT);
|
||||||
|
super.onRestoreInstanceState(superState);
|
||||||
|
|
||||||
|
mAngle = savedState.getFloat(STATE_ANGLE);
|
||||||
|
mPointerColor.setColor(calculateColor(mAngle));
|
||||||
|
}
|
||||||
|
}
|
@ -16,3 +16,4 @@ extensible.libs.classpath=compile-only-libs
|
|||||||
android.library.reference.1=plugins/ActionBarSherlock/library
|
android.library.reference.1=plugins/ActionBarSherlock/library
|
||||||
android.library.reference.2=plugins/Android-PullToRefresh/library
|
android.library.reference.2=plugins/Android-PullToRefresh/library
|
||||||
android.library.reference.3=plugins/ckChangeLog/library
|
android.library.reference.3=plugins/ckChangeLog/library
|
||||||
|
android.library.reference.4=plugins/HoloColorPicker
|
||||||
|
15
res/layout/color_picker_dialog.xml
Normal file
15
res/layout/color_picker_dialog.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res/com.fsck.k9"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent" >
|
||||||
|
|
||||||
|
<com.larswerkman.colorpicker.ColorPicker
|
||||||
|
android:id="@+id/color_picker"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
app:pointer_size="48"
|
||||||
|
app:wheel_size="16" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
@ -1200,7 +1200,8 @@ public class Accounts extends K9ListActivity implements OnItemClickListener {
|
|||||||
new String[] {"HtmlCleaner", "http://htmlcleaner.sourceforge.net/"},
|
new String[] {"HtmlCleaner", "http://htmlcleaner.sourceforge.net/"},
|
||||||
new String[] {"ActionBarSherlock", "http://actionbarsherlock.com/"},
|
new String[] {"ActionBarSherlock", "http://actionbarsherlock.com/"},
|
||||||
new String[] {"Android-PullToRefresh", "https://github.com/chrisbanes/Android-PullToRefresh"},
|
new String[] {"Android-PullToRefresh", "https://github.com/chrisbanes/Android-PullToRefresh"},
|
||||||
new String[] {"ckChangeLog", "https://github.com/cketti/ckChangeLog"}
|
new String[] {"ckChangeLog", "https://github.com/cketti/ckChangeLog"},
|
||||||
|
new String[] {"HoloColorPicker", "https://github.com/LarsWerkman/HoloColorPicker"}
|
||||||
};
|
};
|
||||||
|
|
||||||
private void onAbout() {
|
private void onAbout() {
|
||||||
|
@ -1,218 +1,68 @@
|
|||||||
/* Sourced from http://code.google.com/p/android-color-picker/source/browse/trunk/AmbilWarna/src/yuku/ambilwarna/AmbilWarnaDialog.java?r=1
|
|
||||||
* On 2010-11-07
|
|
||||||
* Translated to English, Ported to use the same (inferior) API as the more standard "ColorPickerDialog" and imported into the K-9 namespace by Jesse Vincent
|
|
||||||
* In an ideal world, we should move to using AmbilWarna as an Android Library Project in the future
|
|
||||||
* License: Apache 2.0
|
|
||||||
* Author: yukuku@code.google.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
package com.fsck.k9.activity;
|
package com.fsck.k9.activity;
|
||||||
|
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.*;
|
import android.content.*;
|
||||||
import android.graphics.Color;
|
import android.view.LayoutInflater;
|
||||||
import android.os.Bundle;
|
import android.view.View;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.*;
|
import com.larswerkman.colorpicker.ColorPicker;
|
||||||
import android.widget.*;
|
|
||||||
import com.fsck.k9.view.ColorPickerBox;
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dialog displaying a color picker.
|
||||||
|
*/
|
||||||
public class ColorPickerDialog extends AlertDialog {
|
public class ColorPickerDialog extends AlertDialog {
|
||||||
private static final String TAG = ColorPickerDialog.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final String BUNDLE_KEY_PARENT_BUNDLE = "parent";
|
|
||||||
private static final String BUNDLE_KEY_COLOR_OLD = "color_old";
|
|
||||||
private static final String BUNDLE_KEY_COLOR_NEW = "color_new";
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interface users of {@link ColorPickerDialog} have to implement to learn the selected
|
||||||
|
* color.
|
||||||
|
*/
|
||||||
public interface OnColorChangedListener {
|
public interface OnColorChangedListener {
|
||||||
|
/**
|
||||||
|
* This is called after the user pressed the "OK" button of the dialog.
|
||||||
|
*
|
||||||
|
* @param color
|
||||||
|
* The ARGB value of the selected color.
|
||||||
|
*/
|
||||||
void colorChanged(int color);
|
void colorChanged(int color);
|
||||||
}
|
}
|
||||||
|
|
||||||
OnColorChangedListener listener;
|
OnColorChangedListener mColorChangedListener;
|
||||||
View viewHue;
|
ColorPicker mColorPicker;
|
||||||
ColorPickerBox viewBox;
|
|
||||||
ImageView arrow;
|
|
||||||
View viewColorOld;
|
|
||||||
View viewColorNew;
|
|
||||||
ImageView viewSpyglass;
|
|
||||||
|
|
||||||
float onedp;
|
|
||||||
int colorOld;
|
|
||||||
int colorNew;
|
|
||||||
float hue;
|
|
||||||
float sat;
|
|
||||||
float val;
|
|
||||||
float sizeUiDp = 240.f;
|
|
||||||
float sizeUiPx; // diset di constructor
|
|
||||||
|
|
||||||
public ColorPickerDialog(Context context, OnColorChangedListener listener, int color) {
|
public ColorPickerDialog(Context context, OnColorChangedListener listener, int color) {
|
||||||
super(context);
|
super(context);
|
||||||
this.listener = listener;
|
mColorChangedListener = listener;
|
||||||
|
|
||||||
initColor(color);
|
View view = LayoutInflater.from(context).inflate(R.layout.color_picker_dialog, null);
|
||||||
|
|
||||||
onedp = context.getResources().getDimension(R.dimen.colorpicker_onedp);
|
mColorPicker = (ColorPicker) view.findViewById(R.id.color_picker);
|
||||||
sizeUiPx = sizeUiDp * onedp;
|
mColorPicker.setColor(color);
|
||||||
Log.d(TAG, "onedp = " + onedp + ", sizeUiPx=" + sizeUiPx); //$NON-NLS-1$//$NON-NLS-2$
|
|
||||||
|
|
||||||
View view = LayoutInflater.from(context).inflate(R.layout.colorpicker_dialog, null);
|
setView(view);
|
||||||
viewHue = view.findViewById(R.id.colorpicker_viewHue);
|
|
||||||
viewBox = (ColorPickerBox) view.findViewById(R.id.colorpicker_viewBox);
|
|
||||||
arrow = (ImageView) view.findViewById(R.id.colorpicker_arrow);
|
|
||||||
viewColorOld = view.findViewById(R.id.colorpicker_colorOld);
|
|
||||||
viewColorNew = view.findViewById(R.id.colorpicker_colorNew);
|
|
||||||
viewSpyglass = (ImageView) view.findViewById(R.id.colorpicker_spyglass);
|
|
||||||
|
|
||||||
updateView();
|
setButton(BUTTON_POSITIVE, context.getString(R.string.okay_action),
|
||||||
|
|
||||||
viewHue.setOnTouchListener(new View.OnTouchListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
if (event.getAction() == MotionEvent.ACTION_MOVE
|
|
||||||
|| event.getAction() == MotionEvent.ACTION_DOWN
|
|
||||||
|| event.getAction() == MotionEvent.ACTION_UP) {
|
|
||||||
|
|
||||||
float y = event.getY(); // dalam px, bukan dp
|
|
||||||
if (y < 0.f) y = 0.f;
|
|
||||||
if (y > sizeUiPx) y = sizeUiPx - 0.001f;
|
|
||||||
|
|
||||||
hue = 360.f - 360.f / sizeUiPx * y;
|
|
||||||
if (hue == 360.f) hue = 0.f;
|
|
||||||
|
|
||||||
colorNew = calculateColor();
|
|
||||||
// update view
|
|
||||||
viewBox.setHue(hue);
|
|
||||||
placeArrow();
|
|
||||||
viewColorNew.setBackgroundColor(colorNew);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
viewBox.setOnTouchListener(new View.OnTouchListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
if (event.getAction() == MotionEvent.ACTION_MOVE
|
|
||||||
|| event.getAction() == MotionEvent.ACTION_DOWN
|
|
||||||
|| event.getAction() == MotionEvent.ACTION_UP) {
|
|
||||||
|
|
||||||
float x = event.getX(); // dalam px, bukan dp
|
|
||||||
float y = event.getY(); // dalam px, bukan dp
|
|
||||||
|
|
||||||
if (x < 0.f) x = 0.f;
|
|
||||||
if (x > sizeUiPx) x = sizeUiPx;
|
|
||||||
if (y < 0.f) y = 0.f;
|
|
||||||
if (y > sizeUiPx) y = sizeUiPx;
|
|
||||||
|
|
||||||
sat = (1.f / sizeUiPx * x);
|
|
||||||
val = 1.f - (1.f / sizeUiPx * y);
|
|
||||||
|
|
||||||
colorNew = calculateColor();
|
|
||||||
// update view
|
|
||||||
placeSpyglass();
|
|
||||||
viewColorNew.setBackgroundColor(colorNew);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setView(view);
|
|
||||||
this.setButton(BUTTON_POSITIVE, context.getString(R.string.okay_action),
|
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
if (ColorPickerDialog.this.listener != null) {
|
if (mColorChangedListener != null) {
|
||||||
ColorPickerDialog.this.listener.colorChanged(colorNew);
|
mColorChangedListener.colorChanged(mColorPicker.getColor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setButton(BUTTON_NEGATIVE, context.getString(R.string.cancel_action), (OnClickListener) null);
|
setButton(BUTTON_NEGATIVE, context.getString(R.string.cancel_action),
|
||||||
}
|
(OnClickListener) null);
|
||||||
|
|
||||||
private void updateView() {
|
|
||||||
placeArrow();
|
|
||||||
placeSpyglass();
|
|
||||||
viewBox.setHue(hue);
|
|
||||||
viewColorOld.setBackgroundColor(colorOld);
|
|
||||||
viewColorNew.setBackgroundColor(colorNew);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initColor(int color) {
|
|
||||||
colorNew = color;
|
|
||||||
colorOld = color;
|
|
||||||
|
|
||||||
Color.colorToHSV(color, tmp01);
|
|
||||||
hue = tmp01[0];
|
|
||||||
sat = tmp01[1];
|
|
||||||
val = tmp01[2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color the color picker should highlight as selected color.
|
||||||
|
*
|
||||||
|
* @param color
|
||||||
|
* The (A)RGB value of a color (the alpha channel will be ignored).
|
||||||
|
*/
|
||||||
public void setColor(int color) {
|
public void setColor(int color) {
|
||||||
initColor(color);
|
mColorPicker.setColor(color);
|
||||||
updateView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Bundle onSaveInstanceState() {
|
|
||||||
Bundle parentBundle = super.onSaveInstanceState();
|
|
||||||
|
|
||||||
Bundle savedInstanceState = new Bundle();
|
|
||||||
savedInstanceState.putBundle(BUNDLE_KEY_PARENT_BUNDLE, parentBundle);
|
|
||||||
savedInstanceState.putInt(BUNDLE_KEY_COLOR_OLD, colorOld);
|
|
||||||
savedInstanceState.putInt(BUNDLE_KEY_COLOR_NEW, colorNew);
|
|
||||||
|
|
||||||
return savedInstanceState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRestoreInstanceState(Bundle savedInstanceState) {
|
|
||||||
Bundle parentBundle = savedInstanceState.getBundle(BUNDLE_KEY_PARENT_BUNDLE);
|
|
||||||
super.onRestoreInstanceState(parentBundle);
|
|
||||||
|
|
||||||
int color = savedInstanceState.getInt(BUNDLE_KEY_COLOR_NEW);
|
|
||||||
|
|
||||||
// Sets colorOld, colorNew to color and initializes hue, sat, val from color
|
|
||||||
initColor(color);
|
|
||||||
|
|
||||||
// Now restore the real colorOld value
|
|
||||||
colorOld = savedInstanceState.getInt(BUNDLE_KEY_COLOR_OLD);
|
|
||||||
|
|
||||||
updateView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
protected void placeArrow() {
|
|
||||||
float y = sizeUiPx - (hue * sizeUiPx / 360.f);
|
|
||||||
if (y == sizeUiPx) y = 0.f;
|
|
||||||
|
|
||||||
AbsoluteLayout.LayoutParams layoutParams = (AbsoluteLayout.LayoutParams) arrow.getLayoutParams();
|
|
||||||
layoutParams.y = (int)(y + 4);
|
|
||||||
arrow.setLayoutParams(layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
protected void placeSpyglass() {
|
|
||||||
float x = sat * sizeUiPx;
|
|
||||||
float y = (1.f - val) * sizeUiPx;
|
|
||||||
|
|
||||||
AbsoluteLayout.LayoutParams layoutParams = (AbsoluteLayout.LayoutParams) viewSpyglass.getLayoutParams();
|
|
||||||
layoutParams.x = (int)(x + 3);
|
|
||||||
layoutParams.y = (int)(y + 3);
|
|
||||||
viewSpyglass.setLayoutParams(layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
float[] tmp01 = new float[3];
|
|
||||||
private int calculateColor() {
|
|
||||||
tmp01[0] = hue;
|
|
||||||
tmp01[1] = sat;
|
|
||||||
tmp01[2] = val;
|
|
||||||
return Color.HSVToColor(tmp01);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user