Showing preview only (251K chars total). Download the full file or copy to clipboard to get everything.
Repository: nicholasrout/lens-launcher
Branch: master
Commit: dd9bd11905ff
Files: 87
Total size: 226.9 KB
Directory structure:
gitextract_6p3thwce/
├── .gitignore
├── LICENSE.md
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── build.gradle.orig
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── nickrout/
│ │ └── lenslauncher/
│ │ └── ApplicationTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── AndroidManifest.xml.orig
│ │ ├── java/
│ │ │ └── nickrout/
│ │ │ └── lenslauncher/
│ │ │ ├── AppsSingleton.java
│ │ │ ├── LensLauncherApplication.java
│ │ │ ├── adapter/
│ │ │ │ └── AppRecyclerAdapter.java
│ │ │ ├── background/
│ │ │ │ ├── BackgroundChangedObservable.java
│ │ │ │ ├── BroadcastReceivers.java
│ │ │ │ ├── EditedObservable.java
│ │ │ │ ├── LoadedObservable.java
│ │ │ │ ├── NightModeObservable.java
│ │ │ │ ├── SortAppsTask.java
│ │ │ │ ├── UpdateAppsTask.java
│ │ │ │ ├── UpdatedObservable.java
│ │ │ │ └── VisibilityChangedObservable.java
│ │ │ ├── model/
│ │ │ │ ├── App.java
│ │ │ │ ├── AppPersistent.java
│ │ │ │ └── Grid.java
│ │ │ ├── ui/
│ │ │ │ ├── AboutActivity.java
│ │ │ │ ├── AppsFragment.java
│ │ │ │ ├── BaseActivity.java
│ │ │ │ ├── FakeLauncherActivity.java
│ │ │ │ ├── HomeActivity.java
│ │ │ │ ├── LensFragment.java
│ │ │ │ ├── LensView.java
│ │ │ │ ├── SettingsActivity.java
│ │ │ │ └── SettingsFragment.java
│ │ │ └── util/
│ │ │ ├── AppSorter.java
│ │ │ ├── AppUtil.java
│ │ │ ├── BitmapUtil.java
│ │ │ ├── ColorUtil.java
│ │ │ ├── IconPackManager.java
│ │ │ ├── LauncherUtil.java
│ │ │ ├── LensCalculator.java
│ │ │ ├── NightModeUtil.java
│ │ │ └── Settings.java
│ │ └── res/
│ │ ├── anim/
│ │ │ ├── fade_in.xml
│ │ │ ├── fade_out.xml
│ │ │ ├── slide_in_left.xml
│ │ │ ├── slide_in_right.xml
│ │ │ ├── slide_out_left.xml
│ │ │ └── slide_out_right.xml
│ │ ├── animator/
│ │ │ └── raise.xml
│ │ ├── drawable/
│ │ │ ├── ic_launcher_background.xml
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── layout/
│ │ │ ├── activity_about.xml
│ │ │ ├── activity_fake_launcher.xml
│ │ │ ├── activity_home.xml
│ │ │ ├── activity_settings.xml
│ │ │ ├── fragment_apps.xml
│ │ │ ├── fragment_lens.xml
│ │ │ ├── fragment_settings.xml
│ │ │ ├── layout_pro.xml
│ │ │ └── recycler_item_app.xml
│ │ ├── menu/
│ │ │ ├── menu_app.xml
│ │ │ └── menu_settings.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ └── ic_launcher.xml
│ │ ├── values/
│ │ │ ├── arrays.xml
│ │ │ ├── colors.xml
│ │ │ ├── dimen.xml
│ │ │ ├── integers.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-land/
│ │ │ └── dimen.xml
│ │ ├── values-night/
│ │ │ ├── colors.xml
│ │ │ └── styles.xml
│ │ ├── values-w640dp/
│ │ │ └── integers.xml
│ │ ├── values-w820dp/
│ │ │ └── dimen.xml
│ │ └── xml/
│ │ └── shortcuts.xml
│ └── test/
│ └── java/
│ └── nickrout/
│ └── lenslauncher/
│ └── ExampleUnitTest.java
├── build.gradle
├── docker-compose.yml
├── docker-entrypoint.sh
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── resources/
│ └── art/
│ └── lens_launcher.sketch
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
out/
# Local configuration file (sdk path, etc)
local.properties
# Eclipse project files
.classpath
.project
# Android Studio
.idea/
.gradle
build/
/*/local.properties
local.properties
/*/out
/*/*/build
/*/*/production
*.iml
*.iws
*.ipr
*~
*.swp
proguard/
*.log
.navigation/
captures/
# Keystore files
*.jks
# Android SDK
/android-sdk.zip
/android-studio
================================================
FILE: LICENSE.md
================================================
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 2017 Nicholas Rout
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.
================================================
FILE: README.md
================================================
# Lens Launcher
Lens Launcher is a unique, efficient way to browse and launch your apps.

Instead of scrolling long lists or swiping through multiple pages, Lens Launcher implements two unique features:
<b>• An Equispaced Grid that displays all of your apps, regardless of screen size or app count.</b>
<b>• A Graphical Fisheye Lens to quickly zoom, pan and launch apps using touch gestures.</b>
Lens Launcher also includes a full Settings menu to tweak all aspects of the Lens; Distortion, Scaling, Icon Size, Haptic Feedback, etc.
The Graphical Fisheye Lens algorithm is derived from methods proposed by Manojit Sarkar and Marc H. Brown. Their original 1993 paper, titled <i>Graphical Fisheye Views</i>, can be found here:
https://drive.google.com/open?id=0B6Nqy9y098RLa2pqNVFUcUhIZXM
Major contributions to Lens Launcher have been made by Rish Bhardwaj (@CreaRo)
You can download Lens Launcher on Google Play:
https://play.google.com/store/apps/details?id=nickrout.lenslauncher
## Build from Source
If you'd like to build from source, you may do so easily with [Docker][1], but
if you are wanting to contribute it may be better to install the build tools on
your machine.
### Easy Way
Building the APK is extremely easy using [`docker-compose`][2], all that is
needed is to run the following inside the repo's directory:
```bash
docker-compose run --rm gradle
```
Then download the APK inside
`lens-launcher/app/build/outputs/apk/app-release.apk` to your phone to install.
### For Development
1. Install the latest Android SDK from [Android Studio][3] and accept the
licenses.
2. Install Java JDK 8 from [Oracle][4].
3. Run `keytool` and create a keystore following the command prompts.
4. Generate an APK with `gradlew` like below:
```bash
gradlew assembleRelease \
-Pandroid.injected.signing.key.alias=$KEY_ALIAS \
-Pandroid.injected.signing.store.file=$KEY_STORE_PATH \
-Pandroid.injected.signing.store.password=$KEY_STORE_PASSWORD \
-Pandroid.injected.signing.key.password=$KEY_PASSWORD;
```
[1]: https://docs.docker.com/
[2]: https://docs.docker.com/compose/install/
[3]: https://developer.android.com/studio/index.html
[4]: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
android {
namespace "nickrout.lenslauncher"
compileSdk 34
defaultConfig {
applicationId "nickrout.lenslauncher"
minSdkVersion 15
targetSdkVersion 34
versionCode 46
versionName "3.0.1"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.13.2'
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.1.0'
implementation 'com.android.support:cardview-v7:26.1.0'
implementation 'com.android.support:palette-v7:26.1.0'
implementation 'com.github.satyan:sugar:1.5'
implementation 'com.afollestad.material-dialogs:core:0.9.5.0'
implementation 'com.afollestad.material-dialogs:commons:0.9.5.0'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}
tasks.withType(JavaCompile).configureEach{
options.fork = true
options.forkOptions.jvmArgs +=[
'--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',
'--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',
'--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED']
}
================================================
FILE: app/build.gradle.orig
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "nickrout.lenslauncher"
minSdkVersion 16
targetSdkVersion 23
versionCode 16
versionName "1.3.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
<<<<<<< HEAD
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:recyclerview-v7:23.3.0'
compile 'com.android.support:cardview-v7:23.3.0'
=======
compile 'com.android.support:palette-v7:23.4.0'
>>>>>>> 85209e8a5dc31e126a1f49a543f70d299720c052
compile 'com.github.satyan:sugar:1.5'
compile 'com.afollestad.material-dialogs:core:0.8.5.8'
compile 'com.afollestad.material-dialogs:commons:0.8.5.8'
compile 'com.makeramen:dragsortadapter:1.3.0'
compile 'com.jakewharton:butterknife:7.0.1'
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/nicholasrout/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: app/src/androidTest/java/nickrout/lenslauncher/ApplicationTest.java
================================================
package nickrout.lenslauncher;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="nickrout.lenslauncher">
<uses-permission android:name="QUERY_ALL_PACKAGES" />
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
</intent>
</queries>
<application
android:name=".LensLauncherApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@style/AppTheme"
android:supportsRtl="true">
<meta-data
android:name="DATABASE"
android:value="app_persistent.db" />
<meta-data
android:name="VERSION"
android:value="7" />
<meta-data
android:name="QUERY_LOG"
android:value="false" />
<meta-data
android:name="DOMAIN_PACKAGE_NAME"
android:value="nickrout.lenslauncher.model" />
<activity
android:name=".ui.HomeActivity"
android:launchMode="singleTask"
android:stateNotNeeded="true"
android:taskAffinity=""
android:theme="@style/HomeTheme"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".ui.SettingsActivity"
android:launchMode="singleTask"
android:stateNotNeeded="true"
android:taskAffinity=""
android:theme="@style/AppTheme.NoActionBar"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
<activity
android:name=".ui.AboutActivity"
android:label="@string/activity_title_about"
android:theme="@style/AppTheme.NoActionBar">
</activity>
<activity
android:name=".ui.FakeLauncherActivity"
android:enabled="false"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<receiver
android:name=".background.BroadcastReceivers$AppsUpdatedReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_CHANGED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver android:name=".background.BroadcastReceivers$AppsEditedReceiver">
</receiver>
<receiver android:name=".background.BroadcastReceivers$AppsVisibilityChangedReceiver">
</receiver>
<receiver android:name=".background.BroadcastReceivers$AppsLoadedReceiver">
</receiver>
<receiver android:name=".background.BroadcastReceivers$BackgroundChangedReceiver">
</receiver>
<receiver android:name=".background.BroadcastReceivers$NightModeReceiver">
</receiver>
</application>
</manifest>
================================================
FILE: app/src/main/AndroidManifest.xml.orig
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="nickrout.lenslauncher">
<application
android:name="com.orm.SugarApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="DATABASE"
android:value="app_persistent.db" />
<meta-data
android:name="VERSION"
<<<<<<< HEAD
android:value="2" />
=======
android:value="3" />
>>>>>>> 0c9969d213bbd5efac04492932bd13b6d97bacc0
<meta-data
android:name="QUERY_LOG"
android:value="false" />
<meta-data
android:name="DOMAIN_PACKAGE_NAME"
android:value="nickrout.lenslauncher.model" />
<activity
android:name=".ui.HomeActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:stateNotNeeded="true"
android:theme="@style/HomeTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<receiver android:name=".ui.HomeActivity$AppsUpdatedReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_CHANGED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<activity
android:name=".ui.SettingsActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.AboutActivity"
android:label="@string/activity_title_about"
android:screenOrientation="portrait">
</activity>
</application>
</manifest>
================================================
FILE: app/src/main/java/nickrout/lenslauncher/AppsSingleton.java
================================================
package nickrout.lenslauncher;
import android.graphics.Bitmap;
import java.util.ArrayList;
import nickrout.lenslauncher.model.App;
/**
* Created by nicholasrout on 2016/05/30.
*/
public class AppsSingleton {
private static AppsSingleton mAppsSingleton;
private ArrayList<App> mApps;
private ArrayList<Bitmap> mAppIcons;
private AppsSingleton() {}
public static AppsSingleton getInstance() {
if (mAppsSingleton == null) {
mAppsSingleton = new AppsSingleton();
}
return mAppsSingleton;
}
public ArrayList<App> getApps() {
ArrayList<App> apps = new ArrayList<>();
if (mApps == null) {
return apps;
}
apps.addAll(mApps);
return apps;
}
public void setApps(ArrayList<App> apps) {
mApps = apps;
}
public ArrayList<Bitmap> getAppIcons() {
ArrayList<Bitmap> appIcons = new ArrayList<>();
if (mAppIcons == null) {
return appIcons;
}
appIcons.addAll(mAppIcons);
return appIcons;
}
public void setAppIcons(ArrayList<Bitmap> appIcons) {
mAppIcons = appIcons;
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/LensLauncherApplication.java
================================================
package nickrout.lenslauncher;
import com.orm.SugarApp;
import java.util.Observable;
import java.util.Observer;
import nickrout.lenslauncher.background.SortAppsTask;
import nickrout.lenslauncher.background.EditedObservable;
import nickrout.lenslauncher.background.UpdatedObservable;
import nickrout.lenslauncher.background.UpdateAppsTask;
/**
* Created by nicholasrout on 2016/06/12.
*/
public class LensLauncherApplication extends SugarApp implements Observer {
@Override
public void onCreate() {
super.onCreate();
UpdatedObservable.getInstance().addObserver(this);
EditedObservable.getInstance().addObserver(this);
updateApps();
}
@Override
public void update(Observable observable, Object data) {
if (observable instanceof UpdatedObservable) {
updateApps();
} else if (observable instanceof EditedObservable) {
editApps();
}
}
private void updateApps() {
new UpdateAppsTask(
getPackageManager(),
getApplicationContext(),
this)
.execute();
}
private void editApps() {
new SortAppsTask(
getApplicationContext(),
this)
.execute();
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/adapter/AppRecyclerAdapter.java
================================================
package nickrout.lenslauncher.adapter;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.net.Uri;
import android.provider.Settings;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.CardView;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import nickrout.lenslauncher.R;
import nickrout.lenslauncher.background.BroadcastReceivers;
import nickrout.lenslauncher.model.App;
import nickrout.lenslauncher.model.AppPersistent;
import nickrout.lenslauncher.ui.SettingsActivity;
import nickrout.lenslauncher.util.AppUtil;
public class AppRecyclerAdapter extends RecyclerView.Adapter {
public static final String TAG = "AppRecyclerAdapter";
private Context mContext;
private final List<App> mApps;
public AppRecyclerAdapter(Context mContext, List<App> mApps) {
this.mContext = mContext;
this.mApps = mApps;
}
public App getItemForPosition(int position) {
return mApps.get(position);
}
@Override
public int getItemCount() {
return mApps.size();
}
@Override
public long getItemId(int position) {
return mApps.get(position).getId();
}
@Override
public AppViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.recycler_item_app, parent, false);
final AppViewHolder holder = new AppViewHolder(view, mContext);
holder.setOnClickListeners();
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
App app = getItemForPosition(position);
if (app == null) {
return;
}
AppViewHolder appViewHolder = (AppViewHolder) holder;
appViewHolder.setAppElement(app);
}
public static class AppViewHolder extends RecyclerView.ViewHolder implements PopupMenu.OnMenuItemClickListener {
@BindView(R.id.element_app_container)
CardView mContainer;
@BindView(R.id.element_app_label)
TextView mLabel;
@BindView(R.id.element_app_icon)
ImageView mIcon;
@BindView(R.id.element_app_hide)
ImageView mToggleAppVisibility;
@BindView(R.id.element_app_menu)
ImageView mMenu;
private App mApp;
private Context mContext;
public AppViewHolder(View itemView, Context context) {
super(itemView);
ButterKnife.bind(this, itemView);
this.mContext = context;
}
public void setAppElement(App app) {
this.mApp = app;
mLabel.setText(mApp.getLabel());
mIcon.setImageBitmap(mApp.getIcon());
boolean isAppVisible =
AppPersistent.getAppVisibility(mApp.getPackageName().toString(), mApp.getName().toString());
if (isAppVisible) {
mToggleAppVisibility.setImageResource(R.drawable.ic_visibility_grey_24dp);
} else {
mToggleAppVisibility.setImageResource(R.drawable.ic_visibility_off_grey_24dp);
}
if (mApp.getPackageName().toString().equals("nickrout.lenslauncher")) {
mToggleAppVisibility.setVisibility(View.INVISIBLE);
} else {
mToggleAppVisibility.setVisibility(View.VISIBLE);
}
}
public void toggleAppVisibility(App app) {
this.mApp = app;
boolean isAppVisible =
AppPersistent.getAppVisibility(mApp.getPackageName().toString(), mApp.getName().toString());
AppPersistent.setAppVisibility(
mApp.getPackageName().toString(),
mApp.getName().toString(),
!isAppVisible);
if (isAppVisible) {
Snackbar.make(mContainer, mApp.getLabel() + " is now hidden", Snackbar.LENGTH_LONG).show();
mToggleAppVisibility.setImageResource(R.drawable.ic_visibility_off_grey_24dp);
} else {
Snackbar.make(mContainer, mApp.getLabel() + " is now visible", Snackbar.LENGTH_LONG).show();
mToggleAppVisibility.setImageResource(R.drawable.ic_visibility_grey_24dp);
}
}
private void sendChangeAppsVisibilityBroadcast() {
if (mContext == null) {
return;
}
if (!(mContext instanceof SettingsActivity)) {
return;
}
SettingsActivity settingsActivity = (SettingsActivity) mContext;
Intent changeAppsVisibilityIntent = new Intent(settingsActivity, BroadcastReceivers.AppsVisibilityChangedReceiver.class);
settingsActivity.sendBroadcast(changeAppsVisibilityIntent);
}
public void setOnClickListeners() {
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AppUtil.launchComponent(
mContext,
mApp.getPackageName().toString(), mApp.getName().toString(),
itemView, new Rect(0, 0, itemView.getMeasuredWidth(), itemView.getMeasuredHeight()));
}
});
mToggleAppVisibility.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mApp != null) {
sendChangeAppsVisibilityBroadcast();
toggleAppVisibility(mApp);
} else {
Snackbar.make(mContainer, mContext.getString(R.string.error_app_not_found), Snackbar.LENGTH_LONG).show();
}
}
});
mMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PopupMenu popupMenu = new PopupMenu(mContext, view);
popupMenu.setOnMenuItemClickListener(AppViewHolder.this);
popupMenu.inflate(R.menu.menu_app);
popupMenu.show();
}
});
}
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_element_app_info:
try {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + mApp.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(mContext, R.string.error_app_not_found, Toast.LENGTH_SHORT).show();
}
return true;
case R.id.menu_item_element_uninstall:
try {
Intent intent = new Intent(Intent.ACTION_DELETE);
intent.setData(Uri.parse("package:" + mApp.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(mContext, R.string.error_app_not_found, Toast.LENGTH_SHORT).show();
}
return true;
}
return false;
}
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/background/BackgroundChangedObservable.java
================================================
package nickrout.lenslauncher.background;
import java.util.Observable;
public class BackgroundChangedObservable extends Observable {
private static BackgroundChangedObservable instance = new BackgroundChangedObservable();
public static BackgroundChangedObservable getInstance() {
return instance;
}
private BackgroundChangedObservable() {
}
public void updateValue(Object data) {
synchronized (this) {
setChanged();
notifyObservers(data);
}
}
public void update() {
updateValue(null);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/background/BroadcastReceivers.java
================================================
package nickrout.lenslauncher.background;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
/**
* Created by nicholasrout on 2016/06/12.
*/
public class BroadcastReceivers {
public static class AppsUpdatedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
UpdatedObservable.getInstance().update();
}
}
public static class AppsEditedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
EditedObservable.getInstance().update();
}
}
public static class AppsVisibilityChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
VisibilityChangedObservable.getInstance().update();
}
}
public static class AppsLoadedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
LoadedObservable.getInstance().update();
}
}
public static class BackgroundChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
BackgroundChangedObservable.getInstance().update();
}
}
public static class NightModeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
NightModeObservable.getInstance().update();
}
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/background/EditedObservable.java
================================================
package nickrout.lenslauncher.background;
import java.util.Observable;
/**
* Created by nicholasrout on 2016/06/23.
*/
public class EditedObservable extends Observable {
private static EditedObservable instance = new EditedObservable();
public static EditedObservable getInstance() {
return instance;
}
private EditedObservable() {
}
public void updateValue(Object data) {
synchronized (this) {
setChanged();
notifyObservers(data);
}
}
public void update() {
updateValue(null);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/background/LoadedObservable.java
================================================
package nickrout.lenslauncher.background;
import java.util.Observable;
/**
* Created by nicholasrout on 2016/06/12.
*/
public class LoadedObservable extends Observable {
private static LoadedObservable instance = new LoadedObservable();
public static LoadedObservable getInstance() {
return instance;
}
private LoadedObservable() {
}
public void updateValue(Object data) {
synchronized (this) {
setChanged();
notifyObservers(data);
}
}
public void update() {
updateValue(null);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/background/NightModeObservable.java
================================================
package nickrout.lenslauncher.background;
import java.util.Observable;
/**
* Created by nicholasrout on 2017/01/15.
*/
public class NightModeObservable extends Observable {
private static NightModeObservable instance = new NightModeObservable();
public static NightModeObservable getInstance() {
return instance;
}
private NightModeObservable() {
}
public void updateValue(Object data) {
synchronized (this) {
setChanged();
notifyObservers(data);
}
}
public void update() {
updateValue(null);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/background/SortAppsTask.java
================================================
package nickrout.lenslauncher.background;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import java.util.ArrayList;
import nickrout.lenslauncher.model.App;
import nickrout.lenslauncher.util.AppSorter;
import nickrout.lenslauncher.AppsSingleton;
import nickrout.lenslauncher.util.Settings;
/**
* Created by nicholasrout on 2016/06/23.
*/
public class SortAppsTask extends AsyncTask<Void, Void, Void> {
private Context mContext;
private Application mApplication;
private Settings mSettings;
private ArrayList<App> mApps;
private ArrayList<Bitmap> mAppIcons;
public SortAppsTask(Context context,
Application application) {
mContext = context;
mApplication = application;
mSettings = new Settings(mContext);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
ArrayList<App> apps = AppsSingleton.getInstance().getApps();
AppSorter.sort(apps, mSettings.getSortType());
mApps = new ArrayList<>();
mAppIcons = new ArrayList<>();
for (int i = 0; i < apps.size(); i++) {
App app = apps.get(i);
Bitmap appIcon = app.getIcon();
if (appIcon != null) {
mApps.add(app);
mAppIcons.add(appIcon);
}
}
return null;
}
@Override
protected void onPostExecute(Void result) {
AppsSingleton.getInstance().setApps(mApps);
AppsSingleton.getInstance().setAppIcons(mAppIcons);
Intent appsLoadedIntent = new Intent(mApplication, BroadcastReceivers.AppsLoadedReceiver.class);
mApplication.sendBroadcast(appsLoadedIntent);
super.onPostExecute(result);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/background/UpdateAppsTask.java
================================================
package nickrout.lenslauncher.background;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import java.util.ArrayList;
import nickrout.lenslauncher.model.App;
import nickrout.lenslauncher.util.AppUtil;
import nickrout.lenslauncher.AppsSingleton;
import nickrout.lenslauncher.util.Settings;
/**
* Created by rish on 26/5/16.
*/
public class UpdateAppsTask extends AsyncTask<Void, Void, Void> {
private PackageManager mPackageManager;
private Context mContext;
private Application mApplication;
private Settings mSettings;
private ArrayList<App> mApps;
private ArrayList<Bitmap> mAppIcons;
public UpdateAppsTask(PackageManager packageManager,
Context context,
Application application) {
this.mPackageManager = packageManager;
this.mContext = context;
this.mApplication = application;
this.mSettings = new Settings(context);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
ArrayList<App> apps = AppUtil.getApps(
mPackageManager,
mContext,
mApplication,
mSettings.getString(Settings.KEY_ICON_PACK_LABEL_NAME),
mSettings.getSortType());
mApps = new ArrayList<>();
mAppIcons = new ArrayList<>();
for (int i = 0; i < apps.size(); i++) {
App app = apps.get(i);
Bitmap appIcon = app.getIcon();
if (appIcon != null) {
mApps.add(app);
mAppIcons.add(appIcon);
}
}
return null;
}
@Override
protected void onPostExecute(Void result) {
AppsSingleton.getInstance().setApps(mApps);
AppsSingleton.getInstance().setAppIcons(mAppIcons);
Intent appsLoadedIntent = new Intent(mApplication, BroadcastReceivers.AppsLoadedReceiver.class);
mApplication.sendBroadcast(appsLoadedIntent);
super.onPostExecute(result);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/background/UpdatedObservable.java
================================================
package nickrout.lenslauncher.background;
import java.util.Observable;
/**
* Created by nickrout on 2016/04/08.
*/
public class UpdatedObservable extends Observable {
private static UpdatedObservable instance = new UpdatedObservable();
public static UpdatedObservable getInstance() {
return instance;
}
private UpdatedObservable() {
}
public void updateValue(Object data) {
synchronized (this) {
setChanged();
notifyObservers(data);
}
}
public void update() {
updateValue(null);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/background/VisibilityChangedObservable.java
================================================
package nickrout.lenslauncher.background;
import java.util.Observable;
public class VisibilityChangedObservable extends Observable {
private static VisibilityChangedObservable instance = new VisibilityChangedObservable();
public static VisibilityChangedObservable getInstance() {
return instance;
}
private VisibilityChangedObservable() {
}
public void updateValue(Object data) {
synchronized (this) {
setChanged();
notifyObservers(data);
}
}
public void update() {
updateValue(null);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/model/App.java
================================================
package nickrout.lenslauncher.model;
import android.graphics.Bitmap;
import android.support.annotation.ColorInt;
/**
* Created by nickrout on 2016/04/02.
*/
public class App {
private int mId;
private CharSequence mLabel;
private CharSequence mPackageName;
private CharSequence mName;
private int mIconResId;
private Bitmap mIcon;
private long mInstallDate;
private @ColorInt int mPaletteColor;
public App() {
}
public int getId() {
return mId;
}
public void setId(int mId) {
this.mId = mId;
}
public CharSequence getLabel() {
return mLabel;
}
public void setLabel(CharSequence label) {
mLabel = label;
}
public CharSequence getPackageName() {
return mPackageName;
}
public void setPackageName(CharSequence packageName) {
mPackageName = packageName;
}
public CharSequence getName() {
return mName;
}
public void setName(CharSequence name) {
mName = name;
}
public int getIconResId() {
return mIconResId;
}
public void setIconResId(int iconResId) {
mIconResId = iconResId;
}
public Bitmap getIcon() {
return mIcon;
}
public void setIcon(Bitmap icon) {
mIcon = icon;
}
public long getInstallDate() {
return mInstallDate;
}
public void setInstallDate(long mInstallDate) {
this.mInstallDate = mInstallDate;
}
public int getPaletteColor() {
return mPaletteColor;
}
public void setPaletteColor(int paletteColor) {
mPaletteColor = paletteColor;
}
@Override
public String toString() {
return "App{" +
"mId=" + mId +
", mLabel=" + mLabel +
", mPackageName=" + mPackageName +
", mName=" + mName +
", mIconResId=" + mIconResId +
", mIcon=" + mIcon +
", mInstallDate=" + mInstallDate +
", mPaletteColor=" + mPaletteColor +
'}';
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/model/AppPersistent.java
================================================
package nickrout.lenslauncher.model;
import com.orm.SugarRecord;
import com.orm.query.Condition;
import com.orm.query.Select;
import com.orm.util.NamingHelper;
/**
* Created by rish on 20/5/16.
*/
public class AppPersistent extends SugarRecord {
private static final String TAG = "AppPersistent";
/* Required Default Constructor */
public AppPersistent() {
}
private String mPackageName;
private String mName;
private String mIdentifier;
private long mOpenCount;
private int mOrderNumber;
private boolean mAppVisible;
private static boolean DEFAULT_APP_VISIBILITY = true;
private static int DEFAULT_ORDER_NUMBER = -1;
private static long DEFAULT_OPEN_COUNT = 1;
public AppPersistent(String packageName, String name, long openCount, int orderNumber, boolean appVisible) {
this.mPackageName = packageName;
this.mName = name;
this.mIdentifier = AppPersistent.generateIdentifier(packageName, name);
this.mOpenCount = openCount;
this.mOrderNumber = orderNumber;
this.mAppVisible = appVisible;
}
public String getPackageName() {
return mPackageName;
}
public void setPackageName(String packageName) {
this.mPackageName = packageName;
this.mIdentifier =
AppPersistent.generateIdentifier(this.mPackageName, this.mName);
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
this.mIdentifier =
AppPersistent.generateIdentifier(this.mPackageName, this.mName);
}
public String getIdentifier() {
return mIdentifier;
}
public long getOpenCount() {
return mOpenCount;
}
public void setOpenCount(long openCount) {
this.mOpenCount = openCount;
}
public int getOrderNumber() {
return mOrderNumber;
}
public void setOrderNumber(int orderNumber) {
this.mOrderNumber = orderNumber;
}
public boolean isAppVisible() {
return mAppVisible;
}
public void setAppVisible(boolean appVisible) {
this.mAppVisible = appVisible;
}
@Override
public String toString() {
return "AppPersistent{" +
"mPackageName='" + mPackageName + '\'' +
", mName='" + mName + '\'' +
", mIdentifier='" + mIdentifier + '\'' +
", mOpenCount=" + mOpenCount +
", mOrderNumber=" + mOrderNumber +
", mAppVisible=" + mAppVisible +
'}';
}
public static String generateIdentifier(String packageName, String name) {
return packageName + "-" + name;
}
public static void incrementAppCount(String packageName, String name) {
String identifier = AppPersistent.generateIdentifier(packageName, name);
AppPersistent appPersistent = Select.from(AppPersistent.class).where(Condition.prop(NamingHelper.toSQLNameDefault("mIdentifier")).eq(identifier)).first();
if (appPersistent != null) {
appPersistent.setOpenCount(appPersistent.getOpenCount() + 1);
appPersistent.save();
} else {
AppPersistent newAppPersistent = new AppPersistent(packageName, name, DEFAULT_OPEN_COUNT, DEFAULT_ORDER_NUMBER, DEFAULT_APP_VISIBILITY);
newAppPersistent.save();
}
}
public static void setAppOrderNumber(String packageName, String name, int orderNumber) {
String identifier = AppPersistent.generateIdentifier(packageName, name);
AppPersistent appPersistent = Select.from(AppPersistent.class).where(Condition.prop(NamingHelper.toSQLNameDefault("mIdentifier")).eq(identifier)).first();
if (appPersistent != null) {
appPersistent.setOrderNumber(orderNumber);
appPersistent.save();
} else {
AppPersistent newAppPersistent = new AppPersistent(packageName, name, DEFAULT_OPEN_COUNT, DEFAULT_ORDER_NUMBER, DEFAULT_APP_VISIBILITY);
newAppPersistent.save();
}
}
public static boolean getAppVisibility(String packageName, String name) {
String identifier = AppPersistent.generateIdentifier(packageName, name);
AppPersistent appPersistent = Select.from(AppPersistent.class).where(Condition.prop(NamingHelper.toSQLNameDefault("mIdentifier")).eq(identifier)).first();
if (appPersistent != null) {
return appPersistent.isAppVisible();
} else {
return true;
}
}
public static void setAppVisibility(String packageName, String name, boolean mHideApp) {
String identifier = AppPersistent.generateIdentifier(packageName, name);
AppPersistent appPersistent = Select.from(AppPersistent.class).where(Condition.prop(NamingHelper.toSQLNameDefault("mIdentifier")).eq(identifier)).first();
if (appPersistent != null) {
appPersistent.setAppVisible(mHideApp);
appPersistent.save();
} else {
AppPersistent newAppPersistent = new AppPersistent(packageName, name, DEFAULT_OPEN_COUNT, DEFAULT_ORDER_NUMBER, mHideApp);
newAppPersistent.save();
}
}
public static long getAppOpenCount(String packageName, String name) {
String identifier = AppPersistent.generateIdentifier(packageName, name);
AppPersistent appPersistent = Select.from(AppPersistent.class).where(Condition.prop(NamingHelper.toSQLNameDefault("mIdentifier")).eq(identifier)).first();
if (appPersistent != null) {
return appPersistent.getOpenCount();
} else {
return 0;
}
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/model/Grid.java
================================================
package nickrout.lenslauncher.model;
/**
* Created by nickrout on 2016/04/02.
*/
public class Grid {
private int mItemCount;
private int mItemCountHorizontal;
private int mItemCountVertical;
private float mItemSize;
private float mSpacingHorizontal;
private float mSpacingVertical;
public Grid() {}
public int getItemCount() {
return mItemCount;
}
public void setItemCount(int itemCount) {
mItemCount = itemCount;
}
public int getItemCountHorizontal() {
return mItemCountHorizontal;
}
public void setItemCountHorizontal(int itemCountHorizontal) {
mItemCountHorizontal = itemCountHorizontal;
}
public int getItemCountVertical() {
return mItemCountVertical;
}
public void setItemCountVertical(int itemCountVertical) {
mItemCountVertical = itemCountVertical;
}
public float getItemSize() {
return mItemSize;
}
public void setItemSize(float itemSize) {
mItemSize = itemSize;
}
public float getSpacingHorizontal() {
return mSpacingHorizontal;
}
public void setSpacingHorizontal(float spacingHorizontal) {
mSpacingHorizontal = spacingHorizontal;
}
public float getSpacingVertical() {
return mSpacingVertical;
}
public void setSpacingVertical(float spacingVertical) {
mSpacingVertical = spacingVertical;
}
@Override
public String toString() {
return "Grid{" +
"mItemCount=" + mItemCount +
", mItemCountHorizontal=" + mItemCountHorizontal +
", mItemCountVertical=" + mItemCountVertical +
", mItemSize=" + mItemSize +
", mSpacingHorizontal=" + mSpacingHorizontal +
", mSpacingVertical=" + mSpacingVertical +
'}';
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/ui/AboutActivity.java
================================================
package nickrout.lenslauncher.ui;
import android.animation.Animator;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Observable;
import java.util.Observer;
import butterknife.BindView;
import butterknife.ButterKnife;
import nickrout.lenslauncher.R;
import nickrout.lenslauncher.background.NightModeObservable;
/**
* Created by nickrout on 2016/04/06.
*/
public class AboutActivity extends BaseActivity implements Observer {
private static final String TAG = "AboutActivity";
@BindView(R.id.text_view_about)
TextView mTextViewAbout;
@BindView(R.id.backdrop)
ImageView mImageAbout;
@BindView(R.id.collapsing_toolbar)
CollapsingToolbarLayout mCollapsingToolbar;
@BindView(R.id.toolbar)
Toolbar mToolbar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
ButterKnife.bind(this);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mCollapsingToolbar.setExpandedTitleColor(ContextCompat.getColor(this, R.color.colorTransparent));
setupViews();
mImageAbout.postDelayed(new Runnable() {
@Override
public void run() {
circularRevealAboutImage();
}
}, 150);
NightModeObservable.getInstance().addObserver(this);
}
private void circularRevealAboutImage() {
if (mImageAbout != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int cx = mImageAbout.getWidth() / 2;
int cy = mImageAbout.getHeight() / 2;
float finalRadius = (float) Math.hypot(cx, cy);
Animator anim =
ViewAnimationUtils.createCircularReveal(mImageAbout, cx, cy, 0, finalRadius);
mImageAbout.setVisibility(View.VISIBLE);
anim.start();
} else {
mImageAbout.setVisibility(View.VISIBLE);
}
}
}
private void setupViews() {
mTextViewAbout.setText(Html.fromHtml(getString(R.string.about)));
mTextViewAbout.setMovementMethod(LinkMovementMethod.getInstance());
}
@Override
public void onBackPressed() {
finish();
}
@Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void update(Observable observable, Object o) {
if (observable instanceof NightModeObservable) {
updateNightMode();
}
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/ui/AppsFragment.java
================================================
package nickrout.lenslauncher.ui;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import nickrout.lenslauncher.R;
import nickrout.lenslauncher.adapter.AppRecyclerAdapter;
import nickrout.lenslauncher.model.App;
import nickrout.lenslauncher.util.AppSorter;
import nickrout.lenslauncher.AppsSingleton;
import nickrout.lenslauncher.background.BroadcastReceivers;
import nickrout.lenslauncher.util.Settings;
/**
* Created by nicholasrout on 2016/06/08.
*/
public class AppsFragment extends Fragment implements SettingsActivity.AppsInterface {
private static final String TAG = "AppsFragment";
@BindView(R.id.recycler_apps)
RecyclerView mRecycler;
@BindView(R.id.progress_apps)
MaterialProgressBar mProgress;
private Settings mSettings;
private AppRecyclerAdapter mAppRecyclerAdapter;
private int mScrolledItemIndex;
public AppsFragment() {
}
public static AppsFragment newInstance() {
AppsFragment appsFragment = new AppsFragment();
// Include potential bundle extras here
return appsFragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_apps, container, false);
ButterKnife.bind(this, view);
mSettings = new Settings(getActivity());
setupRecycler(AppsSingleton.getInstance().getApps());
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (getActivity() != null && getActivity() instanceof SettingsActivity) {
((SettingsActivity) getActivity()).setAppsInterface(this);
}
}
private void sendEditAppsBroadcast() {
if (getActivity() == null) {
return;
}
Intent editAppsIntent = new Intent(getActivity(), BroadcastReceivers.AppsEditedReceiver.class);
getActivity().sendBroadcast(editAppsIntent);
}
private void setupRecycler(ArrayList<App> apps) {
if (getActivity() == null || apps.size() == 0) {
return;
}
if (mRecycler.getLayoutManager() != null) {
mScrolledItemIndex = ((LinearLayoutManager) mRecycler.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
}
mProgress.setVisibility(View.INVISIBLE);
mRecycler.setVisibility(View.VISIBLE);
mAppRecyclerAdapter = new AppRecyclerAdapter(getActivity(), apps);
mRecycler.setAdapter(mAppRecyclerAdapter);
mRecycler.setLayoutManager(new GridLayoutManager(getActivity(), getResources().getInteger(R.integer.columns_apps)));
mRecycler.setItemAnimator(new DefaultItemAnimator());
mRecycler.scrollToPosition(mScrolledItemIndex);
mScrolledItemIndex = 0;
}
@Override
public void onDefaultsReset() {
if (mSettings.getSortType() != AppSorter.SortType.values()[Settings.DEFAULT_SORT_TYPE]) {
mSettings.save(Settings.KEY_SORT_TYPE, Settings.DEFAULT_SORT_TYPE);
sendEditAppsBroadcast();
}
}
@Override
public void onAppsUpdated(ArrayList<App> apps) {
setupRecycler(apps);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/ui/BaseActivity.java
================================================
package nickrout.lenslauncher.ui;
import android.app.ActivityManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import nickrout.lenslauncher.R;
import nickrout.lenslauncher.util.Settings;
/**
* Created by nickrout on 2016/04/05.
*/
public class BaseActivity extends AppCompatActivity {
protected Settings mSettings;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mSettings = new Settings(this);
if (savedInstanceState == null) {
updateNightMode();
}
super.onCreate(savedInstanceState);
}
@Override
public void setContentView(@LayoutRes int layoutResID) {
super.setContentView(layoutResID);
setTaskDescription();
}
private void setTaskDescription() {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Bitmap appIconBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
ActivityManager.TaskDescription taskDescription = new ActivityManager.TaskDescription(
getString(R.string.app_name),
appIconBitmap,
ContextCompat.getColor(getBaseContext(), R.color.colorPrimaryDark));
setTaskDescription(taskDescription);
}
}
protected void updateNightMode() {
if (mSettings == null) {
mSettings = new Settings(this);
}
getDelegate().setLocalNightMode(mSettings.getNightMode());
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/ui/FakeLauncherActivity.java
================================================
package nickrout.lenslauncher.ui;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import nickrout.lenslauncher.R;
public class FakeLauncherActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fake_launcher);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/ui/HomeActivity.java
================================================
package nickrout.lenslauncher.ui;
import android.annotation.TargetApi;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;
import butterknife.BindView;
import butterknife.ButterKnife;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import nickrout.lenslauncher.R;
import nickrout.lenslauncher.background.BackgroundChangedObservable;
import nickrout.lenslauncher.background.NightModeObservable;
import nickrout.lenslauncher.background.VisibilityChangedObservable;
import nickrout.lenslauncher.model.App;
import nickrout.lenslauncher.model.AppPersistent;
import nickrout.lenslauncher.AppsSingleton;
import nickrout.lenslauncher.background.LoadedObservable;
/**
* Created by nickrout on 2016/04/02.
*/
public class HomeActivity extends BaseActivity implements Observer {
private final static String TAG = "HomeActivity";
@BindView(R.id.lens_view_apps)
LensView mLensView;
@BindView(R.id.progress_home)
MaterialProgressBar mProgress;
private PackageManager mPackageManager;
private ArrayList<App> mApps;
private ArrayList<Bitmap> mAppIcons;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
ButterKnife.bind(this);
mPackageManager = getPackageManager();
mLensView.setPackageManager(mPackageManager);
mLensView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
assignApps(AppsSingleton.getInstance().getApps(), AppsSingleton.getInstance().getAppIcons());
LoadedObservable.getInstance().addObserver(this);
VisibilityChangedObservable.getInstance().addObserver(this);
BackgroundChangedObservable.getInstance().addObserver(this);
NightModeObservable.getInstance().addObserver(this);
}
@Override
protected void onResume() {
super.onResume();
setupTransparentSystemBarsForLollipop();
}
/**
* Sets up transparent navigation and status bars in Lollipop.
* This method is a no-op for other platform versions.
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void setupTransparentSystemBarsForLollipop() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.getAttributes().systemUiVisibility |=
(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
}
}
private void setBackground() {
mLensView.invalidate();
}
private void assignApps(ArrayList<App> apps, ArrayList<Bitmap> appIcons) {
if (apps.size() == 0 || appIcons.size() == 0) {
return;
}
mProgress.setVisibility(View.INVISIBLE);
mLensView.setVisibility(View.VISIBLE);
mApps = apps;
mAppIcons = appIcons;
removeHiddenApps();
mLensView.setApps(mApps, mAppIcons);
}
private void removeHiddenApps() {
for (int i = 0; i < mApps.size(); i++) {
if (!AppPersistent.getAppVisibility(
mApps.get(i).getPackageName().toString(), mApps.get(i).getName().toString())) {
mApps.remove(i);
mAppIcons.remove(i);
i--;
}
}
}
@Override
public void onBackPressed() {
// Do Nothing
}
@Override
protected void onDestroy() {
LoadedObservable.getInstance().deleteObserver(this);
super.onDestroy();
}
@Override
public void update(Observable observable, Object data) {
if (observable instanceof LoadedObservable || observable instanceof VisibilityChangedObservable) {
assignApps(AppsSingleton.getInstance().getApps(), AppsSingleton.getInstance().getAppIcons());
} else if (observable instanceof BackgroundChangedObservable) {
setBackground();
} else if (observable instanceof NightModeObservable) {
updateNightMode();
}
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/ui/LensFragment.java
================================================
package nickrout.lenslauncher.ui;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.AppCompatSeekBar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import nickrout.lenslauncher.R;
import nickrout.lenslauncher.util.Settings;
/**
* Created by nicholasrout on 2016/06/08.
*/
public class LensFragment extends Fragment implements SettingsActivity.LensInterface {
private static final String TAG = "LensFragment";
@BindView(R.id.lens_view_settings)
LensView mLensView;
@BindView(R.id.seek_bar_min_icon_size)
AppCompatSeekBar mMinIconSize;
@BindView(R.id.value_min_icon_size)
TextView mValueMinIconSize;
@BindView(R.id.seek_bar_distortion_factor)
AppCompatSeekBar mDistortionFactor;
@BindView(R.id.value_distortion_factor)
TextView mValueDistortionFactor;
@BindView(R.id.seek_bar_scale_factor)
AppCompatSeekBar mScaleFactor;
@BindView(R.id.value_scale_factor)
TextView mValueScaleFactor;
@BindView(R.id.seek_bar_animation_time)
AppCompatSeekBar mAnimationTime;
@BindView(R.id.value_animation_time)
TextView mValueAnimationTime;
private Settings mSettings;
public LensFragment() {
}
public static LensFragment newInstance() {
LensFragment lensFragment = new LensFragment();
// Include potential bundle extras here
return lensFragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_lens, container, false);
ButterKnife.bind(this, view);
mSettings = new Settings(getActivity());
setupViews();
assignValues();
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (getActivity() != null && getActivity() instanceof SettingsActivity) {
((SettingsActivity) getActivity()).setLensInterface(this);
}
}
private void setupViews() {
mLensView.setDrawType(LensView.DrawType.CIRCLES);
mMinIconSize.setMax(Settings.MAX_ICON_SIZE);
mMinIconSize.setOnSeekBarChangeListener(new AppCompatSeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int appropriateProgress = progress + (int) Settings.MIN_ICON_SIZE;
String minIconSize = appropriateProgress + "dp";
mValueMinIconSize.setText(minIconSize);
mSettings.save(Settings.KEY_ICON_SIZE, (float) appropriateProgress);
mLensView.invalidate();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mDistortionFactor.setMax(Settings.MAX_DISTORTION_FACTOR);
mDistortionFactor.setOnSeekBarChangeListener(new AppCompatSeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float appropriateProgress = (float) progress / 2.0f + Settings.MIN_DISTORTION_FACTOR;
String distortionFactor = appropriateProgress + "";
mValueDistortionFactor.setText(distortionFactor);
mSettings.save(Settings.KEY_DISTORTION_FACTOR, appropriateProgress);
mLensView.invalidate();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mScaleFactor.setMax(Settings.MAX_SCALE_FACTOR);
mScaleFactor.setOnSeekBarChangeListener(new AppCompatSeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float appropriateProgress = (float) progress / 5.0f + Settings.MIN_SCALE_FACTOR;
String scaleFactor = appropriateProgress + "";
mValueScaleFactor.setText(scaleFactor);
mSettings.save(Settings.KEY_SCALE_FACTOR, appropriateProgress);
mLensView.invalidate();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mAnimationTime.setMax(Settings.MAX_ANIMATION_TIME);
mAnimationTime.setOnSeekBarChangeListener(new AppCompatSeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
long appropriateProgress = (long) progress / 2 + Settings.MIN_ANIMATION_TIME;
String animationTime = appropriateProgress + "ms";
mValueAnimationTime.setText(animationTime);
mSettings.save(Settings.KEY_ANIMATION_TIME, appropriateProgress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
private void assignValues() {
mMinIconSize.setProgress((int) mSettings.getFloat(Settings.KEY_ICON_SIZE) - (int) Settings.MIN_ICON_SIZE);
String minIconSize = (int) mSettings.getFloat(Settings.KEY_ICON_SIZE) + "dp";
mValueMinIconSize.setText(minIconSize);
mDistortionFactor.setProgress((int) (2.0f * (mSettings.getFloat(Settings.KEY_DISTORTION_FACTOR) - Settings.MIN_DISTORTION_FACTOR)));
String distortionFactor = mSettings.getFloat(Settings.KEY_DISTORTION_FACTOR) + "";
mValueDistortionFactor.setText(distortionFactor);
mScaleFactor.setProgress((int) (5.0f * (mSettings.getFloat(Settings.KEY_SCALE_FACTOR) - Settings.MIN_SCALE_FACTOR)));
String scaleFactor = mSettings.getFloat(Settings.KEY_SCALE_FACTOR) + "";
mValueScaleFactor.setText(scaleFactor);
mAnimationTime.setProgress((int) (2 * (mSettings.getLong(Settings.KEY_ANIMATION_TIME) - Settings.MIN_ANIMATION_TIME)));
String animationTime = mSettings.getLong(Settings.KEY_ANIMATION_TIME) + "ms";
mValueAnimationTime.setText(animationTime);
}
@Override
public void onDefaultsReset() {
resetToDefault();
assignValues();
}
private void resetToDefault() {
mSettings.save(Settings.KEY_ICON_SIZE, Settings.DEFAULT_ICON_SIZE);
mSettings.save(Settings.KEY_DISTORTION_FACTOR, Settings.DEFAULT_DISTORTION_FACTOR);
mSettings.save(Settings.KEY_SCALE_FACTOR, Settings.DEFAULT_SCALE_FACTOR);
mSettings.save(Settings.KEY_ANIMATION_TIME, Settings.DEFAULT_ANIMATION_TIME);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/ui/LensView.java
================================================
package nickrout.lenslauncher.ui;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.NinePatchDrawable;
import android.os.Build;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import java.util.ArrayList;
import nickrout.lenslauncher.R;
import nickrout.lenslauncher.model.App;
import nickrout.lenslauncher.model.AppPersistent;
import nickrout.lenslauncher.model.Grid;
import nickrout.lenslauncher.util.AppUtil;
import nickrout.lenslauncher.util.LensCalculator;
import nickrout.lenslauncher.util.Settings;
/**
* Created by nickrout on 2016/04/02.
*/
public class LensView extends View {
private static final String TAG = "LensView";
private Paint mPaintIcons;
private Paint mPaintCircles;
private Paint mPaintTouchSelection;
private Paint mPaintText;
private Paint mPaintNewAppTag;
private float mTouchX = -Float.MAX_VALUE;
private float mTouchY = -Float.MAX_VALUE;
private boolean mInsideRect = false;
private RectF mRectToSelect = new RectF(0, 0, 0, 0);
private boolean mMustVibrate = true;
private int mSelectIndex;
private ArrayList<App> mApps;
private ArrayList<Bitmap> mAppIcons;
private PackageManager mPackageManager;
private float mAnimationMultiplier = 0.0f;
private boolean mAnimationHiding = false;
private int mNumberOfCircles;
private float mTouchSlop;
private boolean mMoving;
private Settings mSettings;
private NinePatchDrawable mWorkspaceBackgroundDrawable;
private Rect mInsets = new Rect(0, 0, 0, 0);
public enum DrawType {
APPS,
CIRCLES
}
private DrawType mDrawType;
public void setDrawType(DrawType drawType) {
mDrawType = drawType;
invalidate();
}
public LensView(Context context) {
super(context);
init();
}
public LensView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public LensView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public void setApps(ArrayList<App> apps, ArrayList<Bitmap> appIcons) {
mApps = apps;
mAppIcons = appIcons;
invalidate();
}
public void setPackageManager(PackageManager packageManager) {
mPackageManager = packageManager;
}
private void init() {
mApps = new ArrayList<>();
mAppIcons = new ArrayList<>();
mDrawType = DrawType.APPS;
setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorTransparent));
mSettings = new Settings(getContext());
setupPaints();
mWorkspaceBackgroundDrawable = (NinePatchDrawable) ContextCompat.getDrawable(getContext(), R.drawable.workspace_bg);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
@Override
protected boolean fitSystemWindows(Rect insets) {
mInsets = insets;
return true;
}
private void setupPaints() {
mPaintIcons = new Paint();
mPaintIcons.setAntiAlias(true);
mPaintIcons.setStyle(Paint.Style.FILL);
mPaintIcons.setFilterBitmap(true);
mPaintIcons.setDither(true);
mPaintCircles = new Paint();
mPaintCircles.setAntiAlias(true);
mPaintCircles.setStyle(Paint.Style.FILL);
mPaintCircles.setColor(ContextCompat.getColor(getContext(), R.color.colorCircles));
mPaintTouchSelection = new Paint();
mPaintTouchSelection.setAntiAlias(true);
mPaintTouchSelection.setStyle(Paint.Style.STROKE);
mPaintTouchSelection.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));
mPaintTouchSelection.setStrokeWidth(getResources().getDimension(R.dimen.stroke_width_touch_selection));
mPaintText = new Paint();
mPaintText.setAntiAlias(true);
mPaintText.setStyle(Paint.Style.FILL);
mPaintText.setColor(ContextCompat.getColor(getContext(), R.color.colorWhite));
mPaintText.setTextSize(getResources().getDimension(R.dimen.text_size_lens));
mPaintText.setTextAlign(Paint.Align.CENTER);
mPaintText.setTypeface(Typeface.createFromAsset(getContext().getAssets(),"fonts/RobotoCondensed-Regular.ttf"));
mPaintNewAppTag = new Paint();
mPaintNewAppTag.setAntiAlias(true);
mPaintNewAppTag.setStyle(Paint.Style.FILL);
mPaintNewAppTag.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));
mPaintNewAppTag.setDither(true);
mPaintNewAppTag.setShadowLayer(getResources().getDimension(R.dimen.shadow_text),
getResources().getDimension(R.dimen.shadow_text),
getResources().getDimension(R.dimen.shadow_text),
ContextCompat.getColor(getContext(), R.color.colorShadow));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mDrawType == DrawType.APPS) {
if (mSettings.getString(Settings.KEY_BACKGROUND).equals("Color")) {
canvas.drawColor(Color.parseColor(mSettings.getString(Settings.KEY_BACKGROUND_COLOR)));
}
mPaintNewAppTag.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));
drawWorkspaceBackground(canvas);
if (mApps != null) {
drawGrid(canvas, mApps.size());
}
if (mSettings.getBoolean(Settings.KEY_SHOW_TOUCH_SELECTION)) {
drawTouchSelection(canvas);
}
} else if (mDrawType == DrawType.CIRCLES) {
mNumberOfCircles = 100;
mTouchX = getWidth() / 2;
mTouchY = getHeight() / 2;
drawGrid(canvas, mNumberOfCircles);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mDrawType == DrawType.APPS) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
if (event.getX() < 0.0f) {
mTouchX = 0.0f;
} else {
mTouchX = event.getX();
}
if (event.getY() < 0.0f) {
mTouchY = 0.0f;
} else {
mTouchY = event.getY();
}
mSelectIndex = -1;
mMoving = false;
invalidate();
return true;
}
case MotionEvent.ACTION_MOVE: {
if (!mMoving && Math.sqrt(Math.pow(event.getX() - mTouchX, 2) + Math.pow(event.getY() - mTouchY, 2)) > mTouchSlop) {
mMoving = true;
LensAnimation lensShowAnimation = new LensAnimation(true);
startAnimation(lensShowAnimation);
}
if (!mMoving) {
return true;
}
if (event.getX() < 0.0f) {
mTouchX = 0.0f;
} else {
mTouchX = event.getX();
}
if (event.getY() < 0.0f) {
mTouchY = 0.0f;
} else {
mTouchY = event.getY();
}
invalidate();
return true;
}
case MotionEvent.ACTION_UP: {
performLaunchVibration();
if (mMoving) {
LensAnimation lensHideAnimation = new LensAnimation(false);
startAnimation(lensHideAnimation);
mMoving = false;
} else {
launchApp();
}
return true;
}
default: {
return super.onTouchEvent(event);
}
}
}
return super.onTouchEvent(event);
}
private void drawWorkspaceBackground(Canvas canvas) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Rect rect = new Rect(0, 0, getWidth(), getHeight());
mWorkspaceBackgroundDrawable.setBounds(rect);
mWorkspaceBackgroundDrawable.draw(canvas);
}
}
private void drawTouchSelection(Canvas canvas) {
canvas.drawCircle(mTouchX, mTouchY, getResources().getDimension(R.dimen.radius_touch_selection), mPaintTouchSelection);
}
private void drawGrid(Canvas canvas, int itemCount) {
Grid grid = LensCalculator.calculateGrid(
getContext(),
getWidth() - (mInsets.left + mInsets.right),
getHeight() - (mInsets.top + mInsets.bottom),
itemCount);
mInsideRect = false;
int selectIndex = -1;
mRectToSelect = null;
for (float y = 0.0f; y < (float) grid.getItemCountVertical(); y += 1.0f) {
for (float x = 0.0f; x < (float) grid.getItemCountHorizontal(); x += 1.0f) {
int currentItem = (int) (y * ((float) grid.getItemCountHorizontal()) + (x + 1.0f));
int currentIndex = currentItem - 1;
if (currentItem <= grid.getItemCount() || mDrawType == DrawType.CIRCLES) {
RectF rect = new RectF();
rect.left = mInsets.left + (x + 1.0f) * grid.getSpacingHorizontal() + x * grid.getItemSize();
rect.top = mInsets.top + (y + 1.0f) * grid.getSpacingVertical() + y * grid.getItemSize();
rect.right = rect.left + grid.getItemSize();
rect.bottom = rect.top + grid.getItemSize();
float animationMultiplier;
if (mDrawType == DrawType.APPS) {
animationMultiplier = mAnimationMultiplier;
} else {
animationMultiplier = 1.0f;
}
if (mTouchX >= 0 && mTouchY >= 0) {
float shiftedCenterX = LensCalculator.shiftPoint(getContext(), mTouchX, rect.centerX(), getWidth(), animationMultiplier);
float shiftedCenterY = LensCalculator.shiftPoint(getContext(), mTouchY, rect.centerY(), getHeight(), animationMultiplier);
float scaledCenterX = LensCalculator.scalePoint(getContext(), mTouchX, rect.centerX(), rect.width(), getWidth(), animationMultiplier);
float scaledCenterY = LensCalculator.scalePoint(getContext(), mTouchY, rect.centerY(), rect.height(), getHeight(), animationMultiplier);
float newSize = LensCalculator.calculateSquareScaledSize(scaledCenterX, shiftedCenterX, scaledCenterY, shiftedCenterY);
if (mSettings.getFloat(Settings.KEY_DISTORTION_FACTOR) > 0.0f && mSettings.getFloat(Settings.KEY_SCALE_FACTOR) > 0.0f) {
rect = LensCalculator.calculateRect(shiftedCenterX, shiftedCenterY, newSize);
} else if (mSettings.getFloat(Settings.KEY_DISTORTION_FACTOR) > 0.0f && mSettings.getFloat(Settings.KEY_SCALE_FACTOR) == 0.0f) {
rect = LensCalculator.calculateRect(shiftedCenterX, shiftedCenterY, rect.width());
}
if (LensCalculator.isInsideRect(mTouchX, mTouchY, rect)) {
mInsideRect = true;
selectIndex = currentIndex;
mRectToSelect = rect;
}
}
if (mDrawType == DrawType.APPS) {
drawAppIcon(canvas, rect, currentIndex);
} else if (mDrawType == DrawType.CIRCLES) {
drawCircle(canvas, rect);
}
}
}
}
if (selectIndex >= 0) {
if (selectIndex != mSelectIndex) {
mMustVibrate = true;
} else {
mMustVibrate = false;
}
} else {
mMustVibrate = false;
}
if (!mAnimationHiding) {
mSelectIndex = selectIndex;
}
if (mDrawType == DrawType.APPS) {
performHoverVibration();
}
if (mRectToSelect != null && mDrawType == DrawType.APPS && mApps != null && mSelectIndex >= 0) {
drawAppName(canvas, mRectToSelect);
}
}
private void drawAppIcon(Canvas canvas, RectF rect, int index) {
if (index < mAppIcons.size()) {
Bitmap appIcon = mAppIcons.get(index);
Rect src = new Rect(0, 0, appIcon.getWidth(), appIcon.getHeight());
canvas.drawBitmap(appIcon, src, rect, mPaintIcons);
/**
* Check if the app was installed Settings.SHOW_NEW_APP_TAG_DURATION ago, and if it has been opened since.
* If not, drawNewAppTag()
*/
if ((mApps.get(index).getInstallDate() >= (System.currentTimeMillis() - Settings.SHOW_NEW_APP_TAG_DURATION)
&& (AppPersistent.getAppOpenCount(
mApps.get(index).getPackageName().toString(), mApps.get(index).getName().toString()) == 0))) {
drawNewAppTag(canvas, rect);
}
}
}
private void drawCircle(Canvas canvas, RectF rect) {
canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 2.0f, mPaintCircles);
}
private void drawAppName(Canvas canvas, RectF rect) {
if (mSettings.getBoolean(Settings.KEY_SHOW_NAME_APP_HOVER) && mMoving) {
canvas.drawText((String) mApps.get(mSelectIndex).getLabel(),
rect.centerX(),
rect.top - getResources().getDimension(R.dimen.margin_lens_text),
mPaintText);
}
}
private void drawNewAppTag(Canvas canvas, RectF rect) {
if (mSettings.getBoolean(Settings.KEY_SHOW_NEW_APP_TAG)) {
canvas.drawCircle(rect.centerX(),
rect.bottom + getResources().getDimension(R.dimen.margin_new_app_tag),
getResources().getDimension(R.dimen.radius_new_app_tag),
mPaintNewAppTag);
}
}
private void performHoverVibration() {
if (mInsideRect) {
if (mMustVibrate) {
if (mSettings.getBoolean(Settings.KEY_VIBRATE_APP_HOVER) && !mAnimationHiding) {
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
}
mMustVibrate = false;
}
} else {
mMustVibrate = true;
}
}
private void performLaunchVibration() {
if (mInsideRect) {
if (mSettings.getBoolean(Settings.KEY_VIBRATE_APP_LAUNCH)) {
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
}
}
}
private void launchApp() {
if (mPackageManager != null && mApps != null && mSelectIndex >= 0) {
AppUtil.launchComponent(
getContext(),
(String) mApps.get(mSelectIndex).getPackageName(),
(String) mApps.get(mSelectIndex).getName(),
this,
mRectToSelect == null ? null :
new Rect((int) mRectToSelect.left, (int) mRectToSelect.top,
(int) mRectToSelect.right, (int) mRectToSelect.bottom));
}
}
private class LensAnimation extends Animation {
private boolean mShow;
public LensAnimation(boolean show) {
mShow = show;
setInterpolator(new AccelerateDecelerateInterpolator());
setDuration(mSettings.getLong(Settings.KEY_ANIMATION_TIME));
setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
if (!mShow) {
mAnimationHiding = true;
mPaintText.clearShadowLayer();
} else {
mAnimationHiding = false;
}
}
@Override
public void onAnimationEnd(Animation animation) {
if (!mShow) {
launchApp();
mTouchX = -Float.MAX_VALUE;
mTouchY = -Float.MAX_VALUE;
mAnimationHiding = false;
} else {
mPaintText.setShadowLayer(
getResources().getDimension(R.dimen.shadow_text),
getResources().getDimension(R.dimen.shadow_text),
getResources().getDimension(R.dimen.shadow_text),
ContextCompat.getColor(getContext(), R.color.colorShadow));
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
if (mShow) {
mAnimationMultiplier = interpolatedTime;
mPaintTouchSelection.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));
mPaintTouchSelection.setAlpha((int) (255.0f * interpolatedTime));
mPaintText.setAlpha((int) (255.0f * interpolatedTime));
} else {
mAnimationMultiplier = 1.0f - interpolatedTime;
mPaintTouchSelection.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));
mPaintTouchSelection.setAlpha((int) (255.0f * (1.0f - interpolatedTime)));
mPaintText.setAlpha((int) (255.0f * (1.0f - interpolatedTime)));
}
postInvalidate();
}
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/ui/SettingsActivity.java
================================================
package nickrout.lenslauncher.ui;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.color.ColorChooserDialog;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import nickrout.lenslauncher.R;
import nickrout.lenslauncher.background.NightModeObservable;
import nickrout.lenslauncher.model.App;
import nickrout.lenslauncher.util.AppSorter;
import nickrout.lenslauncher.AppsSingleton;
import nickrout.lenslauncher.background.BroadcastReceivers;
import nickrout.lenslauncher.util.IconPackManager;
import nickrout.lenslauncher.util.LauncherUtil;
import nickrout.lenslauncher.background.LoadedObservable;
import nickrout.lenslauncher.util.NightModeUtil;
import nickrout.lenslauncher.util.Settings;
/**
* Created by nicholasrout on 2016/06/07.
*/
public class SettingsActivity extends BaseActivity
implements Observer, ColorChooserDialog.ColorCallback {
private static final String TAG = "SettingsActivity";
private static final String COLOR_TAG_BACKGROUND = "BackgroundColor";
private static final String COLOR_TAG_HIGHLIGHT = "HighlightColor";
@BindView(R.id.toolbar)
Toolbar mToolbar;
@BindView(R.id.tabs)
TabLayout mTabLayout;
@BindView(R.id.viewpager)
ViewPager mViewPager;
@BindView(R.id.fab_sort)
FloatingActionButton mSortFab;
@OnClick(R.id.fab_sort)
public void onSortClicked() {
showSortTypeDialog();
}
private FragmentPagerAdapter mPagerAdapter;
private ArrayList<App> mApps;
private MaterialDialog mSortTypeDialog;
private MaterialDialog mIconPackDialog;
private MaterialDialog mNightModeDialog;
private MaterialDialog mBackgroundDialog;
private ColorChooserDialog mBackgroundColorDialog;
private ColorChooserDialog mHighlightColorDialog;
public interface LensInterface {
void onDefaultsReset();
}
private LensInterface mLensInterface;
public void setLensInterface(LensInterface lensInterface) {
mLensInterface = lensInterface;
}
public interface AppsInterface {
void onDefaultsReset();
void onAppsUpdated(ArrayList<App> apps);
}
private AppsInterface mAppsInterface;
public void setAppsInterface(AppsInterface appsInterface) {
mAppsInterface = appsInterface;
}
public interface SettingsInterface {
void onDefaultsReset();
void onValuesUpdated();
}
private SettingsInterface mSettingsInterface;
public void setSettingsInterface(SettingsInterface settingsInterface) {
mSettingsInterface = settingsInterface;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
ButterKnife.bind(this);
mSortFab.hide();
setSupportActionBar(mToolbar);
mPagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager(), SettingsActivity.this);
mViewPager.setAdapter(mPagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
switch (position) {
case 1:
mSortFab.show();
break;
default:
mSortFab.hide();
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
mApps = AppsSingleton.getInstance().getApps();
LoadedObservable.getInstance().addObserver(this);
NightModeObservable.getInstance().addObserver(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_settings, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_show_apps:
if (LauncherUtil.isLauncherDefault(getApplication())) {
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
startActivity(homeIntent);
} else {
Intent homeIntent = new Intent(SettingsActivity.this, HomeActivity.class);
startActivity(homeIntent);
}
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
return true;
case R.id.menu_item_about:
Intent aboutIntent = new Intent(SettingsActivity.this, AboutActivity.class);
startActivity(aboutIntent);
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
return true;
case R.id.menu_item_reset_default_settings:
switch (mViewPager.getCurrentItem()) {
case 0:
if (mLensInterface != null) {
mLensInterface.onDefaultsReset();
}
break;
case 1:
if (mAppsInterface != null) {
mAppsInterface.onDefaultsReset();
}
break;
case 2:
if (mSettingsInterface != null) {
mSettingsInterface.onDefaultsReset();
}
break;
}
Snackbar.make(mToolbar, getString(R.string.snackbar_reset_successful), Snackbar.LENGTH_LONG).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void update(Observable observable, Object data) {
if (observable instanceof LoadedObservable) {
mApps = AppsSingleton.getInstance().getApps();
if (mAppsInterface != null) {
mAppsInterface.onAppsUpdated(mApps);
}
} else if (observable instanceof NightModeObservable) {
updateNightMode();
}
}
private void sendUpdateAppsBroadcast() {
Intent refreshAppsIntent = new Intent(SettingsActivity.this, BroadcastReceivers.AppsUpdatedReceiver.class);
sendBroadcast(refreshAppsIntent);
}
private void sendEditAppsBroadcast() {
Intent editAppsIntent = new Intent(SettingsActivity.this, BroadcastReceivers.AppsEditedReceiver.class);
sendBroadcast(editAppsIntent);
}
private void sendBackgroundChangedBroadcast() {
Intent changeBackgroundIntent = new Intent(SettingsActivity.this, BroadcastReceivers.BackgroundChangedReceiver.class);
sendBroadcast(changeBackgroundIntent);
}
public void sendNightModeBroadcast() {
Intent nightModeIntent = new Intent(SettingsActivity.this, BroadcastReceivers.NightModeReceiver.class);
sendBroadcast(nightModeIntent);
}
private void showSortTypeDialog() {
final List<AppSorter.SortType> sortTypes = new ArrayList<>(EnumSet.allOf(AppSorter.SortType.class));
final List<String> sortTypeStrings = new ArrayList<>();
for (int i = 0; i < sortTypes.size(); i++) {
sortTypeStrings.add(getApplicationContext().getString(sortTypes.get(i).getDisplayNameResId()));
}
AppSorter.SortType selectedSortType = mSettings.getSortType();
int selectedIndex = sortTypes.indexOf(selectedSortType);
mSortTypeDialog = new MaterialDialog.Builder(SettingsActivity.this)
.title(R.string.setting_sort_apps)
.items(sortTypeStrings)
.alwaysCallSingleChoiceCallback()
.itemsCallbackSingleChoice(selectedIndex, new MaterialDialog.ListCallbackSingleChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
mSettings.save(sortTypes.get(which));
sendEditAppsBroadcast();
return true;
}
})
.show();
}
public void showIconPackDialog() {
final ArrayList<IconPackManager.IconPack> availableIconPacks =
new IconPackManager().getAvailableIconPacksWithIcons(true, getApplication());
final ArrayList<String> iconPackNames = new ArrayList<>();
iconPackNames.add(getString(R.string.setting_default_icon_pack));
for (int i = 0; i < availableIconPacks.size(); i++) {
if (iconPackNames.size() > 0 && !iconPackNames.contains(availableIconPacks.get(i).mName)) {
iconPackNames.add(availableIconPacks.get(i).mName);
}
}
String selectedPackageName = mSettings.getString(Settings.KEY_ICON_PACK_LABEL_NAME);
int selectedIndex = iconPackNames.indexOf(selectedPackageName);
mIconPackDialog = new MaterialDialog.Builder(SettingsActivity.this)
.title(R.string.setting_icon_pack)
.items(iconPackNames)
.alwaysCallSingleChoiceCallback()
.itemsCallbackSingleChoice(selectedIndex, new MaterialDialog.ListCallbackSingleChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
mSettings.save(Settings.KEY_ICON_PACK_LABEL_NAME, iconPackNames.get(which));
if (mSettingsInterface != null) {
mSettingsInterface.onValuesUpdated();
}
sendUpdateAppsBroadcast();
return true;
}
})
.show();
}
public void showHomeLauncherChooser() {
LauncherUtil.resetPreferredLauncherAndOpenChooser(getApplicationContext());
}
public void showNightModeChooser() {
String[] availableNightModes = getResources().getStringArray(R.array.night_modes);
final ArrayList<String> nightModes = new ArrayList<>();
for (int i = 0; i < availableNightModes.length; i++) {
nightModes.add(availableNightModes[i]);
}
String selectedNightMode = NightModeUtil.getNightModeDisplayName(mSettings.getNightMode());
int selectedIndex = nightModes.indexOf(selectedNightMode);
mNightModeDialog = new MaterialDialog.Builder(SettingsActivity.this)
.title(R.string.setting_night_mode)
.items(R.array.night_modes)
.alwaysCallSingleChoiceCallback()
.itemsCallbackSingleChoice(selectedIndex, new MaterialDialog.ListCallbackSingleChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
String selection = nightModes.get(which);
mSettings.save(Settings.KEY_NIGHT_MODE, NightModeUtil.getNightModeFromDisplayName(selection));
sendNightModeBroadcast();
if (mSettingsInterface != null) {
mSettingsInterface.onValuesUpdated();
}
dismissBackgroundDialog();
return true;
}
})
.show();
}
public void showBackgroundDialog() {
String[] availableBackgrounds = getResources().getStringArray(R.array.backgrounds);
final ArrayList<String> backgroundNames = new ArrayList<>();
for (int i = 0; i < availableBackgrounds.length; i++) {
backgroundNames.add(availableBackgrounds[i]);
}
String selectedBackground = mSettings.getString(Settings.KEY_BACKGROUND);
int selectedIndex = backgroundNames.indexOf(selectedBackground);
mBackgroundDialog = new MaterialDialog.Builder(SettingsActivity.this)
.title(R.string.setting_background)
.items(R.array.backgrounds)
.alwaysCallSingleChoiceCallback()
.itemsCallbackSingleChoice(selectedIndex, new MaterialDialog.ListCallbackSingleChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
String selection = backgroundNames.get(which);
if (selection.equals("Wallpaper")) {
mSettings.save(Settings.KEY_BACKGROUND, selection);
sendBackgroundChangedBroadcast();
if (mSettingsInterface != null) {
mSettingsInterface.onValuesUpdated();
}
dismissBackgroundDialog();
showWallpaperPicker();
} else if (selection.equals("Color")) {
dismissBackgroundDialog();
showBackgroundColorDialog();
}
return true;
}
})
.show();
}
public void showWallpaperPicker() {
Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
startActivity(Intent.createChooser(intent, "Select Wallpaper"));
}
public void showBackgroundColorDialog() {
mBackgroundColorDialog = new ColorChooserDialog.Builder(this, R.string.setting_background_color)
.titleSub(R.string.setting_background_color)
.accentMode(false)
.doneButton(com.afollestad.materialdialogs.commons.R.string.md_done_label)
.cancelButton(com.afollestad.materialdialogs.commons.R.string.md_cancel_label)
.backButton(com.afollestad.materialdialogs.commons.R.string.md_back_label)
.preselect(Color.parseColor(mSettings.getString(Settings.KEY_BACKGROUND_COLOR)))
.dynamicButtonColor(false)
.allowUserColorInputAlpha(false)
.tag(COLOR_TAG_BACKGROUND)
.show(this);
}
public void showHighlightColorDialog() {
mHighlightColorDialog = new ColorChooserDialog.Builder(this, R.string.setting_highlight_color)
.titleSub(R.string.setting_highlight_color)
.accentMode(true)
.doneButton(com.afollestad.materialdialogs.commons.R.string.md_done_label)
.cancelButton(com.afollestad.materialdialogs.commons.R.string.md_cancel_label)
.backButton(com.afollestad.materialdialogs.commons.R.string.md_back_label)
.preselect(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)))
.dynamicButtonColor(false)
.allowUserColorInputAlpha(false)
.tag(COLOR_TAG_HIGHLIGHT)
.show(this);
}
@Override
public void onColorSelection(@NonNull ColorChooserDialog dialog, @ColorInt int selectedColor) {
String hexColor = String.format("#%06X", selectedColor);
if (dialog.tag().equals(COLOR_TAG_BACKGROUND)) {
mSettings.save(Settings.KEY_BACKGROUND, "Color");
mSettings.save(Settings.KEY_BACKGROUND_COLOR, hexColor);
sendBackgroundChangedBroadcast();
} else if (dialog.tag().equals(COLOR_TAG_HIGHLIGHT)) {
mSettings.save(Settings.KEY_HIGHLIGHT_COLOR, hexColor);
}
if (mSettingsInterface != null) {
mSettingsInterface.onValuesUpdated();
}
}
@Override
public void onColorChooserDismissed(@NonNull ColorChooserDialog dialog) {
}
private void dismissSortTypeDialog() {
if (mSortTypeDialog != null && mSortTypeDialog.isShowing()) {
mSortTypeDialog.dismiss();
}
}
private void dismissIconPackDialog() {
if (mIconPackDialog != null && mIconPackDialog.isShowing()) {
mIconPackDialog.dismiss();
}
}
private void dismissNightModeDialog() {
if (mNightModeDialog != null && mNightModeDialog.isShowing()) {
mNightModeDialog.dismiss();
}
}
private void dismissBackgroundDialog() {
if (mBackgroundDialog != null && mBackgroundDialog.isShowing()) {
mBackgroundDialog.dismiss();
}
}
private void dismissAllDialogs() {
dismissSortTypeDialog();
dismissIconPackDialog();
dismissNightModeDialog();
dismissBackgroundDialog();
// Color dialogs do not need to be dismissed
}
@Override
protected void onDestroy() {
dismissAllDialogs();
LoadedObservable.getInstance().deleteObserver(this);
super.onDestroy();
}
@Override
public void onBackPressed() {
finish();
}
@Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}
private class FragmentPagerAdapter extends FragmentStatePagerAdapter {
private static final int NUM_PAGES = 3;
private Context mContext;
public FragmentPagerAdapter(FragmentManager fragmentManager, Context context) {
super(fragmentManager);
mContext = context;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return LensFragment.newInstance();
case 1:
return AppsFragment.newInstance();
case 2:
return SettingsFragment.newInstance();
}
return new Fragment();
}
@Override
public int getCount() {
return NUM_PAGES;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return mContext.getResources().getString(R.string.tab_lens);
case 1:
return mContext.getResources().getString(R.string.tab_apps);
case 2:
return mContext.getResources().getString(R.string.tab_settings);
}
return super.getPageTitle(position);
}
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/ui/SettingsFragment.java
================================================
package nickrout.lenslauncher.ui;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.SwitchCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import nickrout.lenslauncher.R;
import nickrout.lenslauncher.util.LauncherUtil;
import nickrout.lenslauncher.util.NightModeUtil;
import nickrout.lenslauncher.util.Settings;
/**
* Created by nicholasrout on 2016/06/08.
*/
public class SettingsFragment extends Fragment implements SettingsActivity.SettingsInterface {
private static final String TAG = "SettingsFragment";
@OnClick(R.id.layout_home_launcher)
public void onHomeLauncherClick() {
showHomeLauncherChooser();
}
@BindView(R.id.text_view_selected_home_launcher)
TextView mHomeLauncherTextView;
@OnClick(R.id.layout_icon_pack)
public void onIconPackClick() {
showIconPackDialog();
}
@BindView(R.id.text_view_selected_icon_pack)
TextView mIconPackTextView;
@OnClick(R.id.layout_night_mode)
public void onNightModeClick() {
showNightModeChooser();
}
@BindView(R.id.text_view_selected_night_mode)
TextView mNightModeTextView;
@OnClick(R.id.layout_background)
public void onBackgroundClick() {
showBackgroundDialog();
}
@BindView(R.id.text_view_selected_background)
TextView mBackgroundTextView;
@BindView(R.id.image_view_selected_background_color)
ImageView mBackgroundColorImageView;
@OnClick(R.id.layout_highlight_color)
public void onHighlightColorClick() {
showHighlightColorDialog();
}
@BindView(R.id.text_view_selected_highlight_color)
TextView mHighlightColorTextView;
@BindView(R.id.image_view_selected_highlight_color)
ImageView mHighlightColorImageView;
@BindView(R.id.switch_vibrate_app_hover)
SwitchCompat mVibrateAppHover;
@BindView(R.id.switch_vibrate_app_launch)
SwitchCompat mVibrateAppLaunch;
@BindView(R.id.switch_show_name_app_hover)
SwitchCompat mShowNameAppHover;
@BindView(R.id.switch_show_new_app_tag)
SwitchCompat mShowNewAppTag;
@BindView(R.id.switch_show_touch_selection)
SwitchCompat mShowTouchSelection;
private Settings mSettings;
public SettingsFragment() {
}
public static SettingsFragment newInstance() {
SettingsFragment settingsFragment = new SettingsFragment();
// Include potential bundle extras here
return settingsFragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_settings, container, false);
ButterKnife.bind(this, view);
mSettings = new Settings(getActivity());
setupViews();
assignValues();
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (getActivity() != null && getActivity() instanceof SettingsActivity) {
((SettingsActivity) getActivity()).setSettingsInterface(this);
}
}
private void setupViews() {
mVibrateAppHover.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mSettings.save(Settings.KEY_VIBRATE_APP_HOVER, isChecked);
}
});
mVibrateAppLaunch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mSettings.save(Settings.KEY_VIBRATE_APP_LAUNCH, isChecked);
}
});
mShowNameAppHover.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mSettings.save(Settings.KEY_SHOW_NAME_APP_HOVER, isChecked);
}
});
mShowNewAppTag.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mSettings.save(Settings.KEY_SHOW_NEW_APP_TAG, isChecked);
}
});
mShowTouchSelection.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mSettings.save(Settings.KEY_SHOW_TOUCH_SELECTION, isChecked);
}
});
}
private void assignValues() {
mIconPackTextView.setText(mSettings.getString(Settings.KEY_ICON_PACK_LABEL_NAME));
String highlightColor = "#" + mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR).substring(3);
String homeLauncher = "";
if (getActivity() != null) {
homeLauncher = LauncherUtil.getHomeLauncherName(getActivity().getApplication());
}
mHomeLauncherTextView.setText(homeLauncher);
mNightModeTextView.setText(NightModeUtil.getNightModeDisplayName(mSettings.getNightMode()));
if (mSettings.getString(Settings.KEY_BACKGROUND).equals("Color")) {
String backgroundColor = "#" + mSettings.getString(Settings.KEY_BACKGROUND_COLOR).substring(3);
mBackgroundTextView.setText(backgroundColor);
mBackgroundColorImageView.setVisibility(View.VISIBLE);
GradientDrawable backgroundColorDrawable = new GradientDrawable();
backgroundColorDrawable.setColor(Color.parseColor(mSettings.getString(Settings.KEY_BACKGROUND_COLOR)));
backgroundColorDrawable.setCornerRadius(getResources().getDimension(R.dimen.radius_highlight_color_switch));
mBackgroundColorImageView.setImageDrawable(backgroundColorDrawable);
} else {
mBackgroundTextView.setText(mSettings.getString(Settings.KEY_BACKGROUND));
mBackgroundColorImageView.setVisibility(View.GONE);
}
mHighlightColorTextView.setText(highlightColor);
GradientDrawable highlightColorDrawable = new GradientDrawable();
highlightColorDrawable.setColor(Color.parseColor(mSettings.getString(Settings.KEY_HIGHLIGHT_COLOR)));
highlightColorDrawable.setCornerRadius(getResources().getDimension(R.dimen.radius_highlight_color_switch));
mHighlightColorImageView.setImageDrawable(highlightColorDrawable);
mVibrateAppHover.setChecked(mSettings.getBoolean(Settings.KEY_VIBRATE_APP_HOVER));
mVibrateAppLaunch.setChecked(mSettings.getBoolean(Settings.KEY_VIBRATE_APP_LAUNCH));
mShowNameAppHover.setChecked(mSettings.getBoolean(Settings.KEY_SHOW_NAME_APP_HOVER));
mShowNewAppTag.setChecked(mSettings.getBoolean(Settings.KEY_SHOW_NEW_APP_TAG));
mShowTouchSelection.setChecked(mSettings.getBoolean(Settings.KEY_SHOW_TOUCH_SELECTION));
}
private void showIconPackDialog() {
if (getActivity() != null && getActivity() instanceof SettingsActivity) {
((SettingsActivity) getActivity()).showIconPackDialog();
}
}
private void showHomeLauncherChooser() {
if (getActivity() != null && getActivity() instanceof SettingsActivity) {
((SettingsActivity) getActivity()).showHomeLauncherChooser();
}
}
private void showNightModeChooser() {
if (getActivity() != null && getActivity() instanceof SettingsActivity) {
((SettingsActivity) getActivity()).showNightModeChooser();
}
}
private void showBackgroundDialog() {
if (getActivity() != null && getActivity() instanceof SettingsActivity) {
((SettingsActivity) getActivity()).showBackgroundDialog();
}
}
private void showHighlightColorDialog() {
if (getActivity() != null && getActivity() instanceof SettingsActivity) {
((SettingsActivity) getActivity()).showHighlightColorDialog();
}
}
@Override
public void onDefaultsReset() {
resetToDefault();
assignValues();
}
@Override
public void onValuesUpdated() {
assignValues();
}
private void resetToDefault() {
mSettings.save(Settings.KEY_VIBRATE_APP_HOVER, Settings.DEFAULT_VIBRATE_APP_HOVER);
mSettings.save(Settings.KEY_VIBRATE_APP_LAUNCH, Settings.DEFAULT_VIBRATE_APP_LAUNCH);
mSettings.save(Settings.KEY_SHOW_NAME_APP_HOVER, Settings.DEFAULT_SHOW_NAME_APP_HOVER);
mSettings.save(Settings.KEY_SHOW_TOUCH_SELECTION, Settings.DEFAULT_SHOW_TOUCH_SELECTION);
mSettings.save(Settings.KEY_SHOW_NEW_APP_TAG, Settings.DEFAULT_SHOW_NEW_APP_TAG);
mSettings.save(Settings.KEY_BACKGROUND, Settings.DEFAULT_BACKGROUND);
mSettings.save(Settings.KEY_BACKGROUND_COLOR, Settings.DEFAULT_BACKGROUND_COLOR);
mSettings.save(Settings.KEY_HIGHLIGHT_COLOR, Settings.DEFAULT_HIGHLIGHT_COLOR);
mSettings.save(Settings.KEY_ICON_PACK_LABEL_NAME, Settings.DEFAULT_ICON_PACK_LABEL_NAME);
mSettings.save(Settings.KEY_NIGHT_MODE, Settings.DEFAULT_NIGHT_MODE);
if (getActivity() != null && getActivity() instanceof SettingsActivity) {
((SettingsActivity) getActivity()).sendNightModeBroadcast();
}
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/util/AppSorter.java
================================================
package nickrout.lenslauncher.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import nickrout.lenslauncher.R;
import nickrout.lenslauncher.model.App;
import nickrout.lenslauncher.model.AppPersistent;
/**
* Created by nicholasrout on 2016/05/28.
*/
public class AppSorter {
public enum SortType {
LABEL_ASCENDING(R.string.setting_sort_type_label_ascending),
LABEL_DESCENDING(R.string.setting_sort_type_label_descending),
INSTALL_DATE_ASCENDING(R.string.setting_sort_type_install_date_ascending),
INSTALL_DATE_DESCENDING(R.string.setting_sort_type_install_date_descending),
ICON_COLOR_ASCENDING(R.string.setting_sort_type_icon_color_ascending),
ICON_COLOR_DESCENDING(R.string.setting_sort_type_icon_color_descending),
OPEN_COUNT_ASCENDING(R.string.setting_sort_type_open_count_ascending),
OPEN_COUNT_DESCENDING(R.string.setting_sort_type_open_count_descending);
int mDisplayNameResId;
SortType(int displayNameResId) {
mDisplayNameResId = displayNameResId;
}
public int getDisplayNameResId() {
return mDisplayNameResId;
}
}
public static void sort(ArrayList<App> apps, SortType sortType) {
switch (sortType) {
case LABEL_ASCENDING:
sortByLabelAscending(apps);
break;
case LABEL_DESCENDING:
sortByLabelDescending(apps);
break;
case INSTALL_DATE_ASCENDING:
sortByInstallDateAscending(apps);
break;
case INSTALL_DATE_DESCENDING:
sortByInstallDateDescending(apps);
break;
case OPEN_COUNT_ASCENDING:
sortByOpenCountAscending(apps);
break;
case OPEN_COUNT_DESCENDING:
sortByOpenCountDescending(apps);
break;
case ICON_COLOR_ASCENDING:
sortByIconColorAscending(apps);
break;
case ICON_COLOR_DESCENDING:
sortByIconColorDescending(apps);
break;
default:
sortByLabelAscending(apps);
break;
}
}
private static void sortByLabelAscending(ArrayList<App> apps) {
Collections.sort(apps, new Comparator<App>() {
@Override
public int compare(App a1, App a2) {
return (a1.getLabel().toString()).compareToIgnoreCase(a2.getLabel().toString());
}
});
}
private static void sortByLabelDescending(ArrayList<App> apps) {
sortByLabelAscending(apps);
Collections.reverse(apps);
}
private static void sortByInstallDateAscending(ArrayList<App> apps) {
Collections.sort(apps, new Comparator<App>() {
@Override
public int compare(App a1, App a2) {
if (a1.getInstallDate() > a2.getInstallDate()) {
return -1;
} else if (a1.getInstallDate() < a2.getInstallDate()) {
return +1;
}
return 0;
}
});
}
private static void sortByInstallDateDescending(ArrayList<App> apps) {
sortByInstallDateAscending(apps);
Collections.reverse(apps);
}
private static void sortByOpenCountAscending(ArrayList<App> apps) {
Collections.sort(apps, new Comparator<App>() {
@Override
public int compare(App a1, App a2) {
long a1OpenCount =
AppPersistent.getAppOpenCount(a1.getPackageName().toString(), a1.getName().toString());
long a2OpenCount =
AppPersistent.getAppOpenCount(a2.getPackageName().toString(), a2.getName().toString());
if (a1OpenCount > a2OpenCount) {
return -1;
} else if (a1OpenCount < a2OpenCount) {
return +1;
}
return 0;
}
});
}
private static void sortByOpenCountDescending(ArrayList<App> apps) {
sortByOpenCountAscending(apps);
Collections.reverse(apps);
}
private static void sortByIconColorAscending(ArrayList<App> apps) {
Collections.sort(apps, new Comparator<App>() {
@Override
public int compare(App a1, App a2) {
float a1HSVColor = ColorUtil.getHueColorFromApp(a1);
float a2HSVColor = ColorUtil.getHueColorFromApp(a2);
if (a1HSVColor > a2HSVColor) {
return -1;
} else if (a1HSVColor < a2HSVColor) {
return +1;
}
return 0;
}
});
}
private static void sortByIconColorDescending(ArrayList<App> apps) {
sortByIconColorAscending(apps);
Collections.reverse(apps);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/util/AppUtil.java
================================================
package nickrout.lenslauncher.util;
import android.app.Application;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import nickrout.lenslauncher.R;
import nickrout.lenslauncher.background.BroadcastReceivers;
import nickrout.lenslauncher.model.App;
import nickrout.lenslauncher.model.AppPersistent;
/**
* Created by nickrout on 2016/04/02.
*/
public class AppUtil {
private static final String TAG = AppUtil.class.getSimpleName();
// Get all available apps for launcher
public static ArrayList<App> getApps(
PackageManager packageManager, Context context, Application application,
String iconPackLabelName, AppSorter.SortType sortType) {
ArrayList<App> apps = new ArrayList<>();
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> availableActivities = null;
try {
availableActivities = packageManager.queryIntentActivities(intent, 0);
} catch (RuntimeException e) {
e.printStackTrace();
Toast.makeText(context, R.string.error_too_many_apps, Toast.LENGTH_SHORT).show();
}
if (availableActivities != null) {
IconPackManager.IconPack selectedIconPack = null;
ArrayList<IconPackManager.IconPack> iconPacks = new IconPackManager().getAvailableIconPacksWithIcons(true, application);
for (IconPackManager.IconPack iconPack : iconPacks) {
if (iconPack.mName.equals(iconPackLabelName))
selectedIconPack = iconPack;
}
for (int i = 0; i < availableActivities.size(); i++) {
ResolveInfo resolveInfo = availableActivities.get(i);
App app = new App();
app.setId(i);
try {
app.setInstallDate(packageManager.getPackageInfo(resolveInfo.activityInfo.packageName, 0).firstInstallTime);
} catch (PackageManager.NameNotFoundException e) {
app.setInstallDate(0);
}
app.setLabel(resolveInfo.loadLabel(packageManager));
app.setPackageName(resolveInfo.activityInfo.packageName);
app.setName(resolveInfo.activityInfo.name);
app.setIconResId(resolveInfo.activityInfo.getIconResource());
Bitmap defaultBitmap = BitmapUtil.packageNameToBitmap(
context, packageManager, resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.getIconResource());
if (selectedIconPack != null)
app.setIcon(selectedIconPack.getIconForPackage(app.getPackageName().toString(), defaultBitmap));
else
app.setIcon(defaultBitmap);
app.setPaletteColor(ColorUtil.getPaletteColorFromApp(app));
apps.add(app);
}
}
AppSorter.sort(apps, sortType);
return apps;
}
// Launch apps, for launcher :-P
public static void launchComponent(Context context, String packageName, String name, View view, Rect bounds) {
if (packageName != null && name != null) {
Intent componentIntent = new Intent();
componentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
componentIntent.setComponent(new ComponentName(packageName, name));
if (!packageName.equals("nickrout.lenslauncher")) {
componentIntent.setAction(Intent.ACTION_MAIN);
}
componentIntent.addCategory(Intent.CATEGORY_LAUNCHER);
try {
// Launch Component
ContextCompat.startActivity(context, componentIntent, getLauncherOptionsBundle(context, view, bounds));
// Increment app open count
AppPersistent.incrementAppCount(packageName, name);
// Resort apps (if open count selected)
Settings settings = new Settings(context);
if (settings.getSortType() == AppSorter.SortType.OPEN_COUNT_ASCENDING ||
settings.getSortType() == AppSorter.SortType.OPEN_COUNT_DESCENDING) {
Intent editAppsIntent = new Intent(context, BroadcastReceivers.AppsEditedReceiver.class);
context.sendBroadcast(editAppsIntent);
}
} catch (ActivityNotFoundException e) {
Toast.makeText(context, R.string.error_app_not_found, Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(context, R.string.error_app_not_found, Toast.LENGTH_SHORT).show();
}
}
private static Bundle getLauncherOptionsBundle(Context context, View source, Rect bounds) {
Bundle optionsBundle = null;
if (source != null) {
ActivityOptionsCompat options;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && bounds != null) {
// Clip reveal animation for Marshmallow and above
options = ActivityOptionsCompat.makeClipRevealAnimation(source, bounds.left, bounds.top, bounds.width(), bounds.height());
} else {
// Fade animation otherwise
options = ActivityOptionsCompat.makeCustomAnimation(context, R.anim.fade_in, R.anim.fade_out);
}
optionsBundle = options.toBundle();
}
return optionsBundle;
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/util/BitmapUtil.java
================================================
package nickrout.lenslauncher.util;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
/**
* Created by nickrout on 2016/04/02.
*/
public class BitmapUtil {
// Old method - does not allow for adding options i.e. lower quality
// Source: http://stackoverflow.com/questions/3035692/how-to-convert-a-drawable-to-a-bitmap
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
bitmapDrawable.setAntiAlias(true);
bitmapDrawable.setDither(true);
bitmapDrawable.setTargetDensity(Integer.MAX_VALUE);
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
// Get bitmap from resource id, with quality options
public static Bitmap resIdToBitmap(Resources res, int resId) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inPreferQualityOverSpeed = true;
try {
return BitmapFactory.decodeResource(res, resId, options);
} catch (OutOfMemoryError e1) {
e1.printStackTrace();
return null;
}
}
// Get res id from app package name
public static int packageNameToResId(PackageManager packageManager, String packageName) {
try {
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
return applicationInfo.icon;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return -1;
}
}
// Get bitmap from app package name
public static Bitmap packageNameToBitmap(PackageManager packageManager, String packageName) {
try {
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
Resources resources = packageManager.getResourcesForApplication(applicationInfo);
int appIconResId = applicationInfo.icon;
return resIdToBitmap(resources, appIconResId);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return null;
}
}
// Get bitmap from app package name (with res id)
public static Bitmap packageNameToBitmap(Context context, PackageManager packageManager, String packageName, int resId) {
try {
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
Resources resources = packageManager.getResourcesForApplication(applicationInfo);
Bitmap bitmap = resIdToBitmap(resources, resId);
if (bitmap == null) {
Drawable drawable = packageManager.getApplicationIcon(packageName);
if (drawable != null) {
bitmap = drawableToBitmap(drawable);
}
}
return bitmap;
} catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
e.printStackTrace();
return null;
}
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/util/ColorUtil.java
================================================
package nickrout.lenslauncher.util;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.support.annotation.ColorInt;
import android.support.v7.graphics.Palette;
import nickrout.lenslauncher.model.App;
/**
* Created by nicholasrout on 2016/05/28.
*/
public class ColorUtil {
public static @ColorInt int getPaletteColorFromApp(App app) {
return getPaletteColorFromBitmap(app.getIcon());
}
public static @ColorInt int getPaletteColorFromBitmap(Bitmap bitmap) {
Palette palette;
try {
palette = Palette.from(bitmap).generate();
} catch (IllegalArgumentException e) {
e.printStackTrace();
return Color.BLACK;
}
if (palette.getSwatches().size() > 0) {
int swatchIndex = 0;
for (int i = 1; i < palette.getSwatches().size(); i++) {
if (palette.getSwatches().get(i).getPopulation()
> palette.getSwatches().get(swatchIndex).getPopulation()) {
swatchIndex = i;
}
}
return palette.getSwatches().get(swatchIndex).getRgb();
} else {
return Color.BLACK;
}
}
public static float getHueColorFromApp(App app) {
return getHueColorFromColor(app.getPaletteColor());
}
public static float getHueColorFromColor(@ColorInt int color) {
float[] hsvValues = new float[3];
Color.colorToHSV(color, hsvValues);
return hsvValues[0];
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/util/IconPackManager.java
================================================
package nickrout.lenslauncher.util;
/**
* Created by rish on 22/5/16.
*/
import android.app.Application;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.util.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import nickrout.lenslauncher.R;
public class IconPackManager {
private static final String TAG = "IconPackManager";
private Application mApplication;
public class IconPack {
public IconPack() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setFilterBitmap(true);
mPaint.setDither(true);
}
public String mPackageName;
public String mName;
private boolean mLoaded = false;
private HashMap<String, String> mPackagesDrawables = new HashMap<String, String>();
private List<Bitmap> mBackImages = new ArrayList<Bitmap>();
private Bitmap mMaskImage = null;
private Bitmap mFrontImage = null;
private float mFactor = 1.0f;
private Paint mPaint;
Resources mIconPackRes = null;
public void load() {
// Load appfilter.xml from the icon pack package
PackageManager pm = mApplication.getPackageManager();
try {
XmlPullParser xpp = null;
mIconPackRes = pm.getResourcesForApplication(mPackageName);
int appfilterid = mIconPackRes.getIdentifier("appfilter", "xml", mPackageName);
if (appfilterid > 0) {
xpp = mIconPackRes.getXml(appfilterid);
} else {
// No resource found, try to open it from assets folder
try {
InputStream appfilterstream = mIconPackRes.getAssets().open("appfilter.xml");
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
xpp = factory.newPullParser();
xpp.setInput(appfilterstream, "utf-8");
} catch (IOException e1) {
Log.d(TAG, "No appfilter.xml file");
}
}
if (xpp != null) {
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
if (xpp.getName().equals("iconback")) {
for (int i = 0; i < xpp.getAttributeCount(); i++) {
if (xpp.getAttributeName(i).startsWith("img")) {
String drawableName = xpp.getAttributeValue(i);
Bitmap iconback = loadBitmap(drawableName);
if (iconback != null)
mBackImages.add(iconback);
}
}
} else if (xpp.getName().equals("iconmask")) {
if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals("img1")) {
String drawableName = xpp.getAttributeValue(0);
mMaskImage = loadBitmap(drawableName);
}
} else if (xpp.getName().equals("iconupon")) {
if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals("img1")) {
String drawableName = xpp.getAttributeValue(0);
mFrontImage = loadBitmap(drawableName);
}
} else if (xpp.getName().equals("scale")) {
if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals("factor")) {
try {
mFactor = Float.valueOf(xpp.getAttributeValue(0));
} catch (NumberFormatException e) {
mFactor = 1.0f;
e.printStackTrace();
}
}
} else if (xpp.getName().equals("item")) {
String componentName = null;
String drawableName = null;
for (int i = 0; i < xpp.getAttributeCount(); i++) {
if (xpp.getAttributeName(i).equals("component")) {
componentName = xpp.getAttributeValue(i);
} else if (xpp.getAttributeName(i).equals("drawable")) {
drawableName = xpp.getAttributeValue(i);
}
}
if (!mPackagesDrawables.containsKey(componentName))
mPackagesDrawables.put(componentName, drawableName);
}
}
eventType = xpp.next();
}
}
mLoaded = true;
} catch (PackageManager.NameNotFoundException e) {
Log.d(TAG, "Cannot load icon pack");
} catch (XmlPullParserException e) {
Log.d(TAG, "Cannot parse icon pack appfilter.xml");
} catch (IOException e) {
e.printStackTrace();
}
}
private Bitmap loadBitmap(String drawableName) {
int id = mIconPackRes.getIdentifier(drawableName, "drawable", mPackageName);
if (id > 0) {
Drawable bitmap = mIconPackRes.getDrawable(id);
if (bitmap instanceof BitmapDrawable)
return ((BitmapDrawable) bitmap).getBitmap();
}
return null;
}
public Bitmap getIconForPackage(String appPackageName, Bitmap defaultBitmap) {
if (!mLoaded) {
load();
}
PackageManager pm = mApplication.getPackageManager();
Intent launchIntent = pm.getLaunchIntentForPackage(appPackageName);
String componentName = null;
if (launchIntent != null)
componentName = pm.getLaunchIntentForPackage(appPackageName).getComponent().toString();
String drawable = mPackagesDrawables.get(componentName);
if (drawable != null) {
Bitmap bitmap = loadBitmap(drawable);
if (bitmap == null) {
return generateBitmap(defaultBitmap);
}
return bitmap;
} else {
// Try to get a resource with the component filename
if (componentName != null) {
int start = componentName.indexOf("{") + 1;
int end = componentName.indexOf("}", start);
if (end > start) {
drawable = componentName.substring(start, end).toLowerCase(Locale.getDefault()).replace(".", "_").replace("/", "_");
if (mIconPackRes.getIdentifier(drawable, "drawable", mPackageName) > 0)
return loadBitmap(drawable);
}
}
}
return generateBitmap(defaultBitmap);
}
private Bitmap generateBitmap(Bitmap defaultBitmap) {
// No need to go through below process id defaultBitmap is null
if (defaultBitmap == null) {
return null;
}
// If no back images, return default app icon
if (mBackImages.size() == 0) {
return defaultBitmap;
}
// Get a random back image
Bitmap backImage = getMostAppropriateBackImage(defaultBitmap);
int backImageWidth = backImage.getWidth();
int backImageHeight = backImage.getHeight();
// Create a bitmap for the result
Bitmap result;
try {
result = Bitmap.createBitmap(backImageWidth, backImageHeight, Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
}
// Instantiate a canvas to combine the icon / background
Canvas canvas = new Canvas(result);
// Draw the background first
canvas.drawBitmap(backImage, 0, 0, null);
// Create rects for scaling the default bitmap
Rect srcRect = new Rect(
0,
0,
defaultBitmap.getWidth(),
defaultBitmap.getHeight()
);
float scaledWidth = mFactor * ((float) backImageWidth);
float scaledHeight = mFactor * ((float) backImageHeight);
RectF destRect = new RectF(
((float) backImageWidth) / 2.0f - scaledWidth / 2.0f,
((float) backImageHeight) / 2.0f - scaledHeight / 2.0f,
((float) backImageWidth) / 2.0f + scaledWidth / 2.0f,
((float) backImageHeight) / 2.0f + scaledHeight / 2.0f
);
// Handle mask image
if (mMaskImage != null) {
// First get mask bitmap
Bitmap mask;
try {
mask = Bitmap.createBitmap(backImageWidth, backImageHeight, Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
}
// Make a temp mask canvas
Canvas maskCanvas = new Canvas(mask);
// Draw the bitmap with mask into the result
maskCanvas.drawBitmap(
defaultBitmap, srcRect, destRect, mPaint
);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
maskCanvas.drawBitmap(mMaskImage, 0, 0, mPaint);
mPaint.setXfermode(null);
canvas.drawBitmap(mask, 0, 0, mPaint);
} else {
// Draw the scaled bitmap without mask
canvas.drawBitmap(
defaultBitmap, srcRect, destRect, mPaint
);
}
// Draw the front image
if (mFrontImage != null) {
canvas.drawBitmap(mFrontImage, 0, 0, mPaint);
}
// Return result
return result;
}
private Bitmap getMostAppropriateBackImage(Bitmap defaultBitmap) {
if (mBackImages.size() == 1) {
return mBackImages.get(0);
}
@ColorInt int defaultPaletteColor = ColorUtil.getPaletteColorFromBitmap(defaultBitmap);
float defaultHueColor = ColorUtil.getHueColorFromColor(defaultPaletteColor);
float difference = Float.MAX_VALUE;
int index = 0;
for (int i = 0; i < mBackImages.size(); i++) {
@ColorInt int backPaletteColor = ColorUtil.getPaletteColorFromBitmap(mBackImages.get(i));
float backHueColor = ColorUtil.getHueColorFromColor(backPaletteColor);
if (Math.abs(defaultHueColor - backHueColor) < difference) {
difference = Math.abs(defaultHueColor - backHueColor);
index = i;
}
}
return mBackImages.get(index);
}
}
private ArrayList<IconPack> mIconPacks = null;
public ArrayList<IconPack> getAvailableIconPacksWithIcons(boolean forceReload, Application application) {
mApplication = application;
if (mIconPacks == null || forceReload) {
mIconPacks = new ArrayList<>();
PackageManager pm = mApplication.getPackageManager();
/**
* Currently Lens Launcher supports all icon packs supported by GoLauncher / EX
* Create a set by filter the list to contain unique icon packs only
*/
List<ResolveInfo> rinfo = new ArrayList<>();
for (String launcher : mApplication.getResources().getStringArray(R.array.icon_pack_launchers)) {
rinfo.addAll(pm.queryIntentActivities(new Intent(launcher), PackageManager.GET_META_DATA));
}
for (ResolveInfo ri : rinfo) {
IconPack ip = new IconPack();
ip.mPackageName = ri.activityInfo.packageName;
ApplicationInfo ai = null;
try {
ai = pm.getApplicationInfo(ip.mPackageName, PackageManager.GET_META_DATA);
ip.mName = mApplication.getPackageManager().getApplicationLabel(ai).toString();
mIconPacks.add(ip);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
}
return mIconPacks;
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/util/LauncherUtil.java
================================================
package nickrout.lenslauncher.util;
import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
/**
* Created by rish on 5/6/16.
*/
public class LauncherUtil {
public static boolean isLauncherDefault(Application application) {
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
final ResolveInfo res = application.getPackageManager().resolveActivity(intent, 0);
if (res.activityInfo == null) {
return false;
} else if ("android".equals(res.activityInfo.packageName)) {
return false;
} else {
if (res.activityInfo.packageName.equals(application.getPackageName())) return true;
else
return false;
}
}
public static String getHomeLauncherName(Application application) {
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
final ResolveInfo res = application.getPackageManager().resolveActivity(intent, 0);
if (res.activityInfo == null) {
return "";
}
return res.activityInfo.loadLabel(application.getPackageManager()).toString();
}
public static void resetPreferredLauncherAndOpenChooser(Context context) {
PackageManager packageManager = context.getPackageManager();
ComponentName componentName = new ComponentName(context, nickrout.lenslauncher.ui.FakeLauncherActivity.class);
packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
Intent selector = new Intent(Intent.ACTION_MAIN);
selector.addCategory(Intent.CATEGORY_HOME);
selector.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(selector);
packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, PackageManager.DONT_KILL_APP);
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/util/LensCalculator.java
================================================
package nickrout.lenslauncher.util;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.RectF;
import android.util.DisplayMetrics;
import nickrout.lenslauncher.model.Grid;
/**
* Created by nickrout on 2016/04/02.
*/
public class LensCalculator {
// Algorithm for calculating equispaced grid
public static Grid calculateGrid(Context context, int screenWidth, int screenHeight, int itemCount) {
Grid grid = new Grid();
grid.setItemCount(itemCount);
int itemCountHorizontal, itemCountVertical;
if (itemCount == 0 || itemCount == 1) {
itemCountHorizontal = itemCount;
itemCountVertical = itemCount;
} else {
double optimalSquareSize = calculateOptimalSquareSize(screenWidth, screenHeight, itemCount);
itemCountHorizontal = (int) Math.ceil(screenWidth / optimalSquareSize);
itemCountVertical = (int) Math.ceil((double) itemCount / (double) itemCountHorizontal);
}
grid.setItemCountHorizontal(itemCountHorizontal);
grid.setItemCountVertical(itemCountVertical);
Settings settings = new Settings(context);
float itemSize = LensCalculator.convertDpToPixel(settings.getFloat(Settings.KEY_ICON_SIZE), context);
grid.setItemSize(itemSize);
float spacingHorizontal = (((float) screenWidth) - ((float) itemCountHorizontal * itemSize)) / ((float) (itemCountHorizontal + 1));
grid.setSpacingHorizontal(spacingHorizontal);
float spacingVertical = (((float) screenHeight) - ((float) itemCountVertical * itemSize)) / ((float) (itemCountVertical + 1));
grid.setSpacingVertical(spacingVertical);
return grid;
}
// Algorithm for calculating optimal square side length given width, height and number of items
public static double calculateOptimalSquareSize(int screenWidth, int screenHeight, int itemCount) {
// Source: http://math.stackexchange.com/questions/466198/algorithm-to-get-the-maximum-size-of-n-squares-that-fit-into-a-rectangle-with-a
double x = (double) screenWidth, y = (double) screenHeight, n = (double) itemCount;
double px = Math.ceil(Math.sqrt(n * x / y));
double sx, sy;
if(Math.floor(px * y / x) * px < n) {
sx = y / Math.ceil(px * y / x);
} else {
sx = x / px;
}
double py = Math.ceil(Math.sqrt(n * y / x));
if(Math.floor(py * x / y) * py < n) {
sy = x / Math.ceil(x * py / y);
} else {
sy = y / py;
}
return Math.max(sx, sy);
}
// Algorithm for circular distance
public static double calculateDistance(float x1, float x2, float y1, float y2) {
return Math.sqrt(Math.pow((double) (x2 - x1), 2) + Math.pow((double) (y2 - y1), 2));
}
// Algorithm for determining whether a rect is within a given lens (centered at touchX, touchY)
public static boolean isRectWithinLens(RectF rect, float touchX, float touchY, float lensDiameter) {
if (rect.left >= touchX - lensDiameter / 2.0f &&
rect.right <= touchX + lensDiameter / 2.0f &&
rect.top >= touchY - lensDiameter / 2.0f &&
rect.bottom <= touchY + lensDiameter / 2.0f) {
return true;
} else {
return false;
}
}
// Graphical Fisheye Lens algorithm for shifting
public static float shiftPoint(Context context, float lensPosition, float itemPosition, float boundary, float multiplier) {
if (lensPosition < 0) {
return itemPosition;
}
Settings settings = new Settings(context);
float shiftedPosition;
float a = Math.abs(lensPosition - itemPosition);
float b = Math.max(lensPosition, boundary - lensPosition);
float x = a / b;
float d = multiplier * settings.getFloat(Settings.KEY_DISTORTION_FACTOR);
float y = ((1.0f + d) * x) / (1.0f + (d * x));
float newDistanceFromCenter = b * y;
if (lensPosition >= itemPosition) {
shiftedPosition = lensPosition - newDistanceFromCenter;
} else {
shiftedPosition = lensPosition + newDistanceFromCenter;
}
return shiftedPosition;
}
// Graphical Fisheye Lens algorithm for scaling
public static float scalePoint(Context context, float lensPosition, float itemPosition, float itemSize, float boundary, float multiplier) {
if (lensPosition < 0) {
return itemSize;
}
Settings settings = new Settings(context);
float scaleDifference = settings.getFloat(Settings.KEY_SCALE_FACTOR) - Settings.MIN_SCALE_FACTOR;
float d = Settings.MIN_SCALE_FACTOR + scaleDifference * multiplier;
if (lensPosition >= itemPosition) {
itemPosition = itemPosition - d * (itemSize / 2.0f);
} else {
itemPosition = itemPosition + d * (itemSize / 2.0f);
}
return LensCalculator.shiftPoint(context, lensPosition, itemPosition, boundary, multiplier);
}
// Graphical Fisheye Lens algorithm for determining final scaled size
public static float calculateSquareScaledSize(float scaledPositionX, float shiftedPositionX, float scaledPositionY, float shiftedPositionY) {
return 2.0f * Math.min(Math.abs(scaledPositionX - shiftedPositionX), Math.abs(scaledPositionY - shiftedPositionY));
}
// Algorithm for calculating new rect
public static RectF calculateRect(float newCenterX, float newCenterY, float newSize) {
RectF newRect = new RectF(
newCenterX - newSize / 2.0f,
newCenterY - newSize / 2.0f,
newCenterX + newSize / 2.0f,
newCenterY + newSize / 2.0f);
return newRect;
}
// Algorithm for determining if touch point is within rect
public static boolean isInsideRect(float x, float y, RectF rect) {
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
return true;
} else {
return false;
}
}
// Algorithm for converting dp measurements to pixels
public static float convertDpToPixel(float dp, Context context) {
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
return px;
}
// Algorithm for converting pixels to dp measurements
public static float convertPixelsToDp(float px, Context context) {
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float dp = px / ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
return dp;
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/util/NightModeUtil.java
================================================
package nickrout.lenslauncher.util;
import android.support.v7.app.AppCompatDelegate;
/**
* Created by nicholasrout on 2017/01/15.
*/
public class NightModeUtil {
public static String getNightModeDisplayName(@AppCompatDelegate.NightMode int nightMode) {
switch (nightMode) {
case AppCompatDelegate.MODE_NIGHT_NO:
return "Light";
case AppCompatDelegate.MODE_NIGHT_YES:
return "Dark";
case AppCompatDelegate.MODE_NIGHT_AUTO:
return "Auto";
default:
return "Follow System";
}
}
public static @AppCompatDelegate.NightMode int getNightModeFromDisplayName(String displayName) {
switch (displayName) {
case "Light":
return AppCompatDelegate.MODE_NIGHT_NO;
case "Dark":
return AppCompatDelegate.MODE_NIGHT_YES;
case "Auto":
return AppCompatDelegate.MODE_NIGHT_AUTO;
default:
return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
}
}
}
================================================
FILE: app/src/main/java/nickrout/lenslauncher/util/Settings.java
================================================
package nickrout.lenslauncher.util;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatDelegate;
/**
* Created by nicholasrout on 2016/04/02.
*/
public class Settings {
public static final float DEFAULT_ICON_SIZE = 18.0f;
public static final float DEFAULT_DISTORTION_FACTOR = 2.5f;
public static final float DEFAULT_SCALE_FACTOR = 1.0f;
public static final long DEFAULT_ANIMATION_TIME = 200;
public static final boolean DEFAULT_VIBRATE_APP_HOVER = false;
public static final boolean DEFAULT_VIBRATE_APP_LAUNCH = true;
public static final boolean DEFAULT_SHOW_NAME_APP_HOVER = true;
public static final boolean DEFAULT_SHOW_TOUCH_SELECTION = false;
public static final boolean DEFAULT_SHOW_NEW_APP_TAG = true;
public static final String DEFAULT_BACKGROUND = "Wallpaper";
public static final String DEFAULT_BACKGROUND_COLOR = "#FFF8BBD0";
public static final String DEFAULT_HIGHLIGHT_COLOR = "#FFF50057";
public static final String DEFAULT_ICON_PACK_LABEL_NAME = "Default Icon Pack";
public static final int DEFAULT_SORT_TYPE = 0;
public static final int DEFAULT_NIGHT_MODE = AppCompatDelegate.MODE_NIGHT_NO;
// These values are for the progress bars, their real values = (MAX_VALUE / INTERVAL (eg. 2)) + MIN_VALUE
public static final int MAX_ICON_SIZE = 45;
public static final int MAX_DISTORTION_FACTOR = 9;
public static final int MAX_SCALE_FACTOR = 5;
public static final int MAX_ANIMATION_TIME = 600;
public static final int SHOW_NEW_APP_TAG_DURATION = 12 * 60 * 60 * 1000; /* An app has the new tag for twelve hours. If openCount >= 1, the new tag is not drawn. */
public static final float MIN_ICON_SIZE = 10.0f;
public static final float MIN_DISTORTION_FACTOR = 0.5f;
public static final float MIN_SCALE_FACTOR = 1.0f;
public static final long MIN_ANIMATION_TIME = 100;
public static final float DEFAULT_FLOAT = Float.MIN_VALUE;
public static final long DEFAULT_LONG = Long.MIN_VALUE;
public static final boolean DEFAULT_BOOLEAN = false;
public static final String DEFAULT_STRING = "";
public static final String KEY_ICON_SIZE = "min_icon_size";
public static final String KEY_DISTORTION_FACTOR = "distortion_factor";
public static final String KEY_SCALE_FACTOR = "scale_factor";
public static final String KEY_ANIMATION_TIME = "animation_time";
public static final String KEY_VIBRATE_APP_HOVER = "vibrate_app_hover";
public static final String KEY_VIBRATE_APP_LAUNCH = "vibrate_app_launch";
public static final String KEY_SHOW_NAME_APP_HOVER = "show_name_app_hover";
public static final String KEY_SHOW_TOUCH_SELECTION = "show_touch_selection";
public static final String KEY_SHOW_NEW_APP_TAG = "show_new_tag_app";
public static final String KEY_BACKGROUND = "background";
public static final String KEY_BACKGROUND_COLOR = "background_color";
public static final String KEY_HIGHLIGHT_COLOR = "show_touch_selection_color";
public static final String KEY_ICON_PACK_LABEL_NAME = "icon_pack_label_name";
public static final String KEY_SORT_TYPE = "sort_type";
public static final String KEY_NIGHT_MODE = "night_mode";
private Context mContext;
private SharedPreferences mPrefs;
public Settings(Context context) {
mContext = context;
}
private SharedPreferences sharedPreferences() {
if (mPrefs == null) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
}
return mPrefs;
}
public void save(String name, int value) {
sharedPreferences().edit().putInt(name, value).commit();
}
public @AppCompatDelegate.NightMode int getNightMode() {
switch (sharedPreferences().getInt(KEY_NIGHT_MODE, DEFAULT_NIGHT_MODE)) {
case AppCompatDelegate.MODE_NIGHT_AUTO:
return AppCompatDelegate.MODE_NIGHT_AUTO;
case AppCompatDelegate.MODE_NIGHT_NO:
return AppCompatDelegate.MODE_NIGHT_NO;
case AppCompatDelegate.MODE_NIGHT_YES:
return AppCompatDelegate.MODE_NIGHT_YES;
default:
return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
}
}
public void save(String name, float value) {
sharedPreferences().edit().putFloat(name, value).commit();
}
public float getFloat(String name) {
if (name.equals(KEY_ICON_SIZE)) {
if (sharedPreferences().getFloat(name, DEFAULT_ICON_SIZE) < MIN_ICON_SIZE) {
save(name, MIN_ICON_SIZE);
} else if (sharedPreferences().getFloat(name, DEFAULT_ICON_SIZE) > getMaxFloatValue(name)) {
save(name, getMaxFloatValue(name));
}
return sharedPreferences().getFloat(name, DEFAULT_ICON_SIZE);
} else if (name.equals(KEY_DISTORTION_FACTOR)) {
if (sharedPreferences().getFloat(name, DEFAULT_DISTORTION_FACTOR) < MIN_DISTORTION_FACTOR) {
save(name, MIN_DISTORTION_FACTOR);
} else if (sharedPreferences().getFloat(name, DEFAULT_DISTORTION_FACTOR) > getMaxFloatValue(name)) {
save(name, getMaxFloatValue(name));
}
return sharedPreferences().getFloat(name, DEFAULT_DISTORTION_FACTOR);
} else if (name.equals(KEY_SCALE_FACTOR)) {
if (sharedPreferences().getFloat(name, DEFAULT_SCALE_FACTOR) < MIN_SCALE_FACTOR) {
save(name, MIN_SCALE_FACTOR);
} else if (sharedPreferences().getFloat(name, DEFAULT_SCALE_FACTOR) > getMaxFloatValue(name)) {
save(name, getMaxFloatValue(name));
}
return sharedPreferences().getFloat(name, DEFAULT_SCALE_FACTOR);
} else {
return sharedPreferences().getFloat(name, DEFAULT_FLOAT);
}
}
public void save(String name, long value) {
sharedPreferences().edit().putLong(name, value).commit();
}
public long getLong(String name) {
if (name.equals(KEY_ANIMATION_TIME)) {
if (sharedPreferences().getLong(name, DEFAULT_ANIMATION_TIME) < MIN_ANIMATION_TIME) {
save(name, MIN_ANIMATION_TIME);
} else if (sharedPreferences().getLong(name, DEFAULT_ANIMATION_TIME) > getMaxLongValue(name)) {
save(name, getMaxLongValue(name));
}
return sharedPreferences().getLong(name, DEFAULT_ANIMATION_TIME);
} else {
return sharedPreferences().getLong(name, DEFAULT_LONG);
}
}
public void save(String name, String value) {
sharedPreferences().edit().putString(name, value).commit();
}
public String getString(String name) {
if (name.equals(KEY_BACKGROUND)) {
return sharedPreferences().getString(name, DEFAULT_BACKGROUND);
} else if (name.equals(KEY_BACKGROUND_COLOR)) {
return sharedPreferences().getString(name, DEFAULT_BACKGROUND_COLOR);
} else if (name.equals(KEY_HIGHLIGHT_COLOR)) {
return sharedPreferences().getString(name, DEFAULT_HIGHLIGHT_COLOR);
} else if (name.equals(KEY_ICON_PACK_LABEL_NAME)) {
return sharedPreferences().getString(name, DEFAULT_ICON_PACK_LABEL_NAME);
} else {
return sharedPreferences().getString(name, DEFAULT_STRING);
}
}
public void save(String name, boolean value) {
sharedPreferences().edit().putBoolean(name, value).commit();
}
public boolean getBoolean(String name) {
if (name.equals(KEY_VIBRATE_APP_HOVER)) {
return sharedPreferences().getBoolean(name, DEFAULT_VIBRATE_APP_HOVER);
} else if (name.equals(KEY_VIBRATE_APP_LAUNCH)) {
return sharedPreferences().getBoolean(name, DEFAULT_VIBRATE_APP_LAUNCH);
} else if (name.equals(KEY_SHOW_NAME_APP_HOVER)) {
return sharedPreferences().getBoolean(name, DEFAULT_SHOW_NAME_APP_HOVER);
} else if (name.equals(KEY_SHOW_TOUCH_SELECTION)) {
return sharedPreferences().getBoolean(name, DEFAULT_SHOW_TOUCH_SELECTION);
} else if (name.equals(KEY_SHOW_NEW_APP_TAG)) {
return sharedPreferences().getBoolean(name, DEFAULT_SHOW_NEW_APP_TAG);
} else {
return sharedPreferences().getBoolean(name, DEFAULT_BOOLEAN);
}
}
public void save(AppSorter.SortType value) {
save(KEY_SORT_TYPE, value.ordinal());
}
public AppSorter.SortType getSortType() {
int ordinal = sharedPreferences().getInt(KEY_SORT_TYPE, DEFAULT_SORT_TYPE);
return AppSorter.SortType.values()[ordinal];
}
public float getMaxFloatValue(String name) {
if (name.equals(KEY_ICON_SIZE)) {
return (float) MAX_ICON_SIZE + MIN_ICON_SIZE;
} else if (name.equals(KEY_DISTORTION_FACTOR)) {
return (float) MAX_DISTORTION_FACTOR / 2 + MIN_DISTORTION_FACTOR;
} else if (name.equals(KEY_SCALE_FACTOR)) {
return (float) MAX_SCALE_FACTOR / 2 + MIN_SCALE_FACTOR;
} else {
return DEFAULT_FLOAT;
}
}
public long getMaxLongValue(String name) {
if (name.equals(KEY_ANIMATION_TIME)) {
return (long) MAX_ANIMATION_TIME / 2 + MIN_ANIMATION_TIME;
} else {
return DEFAULT_LONG;
}
}
}
================================================
FILE: app/src/main/res/anim/fade_in.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
================================================
FILE: app/src/main/res/anim/fade_out.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="@android:integer/config_mediumAnimTime" />
================================================
FILE: app/src/main/res/anim/slide_in_left.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_shortAnimTime">
<translate
android:fromXDelta="100%p"
android:toXDelta="0" />
</set>
================================================
FILE: app/src/main/res/anim/slide_in_right.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_shortAnimTime" >
<translate
android:fromXDelta="-100%p"
android:toXDelta="0" />
</set>
================================================
FILE: app/src/main/res/anim/slide_out_left.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_shortAnimTime">
<translate
android:fromXDelta="0"
android:toXDelta="100%p" />
</set>
================================================
FILE: app/src/main/res/anim/slide_out_right.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_shortAnimTime">
<translate
android:fromXDelta="0"
android:toXDelta="-100%p" />
</set>
================================================
FILE: app/src/main/res/animator/raise.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="true"
android:state_pressed="true">
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="translationZ"
android:valueTo="4dp" />
</item>
<item>
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="translationZ"
android:valueTo="0dp" />
</item>
</selector>
================================================
FILE: app/src/main/res/drawable/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="108dp"
android:height="108dp"/>
<solid
android:color="@color/colorPrimary"/>
</shape>
================================================
FILE: app/src/main/res/drawable/ic_launcher_foreground.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108.0"
android:viewportHeight="108.0">
<path
android:pathData="M54.5,35C55.34,35 56,34.34 56,33.5C56,32.66 55.34,32 54.5,32C53.66,32 53,32.66 53,33.5C53,34.34 53.66,35 54.5,35ZM54.5,74C53.66,74 53,74.66 53,75.5C53,76.34 53.66,77 54.5,77C55.34,77 56,76.34 56,75.5C56,74.66 55.34,74 54.5,74ZM75.5,53C74.66,53 74,53.66 74,54.5C74,55.34 74.66,56 75.5,56C76.34,56 77,55.34 77,54.5C77,53.66 76.34,53 75.5,53ZM33.5,53C32.66,53 32,53.66 32,54.5C32,55.34 32.66,56 33.5,56C34.34,56 35,55.34 35,54.5C35,53.66 34.34,53 33.5,53ZM42.5,51.5C40.85,51.5 39.5,52.85 39.5,54.5C39.5,56.15 40.85,57.5 42.5,57.5C44.15,57.5 45.5,56.15 45.5,54.5C45.5,52.85 44.15,51.5 42.5,51.5ZM42.5,39.5C40.85,39.5 39.5,40.85 39.5,42.5C39.5,44.15 40.85,45.5 42.5,45.5C44.15,45.5 45.5,44.15 45.5,42.5C45.5,40.85 44.15,39.5 42.5,39.5ZM66.5,51.5C64.85,51.5 63.5,52.85 63.5,54.5C63.5,56.15 64.85,57.5 66.5,57.5C68.15,57.5 69.5,56.15 69.5,54.5C69.5,52.85 68.15,51.5 66.5,51.5ZM66.5,63.5C64.85,63.5 63.5,64.85 63.5,66.5C63.5,68.15 64.85,69.5 66.5,69.5C68.15,69.5 69.5,68.15 69.5,66.5C69.5,64.85 68.15,63.5 66.5,63.5ZM66.5,39.5C64.85,39.5 63.5,40.85 63.5,42.5C63.5,44.15 64.85,45.5 66.5,45.5C68.15,45.5 69.5,44.15 69.5,42.5C69.5,40.85 68.15,39.5 66.5,39.5ZM54.5,39.5C52.85,39.5 51.5,40.85 51.5,42.5C51.5,44.15 52.85,45.5 54.5,45.5C56.15,45.5 57.5,44.15 57.5,42.5C57.5,40.85 56.15,39.5 54.5,39.5ZM54.5,63.5C52.85,63.5 51.5,64.85 51.5,66.5C51.5,68.15 52.85,69.5 54.5,69.5C56.15,69.5 57.5,68.15 57.5,66.5C57.5,64.85 56.15,63.5 54.5,63.5ZM42.5,63.5C40.85,63.5 39.5,64.85 39.5,66.5C39.5,68.15 40.85,69.5 42.5,69.5C44.15,69.5 45.5,68.15 45.5,66.5C45.5,64.85 44.15,63.5 42.5,63.5ZM54.5,50C52.01,50 50,52.01 50,54.5C50,56.99 52.01,59 54.5,59C56.99,59 59,56.99 59,54.5C59,52.01 56.99,50 54.5,50Z"
android:fillType="evenOdd"
android:fillColor="#FFFFFF"/>
</vector>
================================================
FILE: app/src/main/res/layout/activity_about.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.AboutActivity">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="24dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
android:src="@drawable/im_about"
tools:ignore="contentDescription" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<TextView
android:id="@+id/text_view_about"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColorHighlight="@color/colorPrimary"
android:textColorLink="@color/colorAccent"
android:padding="@dimen/padding_about"/>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
================================================
FILE: app/src/main/res/layout/activity_fake_launcher.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="nickrout.lenslauncher.ui.FakeLauncherActivity">
</RelativeLayout>
================================================
FILE: app/src/main/res/layout/activity_home.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<nickrout.lenslauncher.ui.LensView
android:id="@+id/lens_view_apps"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hapticFeedbackEnabled="true"
android:visibility="invisible"/>
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/progress_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>
================================================
FILE: app/src/main/res/layout/activity_settings.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
app:tabMode="fixed"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab_sort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_fab"
android:layout_gravity="bottom|end"
android:src="@drawable/ic_sort_white_24dp"
app:fabSize="normal" />
</android.support.design.widget.CoordinatorLayout>
================================================
FILE: app/src/main/res/layout/fragment_apps.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_apps"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="80dp"
android:paddingStart="@dimen/activity_horizontal_margin_apps"
android:paddingLeft="@dimen/activity_horizontal_margin_apps"
android:paddingEnd="@dimen/activity_horizontal_margin_apps"
android:paddingRight="@dimen/activity_horizontal_margin_apps"
android:clipToPadding="false"
android:visibility="invisible"/>
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/progress_apps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>
================================================
FILE: app/src/main/res/layout/fragment_lens.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<nickrout.lenslauncher.ui.LensView
android:id="@+id/lens_view_settings"
android:layout_width="match_parent"
android:layout_height="@dimen/height_lens_preview" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorDivider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:text="@string/setting_min_icon_size" />
<TextView
android:id="@+id/value_min_icon_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textStyle="bold" />
</RelativeLayout>
<android.support.v7.widget.AppCompatSeekBar
android:id="@+id/seek_bar_min_icon_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:text="@string/setting_distortion_factor" />
<TextView
android:id="@+id/value_distortion_factor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textStyle="bold" />
</RelativeLayout>
<android.support.v7.widget.AppCompatSeekBar
android:id="@+id/seek_bar_distortion_factor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:text="@string/setting_scale_factor" />
<TextView
android:id="@+id/value_scale_factor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textStyle="bold" />
</RelativeLayout>
<android.support.v7.widget.AppCompatSeekBar
android:id="@+id/seek_bar_scale_factor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
andro
gitextract_6p3thwce/ ├── .gitignore ├── LICENSE.md ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── build.gradle.orig │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── nickrout/ │ │ └── lenslauncher/ │ │ └── ApplicationTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── AndroidManifest.xml.orig │ │ ├── java/ │ │ │ └── nickrout/ │ │ │ └── lenslauncher/ │ │ │ ├── AppsSingleton.java │ │ │ ├── LensLauncherApplication.java │ │ │ ├── adapter/ │ │ │ │ └── AppRecyclerAdapter.java │ │ │ ├── background/ │ │ │ │ ├── BackgroundChangedObservable.java │ │ │ │ ├── BroadcastReceivers.java │ │ │ │ ├── EditedObservable.java │ │ │ │ ├── LoadedObservable.java │ │ │ │ ├── NightModeObservable.java │ │ │ │ ├── SortAppsTask.java │ │ │ │ ├── UpdateAppsTask.java │ │ │ │ ├── UpdatedObservable.java │ │ │ │ └── VisibilityChangedObservable.java │ │ │ ├── model/ │ │ │ │ ├── App.java │ │ │ │ ├── AppPersistent.java │ │ │ │ └── Grid.java │ │ │ ├── ui/ │ │ │ │ ├── AboutActivity.java │ │ │ │ ├── AppsFragment.java │ │ │ │ ├── BaseActivity.java │ │ │ │ ├── FakeLauncherActivity.java │ │ │ │ ├── HomeActivity.java │ │ │ │ ├── LensFragment.java │ │ │ │ ├── LensView.java │ │ │ │ ├── SettingsActivity.java │ │ │ │ └── SettingsFragment.java │ │ │ └── util/ │ │ │ ├── AppSorter.java │ │ │ ├── AppUtil.java │ │ │ ├── BitmapUtil.java │ │ │ ├── ColorUtil.java │ │ │ ├── IconPackManager.java │ │ │ ├── LauncherUtil.java │ │ │ ├── LensCalculator.java │ │ │ ├── NightModeUtil.java │ │ │ └── Settings.java │ │ └── res/ │ │ ├── anim/ │ │ │ ├── fade_in.xml │ │ │ ├── fade_out.xml │ │ │ ├── slide_in_left.xml │ │ │ ├── slide_in_right.xml │ │ │ ├── slide_out_left.xml │ │ │ └── slide_out_right.xml │ │ ├── animator/ │ │ │ └── raise.xml │ │ ├── drawable/ │ │ │ ├── ic_launcher_background.xml │ │ │ └── ic_launcher_foreground.xml │ │ ├── layout/ │ │ │ ├── activity_about.xml │ │ │ ├── activity_fake_launcher.xml │ │ │ ├── activity_home.xml │ │ │ ├── activity_settings.xml │ │ │ ├── fragment_apps.xml │ │ │ ├── fragment_lens.xml │ │ │ ├── fragment_settings.xml │ │ │ ├── layout_pro.xml │ │ │ └── recycler_item_app.xml │ │ ├── menu/ │ │ │ ├── menu_app.xml │ │ │ └── menu_settings.xml │ │ ├── mipmap-anydpi-v26/ │ │ │ └── ic_launcher.xml │ │ ├── values/ │ │ │ ├── arrays.xml │ │ │ ├── colors.xml │ │ │ ├── dimen.xml │ │ │ ├── integers.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── values-land/ │ │ │ └── dimen.xml │ │ ├── values-night/ │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ ├── values-w640dp/ │ │ │ └── integers.xml │ │ ├── values-w820dp/ │ │ │ └── dimen.xml │ │ └── xml/ │ │ └── shortcuts.xml │ └── test/ │ └── java/ │ └── nickrout/ │ └── lenslauncher/ │ └── ExampleUnitTest.java ├── build.gradle ├── docker-compose.yml ├── docker-entrypoint.sh ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── resources/ │ └── art/ │ └── lens_launcher.sketch └── settings.gradle
SYMBOL INDEX (344 symbols across 35 files)
FILE: app/src/androidTest/java/nickrout/lenslauncher/ApplicationTest.java
class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
method ApplicationTest (line 10) | public ApplicationTest() {
FILE: app/src/main/java/nickrout/lenslauncher/AppsSingleton.java
class AppsSingleton (line 11) | public class AppsSingleton {
method AppsSingleton (line 18) | private AppsSingleton() {}
method getInstance (line 20) | public static AppsSingleton getInstance() {
method getApps (line 27) | public ArrayList<App> getApps() {
method setApps (line 36) | public void setApps(ArrayList<App> apps) {
method getAppIcons (line 40) | public ArrayList<Bitmap> getAppIcons() {
method setAppIcons (line 49) | public void setAppIcons(ArrayList<Bitmap> appIcons) {
FILE: app/src/main/java/nickrout/lenslauncher/LensLauncherApplication.java
class LensLauncherApplication (line 16) | public class LensLauncherApplication extends SugarApp implements Observer {
method onCreate (line 18) | @Override
method update (line 26) | @Override
method updateApps (line 35) | private void updateApps() {
method editApps (line 43) | private void editApps() {
FILE: app/src/main/java/nickrout/lenslauncher/adapter/AppRecyclerAdapter.java
class AppRecyclerAdapter (line 32) | public class AppRecyclerAdapter extends RecyclerView.Adapter {
method AppRecyclerAdapter (line 39) | public AppRecyclerAdapter(Context mContext, List<App> mApps) {
method getItemForPosition (line 44) | public App getItemForPosition(int position) {
method getItemCount (line 48) | @Override
method getItemId (line 53) | @Override
method onCreateViewHolder (line 58) | @Override
method onBindViewHolder (line 67) | @Override
class AppViewHolder (line 77) | public static class AppViewHolder extends RecyclerView.ViewHolder impl...
method AppViewHolder (line 97) | public AppViewHolder(View itemView, Context context) {
method setAppElement (line 103) | public void setAppElement(App app) {
method toggleAppVisibility (line 121) | public void toggleAppVisibility(App app) {
method sendChangeAppsVisibilityBroadcast (line 138) | private void sendChangeAppsVisibilityBroadcast() {
method setOnClickListeners (line 150) | public void setOnClickListeners() {
method onMenuItemClick (line 183) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/background/BackgroundChangedObservable.java
class BackgroundChangedObservable (line 5) | public class BackgroundChangedObservable extends Observable {
method getInstance (line 8) | public static BackgroundChangedObservable getInstance() {
method BackgroundChangedObservable (line 12) | private BackgroundChangedObservable() {
method updateValue (line 15) | public void updateValue(Object data) {
method update (line 22) | public void update() {
FILE: app/src/main/java/nickrout/lenslauncher/background/BroadcastReceivers.java
class BroadcastReceivers (line 10) | public class BroadcastReceivers {
class AppsUpdatedReceiver (line 12) | public static class AppsUpdatedReceiver extends BroadcastReceiver {
method onReceive (line 13) | @Override
class AppsEditedReceiver (line 19) | public static class AppsEditedReceiver extends BroadcastReceiver {
method onReceive (line 20) | @Override
class AppsVisibilityChangedReceiver (line 26) | public static class AppsVisibilityChangedReceiver extends BroadcastRec...
method onReceive (line 27) | @Override
class AppsLoadedReceiver (line 33) | public static class AppsLoadedReceiver extends BroadcastReceiver {
method onReceive (line 34) | @Override
class BackgroundChangedReceiver (line 40) | public static class BackgroundChangedReceiver extends BroadcastReceiver {
method onReceive (line 41) | @Override
class NightModeReceiver (line 47) | public static class NightModeReceiver extends BroadcastReceiver {
method onReceive (line 48) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/background/EditedObservable.java
class EditedObservable (line 8) | public class EditedObservable extends Observable {
method getInstance (line 11) | public static EditedObservable getInstance() {
method EditedObservable (line 15) | private EditedObservable() {
method updateValue (line 18) | public void updateValue(Object data) {
method update (line 25) | public void update() {
FILE: app/src/main/java/nickrout/lenslauncher/background/LoadedObservable.java
class LoadedObservable (line 8) | public class LoadedObservable extends Observable {
method getInstance (line 11) | public static LoadedObservable getInstance() {
method LoadedObservable (line 15) | private LoadedObservable() {
method updateValue (line 18) | public void updateValue(Object data) {
method update (line 25) | public void update() {
FILE: app/src/main/java/nickrout/lenslauncher/background/NightModeObservable.java
class NightModeObservable (line 9) | public class NightModeObservable extends Observable {
method getInstance (line 12) | public static NightModeObservable getInstance() {
method NightModeObservable (line 16) | private NightModeObservable() {
method updateValue (line 19) | public void updateValue(Object data) {
method update (line 26) | public void update() {
FILE: app/src/main/java/nickrout/lenslauncher/background/SortAppsTask.java
class SortAppsTask (line 19) | public class SortAppsTask extends AsyncTask<Void, Void, Void> {
method SortAppsTask (line 28) | public SortAppsTask(Context context,
method onPreExecute (line 35) | @Override
method doInBackground (line 40) | @Override
method onPostExecute (line 57) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/background/UpdateAppsTask.java
class UpdateAppsTask (line 20) | public class UpdateAppsTask extends AsyncTask<Void, Void, Void> {
method UpdateAppsTask (line 30) | public UpdateAppsTask(PackageManager packageManager,
method onPreExecute (line 39) | @Override
method doInBackground (line 44) | @Override
method onPostExecute (line 65) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/background/UpdatedObservable.java
class UpdatedObservable (line 8) | public class UpdatedObservable extends Observable {
method getInstance (line 11) | public static UpdatedObservable getInstance() {
method UpdatedObservable (line 15) | private UpdatedObservable() {
method updateValue (line 18) | public void updateValue(Object data) {
method update (line 25) | public void update() {
FILE: app/src/main/java/nickrout/lenslauncher/background/VisibilityChangedObservable.java
class VisibilityChangedObservable (line 5) | public class VisibilityChangedObservable extends Observable {
method getInstance (line 8) | public static VisibilityChangedObservable getInstance() {
method VisibilityChangedObservable (line 12) | private VisibilityChangedObservable() {
method updateValue (line 15) | public void updateValue(Object data) {
method update (line 22) | public void update() {
FILE: app/src/main/java/nickrout/lenslauncher/model/App.java
class App (line 9) | public class App {
method App (line 20) | public App() {
method getId (line 23) | public int getId() {
method setId (line 27) | public void setId(int mId) {
method getLabel (line 31) | public CharSequence getLabel() {
method setLabel (line 35) | public void setLabel(CharSequence label) {
method getPackageName (line 39) | public CharSequence getPackageName() {
method setPackageName (line 43) | public void setPackageName(CharSequence packageName) {
method getName (line 47) | public CharSequence getName() {
method setName (line 51) | public void setName(CharSequence name) {
method getIconResId (line 55) | public int getIconResId() {
method setIconResId (line 59) | public void setIconResId(int iconResId) {
method getIcon (line 63) | public Bitmap getIcon() {
method setIcon (line 67) | public void setIcon(Bitmap icon) {
method getInstallDate (line 71) | public long getInstallDate() {
method setInstallDate (line 75) | public void setInstallDate(long mInstallDate) {
method getPaletteColor (line 79) | public int getPaletteColor() {
method setPaletteColor (line 83) | public void setPaletteColor(int paletteColor) {
method toString (line 87) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/model/AppPersistent.java
class AppPersistent (line 11) | public class AppPersistent extends SugarRecord {
method AppPersistent (line 16) | public AppPersistent() {
method AppPersistent (line 30) | public AppPersistent(String packageName, String name, long openCount, ...
method getPackageName (line 39) | public String getPackageName() {
method setPackageName (line 43) | public void setPackageName(String packageName) {
method getName (line 49) | public String getName() {
method setName (line 53) | public void setName(String name) {
method getIdentifier (line 59) | public String getIdentifier() {
method getOpenCount (line 63) | public long getOpenCount() {
method setOpenCount (line 67) | public void setOpenCount(long openCount) {
method getOrderNumber (line 71) | public int getOrderNumber() {
method setOrderNumber (line 75) | public void setOrderNumber(int orderNumber) {
method isAppVisible (line 79) | public boolean isAppVisible() {
method setAppVisible (line 83) | public void setAppVisible(boolean appVisible) {
method toString (line 87) | @Override
method generateIdentifier (line 99) | public static String generateIdentifier(String packageName, String nam...
method incrementAppCount (line 103) | public static void incrementAppCount(String packageName, String name) {
method setAppOrderNumber (line 115) | public static void setAppOrderNumber(String packageName, String name, ...
method getAppVisibility (line 127) | public static boolean getAppVisibility(String packageName, String name) {
method setAppVisibility (line 137) | public static void setAppVisibility(String packageName, String name, b...
method getAppOpenCount (line 149) | public static long getAppOpenCount(String packageName, String name) {
FILE: app/src/main/java/nickrout/lenslauncher/model/Grid.java
class Grid (line 6) | public class Grid {
method Grid (line 15) | public Grid() {}
method getItemCount (line 17) | public int getItemCount() {
method setItemCount (line 21) | public void setItemCount(int itemCount) {
method getItemCountHorizontal (line 25) | public int getItemCountHorizontal() {
method setItemCountHorizontal (line 29) | public void setItemCountHorizontal(int itemCountHorizontal) {
method getItemCountVertical (line 33) | public int getItemCountVertical() {
method setItemCountVertical (line 37) | public void setItemCountVertical(int itemCountVertical) {
method getItemSize (line 41) | public float getItemSize() {
method setItemSize (line 45) | public void setItemSize(float itemSize) {
method getSpacingHorizontal (line 49) | public float getSpacingHorizontal() {
method setSpacingHorizontal (line 53) | public void setSpacingHorizontal(float spacingHorizontal) {
method getSpacingVertical (line 57) | public float getSpacingVertical() {
method setSpacingVertical (line 61) | public void setSpacingVertical(float spacingVertical) {
method toString (line 65) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/ui/AboutActivity.java
class AboutActivity (line 29) | public class AboutActivity extends BaseActivity implements Observer {
method onCreate (line 45) | @Override
method circularRevealAboutImage (line 63) | private void circularRevealAboutImage() {
method setupViews (line 79) | private void setupViews() {
method onBackPressed (line 84) | @Override
method finish (line 89) | @Override
method onOptionsItemSelected (line 95) | @Override
method update (line 105) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/ui/AppsFragment.java
class AppsFragment (line 32) | public class AppsFragment extends Fragment implements SettingsActivity.A...
method AppsFragment (line 46) | public AppsFragment() {
method newInstance (line 49) | public static AppsFragment newInstance() {
method onCreateView (line 55) | @Nullable
method onAttach (line 65) | @Override
method sendEditAppsBroadcast (line 73) | private void sendEditAppsBroadcast() {
method setupRecycler (line 81) | private void setupRecycler(ArrayList<App> apps) {
method onDefaultsReset (line 98) | @Override
method onAppsUpdated (line 106) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/ui/BaseActivity.java
class BaseActivity (line 19) | public class BaseActivity extends AppCompatActivity {
method onCreate (line 23) | @Override
method setContentView (line 32) | @Override
method setTaskDescription (line 38) | private void setTaskDescription() {
method updateNightMode (line 49) | protected void updateNightMode() {
FILE: app/src/main/java/nickrout/lenslauncher/ui/FakeLauncherActivity.java
class FakeLauncherActivity (line 8) | public class FakeLauncherActivity extends AppCompatActivity {
method onCreate (line 9) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/ui/HomeActivity.java
class HomeActivity (line 32) | public class HomeActivity extends BaseActivity implements Observer {
method onCreate (line 46) | @Override
method onResume (line 62) | @Override
method setupTransparentSystemBarsForLollipop (line 72) | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
method setBackground (line 88) | private void setBackground() {
method assignApps (line 92) | private void assignApps(ArrayList<App> apps, ArrayList<Bitmap> appIcon...
method removeHiddenApps (line 104) | private void removeHiddenApps() {
method onBackPressed (line 115) | @Override
method onDestroy (line 120) | @Override
method update (line 126) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/ui/LensFragment.java
class LensFragment (line 22) | public class LensFragment extends Fragment implements SettingsActivity.L...
method LensFragment (line 55) | public LensFragment() {
method newInstance (line 58) | public static LensFragment newInstance() {
method onCreateView (line 64) | @Nullable
method onAttach (line 75) | @Override
method setupViews (line 83) | private void setupViews() {
method assignValues (line 162) | private void assignValues() {
method onDefaultsReset (line 177) | @Override
method resetToDefault (line 183) | private void resetToDefault() {
FILE: app/src/main/java/nickrout/lenslauncher/ui/LensView.java
class LensView (line 37) | public class LensView extends View {
type DrawType (line 72) | public enum DrawType {
method setDrawType (line 79) | public void setDrawType(DrawType drawType) {
method LensView (line 84) | public LensView(Context context) {
method LensView (line 89) | public LensView(Context context, AttributeSet attrs) {
method LensView (line 94) | public LensView(Context context, AttributeSet attrs, int defStyle) {
method setApps (line 99) | public void setApps(ArrayList<App> apps, ArrayList<Bitmap> appIcons) {
method setPackageManager (line 105) | public void setPackageManager(PackageManager packageManager) {
method init (line 109) | private void init() {
method fitSystemWindows (line 120) | @Override
method setupPaints (line 126) | private void setupPaints() {
method onDraw (line 163) | @Override
method onTouchEvent (line 186) | @Override
method drawWorkspaceBackground (line 249) | private void drawWorkspaceBackground(Canvas canvas) {
method drawTouchSelection (line 257) | private void drawTouchSelection(Canvas canvas) {
method drawGrid (line 261) | private void drawGrid(Canvas canvas, int itemCount) {
method drawAppIcon (line 343) | private void drawAppIcon(Canvas canvas, RectF rect, int index) {
method drawCircle (line 361) | private void drawCircle(Canvas canvas, RectF rect) {
method drawAppName (line 365) | private void drawAppName(Canvas canvas, RectF rect) {
method drawNewAppTag (line 374) | private void drawNewAppTag(Canvas canvas, RectF rect) {
method performHoverVibration (line 383) | private void performHoverVibration() {
method performLaunchVibration (line 396) | private void performLaunchVibration() {
method launchApp (line 404) | private void launchApp() {
class LensAnimation (line 417) | private class LensAnimation extends Animation {
method LensAnimation (line 421) | public LensAnimation(boolean show) {
method applyTransformation (line 458) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/ui/SettingsActivity.java
class SettingsActivity (line 50) | public class SettingsActivity extends BaseActivity
method onSortClicked (line 71) | @OnClick(R.id.fab_sort)
type LensInterface (line 86) | public interface LensInterface {
method onDefaultsReset (line 87) | void onDefaultsReset();
method setLensInterface (line 90) | public void setLensInterface(LensInterface lensInterface) {
type AppsInterface (line 94) | public interface AppsInterface {
method onDefaultsReset (line 95) | void onDefaultsReset();
method onAppsUpdated (line 96) | void onAppsUpdated(ArrayList<App> apps);
method setAppsInterface (line 99) | public void setAppsInterface(AppsInterface appsInterface) {
type SettingsInterface (line 103) | public interface SettingsInterface {
method onDefaultsReset (line 104) | void onDefaultsReset();
method onValuesUpdated (line 105) | void onValuesUpdated();
method setSettingsInterface (line 108) | public void setSettingsInterface(SettingsInterface settingsInterface) {
method onCreate (line 112) | @Override
method onCreateOptionsMenu (line 148) | @Override
method onOptionsItemSelected (line 155) | @Override
method update (line 199) | @Override
method sendUpdateAppsBroadcast (line 211) | private void sendUpdateAppsBroadcast() {
method sendEditAppsBroadcast (line 216) | private void sendEditAppsBroadcast() {
method sendBackgroundChangedBroadcast (line 221) | private void sendBackgroundChangedBroadcast() {
method sendNightModeBroadcast (line 226) | public void sendNightModeBroadcast() {
method showSortTypeDialog (line 231) | private void showSortTypeDialog() {
method showIconPackDialog (line 254) | public void showIconPackDialog() {
method showHomeLauncherChooser (line 284) | public void showHomeLauncherChooser() {
method showNightModeChooser (line 288) | public void showNightModeChooser() {
method showBackgroundDialog (line 316) | public void showBackgroundDialog() {
method showWallpaperPicker (line 350) | public void showWallpaperPicker() {
method showBackgroundColorDialog (line 355) | public void showBackgroundColorDialog() {
method showHighlightColorDialog (line 369) | public void showHighlightColorDialog() {
method onColorSelection (line 383) | @Override
method onColorChooserDismissed (line 398) | @Override
method dismissSortTypeDialog (line 402) | private void dismissSortTypeDialog() {
method dismissIconPackDialog (line 408) | private void dismissIconPackDialog() {
method dismissNightModeDialog (line 414) | private void dismissNightModeDialog() {
method dismissBackgroundDialog (line 420) | private void dismissBackgroundDialog() {
method dismissAllDialogs (line 426) | private void dismissAllDialogs() {
method onDestroy (line 434) | @Override
method onBackPressed (line 441) | @Override
method finish (line 446) | @Override
class FragmentPagerAdapter (line 452) | private class FragmentPagerAdapter extends FragmentStatePagerAdapter {
method FragmentPagerAdapter (line 458) | public FragmentPagerAdapter(FragmentManager fragmentManager, Context...
method getItem (line 463) | @Override
method getCount (line 476) | @Override
method getPageTitle (line 481) | @Override
FILE: app/src/main/java/nickrout/lenslauncher/ui/SettingsFragment.java
class SettingsFragment (line 28) | public class SettingsFragment extends Fragment implements SettingsActivi...
method onHomeLauncherClick (line 32) | @OnClick(R.id.layout_home_launcher)
method onIconPackClick (line 40) | @OnClick(R.id.layout_icon_pack)
method onNightModeClick (line 48) | @OnClick(R.id.layout_night_mode)
method onBackgroundClick (line 56) | @OnClick(R.id.layout_background)
method onHighlightColorClick (line 67) | @OnClick(R.id.layout_highlight_color)
method SettingsFragment (line 95) | public SettingsFragment() {
method newInstance (line 98) | public static SettingsFragment newInstance() {
method onCreateView (line 104) | @Nullable
method onAttach (line 115) | @Override
method setupViews (line 123) | private void setupViews() {
method assignValues (line 156) | private void assignValues() {
method showIconPackDialog (line 189) | private void showIconPackDialog() {
method showHomeLauncherChooser (line 195) | private void showHomeLauncherChooser() {
method showNightModeChooser (line 201) | private void showNightModeChooser() {
method showBackgroundDialog (line 207) | private void showBackgroundDialog() {
method showHighlightColorDialog (line 213) | private void showHighlightColorDialog() {
method onDefaultsReset (line 219) | @Override
method onValuesUpdated (line 225) | @Override
method resetToDefault (line 230) | private void resetToDefault() {
FILE: app/src/main/java/nickrout/lenslauncher/util/AppSorter.java
class AppSorter (line 14) | public class AppSorter {
type SortType (line 16) | public enum SortType {
method SortType (line 28) | SortType(int displayNameResId) {
method getDisplayNameResId (line 32) | public int getDisplayNameResId() {
method sort (line 37) | public static void sort(ArrayList<App> apps, SortType sortType) {
method sortByLabelAscending (line 69) | private static void sortByLabelAscending(ArrayList<App> apps) {
method sortByLabelDescending (line 78) | private static void sortByLabelDescending(ArrayList<App> apps) {
method sortByInstallDateAscending (line 83) | private static void sortByInstallDateAscending(ArrayList<App> apps) {
method sortByInstallDateDescending (line 97) | private static void sortByInstallDateDescending(ArrayList<App> apps) {
method sortByOpenCountAscending (line 102) | private static void sortByOpenCountAscending(ArrayList<App> apps) {
method sortByOpenCountDescending (line 120) | private static void sortByOpenCountDescending(ArrayList<App> apps) {
method sortByIconColorAscending (line 125) | private static void sortByIconColorAscending(ArrayList<App> apps) {
method sortByIconColorDescending (line 142) | private static void sortByIconColorDescending(ArrayList<App> apps) {
FILE: app/src/main/java/nickrout/lenslauncher/util/AppUtil.java
class AppUtil (line 30) | public class AppUtil {
method getApps (line 35) | public static ArrayList<App> getApps(
method launchComponent (line 85) | public static void launchComponent(Context context, String packageName...
method getLauncherOptionsBundle (line 114) | private static Bundle getLauncherOptionsBundle(Context context, View s...
FILE: app/src/main/java/nickrout/lenslauncher/util/BitmapUtil.java
class BitmapUtil (line 16) | public class BitmapUtil {
method drawableToBitmap (line 20) | public static Bitmap drawableToBitmap (Drawable drawable) {
method resIdToBitmap (line 46) | public static Bitmap resIdToBitmap(Resources res, int resId) {
method packageNameToResId (line 61) | public static int packageNameToResId(PackageManager packageManager, St...
method packageNameToBitmap (line 72) | public static Bitmap packageNameToBitmap(PackageManager packageManager...
method packageNameToBitmap (line 85) | public static Bitmap packageNameToBitmap(Context context, PackageManag...
FILE: app/src/main/java/nickrout/lenslauncher/util/ColorUtil.java
class ColorUtil (line 13) | public class ColorUtil {
method getPaletteColorFromApp (line 15) | public static @ColorInt int getPaletteColorFromApp(App app) {
method getPaletteColorFromBitmap (line 19) | public static @ColorInt int getPaletteColorFromBitmap(Bitmap bitmap) {
method getHueColorFromApp (line 41) | public static float getHueColorFromApp(App app) {
method getHueColorFromColor (line 45) | public static float getHueColorFromColor(@ColorInt int color) {
FILE: app/src/main/java/nickrout/lenslauncher/util/IconPackManager.java
class IconPackManager (line 38) | public class IconPackManager {
class IconPack (line 44) | public class IconPack {
method IconPack (line 46) | public IconPack() {
method load (line 69) | public void load() {
method loadBitmap (line 152) | private Bitmap loadBitmap(String drawableName) {
method getIconForPackage (line 162) | public Bitmap getIconForPackage(String appPackageName, Bitmap defaul...
method generateBitmap (line 194) | private Bitmap generateBitmap(Bitmap defaultBitmap) {
method getMostAppropriateBackImage (line 268) | private Bitmap getMostAppropriateBackImage(Bitmap defaultBitmap) {
method getAvailableIconPacksWithIcons (line 290) | public ArrayList<IconPack> getAvailableIconPacksWithIcons(boolean forc...
FILE: app/src/main/java/nickrout/lenslauncher/util/LauncherUtil.java
class LauncherUtil (line 13) | public class LauncherUtil {
method isLauncherDefault (line 15) | public static boolean isLauncherDefault(Application application) {
method getHomeLauncherName (line 30) | public static String getHomeLauncherName(Application application) {
method resetPreferredLauncherAndOpenChooser (line 40) | public static void resetPreferredLauncherAndOpenChooser(Context contex...
FILE: app/src/main/java/nickrout/lenslauncher/util/LensCalculator.java
class LensCalculator (line 13) | public class LensCalculator {
method calculateGrid (line 16) | public static Grid calculateGrid(Context context, int screenWidth, int...
method calculateOptimalSquareSize (line 41) | public static double calculateOptimalSquareSize(int screenWidth, int s...
method calculateDistance (line 61) | public static double calculateDistance(float x1, float x2, float y1, f...
method isRectWithinLens (line 66) | public static boolean isRectWithinLens(RectF rect, float touchX, float...
method shiftPoint (line 78) | public static float shiftPoint(Context context, float lensPosition, fl...
method scalePoint (line 99) | public static float scalePoint(Context context, float lensPosition, fl...
method calculateSquareScaledSize (line 115) | public static float calculateSquareScaledSize(float scaledPositionX, f...
method calculateRect (line 120) | public static RectF calculateRect(float newCenterX, float newCenterY, ...
method isInsideRect (line 130) | public static boolean isInsideRect(float x, float y, RectF rect) {
method convertDpToPixel (line 139) | public static float convertDpToPixel(float dp, Context context) {
method convertPixelsToDp (line 147) | public static float convertPixelsToDp(float px, Context context) {
FILE: app/src/main/java/nickrout/lenslauncher/util/NightModeUtil.java
class NightModeUtil (line 9) | public class NightModeUtil {
method getNightModeDisplayName (line 11) | public static String getNightModeDisplayName(@AppCompatDelegate.NightM...
method getNightModeFromDisplayName (line 24) | public static @AppCompatDelegate.NightMode int getNightModeFromDisplay...
FILE: app/src/main/java/nickrout/lenslauncher/util/Settings.java
class Settings (line 11) | public class Settings {
method Settings (line 66) | public Settings(Context context) {
method sharedPreferences (line 70) | private SharedPreferences sharedPreferences() {
method save (line 77) | public void save(String name, int value) {
method getNightMode (line 81) | public @AppCompatDelegate.NightMode int getNightMode() {
method save (line 94) | public void save(String name, float value) {
method getFloat (line 98) | public float getFloat(String name) {
method save (line 125) | public void save(String name, long value) {
method getLong (line 129) | public long getLong(String name) {
method save (line 142) | public void save(String name, String value) {
method getString (line 146) | public String getString(String name) {
method save (line 161) | public void save(String name, boolean value) {
method getBoolean (line 165) | public boolean getBoolean(String name) {
method save (line 181) | public void save(AppSorter.SortType value) {
method getSortType (line 185) | public AppSorter.SortType getSortType() {
method getMaxFloatValue (line 190) | public float getMaxFloatValue(String name) {
method getMaxLongValue (line 202) | public long getMaxLongValue(String name) {
FILE: app/src/test/java/nickrout/lenslauncher/ExampleUnitTest.java
class ExampleUnitTest (line 10) | public class ExampleUnitTest {
method addition_isCorrect (line 11) | @Test
Condensed preview — 87 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (247K chars).
[
{
"path": ".gitignore",
"chars": 485,
"preview": "# built application files\n*.apk\n*.ap_\n\n# files for the dex VM\n*.dex\n\n# Java class files\n*.class\n\n# generated files\nbin/\n"
},
{
"path": "LICENSE.md",
"chars": 11343,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 2346,
"preview": "# Lens Launcher\n\nLens Launcher is a unique, efficient way to browse and launch your apps.\n\n*>\n <!ELEMENT dimen (#PCD"
},
{
"path": "app/src/main/res/values/integers.xml",
"chars": 108,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <integer name=\"columns_apps\">1</integer>\n</resources>"
},
{
"path": "app/src/main/res/values/strings.xml",
"chars": 5285,
"preview": "<resources>\n\n <!-- App & Activity Strings -->\n <string name=\"app_name\">Lens Launcher</string>\n <string name=\"ac"
},
{
"path": "app/src/main/res/values/styles.xml",
"chars": 1526,
"preview": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n\n <!-- App Theme -->\n <style name=\"AppTheme\" parent=\"Th"
},
{
"path": "app/src/main/res/values-land/dimen.xml",
"chars": 256,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <!-- Lens Dimensions -->\n <dimen name=\"offset_system_vertical"
},
{
"path": "app/src/main/res/values-night/colors.xml",
"chars": 205,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <!-- View Colors -->\n <color name=\"colorCircles\">@color/color"
},
{
"path": "app/src/main/res/values-night/styles.xml",
"chars": 135,
"preview": "<resources>\n\n <!-- App Bar Themes -->\n <style name=\"AppTheme.PopupOverlay\" parent=\"ThemeOverlay.AppCompat.Dark\" />"
},
{
"path": "app/src/main/res/values-w640dp/integers.xml",
"chars": 108,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <integer name=\"columns_apps\">2</integer>\n</resources>"
},
{
"path": "app/src/main/res/values-w820dp/dimen.xml",
"chars": 207,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <!-- General -->\n <dimen name=\"activity_horizontal_margin\">64"
},
{
"path": "app/src/main/res/xml/shortcuts.xml",
"chars": 1109,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shortcuts\n xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <"
},
{
"path": "app/src/test/java/nickrout/lenslauncher/ExampleUnitTest.java",
"chars": 314,
"preview": "package nickrout.lenslauncher;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * To work on unit tests,"
},
{
"path": "build.gradle",
"chars": 357,
"preview": "buildscript {\n repositories {\n google()\n mavenCentral()\n }\n dependencies {\n classpath 'com"
},
{
"path": "docker-compose.yml",
"chars": 240,
"preview": "version: '2'\nservices:\n gradle:\n image: openjdk\n working_dir: /app\n environment:\n - ANDROID_HOME=/app/and"
},
{
"path": "docker-entrypoint.sh",
"chars": 1416,
"preview": "#! /bin/bash\n\nset -e;\n\ncd /app;\n\n# Ensure Android SDK is installed\nif [ ! -d /app/android-studio ]; then\n echo \"Android"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 231,
"preview": "#Wed Jan 31 16:09:16 SAST 2024\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\:/"
},
{
"path": "gradle.properties",
"chars": 886,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "gradlew",
"chars": 4971,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "gradlew.bat",
"chars": 2404,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
},
{
"path": "settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
}
]
// ... and 2 more files (download for full content)
About this extraction
This page contains the full source code of the nicholasrout/lens-launcher GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 87 files (226.9 KB), approximately 52.7k tokens, and a symbol index with 344 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.