Reformat code to match intellij style

This commit is contained in:
SVolf 2023-09-23 10:38:21 +07:00 committed by TrianguloY
parent 836d879a4f
commit dcf8e580a9
248 changed files with 49825 additions and 48471 deletions

View file

@ -19,7 +19,7 @@ package com.google.android.vending.licensing;
import com.google.android.vending.licensing.util.Base64;
import com.google.android.vending.licensing.util.Base64DecoderException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.spec.KeySpec;
@ -43,8 +43,8 @@ public class AESObfuscator implements Obfuscator {
{16, 74, 71, -80, 32, 101, -47, 72, 117, -14, 0, -29, 70, 65, -12, 74};
private static final String header = "com.android.vending.licensing.AESObfuscator-1|";
private Cipher mEncryptor;
private Cipher mDecryptor;
private final Cipher mEncryptor;
private final Cipher mDecryptor;
/**
* @param salt an array of random bytes to use for each (un)obfuscation
@ -75,9 +75,7 @@ public class AESObfuscator implements Obfuscator {
}
try {
// Header is appended as an integrity check
return Base64.encode(mEncryptor.doFinal((header + key + original).getBytes(UTF8)));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Invalid environment", e);
return Base64.encode(mEncryptor.doFinal((header + key + original).getBytes(StandardCharsets.UTF_8)));
} catch (GeneralSecurityException e) {
throw new RuntimeException("Invalid environment", e);
}
@ -88,7 +86,7 @@ public class AESObfuscator implements Obfuscator {
return null;
}
try {
String result = new String(mDecryptor.doFinal(Base64.decode(obfuscated)), UTF8);
String result = new String(mDecryptor.doFinal(Base64.decode(obfuscated)), StandardCharsets.UTF_8);
// Check for presence of header. This serves as a final integrity check, for cases
// where the block size is correct during decryption.
int headerIndex = result.indexOf(header + key);
@ -96,15 +94,13 @@ public class AESObfuscator implements Obfuscator {
throw new ValidationException("Header not found (invalid data or key)" + ":" +
obfuscated);
}
return result.substring(header.length()+key.length(), result.length());
return result.substring(header.length() + key.length());
} catch (Base64DecoderException e) {
throw new ValidationException(e.getMessage() + ":" + obfuscated);
} catch (IllegalBlockSizeException e) {
throw new ValidationException(e.getMessage() + ":" + obfuscated);
} catch (BadPaddingException e) {
throw new ValidationException(e.getMessage() + ":" + obfuscated);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Invalid environment", e);
}
}
}

View file

@ -17,9 +17,7 @@
package com.google.android.vending.licensing;
import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings;
import android.util.Log;
import net.pierrox.lightning_launcher.data.FileUtils;
@ -37,10 +35,10 @@ public class JSONDataObfuscator {
-54, -77, 123, -12, -72, -99, 10, 0, 73
};
private File mFile;
private String mPackageName;
private JSONObject mData;
private final File mFile;
private final String mPackageName;
private final Obfuscator mObfuscator;
private JSONObject mData;
public JSONDataObfuscator(Context context) {

View file

@ -16,11 +16,6 @@
package com.google.android.vending.licensing;
import com.android.vending.licensing.ILicenseResultListener;
import com.android.vending.licensing.ILicensingService;
import com.google.android.vending.licensing.util.Base64;
import com.google.android.vending.licensing.util.Base64DecoderException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@ -31,6 +26,11 @@ import android.os.HandlerThread;
import android.os.IBinder;
import android.os.RemoteException;
import com.android.vending.licensing.ILicenseResultListener;
import com.android.vending.licensing.ILicensingService;
import com.google.android.vending.licensing.util.Base64;
import com.google.android.vending.licensing.util.Base64DecoderException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
@ -64,21 +64,19 @@ public class LicenseChecker implements ServiceConnection {
private static final SecureRandom RANDOM = new SecureRandom();
private static final boolean DEBUG_LICENSE_ERROR = false;
private ILicensingService mService;
private PublicKey mPublicKey;
private final PublicKey mPublicKey;
private final Context mContext;
private final Policy mPolicy;
/**
* A handler for running tasks on a background thread. We don't want license
* processing to block the UI thread.
*/
private Handler mHandler;
private final Handler mHandler;
private final String mPackageName;
private final String mVersionCode;
private final Set<LicenseValidator> mChecksInProgress = new HashSet<LicenseValidator>();
private final Queue<LicenseValidator> mPendingChecks = new LinkedList<LicenseValidator>();
private ILicensingService mService;
/**
* @param context a Context
@ -122,6 +120,23 @@ public class LicenseChecker implements ServiceConnection {
}
}
/**
* Get version code for the application package name.
*
* @param context
* @param packageName application package name
* @return the version code or empty string if package not found
*/
private static String getVersionCode(Context context, String packageName) {
try {
return String.valueOf(context.getPackageManager().getPackageInfo(packageName, 0).
versionCode);
} catch (NameNotFoundException e) {
// Log.e(TAG, "Package not found. could not get version code.");
return "";
}
}
/**
* Checks if the user should have access to the app. Binds the service if necessary.
* <p>
@ -131,6 +146,7 @@ public class LicenseChecker implements ServiceConnection {
* <p>
* source string: "com.android.vending.licensing.ILicensingService"
* <p>
*
* @param callback
*/
public synchronized void checkAccess(LicenseCheckerCallback callback) {
@ -195,10 +211,88 @@ public class LicenseChecker implements ServiceConnection {
}
}
private class ResultListener extends ILicenseResultListener.Stub {
private final LicenseValidator mValidator;
private Runnable mOnTimeout;
public synchronized void onServiceConnected(ComponentName name, IBinder service) {
mService = ILicensingService.Stub.asInterface(service);
runChecks();
}
public synchronized void onServiceDisconnected(ComponentName name) {
// Called when the connection with the service has been
// unexpectedly disconnected. That is, Market crashed.
// If there are any checks in progress, the timeouts will handle them.
// Log.w(TAG, "Service unexpectedly disconnected.");
mService = null;
}
/**
* Generates policy response for service connection errors, as a result of
* disconnections or timeouts.
*/
private synchronized void handleServiceConnectionError(LicenseValidator validator) {
mPolicy.processServerResponse(Policy.RETRY, null);
if (mPolicy.allowAccess()) {
validator.getCallback().allow(Policy.RETRY);
} else {
validator.getCallback().dontAllow(Policy.RETRY);
}
}
/**
* Generates policy response for no service connection error (no Google Play service)
*/
private synchronized void handleNoServiceConnectionError(LicenseValidator validator) {
mPolicy.processServerResponse(Policy.NO_SERVICE, null);
if (mPolicy.allowAccess()) {
validator.getCallback().allow(Policy.NO_SERVICE);
} else {
validator.getCallback().dontAllow(Policy.NO_SERVICE);
}
}
/**
* Unbinds service if necessary and removes reference to it.
*/
private void cleanupService() {
if (mService != null) {
try {
mContext.unbindService(this);
} catch (IllegalArgumentException e) {
// Somehow we've already been unbound. This is a non-fatal
// error.
// Log.e(TAG, "Unable to unbind from licensing service (already unbound)");
}
mService = null;
}
}
/**
* Inform the library that the context is about to be destroyed, so that any
* open connections can be cleaned up.
* <p>
* Failure to call this method can result in a crash under certain
* circumstances, such as during screen rotation if an Activity requests the
* license check or when the user exits the application.
*/
public synchronized void onDestroy() {
cleanupService();
mHandler.getLooper().quit();
}
/**
* Generates a nonce (number used once).
*/
private int generateNonce() {
return RANDOM.nextInt();
}
private class ResultListener extends ILicenseResultListener.Stub {
private static final int ERROR_CONTACTING_SERVER = 0x101;
private static final int ERROR_INVALID_PACKAGE_NAME = 0x102;
private static final int ERROR_NON_MATCHING_UID = 0x103;
private final LicenseValidator mValidator;
private final Runnable mOnTimeout;
public ResultListener(LicenseValidator validator) {
mValidator = validator;
mOnTimeout = new Runnable() {
@ -211,10 +305,6 @@ public class LicenseChecker implements ServiceConnection {
startTimeout();
}
private static final int ERROR_CONTACTING_SERVER = 0x101;
private static final int ERROR_INVALID_PACKAGE_NAME = 0x102;
private static final int ERROR_NON_MATCHING_UID = 0x103;
// Runs in IPC thread pool. Post it to the Handler, so we can guarantee
// either this or the timeout runs.
public void verifyLicense(final int responseCode, final String signedData,
@ -272,93 +362,4 @@ public class LicenseChecker implements ServiceConnection {
mHandler.removeCallbacks(mOnTimeout);
}
}
public synchronized void onServiceConnected(ComponentName name, IBinder service) {
mService = ILicensingService.Stub.asInterface(service);
runChecks();
}
public synchronized void onServiceDisconnected(ComponentName name) {
// Called when the connection with the service has been
// unexpectedly disconnected. That is, Market crashed.
// If there are any checks in progress, the timeouts will handle them.
// Log.w(TAG, "Service unexpectedly disconnected.");
mService = null;
}
/**
* Generates policy response for service connection errors, as a result of
* disconnections or timeouts.
*/
private synchronized void handleServiceConnectionError(LicenseValidator validator) {
mPolicy.processServerResponse(Policy.RETRY, null);
if (mPolicy.allowAccess()) {
validator.getCallback().allow(Policy.RETRY);
} else {
validator.getCallback().dontAllow(Policy.RETRY);
}
}
/**
* Generates policy response for no service connection error (no Google Play service)
*/
private synchronized void handleNoServiceConnectionError(LicenseValidator validator) {
mPolicy.processServerResponse(Policy.NO_SERVICE, null);
if (mPolicy.allowAccess()) {
validator.getCallback().allow(Policy.NO_SERVICE);
} else {
validator.getCallback().dontAllow(Policy.NO_SERVICE);
}
}
/** Unbinds service if necessary and removes reference to it. */
private void cleanupService() {
if (mService != null) {
try {
mContext.unbindService(this);
} catch (IllegalArgumentException e) {
// Somehow we've already been unbound. This is a non-fatal
// error.
// Log.e(TAG, "Unable to unbind from licensing service (already unbound)");
}
mService = null;
}
}
/**
* Inform the library that the context is about to be destroyed, so that any
* open connections can be cleaned up.
* <p>
* Failure to call this method can result in a crash under certain
* circumstances, such as during screen rotation if an Activity requests the
* license check or when the user exits the application.
*/
public synchronized void onDestroy() {
cleanupService();
mHandler.getLooper().quit();
}
/** Generates a nonce (number used once). */
private int generateNonce() {
return RANDOM.nextInt();
}
/**
* Get version code for the application package name.
*
* @param context
* @param packageName application package name
* @return the version code or empty string if package not found
*/
private static String getVersionCode(Context context, String packageName) {
try {
return String.valueOf(context.getPackageManager().getPackageInfo(packageName, 0).
versionCode);
} catch (NameNotFoundException e) {
// Log.e(TAG, "Package not found. could not get version code.");
return "";
}
}
}

View file

@ -34,13 +34,23 @@ package com.google.android.vending.licensing;
*/
public interface LicenseCheckerCallback {
/**
* Application error codes.
*/
int ERROR_INVALID_PACKAGE_NAME = 1;
int ERROR_NON_MATCHING_UID = 2;
int ERROR_NOT_MARKET_MANAGED = 3;
int ERROR_CHECK_IN_PROGRESS = 4;
int ERROR_INVALID_PUBLIC_KEY = 5;
int ERROR_MISSING_PERMISSION = 6;
/**
* Allow use. App should proceed as normal.
*
* @param reason Policy.LICENSED or Policy.RETRY typically. (although in
* theory the policy can return Policy.NOT_LICENSED here as well)
*/
public void allow(int reason);
void allow(int reason);
/**
* Don't allow use. App should inform user and take appropriate action.
@ -49,19 +59,11 @@ public interface LicenseCheckerCallback {
* the policy can return Policy.LICENSED here as well ---
* perhaps the call to the LVL took too long, for example)
*/
public void dontAllow(int reason);
/** Application error codes. */
public static final int ERROR_INVALID_PACKAGE_NAME = 1;
public static final int ERROR_NON_MATCHING_UID = 2;
public static final int ERROR_NOT_MARKET_MANAGED = 3;
public static final int ERROR_CHECK_IN_PROGRESS = 4;
public static final int ERROR_INVALID_PUBLIC_KEY = 5;
public static final int ERROR_MISSING_PERMISSION = 6;
void dontAllow(int reason);
/**
* Error in application code. Caller did not call or set up license checker
* correctly. Should be considered fatal.
*/
public void applicationError(int errorCode);
void applicationError(int errorCode);
}

View file

@ -30,21 +30,21 @@ public interface Policy {
/**
* LICENSED means that the server returned back a valid license response
*/
public static final int LICENSED = 0x16f8e94;
int LICENSED = 0x16f8e94;
/**
* NOT_LICENSED means that the server returned back a valid license response
* that indicated that the user definitively is not licensed
*/
public static final int NOT_LICENSED = 0x1;
int NOT_LICENSED = 0x1;
/**
* RETRY means that the license response was unable to be determined ---
* perhaps as a result of faulty networking
*/
public static final int RETRY = 0x56ee981;
int RETRY = 0x56ee981;
/**
* NO_SERVICE means no connection with the Google Play service
*/
public static final int NO_SERVICE = 0x936af1;
int NO_SERVICE = 0x936af1;
/**
* Provide results from contact with the license server. Retry counts are

View file

@ -16,17 +16,17 @@
package com.google.android.vending.licensing;
import android.content.Context;
import com.google.android.vending.licensing.util.Item;
import com.google.android.vending.licensing.util.URLUtils;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.content.Context;
import com.google.android.vending.licensing.util.Item;
import com.google.android.vending.licensing.util.URLUtils;
/**
* Default policy. All policy decisions are based off of response data received
* from the licensing service. Specifically, the licensing server sends the
@ -54,14 +54,13 @@ public class ServerManagedPolicy implements Policy {
private static final String DEFAULT_RETRY_COUNT = "5";
private static final long MILLIS_PER_MINUTE = 60 * 1000;
private final JSONDataObfuscator mPreferences;
private long mValidityTimestamp;
private long mRetryUntil;
private long mMaxRetries;
private long mRetryCount;
private long mLastResponseTime = 0;
private int mLastResponse;
private JSONDataObfuscator mPreferences;
public ServerManagedPolicy(Context context) {
// Import old values
@ -128,6 +127,10 @@ public class ServerManagedPolicy implements Policy {
mPreferences.putString(PREF_LAST_RESPONSE, Integer.toString(l));
}
public long getRetryCount() {
return mRetryCount;
}
/**
* Set the current retry count and add to preferences. You must manually
* call PreferenceObfuscator.commit() to commit these changes to disk.
@ -139,8 +142,8 @@ public class ServerManagedPolicy implements Policy {
mPreferences.putString(PREF_RETRY_COUNT, Long.toString(c));
}
public long getRetryCount() {
return mRetryCount;
public long getValidityTimestamp() {
return mValidityTimestamp;
}
/**
@ -165,8 +168,8 @@ public class ServerManagedPolicy implements Policy {
mPreferences.putString(PREF_VALIDITY_TIMESTAMP, validityTimestamp);
}
public long getValidityTimestamp() {
return mValidityTimestamp;
public long getRetryUntil() {
return mRetryUntil;
}
/**
@ -184,15 +187,15 @@ public class ServerManagedPolicy implements Policy {
// No response or not parsable, expire immediately
// Log.w(TAG, "License retry timestamp (GT) missing, grace period disabled");
retryUntil = "0";
lRetryUntil = 0l;
lRetryUntil = 0L;
}
mRetryUntil = lRetryUntil;
mPreferences.putString(PREF_RETRY_UNTIL, retryUntil);
}
public long getRetryUntil() {
return mRetryUntil;
public long getMaxRetries() {
return mMaxRetries;
}
/**
@ -210,20 +213,16 @@ public class ServerManagedPolicy implements Policy {
// No response or not parsable, expire immediately
// Log.w(TAG, "Licence retry count (GR) missing, grace period disabled");
maxRetries = "0";
lMaxRetries = 0l;
lMaxRetries = 0L;
}
mMaxRetries = lMaxRetries;
mPreferences.putString(PREF_MAX_RETRIES, maxRetries);
}
public long getMaxRetries() {
return mMaxRetries;
}
/**
* {@inheritDoc}
*
* <p>
* This implementation allows access if either:<br>
* <ol>
* <li>a LICENSED response was received within the validity period
@ -235,19 +234,14 @@ public class ServerManagedPolicy implements Policy {
long ts = System.currentTimeMillis();
if (mLastResponse == Policy.LICENSED) {
// Check if the LICENSED response occurred within the validity timeout.
if (ts <= mValidityTimestamp) {
// Cached LICENSED response is still valid.
return true;
}
return ts <= mValidityTimestamp;
} else if (mLastResponse == Policy.RETRY &&
ts < mLastResponseTime + MILLIS_PER_MINUTE) {
// Only allow access if we are within the retry period or we haven't used up our
// max retries.
return (ts <= mRetryUntil || mRetryCount <= mMaxRetries);
} else if(mLastResponse == Policy.NO_SERVICE) {
return true;
}
return false;
} else return mLastResponse == Policy.NO_SERVICE;
}
private Map<String, String> decodeExtras(String extras) {

View file

@ -39,16 +39,24 @@ package com.google.android.vending.licensing.util;
* class.
*/
public class Base64 {
/** Specify encoding (value is {@code true}). */
/**
* Specify encoding (value is {@code true}).
*/
public final static boolean ENCODE = true;
/** Specify decoding (value is {@code false}). */
/**
* Specify decoding (value is {@code false}).
*/
public final static boolean DECODE = false;
/** The equals sign (=) as a byte. */
/**
* The equals sign (=) as a byte.
*/
private final static byte EQUALS_SIGN = (byte) '=';
/** The new line character (\n) as a byte. */
/**
* The new line character (\n) as a byte.
*/
private final static byte NEW_LINE = (byte) '\n';
/**
@ -124,7 +132,9 @@ public class Base64 {
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
};
/** The web safe decodabet */
/**
* The web safe decodabet
*/
private final static byte[] WEBSAFE_DECODABET =
{-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
-5, -5, // Whitespace: Tab and Linefeed
@ -165,7 +175,9 @@ public class Base64 {
// Indicates equals sign in encoding
private final static byte EQUALS_SIGN_ENC = -1;
/** Defeats instantiation. */
/**
* Defeats instantiation.
*/
private Base64() {
}
@ -276,7 +288,7 @@ public class Base64 {
// If doPadding is false, set length to truncate '='
// padding characters
while (doPadding == false && outLen > 0) {
while (!doPadding && outLen > 0) {
if (outBuff[outLen - 1] != '=') {
break;
}
@ -363,7 +375,6 @@ public class Base64 {
* This method returns the actual number of bytes that
* were converted from the Base64 encoding.
*
*
* @param source the array to convert
* @param srcOffset the index where conversion begins
* @param destination the array to hold the conversion
@ -438,8 +449,8 @@ public class Base64 {
*
* @param source The Base64 encoded data
* @return decoded data
* @since 1.3
* @throws Base64DecoderException
* @since 1.3
*/
public static byte[] decode(byte[] source) throws Base64DecoderException {
return decode(source, 0, source.length);
@ -466,8 +477,8 @@ public class Base64 {
* @param off The offset of where to begin decoding
* @param len The length of characters to decode
* @return decoded data
* @since 1.3
* @throws Base64DecoderException
* @since 1.3
*/
public static byte[] decode(byte[] source, int off, int len)
throws Base64DecoderException {

View file

@ -1,8 +1,8 @@
package com.google.android.vending.licensing.util;
public class Item {
private String name;
private String value;
private final String name;
private final String value;
public Item(String n, String v) {
name = n;

View file

@ -33,7 +33,6 @@ import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Process;
import android.view.View;
import android.widget.Toast;
@ -43,15 +42,15 @@ import com.google.android.vending.licensing.LicenseCheckerCallback;
import com.google.android.vending.licensing.Policy;
import com.google.android.vending.licensing.ServerManagedPolicy;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher_extreme.R;
import net.pierrox.lightning_launcher.data.FileUtils;
import net.pierrox.lightning_launcher.data.Page;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher.iab.IabHelper;
import net.pierrox.lightning_launcher.iab.IabResult;
import net.pierrox.lightning_launcher.iab.Inventory;
import net.pierrox.lightning_launcher.iab.Purchase;
import net.pierrox.lightning_launcher.prefs.LLPreference;
import net.pierrox.lightning_launcher_extreme.R;
import org.json.JSONException;
import org.json.JSONObject;
@ -67,11 +66,12 @@ public class LLAppExtreme extends LLAppPhone {
private static final String key4 = "hI3T9SPxlX4faIxSX0hwLJAtbb5IZWX5XvuQdQovF9W9";
private static final String key5 = "vRdURFT6D7K01k+doWbMDZnbfQXiYKHaaBja+SlsZA4UsHF6RubVTi+nOET1xBlpjNwQ6wl69GdM+y8WA1WR47JBNph6wuCF0q7pz2KbuBDvh5vSvYaBGb9dflqnOKy2S47DSA7HOwffTUtxilskp";
private static final String key6 = "JvKKBdyKwQoNTKyp7bjXUrFg/tlJOTo0je4RkcvBHiYCW/yEQKSPY43nlnapcy6L4P+0IV+GDHI+Zx1D+mPo6BmsTwIDAQAB";
private static final String LWP_PKG = "net.pierrox.lightning_launcher.lwp_key";
private static final String PATH_TEST = "t";
private static final String COLUMN_IS_LICENSED = "l";
private LicenseCheckerCallback mLicenseCheckerCallback;
private LicenseChecker mChecker;
private boolean mIsLicensed = true;
private IabHelper mIABHelper;
private String mIabKey;
private boolean mHasLWPIab;
@ -171,33 +171,6 @@ public class LLAppExtreme extends LLAppPhone {
mChecker.checkAccess(mLicenseCheckerCallback);
}
private class MyLicenseCheckerCallback implements LicenseCheckerCallback {
public void allow(int reason) {
mIsLicensed = true;
}
public void dontAllow(int reason) {
if (reason == Policy.RETRY) {
// If the reason received from the policy is RETRY, it was probably
// due to a loss of connection with the service, so we should give the
// user a chance to retry. So show a dialog to retry.
mIsLicensed = true;
} else {
// Otherwise, the user is not licensed to use this app.
// Your response should always inform the user that the application
// is not licensed, but your behavior at that point can vary. You might
// provide the user a limited access version of your app or you can
// take them to Google Play to purchase the app.
mIsLicensed = false;
}
}
@Override
public void applicationError(int errorCode) {
}
}
public String getIabKey() {
return mIabKey;
}
@ -221,10 +194,6 @@ public class LLAppExtreme extends LLAppPhone {
});
}
private static final String LWP_PKG = "net.pierrox.lightning_launcher.lwp_key";
private static final String PATH_TEST = "t";
private static final String COLUMN_IS_LICENSED = "l";
public void checkLwpKey() {
// first step : the permission is granted meaning the package is installed
mHasLWPKey = checkPermission(LWP_PKG, Process.myPid(), Process.myUid()) == PackageManager.PERMISSION_GRANTED;
@ -297,10 +266,6 @@ public class LLAppExtreme extends LLAppPhone {
}
}
public interface UnlockResultReceiver {
void setUnlocked(String sku, boolean unlocked);
}
public void checkProducts(final UnlockResultReceiver receiver) {
// Have we been disposed of in the meantime? If so, quit.
if (mIABHelper == null || !mIABHelper.isSetupDone()) return;
@ -357,4 +322,31 @@ public class LLAppExtreme extends LLAppPhone {
private void startPurchaseProcess(Context context, String sku) {
PurchaseProcess.startActivity(context, sku);
}
public interface UnlockResultReceiver {
void setUnlocked(String sku, boolean unlocked);
}
private class MyLicenseCheckerCallback implements LicenseCheckerCallback {
public void allow(int reason) {
mIsLicensed = true;
}
public void dontAllow(int reason) {
// If the reason received from the policy is RETRY, it was probably
// due to a loss of connection with the service, so we should give the
// user a chance to retry. So show a dialog to retry.
// Otherwise, the user is not licensed to use this app.
// Your response should always inform the user that the application
// is not licensed, but your behavior at that point can vary. You might
// provide the user a limited access version of your app or you can
// take them to Google Play to purchase the app.
mIsLicensed = reason == Policy.RETRY;
}
@Override
public void applicationError(int errorCode) {
}
}
}

View file

@ -39,16 +39,24 @@ package net.pierrox.lightning_launcher.iab;
* class.
*/
public class Base64 {
/** Specify encoding (value is {@code true}). */
/**
* Specify encoding (value is {@code true}).
*/
public final static boolean ENCODE = true;
/** Specify decoding (value is {@code false}). */
/**
* Specify decoding (value is {@code false}).
*/
public final static boolean DECODE = false;
/** The equals sign (=) as a byte. */
/**
* The equals sign (=) as a byte.
*/
private final static byte EQUALS_SIGN = (byte) '=';
/** The new line character (\n) as a byte. */
/**
* The new line character (\n) as a byte.
*/
private final static byte NEW_LINE = (byte) '\n';
/**
@ -124,7 +132,9 @@ public class Base64 {
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
};
/** The web safe decodabet */
/**
* The web safe decodabet
*/
private final static byte[] WEBSAFE_DECODABET =
{-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
-5, -5, // Whitespace: Tab and Linefeed
@ -165,7 +175,9 @@ public class Base64 {
// Indicates equals sign in encoding
private final static byte EQUALS_SIGN_ENC = -1;
/** Defeats instantiation. */
/**
* Defeats instantiation.
*/
private Base64() {
}
@ -276,7 +288,7 @@ public class Base64 {
// If doPadding is false, set length to truncate '='
// padding characters
while (doPadding == false && outLen > 0) {
while (!doPadding && outLen > 0) {
if (outBuff[outLen - 1] != '=') {
break;
}
@ -363,7 +375,6 @@ public class Base64 {
* This method returns the actual number of bytes that
* were converted from the Base64 encoding.
*
*
* @param source the array to convert
* @param srcOffset the index where conversion begins
* @param destination the array to hold the conversion
@ -438,8 +449,8 @@ public class Base64 {
*
* @param source The Base64 encoded data
* @return decoded data
* @since 1.3
* @throws Base64DecoderException
* @since 1.3
*/
public static byte[] decode(byte[] source) throws Base64DecoderException {
return decode(source, 0, source.length);
@ -466,8 +477,8 @@ public class Base64 {
* @param off the offset of where to begin decoding
* @param len the length of characters to decode
* @return decoded data
* @since 1.3
* @throws Base64DecoderException
* @since 1.3
*/
public static byte[] decode(byte[] source, int off, int len)
throws Base64DecoderException {

View file

@ -44,22 +44,22 @@ import java.util.List;
* It provides synchronous (blocking) and asynchronous (non-blocking) methods for
* many common in-app billing operations, as well as automatic signature
* verification.
*
* <p>
* After instantiating, you must perform setup in order to start using the object.
* To perform setup, call the {@link #startSetup} method and provide a listener;
* that listener will be notified when setup is complete, after which (and not before)
* you may call other methods.
*
* <p>
* After setup is complete, you will typically want to request an inventory of owned
* items and subscriptions. See {@link #queryInventory}, {@link #queryInventoryAsync}
* and related methods.
*
* <p>
* When you are done with this object, don't forget to call {@link #dispose}
* to ensure proper cleanup. This object holds a binding to the in-app billing
* service, which will leak unless you dispose of it correctly. If you created
* the object on an Activity's onCreate method, then the recommended
* place to dispose of it is the Activity's onDestroy method.
*
* <p>
* A note about threading: When using this object from a background thread, you may
* call the blocking versions of methods; when using from a UI thread, call
* only the asynchronous versions and handle the results via callbacks.
@ -68,47 +68,8 @@ import java.util.List;
* has not yet completed will result in an exception being thrown.
*
* @author Bruno Oliveira (Google)
*
*/
public class IabHelper {
// Is debug logging enabled?
boolean mDebugLog = false;
String mDebugTag = "IabHelper";
// Is setup done?
boolean mSetupDone = false;
// Has this object been disposed of? (If so, we should ignore callbacks, etc)
boolean mDisposed = false;
// Are subscriptions supported?
boolean mSubscriptionsSupported = false;
// Is an asynchronous operation in progress?
// (only one at a time can be in progress)
boolean mAsyncInProgress = false;
// (for logging/debugging)
// if mAsyncInProgress == true, what asynchronous operation is in progress?
String mAsyncOperation = "";
// Context we were passed during initialization
Context mContext;
// Connection to the service
IInAppBillingService mService;
ServiceConnection mServiceConn;
boolean mServiceBound;
// The request code used to launch purchase flow
int mRequestCode;
// The item type of the current purchase flow
String mPurchasingItemType;
// Public key for verifying signature, in base64 encoding
String mSignatureBase64 = null;
// Billing response codes
public static final int BILLING_RESPONSE_RESULT_OK = 0;
public static final int BILLING_RESPONSE_RESULT_USER_CANCELED = 1;
@ -118,7 +79,6 @@ public class IabHelper {
public static final int BILLING_RESPONSE_RESULT_ERROR = 6;
public static final int BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED = 7;
public static final int BILLING_RESPONSE_RESULT_ITEM_NOT_OWNED = 8;
// IAB Helper error codes
public static final int IABHELPER_ERROR_BASE = -1000;
public static final int IABHELPER_REMOTE_EXCEPTION = -1001;
@ -131,7 +91,6 @@ public class IabHelper {
public static final int IABHELPER_UNKNOWN_ERROR = -1008;
public static final int IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE = -1009;
public static final int IABHELPER_INVALID_CONSUMPTION = -1010;
// Keys for the responses from InAppBillingService
public static final String RESPONSE_CODE = "RESPONSE_CODE";
public static final String RESPONSE_GET_SKU_DETAILS_LIST = "DETAILS_LIST";
@ -142,14 +101,42 @@ public class IabHelper {
public static final String RESPONSE_INAPP_PURCHASE_DATA_LIST = "INAPP_PURCHASE_DATA_LIST";
public static final String RESPONSE_INAPP_SIGNATURE_LIST = "INAPP_DATA_SIGNATURE_LIST";
public static final String INAPP_CONTINUATION_TOKEN = "INAPP_CONTINUATION_TOKEN";
// Item types
public static final String ITEM_TYPE_INAPP = "inapp";
public static final String ITEM_TYPE_SUBS = "subs";
// some fields on the getSkuDetails response bundle
public static final String GET_SKU_DETAILS_ITEM_LIST = "ITEM_ID_LIST";
public static final String GET_SKU_DETAILS_ITEM_TYPE_LIST = "ITEM_TYPE_LIST";
// Is debug logging enabled?
boolean mDebugLog = false;
String mDebugTag = "IabHelper";
// Is setup done?
boolean mSetupDone = false;
// Has this object been disposed of? (If so, we should ignore callbacks, etc)
boolean mDisposed = false;
// Are subscriptions supported?
boolean mSubscriptionsSupported = false;
// Is an asynchronous operation in progress?
// (only one at a time can be in progress)
boolean mAsyncInProgress = false;
// (for logging/debugging)
// if mAsyncInProgress == true, what asynchronous operation is in progress?
String mAsyncOperation = "";
// Context we were passed during initialization
Context mContext;
// Connection to the service
IInAppBillingService mService;
ServiceConnection mServiceConn;
boolean mServiceBound;
// The request code used to launch purchase flow
int mRequestCode;
// The item type of the current purchase flow
String mPurchasingItemType;
// Public key for verifying signature, in base64 encoding
String mSignatureBase64 = null;
// The listener registered on launchPurchaseFlow, which we have to call back when
// the purchase finishes
OnIabPurchaseFinishedListener mPurchaseListener;
/**
* Creates an instance. After creation, it will not yet be ready to use. You must perform
@ -168,6 +155,39 @@ public class IabHelper {
logDebug("IAB helper created.");
}
/**
* Returns a human-readable description for the given response code.
*
* @param code The response code
* @return A human-readable string explaining the result code.
* It also includes the result code numerically.
*/
public static String getResponseDesc(int code) {
String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/" +
"3:Billing Unavailable/4:Item unavailable/" +
"5:Developer Error/6:Error/7:Item Already Owned/" +
"8:Item not owned").split("/");
String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/" +
"-1002:Bad response received/" +
"-1003:Purchase signature verification failed/" +
"-1004:Send intent failed/" +
"-1005:User cancelled/" +
"-1006:Unknown purchase response/" +
"-1007:Missing token/" +
"-1008:Unknown error/" +
"-1009:Subscriptions not available/" +
"-1010:Invalid consumption attempt").split("/");
if (code <= IABHELPER_ERROR_BASE) {
int index = IABHELPER_ERROR_BASE - code;
if (index >= 0 && index < iabhelper_msgs.length) return iabhelper_msgs[index];
else return code + ":Unknown IAB Helper Error";
} else if (code < 0 || code >= iab_msgs.length)
return code + ":Unknown";
else
return iab_msgs[code];
}
/**
* Enables or disable debug logging through LogCat.
*/
@ -182,19 +202,6 @@ public class IabHelper {
mDebugLog = enable;
}
/**
* Callback for setup process. This listener's {@link #onIabSetupFinished} method is called
* when the setup process is complete.
*/
public interface OnIabSetupFinishedListener {
/**
* Called to notify that setup is complete.
*
* @param result The result of the setup process.
*/
public void onIabSetupFinished(IabResult result);
}
/**
* Starts the setup process. This will start up the setup process asynchronously.
* You will be notified through the listener when the setup process is complete.
@ -226,7 +233,8 @@ public class IabHelper {
logDebug("Checking for in-app billing 3 support.");
if (mService == null) {
if (listener != null) listener.onIabSetupFinished(new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
if (listener != null)
listener.onIabSetupFinished(new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
"Error checking for billing v3 support, no service."));
// if in-app purchases aren't supported, neither are subscriptions.
@ -251,14 +259,12 @@ public class IabHelper {
if (response == BILLING_RESPONSE_RESULT_OK) {
logDebug("Subscriptions AVAILABLE.");
mSubscriptionsSupported = true;
}
else {
} else {
logDebug("Subscriptions NOT AVAILABLE. Response: " + response);
}
mSetupDone = true;
}
catch (RemoteException e) {
} catch (RemoteException e) {
if (listener != null) {
listener.onIabSetupFinished(new IabResult(IABHELPER_REMOTE_EXCEPTION,
"RemoteException while setting up in-app billing."));
@ -280,8 +286,7 @@ public class IabHelper {
// service available to handle that Intent
mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
mServiceBound = true;
}
else {
} else {
// no service available to handle that Intent
if (listener != null) {
listener.onIabSetupFinished(
@ -319,36 +324,18 @@ public class IabHelper {
}
private void checkNotDisposed() {
if (mDisposed) throw new IllegalStateException("IabHelper was disposed of, so it cannot be used.");
if (mDisposed)
throw new IllegalStateException("IabHelper was disposed of, so it cannot be used.");
}
/** Returns whether subscriptions are supported. */
/**
* Returns whether subscriptions are supported.
*/
public boolean subscriptionsSupported() {
checkNotDisposed();
return mSubscriptionsSupported;
}
/**
* Callback that notifies when a purchase is finished.
*/
public interface OnIabPurchaseFinishedListener {
/**
* Called to notify that an in-app purchase finished. If the purchase was successful,
* then the sku parameter specifies which item was purchased. If the purchase failed,
* the sku and extraData parameters may or may not be null, depending on how far the purchase
* process went.
*
* @param result The result of the purchase.
* @param info The purchase information (null if purchase failed)
*/
public void onIabPurchaseFinished(IabResult result, Purchase info);
}
// The listener registered on launchPurchaseFlow, which we have to call back when
// the purchase finishes
OnIabPurchaseFinishedListener mPurchaseListener;
public void launchPurchaseFlow(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListener listener) {
launchPurchaseFlow(act, sku, requestCode, listener, "");
}
@ -422,16 +409,14 @@ public class IabHelper {
requestCode, new Intent(),
Integer.valueOf(0), Integer.valueOf(0),
Integer.valueOf(0));
}
catch (SendIntentException e) {
} catch (SendIntentException e) {
logError("SendIntentException while launching purchase flow for sku " + sku);
e.printStackTrace();
flagEndAsync();
result = new IabResult(IABHELPER_SEND_INTENT_FAILED, "Failed to send intent.");
if (listener != null) listener.onIabPurchaseFinished(result, null);
}
catch (RemoteException e) {
} catch (RemoteException e) {
logError("RemoteException while launching purchase flow for sku " + sku);
e.printStackTrace();
flagEndAsync();
@ -486,7 +471,8 @@ public class IabHelper {
logError("BUG: either purchaseData or dataSignature is null.");
logDebug("Extras: " + data.getExtras().toString());
result = new IabResult(IABHELPER_UNKNOWN_ERROR, "IAB returned null purchaseData or dataSignature");
if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
if (mPurchaseListener != null)
mPurchaseListener.onIabPurchaseFinished(result, null);
return true;
}
@ -499,38 +485,36 @@ public class IabHelper {
if (!Security.verifyPurchase(mSignatureBase64, purchaseData, dataSignature)) {
logError("Purchase signature verification FAILED for sku " + sku);
result = new IabResult(IABHELPER_VERIFICATION_FAILED, "Signature verification failed for sku " + sku);
if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, purchase);
if (mPurchaseListener != null)
mPurchaseListener.onIabPurchaseFinished(result, purchase);
return true;
}
logDebug("Purchase signature successfully verified.");
}
catch (JSONException e) {
} catch (JSONException e) {
logError("Failed to parse purchase data.");
e.printStackTrace();
result = new IabResult(IABHELPER_BAD_RESPONSE, "Failed to parse purchase data.");
if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
if (mPurchaseListener != null)
mPurchaseListener.onIabPurchaseFinished(result, null);
return true;
}
if (mPurchaseListener != null) {
mPurchaseListener.onIabPurchaseFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Success"), purchase);
}
}
else if (resultCode == Activity.RESULT_OK) {
} else if (resultCode == Activity.RESULT_OK) {
// result code was OK, but in-app billing response was not OK.
logDebug("Result code was OK but in-app billing response was not OK: " + getResponseDesc(responseCode));
if (mPurchaseListener != null) {
result = new IabResult(responseCode, "Problem purchashing item.");
mPurchaseListener.onIabPurchaseFinished(result, null);
}
}
else if (resultCode == Activity.RESULT_CANCELED) {
} else if (resultCode == Activity.RESULT_CANCELED) {
logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode));
result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled.");
if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
}
else {
logError("Purchase failed. Result code: " + Integer.toString(resultCode)
} else {
logError("Purchase failed. Result code: " + resultCode
+ ". Response: " + getResponseDesc(responseCode));
result = new IabResult(IABHELPER_UNKNOWN_PURCHASE_RESPONSE, "Unknown purchase response.");
if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
@ -589,29 +573,13 @@ public class IabHelper {
}
return inv;
}
catch (RemoteException e) {
} catch (RemoteException e) {
throw new IabException(IABHELPER_REMOTE_EXCEPTION, "Remote exception while refreshing inventory.", e);
}
catch (JSONException e) {
} catch (JSONException e) {
throw new IabException(IABHELPER_BAD_RESPONSE, "Error parsing JSON response while refreshing inventory.", e);
}
}
/**
* Listener that notifies when an inventory query operation completes.
*/
public interface QueryInventoryFinishedListener {
/**
* Called to notify that an inventory query operation completed.
*
* @param result The result of the operation.
* @param inv The inventory.
*/
public void onQueryInventoryFinished(IabResult result, Inventory inv);
}
/**
* Asynchronous wrapper for inventory query. This will perform an inventory
* query as described in {@link #queryInventory}, but will do so asynchronously
@ -639,8 +607,7 @@ public class IabHelper {
Inventory inv = null;
try {
inv = queryInventory(querySkuDetails, moreSkus);
}
catch (IabException ex) {
} catch (IabException ex) {
result = ex.getResult();
}
@ -667,7 +634,6 @@ public class IabHelper {
queryInventoryAsync(querySkuDetails, null, listener);
}
/**
* Consumes a given in-app product. Consuming can only be done on an item
* that's owned, and as a result of consumption, the user will no longer own it.
@ -699,44 +665,15 @@ public class IabHelper {
int response = mService.consumePurchase(3, mContext.getPackageName(), token);
if (response == BILLING_RESPONSE_RESULT_OK) {
logDebug("Successfully consumed sku: " + sku);
}
else {
} else {
logDebug("Error consuming consuming sku " + sku + ". " + getResponseDesc(response));
throw new IabException(response, "Error consuming sku " + sku);
}
}
catch (RemoteException e) {
} catch (RemoteException e) {
throw new IabException(IABHELPER_REMOTE_EXCEPTION, "Remote exception while consuming. PurchaseInfo: " + itemInfo, e);
}
}
/**
* Callback that notifies when a consumption operation finishes.
*/
public interface OnConsumeFinishedListener {
/**
* Called to notify that a consumption has finished.
*
* @param purchase The purchase that was (or was to be) consumed.
* @param result The result of the consumption operation.
*/
public void onConsumeFinished(Purchase purchase, IabResult result);
}
/**
* Callback that notifies when a multi-item consumption operation finishes.
*/
public interface OnConsumeMultiFinishedListener {
/**
* Called to notify that a consumption of multiple items has finished.
*
* @param purchases The purchases that were (or were to be) consumed.
* @param results The results of each consumption operation, corresponding to each
* sku.
*/
public void onConsumeMultiFinished(List<Purchase> purchases, List<IabResult> results);
}
/**
* Asynchronous wrapper to item consumption. Works like {@link #consume}, but
* performs the consumption in the background and notifies completion through
@ -755,6 +692,7 @@ public class IabHelper {
/**
* Same as {@link consumeAsync}, but for multiple items at once.
*
* @param purchases The list of PurchaseInfo objects representing the purchases to consume.
* @param listener The listener to notify when the consumption operation finishes.
*/
@ -764,41 +702,6 @@ public class IabHelper {
consumeAsyncInternal(purchases, null, listener);
}
/**
* Returns a human-readable description for the given response code.
*
* @param code The response code
* @return A human-readable string explaining the result code.
* It also includes the result code numerically.
*/
public static String getResponseDesc(int code) {
String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/" +
"3:Billing Unavailable/4:Item unavailable/" +
"5:Developer Error/6:Error/7:Item Already Owned/" +
"8:Item not owned").split("/");
String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/" +
"-1002:Bad response received/" +
"-1003:Purchase signature verification failed/" +
"-1004:Send intent failed/" +
"-1005:User cancelled/" +
"-1006:Unknown purchase response/" +
"-1007:Missing token/" +
"-1008:Unknown error/" +
"-1009:Subscriptions not available/" +
"-1010:Invalid consumption attempt").split("/");
if (code <= IABHELPER_ERROR_BASE) {
int index = IABHELPER_ERROR_BASE - code;
if (index >= 0 && index < iabhelper_msgs.length) return iabhelper_msgs[index];
else return String.valueOf(code) + ":Unknown IAB Helper Error";
}
else if (code < 0 || code >= iab_msgs.length)
return String.valueOf(code) + ":Unknown";
else
return iab_msgs[code];
}
// Checks that setup was done; if not, throws an exception.
void checkSetupDone(String operation) {
if (!mSetupDone) {
@ -813,8 +716,7 @@ public class IabHelper {
if (o == null) {
logDebug("Bundle with null response code, assuming OK (known issue)");
return BILLING_RESPONSE_RESULT_OK;
}
else if (o instanceof Integer) return ((Integer)o).intValue();
} else if (o instanceof Integer) return ((Integer) o).intValue();
else if (o instanceof Long) return (int) ((Long) o).longValue();
else {
logError("Unexpected type for bundle response code.");
@ -829,8 +731,7 @@ public class IabHelper {
if (o == null) {
logError("Intent with no response code, assuming OK (known issue)");
return BILLING_RESPONSE_RESULT_OK;
}
else if (o instanceof Integer) return ((Integer)o).intValue();
} else if (o instanceof Integer) return ((Integer) o).intValue();
else if (o instanceof Long) return (int) ((Long) o).longValue();
else {
logError("Unexpected type for intent response code.");
@ -853,7 +754,6 @@ public class IabHelper {
mAsyncInProgress = false;
}
int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException {
// Query purchases
logDebug("Querying owned items, item type: " + itemType);
@ -867,7 +767,7 @@ public class IabHelper {
itemType, continueToken);
int response = getResponseCodeFromBundle(ownedItems);
logDebug("Owned items response: " + String.valueOf(response));
logDebug("Owned items response: " + response);
if (response != BILLING_RESPONSE_RESULT_OK) {
logDebug("getPurchases() failed: " + getResponseDesc(response));
return response;
@ -901,8 +801,7 @@ public class IabHelper {
// Record ownership and token
inv.addPurchase(purchase);
}
else {
} else {
logWarn("Purchase signature verification **FAILED**. Not adding item.");
logDebug(" Purchase data: " + purchaseData);
logDebug(" Signature: " + signature);
@ -945,8 +844,7 @@ public class IabHelper {
if (response != BILLING_RESPONSE_RESULT_OK) {
logDebug("getSkuDetails() failed: " + getResponseDesc(response));
return response;
}
else {
} else {
logError("getSkuDetails() returned a bundle with neither an error nor a detail list.");
return IABHELPER_BAD_RESPONSE;
}
@ -963,7 +861,6 @@ public class IabHelper {
return BILLING_RESPONSE_RESULT_OK;
}
void consumeAsyncInternal(final List<Purchase> purchases,
final OnConsumeFinishedListener singleListener,
final OnConsumeMultiFinishedListener multiListener) {
@ -976,8 +873,7 @@ public class IabHelper {
try {
consume(purchase);
results.add(new IabResult(BILLING_RESPONSE_RESULT_OK, "Successful consume of sku " + purchase.getSku()));
}
catch (IabException ex) {
} catch (IabException ex) {
results.add(ex.getResult());
}
}
@ -1012,4 +908,74 @@ public class IabHelper {
void logWarn(String msg) {
Log.w(mDebugTag, "In-app billing warning: " + msg);
}
/**
* Callback for setup process. This listener's {@link #onIabSetupFinished} method is called
* when the setup process is complete.
*/
public interface OnIabSetupFinishedListener {
/**
* Called to notify that setup is complete.
*
* @param result The result of the setup process.
*/
void onIabSetupFinished(IabResult result);
}
/**
* Callback that notifies when a purchase is finished.
*/
public interface OnIabPurchaseFinishedListener {
/**
* Called to notify that an in-app purchase finished. If the purchase was successful,
* then the sku parameter specifies which item was purchased. If the purchase failed,
* the sku and extraData parameters may or may not be null, depending on how far the purchase
* process went.
*
* @param result The result of the purchase.
* @param info The purchase information (null if purchase failed)
*/
void onIabPurchaseFinished(IabResult result, Purchase info);
}
/**
* Listener that notifies when an inventory query operation completes.
*/
public interface QueryInventoryFinishedListener {
/**
* Called to notify that an inventory query operation completed.
*
* @param result The result of the operation.
* @param inv The inventory.
*/
void onQueryInventoryFinished(IabResult result, Inventory inv);
}
/**
* Callback that notifies when a consumption operation finishes.
*/
public interface OnConsumeFinishedListener {
/**
* Called to notify that a consumption has finished.
*
* @param purchase The purchase that was (or was to be) consumed.
* @param result The result of the consumption operation.
*/
void onConsumeFinished(Purchase purchase, IabResult result);
}
/**
* Callback that notifies when a multi-item consumption operation finishes.
*/
public interface OnConsumeMultiFinishedListener {
/**
* Called to notify that a consumption of multiple items has finished.
*
* @param purchases The purchases that were (or were to be) consumed.
* @param results The results of each consumption operation, corresponding to each
* sku.
*/
void onConsumeMultiFinished(List<Purchase> purchases, List<IabResult> results);
}
}

View file

@ -28,24 +28,33 @@ public class Inventory {
Map<String, SkuDetails> mSkuMap = new HashMap<String, SkuDetails>();
Map<String, Purchase> mPurchaseMap = new HashMap<String, Purchase>();
Inventory() { }
Inventory() {
}
/** Returns the listing details for an in-app product. */
/**
* Returns the listing details for an in-app product.
*/
public SkuDetails getSkuDetails(String sku) {
return mSkuMap.get(sku);
}
/** Returns purchase information for a given product, or null if there is no purchase. */
/**
* Returns purchase information for a given product, or null if there is no purchase.
*/
public Purchase getPurchase(String sku) {
return mPurchaseMap.get(sku);
}
/** Returns whether or not there exists a purchase of the given product. */
/**
* Returns whether or not there exists a purchase of the given product.
*/
public boolean hasPurchase(String sku) {
return mPurchaseMap.containsKey(sku);
}
/** Return whether or not details about the given product are available. */
/**
* Return whether or not details about the given product are available.
*/
public boolean hasDetails(String sku) {
return mSkuMap.containsKey(sku);
}
@ -59,15 +68,19 @@ public class Inventory {
* a new Inventory.
*/
public void erasePurchase(String sku) {
if (mPurchaseMap.containsKey(sku)) mPurchaseMap.remove(sku);
mPurchaseMap.remove(sku);
}
/** Returns a list of all owned product IDs. */
/**
* Returns a list of all owned product IDs.
*/
List<String> getAllOwnedSkus() {
return new ArrayList<String>(mPurchaseMap.keySet());
}
/** Returns a list of all owned product IDs of a given type */
/**
* Returns a list of all owned product IDs of a given type
*/
List<String> getAllOwnedSkus(String itemType) {
List<String> result = new ArrayList<String>();
for (Purchase p : mPurchaseMap.values()) {
@ -76,7 +89,9 @@ public class Inventory {
return result;
}
/** Returns a list of all purchases. */
/**
* Returns a list of all purchases.
*/
List<Purchase> getAllPurchases() {
return new ArrayList<Purchase>(mPurchaseMap.values());
}

View file

@ -16,13 +16,7 @@
package com.boombuler.system.appwidgetpicker;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import android.annotation.TargetApi;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@ -37,6 +31,11 @@ import android.view.Window;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.activities.ResourceWrapperActivity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class AppWidgetPickerActivity extends ResourceWrapperActivity {
private static final int REQUEST_BIND_APPWIDGET = 1;
@ -172,8 +171,7 @@ public class AppWidgetPickerActivity extends ResourceWrapperActivity {
}
}
}
try
{
try {
android.content.pm.ApplicationInfo appInfo = fPManager.getApplicationInfo(info.provider.getPackageName(), 0);
Drawable appIcon = fPManager.getApplicationIcon(appInfo);
CharSequence str = fPManager.getApplicationLabel(appInfo);
@ -181,8 +179,7 @@ public class AppWidgetPickerActivity extends ResourceWrapperActivity {
newItm.setPackageName(packName);
fItems.add(newItm);
return newItm;
}
catch(PackageManager.NameNotFoundException expt) {
} catch (PackageManager.NameNotFoundException expt) {
}
return null;
}
@ -191,15 +188,13 @@ public class AppWidgetPickerActivity extends ResourceWrapperActivity {
List<AppWidgetProviderInfo> infos = fAppWManager.getInstalledProviders();
for (AppWidgetProviderInfo info : infos) {
try
{
try {
android.content.pm.ApplicationInfo appInfo = fPManager.getApplicationInfo(info.provider.getPackageName(), 0);
SubItem itm = new SubItem(info.label, fPManager.getDrawable(info.provider.getPackageName(), info.icon, appInfo));
itm.setProvider(info.provider);
Item mainItm = getPackageItem(info);
mainItm.getItems().add(itm);
}
catch(PackageManager.NameNotFoundException expt) {
} catch (PackageManager.NameNotFoundException expt) {
}
}
}
@ -210,7 +205,8 @@ public class AppWidgetPickerActivity extends ResourceWrapperActivity {
// get and validate the extras they gave us
ArrayList<AppWidgetProviderInfo> customInfo = null;
ArrayList<Bundle> customExtras = null;
try_custom_items: {
try_custom_items:
{
customInfo = extras.getParcelableArrayList(AppWidgetManager.EXTRA_CUSTOM_INFO);
if (customInfo == null || customInfo.size() == 0) {
@ -254,7 +250,7 @@ public class AppWidgetPickerActivity extends ResourceWrapperActivity {
for (int i = 0; i < size; i++) {
AppWidgetProviderInfo info = appWidgets.get(i);
String label = info.label.toString();
String label = info.label;
Drawable icon = null;
if (info.icon != 0) {

View file

@ -15,8 +15,6 @@
*/
package com.boombuler.system.appwidgetpicker;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
@ -27,6 +25,8 @@ import android.widget.TextView;
import net.pierrox.lightning_launcher_extreme.R;
import java.util.ArrayList;
public class ItemAdapter extends ArrayAdapter<SubItem> {
private final ArrayList<SubItem> items;
@ -48,24 +48,21 @@ public class ItemAdapter extends ArrayAdapter<SubItem> {
SubItem o = items.get(position);
v.setTag(o);
if (o != null) {
TextView tv = (TextView) v.findViewById(R.id.appwidgetpicker_textview);
TextView count_view = (TextView) v.findViewById(R.id.appwidgetpicker_count);
ImageView iv = (ImageView) v.findViewById(R.id.appwidgetpicker_imageview);
TextView tv = v.findViewById(R.id.appwidgetpicker_textview);
TextView count_view = v.findViewById(R.id.appwidgetpicker_count);
ImageView iv = v.findViewById(R.id.appwidgetpicker_imageview);
if (tv != null) {
tv.setText(o.getName());
}
if (count_view != null) {
if (o instanceof Item)
{
if (o instanceof Item) {
int cnt = ((Item) o).getItems().size();
if (cnt > 1) {
count_view.setText(String.format(fContext.getString(R.string.widget_count), cnt));
count_view.setVisibility(View.VISIBLE);
}
else
} else
count_view.setVisibility(View.GONE);
}
else
} else
count_view.setVisibility(View.GONE);
}
if (iv != null) {

View file

@ -21,8 +21,8 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
public class SubItem {
private String fName;
private Drawable fImage;
private final String fName;
private final Drawable fImage;
public Bundle fExtra = null;
public ComponentName fProvider = null;
@ -31,23 +31,26 @@ public class SubItem {
fImage = image;
}
public Bundle getExtra() {
return fExtra;
}
public void setExtra(Bundle aValue) {
fExtra = aValue;
}
public Bundle getExtra() {
return fExtra;
public ComponentName getProvider() {
return fProvider;
}
public void setProvider(ComponentName aValue) {
fProvider = aValue;
}
public ComponentName getProvider() {
return fProvider;
}
public String getName() {
return fName;
}
public Drawable getImage() {
return fImage;
}

View file

@ -74,7 +74,6 @@ public class HotwordServiceClient {
mHotwordService.requestHotwordDetection(mActivity.getPackageName(), mIsFocused && mIsRequested);
} catch (RemoteException e) {
Log.w(TAG, "requestHotwordDetection - remote call failed", e);
return;
}
}
@ -104,7 +103,8 @@ public class HotwordServiceClient {
}
private class HotwordServiceConnection implements ServiceConnection {
private HotwordServiceConnection() {}
private HotwordServiceConnection() {
}
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mHotwordService = IHotwordService.Stub.asInterface(iBinder);
@ -118,7 +118,8 @@ public class HotwordServiceClient {
}
private class WindowFocusObserver extends WindowId.FocusObserver {
private WindowFocusObserver() {}
private WindowFocusObserver() {
}
public void onFocusGained(WindowId wid) {
mIsFocused = true;

View file

@ -6,12 +6,12 @@ import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
public abstract interface IHotwordService extends IInterface {
public abstract void requestHotwordDetection(String packageName, boolean detect) throws RemoteException;
public interface IHotwordService extends IInterface {
void requestHotwordDetection(String packageName, boolean detect) throws RemoteException;
public static abstract class Stub extends Binder implements IHotwordService {
private static final String DESCRIPTOR = "com.google.android.hotword.service.IHotwordService";
abstract class Stub extends Binder implements IHotwordService {
static final int TRANSACTION_requestHotwordDetection = 1;
private static final String DESCRIPTOR = "com.google.android.hotword.service.IHotwordService";
public Stub() {
attachInterface(this, DESCRIPTOR);
@ -40,14 +40,14 @@ public abstract interface IHotwordService extends IInterface {
case TRANSACTION_requestHotwordDetection:
data.enforceInterface(DESCRIPTOR);
String packageName = data.readString();
boolean detect = (data.readInt() == 1) ? true : false;
boolean detect = data.readInt() == 1;
requestHotwordDetection(packageName, detect);
return true;
}
}
private static class Proxy implements IHotwordService {
private IBinder mRemote;
private final IBinder mRemote;
Proxy(IBinder iBinder) {
mRemote = iBinder;

View file

@ -13,7 +13,7 @@ import android.widget.AdapterView;
* based on touch gestures. This class also inherits from
* {@link SimpleFloatViewManager}, which provides basic float View
* creation.
*
* <p>
* An instance of this class is meant to be passed to the methods
* {@link DragSortListView#setTouchListener()} and
* {@link DragSortListView#setFloatViewManager()} of your
@ -27,59 +27,62 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
public static final int ON_DOWN = 0;
public static final int ON_DRAG = 1;
public static final int ON_LONG_PRESS = 2;
private int mDragInitMode = ON_DOWN;
private boolean mSortEnabled = true;
/**
* Remove mode enum.
*/
public static final int CLICK_REMOVE = 0;
public static final int FLING_REMOVE = 1;
public static final int MISS = -1;
private final GestureDetector mDetector;
private final GestureDetector mFlingRemoveDetector;
private final int mTouchSlop;
private final int[] mTempLoc = new int[2];
private final float mFlingSpeed = 500f;
private final DragSortListView mDslv;
protected int mHitPos = MISS;
private int mDragInitMode = ON_DOWN;
private boolean mSortEnabled = true;
/**
* The current remove mode.
*/
private int mRemoveMode;
private boolean mRemoveEnabled = false;
private boolean mIsRemoving = false;
private GestureDetector mDetector;
private GestureDetector mFlingRemoveDetector;
private int mTouchSlop;
public static final int MISS = -1;
protected int mHitPos = MISS;
private int mFlingHitPos = MISS;
private int mClickRemoveHitPos = MISS;
private int[] mTempLoc = new int[2];
private int mItemX;
private int mItemY;
private int mCurrX;
private int mCurrY;
private boolean mDragging = false;
private float mFlingSpeed = 500f;
private int mDragHandleId;
private int mClickRemoveId;
private int mFlingHandleId;
private boolean mCanDrag;
private DragSortListView mDslv;
private int mPositionX;
private final GestureDetector.OnGestureListener mFlingRemoveListener =
new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// Log.d("mobeta", "on fling remove called");
if (mRemoveEnabled && mIsRemoving) {
int w = mDslv.getWidth();
int minPos = w / 5;
if (velocityX > mFlingSpeed) {
if (mPositionX > -minPos) {
mDslv.stopDragWithVelocity(true, velocityX);
}
} else if (velocityX < -mFlingSpeed) {
if (mPositionX < minPos) {
mDslv.stopDragWithVelocity(true, velocityX);
}
}
mIsRemoving = false;
}
return false;
}
};
/**
* Calls {@link #DragSortController(DragSortListView, int)} with a
@ -101,6 +104,7 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
this(dslv, dragHandleId, dragInitMode, removeMode, clickRemoveId, 0);
}
/**
* By default, sorting is enabled, and removal is disabled.
*
@ -123,7 +127,6 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
setDragInitMode(dragInitMode);
}
public int getDragInitMode() {
return mDragInitMode;
}
@ -138,6 +141,10 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
mDragInitMode = mode;
}
public boolean isSortEnabled() {
return mSortEnabled;
}
/**
* Enable/Disable list item sorting. Disabling is useful if only item
* removal is desired. Prevents drags in the vertical direction.
@ -149,8 +156,8 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
mSortEnabled = enabled;
}
public boolean isSortEnabled() {
return mSortEnabled;
public int getRemoveMode() {
return mRemoveMode;
}
/**
@ -162,8 +169,8 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
mRemoveMode = mode;
}
public int getRemoveMode() {
return mRemoveMode;
public boolean isRemoveEnabled() {
return mRemoveEnabled;
}
/**
@ -173,10 +180,6 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
mRemoveEnabled = enabled;
}
public boolean isRemoveEnabled() {
return mRemoveEnabled;
}
/**
* Set the resource id for the View that represents the drag
* handle in a list item.
@ -215,7 +218,6 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
* @param position The list item position (includes headers).
* @param deltaX Touch x-coord minus left edge of floating View.
* @param deltaY Touch y-coord minus top edge of floating View.
*
* @return True if drag started, false otherwise.
*/
public boolean startDrag(int position, int deltaX, int deltaY) {
@ -295,7 +297,6 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
* event is detected.
*
* @param ev The ACTION_DOWN MotionEvent.
*
* @return The list position to drag if a drag-init gesture is
* detected; MISS if unsuccessful.
*/
@ -313,7 +314,6 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
* if a drag handle touch was detected.
*
* @param ev The ACTION_DOWN MotionEvent.
* @return The list position of the item whose drag handle was
* touched; MISS if unsuccessful.
*/
@ -344,7 +344,7 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
final int rawX = (int) ev.getRawX();
final int rawY = (int) ev.getRawY();
View dragBox = id == 0 ? item : (View) item.findViewById(id);
View dragBox = id == 0 ? item : item.findViewById(id);
if (dragBox != null) {
dragBox.getLocationOnScreen(mTempLoc);
@ -396,9 +396,7 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
if (mHitPos != MISS) {
if (mDragInitMode == ON_DRAG && Math.abs(y2 - y1) > mTouchSlop && mSortEnabled) {
startDrag(mHitPos, deltaX, deltaY);
}
else if (mDragInitMode != ON_DOWN && Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled)
{
} else if (mDragInitMode != ON_DOWN && Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled) {
mIsRemoving = true;
startDrag(mFlingHitPos, deltaX, deltaY);
}
@ -458,28 +456,4 @@ public class DragSortController extends SimpleFloatViewManager implements View.O
// do nothing
}
private GestureDetector.OnGestureListener mFlingRemoveListener =
new GestureDetector.SimpleOnGestureListener() {
@Override
public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// Log.d("mobeta", "on fling remove called");
if (mRemoveEnabled && mIsRemoving) {
int w = mDslv.getWidth();
int minPos = w / 5;
if (velocityX > mFlingSpeed) {
if (mPositionX > -minPos) {
mDslv.stopDragWithVelocity(true, velocityX);
}
} else if (velocityX < -mFlingSpeed) {
if (mPositionX < minPos) {
mDslv.stopDragWithVelocity(true, velocityX);
}
}
mIsRemoving = false;
}
return false;
}
};
}

View file

@ -14,14 +14,11 @@ import android.widget.ListView;
*/
public class SimpleFloatViewManager implements DragSortListView.FloatViewManager {
private final ListView mListView;
private Bitmap mFloatBitmap;
private ImageView mImageView;
private int mFloatBGColor = Color.BLACK;
private ListView mListView;
public SimpleFloatViewManager(ListView lv) {
mListView = lv;
}

View file

@ -31,17 +31,57 @@ import android.widget.Scroller;
*/
public class AdvancedEditText extends EditText implements OnKeyListener, OnGestureListener {
public interface OnAdvancedEditTextEvent {
public boolean onLeftEdgeSwipe();
public boolean onTap();
public void onPinchStart();
public void onPinchZoom(double scale);
}
/**
* @param context
* the current context
* @param attrs
* some attributes
* The line numbers paint
*/
protected Paint mPaintNumbers;
/**
* The line numbers paint
*/
protected Paint mPaintHighlight;
/**
* the offset value in dp
*/
protected int mPaddingDP = 6;
/**
* the padding scaled
*/
protected int mPadding, mLinePadding;
/**
* the scale for desnity pixels
*/
protected float mScale;
protected float mScaledDensity;
/**
* the scroller instance
*/
protected Scroller mTedScroller;
/**
* the velocity tracker
*/
protected GestureDetector mGestureDetector;
/**
* the Max size of the view
*/
protected Point mMaxSize;
/**
* the highlighted line index
*/
protected int mHighlightedLine;
protected int mHighlightStart;
protected Rect mDrawingRect, mLineBounds;
protected boolean mFlingToScroll = true;
protected boolean mShowLineNumbers;
protected boolean mWordWrap;
protected OnAdvancedEditTextEvent mOnAdvancedEditTextEvent;
private int mDeferredScrollToLine = -1;
private double mInitialPinchDistance;
private int mFirstVisibleLine;
private boolean mSkipNextFling;
/**
* @param context the current context
* @param attrs some attributes
* @category ObjectLifecycle
*/
public AdvancedEditText(Context context, AttributeSet attrs) {
@ -84,8 +124,8 @@ public class AdvancedEditText extends EditText implements OnKeyListener, OnGestu
}
/**
* @see android.widget.TextView#computeScroll()
* @category View
* @see android.widget.TextView#computeScroll()
*/
public void computeScroll() {
@ -98,7 +138,6 @@ public class AdvancedEditText extends EditText implements OnKeyListener, OnGestu
}
}
private int mDeferredScrollToLine = -1;
public void scrollToLine(int line) {
Layout layout = getLayout();
if (layout == null) {
@ -169,8 +208,8 @@ public class AdvancedEditText extends EditText implements OnKeyListener, OnGestu
}
/**
* @see android.widget.EditText#onDraw(android.graphics.Canvas)
* @category View
* @see android.widget.EditText#onDraw(android.graphics.Canvas)
*/
public void onDraw(Canvas canvas) {
final Layout layout = getLayout();
@ -269,8 +308,8 @@ public class AdvancedEditText extends EditText implements OnKeyListener, OnGestu
}
/**
* @see android.widget.TextView#onTouchEvent(android.view.MotionEvent)
* @category GestureDetection
* @see android.widget.TextView#onTouchEvent(android.view.MotionEvent)
*/
public boolean onTouchEvent(MotionEvent event) {
if (mTedScroller != null && !mTedScroller.isFinished()) {
@ -314,16 +353,16 @@ public class AdvancedEditText extends EditText implements OnKeyListener, OnGestu
}
/**
* @see android.view.GestureDetector.OnGestureListener#onDown(android.view.MotionEvent)
* @category GestureDetection
* @see android.view.GestureDetector.OnGestureListener#onDown(android.view.MotionEvent)
*/
public boolean onDown(MotionEvent e) {
return false;
}
/**
* @see android.view.GestureDetector.OnGestureListener#onSingleTapUp(android.view.MotionEvent)
* @category GestureDetection
* @see android.view.GestureDetector.OnGestureListener#onSingleTapUp(android.view.MotionEvent)
*/
public boolean onSingleTapUp(MotionEvent e) {
@ -343,8 +382,8 @@ public class AdvancedEditText extends EditText implements OnKeyListener, OnGestu
}
/**
* @see android.view.GestureDetector.OnGestureListener#onShowPress(android.view.MotionEvent)
* @category GestureDetection
* @see android.view.GestureDetector.OnGestureListener#onShowPress(android.view.MotionEvent)
*/
public void onShowPress(MotionEvent e) {
}
@ -466,7 +505,6 @@ public class AdvancedEditText extends EditText implements OnKeyListener, OnGestu
setPadding(mPadding, mPadding, mPadding, mPadding);
}
}*/
public void setFlingToScroll(boolean flingToScroll) {
if (flingToScroll) {
mTedScroller = new Scroller(getContext());
@ -549,40 +587,14 @@ public class AdvancedEditText extends EditText implements OnKeyListener, OnGestu
return Math.max(super.getSelectionStart(), super.getSelectionEnd());
}
/** The line numbers paint */
protected Paint mPaintNumbers;
/** The line numbers paint */
protected Paint mPaintHighlight;
/** the offset value in dp */
protected int mPaddingDP = 6;
/** the padding scaled */
protected int mPadding, mLinePadding;
/** the scale for desnity pixels */
protected float mScale;
protected float mScaledDensity;
public interface OnAdvancedEditTextEvent {
boolean onLeftEdgeSwipe();
/** the scroller instance */
protected Scroller mTedScroller;
/** the velocity tracker */
protected GestureDetector mGestureDetector;
/** the Max size of the view */
protected Point mMaxSize;
boolean onTap();
/** the highlighted line index */
protected int mHighlightedLine;
protected int mHighlightStart;
void onPinchStart();
protected Rect mDrawingRect, mLineBounds;
protected boolean mFlingToScroll = true;
protected boolean mShowLineNumbers;
protected boolean mWordWrap;
private double mInitialPinchDistance;
protected OnAdvancedEditTextEvent mOnAdvancedEditTextEvent;
private int mFirstVisibleLine;
private boolean mSkipNextFling;
void onPinchZoom(double scale);
}
}

View file

@ -27,7 +27,6 @@ package net.pierrox.lightning_launcher;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.view.View;
import android.widget.Toast;
@ -145,9 +144,7 @@ public abstract class LLAppPhone extends LLApp {
public boolean isLightningIntent(Intent intent) {
ComponentName cn = intent.getComponent();
if (cn != null) {
if(cn.getPackageName().equals(getPackageName()) && cn.getClassName().equals(Dashboard.class.getName())) {
return true;
}
return cn.getPackageName().equals(getPackageName()) && cn.getClassName().equals(Dashboard.class.getName());
}
return false;
}

View file

@ -39,7 +39,6 @@ import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
@ -68,7 +67,6 @@ import net.pierrox.lightning_launcher.api.ScreenIdentity;
import net.pierrox.lightning_launcher.configuration.GlobalConfig;
import net.pierrox.lightning_launcher.configuration.ItemConfig;
import net.pierrox.lightning_launcher.configuration.PageConfig;
import net.pierrox.lightning_launcher.data.State;
import net.pierrox.lightning_launcher.configuration.SystemConfig;
import net.pierrox.lightning_launcher.data.ContainerPath;
import net.pierrox.lightning_launcher.data.EventAction;
@ -80,6 +78,7 @@ import net.pierrox.lightning_launcher.data.LightningIntent;
import net.pierrox.lightning_launcher.data.Page;
import net.pierrox.lightning_launcher.data.PageIndicator;
import net.pierrox.lightning_launcher.data.Shortcut;
import net.pierrox.lightning_launcher.data.State;
import net.pierrox.lightning_launcher.data.Utils;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher.engine.Screen;
@ -122,17 +121,34 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
private static final int ACTION_BAR_CHILD_DRAWER_ACTIONS = 0;
private static final int ACTION_BAR_CHILD_SEARCH = 1;
private static final int ACTION_BAR_CHILD_BATCH = 2;
private static final Matrix sIdentityTransform = new Matrix();
private final Matrix mSavedItemLayoutLocalTransformCustom = new Matrix();
private final Matrix mSavedItemLayoutLocalTransformByName = new Matrix();
private int mLayoutMode;
private boolean mSearchMode;
private EditTextIme mSearchField;
private ItemLayout mItemLayout;
private ViewAnimator mActionBar;
private final SharedAsyncGraphicsDrawable.SharedAsyncGraphicsDrawableListener mActionBarSharedDrawableListener = new SharedAsyncGraphicsDrawable.SharedAsyncGraphicsDrawableListener() {
@Override
public void onSharedAsyncGraphicsDrawableInvalidated(SharedAsyncGraphicsDrawable drawable) {
mActionBar.invalidate();
}
@Override
public void onSharedAsyncGraphicsDrawableSizeChanged(SharedAsyncGraphicsDrawable drawable) {
mActionBar.requestLayout();
}
};
private final Runnable mHideCustomActionBarRunnable = new Runnable() {
@Override
public void run() {
hideCustomActionBar();
}
};
private TextView mModeIcon;
private TextView mBatchCount;
private TextView mBatchAdd;
private Page mDrawerPage;
private ArrayList<Integer> mAllDrawerPageIDs; // gather ids of all pages displayed in the app drawer, including folders
private State mState;
@ -146,17 +162,40 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
private boolean mBatchMode;
private Drawable mActionBarBackground = null;
private boolean mResumed;
private static Matrix sIdentityTransform = new Matrix();
private Matrix mSavedItemLayoutLocalTransformCustom = new Matrix();
private Matrix mSavedItemLayoutLocalTransformByName = new Matrix();
private ComponentName mThisCn;
private ComponentName mDashboardCn;
private Animation mLayoutModeSwitchAnimation;
/*private void checkIfRefreshIsNeeded() {
final ArrayList<Item> items = new ArrayList<Item>();
addAppsFromPage(Utils.APP_DRAWER_PAGE, items);
new AsyncTask<Void,Void,Boolean>() {
@Override
protected Boolean doInBackground(Void... params) {
long t= SystemClock.uptimeMillis();
PackageManager pm=getPackageManager();
Intent intent_filter=new Intent(Intent.ACTION_MAIN, null);
intent_filter.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> ris=pm.queryIntentActivities(intent_filter, 0);
return ris.size() != items.size();
}
@Override
protected void onPostExecute(Boolean differ) {
if(differ) {
refreshAppDrawerItems(true);
}
}
}.execute((Void)null);
}*/
private int mNextLayoutMode;
public static File getAppDrawerActionBarBackgroundFile(Page drawer_page) {
return new File(drawer_page.getIconDir(), FileUtils.SUFFIX_APP_DRAWER_AB_BACKGROUND);
}
@Override
protected void createActivity(Bundle savedInstanceState) {
mThisCn = new ComponentName(this, AppDrawerX.class);
@ -199,41 +238,41 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
Typeface typeface = LLApp.get().getIconsTypeface();
mModeIcon = (TextView)findViewById(R.id.drawer_mode_icon);
mModeIcon = findViewById(R.id.drawer_mode_icon);
mModeIcon.setTypeface(typeface);
mSearchField=(EditTextIme)findViewById(R.id.drawer_search_field);
mSearchField = findViewById(R.id.drawer_search_field);
mSearchField.setHint(getString(R.string.an_sa));
mSearchField.setOnEditTextImeListener(this);
mSearchField.addTextChangedListener(this);
mSearchField.setOnEditorActionListener(this);
final TextView batch_ok = (TextView) findViewById(R.id.batch_ok);
final TextView batch_ok = findViewById(R.id.batch_ok);
batch_ok.setTypeface(typeface);
batch_ok.setOnClickListener(this);
mBatchCount = (TextView) findViewById(R.id.batch_count);
mBatchCount = findViewById(R.id.batch_count);
mBatchCount.setOnClickListener(this);
mBatchAdd = (TextView) findViewById(R.id.batch_add);
mBatchAdd = findViewById(R.id.batch_add);
mBatchAdd.setTypeface(typeface);
mBatchAdd.setOnClickListener(this);
mItemLayout=(ItemLayout)findViewById(R.id.drawer_il);
mItemLayout = findViewById(R.id.drawer_il);
mScreen.takeItemLayoutOwnership(mItemLayout);
findViewById(R.id.drawer_mode_grp).setOnClickListener(this);
TextView btn;
btn = (TextView) findViewById(R.id.drawer_zoom);
btn = findViewById(R.id.drawer_zoom);
btn.setOnClickListener(this);
btn.setTypeface(typeface);
btn = (TextView) findViewById(R.id.drawer_search);
btn = findViewById(R.id.drawer_search);
btn.setOnClickListener(this);
btn.setTypeface(typeface);
btn = (TextView) findViewById(R.id.drawer_more);
btn = findViewById(R.id.drawer_more);
btn.setOnClickListener(this);
btn.setTypeface(typeface);
mActionBar = (ViewAnimator) findViewById(R.id.ab);
mActionBar = findViewById(R.id.ab);
loadState();
@ -261,31 +300,6 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
}
}
/*private void checkIfRefreshIsNeeded() {
final ArrayList<Item> items = new ArrayList<Item>();
addAppsFromPage(Utils.APP_DRAWER_PAGE, items);
new AsyncTask<Void,Void,Boolean>() {
@Override
protected Boolean doInBackground(Void... params) {
long t= SystemClock.uptimeMillis();
PackageManager pm=getPackageManager();
Intent intent_filter=new Intent(Intent.ACTION_MAIN, null);
intent_filter.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> ris=pm.queryIntentActivities(intent_filter, 0);
return ris.size() != items.size();
}
@Override
protected void onPostExecute(Boolean differ) {
if(differ) {
refreshAppDrawerItems(true);
}
}
}.execute((Void)null);
}*/
@Override
protected void destroyActivity() {
// pass disable code from super
@ -366,6 +380,16 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
return super.closeBubble();
}
// @Override
// protected void myStartActivityForResult(Intent intent, int requestCode) {
// realStartActivityForResult(intent, requestCode);
// }
//
// @Override
// protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// myOnActivityResult(requestCode, resultCode, data);
// }
@Override
protected void configureActivity(Page page) {
super.configureActivity(page);
@ -415,33 +439,11 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
mActionBar.setBackgroundDrawable(mActionBarBackground);
}
private SharedAsyncGraphicsDrawable.SharedAsyncGraphicsDrawableListener mActionBarSharedDrawableListener = new SharedAsyncGraphicsDrawable.SharedAsyncGraphicsDrawableListener() {
@Override
public void onSharedAsyncGraphicsDrawableInvalidated(SharedAsyncGraphicsDrawable drawable) {
mActionBar.invalidate();
}
@Override
public void onSharedAsyncGraphicsDrawableSizeChanged(SharedAsyncGraphicsDrawable drawable) {
mActionBar.requestLayout();
}
};
@Override
protected int getActionBarHeight() {
return mDrawerPage.config.adHideActionBar || mIsAndroidActionBarDisplayed ? 0 : getResources().getDimensionPixelSize(R.dimen.ab_height);
}
// @Override
// protected void myStartActivityForResult(Intent intent, int requestCode) {
// realStartActivityForResult(intent, requestCode);
// }
//
// @Override
// protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// myOnActivityResult(requestCode, resultCode, data);
// }
@Override
protected boolean goBack() {
if (mActionBar.getDisplayedChild() == ACTION_BAR_CHILD_BATCH) {
@ -460,10 +462,6 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
return false;
}
public static File getAppDrawerActionBarBackgroundFile(Page drawer_page) {
return new File(drawer_page.getIconDir(), FileUtils.SUFFIX_APP_DRAWER_AB_BACKGROUND);
}
private boolean isSelectForAdd() {
return getIntent().hasExtra(INTENT_EXTRA_SELECT_FOR_ADD);
}
@ -1153,7 +1151,8 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
} else {
addBubbleItem(R.id.mi_actions, R.string.mi_actions);
}
if(item.getPage().isFolder()) addBubbleItem(R.id.mi_move_out_of_folder, R.string.mi_move_out_of_folder);
if (item.getPage().isFolder())
addBubbleItem(R.id.mi_move_out_of_folder, R.string.mi_move_out_of_folder);
} else if (mode == BUBBLE_MODE_ITEM_POSITION) {
ItemConfig ic = item.getItemConfig();
addBubbleItem(R.id.mi_pin, ic.pinMode != ItemConfig.PinMode.NONE ? R.string.mi_unpin : R.string.mi_pin);
@ -1181,12 +1180,18 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
addBubbleItem(R.id.mi_vov, toBold(R.string.v_ov, handling == Item.APP_DRAWER_HIDDEN_ONLY_VISIBLE));
addBubbleItem(R.id.mi_voh, toBold(R.string.v_oh, handling == Item.APP_DRAWER_HIDDEN_ONLY_HIDDEN));
} else if (mode == BUBBLE_MODE_DRAWER_MODE) {
if(hasMode(Utils.LAYOUT_MODE_CUSTOM)) addBubbleItem(R.id.mi_mode_custom, R.string.mi_mode_custom);
if(hasMode(Utils.LAYOUT_MODE_BY_NAME)) addBubbleItem(R.id.mi_mode_by_name, R.string.mi_mode_by_name);
if(hasMode(Utils.LAYOUT_MODE_FREQUENTLY_USED)) addBubbleItem(R.id.mi_mode_frequently_used, R.string.mi_mode_frequently_used);
if(hasMode(Utils.LAYOUT_MODE_RECENT_APPS)) addBubbleItem(R.id.mi_mode_recent_apps, R.string.mi_mode_recent_apps);
if(hasMode(Utils.LAYOUT_MODE_RECENTLY_UPDATED)) addBubbleItem(R.id.mi_mode_recently_updated, R.string.mi_mode_recently_updated);
if(hasMode(Utils.LAYOUT_MODE_RUNNING)) addBubbleItem(R.id.mi_mode_running, R.string.mi_mode_running);
if (hasMode(Utils.LAYOUT_MODE_CUSTOM))
addBubbleItem(R.id.mi_mode_custom, R.string.mi_mode_custom);
if (hasMode(Utils.LAYOUT_MODE_BY_NAME))
addBubbleItem(R.id.mi_mode_by_name, R.string.mi_mode_by_name);
if (hasMode(Utils.LAYOUT_MODE_FREQUENTLY_USED))
addBubbleItem(R.id.mi_mode_frequently_used, R.string.mi_mode_frequently_used);
if (hasMode(Utils.LAYOUT_MODE_RECENT_APPS))
addBubbleItem(R.id.mi_mode_recent_apps, R.string.mi_mode_recent_apps);
if (hasMode(Utils.LAYOUT_MODE_RECENTLY_UPDATED))
addBubbleItem(R.id.mi_mode_recently_updated, R.string.mi_mode_recently_updated);
if (hasMode(Utils.LAYOUT_MODE_RUNNING))
addBubbleItem(R.id.mi_mode_running, R.string.mi_mode_running);
} else {
super.configureBubbleForContainer(mode, il);
}
@ -1221,11 +1226,16 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
@Override
protected boolean displayBubbleButtonsForMode(int mode) {
switch (mode) {
case BUBBLE_MODE_DRAWER_MENU: return true;
case BUBBLE_MODE_DRAWER_MODE: return false;
case BUBBLE_MODE_DRAWER_VISIBILITY: return false;
case BUBBLE_MODE_ITEM_NO_EM: return mLayoutMode == Utils.LAYOUT_MODE_CUSTOM;
default: return super.displayBubbleButtonsForMode(mode);
case BUBBLE_MODE_DRAWER_MENU:
return true;
case BUBBLE_MODE_DRAWER_MODE:
return false;
case BUBBLE_MODE_DRAWER_VISIBILITY:
return false;
case BUBBLE_MODE_ITEM_NO_EM:
return mLayoutMode == Utils.LAYOUT_MODE_CUSTOM;
default:
return super.displayBubbleButtonsForMode(mode);
}
}
@ -1289,9 +1299,15 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
case R.id.mi_voh:
int vis = 0;
switch (id) {
case R.id.mi_va: vis = Item.APP_DRAWER_HIDDEN_ALL; break;
case R.id.mi_voh: vis = Item.APP_DRAWER_HIDDEN_ONLY_HIDDEN; break;
case R.id.mi_vov: vis = Item.APP_DRAWER_HIDDEN_ONLY_VISIBLE; break;
case R.id.mi_va:
vis = Item.APP_DRAWER_HIDDEN_ALL;
break;
case R.id.mi_voh:
vis = Item.APP_DRAWER_HIDDEN_ONLY_HIDDEN;
break;
case R.id.mi_vov:
vis = Item.APP_DRAWER_HIDDEN_ONLY_VISIBLE;
break;
}
il = mScreen.getTargetOrTopmostItemLayout();
@ -1644,13 +1660,6 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
mActionBar.startAnimation(as);
}
private Runnable mHideCustomActionBarRunnable = new Runnable() {
@Override
public void run() {
hideCustomActionBar();
}
};
private void moveFolderItemsToDrawer(ItemView folderItemView) {
FolderView fv = mScreen.findFolderView(folderItemView, null);
if (fv == null) {
@ -1673,7 +1682,7 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
}
private class MergedPage extends Page {
private HashSet<Integer> mPageIds;
private final HashSet<Integer> mPageIds;
public MergedPage(LightningEngine engine, PageConfig c, ArrayList<Item> items) {
super(engine, Page.MERGED_APP_DRAWER_PAGE);
@ -1830,7 +1839,7 @@ public class AppDrawerX extends Dashboard implements EditTextIme.OnEditTextImeLi
int x_max = (int) (mItemLayout.getWidth() / (mItemLayout.getCurrentScale() * mItemLayout.getCellWidth()));
if (x_max < 1) x_max = 1;
if (x_max > 40) x_max = 40;
float scale=mItemLayout.getWidth()/(float)(x_max*mItemLayout.getCellWidth())-0.001f;
float scale = mItemLayout.getWidth() / (x_max * mItemLayout.getCellWidth()) - 0.001f;
mItemLayout.animateZoomTo(ItemLayout.POSITION_FREE, scale);
}
}

View file

@ -24,40 +24,6 @@ SOFTWARE.
package net.pierrox.lightning_launcher.activities;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import net.pierrox.lightning_launcher.API;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.configuration.GlobalConfig;
import net.pierrox.lightning_launcher.data.BackupRestoreTool;
import net.pierrox.lightning_launcher.data.FileUtils;
import net.pierrox.lightning_launcher.data.Item;
import net.pierrox.lightning_launcher.data.Page;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher.data.PageProcessor;
import net.pierrox.lightning_launcher.data.Utils;
import net.pierrox.lightning_launcher.data.Widget;
import net.pierrox.lightning_launcher.script.ScriptManager;
import net.pierrox.lightning_launcher.script.Script;
import net.pierrox.lightning_launcher.template.LLTemplateAPI;
import net.pierrox.lightning_launcher_extreme.R;
import org.json.JSONException;
import org.json.JSONObject;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
@ -89,52 +55,49 @@ import android.widget.CheckBox;
import android.widget.RadioButton;
import android.widget.Toast;
import net.pierrox.lightning_launcher.API;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.configuration.GlobalConfig;
import net.pierrox.lightning_launcher.data.BackupRestoreTool;
import net.pierrox.lightning_launcher.data.FileUtils;
import net.pierrox.lightning_launcher.data.Item;
import net.pierrox.lightning_launcher.data.Page;
import net.pierrox.lightning_launcher.data.PageProcessor;
import net.pierrox.lightning_launcher.data.Utils;
import net.pierrox.lightning_launcher.data.Widget;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher.script.Script;
import net.pierrox.lightning_launcher.script.ScriptManager;
import net.pierrox.lightning_launcher.template.LLTemplateAPI;
import net.pierrox.lightning_launcher_extreme.R;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ApplyTemplate extends ResourceWrapperActivity {
/*package*/ static final String INTENT_EXTRA_PATH = "p";
/*package*/ static final String INTENT_EXTRA_URI = "u";
private static final int DIALOG_CONFIRM_APPLY = 1;
private static final int DIALOG_NEED_UPGRADE = 2;
private static final int DIALOG_WARNING = 3;
private static final int REQUEST_BIND_APPWIDGET = 1;
private static final int REQUEST_SELECT_SCREEN_FOR_GOTO = 2;
/*package*/ static final String INTENT_EXTRA_PATH = "p";
/*package*/ static final String INTENT_EXTRA_URI = "u";
private enum ApplyMode {
REPLACE,
MERGE,
UPDATE
}
private ComponentName mTemplateCN;
private String mTemplateDisplayName;
private File mTemplateFile;
private Uri mTemplateUri;
private boolean mBackupFirst;
private ApplyMode mApplyMode = ApplyMode.MERGE;
private boolean mLoadWallpaper;
private int mLLVersionFrom;
private boolean mWarningFreeVersion;
private boolean mWarningScreen;
private boolean mWarningWidget;
private SparseArray<ComponentName> mAppWidgetsToBind;
private ParcelableSparseIntArray mNewAppWidgetIds;
private int mBindWidgetOldId;
private int mBindWidgetNewId;
private int mFromScreenDpi;
private int mFromScreenWidth;
private int mFromScreenHeight;
private int mFromStatusBarHeight;
private File mAppBaseDir;
private ArrayList<Page> mImportedPages;
private static Method sBindAppWidgetIdIfAllowed;
static {
@ -144,6 +107,30 @@ public class ApplyTemplate extends ResourceWrapperActivity {
}
}
private ComponentName mTemplateCN;
private String mTemplateDisplayName;
private File mTemplateFile;
private Uri mTemplateUri;
private boolean mBackupFirst;
private ApplyMode mApplyMode = ApplyMode.MERGE;
private boolean mLoadWallpaper;
private int mLLVersionFrom;
private boolean mWarningFreeVersion;
private boolean mWarningScreen;
private boolean mWarningWidget;
private SparseArray<ComponentName> mAppWidgetsToBind;
private ParcelableSparseIntArray mNewAppWidgetIds;
private int mBindWidgetOldId;
private int mBindWidgetNewId;
private int mFromScreenDpi;
private int mFromScreenWidth;
private int mFromScreenHeight;
private int mFromStatusBarHeight;
private File mAppBaseDir;
private ArrayList<Page> mImportedPages;
private ProgressDialog mDialog;
private LinkedList<Pair<Integer, File>> mAppWidgetsToLoad;
@Override
protected void onCreate(Bundle savedInstanceState) {
Utils.setTheme(this, Utils.APP_THEME);
@ -255,10 +242,10 @@ public class ApplyTemplate extends ResourceWrapperActivity {
builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.apply_tmpl_t);
final View content = getLayoutInflater().inflate(R.layout.dialog_apply_tmpl, null);
final RadioButton rb_replace = (RadioButton) content.findViewById(R.id.tmpl_r);
final RadioButton rb_merge = (RadioButton) content.findViewById(R.id.tmpl_m);
final CheckBox cb_backup = (CheckBox) content.findViewById(R.id.tmpl_b);
final CheckBox cb_wallpaper = (CheckBox) content.findViewById(R.id.tmpl_w);
final RadioButton rb_replace = content.findViewById(R.id.tmpl_r);
final RadioButton rb_merge = content.findViewById(R.id.tmpl_m);
final CheckBox cb_backup = content.findViewById(R.id.tmpl_b);
final CheckBox cb_wallpaper = content.findViewById(R.id.tmpl_w);
rb_replace.setText(R.string.tmpl_r);
rb_merge.setText(R.string.tmpl_m);
@ -370,7 +357,10 @@ public class ApplyTemplate extends ResourceWrapperActivity {
if (is != null) {
JSONObject manifest = BackupRestoreTool.readManifest(is);
try { is.close(); } catch(IOException e) {}
try {
is.close();
} catch (IOException e) {
}
return manifest;
} else {
return null;
@ -416,8 +406,6 @@ public class ApplyTemplate extends ResourceWrapperActivity {
}.execute((Void) null);
}
private ProgressDialog mDialog;
private File getExtractedTemplateDir() {
String tempTemplatePath = FileUtils.LL_TMP_DIR + "/template";
return new File(tempTemplatePath);
@ -745,8 +733,6 @@ public class ApplyTemplate extends ResourceWrapperActivity {
}
}
private LinkedList<Pair<Integer,File>> mAppWidgetsToLoad;
private void updateAppWidgetIds() {
mAppWidgetsToLoad = new LinkedList<Pair<Integer, File>>();
@ -789,7 +775,7 @@ public class ApplyTemplate extends ResourceWrapperActivity {
double from_screen_phys_width = (double) mFromScreenWidth / mFromScreenDpi;
double to_screen_phys_width = (double) dm.widthPixels / dm.densityDpi;
File patched_widget_file = new File(FileUtils.LL_TMP_DIR, String.valueOf(old_id) + "p");
File patched_widget_file = new File(FileUtils.LL_TMP_DIR, old_id + "p");
FileInputStream fis = null;
FileOutputStream fos = null;
ZipInputStream zis = null;
@ -850,7 +836,7 @@ public class ApplyTemplate extends ResourceWrapperActivity {
// json.put("preset_dpiheight", (int)(json.getDouble("preset_dpiheight") * ratio_height / ratio_dpi));
// json.put("pref_widget_scale", widget_scale * (widget_width>widget_height ? ratio_width : ratio_height));
zos.write(json.toString().getBytes("utf-8"));
zos.write(json.toString().getBytes(StandardCharsets.UTF_8));
} else {
while ((n = zis.read(buffer, 0, buffer.length)) > 0) {
zos.write(buffer, 0, n);
@ -987,6 +973,12 @@ public class ApplyTemplate extends ResourceWrapperActivity {
}
}
private enum ApplyMode {
REPLACE,
MERGE,
UPDATE
}
private static class ParcelableSparseIntArray implements Cloneable, Parcelable {
public static final Creator<ParcelableSparseIntArray> CREATOR = new Creator<ParcelableSparseIntArray>() {
@Override
@ -1004,6 +996,19 @@ public class ApplyTemplate extends ResourceWrapperActivity {
return new ParcelableSparseIntArray[size];
}
};
private int[] mKeys;
private int mSize;
private int[] mValues;
public ParcelableSparseIntArray() {
this(10);
}
public ParcelableSparseIntArray(int initialCapacity) {
mKeys = new int[initialCapacity];
mValues = new int[initialCapacity];
mSize = 0;
}
private static int binarySearch(int[] a, int start, int len, int key) {
int high = start + len, low = start - 1, guess;
@ -1024,22 +1029,6 @@ public class ApplyTemplate extends ResourceWrapperActivity {
}
}
private int[] mKeys;
private int mSize;
private int[] mValues;
public ParcelableSparseIntArray() {
this(10);
}
public ParcelableSparseIntArray(int initialCapacity) {
mKeys = new int[initialCapacity];
mValues = new int[initialCapacity];
mSize = 0;
}
// public ParcelableSparseIntArray(ParcelableSparseIntArray arrayForCopy) {
// if (arrayForCopy == null) {
// int initialCapacity = arrayForCopy.mSize;

View file

@ -24,33 +24,6 @@ SOFTWARE.
package net.pierrox.lightning_launcher.activities;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import net.pierrox.lightning_launcher.API;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.data.BackupRestoreTool;
import net.pierrox.lightning_launcher.data.FileUtils;
import net.pierrox.lightning_launcher.data.Folder;
import net.pierrox.lightning_launcher.data.Item;
import net.pierrox.lightning_launcher.data.Page;
import net.pierrox.lightning_launcher.data.Utils;
import net.pierrox.lightning_launcher.util.FileProvider;
import net.pierrox.lightning_launcher_extreme.R;
import org.json.JSONObject;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
@ -79,6 +52,33 @@ import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import net.pierrox.lightning_launcher.API;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.data.BackupRestoreTool;
import net.pierrox.lightning_launcher.data.FileUtils;
import net.pierrox.lightning_launcher.data.Folder;
import net.pierrox.lightning_launcher.data.Item;
import net.pierrox.lightning_launcher.data.Page;
import net.pierrox.lightning_launcher.data.Utils;
import net.pierrox.lightning_launcher.util.FileProvider;
import net.pierrox.lightning_launcher_extreme.R;
import org.json.JSONObject;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
public class BackupRestore extends ResourceWrapperActivity implements View.OnClickListener, AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener, OnLongClickListener {
private static final int DIALOG_BACKUP_IN_PROGRESS = 1;
private static final int DIALOG_RESTORE_IN_PROGRESS = 2;
@ -106,25 +106,25 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
setContentView(R.layout.backup_restore);
Button backup = (Button) findViewById(R.id.backup);
Button backup = findViewById(R.id.backup);
backup.setText(R.string.backup_t);
backup.setOnClickListener(this);
Button import_ = (Button) findViewById(R.id.import_);
Button import_ = findViewById(R.id.import_);
import_.setText(R.string.import_t);
import_.setOnClickListener(this);
import_.setOnLongClickListener(this);
Button export = (Button) findViewById(R.id.export);
Button export = findViewById(R.id.export);
export.setText(R.string.tmpl_e_t);
export.setOnClickListener(this);
export.setOnLongClickListener(this);
mListView = (ListView) findViewById(R.id.archives);
mListView = findViewById(R.id.archives);
mListView.setOnItemClickListener(this);
mListView.setOnItemLongClickListener(this);
mEmptyView = (TextView) findViewById(R.id.empty);
mEmptyView = findViewById(R.id.empty);
mEmptyView.setText(R.string.no_backup_archive);
loadArchivesList();
@ -338,7 +338,10 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
break;
case 2:
try { removeDialog(DIALOG_SELECT_ARCHIVE_NAME); } catch(Exception e) {}
try {
removeDialog(DIALOG_SELECT_ARCHIVE_NAME);
} catch (Exception e) {
}
showDialog(DIALOG_SELECT_ARCHIVE_NAME);
break;
case 3:
@ -351,7 +354,10 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.br_s)));
break;
case 4:
try { removeDialog(DIALOG_CONFIRM_DELETE); } catch(Exception e) {}
try {
removeDialog(DIALOG_CONFIRM_DELETE);
} catch (Exception e) {
}
showDialog(DIALOG_CONFIRM_DELETE);
break;
}
@ -436,7 +442,10 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
private void exportArchive(boolean for_backup) {
mSelectArchiveNameForBackup = for_backup;
mArchiveName = null;
try { removeDialog(DIALOG_SELECT_ARCHIVE_NAME); } catch(Exception e) {}
try {
removeDialog(DIALOG_SELECT_ARCHIVE_NAME);
} catch (Exception e) {
}
showDialog(DIALOG_SELECT_ARCHIVE_NAME);
}
@ -497,8 +506,95 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
}.execute((Void) null);
}
/**
* Request the user to pick an archive.
*
* @param only_load true to directly load the archive without first importing it in the LL_EXT_DIR directory.
*/
private void selectFileToLoadOrImport(boolean only_load) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, getString(R.string.import_t)), only_load ? REQUEST_SELECT_FILE_TO_LOAD : REQUEST_SELECT_FILE_TO_IMPORT);
}
@SuppressLint("StaticFieldLeak")
private void importFile(final Uri uri) {
new AsyncTask<Void, Void, File>() {
private ProgressDialog mDialog;
@Override
protected void onPreExecute() {
mDialog = new ProgressDialog(BackupRestore.this);
mDialog.setMessage(getString(R.string.importing));
mDialog.setCancelable(false);
mDialog.show();
}
@Override
protected File doInBackground(Void... voids) {
InputStream is = null;
FileOutputStream os = null;
File outFile = null;
try {
String name = getNameForUri(uri);
outFile = new File(FileUtils.LL_EXT_DIR, name);
is = getContentResolver().openInputStream(uri);
os = new FileOutputStream(outFile);
FileUtils.copyStream(is, os);
return outFile;
} catch (IOException e) {
if (outFile != null) {
outFile.delete();
}
return null;
} finally {
try {
if (is != null) is.close();
} catch (IOException e) {
}
try {
if (os != null) os.close();
} catch (IOException e) {
}
}
}
@Override
protected void onPostExecute(File outFile) {
mDialog.dismiss();
if (outFile != null) {
loadArchivesList();
loadArchive(null, outFile.getName());
} else {
Toast.makeText(BackupRestore.this, R.string.import_e, Toast.LENGTH_SHORT).show();
}
}
}.execute((Void) null);
}
private String getNameForUri(Uri uri) {
String name = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = getContentResolver().query(uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
name = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
cursor.close();
}
}
if (name == null) {
name = uri.getLastPathSegment();
}
return name;
}
private class BackupTask extends AsyncTask<String, Void, Exception> {
private String mBackupFilePath;
@Override
protected void onPreExecute() {
showDialog(DIALOG_BACKUP_IN_PROGRESS);
@ -506,7 +602,7 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
@Override
protected Exception doInBackground(String... params) {
mBackupFilePath=(String)params[0];
mBackupFilePath = params[0];
BackupRestoreTool.BackupConfig backup_config = new BackupRestoreTool.BackupConfig();
@ -553,7 +649,7 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
}
private class RestoreTask extends AsyncTask<String, Void, Integer> {
private Uri mUri;
private final Uri mUri;
private RestoreTask(String path) {
mUri = Uri.fromFile(new File(path));
@ -584,7 +680,10 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
} catch (Exception e) {
// not a template, continue with normal restore
} finally {
if(is != null) try { is.close(); } catch (IOException e) {}
if (is != null) try {
is.close();
} catch (IOException e) {
}
}
restore_config.context = BackupRestore.this;
@ -627,83 +726,4 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
}
}
}
/**
* Request the user to pick an archive.
* @param only_load true to directly load the archive without first importing it in the LL_EXT_DIR directory.
*/
private void selectFileToLoadOrImport(boolean only_load) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, getString(R.string.import_t)), only_load ? REQUEST_SELECT_FILE_TO_LOAD : REQUEST_SELECT_FILE_TO_IMPORT);
}
@SuppressLint("StaticFieldLeak")
private void importFile(final Uri uri) {
new AsyncTask<Void, Void, File>() {
private ProgressDialog mDialog;
@Override
protected void onPreExecute() {
mDialog = new ProgressDialog(BackupRestore.this);
mDialog.setMessage(getString(R.string.importing));
mDialog.setCancelable(false);
mDialog.show();
}
@Override
protected File doInBackground(Void... voids) {
InputStream is = null;
FileOutputStream os = null;
File outFile = null;
try {
String name = getNameForUri(uri);
outFile = new File(FileUtils.LL_EXT_DIR, name);
is = getContentResolver().openInputStream(uri);
os = new FileOutputStream(outFile);
FileUtils.copyStream(is, os);
return outFile;
} catch (IOException e) {
if(outFile != null) {
outFile.delete();
}
return null;
} finally {
try { if(is != null) is.close(); } catch(IOException e) {}
try { if(os != null) os.close(); } catch(IOException e) {}
}
}
@Override
protected void onPostExecute(File outFile) {
mDialog.dismiss();
if(outFile != null) {
loadArchivesList();
loadArchive(null, outFile.getName());
} else {
Toast.makeText(BackupRestore.this, R.string.import_e, Toast.LENGTH_SHORT).show();
}
}
}.execute((Void) null);
}
private String getNameForUri(Uri uri) {
String name = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = getContentResolver().query(uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
name = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
cursor.close();
}
}
if (name == null) {
name = uri.getLastPathSegment();
}
return name;
}
}

View file

@ -91,6 +91,35 @@ public class EventActionSetup extends ResourceWrapperActivity implements Adapter
private boolean mEventActionForPickNew;
private LightningEngine mAppEngine;
public static void startActivityForResult(Activity activity, EventAction ea, boolean forItem, int type, boolean forShortcut, int requestCode) {
Intent intent = new Intent(activity, EventActionSetup.class);
intent.putExtra(INTENT_EXTRA_FOR_ITEM, forItem);
intent.putExtra(INTENT_EXTRA_FOR_SHORTCUT, forShortcut);
intent.putExtra(INTENT_EXTRA_TYPE, type);
if (ea != null) {
JSONObject out = new JSONObject();
JsonLoader.toJSONObject(out, ea, null);
intent.putExtra(INTENT_EXTRA_EVENT_ACTION_LIST, out.toString());
}
activity.startActivityForResult(intent, requestCode);
}
public static EventAction getEventActionFromIntent(Intent intent) {
String s = intent.getStringExtra(INTENT_EXTRA_EVENT_ACTION_LIST);
if (s != null) {
try {
JSONObject json = new JSONObject(s);
EventAction ea = new EventAction();
JsonLoader.loadFieldsFromJSONObject(ea, json, null);
return ea;
} catch (JSONException e) {
// pass
}
}
return null;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
Utils.setTheme(this, Utils.APP_THEME_NO_ACTION_BAR);
@ -167,7 +196,7 @@ public class EventActionSetup extends ResourceWrapperActivity implements Adapter
setContentView(dialogContent);
final DragSortListView list = (DragSortListView) dialogContent.findViewById(android.R.id.list);
final DragSortListView list = dialogContent.findViewById(android.R.id.list);
mAdapter = new EventActionAdapter(this, mEventActions);
list.setAdapter(mAdapter);
list.setOnItemClickListener(this);
@ -218,35 +247,6 @@ public class EventActionSetup extends ResourceWrapperActivity implements Adapter
}
}
public static void startActivityForResult(Activity activity, EventAction ea, boolean forItem, int type, boolean forShortcut, int requestCode) {
Intent intent = new Intent(activity, EventActionSetup.class);
intent.putExtra(INTENT_EXTRA_FOR_ITEM, forItem);
intent.putExtra(INTENT_EXTRA_FOR_SHORTCUT, forShortcut);
intent.putExtra(INTENT_EXTRA_TYPE, type);
if(ea != null) {
JSONObject out = new JSONObject();
JsonLoader.toJSONObject(out, ea, null);
intent.putExtra(INTENT_EXTRA_EVENT_ACTION_LIST, out.toString());
}
activity.startActivityForResult(intent, requestCode);
}
public static EventAction getEventActionFromIntent(Intent intent) {
String s = intent.getStringExtra(INTENT_EXTRA_EVENT_ACTION_LIST);
if(s != null) {
try {
JSONObject json = new JSONObject(s);
EventAction ea = new EventAction();
JsonLoader.loadFieldsFromJSONObject(ea, json, null);
return ea;
} catch (JSONException e) {
// pass
}
}
return null;
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
editAction(mAdapter.getItem(i), false);
@ -352,7 +352,10 @@ public class EventActionSetup extends ResourceWrapperActivity implements Adapter
Intent i = new Intent(Intent.ACTION_PICK_ACTIVITY);
i.putExtra(Intent.EXTRA_INTENT, new Intent(Intent.ACTION_CREATE_SHORTCUT));
i.putExtra(Intent.EXTRA_TITLE, getString(R.string.tools_pick_shortcut));
try { startActivityForResult(i, REQUEST_PICK_SHORTCUT1); } catch (Exception e) { }
try {
startActivityForResult(i, REQUEST_PICK_SHORTCUT1);
} catch (Exception e) {
}
} else if (new_action == GlobalConfig.RUN_SCRIPT) {
ScriptPickerDialog dialog = new ScriptPickerDialog(this, mAppEngine, ea.data, Script.TARGET_NONE, new ScriptPickerDialog.OnScriptPickerEvent() {
@Override
@ -441,58 +444,11 @@ public class EventActionSetup extends ResourceWrapperActivity implements Adapter
}
}
private class EventActionAdapter extends ArrayAdapter<EventAction> implements View.OnClickListener {
public EventActionAdapter(Context context, List<EventAction> objects) {
super(context, 0, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.event_action_item, parent, false);
TextView drag = (TextView) convertView.findViewById(R.id.drag);
drag.setTypeface(LLApp.get().getIconsTypeface());
TextView delete = (TextView) convertView.findViewById(R.id.delete);
delete.setOnClickListener(this);
delete.setTypeface(LLApp.get().getIconsTypeface());
}
EventAction ea = getItem(position);
TextView title = (TextView) convertView.findViewById(android.R.id.text1);
title.setText(mActions.getActionName(ea.action));
String summaryText = ea.describe(mAppEngine);
TextView summary = (TextView) convertView.findViewById(android.R.id.text2);
if(summaryText == null) {
title.setSingleLine(false);
title.setMaxLines(2);
summary.setVisibility(View.GONE);
} else {
title.setSingleLine(true);
summary.setVisibility(View.VISIBLE);
summary.setText(summaryText);
}
convertView.findViewById(R.id.delete).setTag(ea);
return convertView;
}
@Override
public void onClick(View view) {
EventAction ea = (EventAction) view.getTag();
mEventActions.remove(ea);
mAdapter.notifyDataSetChanged();
}
}
private static class ActionsAdapter extends ArrayAdapter<Action> {
private final LayoutInflater mInflater;
private int mPrefLayout;
private int mPrefCategoryLayout;
private final int mPrefLayout;
private final int mPrefCategoryLayout;
public ActionsAdapter(Context context, ActionsDescription actionsDescription) {
super(context, 0, filterActions(actionsDescription));
@ -534,7 +490,7 @@ public class EventActionSetup extends ResourceWrapperActivity implements Adapter
convertView = mInflater.inflate(isCategory ? mPrefCategoryLayout : mPrefLayout, parent, false);
}
TextView title_view = (TextView) convertView.findViewById(android.R.id.title);
TextView title_view = convertView.findViewById(android.R.id.title);
title_view.setText(action.label);
if (!isCategory) {
title_view.setSingleLine(false);
@ -547,4 +503,51 @@ public class EventActionSetup extends ResourceWrapperActivity implements Adapter
return convertView;
}
}
private class EventActionAdapter extends ArrayAdapter<EventAction> implements View.OnClickListener {
public EventActionAdapter(Context context, List<EventAction> objects) {
super(context, 0, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.event_action_item, parent, false);
TextView drag = convertView.findViewById(R.id.drag);
drag.setTypeface(LLApp.get().getIconsTypeface());
TextView delete = convertView.findViewById(R.id.delete);
delete.setOnClickListener(this);
delete.setTypeface(LLApp.get().getIconsTypeface());
}
EventAction ea = getItem(position);
TextView title = convertView.findViewById(android.R.id.text1);
title.setText(mActions.getActionName(ea.action));
String summaryText = ea.describe(mAppEngine);
TextView summary = convertView.findViewById(android.R.id.text2);
if (summaryText == null) {
title.setSingleLine(false);
title.setMaxLines(2);
summary.setVisibility(View.GONE);
} else {
title.setSingleLine(true);
summary.setVisibility(View.VISIBLE);
summary.setText(summaryText);
}
convertView.findViewById(R.id.delete).setTag(ea);
return convertView;
}
@Override
public void onClick(View view) {
EventAction ea = (EventAction) view.getTag();
mEventActions.remove(ea);
mAdapter.notifyDataSetChanged();
}
}
}

View file

@ -37,7 +37,6 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
@ -59,6 +58,12 @@ public class ImageCropper extends ResourceWrapperActivity implements View.OnClic
private TextView mSelectionText;
private CropperView mCropperView;
public static void startActivity(Activity from, File image, int requestCode) {
final Intent intent = new Intent(from, ImageCropper.class);
intent.putExtra(INTENT_EXTRA_IMAGE, image.getAbsolutePath());
from.startActivityForResult(intent, requestCode);
}
@Override
public void onCreate(Bundle savedInstanceState) {
Utils.setTheme(this, Utils.APP_THEME_NO_ACTION_BAR);
@ -66,9 +71,9 @@ public class ImageCropper extends ResourceWrapperActivity implements View.OnClic
setContentView(R.layout.image_cropper);
mSelectionText = (TextView) findViewById(R.id.sr);
mSelectionText = findViewById(R.id.sr);
mCropperView = (CropperView) findViewById(R.id.cv);
mCropperView = findViewById(R.id.cv);
Bitmap bitmap;
Intent intent = getIntent();
String sourcePath = intent.getStringExtra(INTENT_EXTRA_IMAGE);
@ -184,12 +189,12 @@ public class ImageCropper extends ResourceWrapperActivity implements View.OnClic
((TextView) content.findViewById(R.id.rect_b)).setText(getString(R.string.bottom));
((TextView) content.findViewById(R.id.rect_w)).setText(getString(R.string.gb_w).toLowerCase());
((TextView) content.findViewById(R.id.rect_h)).setText(getString(R.string.gb_h).toLowerCase());
final EditText el = (EditText)content.findViewById(R.id.rect_el);
final EditText et = (EditText)content.findViewById(R.id.rect_et);
final EditText er = (EditText)content.findViewById(R.id.rect_er);
final EditText eb = (EditText)content.findViewById(R.id.rect_eb);
final EditText ew = (EditText)content.findViewById(R.id.rect_ew);
final EditText eh = (EditText)content.findViewById(R.id.rect_eh);
final EditText el = content.findViewById(R.id.rect_el);
final EditText et = content.findViewById(R.id.rect_et);
final EditText er = content.findViewById(R.id.rect_er);
final EditText eb = content.findViewById(R.id.rect_eb);
final EditText ew = content.findViewById(R.id.rect_ew);
final EditText eh = content.findViewById(R.id.rect_eh);
el.setText(String.valueOf(selection.left));
et.setText(String.valueOf(selection.top));
er.setText(String.valueOf(selection.right));
@ -322,10 +327,4 @@ public class ImageCropper extends ResourceWrapperActivity implements View.OnClic
builder.setNegativeButton(android.R.string.cancel, null);
builder.create().show();
}
public static void startActivity(Activity from, File image, int requestCode) {
final Intent intent = new Intent(from, ImageCropper.class);
intent.putExtra(INTENT_EXTRA_IMAGE, image.getAbsolutePath());
from.startActivityForResult(intent, requestCode);
}
}

View file

@ -24,6 +24,8 @@ SOFTWARE.
package net.pierrox.lightning_launcher.activities;
import static android.content.ClipData.newPlainText;
import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
@ -47,7 +49,6 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
@ -88,8 +89,6 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static android.content.ClipData.newPlainText;
public class ImagePicker extends ResourceWrapperActivity implements AdapterView.OnItemSelectedListener, AdapterView.OnItemClickListener, View.OnClickListener, ColorPickerDialog.OnColorChangedListener, View.OnLongClickListener, AdapterView.OnItemLongClickListener, EditTextIme.OnEditTextImeListener, TextWatcher {
private static final int MODE_NONE = -1;
@ -151,18 +150,14 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
private int mLauncherIconDensity;
private View mClickedView;
private static class BitmapInfo {
Bitmap bitmap;
boolean isNinePatch; // need to be stored because 9patch chunk is lost during resize
private BitmapInfo(Bitmap bitmap, boolean isNinePatch) {
this.bitmap = bitmap;
this.isNinePatch = isNinePatch;
}
}
private LruCache<String, BitmapInfo> mThumbnailCache;
public static void startActivity(Activity from, int requestCode) {
final Intent intent = new Intent(from, ImagePicker.class);
intent.putExtra(INTENT_EXTRA_CROP, true);
from.startActivityForResult(intent, requestCode);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
Utils.setTheme(this, Utils.APP_THEME_NO_ACTION_BAR);
@ -236,35 +231,33 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
mCurrentScrollLauncherPage = prefs.getInt(PREF_CURRENT_SCROLL_LAUNCHER_PAGE, 0);
setContentView(R.layout.image_picker);
mSourceSpinner = (Spinner) findViewById(R.id.source);
mSourceSpinner = findViewById(R.id.source);
ArrayAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.ip_s));
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSourceSpinner.setAdapter(adapter);
mSourceSpinner.setOnItemSelectedListener(this);
mIconPackSpinner = (Spinner) findViewById(R.id.icon_pack);
mIconPackSpinner = findViewById(R.id.icon_pack);
mIconPackSpinner.setOnItemSelectedListener(this);
mPkgSpinner = (Spinner) findViewById(R.id.pkg);
mPkgSpinner = findViewById(R.id.pkg);
mPkgSpinner.setOnItemSelectedListener(this);
mLauncherPageSpinner = (Spinner) findViewById(R.id.launcher_page);
mLauncherPageSpinner = findViewById(R.id.launcher_page);
mLauncherPageSpinner.setOnItemSelectedListener(this);
mPathTextGrp = findViewById(R.id.path_grp);
mPathTextView = (TextView) findViewById(R.id.path);
Button up = (Button)findViewById(R.id.path_up);
mPathTextView = findViewById(R.id.path);
Button up = findViewById(R.id.path_up);
up.setText(R.string.file_picker_activity_up);
up.setOnClickListener(this);
mNoIconTextView = (TextView) findViewById(R.id.no_icon);
mNoIconTextView = findViewById(R.id.no_icon);
mNoIconTextView.setText(R.string.ip_e);
mGridView = (GridView) findViewById(R.id.grid);
mGridView = findViewById(R.id.grid);
mGridView.setNumColumns(GridView.AUTO_FIT);
mGridView.setColumnWidth(mStandardIconSize * 2);
mGridView.setStretchMode(GridView.STRETCH_SPACING_UNIFORM);
@ -287,7 +280,7 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
mBackgroundColor = prefs.getInt(PREF_BACKGROUND_COLOR, Color.TRANSPARENT);
mGridView.setBackgroundColor(mBackgroundColor);
mSearchText = (EditTextIme) findViewById(R.id.search_text);
mSearchText = findViewById(R.id.search_text);
mSearchText.setOnEditTextImeListener(this);
mSearchText.addTextChangedListener(this);
@ -445,8 +438,14 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
e.printStackTrace();
tmp_image_file.delete();
} finally {
if(is!=null) try { is.close(); } catch(Exception e) {}
if(fos!=null) try { fos.close(); } catch(Exception e) {}
if (is != null) try {
is.close();
} catch (Exception e) {
}
if (fos != null) try {
fos.close();
} catch (Exception e) {
}
}
} else if (mCurrentMode == MODE_LAUNCHER_PAGE) {
ImageFile imf = (ImageFile) item;
@ -536,12 +535,24 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
public boolean onLongClick(View view) {
int label_res = 0;
switch (view.getId()) {
case R.id.none: label_res = R.string.ip_none; break;
case R.id.ext_file: label_res = R.string.ip_ext_file; break;
case R.id.camera: label_res = R.string.ip_camera; break;
case R.id.bgcolor: label_res = R.string.ip_bgcolor; break;
case R.id.solid: label_res = R.string.ip_solid; break;
case R.id.search: label_res = R.string.ip_search; break;
case R.id.none:
label_res = R.string.ip_none;
break;
case R.id.ext_file:
label_res = R.string.ip_ext_file;
break;
case R.id.camera:
label_res = R.string.ip_camera;
break;
case R.id.bgcolor:
label_res = R.string.ip_bgcolor;
break;
case R.id.solid:
label_res = R.string.ip_solid;
break;
case R.id.search:
label_res = R.string.ip_search;
break;
}
Toast.makeText(this, label_res, Toast.LENGTH_SHORT).show();
return true;
@ -572,8 +583,14 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
} catch (IOException e) {
// pass
} finally {
if(fos != null) try { fos.close(); } catch(IOException e) {}
if(is != null) try { is.close(); } catch(IOException e) {}
if (fos != null) try {
fos.close();
} catch (IOException e) {
}
if (is != null) try {
is.close();
} catch (IOException e) {
}
}
}
break;
@ -591,12 +608,6 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
}
}
public static void startActivity(Activity from, int requestCode) {
final Intent intent = new Intent(from, ImagePicker.class);
intent.putExtra(INTENT_EXTRA_CROP, true);
from.startActivityForResult(intent, requestCode);
}
private void setGridViewAdapter(ListAdapter adapter) {
mNoIconTextView.setVisibility(adapter == null || adapter.getCount() == 0 ? View.VISIBLE : View.GONE);
mGridView.setAdapter(adapter);
@ -842,10 +853,18 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
int y = (index << 16) | offset;
switch (mGridMode) {
case MODE_PKG: mCurrentScrollPkg = y; break;
case MODE_PATH: mCurrentScrollPath = y; break;
case MODE_ICON_PACK: mCurrentScrollIconPack = y; break;
case MODE_LAUNCHER_PAGE: mCurrentScrollLauncherPage = y; break;
case MODE_PKG:
mCurrentScrollPkg = y;
break;
case MODE_PATH:
mCurrentScrollPath = y;
break;
case MODE_ICON_PACK:
mCurrentScrollIconPack = y;
break;
case MODE_LAUNCHER_PAGE:
mCurrentScrollLauncherPage = y;
break;
}
}
}
@ -874,7 +893,10 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if(fos != null) try { fos.close(); } catch(IOException e) {}
if (fos != null) try {
fos.close();
} catch (IOException e) {
}
}
@ -957,6 +979,16 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
}
private static class BitmapInfo {
Bitmap bitmap;
boolean isNinePatch; // need to be stored because 9patch chunk is lost during resize
private BitmapInfo(Bitmap bitmap, boolean isNinePatch) {
this.bitmap = bitmap;
this.isNinePatch = isNinePatch;
}
}
private static class PkgLabel {
String pkg;
String label;
@ -972,11 +1004,52 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
}
}
private static class ImageResource {
int res;
String packageName;
String label;
@Override
public String toString() {
return label;
}
}
private static class ImageFile {
File file;
private ImageFile(File file) {
this.file = file;
}
@Override
public String toString() {
return file.getName();
}
}
private static class TextFilter extends Filter {
TextFilter() {
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
return null;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
}
}
private abstract class MyFilterArrayAdapter<T> extends ArrayAdapter<T> {
private final Object mLock = new Object();
private Filter mFilter;
private List<T> mOriginalItems;
private List<T> mItems;
private final Object mLock = new Object();
public MyFilterArrayAdapter(Context context, int resource) {
@ -1065,9 +1138,6 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
}
}
private class PkgLabelAdapter extends MyFilterArrayAdapter<PkgLabel> {
public PkgLabelAdapter(Context context, boolean icon) {
@ -1132,21 +1202,9 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
}
}
private static class ImageResource {
int res;
String packageName;
String label;
@Override
public String toString() {
return label;
}
}
private class ImageResourceAdapter extends MyFilterArrayAdapter<ImageResource> {
private boolean mDisplayLabels;
private final boolean mDisplayLabels;
public ImageResourceAdapter(Context context, int resource, List<ImageResource> objects, boolean display_labels) {
super(context, resource);
@ -1164,8 +1222,8 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
final ImageResource ir = getItem(position);
final TextView title = (TextView) convertView.findViewById(R.id.label);
final ImageView thumbnail = (ImageView) convertView.findViewById(R.id.icon);
final TextView title = convertView.findViewById(R.id.label);
final ImageView thumbnail = convertView.findViewById(R.id.icon);
if (mDisplayLabels) {
title.setText(ir.label);
@ -1236,23 +1294,10 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
}
}
private static class ImageFile {
File file;
private ImageFile(File file) {
this.file = file;
}
@Override
public String toString() {
return file.getName();
}
}
private class ImageFileAdapter extends MyFilterArrayAdapter<ImageFile> {
private boolean mDisplayLabels;
private Bitmap mFolderIcon;
private final boolean mDisplayLabels;
private final Bitmap mFolderIcon;
public ImageFileAdapter(Context context, int resource, List<ImageFile> objects, boolean display_labels) {
super(context, resource);
@ -1274,8 +1319,8 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
final ImageFile imf = getItem(position);
final TextView title = (TextView) convertView.findViewById(R.id.label);
final ImageView thumbnail = (ImageView) convertView.findViewById(R.id.icon);
final TextView title = convertView.findViewById(R.id.label);
final ImageView thumbnail = convertView.findViewById(R.id.icon);
if (mDisplayLabels) {
title.setText(imf.file.getName());
@ -1335,21 +1380,4 @@ public class ImagePicker extends ResourceWrapperActivity implements AdapterView.
// return mDisplayLabels;
// }
}
private static class TextFilter extends Filter {
TextFilter() {
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
return null;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
}
}
}

View file

@ -32,12 +32,12 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.api.ScreenIdentity;
import net.pierrox.lightning_launcher.configuration.GlobalConfig;
@ -113,8 +113,6 @@ public class LockScreen extends Dashboard {
}
try {
Method getActionBar = getClass().getMethod("getActionBar");
Object action_bar = getActionBar.invoke(this, (Object[]) null);
@ -124,7 +122,6 @@ public class LockScreen extends Dashboard {
}
mNavigationStack = new Stack<Integer>();
LLApp llApp = LLApp.get();
@ -133,7 +130,7 @@ public class LockScreen extends Dashboard {
int lockScreen = globalConfig.lockScreen;
mLockScreenPage = engine.getOrLoadPage(lockScreen);
mItemLayout=(ItemLayout)findViewById(R.id.drawer_il);
mItemLayout = findViewById(R.id.drawer_il);
mScreen.takeItemLayoutOwnership(mItemLayout);
mItemLayout.setHonourFocusChange(false);
mItemLayout.setPage(mLockScreenPage);
@ -197,7 +194,10 @@ public class LockScreen extends Dashboard {
@Override
public void onShow(DialogInterface dialogInterface) {
finish();
try { removeDialog(DIALOG_UNLOCK); } catch(Exception e) {}
try {
removeDialog(DIALOG_UNLOCK);
} catch (Exception e) {
}
if (mRestorePreviousTask) {
if (mLastTaskId != null) {
try {
@ -220,10 +220,12 @@ public class LockScreen extends Dashboard {
}
public void unlock(boolean restore_previous_task) {
mRestorePreviousTask = restore_previous_task;
try { showDialog(DIALOG_UNLOCK); } catch(Exception e) {}
try {
showDialog(DIALOG_UNLOCK);
} catch (Exception e) {
}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
LLApp llApp = LLApp.get();

View file

@ -62,7 +62,6 @@ import android.widget.Toast;
import net.pierrox.lightning_launcher.API;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.LLAppPhone;
import net.pierrox.lightning_launcher.api.ScreenIdentity;
import net.pierrox.lightning_launcher.configuration.GlobalConfig;
import net.pierrox.lightning_launcher.data.Item;
@ -84,37 +83,28 @@ import java.util.ArrayList;
import java.util.List;
public class ScreenManager extends ResourceWrapperActivity implements OnClickListener, View.OnLongClickListener {
protected static final int SCREEN_MODE_LWP = 6;
private static final int DIALOG_LABEL = 2;
private static final int DIALOG_CONFIRM_DELETE = 3;
private static final int REQUEST_PICK_IMAGE = 2;
private static final int SCREEN_SUBVIEWS_IDS[] = new int[] { R.id.screen, R.id.screen_icon, R.id.screen_label, R.id.screen_selected };
private static final int[] SCREEN_SUBVIEWS_IDS = new int[]{R.id.screen, R.id.screen_icon, R.id.screen_label, R.id.screen_selected};
private static final String SIS_CURRENT_PAGE = "c";
private static final int SCREEN_MODE_EDIT = 1;
private static final int SCREEN_MODE_SELECT = 2;
private static final int SCREEN_MODE_SELECT_MULTIPLE = 3;
private static final int SCREEN_MODE_GOTO = 4;
private static final int SCREEN_MODE_SHORTCUT = 5;
protected static final int SCREEN_MODE_LWP = 6;
private static final float PREVIEW_RATIO = 0.3f;
private final Rect mTmpRect = new Rect();
private LightningEngine mLightningEngine;
private net.pierrox.lightning_launcher.engine.Screen mScreen;
private int mMode;
private ViewGroup mScreenContainer;
private List<Screen> mScreens;
private int mHomePage;
private int mCurrentPage;
private Drawable mDefaultIcon;
private Rect mTmpRect = new Rect();
@Override
protected void onCreate(Bundle savedInstanceState) {
Utils.setTheme(this, Utils.APP_THEME_NO_ACTION_BAR);
@ -135,7 +125,7 @@ public class ScreenManager extends ResourceWrapperActivity implements OnClickLis
setContentView(R.layout.screen_manager);
mScreenContainer = (ViewGroup) findViewById(R.id.sm_container);
mScreenContainer = findViewById(R.id.sm_container);
int[] btns = new int[]{
R.id.sm_first,
@ -150,7 +140,7 @@ public class ScreenManager extends ResourceWrapperActivity implements OnClickLis
String codes = "ABCDF476";
Typeface typeface = LLApp.get().getIconsTypeface();
for (int i = 0; i < btns.length; i++) {
Button btn = (Button)findViewById(btns[i]);
Button btn = findViewById(btns[i]);
btn.setOnClickListener(this);
btn.setOnLongClickListener(this);
btn.setText(codes.substring(i, i + 1));
@ -221,7 +211,7 @@ public class ScreenManager extends ResourceWrapperActivity implements OnClickLis
mMode = getMode();
if (mMode == SCREEN_MODE_LWP) {
TextView tv = (TextView) findViewById(R.id.sm_title);
TextView tv = findViewById(R.id.sm_title);
tv.setText(R.string.sd);
tv.setVisibility(View.VISIBLE);
} else if (mMode == SCREEN_MODE_SELECT_MULTIPLE) {
@ -238,11 +228,11 @@ public class ScreenManager extends ResourceWrapperActivity implements OnClickLis
}
String title = intent.getStringExtra(API.SCREEN_PICKER_INTENT_EXTRA_TITLE);
if (title != null) {
TextView tv = (TextView) findViewById(R.id.sm_title);
TextView tv = findViewById(R.id.sm_title);
tv.setText(title);
tv.setVisibility(View.VISIBLE);
}
Button ok = (Button) findViewById(R.id.sm_ok);
Button ok = findViewById(R.id.sm_ok);
ok.setOnClickListener(this);
ok.setVisibility(View.VISIBLE);
}
@ -418,7 +408,10 @@ public class ScreenManager extends ResourceWrapperActivity implements OnClickLis
Toast.makeText(this, R.string.item_settings_icon_copy_failed, Toast.LENGTH_SHORT).show();
e.printStackTrace();
} finally {
if(fos!=null) try { fos.close(); } catch(Exception e) {}
if (fos != null) try {
fos.close();
} catch (Exception e) {
}
}
}
}
@ -559,7 +552,10 @@ public class ScreenManager extends ResourceWrapperActivity implements OnClickLis
case R.id.screen_label:
page = (Integer) v.getTag();
selectScreenByPage(page);
try { removeDialog(DIALOG_LABEL); } catch(Exception e) {}
try {
removeDialog(DIALOG_LABEL);
} catch (Exception e) {
}
showDialog(DIALOG_LABEL);
break;
@ -575,30 +571,45 @@ public class ScreenManager extends ResourceWrapperActivity implements OnClickLis
public void run() {
screen_view.getHitRect(mTmpRect);
mTmpRect.offsetTo(0, 0);
HorizontalScrollView scroller = (HorizontalScrollView) findViewById(R.id.sm_scroller);
HorizontalScrollView scroller = findViewById(R.id.sm_scroller);
scroller.requestChildRectangleOnScreen(screen_view, mTmpRect, false);
}
});
}
}
@Override
public boolean onLongClick(View view) {
int label_res = 0;
switch (view.getId()) {
case R.id.sm_first: label_res = R.string.sm_f; break;
case R.id.sm_previous:label_res = R.string.sm_p; break;
case R.id.sm_next:label_res = R.string.sm_n; break;
case R.id.sm_last:label_res = R.string.sm_l; break;
case R.id.sm_delete:label_res = R.string.sm_d; break;
case R.id.sm_home:label_res = R.string.sm_h; break;
case R.id.sm_add:label_res = R.string.sm_a; break;
case R.id.sm_clone:label_res = R.string.sm_c; break;
case R.id.sm_first:
label_res = R.string.sm_f;
break;
case R.id.sm_previous:
label_res = R.string.sm_p;
break;
case R.id.sm_next:
label_res = R.string.sm_n;
break;
case R.id.sm_last:
label_res = R.string.sm_l;
break;
case R.id.sm_delete:
label_res = R.string.sm_d;
break;
case R.id.sm_home:
label_res = R.string.sm_h;
break;
case R.id.sm_add:
label_res = R.string.sm_a;
break;
case R.id.sm_clone:
label_res = R.string.sm_c;
break;
default:
int page = (Integer) view.getTag();
((LLAppPhone)LLApp.get()).displayPagerPage(page, false);
LLApp.get().displayPagerPage(page, false);
finish();
startActivity(new Intent(this, Dashboard.class));
break;
@ -620,12 +631,12 @@ public class ScreenManager extends ResourceWrapperActivity implements OnClickLis
int page = (Integer) screen_view.getTag();
Screen screen = mScreens.get(getScreenIndex(page));
TextView is_home_icon = (TextView) screen_view.findViewById(R.id.screen_home);
TextView is_home_icon = screen_view.findViewById(R.id.screen_home);
is_home_icon.setTypeface(LLApp.get().getIconsTypeface());
is_home_icon.setVisibility(page == mHomePage ? View.VISIBLE : View.INVISIBLE);
is_home_icon.setTextColor(0xffffffff);
CheckBox selected = (CheckBox)screen_view.findViewById(R.id.screen_selected);
CheckBox selected = screen_view.findViewById(R.id.screen_selected);
if (mMode == SCREEN_MODE_SELECT_MULTIPLE) {
selected.setVisibility(View.VISIBLE);
selected.setChecked(screen.selected);
@ -634,7 +645,7 @@ public class ScreenManager extends ResourceWrapperActivity implements OnClickLis
}
((TextView) screen_view.findViewById(R.id.screen_label)).setText(screen.label != null ? screen.label : String.valueOf(screen.page + 1));
ImageView iv = (ImageView)screen_view.findViewById(R.id.screen_icon);
ImageView iv = screen_view.findViewById(R.id.screen_icon);
if (screen.icon == null) {
iv.setImageDrawable(mDefaultIcon);
} else {
@ -722,7 +733,7 @@ public class ScreenManager extends ResourceWrapperActivity implements OnClickLis
}
screen_view.setOnLongClickListener(this);
ImageView preview = (ImageView) screen_view.findViewById(R.id.screen_preview);
ImageView preview = screen_view.findViewById(R.id.screen_preview);
preview.setImageDrawable(new PageDrawable(page));
mScreenContainer.addView(screen_view, pos);
@ -781,14 +792,11 @@ public class ScreenManager extends ResourceWrapperActivity implements OnClickLis
setResult(RESULT_OK, data);
}
private static final float PREVIEW_RATIO = 0.3f;
private class PageDrawable extends Drawable {
private int mPage;
private ItemLayout il;
private int mWidth;
private int mHeight;
private final int mPage;
private final ItemLayout il;
private final int mWidth;
private final int mHeight;
public PageDrawable(int page) {
mPage = page;

View file

@ -112,13 +112,12 @@ import java.util.List;
import fr.xgouchet.texteditor.ui.AdvancedEditText;
public class ScriptEditor extends ResourceWrapperActivity implements View.OnClickListener, AdapterView.OnItemSelectedListener, CompoundButton.OnCheckedChangeListener {
private static final String INTENT_EXTRA_SCRIPT_ID = "i";
private static final String INTENT_EXTRA_SCRIPT_LINE = "l";
public static final String SIS_SEL_START = "s";
public static final String SIS_SEL_END = "e";
public static final String SIS_SCROLL_X = "x";
public static final String SIS_SCROLL_Y = "y";
private static final String INTENT_EXTRA_SCRIPT_ID = "i";
private static final String INTENT_EXTRA_SCRIPT_LINE = "l";
private static final int REQUEST_EDIT_SCRIPT = 0;
private static final String PREF_LAST_SCRIPT_ID = "se_lsi";
@ -133,149 +132,176 @@ public class ScriptEditor extends ResourceWrapperActivity implements View.OnClic
private static final int DIALOG_CONFIRM_DELETE = 1;
private static final int DIALOG_CHECK_RESULT = 2;
private static final int DIALOG_SCRIPT_IMPORTER_NOT_INSTALLED = 3;
private static final SparseArray<TextPosition> sScriptPositions = new SparseArray<>();
private static final Token[] sMainTokens = new Token[]{
new TokenMethod(Lightning.class, "getEvent", "void", new Class[0])
};
private static ArrayList<TokenMethod> sAutoCompleteTokens;
private final List<Script> mAllScripts = new ArrayList<>();
private final View.OnLongClickListener mCompletionButtonLongClickListener = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
final ArrayList<Token> tokens = (ArrayList<Token>) v.getTag();
int size = tokens.size();
if (size == 1) {
displayTokenApiReference(tokens.get(0));
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(ScriptEditor.this);
String[] items = new String[size];
for (int i = 0; i < size; i++) {
items[i] = tokens.get(i).getUnambiguousDisplayName();
}
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
displayTokenApiReference(tokens.get(which));
}
});
builder.create().show();
}
return true;
}
};
// list of shortcuts to display
private final Shortcut[] mShortcuts = new Shortcut[]{
new ShortcutKey(KeyEvent.KEYCODE_DPAD_LEFT, "|"),
new ShortcutKey(KeyEvent.KEYCODE_DPAD_UP, "~"),
new ShortcutKey(KeyEvent.KEYCODE_DPAD_DOWN, "{"),
new ShortcutKey(KeyEvent.KEYCODE_DPAD_RIGHT, "}"),
new ShortcutAction(SA.DEC_TAB),
new ShortcutAction(SA.INC_TAB),
new ShortcutText("(", ")"),
new ShortcutText("[", "]"),
new ShortcutText("{", "}"),
new ShortcutText("var ", ""),
new ShortcutAction(SA.SEARCH),
new ShortcutAction(SA.SEARCHN),
};
private InputMethodManager mInputMethodManager;
private ScriptManager mScriptManager;
private Script mScript;
private File mCurrentDirectory;
private View mLeftPane;
private ViewGroup mCompletionsViewGroup;
private Spinner mScriptSpinner;
private AdvancedEditText mScriptText;
private final View.OnClickListener mShortcutButtonClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Button btn = (Button) v;
Shortcut shortcut = (Shortcut) btn.getTag();
shortcut.apply(mScriptText);
//mInputMethodManager.restartInput(mScriptText);
}
};
private CheckBox mMenuLightning;
private CheckBox mMenuItem;
private CheckBox mMenuCustom;
private ArrayAdapter<Script> mScriptAdapter;
private List<Script> mAllScripts = new ArrayList<>();
private Indentation mIndentation;
private Search mSearch;
private boolean mShowSubDirs;
private int mCompletionStart;
private int mCompletionEnd;
private Button mSelectDirectoryButton;
private static class TextPosition {
int scrollX;
int scrollY;
int selectionStart;
int selectionEnd;
public TextPosition(AdvancedEditText t) {
this.scrollX = t.getScrollX();
this.scrollY = t.getScrollY();
this.selectionStart = t.getSelectionStart();
this.selectionEnd = t.getSelectionEnd();
}
public void apply(AdvancedEditText t) {
try {
t.setSelection(selectionStart, selectionEnd);
t.scrollTo(scrollX, scrollY);
} catch(Exception e) {
// pass
// scripts can be modified through scripts, hence selection indexes may not be in bounds anymore...
}
}
}
private static SparseArray<TextPosition> sScriptPositions = new SparseArray<>();
private float mScaledDensity;
private interface Token {
String LL_API_BASE_URL = "http://www.lightninglauncher.com/scripting/reference/api"+(BuildConfig.IS_BETA?"-beta":"")+"/reference/";
String ANDROID_API_BASE_URL = "http://developer.android.com/reference/";
String getDisplayName();
String getUnambiguousDisplayName();
String getApiReferenceLink();
}
private static class TokenClass implements Token {
Class cls;
private TokenClass(Class cls) {
this.cls = cls;
}
private final View.OnClickListener mCompletionButtonClickListener = new View.OnClickListener() {
@Override
public String getDisplayName() {
return cls.getSimpleName();
public void onClick(View v) {
Button btn = (Button) v;
ArrayList<Token> tokens = (ArrayList<Token>) btn.getTag();
Object firstToken = tokens.get(0);
String text;
int selection_offset;
if (firstToken.getClass() == TokenClass.class) {
TokenClass token = (TokenClass) firstToken;
text = token.getDisplayName();
selection_offset = text.length();
} else {
TokenMethod token = (TokenMethod) firstToken;
text = token.getDisplayName() + "(";
selection_offset = text.length() + (token.args.length > 0 ? 0 : 1);
// for(int i = 0; i< length; i++) {
// if(i > 0) {
// text += ",";
// }
// }
text += ")";
}
@Override
public String getUnambiguousDisplayName() {
return cls.getSimpleName();
int start, end;
final int selectionStart = mScriptText.getSelectionStart();
if ("LL".equals(text)) {
start = selectionStart;
end = selectionStart;
} else {
start = mCompletionStart;
end = mCompletionEnd;
}
@Override
public String getApiReferenceLink() {
return (cls.getName().startsWith("android") ? ANDROID_API_BASE_URL : LL_API_BASE_URL) + cls.getName().replace('.', '/')+".html";
mScriptText.getEditableText().replace(start, end, text);
mScriptText.setSelection(start + selection_offset);
mCompletionsViewGroup.removeAllViews();
mInputMethodManager.restartInput(mScriptText);
}
}
private static class TokenMethod implements Token {
Class declaring_cls;
String declaring_cls_name;
String method;
String method_lower_case;
String return_cls;
Class[] args;
private TokenMethod(Class declaring_cls, String method, String return_cls, Class[] args) {
this.declaring_cls = declaring_cls;
this.declaring_cls_name = declaring_cls.getSimpleName();
this.method = method;
this.method_lower_case = method.toLowerCase();
this.return_cls = return_cls;
this.args = args;
}
@Override
public String getDisplayName() {
return method;
}
@Override
public String getUnambiguousDisplayName() {
String s = declaring_cls_name +"."+method+"(";
int length = args.length;
for(int i = 0; i< length; i++) {
if(i > 0) {
s += ",";
}
s += args[i].getSimpleName();
}
s += ")";
return s;
}
@Override
public String getApiReferenceLink() {
String s = (declaring_cls.getName().startsWith("android") ? ANDROID_API_BASE_URL : LL_API_BASE_URL) +declaring_cls.getName().replace('.', '/')+".html#"+method+"(";
int length = args.length;
for(int i = 0; i< length; i++) {
if(i > 0) {
s += ", ";
}
s += args[i].getName();
}
s += ")";
return s;
}
}
private static ArrayList<TokenMethod> sAutoCompleteTokens;
private static Token[] sMainTokens = new Token[]{
new TokenMethod(Lightning.class, "getEvent", "void", new Class[0])
};
TextWatcher mScriptTextWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Log.i("XXX", "before "+s + " " + start + " " + after + " " + count);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// isolate token
int seqStart = findTokenStart(s, start);
int seqEnd = findTokenEnd(s, start);
// trigger autocompletion starting at 3 characters
if ((seqEnd - seqStart) >= 1) {
// try to find the previous token
String previousToken = null;
int n = seqStart - 1;
while (n >= 0 && !Character.isLetterOrDigit(s.charAt(n))) {
n--;
}
if (n > 0) {
int m = n;
while (m >= 0 && Character.isLetterOrDigit(s.charAt(m))) {
m--;
}
previousToken = s.subSequence(m + 1, n + 1).toString();
}
String token = s.subSequence(seqStart, seqEnd).toString().toLowerCase();
mCompletionStart = seqStart;
mCompletionEnd = seqEnd;
updateSuggestionsList(token, previousToken);
} else {
mCompletionStart = start;
mCompletionEnd = start;
updateSuggestionsList("-", null);
}
}
@Override
public void afterTextChanged(Editable s) {
}
};
private Button mSelectDirectoryButton;
private float mScaledDensity;
private Animation mLeftPaneAnimIn;
private Animation mLeftPaneAnimOut;
private SharedPreferences mSharedPrefs;
public static void startActivity(Context context, int script_id, int line) {
Intent intent = new Intent(context, ScriptEditor.class);
intent.putExtra(INTENT_EXTRA_SCRIPT_ID, script_id);
intent.putExtra(INTENT_EXTRA_SCRIPT_LINE, line);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
Utils.setTheme(this, Utils.APP_THEME_NO_ACTION_BAR);
@ -331,7 +357,7 @@ public class ScriptEditor extends ResourceWrapperActivity implements View.OnClic
// mCompletionsListView = (ListView) findViewById(R.id.completions);
mCompletionsViewGroup = findViewById(R.id.completions);
initializeShortcuts((ViewGroup) findViewById(R.id.shortcuts));
initializeShortcuts(findViewById(R.id.shortcuts));
Button btn;
@ -377,6 +403,7 @@ public class ScriptEditor extends ResourceWrapperActivity implements View.OnClic
mScriptText.addTextChangedListener(mScriptTextWatcher);
mScriptText.setListener(new AdvancedEditText.OnAdvancedEditTextEvent() {
private float mInitialTextSize;
@Override
public boolean onLeftEdgeSwipe() {
showLeftPane();
@ -921,14 +948,6 @@ public class ScriptEditor extends ResourceWrapperActivity implements View.OnClic
super.onActivityResult(requestCode, resultCode, data);
}
public static void startActivity(Context context, int script_id, int line) {
Intent intent = new Intent(context, ScriptEditor.class);
intent.putExtra(INTENT_EXTRA_SCRIPT_ID, script_id);
intent.putExtra(INTENT_EXTRA_SCRIPT_LINE, line);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
private void saveScript() {
mScript.setSourceText(mScriptText.getText().toString());
mScript.setFlag(Script.FLAG_APP_MENU, mMenuLightning.isChecked());
@ -1113,123 +1132,11 @@ public class ScriptEditor extends ResourceWrapperActivity implements View.OnClic
return len;
}
private View.OnClickListener mCompletionButtonClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Button btn = (Button) v;
ArrayList<Token> tokens = (ArrayList<Token>) btn.getTag();
Object firstToken = tokens.get(0);
String text;
int selection_offset;
if(firstToken.getClass() == TokenClass.class) {
TokenClass token = (TokenClass) firstToken;
text = token.getDisplayName();
selection_offset = text.length();
} else {
TokenMethod token = (TokenMethod) firstToken;
text = token.getDisplayName()+"(";
selection_offset = text.length() + (token.args.length > 0 ? 0 : 1);
// for(int i = 0; i< length; i++) {
// if(i > 0) {
// text += ",";
// }
// }
text += ")";
}
int start, end;
final int selectionStart = mScriptText.getSelectionStart();
if("LL".equals(text)) {
start = selectionStart;
end = selectionStart;
} else {
start = mCompletionStart;
end = mCompletionEnd;
}
mScriptText.getEditableText().replace(start, end, text);
mScriptText.setSelection(start + selection_offset);
mCompletionsViewGroup.removeAllViews();
mInputMethodManager.restartInput(mScriptText);
}
};
private View.OnLongClickListener mCompletionButtonLongClickListener = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
final ArrayList<Token> tokens = (ArrayList<Token>) v.getTag();
int size = tokens.size();
if(size == 1) {
displayTokenApiReference(tokens.get(0));
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(ScriptEditor.this);
String[] items = new String[size];
for(int i=0; i<size; i++) {
items[i] = tokens.get(i).getUnambiguousDisplayName();
}
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
displayTokenApiReference(tokens.get(which));
}
});
builder.create().show();
}
return true;
}
};
private void displayTokenApiReference(Token token) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(token.getApiReferenceLink()));
startActivity(intent);
}
TextWatcher mScriptTextWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Log.i("XXX", "before "+s + " " + start + " " + after + " " + count);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// isolate token
int seqStart = findTokenStart(s, start);
int seqEnd = findTokenEnd(s, start);
// trigger autocompletion starting at 3 characters
if ((seqEnd - seqStart) >= 1) {
// try to find the previous token
String previousToken = null;
int n = seqStart - 1;
while (n >= 0 && !Character.isLetterOrDigit(s.charAt(n))) {
n--;
}
if (n > 0) {
int m = n;
while (m >= 0 && Character.isLetterOrDigit(s.charAt(m))) {
m--;
}
previousToken = s.subSequence(m + 1, n + 1).toString();
}
String token = s.subSequence(seqStart, seqEnd).toString().toLowerCase();
mCompletionStart = seqStart;
mCompletionEnd = seqEnd;
updateSuggestionsList(token, previousToken);
} else {
mCompletionStart = start;
mCompletionEnd = start;
updateSuggestionsList("-", null);
}
}
@Override
public void afterTextChanged(Editable s) {
}
};
private void updateSuggestionsList(String token, String previousToken) {
String preferred_class = null;
if (previousToken != null) {
@ -1245,7 +1152,7 @@ public class ScriptEditor extends ResourceWrapperActivity implements View.OnClic
ArrayList<Token> normal_completions = new ArrayList<>();
for (TokenMethod t : sAutoCompleteTokens) {
if (t.method_lower_case.startsWith(token)) {
if (preferred_class != null && t.declaring_cls_name.equals(preferred_class)) {
if (t.declaring_cls_name.equals(preferred_class)) {
preferred_completions.add(t);
} else {
normal_completions.add(t);
@ -1306,8 +1213,41 @@ public class ScriptEditor extends ResourceWrapperActivity implements View.OnClic
mCompletionsViewGroup.addView(b);
}
private void initializeShortcuts(ViewGroup view) {
Typeface typeface = LLApp.get().getIconsTypeface();
LayoutInflater inflater = getLayoutInflater();
for (Shortcut shortcut : mShortcuts) {
Button b = (Button) inflater.inflate(R.layout.sc_btn, null);
b.setTag(shortcut);
b.setText(shortcut.getLabel());
if (shortcut.isLabelIcon())
b.setTypeface(typeface);
b.setOnClickListener(mShortcutButtonClickListener);
view.addView(b);
}
}
enum SA {
DEC_TAB,
INC_TAB,
SEARCH,
SEARCHN,
}
// -------------- shortcuts --------------------
private interface Token {
String LL_API_BASE_URL = "http://www.lightninglauncher.com/scripting/reference/api" + (BuildConfig.IS_BETA ? "-beta" : "") + "/reference/";
String ANDROID_API_BASE_URL = "http://developer.android.com/reference/";
String getDisplayName();
String getUnambiguousDisplayName();
String getApiReferenceLink();
}
/**
* Represents a button in the bottom of the editor.
*/
@ -1328,12 +1268,110 @@ public class ScriptEditor extends ResourceWrapperActivity implements View.OnClic
void apply(AdvancedEditText editText);
}
private static class TextPosition {
int scrollX;
int scrollY;
int selectionStart;
int selectionEnd;
public TextPosition(AdvancedEditText t) {
this.scrollX = t.getScrollX();
this.scrollY = t.getScrollY();
this.selectionStart = t.getSelectionStart();
this.selectionEnd = t.getSelectionEnd();
}
public void apply(AdvancedEditText t) {
try {
t.setSelection(selectionStart, selectionEnd);
t.scrollTo(scrollX, scrollY);
} catch (Exception e) {
// pass
// scripts can be modified through scripts, hence selection indexes may not be in bounds anymore...
}
}
}
private static class TokenClass implements Token {
Class cls;
private TokenClass(Class cls) {
this.cls = cls;
}
@Override
public String getDisplayName() {
return cls.getSimpleName();
}
@Override
public String getUnambiguousDisplayName() {
return cls.getSimpleName();
}
@Override
public String getApiReferenceLink() {
return (cls.getName().startsWith("android") ? ANDROID_API_BASE_URL : LL_API_BASE_URL) + cls.getName().replace('.', '/') + ".html";
}
}
private static class TokenMethod implements Token {
Class declaring_cls;
String declaring_cls_name;
String method;
String method_lower_case;
String return_cls;
Class[] args;
private TokenMethod(Class declaring_cls, String method, String return_cls, Class[] args) {
this.declaring_cls = declaring_cls;
this.declaring_cls_name = declaring_cls.getSimpleName();
this.method = method;
this.method_lower_case = method.toLowerCase();
this.return_cls = return_cls;
this.args = args;
}
@Override
public String getDisplayName() {
return method;
}
@Override
public String getUnambiguousDisplayName() {
String s = declaring_cls_name + "." + method + "(";
int length = args.length;
for (int i = 0; i < length; i++) {
if (i > 0) {
s += ",";
}
s += args[i].getSimpleName();
}
s += ")";
return s;
}
@Override
public String getApiReferenceLink() {
String s = (declaring_cls.getName().startsWith("android") ? ANDROID_API_BASE_URL : LL_API_BASE_URL) + declaring_cls.getName().replace('.', '/') + ".html#" + method + "(";
int length = args.length;
for (int i = 0; i < length; i++) {
if (i > 0) {
s += ", ";
}
s += args[i].getName();
}
s += ")";
return s;
}
}
/**
* This button will send a key to the editText.
*/
private static class ShortcutKey implements Shortcut {
private int key;
private String label;
private final int key;
private final String label;
ShortcutKey(int key, String iconLabel) {
this.key = key;
@ -1363,8 +1401,8 @@ public class ScriptEditor extends ResourceWrapperActivity implements View.OnClic
* This button will insert a text before and after the cursor.
*/
private static class ShortcutText implements Shortcut {
private String preText;
private String postText;
private final String preText;
private final String postText;
ShortcutText(String preText, String postText) {
this.preText = preText;
@ -1390,17 +1428,11 @@ public class ScriptEditor extends ResourceWrapperActivity implements View.OnClic
}
}
enum SA {
DEC_TAB,
INC_TAB,
SEARCH,
SEARCHN,
}
/**
* This button will trigger an action
*/
private class ShortcutAction implements Shortcut {
private SA action;
private final SA action;
ShortcutAction(SA action) {
this.action = action;
@ -1447,45 +1479,4 @@ public class ScriptEditor extends ResourceWrapperActivity implements View.OnClic
}
}
}
// list of shortcuts to display
private Shortcut[] mShortcuts = new Shortcut[]{
new ShortcutKey(KeyEvent.KEYCODE_DPAD_LEFT, "|"),
new ShortcutKey(KeyEvent.KEYCODE_DPAD_UP, "~"),
new ShortcutKey(KeyEvent.KEYCODE_DPAD_DOWN, "{"),
new ShortcutKey(KeyEvent.KEYCODE_DPAD_RIGHT, "}"),
new ShortcutAction(SA.DEC_TAB),
new ShortcutAction(SA.INC_TAB),
new ShortcutText("(", ")"),
new ShortcutText("[", "]"),
new ShortcutText("{", "}"),
new ShortcutText("var ", ""),
new ShortcutAction(SA.SEARCH),
new ShortcutAction(SA.SEARCHN),
};
private View.OnClickListener mShortcutButtonClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Button btn = (Button) v;
Shortcut shortcut = (Shortcut) btn.getTag();
shortcut.apply(mScriptText);
//mInputMethodManager.restartInput(mScriptText);
}
};
private void initializeShortcuts(ViewGroup view) {
Typeface typeface = LLApp.get().getIconsTypeface();
LayoutInflater inflater = getLayoutInflater();
for (Shortcut shortcut : mShortcuts) {
Button b = (Button) inflater.inflate(R.layout.sc_btn, null);
b.setTag(shortcut);
b.setText(shortcut.getLabel());
if(shortcut.isLabelIcon())
b.setTypeface(typeface);
b.setOnClickListener(mShortcutButtonClickListener);
view.addView(b);
}
}
}

View file

@ -53,6 +53,40 @@ public class Shortcuts extends ResourceWrapperListActivity {
private boolean mIsForTaskerScript;
private boolean mIsForTaskerVariable;
public static Intent getShortcutForIntent(Activity activity, String name, Intent intent) {
if (forTasker(activity)) {
Intent result = new Intent();
Bundle bundle = new Bundle();
bundle.putString("i", intent.toUri(0));
result.putExtra(com.twofortyfouram.locale.Intent.EXTRA_BUNDLE, bundle);
result.putExtra(com.twofortyfouram.locale.Intent.EXTRA_STRING_BLURB, name);
return result;
} else {
int p;
String path = intent.getStringExtra(Customize.INTENT_EXTRA_PAGE_PATH);
if (path == null) {
p = intent.getIntExtra(Customize.INTENT_EXTRA_PAGE_ID, Page.FIRST_DASHBOARD_PAGE);
} else {
p = new ContainerPath(path).getLast();
}
int icon = p == Page.APP_DRAWER_PAGE ? R.drawable.all_apps : R.drawable.icon;
Parcelable icon_resource = Intent.ShortcutIconResource.fromContext(activity, icon);
Intent shortcut = new Intent();
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon_resource);
return shortcut;
}
}
private static boolean forTasker(Activity activity) {
final String action = activity.getIntent().getAction();
return action != null && action.equals(com.twofortyfouram.locale.Intent.ACTION_EDIT_SETTING);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
final Intent intent = getIntent();
@ -66,10 +100,8 @@ public class Shortcuts extends ResourceWrapperListActivity {
if (mIsForTaskerScript) {
pickScriptAndCreateShortcut();
return;
} else if (mIsForTaskerVariable) {
pickVariableAndCreateShortcut();
return;
} else {
mItems = new String[]{
getString(R.string.settings), // 0
@ -200,35 +232,6 @@ public class Shortcuts extends ResourceWrapperListActivity {
createShortcutForIntent(name, intent);
}
public static Intent getShortcutForIntent(Activity activity, String name, Intent intent) {
if(forTasker(activity)) {
Intent result = new Intent();
Bundle bundle = new Bundle();
bundle.putString("i", intent.toUri(0));
result.putExtra(com.twofortyfouram.locale.Intent.EXTRA_BUNDLE, bundle);
result.putExtra(com.twofortyfouram.locale.Intent.EXTRA_STRING_BLURB, name);
return result;
} else {
int p;
String path = intent.getStringExtra(Customize.INTENT_EXTRA_PAGE_PATH);
if(path == null) {
p = intent.getIntExtra(Customize.INTENT_EXTRA_PAGE_ID, Page.FIRST_DASHBOARD_PAGE);
} else {
p = new ContainerPath(path).getLast();
}
int icon = p == Page.APP_DRAWER_PAGE ? R.drawable.all_apps : R.drawable.icon;
Parcelable icon_resource = Intent.ShortcutIconResource.fromContext(activity, icon);
Intent shortcut = new Intent();
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon_resource);
return shortcut;
}
}
private void createShortcutForIntent(String name, Intent intent) {
setResult(RESULT_OK, getShortcutForIntent(this, name, intent));
finish();
@ -324,9 +327,4 @@ public class Shortcuts extends ResourceWrapperListActivity {
}
}).show();
}
private static boolean forTasker(Activity activity) {
final String action = activity.getIntent().getAction();
return action != null && action.equals(com.twofortyfouram.locale.Intent.ACTION_EDIT_SETTING);
}
}

View file

@ -102,10 +102,10 @@ public final class ActionsDescription {
new Action(GlobalConfig.UNSET, R.string.an_u, Action.CAT_ADVANCED, Action.FLAG_TYPE_DESKTOP | Action.FLAG_TYPE_APP_DRAWER | Action.FLAG_TYPE_SCRIPT, Build.VERSION_CODES.FROYO),
};
private ArrayList<Action> mActions;
private String mActionNames[];
private int mType;
private boolean mForItem;
private final ArrayList<Action> mActions;
private final String[] mActionNames;
private final int mType;
private final boolean mForItem;
public ActionsDescription(Context context, int type, boolean forItem) {
mActions = new ArrayList<>(sAllActions.length);

View file

@ -38,6 +38,7 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.util.DisplayMetrics;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.configuration.GlobalConfig;
import net.pierrox.lightning_launcher.engine.LightningEngine;
@ -45,7 +46,13 @@ import net.pierrox.lightning_launcher.engine.LightningEngine;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;
import java.util.zip.ZipEntry;
@ -55,16 +62,6 @@ import java.util.zip.ZipOutputStream;
public class BackupRestoreTool {
private static final int BACKUP_VERSION=1;
private static final String ZIP_FILE_VERSION="version";
private static final String ZIP_FILE_MANIFEST="manifest";
private static final String ZIP_DIR_CORE="core";
private static final String ZIP_DIR_WIDGETS_DATA="widgets_data";
private static final String ZIP_DIR_WALLPAPER="wallpaper";
private static final String ZIP_FILE_WALLPAPER_BITMAP="bitmap.png";
private static final String ZIP_DIR_FONTS="fonts";
public static final String MANIFEST_LL_VERSION = "llVersion";
public static final String MANIFEST_LL_PKG_NAME = "llPkgName";
public static final String MANIFEST_SCREEN_WIDTH = "screenWidth";
@ -72,29 +69,14 @@ public class BackupRestoreTool {
public static final String MANIFEST_SCREEN_DENSITY = "screenDensity";
public static final String MANIFEST_SB_HEIGHT = "sbHeight";
public static final String MANIFEST_DEVICE_MODEL = "deviceModel";
public static class BackupConfig {
public Context context;
public String pathFrom;
public String pathTo;
public boolean includeWidgetsData;
public boolean includeWallpaper;
public boolean includeFonts;
public boolean forTemplate;
public int statusBarHeight;
public ArrayList<Integer> pagesToInclude;
}
public static class RestoreConfig {
public Context context;
public Uri uriFrom;
public InputStream isFrom;
public String pathTo;
public boolean restoreWidgetsData;
public boolean restoreWallpaper;
public boolean restoreFonts;
}
private static final int BACKUP_VERSION = 1;
private static final String ZIP_FILE_VERSION = "version";
private static final String ZIP_FILE_MANIFEST = "manifest";
private static final String ZIP_DIR_CORE = "core";
private static final String ZIP_DIR_WIDGETS_DATA = "widgets_data";
private static final String ZIP_DIR_WALLPAPER = "wallpaper";
private static final String ZIP_FILE_WALLPAPER_BITMAP = "bitmap.png";
private static final String ZIP_DIR_FONTS = "fonts";
public static Exception backup(BackupConfig backup_config) {
FileUtils.LL_EXT_DIR.mkdirs();
@ -159,8 +141,14 @@ public class BackupRestoreTool {
e.printStackTrace();
result = e;
} finally {
if(zos!=null) try { zos.close(); } catch(IOException e) {}
if(fos!=null) try { fos.close(); } catch(IOException e) {}
if (zos != null) try {
zos.close();
} catch (IOException e) {
}
if (fos != null) try {
fos.close();
} catch (IOException e) {
}
}
if (result != null) {
@ -288,11 +276,16 @@ public class BackupRestoreTool {
};
try {
context.sendOrderedBroadcast(br, null, receiver, null, Activity.RESULT_OK, null, null);
} catch (Exception e) { // FileUriExposedException, use Exception because not available before API 24
} catch (
Exception e) { // FileUriExposedException, use Exception because not available before API 24
// pass, new security measure on Android 7
continue;
}
try { sem.acquire(); } catch (InterruptedException e) { e.printStackTrace(); }
try {
sem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (receiver.getResultCode() == 300) {
try {
@ -393,7 +386,7 @@ public class BackupRestoreTool {
}
private static void zipData(BackupConfig backup_config, String data, ZipOutputStream zos, String name, String to) throws IOException {
zipInputStream(backup_config, new ByteArrayInputStream(data.getBytes("utf-8")), zos, name, to);
zipInputStream(backup_config, new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)), zos, name, to);
}
private static void zipInputStream(BackupConfig backup_config, InputStream is, ZipOutputStream zos, String name, String to) throws IOException {
@ -403,7 +396,9 @@ public class BackupRestoreTool {
FileUtils.copyStream(is, zos);
zos.closeEntry();
} finally {
try { is.close(); } catch(Exception e) {/*pass*/}
try {
is.close();
} catch (Exception e) {/*pass*/}
}
}
@ -465,8 +460,14 @@ public class BackupRestoreTool {
} catch (IOException e) {
e.printStackTrace();
} finally {
if(zis!=null) try { zis.close(); } catch(IOException e) {}
if(is!=null) try { is.close(); } catch(IOException e) {}
if (zis != null) try {
zis.close();
} catch (IOException e) {
}
if (is != null) try {
is.close();
} catch (IOException e) {
}
}
return result;
@ -502,7 +503,10 @@ public class BackupRestoreTool {
} catch (JSONException e) {
e.printStackTrace();
} finally {
if(zis!=null) try { zis.close(); } catch(IOException e) {}
if (zis != null) try {
zis.close();
} catch (IOException e) {
}
}
return null;
@ -540,7 +544,10 @@ public class BackupRestoreTool {
} catch (IOException e) {
throw e;
} finally {
if(fos!=null) try { fos.close(); } catch(Exception e) {}
if (fos != null) try {
fos.close();
} catch (Exception e) {
}
}
}
@ -573,7 +580,10 @@ public class BackupRestoreTool {
fos = new FileOutputStream(out);
FileUtils.copyStream(zis, fos);
} finally {
if(fos!=null) try { fos.close(); } catch(Exception e) {}
if (fos != null) try {
fos.close();
} catch (Exception e) {
}
}
}
@ -629,7 +639,10 @@ public class BackupRestoreTool {
fos = new FileOutputStream(out);
FileUtils.copyStream(zis, fos);
} finally {
if(fos!=null) try { fos.close(); } catch(Exception e) {}
if (fos != null) try {
fos.close();
} catch (Exception e) {
}
}
}
@ -652,4 +665,26 @@ public class BackupRestoreTool {
return ze;
}
public static class BackupConfig {
public Context context;
public String pathFrom;
public String pathTo;
public boolean includeWidgetsData;
public boolean includeWallpaper;
public boolean includeFonts;
public boolean forTemplate;
public int statusBarHeight;
public ArrayList<Integer> pagesToInclude;
}
public static class RestoreConfig {
public Context context;
public Uri uriFrom;
public InputStream isFrom;
public String pathTo;
public boolean restoreWidgetsData;
public boolean restoreWallpaper;
public boolean restoreFonts;
}
}

View file

@ -28,7 +28,6 @@ import net.pierrox.lightning_launcher.activities.Dashboard;
import net.pierrox.lightning_launcher.configuration.FolderConfig;
import net.pierrox.lightning_launcher.configuration.ItemConfig;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher.engine.Screen;
import net.pierrox.lightning_launcher.views.item.ItemView;
import org.json.JSONException;
@ -40,10 +39,176 @@ import java.util.ArrayList;
import java.util.LinkedList;
public class UndoStack {
private final Dashboard mDashboard;
private final File mTempStorageDirectory;
private final int mMaxSize;
private final LinkedList<Operation> mUndoOperations = new LinkedList<>();
private final LinkedList<Operation> mRedoOperations = new LinkedList<>();
private final LinkedList<SelectionState> mRedoSelectionState = new LinkedList<>();
private UndoListener mListener;
public UndoStack(Dashboard dashboard, File tempStorageDirectory, int maxSize) {
mDashboard = dashboard;
mTempStorageDirectory = tempStorageDirectory;
mMaxSize = maxSize;
if (mTempStorageDirectory.exists()) {
Utils.deleteDirectory(mTempStorageDirectory, false);
}
}
public void clear() {
if (mUndoOperations.size() > 0 || mRedoOperations.size() > 0) {
Utils.deleteDirectory(mTempStorageDirectory, false);
mUndoOperations.clear();
mRedoOperations.clear();
notifyUndoListener();
}
}
public void setUndoListener(UndoListener listener) {
mListener = listener;
}
public boolean canUndo() {
return mUndoOperations.size() > 0;
}
public boolean canRedo() {
return mRedoOperations.size() > 0;
}
private Operation getNextUndoOperation() {
return mUndoOperations.isEmpty() ? null : mUndoOperations.getLast();
}
public void undo() {
mRedoSelectionState.add(mDashboard.getSelectionState());
Operation operation = mUndoOperations.removeLast();
mRedoOperations.add(operation);
operation.undo();
notifyUndoListener();
}
public boolean willDeleteWidget(boolean for_undo) {
Operation operation = for_undo ? mUndoOperations.getLast() : mRedoOperations.getLast();
if (operation instanceof PageOperationAddOrRemoveItem) {
PageOperationAddOrRemoveItem addOrRemoveItem = (PageOperationAddOrRemoveItem) operation;
Item item = addOrRemoveItem.mPage.findItemById(addOrRemoveItem.mItemId);
boolean widget = item instanceof Widget || (item instanceof Folder && ((Folder) item).hasWidget());
if (for_undo && addOrRemoveItem.mForAdd && widget) return true;
return !for_undo && !addOrRemoveItem.mForAdd && widget;
}
return false;
}
private Operation getNextRedoOperation() {
return mRedoOperations.getLast();
}
public void redo() {
Operation operation = mRedoOperations.removeLast();
mUndoOperations.add(operation);
operation.redo();
notifyUndoListener();
mDashboard.setSelectionState(mRedoSelectionState.removeLast());
}
public void storeGroupStart() {
storeGroupStart(null);
}
public void storeGroupStart(SelectionState selectionState) {
addOperation(new GroupStartOperation(selectionState));
}
public void storeGroupEnd() {
int l = mUndoOperations.size();
if (mUndoOperations.get(l - 1).getClass() == GroupStartOperation.class) {
// nothing between start and end: remove the start and don't add a end
mUndoOperations.removeLast();
} else if (mUndoOperations.get(l - 2).getClass() == GroupStartOperation.class) {
// a single operation between start and end: remove the start and don't add a end
mUndoOperations.remove(l - 2);
} else {
addOperation(new GroupEndOperation());
}
}
public void storeItemSetCell(ItemView itemView, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationSetGeometry(itemView, oldGeometry));
}
public void storeItemSetTransform(ItemView itemView, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationSetGeometry(itemView, oldGeometry));
}
public void storeItemSetViewSize(ItemView itemView, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationSetGeometry(itemView, oldGeometry));
}
public void storeItemGridAttachment(ItemView itemView, boolean wasAttached, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationGridAttachment(itemView, wasAttached, oldGeometry));
}
public void storeItemPinMode(ItemView itemView, ItemConfig.PinMode oldPinMode, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationPinMode(itemView, oldPinMode, oldGeometry));
}
public void storePageAddItem(Item item) {
addOperation(new PageOperationAddOrRemoveItem(item, true));
}
public void storePageRemoveItem(Item item) {
addOperation(new PageOperationAddOrRemoveItem(item, false));
}
public void storePageItemZOrder(Page page, Item item, int oldZOrder) {
addOperation(new PageOperationItemZOrder(page, item, oldZOrder));
}
public void storePageItemMove(ItemView newItemView, int oldItemId, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationMove(newItemView, oldItemId, oldGeometry));
}
public void storeItemState(Item item) {
addOperation(new ItemOperationState(item));
}
public void storePageState(Page page) {
addOperation(new PageOperationState(page));
}
private void addOperation(Operation operation) {
for (Operation op : mRedoOperations) {
op.clearTempStorage();
}
mRedoOperations.clear();
if (mUndoOperations.size() == mMaxSize) {
Operation op = mUndoOperations.removeFirst();
op.clearTempStorage();
}
mUndoOperations.add(operation);
notifyUndoListener();
}
private void notifyUndoListener() {
mListener.onUndoStackStateChanged(canUndo(), canRedo());
}
public interface UndoListener {
public void onUndoStackStateChanged(boolean can_undo, boolean can_redo);
public void onUndoStackItemChanged(Item item);
public void onUndoStackPageChanged(Page page);
void onUndoStackStateChanged(boolean can_undo, boolean can_redo);
void onUndoStackItemChanged(Item item);
void onUndoStackPageChanged(Page page);
}
private abstract class Operation {
@ -160,8 +325,8 @@ public class UndoStack {
}
private class PageOperationItemZOrder extends PageOperation {
private int mOldZOrder;
private int mNewZOrder;
private final int mOldZOrder;
private final int mNewZOrder;
protected PageOperationItemZOrder(Page page, Item item, int oldZOrder) {
super(page);
@ -190,8 +355,8 @@ public class UndoStack {
}
private class PageOperationAddOrRemoveItem extends PageOperation {
private int mItemId;
private boolean mForAdd;
private final int mItemId;
private final boolean mForAdd;
private JSONObject mJsonItem;
private int mZOrder;
@ -239,7 +404,9 @@ public class UndoStack {
private void saveItemState(Item item) {
exchangeFilesWithUndo(item, true);
try { mJsonItem = item.toJSONObject(); } catch (JSONException e) { /*pass*/ }
try {
mJsonItem = item.toJSONObject();
} catch (JSONException e) { /*pass*/ }
mZOrder = mPage.items.indexOf(item);
}
@ -389,6 +556,7 @@ public class UndoStack {
private abstract class ItemOperation extends Operation {
protected int itemId;
public ItemOperation(Item item) {
this.itemId = item.getId();
}
@ -442,7 +610,8 @@ public class UndoStack {
}
private class ItemOperationGridAttachment extends ItemOperationSetGeometry {
private boolean wasAttached;
private final boolean wasAttached;
private ItemOperationGridAttachment(ItemView itemView, boolean wasAttached, SavedItemGeometry oldGeometry) {
super(itemView, oldGeometry);
this.wasAttached = wasAttached;
@ -466,8 +635,9 @@ public class UndoStack {
}
private class ItemOperationPinMode extends ItemOperationSetGeometry {
private ItemConfig.PinMode oldPinMode;
private ItemConfig.PinMode newPinMode;
private final ItemConfig.PinMode oldPinMode;
private final ItemConfig.PinMode newPinMode;
private ItemOperationPinMode(ItemView itemView, ItemConfig.PinMode oldPinMode, SavedItemGeometry oldGeometry) {
super(itemView, oldGeometry);
this.oldPinMode = oldPinMode;
@ -492,10 +662,10 @@ public class UndoStack {
}
private class ItemOperationMove extends ItemOperationSetGeometry {
private int mOldItemId;
private int mNewItemId;
private int mOldPage;
private int mNewPage;
private final int mOldItemId;
private final int mNewItemId;
private final int mOldPage;
private final int mNewPage;
private ItemOperationMove(ItemView itemView, int oldItemId, SavedItemGeometry oldGeometry) {
super(itemView, oldGeometry);
@ -546,7 +716,9 @@ public class UndoStack {
public ItemOperationState(Item item) {
super(item);
try { mOldJsonItem = item.toJSONObject(); } catch (JSONException e) { /*pass*/ }
try {
mOldJsonItem = item.toJSONObject();
} catch (JSONException e) { /*pass*/ }
ArrayList<File> icons = new ArrayList<>();
Page page = item.getPage();
@ -563,7 +735,9 @@ public class UndoStack {
exchangeFilesWithUndo(icons, false, true); // save new files to temp
try { mNewJsonItem = new_item.toJSONObject(); } catch (JSONException e) { /*pass*/ }
try {
mNewJsonItem = new_item.toJSONObject();
} catch (JSONException e) { /*pass*/ }
try {
int zorder = page.items.indexOf(new_item);
@ -629,168 +803,4 @@ public class UndoStack {
}
}
}
private Dashboard mDashboard;
private File mTempStorageDirectory;
private int mMaxSize;
private LinkedList<Operation> mUndoOperations = new LinkedList<>();
private LinkedList<Operation> mRedoOperations = new LinkedList<>();
private LinkedList<SelectionState> mRedoSelectionState = new LinkedList<>();
private UndoListener mListener;
public UndoStack(Dashboard dashboard, File tempStorageDirectory, int maxSize) {
mDashboard = dashboard;
mTempStorageDirectory = tempStorageDirectory;
mMaxSize = maxSize;
if(mTempStorageDirectory.exists()) {
Utils.deleteDirectory(mTempStorageDirectory, false);
}
}
public void clear() {
if(mUndoOperations.size()>0 || mRedoOperations.size()>0) {
Utils.deleteDirectory(mTempStorageDirectory, false);
mUndoOperations.clear();
mRedoOperations.clear();
notifyUndoListener();
}
}
public void setUndoListener(UndoListener listener) {
mListener = listener;
}
public boolean canUndo() {
return mUndoOperations.size() > 0;
}
public boolean canRedo() {
return mRedoOperations.size() > 0;
}
private Operation getNextUndoOperation() {
return mUndoOperations.isEmpty() ? null : mUndoOperations.getLast();
}
public void undo() {
mRedoSelectionState.add(mDashboard.getSelectionState());
Operation operation = mUndoOperations.removeLast();
mRedoOperations.add(operation);
operation.undo();
notifyUndoListener();
}
public boolean willDeleteWidget(boolean for_undo) {
Operation operation = for_undo ? mUndoOperations.getLast() : mRedoOperations.getLast();
if(operation instanceof PageOperationAddOrRemoveItem) {
PageOperationAddOrRemoveItem addOrRemoveItem = (PageOperationAddOrRemoveItem) operation;
Item item = addOrRemoveItem.mPage.findItemById(addOrRemoveItem.mItemId);
boolean widget = item instanceof Widget || (item instanceof Folder && ((Folder)item).hasWidget());
if(for_undo && addOrRemoveItem.mForAdd && widget) return true;
if(!for_undo && !addOrRemoveItem.mForAdd && widget) return true;
}
return false;
}
private Operation getNextRedoOperation() {
return mRedoOperations.getLast();
}
public void redo() {
Operation operation = mRedoOperations.removeLast();
mUndoOperations.add(operation);
operation.redo();
notifyUndoListener();
mDashboard.setSelectionState(mRedoSelectionState.removeLast());
}
public void storeGroupStart() {
storeGroupStart(null);
}
public void storeGroupStart(SelectionState selectionState) {
addOperation(new GroupStartOperation(selectionState));
}
public void storeGroupEnd() {
int l = mUndoOperations.size();
if(mUndoOperations.get(l-1).getClass() == GroupStartOperation.class) {
// nothing between start and end: remove the start and don't add a end
mUndoOperations.removeLast();
} else if(mUndoOperations.get(l-2).getClass() == GroupStartOperation.class) {
// a single operation between start and end: remove the start and don't add a end
mUndoOperations.remove(l-2);
} else {
addOperation(new GroupEndOperation());
}
}
public void storeItemSetCell(ItemView itemView, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationSetGeometry(itemView, oldGeometry));
}
public void storeItemSetTransform(ItemView itemView, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationSetGeometry(itemView, oldGeometry));
}
public void storeItemSetViewSize(ItemView itemView, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationSetGeometry(itemView, oldGeometry));
}
public void storeItemGridAttachment(ItemView itemView, boolean wasAttached, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationGridAttachment(itemView, wasAttached, oldGeometry));
}
public void storeItemPinMode(ItemView itemView, ItemConfig.PinMode oldPinMode, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationPinMode(itemView, oldPinMode, oldGeometry));
}
public void storePageAddItem(Item item) {
addOperation(new PageOperationAddOrRemoveItem(item, true));
}
public void storePageRemoveItem(Item item) {
addOperation(new PageOperationAddOrRemoveItem(item, false));
}
public void storePageItemZOrder(Page page, Item item, int oldZOrder) {
addOperation(new PageOperationItemZOrder(page, item, oldZOrder));
}
public void storePageItemMove(ItemView newItemView, int oldItemId, SavedItemGeometry oldGeometry) {
addOperation(new ItemOperationMove(newItemView, oldItemId, oldGeometry));
}
public void storeItemState(Item item) {
addOperation(new ItemOperationState(item));
}
public void storePageState(Page page) {
addOperation(new PageOperationState(page));
}
private void addOperation(Operation operation) {
for(Operation op : mRedoOperations) {
op.clearTempStorage();
}
mRedoOperations.clear();
if(mUndoOperations.size() == mMaxSize) {
Operation op = mUndoOperations.removeFirst();
op.clearTempStorage();
}
mUndoOperations.add(operation);
notifyUndoListener();
}
private void notifyUndoListener() {
mListener.onUndoStackStateChanged(canUndo(), canRedo());
}
}

View file

@ -32,7 +32,7 @@ import android.content.Context;
* Although this preference only displays a title and a summary, it can nevertheless be used to manage complex settings by using the {@link LLPreferenceListView.OnLLPreferenceListViewEventListener#onLLPreferenceClicked(LLPreference)} event to catch clicks. This preference holds an arbitrary value (an object).
*/
public class LLPreference {
private int mId;
private final int mId;
protected String mTitle;
protected String mSummary;
protected boolean mDisabled;
@ -58,6 +58,7 @@ public class LLPreference {
/**
* Create a new preference.
*
* @param id a unique number to identify the preference, use 0 if unused.
* @param title Displayed title.
* @param summary Displayed summary, use null for none.
@ -73,6 +74,7 @@ public class LLPreference {
/**
* Set the value and optionally a default value.
*
* @param value the value stored by this preference
* @param defaultValue use null if unused
*/
@ -116,13 +118,6 @@ public class LLPreference {
mSummary = summary;
}
/**
* Disable or enable the preference (it will be grayed out and not clickable when disabled)
*/
public void setDisabled(boolean disabled) {
mDisabled = disabled;
}
/**
* Return true if the preference is currently disabled.
*/
@ -130,6 +125,13 @@ public class LLPreference {
return mDisabled;
}
/**
* Disable or enable the preference (it will be grayed out and not clickable when disabled)
*/
public void setDisabled(boolean disabled) {
mDisabled = disabled;
}
/**
* Return true if this preference is showing the override checkbox.
*/
@ -144,13 +146,6 @@ public class LLPreference {
return !mValue.equals(mDefaultValue);
}
/**
* @hide
*/
public void setLocked(boolean locked) {
mIsLocked = locked;
}
/**
* @hide
*/
@ -159,10 +154,10 @@ public class LLPreference {
}
/**
* Show or hide this preference.
* @hide
*/
public void setVisible(boolean visible) {
mVisible = visible;
public void setLocked(boolean locked) {
mIsLocked = locked;
}
/**
@ -172,6 +167,13 @@ public class LLPreference {
return mVisible;
}
/**
* Show or hide this preference.
*/
public void setVisible(boolean visible) {
mVisible = visible;
}
/**
* Set the value of this preference with the default value.
*/

View file

@ -30,10 +30,11 @@ import android.content.Context;
* This preference is used to manage a color. It will display a color preview and a color picker when clicked.
*/
public class LLPreferenceColor extends LLPreference {
private boolean mHasAlpha;
private final boolean mHasAlpha;
/**
* Create a new color preference
*
* @param id a unique number to identify the preference, use 0 if unused.
* @param title Displayed title.
* @param summary Displayed summary, use null for none.
@ -71,6 +72,7 @@ public class LLPreferenceColor extends LLPreference {
/**
* Set this preference color.
*
* @param color a 32 bits ARGB value
*/
public void setColor(int color) {
@ -79,6 +81,7 @@ public class LLPreferenceColor extends LLPreference {
/**
* Set this preference default color.
*
* @param color a 32 bits ARGB value
*/
public void setDefaultColor(int color) {

View file

@ -31,7 +31,7 @@ import net.pierrox.lightning_launcher.data.EventAction;
public class LLPreferenceEventAction extends LLPreference {
private ActionsDescription mActions;
private final ActionsDescription mActions;
public LLPreferenceEventAction(Context context, int id, int title, EventAction value, EventAction defaultValue, ActionsDescription actions) {
super(id, context.getString(title), actions.getActionName(value.action), value, defaultValue);
@ -51,14 +51,14 @@ public class LLPreferenceEventAction extends LLPreference {
return (EventAction) mValue;
}
@Override
public void setValue(Object value, Object defaultValue) {
super.setValue(value, defaultValue);
public void setValue(EventAction ea) {
mValue = ea;
updateLabel();
}
public void setValue(EventAction ea) {
mValue = ea;
@Override
public void setValue(Object value, Object defaultValue) {
super.setValue(value, defaultValue);
updateLabel();
}

View file

@ -56,9 +56,8 @@ import net.margaritov.preference.colorpicker.ColorPickerDialog.OnColorChangedLis
import net.margaritov.preference.colorpicker.ColorPickerPanelView;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.LLAppPhone;
import net.pierrox.lightning_launcher.configuration.GlobalConfig;
import net.pierrox.lightning_launcher.script.api.Property;
import net.pierrox.lightning_launcher.engine.variable.Binding;
import net.pierrox.lightning_launcher.script.api.Property;
import net.pierrox.lightning_launcher.views.BoxEditorView;
import net.pierrox.lightning_launcher.views.BoxEditorView.OnBoxEditorEventListener;
import net.pierrox.lightning_launcher_extreme.R;
@ -71,26 +70,15 @@ import java.util.Arrays;
*/
public class LLPreferenceListView extends ListView implements OnItemClickListener, OnColorChangedListener, DialogInterface.OnClickListener, AdapterView.OnItemLongClickListener, DialogPreferenceSlider.OnDialogPreferenceSliderListener {
public interface OnLLPreferenceListViewEventListener {
public void onLLPreferenceClicked(LLPreference preference);
public void onLLPreferenceLongClicked(LLPreference preference);
public void onLLPreferenceChanged(LLPreference preference);
/** @hide */ public void onLLPreferenceBindingRemoved(LLPreferenceBinding preference);
}
private LLPreferenceColor mDialogColorPreference;
private LLPreferenceSlider mDialogSliderPreference;
private LLPreferenceList mDialogListPreference;
private LLPreferenceText mDialogTextPreference;
private LLPreference mDialogPreference;
private Dialog mDialog;
private PrefAdapter mAdapter;
private boolean mCompactMode;
private boolean mDisplayOverride;
private OnLLPreferenceListViewEventListener mOnLLPreferenceListViewEventListener;
/**
@ -125,7 +113,8 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
LLPreferenceCheckBox cbp = (LLPreferenceCheckBox) p;
cbp.setChecked(!cbp.isChecked());
mAdapter.notifyDataSetChanged();
if(mOnLLPreferenceListViewEventListener != null) mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(cbp);
if (mOnLLPreferenceListViewEventListener != null)
mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(cbp);
} else if (p instanceof LLPreferenceColor) {
mDialogColorPreference = (LLPreferenceColor) p;
ColorPickerDialog color_picker_dialog = new ColorPickerDialog(context, mDialogColorPreference.getColor());
@ -158,7 +147,8 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
mDialog.show();
}
if(mOnLLPreferenceListViewEventListener != null) mOnLLPreferenceListViewEventListener.onLLPreferenceClicked(p);
if (mOnLLPreferenceListViewEventListener != null)
mOnLLPreferenceListViewEventListener.onLLPreferenceClicked(p);
}
/**
@ -167,7 +157,8 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
LLPreference p = (LLPreference) parent.getItemAtPosition(position);
if(mOnLLPreferenceListViewEventListener != null) mOnLLPreferenceListViewEventListener.onLLPreferenceLongClicked(p);
if (mOnLLPreferenceListViewEventListener != null)
mOnLLPreferenceListViewEventListener.onLLPreferenceLongClicked(p);
return true;
}
@ -178,7 +169,8 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
public void onColorChanged(int color) {
mDialogColorPreference.setColor(color);
mAdapter.notifyDataSetChanged();
if(mOnLLPreferenceListViewEventListener != null) mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(mDialogColorPreference);
if (mOnLLPreferenceListViewEventListener != null)
mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(mDialogColorPreference);
}
/**
@ -205,7 +197,8 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
mDialogListPreference.setValueIndex(which);
dialog.dismiss();
mAdapter.notifyDataSetChanged();
if(mOnLLPreferenceListViewEventListener != null) mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(mDialogListPreference);
if (mOnLLPreferenceListViewEventListener != null)
mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(mDialogListPreference);
}
/**
@ -215,6 +208,13 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
mOnLLPreferenceListViewEventListener = listener;
}
/**
* @hide
*/
public ArrayList<LLPreference> getPreferences() {
return mAdapter == null ? null : mAdapter.getObjects();
}
/**
* Set the list of preferences to display in this listview.
*/
@ -230,13 +230,6 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
setAdapter(mAdapter);
}
/**
* @hide
*/
public ArrayList<LLPreference> getPreferences() {
return mAdapter == null ? null : mAdapter.getObjects();
}
/**
* Request a manual refresh.
*/
@ -256,7 +249,8 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
public void onDialogPreferenceSliderValueSet(float value) {
mDialogSliderPreference.setValue(value);
mAdapter.notifyDataSetChanged();
if(mOnLLPreferenceListViewEventListener != null) mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(mDialogSliderPreference);
if (mOnLLPreferenceListViewEventListener != null)
mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(mDialogSliderPreference);
}
/**
@ -269,6 +263,7 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
/**
* Use a mode where preferences are displayed using a more compact layout
*
* @param compactMode true to shrink preferences and display more preferences in a screen.
*/
public void setCompactMode(boolean compactMode) {
@ -285,15 +280,28 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
}
}
public interface OnLLPreferenceListViewEventListener {
void onLLPreferenceClicked(LLPreference preference);
void onLLPreferenceLongClicked(LLPreference preference);
void onLLPreferenceChanged(LLPreference preference);
/**
* @hide
*/
void onLLPreferenceBindingRemoved(LLPreferenceBinding preference);
}
private class PrefAdapter extends ArrayAdapter<LLPreference> implements OnCheckedChangeListener, OnBoxEditorEventListener, OnClickListener {
private int mPrefLayout;
private int mPrefCategoryLayout;
private int mPrefListWidgetLayout;
private float mPrefSizeCategory;
private float mPrefSizeTitle;
private float mPrefSizeSummary;
private LayoutInflater mLayoutInflater;
private float mDensity;
private final int mPrefLayout;
private final int mPrefCategoryLayout;
private final int mPrefListWidgetLayout;
private final float mPrefSizeCategory;
private final float mPrefSizeTitle;
private final float mPrefSizeSummary;
private final LayoutInflater mLayoutInflater;
private final float mDensity;
ArrayList<LLPreference> mObjects;
ArrayList<LLPreference> mFilteredObjects;
@ -329,7 +337,7 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
if (convertView == null) {
View preference_view = mLayoutInflater.inflate(is_category ? mPrefCategoryLayout : mPrefLayout, null);
if (mCompactMode) {
TextView title_view = (TextView) preference_view.findViewById(android.R.id.title);
TextView title_view = preference_view.findViewById(android.R.id.title);
if (is_category) {
title_view.setTextSize(mPrefSizeCategory);
} else {
@ -345,7 +353,7 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
((View) icon.getParent()).setVisibility(View.GONE);
}
ViewGroup widget_frame = (ViewGroup) preference_view.findViewById(android.R.id.widget_frame);
ViewGroup widget_frame = preference_view.findViewById(android.R.id.widget_frame);
if (is_category) {
//preference_view.setEnabled(false);
@ -376,15 +384,15 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
convertView = mLayoutInflater.inflate(R.layout.override_preference, null, false);
CheckBox override = (CheckBox)convertView.findViewById(R.id.override);
CheckBox override = convertView.findViewById(R.id.override);
override.setOnCheckedChangeListener(this);
LinearLayout container = (LinearLayout)convertView.findViewById(R.id.content);
LinearLayout container = convertView.findViewById(R.id.content);
container.addView(preference_view, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
}
View override_g = convertView.findViewById(R.id.override_g);
TextView override_t = (TextView) override_g.findViewById(R.id.override_t);
CheckBox override = (CheckBox)convertView.findViewById(R.id.override);
TextView override_t = override_g.findViewById(R.id.override_t);
CheckBox override = convertView.findViewById(R.id.override);
override.setTag(p);
if (!is_category && p.isShowingOverride() && mDisplayOverride) {
boolean overriding = p.isOverriding();
@ -414,7 +422,7 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
((TextView) convertView.findViewById(android.R.id.title)).setText(title);
if (!is_category) {
String s = p.getSummary();
TextView vs = (TextView) convertView.findViewById(android.R.id.summary);
TextView vs = convertView.findViewById(android.R.id.summary);
if (s == null) {
vs.setVisibility(View.GONE);
} else {
@ -424,7 +432,7 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
}
ViewGroup widget_frame = (ViewGroup) convertView.findViewById(android.R.id.widget_frame);
ViewGroup widget_frame = convertView.findViewById(android.R.id.widget_frame);
if (is_category) {
} else if (p instanceof LLPreferenceCheckBox) {
CheckBox widget = (CheckBox) widget_frame.getChildAt(0);
@ -435,8 +443,8 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
ColorPickerPanelView v = (ColorPickerPanelView) widget_frame.getChildAt(0);
v.setColor(((LLPreferenceColor) p).getColor());
} else if (p instanceof LLPreferenceSlider) {
TextView tv_value = (TextView) widget_frame.findViewById(R.id.slider_value);
TextView tv_unit = (TextView) widget_frame.findViewById(R.id.slider_unit);
TextView tv_value = widget_frame.findViewById(R.id.slider_value);
TextView tv_unit = widget_frame.findViewById(R.id.slider_unit);
LLPreferenceSlider sp = (LLPreferenceSlider) p;
String unit = sp.getUnit();
tv_value.setText(DialogPreferenceSlider.valueAsText(sp.getValueType() == LLPreferenceSlider.ValueType.FLOAT, unit, sp.getValue(), sp.getInterval()));
@ -532,14 +540,16 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
Binding binding = ((LLPreferenceBinding) p).getValue();
if (binding.enabled != isChecked) {
binding.enabled = isChecked;
if (mOnLLPreferenceListViewEventListener != null) mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(p);
if (mOnLLPreferenceListViewEventListener != null)
mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(p);
}
} else {
if (!isChecked) {
if (p.isOverriding()) {
p.reset();
notifyDataSetChanged();
if (mOnLLPreferenceListViewEventListener != null) mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(p);
if (mOnLLPreferenceListViewEventListener != null)
mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(p);
}
}
}
@ -549,7 +559,8 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
public void onBoxSelectionChanged(Object token, int selection) {
LLPreferenceBox p = (LLPreferenceBox) token;
p.setSelection(selection);
if(mOnLLPreferenceListViewEventListener != null) mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(p);
if (mOnLLPreferenceListViewEventListener != null)
mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(p);
}
private void filterObjects() {
@ -564,7 +575,8 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
@Override
public void onClick(View v) {
LLPreferenceBinding p = (LLPreferenceBinding) v.getTag();
if(mOnLLPreferenceListViewEventListener != null) mOnLLPreferenceListViewEventListener.onLLPreferenceBindingRemoved(p);
if (mOnLLPreferenceListViewEventListener != null)
mOnLLPreferenceListViewEventListener.onLLPreferenceBindingRemoved(p);
}
public ArrayList<LLPreference> getObjects() {
@ -573,7 +585,7 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
}
private class LLPreferenceTextDialog extends AlertDialog implements DialogInterface.OnClickListener {
private String mValue;
private final String mValue;
private EditText mDialogEditText;
public LLPreferenceTextDialog(Context context, String value) {
@ -606,7 +618,8 @@ public class LLPreferenceListView extends ListView implements OnItemClickListene
case BUTTON_POSITIVE:
mDialogTextPreference.setValue(mDialogEditText.getText().toString());
mAdapter.notifyDataSetChanged();
if(mOnLLPreferenceListViewEventListener != null) mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(mDialogTextPreference);
if (mOnLLPreferenceListViewEventListener != null)
mOnLLPreferenceListViewEventListener.onLLPreferenceChanged(mDialogTextPreference);
break;
}
}

View file

@ -30,16 +30,11 @@ import android.content.Context;
* This preference is used to manage number settings, using a slider and -/+ buttons.
*/
public class LLPreferenceSlider extends LLPreference {
/**
* @hide
*/
public enum ValueType { INT, FLOAT }
private final float mMinValue;
private final float mMaxValue;
private final float mInterval;
private final String mUnit;
private ValueType mValueType;
private float mMinValue;
private float mMaxValue;
private float mInterval;
private String mUnit;
/**
* @hide
@ -56,6 +51,7 @@ public class LLPreferenceSlider extends LLPreference {
/**
* Construct a slider preference
*
* @param id a unique number to identify the preference, use 0 if unused.
* @param title Displayed title.
* @param summary Displayed summary, use null for none.
@ -116,10 +112,6 @@ public class LLPreferenceSlider extends LLPreference {
super.setValue(Float.valueOf(value), default_value);
}
// public void setValue(float value, Float default_value) {
// super.setValue(Float.valueOf(value), default_value);
// }
/**
* @hide
*/
@ -127,6 +119,10 @@ public class LLPreferenceSlider extends LLPreference {
mDefaultValue = Float.valueOf(value);
}
// public void setValue(float value, Float default_value) {
// super.setValue(Float.valueOf(value), default_value);
// }
/**
* @hide
*/
@ -162,4 +158,9 @@ public class LLPreferenceSlider extends LLPreference {
return mUnit;
}
/**
* @hide
*/
public enum ValueType {INT, FLOAT}
}

View file

@ -74,28 +74,8 @@ public class AddItemDialog extends AlertDialog implements View.OnClickListener,
public static final int AI_BOOKMARK = 16;
public static final int AI_LIGHTNING_ACTION = 17;
public static final int AI_CUSTOM_VIEW = 18;
public interface AddItemDialogInterface {
boolean isDialogAddItemEnabled(int id);
void onBuiltinItemClicked(int id);
void onPluginClicked(Plugin plugin);
void onPluginLongClicked(Plugin plugin);
}
public static class Plugin {
public CharSequence label;
public Drawable icon;
public Intent intent;
public Plugin(CharSequence label, Drawable icon, Intent intent) {
this.label = label;
this.icon = icon;
this.intent = intent;
}
}
private AddItemDialogInterface mAddItemDialogInterface;
private LayoutInflater mInflater;
private final AddItemDialogInterface mAddItemDialogInterface;
private final LayoutInflater mInflater;
public AddItemDialog(final Context context, boolean showPlugins, final AddItemDialogInterface addItemDialogInterface) {
super(context);
@ -106,10 +86,10 @@ public class AddItemDialog extends AlertDialog implements View.OnClickListener,
mInflater = LayoutInflater.from(context);
final ViewGroup content = (ViewGroup) mInflater.inflate(R.layout.add_dialog, null);
final MyViewPager pager = (MyViewPager) content.findViewById(R.id.pager);
ViewGroup builtinsView = (ViewGroup) content.findViewById(R.id.builtins);
final ListView pluginsListView = (ListView) content.findViewById(R.id.plugins);
final TabHost tabHost = (TabHost) content.findViewById(R.id.tab);
final MyViewPager pager = content.findViewById(R.id.pager);
ViewGroup builtinsView = content.findViewById(R.id.builtins);
final ListView pluginsListView = content.findViewById(R.id.plugins);
final TabHost tabHost = content.findViewById(R.id.tab);
tabHost.setup();
tabHost.addTab(tabHost.newTabSpec("B").setIndicator(context.getString(R.string.ad_b)).setContent(R.id.empty));
tabHost.addTab(tabHost.newTabSpec("P").setIndicator(context.getString(R.string.ad_p)).setContent(R.id.empty));
@ -121,7 +101,8 @@ public class AddItemDialog extends AlertDialog implements View.OnClickListener,
});
pager.setOnPageChangeListener(new MyViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
@ -129,7 +110,8 @@ public class AddItemDialog extends AlertDialog implements View.OnClickListener,
}
@Override
public void onPageScrollStateChanged(int state) { }
public void onPageScrollStateChanged(int state) {
}
});
pluginsListView.setOnItemClickListener(this);
@ -227,12 +209,12 @@ public class AddItemDialog extends AlertDialog implements View.OnClickListener,
View cat = mInflater.inflate(R.layout.add_dialog_cat, root, false);
((TextView) cat.findViewById(R.id.title)).setText(title);
root.addView(cat);
return (ViewGroup) cat.findViewById(R.id.content);
return cat.findViewById(R.id.content);
}
private void addDialogAddItem(ViewGroup root, String label, String icon, int id) {
View item = mInflater.inflate(R.layout.add_dialog_item, root, false);
TextView i = (TextView)item.findViewById(R.id.icon);
TextView i = item.findViewById(R.id.icon);
i.setText(icon);
LLAppPhone app = (LLAppPhone) LLApp.get();
i.setTypeface(app.getIconsTypeface());
@ -245,8 +227,30 @@ public class AddItemDialog extends AlertDialog implements View.OnClickListener,
root.addView(item);
}
public interface AddItemDialogInterface {
boolean isDialogAddItemEnabled(int id);
void onBuiltinItemClicked(int id);
void onPluginClicked(Plugin plugin);
void onPluginLongClicked(Plugin plugin);
}
public static class Plugin {
public CharSequence label;
public Drawable icon;
public Intent intent;
public Plugin(CharSequence label, Drawable icon, Intent intent) {
this.label = label;
this.icon = icon;
this.intent = intent;
}
}
private static class PluginAdapter extends ArrayAdapter<Plugin> {
private LayoutInflater mLayoutInflater;
private final LayoutInflater mLayoutInflater;
public PluginAdapter(Context context, List<Plugin> objects) {
super(context, 0, objects);
@ -261,7 +265,7 @@ public class AddItemDialog extends AlertDialog implements View.OnClickListener,
Plugin plugin = getItem(position);
CheckedTextView line1 = (CheckedTextView) convertView.findViewById(android.R.id.text1);
CheckedTextView line1 = convertView.findViewById(android.R.id.text1);
line1.setText(plugin.label);
convertView.findViewById(android.R.id.text2).setVisibility(View.GONE);
((ImageView) convertView.findViewById(android.R.id.icon)).setImageDrawable(plugin.icon);

View file

@ -38,6 +38,10 @@ import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;
import net.pierrox.android.lsvg.SvgDrawable;
import net.pierrox.android.lsvg.SvgElement;
import net.pierrox.android.lsvg.SvgGroup;
import net.pierrox.android.lsvg.SvgPath;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.data.Item;
import net.pierrox.lightning_launcher.engine.LightningEngine;
@ -50,14 +54,9 @@ import net.pierrox.lightning_launcher.views.IconView;
import net.pierrox.lightning_launcher.views.SharedAsyncGraphicsDrawable;
import net.pierrox.lightning_launcher.views.item.ItemView;
import net.pierrox.lightning_launcher.views.item.ShortcutView;
import net.pierrox.android.lsvg.SvgDrawable;
import net.pierrox.android.lsvg.SvgElement;
import net.pierrox.android.lsvg.SvgGroup;
import net.pierrox.android.lsvg.SvgPath;
import net.pierrox.lightning_launcher_extreme.R;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@ -65,19 +64,17 @@ import java.util.List;
import java.util.Map;
public class BindingEditDialog extends AlertDialog implements DialogInterface.OnClickListener, View.OnClickListener {
public interface OnBindingEditDialogListener {
public void onBindingEdited(Binding binding, boolean open_in_script_editor);
}
private Binding mInitValue;
private Binding[] mOtherBindings;
private static final String ROOT_KEY = "r";
private static final String CHILD_KEY = "c";
private final Binding mInitValue;
private final Binding[] mOtherBindings;
private final OnBindingEditDialogListener mListener;
private final ArrayList<Pair<String, ArrayList<Property>>> mProperties;
private Property mSelectedProperty;
private Button mTargetButton;
private EditText mFormulaEditText;
private Button mEditButton;
private Button mOkButton;
private OnBindingEditDialogListener mListener;
private ArrayList<Pair<String,ArrayList<Property>>> mProperties;
public BindingEditDialog(Context context, Binding init_value, ItemView itemView, OnBindingEditDialogListener listener) {
super(context);
@ -89,7 +86,7 @@ public class BindingEditDialog extends AlertDialog implements DialogInterface.On
// build the list of available properties minus the one already used
Class<? extends Item> itemClass = item.getClass();
List<Pair<String, Property[]>> all_properties = Arrays.asList(Property.getForItemClass(itemClass));
Pair<String, Property[]>[] all_properties = Property.getForItemClass(itemClass);
mProperties = new ArrayList<>();
for (Pair<String, Property[]> pair_from : all_properties) {
@ -189,22 +186,22 @@ public class BindingEditDialog extends AlertDialog implements DialogInterface.On
((TextView) view.findViewById(R.id.bd_tt)).setText(R.string.bd_p);
((TextView) view.findViewById(R.id.bd_tf)).setText(R.string.bd_v);
mTargetButton = (Button) view.findViewById(R.id.bd_t);
mTargetButton = view.findViewById(R.id.bd_t);
mSelectedProperty = mInitValue == null ? null : Property.getByName(mInitValue.target);
mTargetButton.setText(mSelectedProperty == null ? getContext().getString(R.string.bd_s) : mSelectedProperty.getLabel());
mTargetButton.setEnabled(mInitValue == null);
mTargetButton.setOnClickListener(this);
Button builtin = (Button) view.findViewById(R.id.bd_fb);
Button builtin = view.findViewById(R.id.bd_fb);
builtin.setTypeface(LLApp.get().getIconsTypeface());
builtin.setOnClickListener(this);
mEditButton = (Button) view.findViewById(R.id.bd_fe);
mEditButton = view.findViewById(R.id.bd_fe);
mEditButton.setTypeface(LLApp.get().getIconsTypeface());
mEditButton.setOnClickListener(this);
mEditButton.setEnabled(mInitValue != null);
mFormulaEditText = (EditText) view.findViewById(R.id.bd_f);
mFormulaEditText = view.findViewById(R.id.bd_f);
if (mInitValue != null) {
mFormulaEditText.setText(mInitValue.formula);
}
@ -250,12 +247,13 @@ public class BindingEditDialog extends AlertDialog implements DialogInterface.On
private void save(boolean open_in_script_editor) {
String target = mSelectedProperty.getName();
String formula = mFormulaEditText.getText().toString();
Binding binding = new Binding(target, formula, mInitValue==null ? true : mInitValue.enabled);
Binding binding = new Binding(target, formula, mInitValue == null || mInitValue.enabled);
mListener.onBindingEdited(binding, open_in_script_editor);
}
private static final String ROOT_KEY = "r";
private static final String CHILD_KEY = "c";
public interface OnBindingEditDialogListener {
void onBindingEdited(Binding binding, boolean open_in_script_editor);
}
private class PropertySelectionDialog extends Dialog implements ExpandableListView.OnChildClickListener {
@ -370,7 +368,6 @@ public class BindingEditDialog extends AlertDialog implements DialogInterface.On
childData.add(child_values);
mAdapter = new SimpleExpandableListAdapter(
getContext(),

View file

@ -26,11 +26,16 @@ package net.pierrox.lightning_launcher.util;
import android.app.ActivityManager;
import android.app.Service;
import android.content.*;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.activities.Dashboard;
import net.pierrox.lightning_launcher.activities.LockScreen;
@ -41,7 +46,8 @@ import java.util.List;
public class EmptyService extends Service {
private BroadcastReceiver mBroadcastReceiver=new BroadcastReceiver() {
private static final int MODE_CHECK_ON_TOP = 0;
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@ -110,21 +116,18 @@ public class EmptyService extends Service {
}
}
};
private static final int MODE_MOVE_ON_TOP_PENDING = 1;
private ActivityManager mActivityManager;
private Method mMoveTaskToFront;
private ComponentName mLockScreenComponenentName;
private Handler mHandler;
private int mMode;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
private ActivityManager mActivityManager;
private Method mMoveTaskToFront;
private ComponentName mLockScreenComponenentName;
private Handler mHandler;
private static final int MODE_CHECK_ON_TOP = 0;
private static final int MODE_MOVE_ON_TOP_PENDING = 1;
private int mMode;
@Override
public void onCreate() {
super.onCreate();
@ -156,7 +159,7 @@ public class EmptyService extends Service {
}
private Runnable mCheckOnTop = new Runnable() {
private final Runnable mCheckOnTop = new Runnable() {
@Override
public void run() {
if (mMode == MODE_CHECK_ON_TOP) {

View file

@ -60,44 +60,22 @@ import java.util.HashMap;
import java.util.List;
public class FileAndDirectoryPickerDialog extends AlertDialog implements DialogInterface.OnClickListener, View.OnClickListener, AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {
public interface FileAndDirectoryPickerDialogListener {
void onFileSelected(File file, File newDirectory);
}
private boolean mForDirectory;
private boolean mForFont;
private boolean mMergeSingleDirectories;
private ScriptManager mScriptManager;
private File mRootDirectory;
private FileAndDirectoryPickerDialogListener mListener;
private static final String FONT_ITEM_PREVIEW = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private final boolean mForDirectory;
private final boolean mForFont;
private final boolean mMergeSingleDirectories;
private final ScriptManager mScriptManager;
private final File mRootDirectory;
private final FileAndDirectoryPickerDialogListener mListener;
private final String[] mExtensions;
private final Bitmap mDirectoryIcon;
private final Bitmap mFileIcon;
private Button mUpButton;
private ListView mFileListView;
private TextView mCurrentPathView;
private TextView mEmptyView;
private File mCurrentDirectory;
private FileFilter mFileFilter;
private String[] mExtensions;
private Bitmap mDirectoryIcon;
private Bitmap mFileIcon;
public static void showForFont(Context context, File initialDirectory, FileAndDirectoryPickerDialogListener listener) {
String[] ttfExtensions = {".ttf", ".otf"};
File rootDirectory = new File("/");
if(initialDirectory == null) {
initialDirectory = Environment.getExternalStorageDirectory();
}
new FileAndDirectoryPickerDialog(context, false, true, initialDirectory, rootDirectory, ttfExtensions, null, listener).show();
}
public static void showForScriptDirectory(Context context, File initialDirectory, ScriptManager scriptManager, FileAndDirectoryPickerDialogListener listener) {
File rootDirectory = scriptManager.getScriptsDir();
if(initialDirectory == null) {
initialDirectory = rootDirectory;
}
new FileAndDirectoryPickerDialog(context, true, false, initialDirectory, rootDirectory, null, scriptManager, listener).show();
}
private FileAndDirectoryPickerDialog(Context context, boolean forDirectory, boolean forFont, File initialDirectory, File rootDirectory, String[] extensions, ScriptManager scriptManager, FileAndDirectoryPickerDialogListener listener) {
super(context);
@ -140,23 +118,40 @@ public class FileAndDirectoryPickerDialog extends AlertDialog implements DialogI
}
}
public static void showForFont(Context context, File initialDirectory, FileAndDirectoryPickerDialogListener listener) {
String[] ttfExtensions = {".ttf", ".otf"};
File rootDirectory = new File("/");
if (initialDirectory == null) {
initialDirectory = Environment.getExternalStorageDirectory();
}
new FileAndDirectoryPickerDialog(context, false, true, initialDirectory, rootDirectory, ttfExtensions, null, listener).show();
}
public static void showForScriptDirectory(Context context, File initialDirectory, ScriptManager scriptManager, FileAndDirectoryPickerDialogListener listener) {
File rootDirectory = scriptManager.getScriptsDir();
if (initialDirectory == null) {
initialDirectory = rootDirectory;
}
new FileAndDirectoryPickerDialog(context, true, false, initialDirectory, rootDirectory, null, scriptManager, listener).show();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
View view = getLayoutInflater().inflate(R.layout.file_dir_picker_dialog, null);
setView(view);
mUpButton = (Button) view.findViewById(R.id.up);
mUpButton = view.findViewById(R.id.up);
mUpButton.setText(R.string.file_picker_activity_up);
mUpButton.setOnClickListener(this);
mCurrentPathView = (TextView) view.findViewById(R.id.path);
mCurrentPathView = view.findViewById(R.id.path);
mFileListView = (ListView) view.findViewById(android.R.id.list);
mFileListView = view.findViewById(android.R.id.list);
mFileListView.setOnItemClickListener(this);
mFileListView.setOnItemLongClickListener(this);
mEmptyView = (TextView) view.findViewById(R.id.empty);
mEmptyView = view.findViewById(R.id.empty);
mEmptyView.setText(R.string.nfh);
setButton(BUTTON_NEGATIVE, getContext().getString(android.R.string.cancel), this);
@ -169,7 +164,7 @@ public class FileAndDirectoryPickerDialog extends AlertDialog implements DialogI
super.onCreate(savedInstanceState);
getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
ViewGroup content = (ViewGroup) getWindow().findViewById(android.R.id.content);
ViewGroup content = getWindow().findViewById(android.R.id.content);
View child = content.getChildAt(0);
child.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
child.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
@ -345,7 +340,7 @@ public class FileAndDirectoryPickerDialog extends AlertDialog implements DialogI
if (!currentPath.endsWith("/")) {
currentPath += "/";
}
String path = "/" + currentPath.substring(rootPath.length(), currentPath.length());
String path = "/" + currentPath.substring(rootPath.length());
/*
/ / -> /
@ -357,9 +352,12 @@ public class FileAndDirectoryPickerDialog extends AlertDialog implements DialogI
mEmptyView.setVisibility(files.length == 0 ? View.VISIBLE : View.GONE);
}
private static final String FONT_ITEM_PREVIEW = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public interface FileAndDirectoryPickerDialogListener {
void onFileSelected(File file, File newDirectory);
}
private class FileAdapter extends ArrayAdapter<File> {
private HashMap<File,Typeface> mTypefaces = new HashMap<>();
private final HashMap<File, Typeface> mTypefaces = new HashMap<>();
public FileAdapter(Context context, List<File> objects) {
super(context, 0, objects);
@ -372,8 +370,8 @@ public class FileAndDirectoryPickerDialog extends AlertDialog implements DialogI
}
File f = getItem(position);
CheckedTextView line1 = (CheckedTextView) convertView.findViewById(android.R.id.text1);
TextView line2 = (TextView) convertView.findViewById(android.R.id.text2);
CheckedTextView line1 = convertView.findViewById(android.R.id.text1);
TextView line2 = convertView.findViewById(android.R.id.text2);
String text1, text2 = null;
Typeface typeface = Typeface.DEFAULT;
String name = f.getName();

View file

@ -43,82 +43,11 @@ import java.util.Map;
public class Indentation {
private static final int INDENT_SIZE = 2;
private Map<EditText, IndentationTextWatcher> mRegistered = new HashMap<>();
/**
* Registers the AutoIndentation on the provided editText (unless it was already registered)
*/
public void register(EditText editText){
if(mRegistered.containsKey(editText))
return;
IndentationTextWatcher itw = new IndentationTextWatcher(editText);
editText.addTextChangedListener(itw);
mRegistered.put(editText, itw);
}
/**
* Unregisters the AutoIndentation on the provided editText (if it was registered before)
*/
public void unregister(EditText editText){
if(!mRegistered.containsKey(editText))
return;
editText.removeTextChangedListener(mRegistered.get(editText));
mRegistered.remove(editText);
}
/**
* Called when an ending bracket is inserted. Decreases the indentation.
* @param posBracket where the endbracket was
* @param editable where to unindent
*/
private void onEndBracket(int posBracket, Editable editable){
// check if beginning of line
if( posBracket == getLineIndent(posBracket, editable).second ){
// decrease indent
decreaseIndent( posBracket, editable );
}
}
/**
* Called when a newline is inserted. Indents it with the same indentation as the previous line (if any)
* @param posEnter position of the newline char
* @param editable where to indent
*/
private void onNewLine(int posEnter, Editable editable){
int n = getLineIndent(posEnter, editable).first;
StringBuilder indent = new StringBuilder();
for(int i=0;i<n;++i){
indent.append(" ");
}
// do if previous line ends in open bracket
if(posEnter > 0 && editable.charAt(posEnter - 1) == '{'){
// add newline if also following close bracket
if(posEnter < editable.length() - 1 && editable.charAt(posEnter + 1) == '}'){
editable.insert(posEnter + 2, "\n" + indent.toString() + "}");
// this avoids moving the cursor
editable.replace(posEnter + 1, posEnter + 2, "");
}
// add indent size
for(int i=0;i<INDENT_SIZE;++i){
indent.append(" ");
}
}
// write indent
editable.insert(posEnter + 1, indent.toString());
}
// ------------ functions -----------------
private final Map<EditText, IndentationTextWatcher> mRegistered = new HashMap<>();
/**
* Returns the size of the indent in the current line (spaces at the left) and the position of the first non-space char
*
* @param currentpos pos of current line (any char)
* @param editable where to search
* @return length of indent (number of spaces) and position of first non-space char (can be end of file)
@ -155,6 +84,7 @@ public class Indentation {
/**
* Changes the indentation of all the lines selected
*
* @param posLeft start of selection
* @param posRight end of selection
* @param increase if true increase indent, decrease otherwise
@ -190,6 +120,7 @@ public class Indentation {
/**
* Increases the indentation of a single line
*
* @param posCursor position of a character in the line that will be indented
* @param editable where to apply the indentation
*/
@ -205,6 +136,7 @@ public class Indentation {
/**
* Decreases the indentation of a single line
*
* @param posCursor position of a character in the line that will be indented
* @param editable where to apply the indentation
*/
@ -233,20 +165,93 @@ public class Indentation {
}
}
// ------------ functions -----------------
/**
* Registers the AutoIndentation on the provided editText (unless it was already registered)
*/
public void register(EditText editText) {
if (mRegistered.containsKey(editText))
return;
IndentationTextWatcher itw = new IndentationTextWatcher(editText);
editText.addTextChangedListener(itw);
mRegistered.put(editText, itw);
}
/**
* Unregisters the AutoIndentation on the provided editText (if it was registered before)
*/
public void unregister(EditText editText) {
if (!mRegistered.containsKey(editText))
return;
editText.removeTextChangedListener(mRegistered.get(editText));
mRegistered.remove(editText);
}
/**
* Called when an ending bracket is inserted. Decreases the indentation.
*
* @param posBracket where the endbracket was
* @param editable where to unindent
*/
private void onEndBracket(int posBracket, Editable editable) {
// check if beginning of line
if (posBracket == getLineIndent(posBracket, editable).second) {
// decrease indent
decreaseIndent(posBracket, editable);
}
}
/**
* Called when a newline is inserted. Indents it with the same indentation as the previous line (if any)
*
* @param posEnter position of the newline char
* @param editable where to indent
*/
private void onNewLine(int posEnter, Editable editable) {
int n = getLineIndent(posEnter, editable).first;
StringBuilder indent = new StringBuilder();
for (int i = 0; i < n; ++i) {
indent.append(" ");
}
// do if previous line ends in open bracket
if (posEnter > 0 && editable.charAt(posEnter - 1) == '{') {
// add newline if also following close bracket
if (posEnter < editable.length() - 1 && editable.charAt(posEnter + 1) == '}') {
editable.insert(posEnter + 2, "\n" + indent + "}");
// this avoids moving the cursor
editable.replace(posEnter + 1, posEnter + 2, "");
}
// add indent size
for (int i = 0; i < INDENT_SIZE; ++i) {
indent.append(" ");
}
}
// write indent
editable.insert(posEnter + 1, indent.toString());
}
// ------------ textwatcher ----------------
private class IndentationTextWatcher implements TextWatcher {
private final String mSpanNewline = "mSpanNewline";
private final String mSpanEndBracket = "mSpanEndBracket";
private final EditText mEditText;
private boolean mEditing = false;
IndentationTextWatcher(EditText mEditText) {
this.mEditText = mEditText;
}
private String mSpanNewline = "mSpanNewline";
private String mSpanEndBracket = "mSpanEndBracket";
private boolean mEditing = false;
private EditText mEditText;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}

View file

@ -109,10 +109,10 @@ public class LightningLWPService extends WallpaperService {
mScreen = new LightningLWPScreen(LightningLWPService.this, R.layout.lwp);
mContentView = (EventFrameLayout) mScreen.getContentView();
mItemLayout = (ItemLayout) mContentView.findViewById(R.id.lwp_il);
mItemLayout = mContentView.findViewById(R.id.lwp_il);
mScreen.takeItemLayoutOwnership(mItemLayout);
mNoDesktopView = (TextView) mContentView.findViewById(R.id.empty);
mNoDesktopView = mContentView.findViewById(R.id.empty);
mNoDesktopView.setText(R.string.sd);
mNoDesktopView.setOnClickListener(new View.OnClickListener() {
@Override

View file

@ -40,40 +40,32 @@ import android.widget.Spinner;
import android.widget.TextView;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher_extreme.R;
import net.pierrox.lightning_launcher.activities.ScriptEditor;
import net.pierrox.lightning_launcher.data.Utils;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher.script.Script;
import net.pierrox.lightning_launcher.script.ScriptManager;
import net.pierrox.lightning_launcher_extreme.R;
import java.io.File;
import java.util.ArrayList;
public class ScriptPickerDialog extends AlertDialog implements AdapterView.OnItemSelectedListener {
private static boolean sShowSubDirs;
private static File sCurrentDirectory;
private final CheckBox mHasDataCheckBox;
private final EditText mDataTextView;
private final Spinner mTargetsSpinner;
private final Spinner mScriptSpinner;
private Button mSelectDirectoryButton;
private ArrayAdapter<Script> mScriptAdapter;
private ArrayList<Script> mAllScripts;
private final Button mSelectDirectoryButton;
private final ArrayAdapter<Script> mScriptAdapter;
private final ArrayList<Script> mAllScripts;
private final ScriptManager mScriptManager;
private final int mInitialTarget;
private final OnScriptPickerEvent mListener;
private Script mScript;
private int mInitialTarget;
private OnScriptPickerEvent mListener;
private static boolean sShowSubDirs;
private static File sCurrentDirectory;
public interface OnScriptPickerEvent {
public void onScriptPicked(String id_data, int target);
public void onScriptPickerCanceled();
}
public ScriptPickerDialog(final Context context, LightningEngine engine, String initial_id_data, final int initial_target, final OnScriptPickerEvent listener) {
super(context);
@ -91,16 +83,16 @@ public class ScriptPickerDialog extends AlertDialog implements AdapterView.OnIte
setTitle(R.string.sst);
View content = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.dialog_select_script, null);
setView(content);
mScriptSpinner = (Spinner) content.findViewById(R.id.script);
mTargetsSpinner = (Spinner) content.findViewById(R.id.tg);
final Button sc_new = (Button) content.findViewById(R.id.sc_new);
mHasDataCheckBox = (CheckBox) content.findViewById(R.id.has_data);
mDataTextView = (EditText) content.findViewById(R.id.data);
mScriptSpinner = content.findViewById(R.id.script);
mTargetsSpinner = content.findViewById(R.id.tg);
final Button sc_new = content.findViewById(R.id.sc_new);
mHasDataCheckBox = content.findViewById(R.id.has_data);
mDataTextView = content.findViewById(R.id.data);
((TextView) content.findViewById(R.id.tgt)).setText(R.string.tg);
((TextView) content.findViewById(R.id.sc_path)).setText(R.string.sc_path);
((TextView) content.findViewById(R.id.sc_name)).setText(R.string.sc_name);
sc_new.setText(R.string.sc_new);
Button editButton = (Button) content.findViewById(R.id.edit);
Button editButton = content.findViewById(R.id.edit);
editButton.setTypeface(LLApp.get().getIconsTypeface());
editButton.setOnClickListener(new View.OnClickListener() {
@Override
@ -111,7 +103,7 @@ public class ScriptPickerDialog extends AlertDialog implements AdapterView.OnIte
}
});
mSelectDirectoryButton = (Button) content.findViewById(R.id.sc_d);
mSelectDirectoryButton = content.findViewById(R.id.sc_d);
mSelectDirectoryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -130,7 +122,7 @@ public class ScriptPickerDialog extends AlertDialog implements AdapterView.OnIte
});
updateSelectDirectoryButton();
CheckBox showSubDirs = (CheckBox) content.findViewById(R.id.sc_sd);
CheckBox showSubDirs = content.findViewById(R.id.sc_sd);
showSubDirs.setText(R.string.sc_all);
showSubDirs.setChecked(sShowSubDirs);
showSubDirs.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@ -303,4 +295,11 @@ public class ScriptPickerDialog extends AlertDialog implements AdapterView.OnIte
private void updateSelectDirectoryButton() {
mSelectDirectoryButton.setText(mScriptManager.getRelativePath(sCurrentDirectory));
}
public interface OnScriptPickerEvent {
void onScriptPicked(String id_data, int target);
void onScriptPickerCanceled();
}
}

View file

@ -43,8 +43,8 @@ import fr.xgouchet.texteditor.ui.AdvancedEditText;
* Class that Manages a searchable dialog (currently for the script editor).
*/
public class Search {
private Activity mCntx;
private AdvancedEditText mEditText;
private final Activity mCntx;
private final AdvancedEditText mEditText;
private AlertDialog mDialog;
private EditText mEdTxt;
@ -100,7 +100,8 @@ public class Search {
if (!mChkBackwards.isChecked()) {
// search fordwards
int from = mEditText.getTrueSelectionStart();
if (from != mEditText.getTrueSelectionEnd()) from++; // avoids returning the current selection
if (from != mEditText.getTrueSelectionEnd())
from++; // avoids returning the current selection
if (matcher.find(from) || matcher.find(0)) {
// found one just after the selection or from the beginning
start = matcher.start();

View file

@ -25,7 +25,6 @@ SOFTWARE.
package net.pierrox.lightning_launcher.util;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
@ -46,17 +45,10 @@ import net.pierrox.lightning_launcher_extreme.R;
import java.util.ArrayList;
public class SetVariableDialog extends AlertDialog implements DialogInterface.OnClickListener, View.OnClickListener {
public interface OnSetVariableDialogListener {
public void onSetVariableEdited(Variable variable);
public void onSetVariableCancel();
}
private Variable mInitValue;
private OnSetVariableDialogListener mListener;
private final Variable mInitValue;
private final OnSetVariableDialogListener mListener;
private EditText mNameEditText;
private EditText mValueEditText;
public SetVariableDialog(Context context, Variable init_value, OnSetVariableDialogListener listener) {
super(context);
@ -71,10 +63,10 @@ public class SetVariableDialog extends AlertDialog implements DialogInterface.On
((TextView) view.findViewById(R.id.sv_nt)).setText(R.string.sv_n);
((TextView) view.findViewById(R.id.sv_vt)).setText(R.string.bd_v);
mNameEditText = (EditText) view.findViewById(R.id.sv_n);
mValueEditText = (EditText) view.findViewById(R.id.sv_v);
mNameEditText = view.findViewById(R.id.sv_n);
mValueEditText = view.findViewById(R.id.sv_v);
Button select_var = (Button) view.findViewById(R.id.sv_ns);
Button select_var = view.findViewById(R.id.sv_ns);
select_var.setTypeface(LLApp.get().getIconsTypeface());
select_var.setOnClickListener(this);
@ -133,8 +125,14 @@ public class SetVariableDialog extends AlertDialog implements DialogInterface.On
}
}
public interface OnSetVariableDialogListener {
void onSetVariableEdited(Variable variable);
void onSetVariableCancel();
}
private class VariableSelectionDialog extends AlertDialog implements AdapterView.OnItemClickListener {
private ArrayList<Variable> mUserVariables;
private final ArrayList<Variable> mUserVariables;
public VariableSelectionDialog(Context context) {
super(context);

View file

@ -34,7 +34,6 @@ import android.graphics.Color;
import android.graphics.Rect;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
import android.util.DisplayMetrics;
@ -60,10 +59,10 @@ import net.pierrox.lightning_launcher.data.Item;
import net.pierrox.lightning_launcher.data.LightningIntent;
import net.pierrox.lightning_launcher.data.Page;
import net.pierrox.lightning_launcher.data.PageIndicator;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher.data.PageProcessor;
import net.pierrox.lightning_launcher.data.Shortcut;
import net.pierrox.lightning_launcher.data.Utils;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher.script.ScriptManager;
import net.pierrox.lightning_launcher_extreme.BuildConfig;
import net.pierrox.lightning_launcher_extreme.R;
@ -73,10 +72,46 @@ import java.io.IOException;
import java.util.ArrayList;
public class Setup {
public interface OnFirstTimeInitEvent {
public void onFirstTimeInitStart(boolean is_import);
public void onFirstTimeInitEnd(boolean success, boolean was_import, Item all_apps_item);
}
private static final String[] CN_DOCK_0 = new String[]{
// phone
"com.android.contacts/.activities.DialtactsActivity",
"com.android.contacts/.DialtactsActivity",
"com.android.contacts/com.android.dialer.DialtactsActivity",
"com.android.dialer/.DialtactsActivity",
"com.android.htccontacts/.DialerTabActivity",
"com.google.android.dialer/.extensions.GoogleDialtactsActivity",
"com.sec.android.app.dialertab/.DialerTabActivity",
"com.sonyericsson.android.socialphonebook/.DialerEntryActivity",
// camera
"com.android.camera/.Camera",
"com.android.camera/.CameraEntry",
"com.asus.camera/.CameraApp",
"com.cyngn.cameranext/com.android.camera.CameraLauncher",
"com.google.android.GoogleCamera/com.android.camera.CameraLauncher",
"com.motorola.camera/.Camera",
"com.sec.android.app.camera/.Camera",
"com.sonyericsson.android.camera/.CameraActivity",
};
private static final String[] CN_DOCK_1 = new String[]{
"com.android.settings/.Settings",
"com.android.settings/.GridSettings",
};
// private static final String[] CN_DOCK_2 = new String[] {
// "net.pierrox.lightning_launcher_extreme/net.pierrox.lightning_launcher.activities.AppDrawerX"
// };
private static final String[] CN_DOCK_3 = new String[]{
"com.android.chrome/com.google.android.apps.chrome.Main",
"com.android.browser/.BrowserActivity",
"com.asus.browser/com.android.browser.BrowserActivity",
"com.opera.mini.android/.Browser",
"com.sec.android.app.sbrowser/.SBrowserMainActivity",
};
private static final String[] CN_DOCK_4 = new String[]{
"com.android.vending/.AssetBrowserActivity"
};
@SuppressWarnings("deprecation")
public static void firstTimeInit(final OnFirstTimeInitEvent listener) {
@ -159,48 +194,6 @@ public class Setup {
}.execute((Void) null);
}
private static final String[] CN_DOCK_0 = new String[] {
// phone
"com.android.contacts/.activities.DialtactsActivity",
"com.android.contacts/.DialtactsActivity",
"com.android.contacts/com.android.dialer.DialtactsActivity",
"com.android.dialer/.DialtactsActivity",
"com.android.htccontacts/.DialerTabActivity",
"com.google.android.dialer/.extensions.GoogleDialtactsActivity",
"com.sec.android.app.dialertab/.DialerTabActivity",
"com.sonyericsson.android.socialphonebook/.DialerEntryActivity",
// camera
"com.android.camera/.Camera",
"com.android.camera/.CameraEntry",
"com.asus.camera/.CameraApp",
"com.cyngn.cameranext/com.android.camera.CameraLauncher",
"com.google.android.GoogleCamera/com.android.camera.CameraLauncher",
"com.motorola.camera/.Camera",
"com.sec.android.app.camera/.Camera",
"com.sonyericsson.android.camera/.CameraActivity",
};
private static final String[] CN_DOCK_1 = new String[] {
"com.android.settings/.Settings",
"com.android.settings/.GridSettings",
};
// private static final String[] CN_DOCK_2 = new String[] {
// "net.pierrox.lightning_launcher_extreme/net.pierrox.lightning_launcher.activities.AppDrawerX"
// };
private static final String[] CN_DOCK_3 = new String[] {
"com.android.chrome/com.google.android.apps.chrome.Main",
"com.android.browser/.BrowserActivity",
"com.asus.browser/com.android.browser.BrowserActivity",
"com.opera.mini.android/.Browser",
"com.sec.android.app.sbrowser/.SBrowserMainActivity",
};
private static final String[] CN_DOCK_4 = new String[] {
"com.android.vending/.AssetBrowserActivity"
};
private static Item defaultSetup(LightningEngine engine) {
File dir = engine.getBaseDir();
@ -258,7 +251,6 @@ public class Setup {
int color_primary_dark = resources.getColor(R.color.color_primary_dark);
final PageConfig dashboard_config = dashboard.config;
dashboard_config.applyDefaultFolderConfig();
dashboard_config.defaultFolderConfig.outsideTapClose = true;
@ -365,7 +357,6 @@ public class Setup {
s.notifyChanged();
// start here folder
Folder start_here;
Page start_here_page;
@ -629,4 +620,10 @@ public class Setup {
Utils.saveIconToFile(shortcut.getDefaultIconFile(), icon);
page.addItem(shortcut);
}
public interface OnFirstTimeInitEvent {
void onFirstTimeInitStart(boolean is_import);
void onFirstTimeInitEnd(boolean success, boolean was_import, Item all_apps_item);
}
}

View file

@ -24,7 +24,6 @@ SOFTWARE.
package net.pierrox.lightning_launcher.views;
import net.pierrox.lightning_launcher_extreme.R;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
@ -34,17 +33,14 @@ import android.graphics.Paint.FontMetrics;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
public class BoxEditorView extends View implements Runnable {
public interface OnBoxEditorEventListener {
public void onBoxSelectionChanged(Object token, int selection);
}
import net.pierrox.lightning_launcher_extreme.R;
public class BoxEditorView extends View implements Runnable {
public static final int SEG_ML = 0;
public static final int SEG_MT = 1;
public static final int SEG_MR = 2;
@ -58,37 +54,34 @@ public class BoxEditorView extends View implements Runnable {
public static final int SEG_PR = 10;
public static final int SEG_PB = 11;
public static final int SEG_CONTENT = 12;
public static final int SEG_SELECTION_COLOR_MASK = 1 << SEG_BL | 1 << SEG_BT | 1 << SEG_BR | 1 << SEG_BB | 1 << SEG_CONTENT;
private static final int ALL_MARGINGS = 1 << SEG_ML | 1 << SEG_MT | 1 << SEG_MR | 1 << SEG_MB;
private static final int ALL_BORDERS = 1 << SEG_BL | 1 << SEG_BT | 1 << SEG_BR | 1 << SEG_BB;
private static final int ALL_PADDINGS = 1 << SEG_PL | 1 << SEG_PT | 1 << SEG_PR | 1 << SEG_PB;
public static final int SEG_SELECTION_COLOR_MASK = 1<<SEG_BL | 1<<SEG_BT | 1<<SEG_BR | 1<<SEG_BB | 1<<SEG_CONTENT;
private static final int DIVIDER = 8;
private String mMargin, mBorder, mPadding, mContent, mLeft, mTop, mRight, mBottom;
private Paint mCountourPlainPaint;
private Paint mCountourDashPaint;
private Paint mBorderAreaPaint;
private Paint mSelectedAreaPaint;
private Paint mTextPaint;
private final String mMargin;
private final String mBorder;
private final String mPadding;
private final String mContent;
private final String mLeft;
private final String mTop;
private final String mRight;
private final String mBottom;
private final Paint mCountourPlainPaint;
private final Paint mCountourDashPaint;
private final Paint mBorderAreaPaint;
private final Paint mSelectedAreaPaint;
private final Paint mTextPaint;
private final RectF mOuterRect = new RectF();
private final RectF mMarginRect = new RectF();
private final RectF mBorderRect = new RectF();
private final RectF mPaddingRect = new RectF();
private final Path[] mAreas = new Path[13];
private FontMetrics mTextMetrics;
private RectF mOuterRect = new RectF();
private RectF mMarginRect = new RectF();
private RectF mBorderRect = new RectF();
private RectF mPaddingRect = new RectF();
private Path[] mAreas = new Path[13];
private int mSelectedSegments;
private int mTouchedSegment;
private Object mOnBoxEditorEventToken;
private OnBoxEditorEventListener mOnBoxEditorEventListener;
private boolean mHasLongClicked;
public BoxEditorView(Context context, AttributeSet attrs) {
@ -133,7 +126,6 @@ public class BoxEditorView extends View implements Runnable {
setMeasuredDimension(w, w * 2 / 3);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
final int sw = (w < h ? w : h) / DIVIDER;
@ -166,22 +158,100 @@ public class BoxEditorView extends View implements Runnable {
Path p;
p = new Path(); p.moveTo(ol, ot); p.lineTo(ml, mt); p.lineTo(ml, mb); p.lineTo(ol, ob); p.close(); mAreas[SEG_ML] = p;
p = new Path(); p.moveTo(ol, ot); p.lineTo(or, ot); p.lineTo(mr, mt); p.lineTo(ml, mt); p.close(); mAreas[SEG_MT] = p;
p = new Path(); p.moveTo(or, ot); p.lineTo(or, ob); p.lineTo(mr, mb); p.lineTo(mr, mt); p.close(); mAreas[SEG_MR] = p;
p = new Path(); p.moveTo(ol, ob); p.lineTo(ml, mb); p.lineTo(mr, mb); p.lineTo(or, ob); p.close(); mAreas[SEG_MB] = p;
p = new Path();
p.moveTo(ol, ot);
p.lineTo(ml, mt);
p.lineTo(ml, mb);
p.lineTo(ol, ob);
p.close();
mAreas[SEG_ML] = p;
p = new Path();
p.moveTo(ol, ot);
p.lineTo(or, ot);
p.lineTo(mr, mt);
p.lineTo(ml, mt);
p.close();
mAreas[SEG_MT] = p;
p = new Path();
p.moveTo(or, ot);
p.lineTo(or, ob);
p.lineTo(mr, mb);
p.lineTo(mr, mt);
p.close();
mAreas[SEG_MR] = p;
p = new Path();
p.moveTo(ol, ob);
p.lineTo(ml, mb);
p.lineTo(mr, mb);
p.lineTo(or, ob);
p.close();
mAreas[SEG_MB] = p;
p = new Path(); p.moveTo(ml, mt); p.lineTo(bl, bt); p.lineTo(bl, bb); p.lineTo(ml, mb); p.close(); mAreas[SEG_BL] = p;
p = new Path(); p.moveTo(ml, mt); p.lineTo(mr, mt); p.lineTo(br, bt); p.lineTo(bl, bt); p.close(); mAreas[SEG_BT] = p;
p = new Path(); p.moveTo(mr, mt); p.lineTo(mr, mb); p.lineTo(br, bb); p.lineTo(br, bt); p.close(); mAreas[SEG_BR] = p;
p = new Path(); p.moveTo(ml, mb); p.lineTo(bl, bb); p.lineTo(br, bb); p.lineTo(mr, mb); p.close(); mAreas[SEG_BB] = p;
p = new Path();
p.moveTo(ml, mt);
p.lineTo(bl, bt);
p.lineTo(bl, bb);
p.lineTo(ml, mb);
p.close();
mAreas[SEG_BL] = p;
p = new Path();
p.moveTo(ml, mt);
p.lineTo(mr, mt);
p.lineTo(br, bt);
p.lineTo(bl, bt);
p.close();
mAreas[SEG_BT] = p;
p = new Path();
p.moveTo(mr, mt);
p.lineTo(mr, mb);
p.lineTo(br, bb);
p.lineTo(br, bt);
p.close();
mAreas[SEG_BR] = p;
p = new Path();
p.moveTo(ml, mb);
p.lineTo(bl, bb);
p.lineTo(br, bb);
p.lineTo(mr, mb);
p.close();
mAreas[SEG_BB] = p;
p = new Path(); p.moveTo(bl, bt); p.lineTo(pl, pt); p.lineTo(pl, pb); p.lineTo(bl, bb); p.close(); mAreas[SEG_PL] = p;
p = new Path(); p.moveTo(bl, bt); p.lineTo(br, bt); p.lineTo(pr, pt); p.lineTo(pl, pt); p.close(); mAreas[SEG_PT] = p;
p = new Path(); p.moveTo(br, bt); p.lineTo(br, bb); p.lineTo(pr, pb); p.lineTo(pr, pt); p.close(); mAreas[SEG_PR] = p;
p = new Path(); p.moveTo(bl, bb); p.lineTo(pl, pb); p.lineTo(pr, pb); p.lineTo(br, bb); p.close(); mAreas[SEG_PB] = p;
p = new Path();
p.moveTo(bl, bt);
p.lineTo(pl, pt);
p.lineTo(pl, pb);
p.lineTo(bl, bb);
p.close();
mAreas[SEG_PL] = p;
p = new Path();
p.moveTo(bl, bt);
p.lineTo(br, bt);
p.lineTo(pr, pt);
p.lineTo(pl, pt);
p.close();
mAreas[SEG_PT] = p;
p = new Path();
p.moveTo(br, bt);
p.lineTo(br, bb);
p.lineTo(pr, pb);
p.lineTo(pr, pt);
p.close();
mAreas[SEG_PR] = p;
p = new Path();
p.moveTo(bl, bb);
p.lineTo(pl, pb);
p.lineTo(pr, pb);
p.lineTo(br, bb);
p.close();
mAreas[SEG_PB] = p;
p = new Path(); p.moveTo(bl, bt); p.lineTo(br, bt); p.lineTo(br, bb); p.lineTo(bl, bb); p.close(); mAreas[SEG_CONTENT] = p;
p = new Path();
p.moveTo(bl, bt);
p.lineTo(br, bt);
p.lineTo(br, bb);
p.lineTo(bl, bb);
p.close();
mAreas[SEG_CONTENT] = p;
mTextPaint.setTextSize(sh / 2);
mTextMetrics = mTextPaint.getFontMetrics();
@ -328,4 +398,8 @@ public class BoxEditorView extends View implements Runnable {
}
}
}
public interface OnBoxEditorEventListener {
void onBoxSelectionChanged(Object token, int selection);
}
}

View file

@ -35,10 +35,10 @@ import net.pierrox.lightning_launcher_extreme.R;
@SuppressWarnings("deprecation")
public class BubbleLayout extends AbsoluteLayout {
private final int mBubbleArrowShift;
private float mDensity;
private int mScreenPadding;
private Rect mItemBounds;
private int mBubbleArrowShift;
public BubbleLayout(Context context, AttributeSet attrs) {
super(context, attrs);
@ -83,7 +83,6 @@ public class BubbleLayout extends AbsoluteLayout {
int a_left, a_right, a_top, a_bottom;
final int bw = bubble.getMeasuredWidth();
final int bh = bubble.getMeasuredHeight();

View file

@ -45,32 +45,26 @@ import android.widget.ImageView;
import net.pierrox.lightning_launcher_extreme.R;
public class CropperView extends ImageView {
public interface OnCropperViewEvent {
public void onCropperViewSelectionChanged(Rect selection);
public void onCropperViewClick();
}
private final Paint mSelectionRectPaint;
private final Paint mOutHighlightPaint;
private final Bitmap mHandleWidthBitmap;
private final Bitmap mHandleHeightBitmap;
private final float mDensity;
private final int mHandleTouchSize;
private final int mTouchSlope;
private final Matrix mTmpMatrix = new Matrix();
RectF mTmpRectF = new RectF();
Rect mTmpRect = new Rect();
private Bitmap mBitmap;
private Rect mSelectionRect;
private Paint mSelectionRectPaint;
private Paint mOutHighlightPaint;
private Bitmap mHandleWidthBitmap;
private Bitmap mHandleHeightBitmap;
private float mDensity;
private int mHandleTouchSize;
private int mTouchSlope;
private boolean mIsDown;
private int mDownX, mDownY;
private int mCurrentMoveArea;
private Rect mInitialSelectionRect;
private long mLastClickDate;
private boolean mMoving;
private OnCropperViewEvent mListener;
private Runnable mClickRunnable = new Runnable() {
private final Runnable mClickRunnable = new Runnable() {
@Override
public void run() {
if (mListener != null) mListener.onCropperViewClick();
@ -278,11 +272,19 @@ public class CropperView extends ImageView {
mListener = listener;
}
public Rect getSelection() {
mTmpRectF.set(mSelectionRect);
getImageMatrix().invert(mTmpMatrix);
Drawable drawable = getDrawable();
Bitmap image = ((BitmapDrawable) drawable).getBitmap();
float sx = image.getWidth() / (float) drawable.getIntrinsicWidth();
float sy = image.getHeight() / (float) drawable.getIntrinsicHeight();
mTmpMatrix.postScale(sx, sy);
mTmpMatrix.mapRect(mTmpRectF);
mTmpRectF.round(mTmpRect);
private Matrix mTmpMatrix = new Matrix();
RectF mTmpRectF = new RectF();
Rect mTmpRect = new Rect();
return mTmpRect;
}
public void setSelection(Rect selection) {
mTmpRectF.set(selection);
@ -302,23 +304,15 @@ public class CropperView extends ImageView {
invalidate();
}
public Rect getSelection() {
mTmpRectF.set(mSelectionRect);
getImageMatrix().invert(mTmpMatrix);
Drawable drawable = getDrawable();
Bitmap image = ((BitmapDrawable) drawable).getBitmap();
float sx = image.getWidth() / (float)drawable.getIntrinsicWidth();
float sy = image.getHeight() / (float)drawable.getIntrinsicHeight();
mTmpMatrix.postScale(sx, sy);
mTmpMatrix.mapRect(mTmpRectF);
mTmpRectF.round(mTmpRect);
return mTmpRect;
}
private void sendSelectionChangedEvent() {
if (mListener != null) {
mListener.onCropperViewSelectionChanged(getSelection());
}
}
public interface OnCropperViewEvent {
void onCropperViewSelectionChanged(Rect selection);
void onCropperViewClick();
}
}

View file

@ -40,7 +40,6 @@ import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.TypedValue;
@ -87,6 +86,7 @@ import net.pierrox.lightning_launcher.data.Shortcut;
import net.pierrox.lightning_launcher.data.StopPoint;
import net.pierrox.lightning_launcher.data.UndoStack;
import net.pierrox.lightning_launcher.data.Utils;
import net.pierrox.lightning_launcher.engine.variable.Binding;
import net.pierrox.lightning_launcher.prefs.LLPreference;
import net.pierrox.lightning_launcher.prefs.LLPreferenceBinding;
import net.pierrox.lightning_launcher.prefs.LLPreferenceBox;
@ -99,11 +99,10 @@ import net.pierrox.lightning_launcher.prefs.LLPreferenceListView;
import net.pierrox.lightning_launcher.prefs.LLPreferenceSlider;
import net.pierrox.lightning_launcher.prefs.LLPreferenceText;
import net.pierrox.lightning_launcher.script.Script;
import net.pierrox.lightning_launcher.util.ScriptPickerDialog;
import net.pierrox.lightning_launcher.util.BindingEditDialog;
import net.pierrox.lightning_launcher.util.FileAndDirectoryPickerDialog;
import net.pierrox.lightning_launcher.util.PhoneUtils;
import net.pierrox.lightning_launcher.engine.variable.Binding;
import net.pierrox.lightning_launcher.util.ScriptPickerDialog;
import net.pierrox.lightning_launcher_extreme.R;
import java.io.File;
@ -129,7 +128,115 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
private static final String SIS_PICK_EVENT_ACTION_PREFERENCE_ID = "civ_pid";
private static final String FONT_ITEM_PREVIEW = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final int ID_mItemLabelDisplay = 1;
// private static final int ID_mItemLabelCustom = 2;
private static final int ID_mItemLabelSize = 3;
private static final int ID_mItemLabelStyle = 4;
private static final int ID_mItemLabelFont = 5;
private static final int ID_mItemLabelNumLines = 6;
private static final int ID_mItemLabelColorNormal = 7;
private static final int ID_mItemLabelColorSelected = 8;
private static final int ID_mItemLabelColorFocused = 9;
private static final int ID_mItemLabelShadow = 10;
private static final int ID_mItemLabelShadowRadius = 11;
private static final int ID_mItemLabelShadowOffsetX = 12;
private static final int ID_mItemLabelShadowOffsetY = 13;
private static final int ID_mItemLabelShadowColor = 14;
private static final int ID_mItemIconDisplay = 15;
// private static final int ID_mItemIconCustom = 16;
private static final int ID_mItemIconFolder = 17;
private static final int ID_mItemIconSmooth = 18;
private static final int ID_mItemIconScale = 19;
private static final int ID_mItemIconEffectBack = 25;
private static final int ID_mItemIconEffectOver = 26;
private static final int ID_mItemIconEffectMask = 27;
private static final int ID_mItemIconEffectScale = 28;
private static final int ID_mItemIconReflection = 29;
private static final int ID_mItemIconReflectionOverlap = 30;
private static final int ID_mItemIconReflectionSize = 31;
private static final int ID_mItemIconReflectionScale = 32;
private static final int ID_mItemLayoutMargin = 33;
private static final int ID_mItemLayoutPosition = 34;
private static final int ID_mItemBoxAlignH = 35;
private static final int ID_mItemBoxAlignV = 36;
private static final int ID_mItemBoxBox = 37;
private static final int ID_mItemBoxSize = 38;
private static final int ID_mItemBoxColorNormal = 39;
private static final int ID_mItemBoxColorSelected = 40;
private static final int ID_mItemBoxColorFocused = 41;
private static final int ID_mItemMiscEnabled = 42;
private static final int ID_mItemMiscAlpha = 43;
private static final int ID_mItemMiscSmoothTransformed = 44;
private static final int ID_mItemMiscEventSwipeLeft = 45;
private static final int ID_mItemMiscEventSwipeRight = 46;
private static final int ID_mItemMiscEventSwipeUp = 47;
private static final int ID_mItemMiscEventSwipeDown = 48;
private static final int ID_mItemMiscEventLongTap = 49;
private static final int ID_mItemMiscEventTap = 107;
private static final int ID_mItemMiscPinMode = 108;
private static final int ID_mItemSpDirLeftToRight = 114;
private static final int ID_mItemSpDirRightToLeft = 115;
private static final int ID_mItemSpDirTopToBottom = 116;
private static final int ID_mItemSpDirBottomToTop = 117;
private static final int ID_mItemSpStopScroll = 118;
private static final int ID_mItemSpStopDrag = 119;
private static final int ID_mItemSpBarrier = 120;
private static final int ID_mItemSpDesktopWide = 121;
private static final int ID_mItemSpSnapping = 122;
private static final int ID_mItemSpMatchEdgeLeft = 131;
private static final int ID_mItemSpMatchEdgeRight = 132;
private static final int ID_mItemSpMatchEdgeTop = 133;
private static final int ID_mItemSpMatchEdgeBottom = 134;
private static final int ID_ninePatch = 135;
private static final int ID_mItemMiscSelectionEffect = 142;
private static final int ID_mItemMiscRotate = 143;
private static final int ID_mItemSpReachedEvent = 144;
private static final int ID_mItemMiscName = 147;
private static final int ID_mItemBoxColorBasic = 149;
private static final int ID_mItemTextColorBasic = 150;
private static final int ID_mPageEventPaused = 153;
private static final int ID_mPageEventResumed = 154;
private static final int ID_mItemMiscEventTouch = 160;
private static final int ID_mItemIconColorFilter = 162;
private static final int ID_mItemMiscSelectionEffectMask = 169;
private static final int ID_mItemPIStyle = 170;
private static final int ID_mItemPIRawFormat = 171;
private static final int ID_mItemPIDotsMarginX = 172;
private static final int ID_mItemPIDotsMarginY = 173;
private static final int ID_mItemPIDotsOuterRadius = 174;
private static final int ID_mItemPIDotsInnerRadius = 175;
private static final int ID_mItemPIDotsOuterStrokeWidth = 176;
private static final int ID_mItemPIDotsOuterColor = 177;
private static final int ID_mItemPIDotsInnerColor = 178;
private static final int ID_mItemPIMiniMapOutStrokeColor = 179;
private static final int ID_mItemPIMiniMapOutFillColor = 180;
private static final int ID_mItemPIMiniMapOutStrokeWidth = 181;
private static final int ID_mItemPIMiniMapInStrokeColor = 182;
private static final int ID_mItemPIMiniMapInFillColor = 183;
private static final int ID_mItemPIMiniMapInStrokeWidth = 184;
private static final int ID_mItemPILineBgWidth = 185;
private static final int ID_mItemPILineBgColor = 186;
private static final int ID_mItemPILineFgWidth = 187;
private static final int ID_mItemPILineFgColor = 188;
private static final int ID_mItemPILineGravity = 189;
private static final int ID_mItemDtTextFormat = 193;
private static final int ID_mItemMiscEventCVCreate = 195;
private static final int ID_mItemMiscEventCVDestroy = 196;
private static final int ID_mItemBindingsAdd = 197;
private static final int ID_mItemMiscHardwareAccelerated = 198;
private static final int ID_mItemMiscLaunchAnimation = 199;
private static final int ID_mItemIconSizeMode = 200;
private static final int ID_mItemMiscEventMenu = 204;
private static final int ID_mItemDtSource = 10004;
private static final int ID_mItemDtDateEasyFormat = 10005;
private static final int ID_mItemDtDateExpertFormat = 10006;
private static final int ID_mItemDtDisplayEmpty = 10007;
private static final int ID_mItemDtCountFormat = 10008;
private static final int ID_mItemDtStorageSource = 10009;
private static final int ID_mItemDtStorageFormat = 10010;
private static final int ID_mItemDtStorageWhat = 10011;
private static final int ID_mItemDtGmailLabel = 10012;
// list views
private LLPreferenceListView[] mAllPreferenceListViews;
private LLPreferenceListView mItemPrefsLabel;
@ -142,7 +249,6 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
private LLPreferenceListView mItemPrefsStopPoint;
private LLPreferenceListView mItemPrefsPageIndicator;
private LLPreferenceListView mItemPrefsBindings;
// label
private LLPreferenceCheckBox mItemLabelDisplay;
private LLPreferenceSlider mItemLabelSize;
@ -158,7 +264,6 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
private LLPreferenceSlider mItemLabelShadowOffsetX;
private LLPreferenceSlider mItemLabelShadowOffsetY;
private LLPreferenceColor mItemLabelShadowColor;
// icon
private LLPreferenceCheckBox mItemIconDisplay;
private LLPreferenceList mItemIconFolder;
@ -175,7 +280,6 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
private LLPreferenceSlider mItemIconReflectionOverlap;
private LLPreferenceSlider mItemIconReflectionSize;
private LLPreferenceSlider mItemIconReflectionScale;
// dynamic text
private LLPreferenceList mItemDtSource;
private LLPreferenceCheckBox mItemDtDisplayEmpty;
@ -187,7 +291,6 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
private LLPreferenceList mItemDtStorageFormat;
private LLPreferenceList mItemDtStorageWhat;
private LLPreferenceList mItemDtGmailLabel;
// page indicator
private LLPreferenceList mItemPIStyle;
private LLPreferenceSlider mItemPIDotsMarginX;
@ -209,11 +312,9 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
private LLPreferenceSlider mItemPILineFgWidth;
private LLPreferenceColor mItemPILineFgColor;
private LLPreferenceList mItemPILineGravity;
// position
private LLPreferenceSlider mItemLayoutMargin;
private LLPreferenceList mItemLayoutPosition;
// box
private LLPreferenceList mItemBoxAlignH;
private LLPreferenceList mItemBoxAlignV;
@ -227,7 +328,6 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
private LLPreference mItemBoxNpSelected;
private LLPreference mItemBoxNpFocused;
private LLPreference mItemBoxNpBasic;
// misc
private LLPreference mItemMiscName;
private LLPreferenceList mItemMiscLaunchAnimation;
@ -239,7 +339,6 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
private LLPreferenceSlider mItemMiscAlpha;
private LLPreferenceCheckBox mItemMiscSmoothTransformed;
private LLPreferenceCheckBox mItemMiscHardwareAccelerated;
// event
private LLPreferenceEventAction mItemMiscEventSwipeLeft;
private LLPreferenceEventAction mItemMiscEventSwipeRight;
@ -254,7 +353,6 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
private LLPreferenceEventAction mItemSpReachedEvent;
private LLPreference mItemMiscEventCVCreate;
private LLPreference mItemMiscEventCVDestroy;
// stop point
private LLPreferenceCheckBox mItemSpStopScroll;
private LLPreferenceCheckBox mItemSpStopDrag;
@ -269,35 +367,39 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
private LLPreferenceCheckBox mItemSpMatchEdgeRight;
private LLPreferenceCheckBox mItemSpMatchEdgeTop;
private LLPreferenceCheckBox mItemSpMatchEdgeBottom;
// bindings
private LLPreference mItemBindingsAdd;
private Dashboard mDashboard;
private UndoStack mUndoStack;
private boolean mSetupDone;
private boolean mExpertMode;
private ItemLayout mItemLayout;
private Page mPage;
private Item mItem;
private boolean mForPage;
private int mPickEventActionPreferenceId;
private File mPreviouslyUsedDir;
private String[] mFonts;
private ItemConfig ic_def;
private ShortcutConfig sc_def;
private FolderConfig fc_def;
private DynamicTextConfig dtc;
private ActionsDescription mActionsDescriptions;
public CustomizeItemView(Context context, AttributeSet attrs) {
super(context, attrs);
}
private static int getEasyDateFormatIndex(Context context, String format) {
String[] date_formats = context.getResources().getStringArray(R.array.dt_date_ef_v);
for (int i = 0; i < date_formats.length; i++) {
if (date_formats[i].equals(format)) {
return i;
}
}
return -1;
}
public void init() {
LLApp app = LLApp.get();
mExpertMode = app.getSystemConfig().expertMode;
@ -886,11 +988,7 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
boolean is_dynamic_text = mItem != null && mItem.getClass() == DynamicText.class;
boolean is_page_indicator = mItem != null && mItem.getClass() == PageIndicator.class;
if(is_dynamic_text || is_page_indicator) {
mItemLabelDisplay.setVisible(false);
} else {
mItemLabelDisplay.setVisible(true);
}
mItemLabelDisplay.setVisible(!is_dynamic_text && !is_page_indicator);
mItemLabelDisplay.setValue(sc.labelVisibility || is_dynamic_text, sc_def == null ? null : sc_def.labelVisibility);
mItemLabelSize.setValue(sc.labelFontSize, sc_def == null ? null : sc_def.labelFontSize);
mItemLabelStyle.setValue(sc.labelFontStyle, sc_def == null ? null : sc_def.labelFontStyle);
@ -1714,25 +1812,63 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
}
break;
case ID_mItemPIDotsOuterColor: pageIndicator.dotsOuterColor = colorValue; break;
case ID_mItemPIDotsOuterRadius: pageIndicator.dotsOuterRadius = intValue; break;
case ID_mItemPIDotsOuterStrokeWidth: pageIndicator.dotsOuterStrokeWidth = intValue; break;
case ID_mItemPIDotsInnerColor: pageIndicator.dotsInnerColor = colorValue; break;
case ID_mItemPIDotsInnerRadius: pageIndicator.dotsInnerRadius = intValue; break;
case ID_mItemPIDotsMarginX: pageIndicator.dotsMarginX = intValue; break;
case ID_mItemPIDotsMarginY: pageIndicator.dotsMarginY = intValue; break;
case ID_mItemPIRawFormat: pageIndicator.rawFormat = textValue; break;
case ID_mItemPIMiniMapOutStrokeColor: pageIndicator.miniMapOutStrokeColor = colorValue; break;
case ID_mItemPIMiniMapOutStrokeWidth: pageIndicator.miniMapOutStrokeWidth = intValue; break;
case ID_mItemPIMiniMapOutFillColor: pageIndicator.miniMapOutFillColor = colorValue; break;
case ID_mItemPIMiniMapInStrokeColor: pageIndicator.miniMapInStrokeColor = colorValue; break;
case ID_mItemPIMiniMapInStrokeWidth: pageIndicator.miniMapInStrokeWidth = intValue; break;
case ID_mItemPIMiniMapInFillColor: pageIndicator.miniMapInFillColor = colorValue; break;
case ID_mItemPILineBgWidth: pageIndicator.lineBgWidth = intValue; break;
case ID_mItemPILineBgColor: pageIndicator.lineBgColor = colorValue; break;
case ID_mItemPILineFgWidth: pageIndicator.lineFgWidth = intValue; break;
case ID_mItemPILineFgColor: pageIndicator.lineFgColor = colorValue; break;
case ID_mItemPILineGravity: pageIndicator.lineGravity = (PageIndicator.LineGravity) enumValue; break;
case ID_mItemPIDotsOuterColor:
pageIndicator.dotsOuterColor = colorValue;
break;
case ID_mItemPIDotsOuterRadius:
pageIndicator.dotsOuterRadius = intValue;
break;
case ID_mItemPIDotsOuterStrokeWidth:
pageIndicator.dotsOuterStrokeWidth = intValue;
break;
case ID_mItemPIDotsInnerColor:
pageIndicator.dotsInnerColor = colorValue;
break;
case ID_mItemPIDotsInnerRadius:
pageIndicator.dotsInnerRadius = intValue;
break;
case ID_mItemPIDotsMarginX:
pageIndicator.dotsMarginX = intValue;
break;
case ID_mItemPIDotsMarginY:
pageIndicator.dotsMarginY = intValue;
break;
case ID_mItemPIRawFormat:
pageIndicator.rawFormat = textValue;
break;
case ID_mItemPIMiniMapOutStrokeColor:
pageIndicator.miniMapOutStrokeColor = colorValue;
break;
case ID_mItemPIMiniMapOutStrokeWidth:
pageIndicator.miniMapOutStrokeWidth = intValue;
break;
case ID_mItemPIMiniMapOutFillColor:
pageIndicator.miniMapOutFillColor = colorValue;
break;
case ID_mItemPIMiniMapInStrokeColor:
pageIndicator.miniMapInStrokeColor = colorValue;
break;
case ID_mItemPIMiniMapInStrokeWidth:
pageIndicator.miniMapInStrokeWidth = intValue;
break;
case ID_mItemPIMiniMapInFillColor:
pageIndicator.miniMapInFillColor = colorValue;
break;
case ID_mItemPILineBgWidth:
pageIndicator.lineBgWidth = intValue;
break;
case ID_mItemPILineBgColor:
pageIndicator.lineBgColor = colorValue;
break;
case ID_mItemPILineFgWidth:
pageIndicator.lineFgWidth = intValue;
break;
case ID_mItemPILineFgColor:
pageIndicator.lineFgColor = colorValue;
break;
case ID_mItemPILineGravity:
pageIndicator.lineGravity = (PageIndicator.LineGravity) enumValue;
break;
}
}
mPage.endItemChange(item);
@ -1933,17 +2069,6 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
}
}
private static int getEasyDateFormatIndex(Context context, String format) {
String[] date_formats = context.getResources().getStringArray(R.array.dt_date_ef_v);
for(int i=0; i<date_formats.length; i++) {
if(date_formats[i].equals(format)) {
return i;
}
}
return -1;
}
private void setPreferenceSummaryForScript(LLPreference preference, String id_data) {
preference.setSummary("");
if (id_data != null) {
@ -2022,16 +2147,36 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
itemConfig = ((Page) object).config.defaultItemConfig;
}
switch (preferenceId) {
case ID_mItemMiscEventSwipeLeft: itemConfig.swipeLeft = ea; break;
case ID_mItemMiscEventSwipeRight: itemConfig.swipeRight = ea; break;
case ID_mItemMiscEventSwipeUp: itemConfig.swipeUp = ea; break;
case ID_mItemMiscEventSwipeDown: itemConfig.swipeDown = ea; break;
case ID_mItemMiscEventTap: itemConfig.tap = ea; break;
case ID_mItemMiscEventLongTap: itemConfig.longTap = ea; break;
case ID_mItemMiscEventTouch: itemConfig.touch = ea; break;
case ID_mPageEventPaused: itemConfig.paused = ea; break;
case ID_mPageEventResumed: itemConfig.resumed = ea; break;
case ID_mItemMiscEventMenu: itemConfig.menu = ea; break;
case ID_mItemMiscEventSwipeLeft:
itemConfig.swipeLeft = ea;
break;
case ID_mItemMiscEventSwipeRight:
itemConfig.swipeRight = ea;
break;
case ID_mItemMiscEventSwipeUp:
itemConfig.swipeUp = ea;
break;
case ID_mItemMiscEventSwipeDown:
itemConfig.swipeDown = ea;
break;
case ID_mItemMiscEventTap:
itemConfig.tap = ea;
break;
case ID_mItemMiscEventLongTap:
itemConfig.longTap = ea;
break;
case ID_mItemMiscEventTouch:
itemConfig.touch = ea;
break;
case ID_mPageEventPaused:
itemConfig.paused = ea;
break;
case ID_mPageEventResumed:
itemConfig.resumed = ea;
break;
case ID_mItemMiscEventMenu:
itemConfig.menu = ea;
break;
}
}
}
@ -2079,8 +2224,14 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
} catch (Exception e) {
file = null;
} finally {
if (fos != null) try { fos.close(); } catch (Exception e) { }
if (fis != null) try { fis.close(); } catch (Exception e) { }
if (fos != null) try {
fos.close();
} catch (Exception e) {
}
if (fis != null) try {
fis.close();
} catch (Exception e) {
}
}
if (file != null) {
if (mForPage) {
@ -2215,8 +2366,6 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
mItem.notifyBindingsChanged(apply);
}
private static final String FONT_ITEM_PREVIEW = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
@Override
public void onSystemConfigChanged(SystemConfig newSystemConfig) {
boolean expert_mode = newSystemConfig.expertMode;
@ -2226,75 +2375,6 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
}
}
private class FontAdapter extends ArrayAdapter<String> {
private HashMap<String,Typeface> mTypefaces = new HashMap<>();
private File mFontsDir;
private int mSelectedIndex;
private int mCheckMarkDrawable;
private LayoutInflater inflater;
public FontAdapter(Context context, String[] fonts, int selected_index) {
super(context, 0, fonts);
mFontsDir = FileUtils.getFontsDir(getPageBaseDir());
mSelectedIndex = selected_index;
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.listChoiceIndicatorSingle, typedValue, true);
mCheckMarkDrawable = typedValue.resourceId;
inflater = (LayoutInflater.from(context));
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = inflater.inflate(R.layout.two_lines_list_item_font, null);
}
String f = getItem(position);
CheckedTextView line1 = (CheckedTextView) convertView.findViewById(android.R.id.text1);
TextView line2 = (TextView) convertView.findViewById(android.R.id.text2);
line1.setText(f);
if(position == 0) {
line1.setCheckMarkDrawable(null);
line2.setVisibility(View.GONE);
} else {
line1.setCheckMarkDrawable(mCheckMarkDrawable);
Typeface font;
if(position == 1) {
font = Typeface.DEFAULT;
} else if(position == 2) {
font = LLApp.get().getIconsTypeface();
} else {
font = mTypefaces.get(f);
if (font == null) {
try {
font = Typeface.createFromFile(new File(mFontsDir, f));
mTypefaces.put(f, font);
} catch (Exception e) {
// pass, use a default font
}
}
if (font == null) {
font = Typeface.DEFAULT;
mTypefaces.put(f, font);
}
}
line2.setVisibility(View.VISIBLE);
line2.setTypeface(font);
line2.setText(FONT_ITEM_PREVIEW);
line1.setChecked(position == mSelectedIndex);
}
return convertView;
}
}
private boolean applyPreferenceOnStylableObject(Object object, LLPreference preference) {
final int preferenceId = preference.getId();
@ -2585,113 +2665,72 @@ public class CustomizeItemView extends MyViewPager implements LLPreferenceListVi
return mForPage ? mPage.getShortcutConfig() : ((ShortcutConfigStylable) mItem).getShortcutConfig();
}
private static final int ID_mItemLabelDisplay = 1;
// private static final int ID_mItemLabelCustom = 2;
private static final int ID_mItemLabelSize = 3;
private static final int ID_mItemLabelStyle = 4;
private static final int ID_mItemLabelFont = 5;
private static final int ID_mItemLabelNumLines = 6;
private static final int ID_mItemLabelColorNormal = 7;
private static final int ID_mItemLabelColorSelected = 8;
private static final int ID_mItemLabelColorFocused = 9;
private static final int ID_mItemLabelShadow = 10;
private static final int ID_mItemLabelShadowRadius = 11;
private static final int ID_mItemLabelShadowOffsetX = 12;
private static final int ID_mItemLabelShadowOffsetY = 13;
private static final int ID_mItemLabelShadowColor = 14;
private static final int ID_mItemIconDisplay = 15;
// private static final int ID_mItemIconCustom = 16;
private static final int ID_mItemIconFolder = 17;
private static final int ID_mItemIconSmooth = 18;
private static final int ID_mItemIconScale = 19;
private static final int ID_mItemIconEffectBack = 25;
private static final int ID_mItemIconEffectOver = 26;
private static final int ID_mItemIconEffectMask = 27;
private static final int ID_mItemIconEffectScale = 28;
private static final int ID_mItemIconReflection = 29;
private static final int ID_mItemIconReflectionOverlap = 30;
private static final int ID_mItemIconReflectionSize = 31;
private static final int ID_mItemIconReflectionScale = 32;
private static final int ID_mItemLayoutMargin = 33;
private static final int ID_mItemLayoutPosition = 34;
private static final int ID_mItemBoxAlignH = 35;
private static final int ID_mItemBoxAlignV = 36;
private static final int ID_mItemBoxBox = 37;
private static final int ID_mItemBoxSize = 38;
private static final int ID_mItemBoxColorNormal = 39;
private static final int ID_mItemBoxColorSelected = 40;
private static final int ID_mItemBoxColorFocused = 41;
private static final int ID_mItemMiscEnabled = 42;
private static final int ID_mItemMiscAlpha = 43;
private static final int ID_mItemMiscSmoothTransformed = 44;
private static final int ID_mItemMiscEventSwipeLeft = 45;
private static final int ID_mItemMiscEventSwipeRight = 46;
private static final int ID_mItemMiscEventSwipeUp = 47;
private static final int ID_mItemMiscEventSwipeDown = 48;
private static final int ID_mItemMiscEventLongTap = 49;
private static final int ID_mItemMiscEventTap = 107;
private static final int ID_mItemMiscPinMode = 108;
private static final int ID_mItemSpDirLeftToRight = 114;
private static final int ID_mItemSpDirRightToLeft = 115;
private static final int ID_mItemSpDirTopToBottom = 116;
private static final int ID_mItemSpDirBottomToTop = 117;
private static final int ID_mItemSpStopScroll = 118;
private static final int ID_mItemSpStopDrag = 119;
private static final int ID_mItemSpBarrier = 120;
private static final int ID_mItemSpDesktopWide = 121;
private static final int ID_mItemSpSnapping = 122;
private static final int ID_mItemSpMatchEdgeLeft = 131;
private static final int ID_mItemSpMatchEdgeRight = 132;
private static final int ID_mItemSpMatchEdgeTop = 133;
private static final int ID_mItemSpMatchEdgeBottom = 134;
private static final int ID_ninePatch= 135;
private static final int ID_mItemMiscSelectionEffect = 142;
private static final int ID_mItemMiscRotate = 143;
private static final int ID_mItemSpReachedEvent = 144;
private static final int ID_mItemMiscName = 147;
private static final int ID_mItemBoxColorBasic = 149;
private static final int ID_mItemTextColorBasic = 150;
private static final int ID_mPageEventPaused = 153;
private static final int ID_mPageEventResumed = 154;
private static final int ID_mItemMiscEventTouch = 160;
private static final int ID_mItemIconColorFilter = 162;
private static final int ID_mItemMiscSelectionEffectMask = 169;
private static final int ID_mItemPIStyle = 170;
private static final int ID_mItemPIRawFormat = 171;
private static final int ID_mItemPIDotsMarginX = 172;
private static final int ID_mItemPIDotsMarginY = 173;
private static final int ID_mItemPIDotsOuterRadius = 174;
private static final int ID_mItemPIDotsInnerRadius = 175;
private static final int ID_mItemPIDotsOuterStrokeWidth = 176;
private static final int ID_mItemPIDotsOuterColor = 177;
private static final int ID_mItemPIDotsInnerColor = 178;
private static final int ID_mItemPIMiniMapOutStrokeColor = 179;
private static final int ID_mItemPIMiniMapOutFillColor = 180;
private static final int ID_mItemPIMiniMapOutStrokeWidth = 181;
private static final int ID_mItemPIMiniMapInStrokeColor = 182;
private static final int ID_mItemPIMiniMapInFillColor = 183;
private static final int ID_mItemPIMiniMapInStrokeWidth = 184;
private static final int ID_mItemPILineBgWidth = 185;
private static final int ID_mItemPILineBgColor = 186;
private static final int ID_mItemPILineFgWidth = 187;
private static final int ID_mItemPILineFgColor = 188;
private static final int ID_mItemPILineGravity = 189;
private static final int ID_mItemDtTextFormat = 193;
private static final int ID_mItemMiscEventCVCreate = 195;
private static final int ID_mItemMiscEventCVDestroy = 196;
private static final int ID_mItemBindingsAdd = 197;
private static final int ID_mItemMiscHardwareAccelerated = 198;
private static final int ID_mItemMiscLaunchAnimation = 199;
private static final int ID_mItemIconSizeMode = 200;
private static final int ID_mItemMiscEventMenu = 204;
private class FontAdapter extends ArrayAdapter<String> {
private final HashMap<String, Typeface> mTypefaces = new HashMap<>();
private final File mFontsDir;
private final int mSelectedIndex;
private final int mCheckMarkDrawable;
private final LayoutInflater inflater;
private static final int ID_mItemDtSource = 10004;
private static final int ID_mItemDtDateEasyFormat = 10005;
private static final int ID_mItemDtDateExpertFormat = 10006;
private static final int ID_mItemDtDisplayEmpty = 10007;
private static final int ID_mItemDtCountFormat = 10008;
private static final int ID_mItemDtStorageSource = 10009;
private static final int ID_mItemDtStorageFormat = 10010;
private static final int ID_mItemDtStorageWhat = 10011;
private static final int ID_mItemDtGmailLabel = 10012;
public FontAdapter(Context context, String[] fonts, int selected_index) {
super(context, 0, fonts);
mFontsDir = FileUtils.getFontsDir(getPageBaseDir());
mSelectedIndex = selected_index;
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.listChoiceIndicatorSingle, typedValue, true);
mCheckMarkDrawable = typedValue.resourceId;
inflater = (LayoutInflater.from(context));
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.two_lines_list_item_font, null);
}
String f = getItem(position);
CheckedTextView line1 = convertView.findViewById(android.R.id.text1);
TextView line2 = convertView.findViewById(android.R.id.text2);
line1.setText(f);
if (position == 0) {
line1.setCheckMarkDrawable(null);
line2.setVisibility(View.GONE);
} else {
line1.setCheckMarkDrawable(mCheckMarkDrawable);
Typeface font;
if (position == 1) {
font = Typeface.DEFAULT;
} else if (position == 2) {
font = LLApp.get().getIconsTypeface();
} else {
font = mTypefaces.get(f);
if (font == null) {
try {
font = Typeface.createFromFile(new File(mFontsDir, f));
mTypefaces.put(f, font);
} catch (Exception e) {
// pass, use a default font
}
}
if (font == null) {
font = Typeface.DEFAULT;
mTypefaces.put(f, font);
}
}
line2.setVisibility(View.VISIBLE);
line2.setTypeface(font);
line2.setText(FONT_ITEM_PREVIEW);
line1.setChecked(position == mSelectedIndex);
}
return convertView;
}
}
}

View file

@ -39,7 +39,7 @@ import net.pierrox.lightning_launcher_extreme.R;
public class EditBarHiderView extends ImageButton implements Runnable {
private static final long ANIM_DURATION = 200;
private Bitmap mBitmap;
private final Bitmap mBitmap;
private float mAngle;
private Matrix mMatrix;
private long mAnimStart;

View file

@ -31,10 +31,7 @@ import android.widget.EditText;
public class EditTextIme extends EditText {
private OnEditTextImeListener mListener;
public interface OnEditTextImeListener {
public void onEditTextImeBackPressed();
}
private boolean mHadKeyDown;
public EditTextIme(Context context, AttributeSet attrs) {
super(context, attrs);
@ -44,8 +41,6 @@ public class EditTextIme extends EditText {
mListener = listener;
}
private boolean mHadKeyDown;
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
@ -64,4 +59,8 @@ public class EditTextIme extends EditText {
}
return false;
}
public interface OnEditTextImeListener {
void onEditTextImeBackPressed();
}
}

View file

@ -60,23 +60,14 @@ import java.util.HashSet;
public class HierarchyScreen {
public interface HierarchyScreenListener {
void onHierarchyScreenItemEdit(ContainerPath path, Item item);
void onHierarchyScreenContainerSettings(ContainerPath path);
void onHierarchyScreenItemMoved(HierarchyItem which, HierarchyItem before, HierarchyItem after);
int[] onHierarchyScreenGetRootPages();
}
private LightningEngine mLightningEngine;
private Screen mScreen;
private final LightningEngine mLightningEngine;
private final Screen mScreen;
private final HierarchyScreenListener mListener;
private View mRootView;
private HierarchyScreenListener mListener;
private Animation mHierarchyPaneAnimIn;
private Animation mHierarchyPaneAnimOut;
private DragSortListView mDragSortListView;
private HierarchyAdapter mAdapter;
public HierarchyScreen(LightningEngine engine, Screen screen, HierarchyScreenListener listener) {
mLightningEngine = engine;
mScreen = screen;
@ -99,10 +90,10 @@ public class HierarchyScreen {
final Context context = mScreen.getContext();
mRootView = LayoutInflater.from(context).inflate(R.layout.hierarchy_pane, null);
ViewGroup contentView = mScreen.getContentView();
ViewGroup editControlsView = (ViewGroup) contentView.findViewById(R.id.edit_controls);
ViewGroup editControlsView = contentView.findViewById(R.id.edit_controls);
editControlsView.addView(mRootView); // the dashboard should be responsible for inserting this view in its hierarchy
mDragSortListView = (DragSortListView) mRootView.findViewById(android.R.id.list);
mDragSortListView = mRootView.findViewById(android.R.id.list);
mAdapter = new HierarchyAdapter(context, mDragSortListView);
mHierarchyPaneAnimIn = AnimationUtils.makeInAnimation(context, true);
@ -153,7 +144,6 @@ public class HierarchyScreen {
});
mDragSortListView.setDragListener(new DragSortListView.DragListener() {
@Override
public void drag(int from, int to) {
@ -225,9 +215,18 @@ public class HierarchyScreen {
mAdapter.notifyDataSetChanged();
}
public interface HierarchyScreenListener {
void onHierarchyScreenItemEdit(ContainerPath path, Item item);
void onHierarchyScreenContainerSettings(ContainerPath path);
void onHierarchyScreenItemMoved(HierarchyItem which, HierarchyItem before, HierarchyItem after);
int[] onHierarchyScreenGetRootPages();
}
private static class ExpandedPathSet {
private HashSet<String> mExpandedPaths = new HashSet<>();
private final HashSet<String> mExpandedPaths = new HashSet<>();
public boolean add(ContainerPath path) {
return mExpandedPaths.add(path.toString());
@ -276,6 +275,7 @@ public class HierarchyScreen {
this.page = page;
this.path = new HierarchyPath(this);
}
public HierarchyItem(HierarchyItem parent, int level, int page, Item item) {
this.parent = parent;
this.level = level;
@ -283,6 +283,7 @@ public class HierarchyScreen {
this.item = item;
this.path = new HierarchyPath(this);
}
public boolean isContainer() {
return item == null || item instanceof Folder;
}
@ -305,16 +306,22 @@ public class HierarchyScreen {
}
private class HierarchyAdapter extends BaseAdapter implements View.OnClickListener, View.OnLongClickListener {
private Context mContext;
private ListView mHostListView;
private LightningEngine.PageManager mPageManager;
private final Context mContext;
private final ListView mHostListView;
private final LightningEngine.PageManager mPageManager;
private final ExpandedPathSet mExpandedPaths;
private final int mIndent;
private final Page.PageListener mPageListener = new Page.EmptyPageListener() {
@Override
public void onPageRemoved(Page page) {
// TODO handle removals
}
@Override
public void onPageLoaded(Page page) {
}
};
private ArrayList<HierarchyItem> mItems;
private ExpandedPathSet mExpandedPaths;
private int mIndent;
private int mHoveredItem = -1;
public HierarchyAdapter(Context context, ListView hostListView) {
@ -365,13 +372,13 @@ public class HierarchyScreen {
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.hierarchy_item, parent, false);
Button containerSettingsButton = (Button) convertView.findViewById(R.id.eb_cs);
Button containerSettingsButton = convertView.findViewById(R.id.eb_cs);
containerSettingsButton.setTypeface(LLApp.get().getIconsTypeface());
containerSettingsButton.setOnClickListener(this);
containerSettingsButton.setOnLongClickListener(this);
containerSettingsButton.setContentDescription(mContext.getString(R.string.mi_es_settings));
Button editButton = (Button) convertView.findViewById(R.id.eb_edit);
Button editButton = convertView.findViewById(R.id.eb_edit);
editButton.setTypeface(LLApp.get().getIconsTypeface());
editButton.setOnClickListener(this);
editButton.setOnLongClickListener(this);
@ -379,7 +386,7 @@ public class HierarchyScreen {
}
HierarchyItem hi = getItem(position);
TextView textView = (TextView) convertView.findViewById(R.id.label);
TextView textView = convertView.findViewById(R.id.label);
Page page = mLightningEngine.getOrLoadPage(hi.page);
CharSequence label;
if (hi.item == null) {
@ -395,11 +402,11 @@ public class HierarchyScreen {
textView.setText(label);
textView.setPadding(hi.level * mIndent, 0, 0, 0);
Button containerSettingsButton = (Button) convertView.findViewById(R.id.eb_cs);
Button containerSettingsButton = convertView.findViewById(R.id.eb_cs);
containerSettingsButton.setTag(hi);
containerSettingsButton.setVisibility(hi.isContainer() ? View.VISIBLE : View.INVISIBLE);
Button editButton = (Button) convertView.findViewById(R.id.eb_edit);
Button editButton = convertView.findViewById(R.id.eb_edit);
editButton.setTag(hi);
return convertView;
@ -423,6 +430,10 @@ public class HierarchyScreen {
notifyDataSetChanged();
}
public int getHoveredItem() {
return mHoveredItem;
}
public void setHoveredItem(int position) {
if (mHoveredItem != position) {
if (mHoveredItem != -1) {
@ -437,10 +448,6 @@ public class HierarchyScreen {
}
}
public int getHoveredItem() {
return mHoveredItem;
}
private void setItemHoveredState(int position, boolean hovered) {
View view = mHostListView.getChildAt(position - mHostListView.getFirstVisiblePosition());
if (view != null) {
@ -480,8 +487,12 @@ public class HierarchyScreen {
public void onClick(View v) {
HierarchyItem hi = (HierarchyItem) v.getTag();
switch (v.getId()) {
case R.id.eb_edit: mListener.onHierarchyScreenItemEdit(hi.path, hi.item); break;
case R.id.eb_cs: mListener.onHierarchyScreenContainerSettings(new HierarchyPath(hi)); break;
case R.id.eb_edit:
mListener.onHierarchyScreenItemEdit(hi.path, hi.item);
break;
case R.id.eb_cs:
mListener.onHierarchyScreenContainerSettings(new HierarchyPath(hi));
break;
}
}
@ -489,8 +500,12 @@ public class HierarchyScreen {
public boolean onLongClick(View v) {
int label_res = 0;
switch (v.getId()) {
case R.id.eb_edit: label_res = R.string.hs_ed; break;
case R.id.eb_cs: label_res = R.string.mi_es_settings; break;
case R.id.eb_edit:
label_res = R.string.hs_ed;
break;
case R.id.eb_cs:
label_res = R.string.mi_es_settings;
break;
}
if (label_res != 0) {
int[] location = new int[2];
@ -501,16 +516,5 @@ public class HierarchyScreen {
}
return true;
}
private Page.PageListener mPageListener = new Page.EmptyPageListener() {
@Override
public void onPageRemoved(Page page) {
// TODO handle removals
}
@Override
public void onPageLoaded(Page page) {
}
};
}
}

View file

@ -24,8 +24,6 @@ SOFTWARE.
package net.pierrox.lightning_launcher.views;
import java.util.ArrayList;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
@ -35,76 +33,28 @@ import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;
import java.util.ArrayList;
public class MyViewPager extends ViewGroup {
/**
* Callback interface for responding to changing state of the selected page.
*/
public interface OnPageChangeListener {
/**
* This method will be invoked when the current page is scrolled, either as part
* of a programmatically initiated smooth scroll or a user initiated touch scroll.
*
* @param position Position index of the first page currently being displayed.
* Page position+1 will be visible if positionOffset is nonzero.
* @param positionOffset Value from [0, 1) indicating the offset from the page at position.
* @param positionOffsetPixels Value in pixels indicating the offset from position.
*/
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
/**
* This method will be invoked when a new page becomes selected. Animation is not
* necessarily complete.
*
* @param position Position index of the new selected page.
*/
public void onPageSelected(int position);
/**
* Called when the scroll state changes. Useful for discovering when the user
* begins dragging, when the pager is automatically settling to the current page,
* or when it is fully stopped/idle.
*
* @param state The new scroll state.
* @see ViewPager#SCROLL_STATE_IDLE
* @see ViewPager#SCROLL_STATE_DRAGGING
* @see ViewPager#SCROLL_STATE_SETTLING
*/
public void onPageScrollStateChanged(int state);
}
/**
* Indicates that the pager is in an idle, settled state. The current page
* is fully in view and no animation is in progress.
*/
public static final int SCROLL_STATE_IDLE = 0;
/**
* Indicates that the pager is currently being dragged by the user.
*/
public static final int SCROLL_STATE_DRAGGING = 1;
/**
* Indicates that the pager is in the process of settling to a final position.
*/
public static final int SCROLL_STATE_SETTLING = 2;
protected static class ItemInfo {
View v;
int position;
boolean scrolling;
}
protected final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>(2);
private OnPageChangeListener mOnPageChangeListener;
private int mScrollState = SCROLL_STATE_IDLE;
private Scroller mScroller;
private int mCurItem;
private boolean mScrolling;
private int mChildWidthMeasureSpec;
private int mChildHeightMeasureSpec;
private boolean mIsBeingDragged;
@ -113,7 +63,6 @@ public class MyViewPager extends ViewGroup {
private float mInitialMotionX;
private float mLastMotionX;
private float mLastMotionY;
private VelocityTracker mVelocityTracker;
private int mMinimumVelocity;
private int mMaximumVelocity;
@ -124,7 +73,6 @@ public class MyViewPager extends ViewGroup {
initViewPager();
}
@Override
protected void onFinishInflate() {
initPagerItems();
@ -157,7 +105,6 @@ public class MyViewPager extends ViewGroup {
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// For simple implementation, or internal size is always 0.
@ -252,7 +199,6 @@ public class MyViewPager extends ViewGroup {
*/
final float x = ev.getX();
final float dx = x - mLastMotionX;
final float xDiff = Math.abs(dx);
@ -437,10 +383,18 @@ public class MyViewPager extends ViewGroup {
mOnPageChangeListener = listener;
}
public int getCurrentItem() {
return mCurItem;
}
public void setCurrentItem(int item) {
setCurrentItemInternal(item, true, false);
}
public View getCurrentView() {
return mItems.get(mCurItem).v;
}
public void setCurrentView(View v) {
for (ItemInfo ii : mItems) {
if (ii.v == v) {
@ -450,14 +404,6 @@ public class MyViewPager extends ViewGroup {
}
}
public int getCurrentItem() {
return mCurItem;
}
public View getCurrentView() {
return mItems.get(mCurItem).v;
}
public boolean isFirst() {
return mCurItem == 0;
}
@ -586,4 +532,47 @@ public class MyViewPager extends ViewGroup {
mOnPageChangeListener.onPageScrollStateChanged(newState);
}
}
/**
* Callback interface for responding to changing state of the selected page.
*/
public interface OnPageChangeListener {
/**
* This method will be invoked when the current page is scrolled, either as part
* of a programmatically initiated smooth scroll or a user initiated touch scroll.
*
* @param position Position index of the first page currently being displayed.
* Page position+1 will be visible if positionOffset is nonzero.
* @param positionOffset Value from [0, 1) indicating the offset from the page at position.
* @param positionOffsetPixels Value in pixels indicating the offset from position.
*/
void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
/**
* This method will be invoked when a new page becomes selected. Animation is not
* necessarily complete.
*
* @param position Position index of the new selected page.
*/
void onPageSelected(int position);
/**
* Called when the scroll state changes. Useful for discovering when the user
* begins dragging, when the pager is automatically settling to the current page,
* or when it is fully stopped/idle.
*
* @param state The new scroll state.
* @see ViewPager#SCROLL_STATE_IDLE
* @see ViewPager#SCROLL_STATE_DRAGGING
* @see ViewPager#SCROLL_STATE_SETTLING
*/
void onPageScrollStateChanged(int state);
}
protected static class ItemInfo {
View v;
int position;
boolean scrolling;
}
}

View file

@ -46,16 +46,16 @@ public class SnappingContext {
public static final int SNAP_CENTER = 16;
public static final int SNAP_ALL = 31;
private int snap_what;
private float touch_slop;
private final int snap_what;
private final float touch_slop;
private final ItemView my_item_view;
public float min_dx = Float.MAX_VALUE;
public float min_dy = Float.MAX_VALUE;
public float anchor_x = Float.MAX_VALUE;
public float anchor_y = Float.MAX_VALUE;
public ItemLayout item_layout;
private ArrayList<ItemView> snapped_items;
private ArrayList<RectF> snapped_bounds;
private ItemView my_item_view;
public ItemLayout item_layout;
public SnappingContext(ItemView my_item_view, float touch_slop, int snap_what) {
this.my_item_view = my_item_view;

View file

@ -40,7 +40,6 @@ import net.pierrox.lightning_launcher.R;
/**
* Class to manage status and navigation bar tint effects when using KitKat
* translucent system UI modes.
*
*/
public class SystemBarTintManager {
@ -66,18 +65,17 @@ public class SystemBarTintManager {
* The default system bar tint color value.
*/
public static final int DEFAULT_TINT_COLOR = 0x99000000;
private static boolean sGlobalStatusBarTintEnabled = false;
private final boolean mStatusBarAvailable = true;
private final boolean mNavBarAvailable = true;
private final Animation mStatusBarAnimEnter;
private final Animation mStatusBarAnimExit;
private SystemBarConfig mConfig;
private boolean mStatusBarAvailable = true;
private boolean mNavBarAvailable = true;
private boolean mStatusBarTintEnabled;
private boolean mNavBarTintEnabled;
private View mStatusBarTintView;
private View mNavBarTintView;
private Animation mStatusBarAnimEnter;
private Animation mStatusBarAnimExit;
/**
* Constructor. Call this in the host activity onCreate method after its
* content view has been set. You should always create new instances when
@ -105,33 +103,9 @@ public class SystemBarTintManager {
setupNavBarLayoutParams();
}
private static boolean sGlobalStatusBarTintEnabled = false;
/**
* Enable tinting of the system status bar.
*
* If the platform is running Jelly Bean or earlier, or translucent system
* UI modes have not been enabled in either the theme or via window flags,
* then this method does nothing.
*
* @param enabled True to enable tinting, false to disable it (default).
*/
public void setStatusBarTintEnabled(boolean enabled) {
mStatusBarTintEnabled = enabled;
if (mStatusBarAvailable) {
int visibility = enabled ? View.VISIBLE : View.GONE;
if(mStatusBarTintView.getVisibility() != visibility) {
mStatusBarTintView.setVisibility(visibility);
if(mStatusBarTintEnabled != sGlobalStatusBarTintEnabled) {
mStatusBarTintView.startAnimation(enabled ? mStatusBarAnimEnter : mStatusBarAnimExit);
sGlobalStatusBarTintEnabled = mStatusBarTintEnabled;
}
}
}
}
/**
* Enable tinting of the system navigation bar.
*
* <p>
* If the platform does not have soft navigation keys, is running Jelly Bean
* or earlier, or translucent system UI modes have not been enabled in either
* the theme or via window flags, then this method does nothing.
@ -295,6 +269,29 @@ public class SystemBarTintManager {
return mStatusBarTintEnabled;
}
/**
* Enable tinting of the system status bar.
* <p>
* If the platform is running Jelly Bean or earlier, or translucent system
* UI modes have not been enabled in either the theme or via window flags,
* then this method does nothing.
*
* @param enabled True to enable tinting, false to disable it (default).
*/
public void setStatusBarTintEnabled(boolean enabled) {
mStatusBarTintEnabled = enabled;
if (mStatusBarAvailable) {
int visibility = enabled ? View.VISIBLE : View.GONE;
if (mStatusBarTintView.getVisibility() != visibility) {
mStatusBarTintView.setVisibility(visibility);
if (mStatusBarTintEnabled != sGlobalStatusBarTintEnabled) {
mStatusBarTintView.startAnimation(enabled ? mStatusBarAnimEnter : mStatusBarAnimExit);
sGlobalStatusBarTintEnabled = mStatusBarTintEnabled;
}
}
}
}
/**
* Is tinting enabled for the system navigation bar?
*
@ -342,7 +339,6 @@ public class SystemBarTintManager {
/**
* Class which describes system bar sizing and other characteristics for the current
* device configuration.
*
*/
public static class SystemBarConfig {
@ -351,7 +347,12 @@ public class SystemBarTintManager {
// private static final String NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME = "navigation_bar_height_landscape";
// private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width";
// private static final String SHOW_NAV_BAR_RES_NAME = "config_showNavigationBar";
// These values are kept in order to be reused when the window insets are not available. This
// is the case when the view is not attached to the window. Also, display cutouts are never
// available in the context of the overlay desktop. Display cutouts are not supposed to change
// so it should be safe enough.
private static int sSafeInsetWidth = 0;
private static int sSafeInsetHeight = 0;
private final boolean mIsInPortrait;
private final int mStatusBarHeight;
private final int mActionBarHeight;
@ -360,13 +361,6 @@ public class SystemBarTintManager {
// private final int mNavigationBarWidth;
private final boolean mIsNavigationAtBottom;
// These values are kept in order to be reused when the window insets are not available. This
// is the case when the view is not attached to the window. Also, display cutouts are never
// available in the context of the overlay desktop. Display cutouts are not supposed to change
// so it should be safe enough.
private static int sSafeInsetWidth = 0;
private static int sSafeInsetHeight = 0;
private SystemBarConfig(Window window) {
Resources res = window.getContext().getResources();

View file

@ -13,11 +13,6 @@
package net.dinglisch.android.tasker;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@ -30,26 +25,26 @@ import android.os.PatternMatcher;
import android.os.Process;
import android.util.Log;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class TaskerIntent extends Intent {
// 3 Tasker versions
public final static String TASKER_PACKAGE = "net.dinglisch.android.tasker";
public final static String TASKER_PACKAGE_MARKET = TASKER_PACKAGE + "m";
public final static String TASKER_PACKAGE_CUPCAKE = TASKER_PACKAGE + "cupcake";
// Play Store download URLs
public final static String MARKET_DOWNLOAD_URL_PREFIX = "market://details?id=";
private final static String TASKER_MARKET_URL = MARKET_DOWNLOAD_URL_PREFIX + TASKER_PACKAGE_MARKET;
public final static String TASKER_PACKAGE_CUPCAKE = TASKER_PACKAGE + "cupcake";
private final static String TASKER_MARKET_URL_CUPCAKE = MARKET_DOWNLOAD_URL_PREFIX + TASKER_PACKAGE_CUPCAKE;
// Direct-purchase version
private final static String TASKER_DOWNLOAD_URL = "http://tasker.dinglisch.net/download.html";
// Intent actions
public final static String ACTION_TASK = TASKER_PACKAGE + ".ACTION_TASK";
public final static String ACTION_TASK_COMPLETE = TASKER_PACKAGE + ".ACTION_TASK_COMPLETE";
public final static String ACTION_TASK_SELECT = TASKER_PACKAGE + ".ACTION_TASK_SELECT";
// Intent parameters
public final static String EXTRA_ACTION_INDEX_PREFIX = "action";
public final static String TASK_NAME_DATA_SCHEME = "task";
@ -59,24 +54,19 @@ public class TaskerIntent extends Intent {
public final static String EXTRA_VAR_NAMES_LIST = "varNames";
public final static String EXTRA_VAR_VALUES_LIST = "varValues";
public final static String EXTRA_TASK_OUTPUT = "output";
// Content provider columns
public static final String PROVIDER_COL_NAME_EXTERNAL_ACCESS = "ext_access";
public static final String PROVIDER_COL_NAME_ENABLED = "enabled";
// DEPRECATED, use EXTRA_VAR_NAMES_LIST, EXTRA_VAR_VALUES_LIST
public final static String EXTRA_PARAM_LIST = "params";
// Intent data
public final static String TASK_ID_SCHEME = "id";
// For particular actions
// Intent data
public final static String DEFAULT_ENCRYPTION_KEY = "default";
// For particular actions
public final static String ENCRYPTED_AFFIX = "tec";
public final static int MAX_NO_ARGS = 10;
// Bundle keys
// Only useful for Tasker
public final static String ACTION_CODE = "action";
@ -84,12 +74,12 @@ public class TaskerIntent extends Intent {
public final static String ICON_ARG_PREFIX = "icn:";
public final static String ARG_INDEX_PREFIX = "arg:";
public static final String PARAM_VAR_NAME_PREFIX = "par";
public final static String EXTRA_OPEN_PREFS_TAB_NO = "tno";
// Direct-purchase version
private final static String TASKER_DOWNLOAD_URL = "http://tasker.dinglisch.net/download.html";
// Misc
private final static String PERMISSION_RUN_TASKS = TASKER_PACKAGE + ".PERMISSION_RUN_TASKS";
private final static String ACTION_OPEN_PREFS = TASKER_PACKAGE + ".ACTION_OPEN_PREFS";
public final static String EXTRA_OPEN_PREFS_TAB_NO = "tno";
private final static int MISC_PREFS_TAB_NO = 3; // 0 based
// To query whether Tasker is enabled and external access is enabled
@ -106,33 +96,41 @@ public class TaskerIntent extends Intent {
// NoReceiver: Tasker has not created a listener for external access (probably a Tasker bug)
// OK: you should be able to send a task to run. Still need to listen for result
// for e.g. task not found
public static enum Status { NotInstalled, NoPermission, NotEnabled, AccessBlocked, NoReceiver, OK };
// -------------------------- PRIVATE VARS ---------------------------- //
private final static String TAG = "TaskerIntent";
// -------------------------- PRIVATE VARS ---------------------------- //
private final static String EXTRA_INTENT_VERSION_NUMBER = "version_number";
private final static String INTENT_VERSION_NUMBER = "1.1";
// Inclusive values
private final static int MIN_PRIORITY = 0;
private final static int MAX_PRIORITY = 10;
// For generating random names
private static Random rand = new Random();
private static final Random rand = new Random();
// Tracking state
private int actionCount = 0;
private int argCount;
public TaskerIntent() {
super(ACTION_TASK);
setRandomData();
putMetaExtras(getRandomString());
}
// -------------------------- PUBLIC METHODS ---------------------------- //
public TaskerIntent(String taskName) {
super(ACTION_TASK);
setRandomData();
putMetaExtras(taskName);
}
public static int getMaxPriority() {
return MAX_PRIORITY;
}
// Tasker has different package names for Play Store and non- versions
// for historical reasons
public static boolean validatePriority(int pri) {
return (
(pri >= MIN_PRIORITY) ||
@ -140,8 +138,9 @@ public class TaskerIntent extends Intent {
);
}
// Tasker has different package names for Play Store and non- versions
// for historical reasons
// test we can send a TaskerIntent to Tasker
// use *before* sending an intent
// still need to test the *result after* sending intent
public static String getInstalledTaskerPackage(Context context) {
@ -150,23 +149,19 @@ public class TaskerIntent extends Intent {
try {
context.getPackageManager().getPackageInfo(TASKER_PACKAGE, 0);
foundPackage = TASKER_PACKAGE;
}
catch ( PackageManager.NameNotFoundException e ) {
} catch (PackageManager.NameNotFoundException e) {
}
try {
context.getPackageManager().getPackageInfo(TASKER_PACKAGE_MARKET, 0);
foundPackage = TASKER_PACKAGE_MARKET;
}
catch ( PackageManager.NameNotFoundException e ) {
} catch (PackageManager.NameNotFoundException e) {
}
return foundPackage;
}
// test we can send a TaskerIntent to Tasker
// use *before* sending an intent
// still need to test the *result after* sending intent
// Check if Tasker installed
public static Status testStatus(Context c) {
@ -188,8 +183,6 @@ public class TaskerIntent extends Intent {
return result;
}
// Check if Tasker installed
public static boolean taskerInstalled(Context context) {
return (getInstalledTaskerPackage(context) != null);
}
@ -211,8 +204,7 @@ public class TaskerIntent extends Intent {
try {
Field f = android.os.Build.VERSION.class.getField("SDK_INT");
return f.getInt(null);
}
catch ( Exception e ) {
} catch (Exception e) {
return CUPCAKE_SDK_VERSION;
}
}
@ -227,6 +219,8 @@ public class TaskerIntent extends Intent {
return filter;
}
// public access deprecated, use TaskerIntent.testSend() instead
public static Intent getTaskSelectIntent() {
return new Intent(ACTION_TASK_SELECT).
setFlags(
@ -236,32 +230,40 @@ public class TaskerIntent extends Intent {
);
}
// public access deprecated, use TaskerIntent.testSend() instead
// Get an intent that will bring up the Tasker prefs screen with the External Access control(s)
// Probably you want to use startActivity or startActivityForResult with it
public static boolean havePermission(Context c) {
return c.checkPermission(PERMISSION_RUN_TASKS, Process.myPid(), Process.myUid()) ==
PackageManager.PERMISSION_GRANTED;
}
// Get an intent that will bring up the Tasker prefs screen with the External Access control(s)
// Probably you want to use startActivity or startActivityForResult with it
// ------------------------------------- INSTANCE METHODS ----------------------------- //
public static Intent getExternalAccessPrefsIntent() {
return new Intent(ACTION_OPEN_PREFS).putExtra(EXTRA_OPEN_PREFS_TAB_NO, MISC_PREFS_TAB_NO);
}
// ------------------------------------- INSTANCE METHODS ----------------------------- //
private static boolean prefSet(Context context, String col) {
public TaskerIntent() {
super( ACTION_TASK );
setRandomData();
putMetaExtras( getRandomString() );
String[] proj = new String[]{col};
Cursor c = context.getContentResolver().query(Uri.parse(TASKER_PREFS_URI), proj, null, null, null);
boolean acceptingFlag = false;
if (c == null)
Log.w(TAG, "no cursor for " + TASKER_PREFS_URI);
else {
c.moveToFirst();
if (Boolean.TRUE.toString().equals(c.getString(0)))
acceptingFlag = true;
c.close();
}
public TaskerIntent( String taskName ) {
super( ACTION_TASK );
setRandomData();
putMetaExtras( taskName );
return acceptingFlag;
}
public TaskerIntent setTaskPriority(int priority) {
@ -297,8 +299,7 @@ public class TaskerIntent extends Intent {
if (hasExtra(EXTRA_VAR_NAMES_LIST)) {
names = getStringArrayListExtra(EXTRA_VAR_NAMES_LIST);
values = getStringArrayListExtra(EXTRA_VAR_VALUES_LIST);
}
else {
} else {
names = new ArrayList<String>();
values = new ArrayList<String>();
@ -322,7 +323,7 @@ public class TaskerIntent extends Intent {
actionBundle.putInt(ACTION_CODE, code);
// Add action bundle to intent
putExtra( EXTRA_ACTION_INDEX_PREFIX + Integer.toString( actionCount ), actionBundle );
putExtra(EXTRA_ACTION_INDEX_PREFIX + actionCount, actionBundle);
return this;
}
@ -333,7 +334,7 @@ public class TaskerIntent extends Intent {
Bundle b = getActionBundle();
if (b != null)
b.putString( ARG_INDEX_PREFIX + Integer.toString( argCount++ ), arg );
b.putString(ARG_INDEX_PREFIX + argCount++, arg);
return this;
}
@ -343,7 +344,7 @@ public class TaskerIntent extends Intent {
Bundle b = getActionBundle();
if (b != null)
b.putInt( ARG_INDEX_PREFIX + Integer.toString( argCount++ ), arg );
b.putInt(ARG_INDEX_PREFIX + argCount++, arg);
return this;
}
@ -353,7 +354,7 @@ public class TaskerIntent extends Intent {
Bundle b = getActionBundle();
if (b != null)
b.putBoolean( ARG_INDEX_PREFIX + Integer.toString( argCount++ ), arg );
b.putBoolean(ARG_INDEX_PREFIX + argCount++, arg);
return this;
}
@ -366,7 +367,7 @@ public class TaskerIntent extends Intent {
StringBuilder builder = new StringBuilder();
builder.append(APP_ARG_PREFIX).
append(pkg).append(",").append(cls);
b.putString( ARG_INDEX_PREFIX + Integer.toString( argCount++ ), b.toString() );
b.putString(ARG_INDEX_PREFIX + argCount++, b.toString());
}
return this;
@ -407,7 +408,7 @@ public class TaskerIntent extends Intent {
if (argCount > MAX_NO_ARGS)
Log.e(TAG, "maximum number of arguments exceeded (" + MAX_NO_ARGS + ")");
else {
String key = EXTRA_ACTION_INDEX_PREFIX + Integer.toString( actionCount );
String key = EXTRA_ACTION_INDEX_PREFIX + actionCount;
if (this.hasExtra(key))
toReturn = getBundleExtra(key);
@ -425,25 +426,5 @@ public class TaskerIntent extends Intent {
// for testing that Tasker is enabled and external access is allowed
private static boolean prefSet( Context context, String col ) {
String [] proj = new String [] { col };
Cursor c = context.getContentResolver().query( Uri.parse( TASKER_PREFS_URI ), proj, null, null, null );
boolean acceptingFlag = false;
if ( c == null )
Log.w( TAG, "no cursor for " + TASKER_PREFS_URI );
else {
c.moveToFirst();
if ( Boolean.TRUE.toString().equals( c.getString( 0 ) ) )
acceptingFlag = true;
c.close();
}
return acceptingFlag;
}
public enum Status {NotInstalled, NoPermission, NotEnabled, AccessBlocked, NoReceiver, OK}
}

View file

@ -22,10 +22,6 @@ package net.pierrox.lightning_launcher.data;
// support for data pass through in REQUEST_QUERY intent
// some javadoc entries fixed (thanks again David :-))
import java.net.URISyntaxException;
import java.security.SecureRandom;
import java.util.regex.Pattern;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@ -35,94 +31,77 @@ import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import java.net.URISyntaxException;
import java.security.SecureRandom;
import java.util.regex.Pattern;
public class TaskerPlugin {
private final static String TAG = "TaskerPlugin";
private final static String BASE_KEY = "net.dinglisch.android.tasker";
private final static String EXTRAS_PREFIX = BASE_KEY + ".extras.";
private final static int FIRST_ON_FIRE_VARIABLES_TASKER_VERSION = 80;
public static final String VARIABLE_PREFIX = "%";
// when generating non-repeating integers, look this far back for repeats
// see getPositiveNonRepeatingRandomInteger()
private final static int RANDOM_HISTORY_SIZE = 100;
/**
* @see Setting#hostSupportsVariableReturn(Bundle)
*/
public final static int EXTRA_HOST_CAPABILITY_SETTING_RETURN_VARIABLES = 2;
/**
* @see Condition#hostSupportsVariableReturn(Bundle)
*/
public final static int EXTRA_HOST_CAPABILITY_CONDITION_RETURN_VARIABLES = 4;
/**
* @see Setting#hostSupportsOnFireVariableReplacement(Bundle)
*/
public final static int EXTRA_HOST_CAPABILITY_SETTING_FIRE_VARIABLE_REPLACEMENT = 8;
public final static int EXTRA_HOST_CAPABILITY_SETTING_SYNCHRONOUS_EXECUTION = 32;
public final static int EXTRA_HOST_CAPABILITY_REQUEST_QUERY_DATA_PASS_THROUGH = 64;
private final static String TAG = "TaskerPlugin";
private final static String BASE_KEY = "net.dinglisch.android.tasker";
/**
* Action that the EditActivity for an event plugin should be launched by
*/
public final static String ACTION_EDIT_EVENT = BASE_KEY + ".ACTION_EDIT_EVENT";
private final static String VARIABLE_NAME_START_EXPRESSION = "[\\w&&[^_]]";
private final static String VARIABLE_NAME_MID_EXPRESSION = "[\\w0-9]+";
private final static String VARIABLE_NAME_END_EXPRESSION = "[\\w0-9&&[^_]]";
public final static String VARIABLE_NAME_MAIN_PART_MATCH_EXPRESSION =
VARIABLE_NAME_START_EXPRESSION + VARIABLE_NAME_MID_EXPRESSION + VARIABLE_NAME_END_EXPRESSION
;
public final static String VARIABLE_NAME_MATCH_EXPRESSION =
VARIABLE_PREFIX + "+" +
VARIABLE_NAME_MAIN_PART_MATCH_EXPRESSION
;
private static Pattern VARIABLE_NAME_MATCH_PATTERN = null;
private final static String EXTRAS_PREFIX = BASE_KEY + ".extras.";
/**
* @see #addVariableBundle(Bundle, Bundle)
* @see Host#getVariablesBundle(Bundle)
*/
private final static String EXTRA_VARIABLES_BUNDLE = EXTRAS_PREFIX + "VARIABLES";
/**
* Host capabilities, passed to plugin with edit intents
*/
private final static String EXTRA_HOST_CAPABILITIES = EXTRAS_PREFIX + "HOST_CAPABILITIES";
/**
* @see Setting#hostSupportsVariableReturn(Bundle)
*/
public final static int EXTRA_HOST_CAPABILITY_SETTING_RETURN_VARIABLES = 2;
/**
* @see Condition#hostSupportsVariableReturn(Bundle)
*/
public final static int EXTRA_HOST_CAPABILITY_CONDITION_RETURN_VARIABLES = 4;
/**
* @see Setting#hostSupportsOnFireVariableReplacement(Bundle)
*/
public final static int EXTRA_HOST_CAPABILITY_SETTING_FIRE_VARIABLE_REPLACEMENT = 8;
private final static int FIRST_ON_FIRE_VARIABLES_TASKER_VERSION = 80;
// when generating non-repeating integers, look this far back for repeats
// see getPositiveNonRepeatingRandomInteger()
private final static int RANDOM_HISTORY_SIZE = 100;
private final static String VARIABLE_NAME_START_EXPRESSION = "[\\w&&[^_]]";
private final static String VARIABLE_NAME_MID_EXPRESSION = "[\\w0-9]+";
private final static String VARIABLE_NAME_END_EXPRESSION = "[\\w0-9&&[^_]]";
public final static String VARIABLE_NAME_MAIN_PART_MATCH_EXPRESSION =
VARIABLE_NAME_START_EXPRESSION + VARIABLE_NAME_MID_EXPRESSION + VARIABLE_NAME_END_EXPRESSION;
public final static String VARIABLE_NAME_MATCH_EXPRESSION =
VARIABLE_PREFIX + "+" +
VARIABLE_NAME_MAIN_PART_MATCH_EXPRESSION;
/**
* @see Setting#hostSupportsVariableReturn(Bundle)
*/
private final static int EXTRA_HOST_CAPABILITY_RELEVANT_VARIABLES = 16;
public final static int EXTRA_HOST_CAPABILITY_SETTING_SYNCHRONOUS_EXECUTION = 32;
public final static int EXTRA_HOST_CAPABILITY_REQUEST_QUERY_DATA_PASS_THROUGH = 64;
public final static int EXTRA_HOST_CAPABILITY_ALL =
EXTRA_HOST_CAPABILITY_SETTING_RETURN_VARIABLES |
EXTRA_HOST_CAPABILITY_CONDITION_RETURN_VARIABLES |
EXTRA_HOST_CAPABILITY_SETTING_FIRE_VARIABLE_REPLACEMENT |
EXTRA_HOST_CAPABILITY_RELEVANT_VARIABLES |
EXTRA_HOST_CAPABILITY_SETTING_SYNCHRONOUS_EXECUTION |
EXTRA_HOST_CAPABILITY_REQUEST_QUERY_DATA_PASS_THROUGH
;
EXTRA_HOST_CAPABILITY_REQUEST_QUERY_DATA_PASS_THROUGH;
/**
*
* @see #hostSupportsRelevantVariables(Bundle)
* @see #addRelevantVariableList(Intent, String[])
* @see #getRelevantVariableList(Bundle)
*/
private final static String BUNDLE_KEY_RELEVANT_VARIABLES = BASE_KEY + ".RELEVANT_VARIABLES";
private static Pattern VARIABLE_NAME_MATCH_PATTERN = null;
// state tracking for random number sequence
private static int[] lastRandomsSeen = null;
private static int randomInsertPointer = 0;
private static SecureRandom sr = null;
public static boolean hostSupportsRelevantVariables(Bundle extrasFromHost) {
return hostSupports(extrasFromHost, EXTRA_HOST_CAPABILITY_RELEVANT_VARIABLES);
@ -130,7 +109,7 @@ public class TaskerPlugin {
/**
* Specifies to host which variables might be used by the plugin.
*
* <p>
* Used in EditActivity, before setResult().
*
* @param intentToHost the intent being returned to the host
@ -140,9 +119,11 @@ public class TaskerPlugin {
intentToHost.putExtra(BUNDLE_KEY_RELEVANT_VARIABLES, variableNames);
}
// ----------------------------- SETTING PLUGIN ONLY --------------------------------- //
/**
* Validate a variable name.
*
* <p>
* The basic requirement for variables from a plugin is that they must be all lower-case.
*
* @param varName name to check
@ -163,14 +144,15 @@ public class TaskerPlugin {
validFlag = true;
else
Log.d(TAG, "variableNameValid: name not local: " + varName);
}
else
} else
Log.d(TAG, "variableNameValid: invalid name: " + varName);
}
return validFlag;
}
// ----------------------------- CONDITION/EVENT PLUGIN ONLY --------------------------------- //
/**
* Allows the plugin/host to indicate to each other a set of variables which they are referencing.
* The host may use this to e.g. show a variable selection list in it's UI.
@ -189,11 +171,13 @@ public class TaskerPlugin {
return relevantVars;
}
// ----------------------------- EVENT PLUGIN ONLY --------------------------------- //
/**
* Used by: plugin QueryReceiver, FireReceiver
*
* <p>
* Add a bundle of variable name/value pairs.
*
* <p>
* Names must be valid Tasker local variable names.
* Values must be String, String [] or ArrayList<String>
* Null values cause deletion of possible already-existing variables.
@ -206,51 +190,136 @@ public class TaskerPlugin {
public static void addVariableBundle(Bundle resultExtras, Bundle variables) {
resultExtras.putBundle(EXTRA_VARIABLES_BUNDLE, variables);
}
// ---------------------------------- HOST ----------------------------------------- //
// ----------------------------- SETTING PLUGIN ONLY --------------------------------- //
private static Object getBundleValueSafe(Bundle b, String key, Class<?> expectedClass, String funcName) {
Object value = null;
if (b != null) {
if (b.containsKey(key)) {
Object obj = b.get(key);
if (obj == null)
Log.w(TAG, funcName + ": " + key + ": null value");
else if (obj.getClass() != expectedClass)
Log.w(TAG, funcName + ": " + key + ": expected " + expectedClass.getClass().getName() + ", got " + obj.getClass().getName());
else
value = obj;
}
}
return value;
}
// ---------------------------------- HELPER FUNCTIONS -------------------------------- //
private static Object getExtraValueSafe(Intent i, String key, Class<?> expectedClass, String funcName) {
return (i.hasExtra(key)) ?
getBundleValueSafe(i.getExtras(), key, expectedClass, funcName) :
null;
}
private static boolean hostSupports(Bundle extrasFromHost, int capabilityFlag) {
Integer flags = (Integer) getBundleValueSafe(extrasFromHost, EXTRA_HOST_CAPABILITIES, Integer.class, "hostSupports");
return
(flags != null) &&
((flags & capabilityFlag) > 0)
;
}
public static int getPackageVersionCode(PackageManager pm, String packageName) {
int code = -1;
if (pm != null) {
try {
PackageInfo pi = pm.getPackageInfo(packageName, 0);
if (pi != null)
code = pi.versionCode;
} catch (Exception e) {
Log.e(TAG, "getPackageVersionCode: exception getting package info");
}
}
return code;
}
private static boolean variableNameIsLocal(String varName) {
int digitCount = 0;
int length = varName.length();
for (int x = 0; x < length; x++) {
char ch = varName.charAt(x);
if (Character.isUpperCase(ch))
return false;
else if (Character.isDigit(ch))
digitCount++;
}
return digitCount != (varName.length() - 1);
}
/**
* Generate a sequence of secure random positive integers which is guaranteed not to repeat
* in the last 100 calls to this function.
*
* @return a random positive integer
*/
public static int getPositiveNonRepeatingRandomInteger() {
// initialize on first call
if (sr == null) {
sr = new SecureRandom();
lastRandomsSeen = new int[RANDOM_HISTORY_SIZE];
for (int x = 0; x < lastRandomsSeen.length; x++)
lastRandomsSeen[x] = -1;
}
int toReturn;
do {
// pick a number
toReturn = sr.nextInt(Integer.MAX_VALUE);
// check we havn't see it recently
for (int seen : lastRandomsSeen) {
if (seen == toReturn) {
toReturn = -1;
break;
}
}
}
while (toReturn == -1);
// update history
lastRandomsSeen[randomInsertPointer] = toReturn;
randomInsertPointer = (randomInsertPointer + 1) % lastRandomsSeen.length;
return toReturn;
}
public static class Setting {
/**
* @see #setVariableReplaceKeys(Bundle, String[])
*/
private final static String BUNDLE_KEY_VARIABLE_REPLACE_STRINGS = EXTRAS_PREFIX + "VARIABLE_REPLACE_KEYS";
/**
* @see #requestTimeoutMS(android.content.Intent, int)
*/
private final static String EXTRA_REQUESTED_TIMEOUT = EXTRAS_PREFIX + "REQUESTED_TIMEOUT";
/**
* @see #requestTimeoutMS(android.content.Intent, int)
*/
public final static int REQUESTED_TIMEOUT_MS_NONE = 0;
/**
* @see #requestTimeoutMS(android.content.Intent, int)
*/
public final static int REQUESTED_TIMEOUT_MS_MAX = 3599000;
/**
* @see #requestTimeoutMS(android.content.Intent, int)
*/
public final static int REQUESTED_TIMEOUT_MS_NEVER = REQUESTED_TIMEOUT_MS_MAX + 1000;
/**
* @see #signalFinish(Context, Intent, int, Bundle)
* @see Host#addCompletionIntent(Intent, Intent)
*/
private final static String EXTRA_PLUGIN_COMPLETION_INTENT = EXTRAS_PREFIX + "COMPLETION_INTENT";
/**
* @see #signalFinish(Context, Intent, int, Bundle)
* @see Host#getSettingResultCode(Intent)
*/
public final static String EXTRA_RESULT_CODE = EXTRAS_PREFIX + "RESULT_CODE";
/**
* @see #signalFinish(Context, Intent, int, Bundle)
* @see Host#getSettingResultCode(Intent)
@ -261,12 +330,25 @@ public class TaskerPlugin {
public final static int RESULT_CODE_FAILED = Activity.RESULT_FIRST_USER + 1;
public final static int RESULT_CODE_PENDING = Activity.RESULT_FIRST_USER + 2;
public final static int RESULT_CODE_UNKNOWN = Activity.RESULT_FIRST_USER + 3;
/**
* @see #setVariableReplaceKeys(Bundle, String[])
*/
private final static String BUNDLE_KEY_VARIABLE_REPLACE_STRINGS = EXTRAS_PREFIX + "VARIABLE_REPLACE_KEYS";
/**
* @see #requestTimeoutMS(android.content.Intent, int)
*/
private final static String EXTRA_REQUESTED_TIMEOUT = EXTRAS_PREFIX + "REQUESTED_TIMEOUT";
/**
* @see #signalFinish(Context, Intent, int, Bundle)
* @see Host#addCompletionIntent(Intent, Intent)
*/
private final static String EXTRA_PLUGIN_COMPLETION_INTENT = EXTRAS_PREFIX + "COMPLETION_INTENT";
/**
* Used by: plugin EditActivity.
*
* <p>
* Indicates to plugin that host will replace variables in specified bundle keys.
*
* <p>
* Replacement takes place every time the setting is fired, before the bundle is
* passed to the plugin FireReceiver.
*
@ -279,9 +361,9 @@ public class TaskerPlugin {
/**
* Used by: plugin EditActivity.
*
* <p>
* Description as above.
*
* <p>
* This version also includes backwards compatibility with pre 4.2 Tasker versions.
* At some point this function will be deprecated.
*
@ -313,12 +395,12 @@ public class TaskerPlugin {
/**
* Request the host to wait the specified number of milliseconds before continuing.
* Note that the host may choose to ignore the request.
*
* <p>
* Maximum value is REQUESTED_TIMEOUT_MS_MAX.
* Also available are REQUESTED_TIMEOUT_MS_NONE (continue immediately without waiting
* for the plugin to finish) and REQUESTED_TIMEOUT_MS_NEVER (wait forever for
* a result).
*
* <p>
* Used in EditActivity, before setResult().
*
* @param intentToHost the intent being returned to the host
@ -341,7 +423,7 @@ public class TaskerPlugin {
/**
* Used by: plugin EditActivity
*
* <p>
* Indicates to host which bundle keys should be replaced.
*
* @param resultBundleToHost the bundle being returned to the host
@ -373,7 +455,7 @@ public class TaskerPlugin {
/**
* Used by: plugin FireReceiver
*
* <p>
* Indicates to plugin whether the host will process variables which it passes back
*
* @param extrasFromHost intent extras from the intent received by the FireReceiver
@ -385,9 +467,9 @@ public class TaskerPlugin {
/**
* Used by: plugin FireReceiver
*
* <p>
* Tell the host that the plugin has finished execution.
*
* <p>
* This should only be used if RESULT_CODE_PENDING was returned by FireReceiver.onReceive().
*
* @param originalFireIntent the intent received from the host (via onReceive())
@ -425,8 +507,7 @@ public class TaskerPlugin {
context.sendBroadcast(completionIntent);
okFlag = true;
}
catch ( URISyntaxException e ) {
} catch (URISyntaxException e) {
Log.w(TAG, errorPrefix + "bad URI: " + completionIntentUri);
}
}
@ -436,13 +517,11 @@ public class TaskerPlugin {
}
}
// ----------------------------- CONDITION/EVENT PLUGIN ONLY --------------------------------- //
public static class Condition {
/**
* Used by: plugin QueryReceiver
*
* <p>
* Indicates to plugin whether the host will process variables which it passes back
*
* @param extrasFromHost intent extras from the intent received by the QueryReceiver
@ -453,8 +532,6 @@ public class TaskerPlugin {
}
}
// ----------------------------- EVENT PLUGIN ONLY --------------------------------- //
public static class Event {
public final static String PASS_THROUGH_BUNDLE_MESSAGE_ID_KEY = BASE_KEY + ".MESSAGE_ID";
@ -473,20 +550,20 @@ public class TaskerPlugin {
* Specify a bundle of data (probably representing whatever change happened in the condition)
* which will be included in the QUERY_CONDITION broadcast sent by the host for each
* event instance of the plugin.
*
* <p>
* The minimal purpose is to enable the plugin to associate a QUERY_CONDITION to the
* with the REQUEST_QUERY that caused it.
*
* <p>
* Note that for security reasons it is advisable to also store a message ID with the bundle
* which can be compared to known IDs on receipt. The host cannot validate the source of
* REQUEST_QUERY intents so fake data may be passed. Replay attacks are also possible.
* addPassThroughMesssageID() can be used to add an ID if the plugin doesn't wish to add it's
* own ID to the pass through bundle.
*
* <p>
* Note also that there are several situations where REQUEST_QUERY will not result in a
* QUERY_CONDITION intent (e.g. event throttling by the host), so plugin-local data
* indexed with a message ID needs to be timestamped and eventually timed-out.
*
* <p>
* This function can be called multiple times, each time all keys in data will be added to
* that of previous calls.
*
@ -495,7 +572,6 @@ public class TaskerPlugin {
* @see #hostSupportsRequestQueryDataPassThrough(Bundle)
* @see #retrievePassThroughData(Intent)
* @see #addPassThroughMessageID
*
*/
public static void addPassThroughData(Intent requestQueryIntent, Bundle data) {
@ -507,7 +583,7 @@ public class TaskerPlugin {
/**
* Retrieve the pass through data from a QUERY_REQUEST from the host which was generated
* by a REQUEST_QUERY from the plugin.
*
* <p>
* Note that if addPassThroughMessageID() was previously called, the data will contain an extra
* key TaskerPlugin.Event.PASS_THOUGH_BUNDLE_MESSAGE_ID_KEY.
*
@ -528,17 +604,16 @@ public class TaskerPlugin {
/**
* Add a message ID to a REQUEST_QUERY intent which will then be included in the corresponding
* QUERY_CONDITION broadcast sent by the host for each event instance of the plugin.
*
* <p>
* The minimal purpose is to enable the plugin to associate a QUERY_CONDITION to the
* with the REQUEST_QUERY that caused it. It also allows the message to be verified
* by the plugin to prevent e.g. replay attacks
*
* @param requestQueryIntent intent being sent to the host
* @return a guaranteed non-repeating within 100 calls message ID
* @return an ID for the bundle so it can be identified and the caller verified when it is again received by the plugin
* @see #hostSupportsRequestQueryDataPassThrough(Bundle)
* @see #retrievePassThroughData(Intent)
* @return an ID for the bundle so it can be identified and the caller verified when it is again received by the plugin
*
*/
public static int addPassThroughMessageID(Intent requestQueryIntent) {
@ -596,7 +671,6 @@ public class TaskerPlugin {
return passThroughBundle;
}
}
// ---------------------------------- HOST ----------------------------------------- //
public static class Host {
@ -696,119 +770,4 @@ public class TaskerPlugin {
b.remove(Setting.BUNDLE_KEY_VARIABLE_REPLACE_STRINGS);
}
}
// ---------------------------------- HELPER FUNCTIONS -------------------------------- //
private static Object getBundleValueSafe( Bundle b, String key, Class<?> expectedClass, String funcName ) {
Object value = null;
if ( b != null ) {
if ( b.containsKey( key ) ) {
Object obj = b.get( key );
if ( obj == null )
Log.w( TAG, funcName + ": " + key + ": null value" );
else if ( obj.getClass() != expectedClass )
Log.w( TAG, funcName + ": " + key + ": expected " + expectedClass.getClass().getName() + ", got " + obj.getClass().getName() );
else
value = obj;
}
}
return value;
}
private static Object getExtraValueSafe( Intent i, String key, Class<?> expectedClass, String funcName ) {
return ( i.hasExtra( key ) ) ?
getBundleValueSafe( i.getExtras(), key, expectedClass, funcName ) :
null;
}
private static boolean hostSupports( Bundle extrasFromHost, int capabilityFlag ) {
Integer flags = (Integer) getBundleValueSafe( extrasFromHost, EXTRA_HOST_CAPABILITIES, Integer.class, "hostSupports" );
return
( flags != null ) &&
( ( flags & capabilityFlag ) > 0 )
;
}
public static int getPackageVersionCode( PackageManager pm, String packageName ) {
int code = -1;
if ( pm != null ) {
try {
PackageInfo pi = pm.getPackageInfo( packageName, 0 );
if ( pi != null )
code = pi.versionCode;
}
catch ( Exception e ) {
Log.e( TAG, "getPackageVersionCode: exception getting package info" );
}
}
return code;
}
private static boolean variableNameIsLocal( String varName ) {
int digitCount = 0;
int length = varName.length();
for ( int x = 0; x < length; x++ ) {
char ch = varName.charAt( x );
if ( Character.isUpperCase( ch ) )
return false;
else if ( Character.isDigit( ch ) )
digitCount++;
}
if ( digitCount == ( varName.length() - 1 ) )
return false;
return true;
}
// state tracking for random number sequence
private static int [] lastRandomsSeen = null;
private static int randomInsertPointer = 0;
private static SecureRandom sr = null;
/**
* Generate a sequence of secure random positive integers which is guaranteed not to repeat
* in the last 100 calls to this function.
*
* @return a random positive integer
*/
public static int getPositiveNonRepeatingRandomInteger() {
// initialize on first call
if ( sr == null ) {
sr = new SecureRandom();
lastRandomsSeen = new int[RANDOM_HISTORY_SIZE];
for ( int x = 0; x < lastRandomsSeen.length; x++ )
lastRandomsSeen[x] = -1;
}
int toReturn;
do {
// pick a number
toReturn = sr.nextInt( Integer.MAX_VALUE );
// check we havn't see it recently
for ( int seen : lastRandomsSeen ) {
if ( seen == toReturn ) {
toReturn = -1;
break;
}
}
}
while ( toReturn == -1 );
// update history
lastRandomsSeen[randomInsertPointer] = toReturn;
randomInsertPointer = ( randomInsertPointer + 1 ) % lastRandomsSeen.length;
return toReturn;
}
}

View file

@ -26,16 +26,15 @@ import android.graphics.drawable.Drawable;
* This drawable that draws a simple white and gray chessboard pattern.
* It's pattern you will often see as a background behind a
* partly transparent image in many applications.
*
* @author Daniel Nilsson
*/
public class AlphaPatternDrawable extends Drawable {
private int mRectangleSize = 10;
// private Paint mPaint = new Paint();
private Paint mPaintWhite = new Paint();
private Paint mPaintGray = new Paint();
private final Paint mPaintWhite = new Paint();
private final Paint mPaintGray = new Paint();
private int mRectangleSize = 10;
private int numRectanglesHorizontal;
private int numRectanglesVertical;
@ -43,7 +42,6 @@ public class AlphaPatternDrawable extends Drawable {
* Bitmap in which the pattern will be cahched.
*/
// private Bitmap mBitmap;
public AlphaPatternDrawable(int rectangleSize) {
mRectangleSize = rectangleSize;
mPaintWhite.setColor(0xffffffff);

View file

@ -28,6 +28,7 @@ import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import net.pierrox.lightning_launcher.R;
public class ColorPickerDialog
@ -45,23 +46,17 @@ public class ColorPickerDialog
private OnColorChangedListener mListener;
@Override
public void onCancel(DialogInterface dialogInterface) {
if(mListener != null) mListener.onColorDialogCanceled();
}
public interface OnColorChangedListener {
public void onColorChanged(int color);
public void onColorDialogSelected(int color);
public void onColorDialogCanceled();
}
public ColorPickerDialog(Context context, int initialColor) {
super(context);
init(initialColor);
}
@Override
public void onCancel(DialogInterface dialogInterface) {
if (mListener != null) mListener.onColorDialogCanceled();
}
private void init(int color) {
// To fight color banding.
getWindow().setFormat(PixelFormat.RGBA_8888);
@ -80,10 +75,10 @@ public class ColorPickerDialog
setTitle(R.string.dialog_color_picker);
mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel);
mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel);
mHexEditor = (EditText) layout.findViewById(R.id.hex_editor);
mColorPicker = layout.findViewById(R.id.color_picker_view);
mOldColor = layout.findViewById(R.id.old_color_panel);
mNewColor = layout.findViewById(R.id.new_color_panel);
mHexEditor = layout.findViewById(R.id.hex_editor);
mHexEditor.clearFocus();
InputFilter filter = new InputFilter() {
@ -177,6 +172,7 @@ public class ColorPickerDialog
/**
* Set a OnColorChangedListener to get notified when the color
* selected by the user has changed.
*
* @param listener
*/
public void setOnColorChangedListener(OnColorChangedListener listener) {
@ -202,6 +198,14 @@ public class ColorPickerDialog
}
dismiss();
}
public interface OnColorChangedListener {
void onColorChanged(int color);
void onColorDialogSelected(int color);
void onColorDialogCanceled();
}
//
// @Override
// public Bundle onSaveInstanceState() {

View file

@ -22,12 +22,12 @@ import android.graphics.Color;
import android.graphics.ComposeShader;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Shader.TileMode;
import android.util.AttributeSet;
import android.view.MotionEvent;
@ -38,6 +38,7 @@ import android.view.View;
* to select a color. A slider for the alpha channel is
* also available. Enable it by setting
* setAlphaSliderVisible(boolean) to true.
*
* @author Daniel Nilsson
*/
public class ColorPickerView extends View {
@ -51,7 +52,9 @@ public class ColorPickerView extends View {
* surrounding all color panels.
*/
private final static float BORDER_WIDTH_PX = 1;
private final String mAlphaSliderText = "";
private final int mSliderTrackerColor = 0xff1c1c1c;
private final int mBorderColor = 0xff6E6E6E;
/**
* The width in dp of the hue panel.
*/
@ -74,36 +77,23 @@ public class ColorPickerView extends View {
* will extend outside of its bounds.
*/
private float RECTANGLE_TRACKER_OFFSET = 2f;
private float mDensity = 1f;
private OnColorChangedListener mListener;
private Paint mSatValPaint;
private Paint mSatValTrackerPaint;
private Paint mHuePaint;
private Paint mHueTrackerPaint;
private Paint mAlphaPaint;
private Paint mAlphaTextPaint;
private Paint mBorderPaint;
private Shader mValShader;
private Shader mSatShader;
private Shader mHueShader;
private Shader mAlphaShader;
private int mAlpha = 0xff;
private float mHue = 360f;
private float mSat = 0f;
private float mVal = 0f;
private String mAlphaSliderText = "";
private int mSliderTrackerColor = 0xff1c1c1c;
private int mBorderColor = 0xff6E6E6E;
private boolean mShowAlphaPanel = false;
/*
@ -134,10 +124,6 @@ public class ColorPickerView extends View {
private Point mStartTouchPoint = null;
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
public ColorPickerView(Context context) {
this(context, null);
}
@ -216,7 +202,6 @@ public class ColorPickerView extends View {
return hue;
}
@Override
protected void onDraw(Canvas canvas) {
@ -254,7 +239,7 @@ public class ColorPickerView extends View {
Point p = satValToPoint(mSat, mVal);
mSatValTrackerPaint.setColor(0xff000000);
canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);
canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - mDensity, mSatValTrackerPaint);
mSatValTrackerPaint.setColor(0xffdddddd);
canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
@ -344,7 +329,6 @@ public class ColorPickerView extends View {
}
private Point hueToPoint(float hue) {
final RectF rect = mHueRect;
@ -396,21 +380,17 @@ public class ColorPickerView extends View {
if (x < rect.left) {
x = 0f;
}
else if(x > rect.right){
} else if (x > rect.right) {
x = width;
}
else{
} else {
x = x - rect.left;
}
if (y < rect.top) {
y = 0f;
}
else if(y > rect.bottom){
} else if (y > rect.bottom) {
y = height;
}
else{
} else {
y = y - rect.top;
}
@ -429,11 +409,9 @@ public class ColorPickerView extends View {
if (y < rect.top) {
y = 0f;
}
else if(y > rect.bottom){
} else if (y > rect.bottom) {
y = height;
}
else{
} else {
y = y - rect.top;
}
@ -447,11 +425,9 @@ public class ColorPickerView extends View {
if (x < rect.left) {
x = 0;
}
else if(x > rect.right){
} else if (x > rect.right) {
x = width;
}
else{
} else {
x = x - (int) rect.left;
}
@ -459,7 +435,6 @@ public class ColorPickerView extends View {
}
@Override
public boolean onTrackballEvent(MotionEvent event) {
@ -482,15 +457,13 @@ public class ColorPickerView extends View {
if (sat < 0f) {
sat = 0f;
}
else if(sat > 1f){
} else if (sat > 1f) {
sat = 1f;
}
if (val < 0f) {
val = 0f;
}
else if(val > 1f){
} else if (val > 1f) {
val = 1f;
}
@ -507,8 +480,7 @@ public class ColorPickerView extends View {
if (hue < 0f) {
hue = 0f;
}
else if(hue > 360f){
} else if (hue > 360f) {
hue = 360f;
}
@ -522,15 +494,13 @@ public class ColorPickerView extends View {
if (!mShowAlphaPanel || mAlphaRect == null) {
update = false;
}
else{
} else {
int alpha = (int) (mAlpha - x * 10);
if (alpha < 0) {
alpha = 0;
}
else if(alpha > 0xff){
} else if (alpha > 0xff) {
alpha = 0xff;
}
@ -622,8 +592,7 @@ public class ColorPickerView extends View {
mHue = pointToHue(event.getY());
update = true;
}
else if(mSatValRect.contains(startX, startY)){
} else if (mSatValRect.contains(startX, startY)) {
mLastTouchedPanel = PANEL_SAT_VAL;
@ -633,8 +602,7 @@ public class ColorPickerView extends View {
mVal = result[1];
update = true;
}
else if(mAlphaRect != null && mAlphaRect.contains(startX, startY)){
} else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) {
mLastTouchedPanel = PANEL_ALPHA;
@ -670,20 +638,17 @@ public class ColorPickerView extends View {
if (height > heightAllowed || getTag().equals("landscape")) {
height = heightAllowed;
width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
}
else{
} else {
width = widthAllowed;
}
}
else{
} else {
width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
if (width > widthAllowed) {
width = widthAllowed;
height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
}
else{
} else {
height = heightAllowed;
}
@ -732,8 +697,6 @@ public class ColorPickerView extends View {
return height;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
@ -800,16 +763,25 @@ public class ColorPickerView extends View {
}
/**
* Set a OnColorChangedListener to get notified when the color
* selected by the user has changed.
*
* @param listener
*/
public void setOnColorChangedListener(OnColorChangedListener listener) {
mListener = listener;
}
/**
* Get the current color this view is showing.
*
* @return the current color.
*/
public int getColor() {
return Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal});
}
// /**
// * Set the color of the border surrounding all panels.
// * @param color
@ -826,16 +798,9 @@ public class ColorPickerView extends View {
// return mBorderColor;
// }
/**
* Get the current color this view is showing.
* @return the current color.
*/
public int getColor(){
return Color.HSVToColor(mAlpha, new float[]{mHue,mSat,mVal});
}
/**
* Set the color the view should show.
*
* @param color The color that should be selected.
*/
public void setColor(int color) {
@ -844,6 +809,7 @@ public class ColorPickerView extends View {
/**
* Set the color this view should show.
*
* @param color The color that should be selected.
* @param callback If you want to get a callback to
* your OnColorChangedListener.
@ -877,6 +843,7 @@ public class ColorPickerView extends View {
* a panel to the side of the view minus the padding.
* Useful if you want to have your own panel below showing
* the currently selected color and want to align it perfectly.
*
* @return The offset in pixels.
*/
public float getDrawingOffset() {
@ -886,6 +853,7 @@ public class ColorPickerView extends View {
/**
* Set if the user is allowed to adjust the alpha panel. Default is false.
* If it is set to false no alpha will be set.
*
* @param visible
*/
public void setAlphaSliderVisible(boolean visible) {
@ -901,13 +869,17 @@ public class ColorPickerView extends View {
mValShader = null;
mSatShader = null;
mHueShader = null;
mAlphaShader = null;;
mAlphaShader = null;
invalidate();
}
}
public interface OnColorChangedListener {
void onColorChanged(int color);
}
// public void setSliderTrackerColor(int color){
// mSliderTrackerColor = color;
//

View file

@ -12,6 +12,7 @@ import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.view.ViewGroup;
import net.pierrox.lightning_launcher.activities.ResourcesWrapperHelper;
import net.pierrox.lightning_launcher.api.ScreenIdentity;
import net.pierrox.lightning_launcher.configuration.SystemConfig;
@ -26,6 +27,7 @@ import net.pierrox.lightning_launcher.script.api.Property;
import net.pierrox.lightning_launcher.views.MyAppWidgetHostView;
import net.pierrox.lightning_launcher.views.NativeImage;
import net.pierrox.lightning_launcher.views.SharedAsyncGraphicsDrawable;
import org.json.JSONObject;
import java.io.File;
@ -34,40 +36,45 @@ import java.util.HashMap;
import java.util.List;
public abstract class LLApp extends Application {
public interface SystemConfigListener {
void onSystemConfigChanged(SystemConfig newSystemConfig);
}
public static final String LL_PKG_NAME = "net.pierrox.lightning_launcher";
public static final String LLX_PKG_NAME = "net.pierrox.lightning_launcher_extreme";
public static final String LKP_PKG_NAME = "net.pierrox.lightning_locker_p";
public static final String INTENT_ITEM_ACTION = LL_PKG_NAME + ".ITEM_ACTION";
private static final int SYSTEM_CONFIG_FILE_VERSION = 1;
private static LLApp sThis;
private final HashMap<String, LightningEngine> mLightningEngines = new HashMap<>();
private final ArrayList<Screen> mScreens = new ArrayList<>();
protected LightningEngine mAppEngine;
private HashMap<String, LightningEngine> mLightningEngines = new HashMap<>();
private MyAppWidgetHost mAppWidgetHost;
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
Screen screen = getActiveScreen();
if (screen != null) {
screen.runAction(mAppEngine, "SCREEN_OFF", mAppEngine.getGlobalConfig().screenOff);
}
} else if (action.equals(Intent.ACTION_SCREEN_ON)) {
Screen screen = getActiveScreen();
if (screen != null) {
screen.runAction(mAppEngine, "SCREEN_ON", mAppEngine.getGlobalConfig().screenOn);
}
}
}
};
protected SystemConfig mSystemConfig;
protected Screen mBackgroundScreen;
private MyAppWidgetHost mAppWidgetHost;
private ArrayList<SystemConfigListener> mSystemConfigListeners;
private ResourcesWrapperHelper mResourcesWrapperHelper;
private String mLanguage;
private int mActiveDashboardPage;
private Typeface mIconsTypeface;
private int mWidgetHostStartListeningCount;
private ArrayList<Screen> mScreens = new ArrayList<>();
protected Screen mBackgroundScreen;
public static LLApp get() {
return sThis;
}
@Override
public void onCreate() {
@ -209,10 +216,6 @@ public abstract class LLApp extends Application {
mSystemConfigListeners.remove(l);
}
public static LLApp get() {
return sThis;
}
public MyAppWidgetHost getAppWidgetHost() {
return mAppWidgetHost;
}
@ -233,14 +236,14 @@ public abstract class LLApp extends Application {
public abstract void displayPagerPage(int page, boolean reset_navigation_history);
public void setActiveDashboardPage(int page) {
mActiveDashboardPage = page;
}
public int getActiveDashboardPage() {
return mActiveDashboardPage;
}
public void setActiveDashboardPage(int page) {
mActiveDashboardPage = page;
}
protected void loadSystemConfig() {
mSystemConfig = JsonLoader.readObject(SystemConfig.class, FileUtils.getSystemConfigFile(this));
}
@ -376,11 +379,15 @@ public abstract class LLApp extends Application {
mSystemConfig.language = json.optString("language", null);
mSystemConfig.expertMode = json.optBoolean("expertMode", false);
mSystemConfig.hotwords = json.optBoolean("hotwords", false);
if(json.has("appStyle")) mSystemConfig.appStyle = SystemConfig.AppStyle.valueOf(json.optString("appStyle"));
if (json.has("appStyle"))
mSystemConfig.appStyle = SystemConfig.AppStyle.valueOf(json.optString("appStyle"));
mSystemConfig.hints = json.optInt("hints", 0);
if(json.optBoolean("showHelpHint", true)) mSystemConfig.hints |= SystemConfig.HINT_CUSTOMIZE_HELP;
if(json.optBoolean("showRateHint", true)) mSystemConfig.hints |= SystemConfig.HINT_RATE;
if(json.optBoolean("myDrawerHint", true)) mSystemConfig.hints |= SystemConfig.HINT_MY_DRAWER;
if (json.optBoolean("showHelpHint", true))
mSystemConfig.hints |= SystemConfig.HINT_CUSTOMIZE_HELP;
if (json.optBoolean("showRateHint", true))
mSystemConfig.hints |= SystemConfig.HINT_RATE;
if (json.optBoolean("myDrawerHint", true))
mSystemConfig.hints |= SystemConfig.HINT_MY_DRAWER;
mSystemConfig.imagePoolSize = (float) json.optDouble("imagePoolSize", 0);
mSystemConfig.switches = json.optInt("switches", SystemConfig.SWITCH_SNAP | SystemConfig.SWITCH_EDIT_BARS | SystemConfig.SWITCH_CONTENT_ZOOMED | SystemConfig.SWITCH_HONOUR_PINNED_ITEMS);
mSystemConfig.editBoxMode = json.optInt("editBoxMode", SystemConfig.EDIT_BOX_NONE);
@ -394,39 +401,8 @@ public abstract class LLApp extends Application {
}
}
private BroadcastReceiver mBroadcastReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
Screen screen = getActiveScreen();
if(screen != null) {
screen.runAction(mAppEngine, "SCREEN_OFF", mAppEngine.getGlobalConfig().screenOff);
}
} else if (action.equals(Intent.ACTION_SCREEN_ON)) {
Screen screen = getActiveScreen();
if(screen != null) {
screen.runAction(mAppEngine, "SCREEN_ON", mAppEngine.getGlobalConfig().screenOn);
}
}
}
};
private class BackgroundScreen extends Screen {
public BackgroundScreen(Context context, int content_view) {
super(context, content_view);
}
@Override
public ScreenIdentity getIdentity() {
return ScreenIdentity.BACKGROUND;
}
@Override
protected Resources getRealResources() {
return LLApp.super.getResources();
}
public interface SystemConfigListener {
void onSystemConfigChanged(SystemConfig newSystemConfig);
}
public static final class MyAppWidgetHost extends AppWidgetHost {
@ -456,4 +432,21 @@ public abstract class LLApp extends Application {
}
}
private class BackgroundScreen extends Screen {
public BackgroundScreen(Context context, int content_view) {
super(context, content_view);
}
@Override
public ScreenIdentity getIdentity() {
return ScreenIdentity.BACKGROUND;
}
@Override
protected Resources getRealResources() {
return LLApp.super.getResources();
}
}
}

View file

@ -8,18 +8,9 @@ import net.pierrox.lightning_launcher.util.ResourcesWrapper;
public class ResourcesWrapperHelper {
private Resources mBaseResources;
private final Resources mBaseResources;
private ResourcesWrapper mResourcesWrapper;
public final Resources getResources() {
if(mResourcesWrapper != null) {
return mResourcesWrapper;
} else {
return mBaseResources;
}
}
public ResourcesWrapperHelper(Context context, Resources base_resources) {
mBaseResources = base_resources;
String language = LLApp.get().getLanguage();
@ -28,4 +19,13 @@ public class ResourcesWrapperHelper {
mResourcesWrapper.setTranslationPackageName(context, language);
}
}
public final Resources getResources() {
if (mResourcesWrapper != null) {
return mResourcesWrapper;
} else {
return mBaseResources;
}
}
}

View file

@ -1,7 +1,9 @@
package net.pierrox.lightning_launcher.configuration;
public interface FolderConfigStylable {
public FolderConfig getFolderConfig();
public void setFolderConfig(FolderConfig fc);
public FolderConfig modifyFolderConfig();
FolderConfig getFolderConfig();
void setFolderConfig(FolderConfig fc);
FolderConfig modifyFolderConfig();
}

View file

@ -6,35 +6,6 @@ import net.pierrox.lightning_launcher.data.Page;
public class GlobalConfig extends JsonLoader {
public enum PageAnimation {
NONE,
FADE,
SLIDE_H,
SLIDE_V
}
public enum OverlayHandlePosition {
LEFT_TOP,
LEFT_MIDDLE,
LEFT_BOTTOM,
RIGHT_TOP,
RIGHT_MIDDLE,
RIGHT_BOTTOM,
TOP_LEFT,
TOP_CENTER,
TOP_RIGHT,
BOTTOM_LEFT,
BOTTOM_CENTER,
BOTTOM_RIGHT
}
public enum OverlayAnimation {
SLIDE,
FADE
}
public static final int CATEGORY = -1;
public static final int UNSET = 0;
public static final int NOTHING = 1;
@ -82,14 +53,12 @@ public class GlobalConfig extends JsonLoader {
public static final int HIDE_FLOATING_DESKTOP = 43;
public static final int OPEN_HIERARCHY_SCREEN = 44;
public static final int SHOW_APP_SHORTCUTS = 45;
// update script EventHandler accordingly
public int version = 1;
public EventAction homeKey = new EventAction(GO_HOME_ZOOM_TO_ORIGIN, null);
public EventAction menuKey = new EventAction(SHOW_HIDE_APP_MENU_STATUS_BAR, null);
// update script EventHandler accordingly
public EventAction longMenuKey = EventAction.NOTHING();
public EventAction backKey = new EventAction(BACK, null);;
public EventAction backKey = new EventAction(BACK, null);
public EventAction longBackKey = EventAction.NOTHING();
public EventAction searchKey = new EventAction(SEARCH, null);
public EventAction itemTap = new EventAction(LAUNCH_ITEM, null);
@ -113,11 +82,7 @@ public class GlobalConfig extends JsonLoader {
public EventAction itemRemoved = EventAction.NOTHING();
public EventAction menu = EventAction.NOTHING();
public EventAction startup = EventAction.NOTHING();
public PageAnimation pageAnimation = PageAnimation.FADE;
public int[] screensOrder = null;
public String[] screensNames = null;
public int homeScreen = Page.FIRST_DASHBOARD_PAGE;
@ -125,8 +90,6 @@ public class GlobalConfig extends JsonLoader {
public boolean launchUnlock = true;
public boolean lockDisableOverlay = false;
public boolean runScripts = true;
public int overlayScreen = Page.NONE;
public OverlayHandlePosition overlayShowHandlePosition = OverlayHandlePosition.LEFT_TOP;
public float overlayShowHandleSize = 0.2f;
@ -137,7 +100,6 @@ public class GlobalConfig extends JsonLoader {
public OverlayAnimation overlayAnimation = OverlayAnimation.SLIDE;
public boolean overlayDisplayHandles = false;
public boolean overlayLaunchHide = true;
public int lwpScreen = Page.NONE;
public int getPageIndex(int p) {
@ -169,4 +131,31 @@ public class GlobalConfig extends JsonLoader {
return true;
}
public enum PageAnimation {
NONE,
FADE,
SLIDE_H,
SLIDE_V
}
public enum OverlayHandlePosition {
LEFT_TOP,
LEFT_MIDDLE,
LEFT_BOTTOM,
RIGHT_TOP,
RIGHT_MIDDLE,
RIGHT_BOTTOM,
TOP_LEFT,
TOP_CENTER,
TOP_RIGHT,
BOTTOM_LEFT,
BOTTOM_CENTER,
BOTTOM_RIGHT
}
public enum OverlayAnimation {
SLIDE,
FADE
}
}

View file

@ -1,7 +1,9 @@
package net.pierrox.lightning_launcher.configuration;
public interface ItemConfigStylable {
public ItemConfig getItemConfig();
public void setItemConfig(ItemConfig c);
public ItemConfig modifyItemConfig();
ItemConfig getItemConfig();
void setItemConfig(ItemConfig c);
ItemConfig modifyItemConfig();
}

View file

@ -24,35 +24,7 @@ import java.io.File;
public class ShortcutConfig extends JsonLoader {
private static final PorterDuffXfermode sMaskXferMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
private static final class CachedTypeface {
String path;
Typeface typeface;
}
private static CachedTypeface sCachedTypefaces[]=new CachedTypeface[15];
public enum LabelVsIconPosition {
LEFT,
TOP,
RIGHT,
BOTTOM,
CENTER
}
public enum FontStyle {
NORMAL,
BOLD,
ITALIC,
BOLD_ITALIC
}
public enum IconSizeMode {
STANDARD,
REAL,
FULL_SCALE_RATIO,
FULL_SCALE,
NORMALIZED,
}
private static final CachedTypeface[] sCachedTypefaces = new CachedTypeface[15];
public boolean labelVisibility = true;
public int labelFontColor = Color.WHITE;
public float labelFontSize = 12f;
@ -71,17 +43,13 @@ public class ShortcutConfig extends JsonLoader {
public int labelVsIconMargin = 4;
public int selectionColorLabel = Color.WHITE;
public int focusColorLabel = 0xffccccff;
public boolean labelShadow = true;
public float labelShadowRadius = 3;
public float labelShadowOffsetX = 1;
public float labelShadowOffsetY = 1;
public int labelShadowColor = 0xaa000000;
public float iconEffectScale = 1f;
public int iconColorFilter = 0xffffffff;
public Drawable iconBack, iconOver, iconMask;
public static ShortcutConfig readFromJsonObject(JSONObject o, ShortcutConfig d) throws JSONException {
@ -96,37 +64,6 @@ public class ShortcutConfig extends JsonLoader {
return c;
}
@Override
public ShortcutConfig clone() {
ShortcutConfig sc = new ShortcutConfig();
sc.copyFrom(this);
return sc;
}
@Override
public void copyFrom(JsonLoader o) {
super.copyFrom(o);
ShortcutConfig sc = (ShortcutConfig)o;
iconBack = sc.iconBack;
iconOver = sc.iconOver;
iconMask = sc.iconMask;
}
public void loadAssociatedIcons(File icon_dir, int id) {
File f = getIconBackFile(icon_dir, id);
if(f.exists()) iconBack=Utils.loadDrawable(f);
f = getIconOverFile(icon_dir, id);
if(f.exists()) iconOver=Utils.loadDrawable(f);
f = getIconMaskFile(icon_dir, id);
if(f.exists()) {
SharedAsyncGraphicsDrawable d = Utils.loadDrawable(f);
iconMask = d;
if(d != null && d.getType() == SharedAsyncGraphicsDrawable.TYPE_BITMAP) {
d.getPaint().setXfermode(sMaskXferMode);
}
}
}
public static File getIconBackFile(File icon_dir, int id) {
return new File(icon_dir, (id == Item.NO_ID ? "" : id) + FileUtils.SUFFIX_ICON_BACK);
}
@ -139,43 +76,6 @@ public class ShortcutConfig extends JsonLoader {
return new File(icon_dir, (id == Item.NO_ID ? "" : id) + FileUtils.SUFFIX_ICON_MASK);
}
public void applyFontStyleToTextView(MyTextView tv) {
Typeface tf=getTypeFace(labelFontTypeFace);
int s;
switch(labelFontStyle) {
case BOLD: s=Typeface.BOLD; break;
case BOLD_ITALIC: s=Typeface.BOLD_ITALIC; break;
case ITALIC: s=Typeface.ITALIC; break;
default: s=Typeface.NORMAL; break;
}
tv.setTypeface(tf, s);
}
public void applyToTextView(MyTextView tv, ItemConfig ic) {
tv.setTextColor(labelFontColor);
tv.setTextSize(labelFontSize);
applyFontStyleToTextView(tv);
//tv.setIncludeFontPadding(false);
tv.setEllipsize(TextUtils.TruncateAt.END);
if(labelMaxLines==1) {
tv.setSingleLine();
} else {
tv.setSingleLine(false);
tv.setMaxLines(labelMaxLines);
int g;
switch(ic.box.ah) {
case LEFT: g= Gravity.LEFT; break;
case RIGHT: g=Gravity.RIGHT; break;
default: g=Gravity.CENTER; break;
}
tv.setGravity(g);
}
if(labelShadow) {
tv.setShadowLayer(labelShadowRadius, labelShadowOffsetX, labelShadowOffsetY, labelShadowColor);
}
tv.setfixWidth(labelShadow || labelFontStyle== ShortcutConfig.FontStyle.ITALIC || labelFontStyle== ShortcutConfig.FontStyle.BOLD_ITALIC);
}
private static Typeface getTypeFace(String font_path) {
if (API.SHORTCUT_SYSTEM_FONT.equals(font_path)) {
return null;
@ -208,4 +108,114 @@ public class ShortcutConfig extends JsonLoader {
return null;
}
}
@Override
public ShortcutConfig clone() {
ShortcutConfig sc = new ShortcutConfig();
sc.copyFrom(this);
return sc;
}
@Override
public void copyFrom(JsonLoader o) {
super.copyFrom(o);
ShortcutConfig sc = (ShortcutConfig) o;
iconBack = sc.iconBack;
iconOver = sc.iconOver;
iconMask = sc.iconMask;
}
public void loadAssociatedIcons(File icon_dir, int id) {
File f = getIconBackFile(icon_dir, id);
if (f.exists()) iconBack = Utils.loadDrawable(f);
f = getIconOverFile(icon_dir, id);
if (f.exists()) iconOver = Utils.loadDrawable(f);
f = getIconMaskFile(icon_dir, id);
if (f.exists()) {
SharedAsyncGraphicsDrawable d = Utils.loadDrawable(f);
iconMask = d;
if (d != null && d.getType() == SharedAsyncGraphicsDrawable.TYPE_BITMAP) {
d.getPaint().setXfermode(sMaskXferMode);
}
}
}
public void applyFontStyleToTextView(MyTextView tv) {
Typeface tf = getTypeFace(labelFontTypeFace);
int s;
switch (labelFontStyle) {
case BOLD:
s = Typeface.BOLD;
break;
case BOLD_ITALIC:
s = Typeface.BOLD_ITALIC;
break;
case ITALIC:
s = Typeface.ITALIC;
break;
default:
s = Typeface.NORMAL;
break;
}
tv.setTypeface(tf, s);
}
public void applyToTextView(MyTextView tv, ItemConfig ic) {
tv.setTextColor(labelFontColor);
tv.setTextSize(labelFontSize);
applyFontStyleToTextView(tv);
//tv.setIncludeFontPadding(false);
tv.setEllipsize(TextUtils.TruncateAt.END);
if (labelMaxLines == 1) {
tv.setSingleLine();
} else {
tv.setSingleLine(false);
tv.setMaxLines(labelMaxLines);
int g;
switch (ic.box.ah) {
case LEFT:
g = Gravity.LEFT;
break;
case RIGHT:
g = Gravity.RIGHT;
break;
default:
g = Gravity.CENTER;
break;
}
tv.setGravity(g);
}
if (labelShadow) {
tv.setShadowLayer(labelShadowRadius, labelShadowOffsetX, labelShadowOffsetY, labelShadowColor);
}
tv.setfixWidth(labelShadow || labelFontStyle == ShortcutConfig.FontStyle.ITALIC || labelFontStyle == ShortcutConfig.FontStyle.BOLD_ITALIC);
}
public enum LabelVsIconPosition {
LEFT,
TOP,
RIGHT,
BOTTOM,
CENTER
}
public enum FontStyle {
NORMAL,
BOLD,
ITALIC,
BOLD_ITALIC
}
public enum IconSizeMode {
STANDARD,
REAL,
FULL_SCALE_RATIO,
FULL_SCALE,
NORMALIZED,
}
private static final class CachedTypeface {
String path;
Typeface typeface;
}
}

View file

@ -1,7 +1,9 @@
package net.pierrox.lightning_launcher.configuration;
public interface ShortcutConfigStylable {
public ShortcutConfig getShortcutConfig();
public void setShortcutConfig(ShortcutConfig c);
public ShortcutConfig modifyShortcutConfig();
ShortcutConfig getShortcutConfig();
void setShortcutConfig(ShortcutConfig c);
ShortcutConfig modifyShortcutConfig();
}

View file

@ -4,28 +4,14 @@ import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import net.pierrox.android.lsvg.SvgDrawable;
import net.pierrox.lightning_launcher.util.AnimationDecoder;
import net.pierrox.lightning_launcher.views.Graphics;
import net.pierrox.lightning_launcher.views.SharedAsyncGraphicsDrawable;
import net.pierrox.android.lsvg.SvgDrawable;
import java.io.File;
public class Box implements SharedAsyncGraphicsDrawable.GraphicsProvider {
public enum AlignH {
LEFT,
CENTER,
RIGHT,
CUSTOM
}
public enum AlignV {
TOP,
MIDDLE,
BOTTOM,
CUSTOM
}
public static final int ML = 0;
public static final int MT = 1;
public static final int MR = 2;
@ -38,7 +24,6 @@ public class Box implements SharedAsyncGraphicsDrawable.GraphicsProvider {
public static final int PT = 9;
public static final int PR = 10;
public static final int PB = 11;
public static final int BCL = 0;
public static final int BCT = 1;
public static final int BCR = 2;
@ -46,19 +31,16 @@ public class Box implements SharedAsyncGraphicsDrawable.GraphicsProvider {
public static final int COLOR_SHIFT_N = 0;
public static final int COLOR_SHIFT_S = 4;
public static final int COLOR_SHIFT_F = 8;
private static final StringBuffer sTmpStringBuffer = new StringBuffer(200);
public int[] size;
public int[] border_color;
// color content normal/pressed/focused
public int ccn = Color.TRANSPARENT;
public int ccs = 0xffffffff;
public int ccf = 0x808080ff;
// align h/v
public AlignH ah = AlignH.CENTER;
public AlignV av = AlignV.MIDDLE;
public Drawable bgNormal;
public Drawable bgSelected;
public Drawable bgFocused;
@ -70,6 +52,31 @@ public class Box implements SharedAsyncGraphicsDrawable.GraphicsProvider {
for (int i = 0; i < border_color.length; i++) border_color[i] = Color.WHITE;
}
public static File getBoxBackgroundNormal(File icon_dir, int id) {
return new File(icon_dir, (id == Item.NO_ID ? "" : id) + FileUtils.SUFFIX_BOX_BG_NORMAL);
}
public static File getBoxBackgroundSelected(File icon_dir, int id) {
return new File(icon_dir, (id == Item.NO_ID ? "" : id) + FileUtils.SUFFIX_BOX_BG_SELECTED);
}
public static File getBoxBackgroundFocused(File icon_dir, int id) {
return new File(icon_dir, (id == Item.NO_ID ? "" : id) + FileUtils.SUFFIX_BOX_BG_FOCUSED);
}
public static File getBoxBackgroundFolder(File icon_dir, int id) {
return new File(icon_dir, (id == Item.NO_ID ? "" : id) + FileUtils.SUFFIX_BOX_BG_FOLDER);
}
private static String getStringAt(String[] e, int i) {
if (i < e.length) {
String v = e[i];
return v.length() == 0 ? null : v;
} else {
return null;
}
}
public void loadFromString(String s, Box d) {
String[] e = s.split(":");
@ -78,12 +85,17 @@ public class Box implements SharedAsyncGraphicsDrawable.GraphicsProvider {
loadArray(e, 12, border_color, d.border_color);
String v;
v=getStringAt(e, 24); ccn=v==null ? d.ccn : Integer.parseInt(v);
v=getStringAt(e, 25); ccs=v==null ? d.ccs : Integer.parseInt(v);
v=getStringAt(e, 26); ccf=v==null ? d.ccf : Integer.parseInt(v);
v = getStringAt(e, 24);
ccn = v == null ? d.ccn : Integer.parseInt(v);
v = getStringAt(e, 25);
ccs = v == null ? d.ccs : Integer.parseInt(v);
v = getStringAt(e, 26);
ccf = v == null ? d.ccf : Integer.parseInt(v);
v=getStringAt(e, 27); ah=v==null ? d.ah : AlignH.valueOf(v);
v=getStringAt(e, 28); av=v==null ? d.av : AlignV.valueOf(v);
v = getStringAt(e, 27);
ah = v == null ? d.ah : AlignH.valueOf(v);
v = getStringAt(e, 28);
av = v == null ? d.av : AlignV.valueOf(v);
} catch (Exception e1) {
// pass
}
@ -129,31 +141,6 @@ public class Box implements SharedAsyncGraphicsDrawable.GraphicsProvider {
return false;
}
public static File getBoxBackgroundNormal(File icon_dir, int id) {
return new File(icon_dir, (id== Item.NO_ID?"":id)+FileUtils.SUFFIX_BOX_BG_NORMAL);
}
public static File getBoxBackgroundSelected(File icon_dir, int id) {
return new File(icon_dir, (id== Item.NO_ID?"":id)+FileUtils.SUFFIX_BOX_BG_SELECTED);
}
public static File getBoxBackgroundFocused(File icon_dir, int id) {
return new File(icon_dir, (id== Item.NO_ID?"":id)+FileUtils.SUFFIX_BOX_BG_FOCUSED);
}
public static File getBoxBackgroundFolder(File icon_dir, int id) {
return new File(icon_dir, (id== Item.NO_ID?"":id)+FileUtils.SUFFIX_BOX_BG_FOLDER);
}
private static String getStringAt(String e[], int i) {
if(i<e.length) {
String v = e[i];
return v.length() == 0 ? null : v;
} else {
return null;
}
}
private void loadArray(String[] e, int offset, int[] dst, int[] dst_def) {
int n = dst.length;
for (int i = 0; i < n; i++) {
@ -193,5 +180,17 @@ public class Box implements SharedAsyncGraphicsDrawable.GraphicsProvider {
}
}
private static StringBuffer sTmpStringBuffer=new StringBuffer(200);
public enum AlignH {
LEFT,
CENTER,
RIGHT,
CUSTOM
}
public enum AlignV {
TOP,
MIDDLE,
BOTTOM,
CUSTOM
}
}

View file

@ -55,7 +55,7 @@ public class ContainerPath {
}
public ContainerPath getParent() {
int pos = mPath.lastIndexOf('/', mPath.length()-1);
int pos = mPath.lastIndexOf('/');
if (pos == -1) {
return null;
} else {

View file

@ -1,7 +1,16 @@
package net.pierrox.lightning_launcher.data;
import android.accounts.*;
import android.content.*;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.Rect;
@ -13,10 +22,10 @@ import android.os.StatFs;
import android.provider.CallLog;
import android.text.format.Formatter;
import net.pierrox.lightning_launcher.R;
import net.pierrox.lightning_launcher.configuration.DynamicTextConfig;
import net.pierrox.lightning_launcher.configuration.JsonFields;
import net.pierrox.lightning_launcher.configuration.ShortcutConfig;
import net.pierrox.lightning_launcher.R;
import net.pierrox.lightning_launcher.views.item.ItemView;
import net.pierrox.lightning_launcher.views.item.ShortcutView;
@ -55,6 +64,35 @@ public class DynamicText extends Shortcut {
super(page);
}
public static ComponentName getDefaultComponentNameForSource(DynamicTextConfig.Source source) {
String cn = null;
switch (source) {
case MISSED_CALLS:
cn = "com.android.contacts/.DialtactsActivity";
break;
case UNREAD_SMS:
cn = "com.android.mms/.ui.ConversationList";
break;
case UNREAD_GMAIL:
cn = "com.google.android.gm/.ConversationListActivityGmail";
break;
case DATE:
cn = "com.google.android.deskclock/com.android.deskclock.DeskClock";
break;
case STORAGE:
cn = "com.android.settings/.Settings";
break;
case BATTERY_LEVEL:
cn = "com.android.settings/.BatteryInfo";
break;
case HEAP_FREE:
case HEAP_MAX:
cn = "com.android.settings/.Settings";
break;
}
return ComponentName.unflattenFromString(cn);
}
public DynamicTextConfig getDynamicTextConfig() {
return mDynamicTextConfig;
}
@ -273,7 +311,6 @@ public class DynamicText extends Shortcut {
super.resume();
}
@Override
public void onCreate() {
super.onCreate();
@ -297,34 +334,11 @@ public class DynamicText extends Shortcut {
super.onDestroy();
}
public static ComponentName getDefaultComponentNameForSource(DynamicTextConfig.Source source) {
String cn = null;
switch(source) {
case MISSED_CALLS: cn="com.android.contacts/.DialtactsActivity"; break;
case UNREAD_SMS: cn="com.android.mms/.ui.ConversationList"; break;
case UNREAD_GMAIL: cn="com.google.android.gm/.ConversationListActivityGmail"; break;
case DATE: cn="com.google.android.deskclock/com.android.deskclock.DeskClock"; break;
case STORAGE: cn="com.android.settings/.Settings"; break;
case BATTERY_LEVEL: cn="com.android.settings/.BatteryInfo"; break;
case HEAP_FREE:
case HEAP_MAX: cn="com.android.settings/.Settings"; break;
}
return ComponentName.unflattenFromString(cn);
}
public void setEditMode(boolean edit_mode) {
mEditMode = edit_mode;
updateVisibility();
}
private Runnable mTimerRunnable = new Runnable() {
@Override
public void run() {
updateText();
mHandler.postDelayed(mTimerRunnable, 1000);
}
};
private void onAccountResults(Context context, Account[] accounts) {
if (accounts != null && accounts.length > 0) {
try {
@ -356,6 +370,14 @@ public class DynamicText extends Shortcut {
}
}
private final Runnable mTimerRunnable = new Runnable() {
@Override
public void run() {
updateText();
mHandler.postDelayed(mTimerRunnable, 1000);
}
};
private void setupMessagingCursor() {
mCursor.registerContentObserver(mContentObserver);
updateText();
@ -381,9 +403,14 @@ public class DynamicText extends Shortcut {
long available_blocks = stat.getAvailableBlocks();
long value;
switch (mDynamicTextConfig.storageWhat) {
case LEFT: value = available_blocks; break;
case USED: value = total_blocks-available_blocks; break;
default: value = total_blocks;
case LEFT:
value = available_blocks;
break;
case USED:
value = total_blocks - available_blocks;
break;
default:
value = total_blocks;
}
value *= block_size;
switch (mDynamicTextConfig.storageFormat) {
@ -396,7 +423,7 @@ public class DynamicText extends Shortcut {
break;
case PERCENT:
new_text = String.valueOf(value*100 / (total_blocks*block_size))+"%";
new_text = value * 100 / (total_blocks * block_size) + "%";
break;
case BYTES:
@ -462,4 +489,6 @@ public class DynamicText extends Shortcut {
private void updateVisibility() {
setVisible(mCount != 0 || mDynamicTextConfig.displayEmpty || mEditMode);
}
}

View file

@ -18,14 +18,6 @@ public class EventAction {
public String data;
public EventAction next;
public static EventAction UNSET() {
return new EventAction(GlobalConfig.UNSET, null);
}
public static final EventAction NOTHING() {
return new EventAction(GlobalConfig.NOTHING, null);
}
public EventAction() {
// empty constructor for serialization
}
@ -41,6 +33,14 @@ public class EventAction {
this.next = next;
}
public static EventAction UNSET() {
return new EventAction(GlobalConfig.UNSET, null);
}
public static final EventAction NOTHING() {
return new EventAction(GlobalConfig.NOTHING, null);
}
public EventAction clone() {
return new EventAction(action, data, next == null ? null : next.clone());
}
@ -50,9 +50,9 @@ public class EventAction {
if (o.getClass() != EventAction.class) return false;
EventAction ea = (EventAction) o;
if (this.action != ea.action) return false;
if((this.data == null && ea.data != null) || (this.data != null && !this.data.equals(ea.data))) return false;
if((this.next == null && ea.next != null) || (this.next != null && !this.next.equals(ea.next))) return false;
return true;
if ((this.data == null && ea.data != null) || (this.data != null && !this.data.equals(ea.data)))
return false;
return (this.next != null || ea.next == null) && (this.next == null || this.next.equals(ea.next));
}
public String describe(LightningEngine engine) {

View file

@ -17,6 +17,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
public class FileUtils {
public static final String WALLPAPER_DIR = "wp";
@ -45,9 +46,9 @@ public class FileUtils {
public static final File LL_EXT_DIR = new File(Environment.getExternalStorageDirectory(), "LightningLauncher");
public static final File LL_TMP_DIR = new File(LL_EXT_DIR, "tmp");
public static final File LL_EXT_SCRIPT_DIR = new File(LL_EXT_DIR, "script");
public static final String THEMES_DIR = "LightningLauncher/themes";
private static final byte[] copy_buffer = new byte[4096];
private static byte[] copy_buffer=new byte[4096];
public static void copyStream(InputStream from, OutputStream to) throws IOException {
int n;
while ((n = from.read(copy_buffer)) != -1) {
@ -60,12 +61,14 @@ public class FileUtils {
try {
out.getParentFile().mkdirs();
fos = new FileOutputStream(out);
fos.write(what.getBytes("utf-8"));
fos.write(what.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
out.delete();
throw e;
} finally {
if(fos!=null) try { fos.close(); } catch(Exception e) { /*pass*/ }
if (fos != null) try {
fos.close();
} catch (Exception e) { /*pass*/ }
}
}
@ -89,11 +92,14 @@ public class FileUtils {
int file_length = (int) f.length();
byte[] data = new byte[file_length];
fis.read(data, 0, file_length);
return new String(data, "utf-8");
return new String(data, StandardCharsets.UTF_8);
} catch (Exception e) {
return null;
} finally {
if(fis!=null) try { fis.close(); } catch(Exception e) {}
if (fis != null) try {
fis.close();
} catch (Exception e) {
}
}
}
@ -109,12 +115,12 @@ public class FileUtils {
} catch (Exception e) {
return null;
} finally {
if(is!=null) try { is.close(); } catch(Exception e) {}
if (is != null) try {
is.close();
} catch (Exception e) {
}
}
}
public static final String THEMES_DIR = "LightningLauncher/themes";
public static final File getExternalThemeDir(String theme_id) {
return new File(Environment.getExternalStorageDirectory(), FileUtils.THEMES_DIR + "/" + theme_id);
@ -127,6 +133,7 @@ public class FileUtils {
public static File getSystemConfigFile(Context context) {
return new File(context.getFilesDir(), "system");
}
public static File getCachedDrawablesDir(Context context) {
return new File(context.getCacheDir(), "drawables");
}

View file

@ -27,10 +27,6 @@ import java.util.HashMap;
public class IconPack {
public interface IconPackListener {
void onPackApplied(boolean success);
}
public static boolean applyIconPackSync(final Context context, final String package_name, final Page page, final int item_id) {
boolean result = doApplyIconPackInBackground(context, package_name, page, item_id);
doApplyIconPackPostExecute(page, item_id);
@ -101,7 +97,8 @@ public class IconPack {
for (String icon_name : icon_names) {
try {
int drawable_res_id = res.getIdentifier(icon_name, "drawable", package_name);
if(drawable_res_id != 0) icon_name_ids.put(icon_name, Integer.valueOf(drawable_res_id));
if (drawable_res_id != 0)
icon_name_ids.put(icon_name, Integer.valueOf(drawable_res_id));
} catch (Resources.NotFoundException e) {
// pass, error in input array
}
@ -182,7 +179,8 @@ public class IconPack {
ComponentName cn = ComponentName.unflattenFromString(component_name);
int drawable_res_id = res.getIdentifier(drawable, "drawable", package_name);
if(drawable_res_id != 0) component_name_ids.put(cn.flattenToString(), Integer.valueOf(drawable_res_id));
if (drawable_res_id != 0)
component_name_ids.put(cn.flattenToString(), Integer.valueOf(drawable_res_id));
} catch (Exception e) {
Log.i("LL", "unable to decode " + component);
// pass, error in input array
@ -194,7 +192,10 @@ public class IconPack {
} catch (Exception e1) {
e1.printStackTrace();
} finally {
if(appfilter_is != null) try { appfilter_is.close(); } catch (IOException e) {}
if (appfilter_is != null) try {
appfilter_is.close();
} catch (IOException e) {
}
}
// File pages_dir = FileUtils.getPagesDir(Customize.this);
@ -229,11 +230,15 @@ public class IconPack {
icon_dir.mkdirs();
if (item_id == Item.NO_ID) {
File icon_effect_back_file = new File(icon_dir, "b");
if (icon_effect_back.size() > 0) saveBitmapToFile(icon_effect_back.get(0), icon_effect_back_file); else icon_effect_back_file.delete();
if (icon_effect_back.size() > 0)
saveBitmapToFile(icon_effect_back.get(0), icon_effect_back_file);
else icon_effect_back_file.delete();
File icon_effect_over_file = new File(icon_dir, "o");
if (icon_effect_over != null) saveBitmapToFile(icon_effect_over, icon_effect_over_file); else icon_effect_over_file.delete();
if (icon_effect_over != null) saveBitmapToFile(icon_effect_over, icon_effect_over_file);
else icon_effect_over_file.delete();
File icon_effect_mask_file = new File(icon_dir, "m");
if (icon_effect_mask != null) saveBitmapToFile(icon_effect_mask, icon_effect_mask_file); else icon_effect_mask_file.delete();
if (icon_effect_mask != null) saveBitmapToFile(icon_effect_mask, icon_effect_mask_file);
else icon_effect_mask_file.delete();
page.setModified();
}
@ -297,9 +302,9 @@ public class IconPack {
int id = s.getId();
ShortcutConfig sc = s.getShortcutConfig().clone();
sc.iconEffectScale = 1;
saveEmptyBitmap(sc.getIconBackFile(icon_dir, id));
saveEmptyBitmap(sc.getIconOverFile(icon_dir, id));
saveEmptyBitmap(sc.getIconMaskFile(icon_dir, id));
saveEmptyBitmap(ShortcutConfig.getIconBackFile(icon_dir, id));
saveEmptyBitmap(ShortcutConfig.getIconOverFile(icon_dir, id));
saveEmptyBitmap(ShortcutConfig.getIconMaskFile(icon_dir, id));
s.setShortcutConfig(sc);
} else if (icon_effect_back.size() > 1) {
Bitmap bitmap = icon_effect_back.get((n++) % icon_effect_back.size());
@ -321,7 +326,6 @@ public class IconPack {
}
}
private static void saveEmptyBitmap(File to) {
FileOutputStream fos = null;
try {
@ -333,7 +337,9 @@ public class IconPack {
} catch (IOException e) {
to.delete();
} finally {
if(fos != null) try { fos.close(); } catch (IOException e) { /*pass*/ }
if (fos != null) try {
fos.close();
} catch (IOException e) { /*pass*/ }
}
}
@ -358,7 +364,14 @@ public class IconPack {
} catch (IOException e) {
file.delete();
} finally {
if(fos != null) try { fos.close(); } catch(IOException e) {}
if (fos != null) try {
fos.close();
} catch (IOException e) {
}
}
}
public interface IconPackListener {
void onPackApplied(boolean success);
}
}

View file

@ -36,80 +36,110 @@ public abstract class Item implements ItemConfigStylable {
public static final int GEOMETRY_CTRL_ROTATE = 3;
public static final int GEOMETRY_CTRL_SCALE = 4;
public static final int GEOMETRY_CTRL_SKEW = 5;
public interface OnItemEventListener {
void onItemPaused(Item item);
void onItemResumed(Item item);
void onItemVisibilityChanged(Item item);
void onItemAlphaChanged(Item item);
void onItemTransformChanged(Item item, boolean fast);
void onItemCellChanged(Item item);
void onItemBindingsChanged(Item item, boolean apply);
void onItemError(Item item, Error error);
void onShortcutLabelChanged(Shortcut shortcut);
void onFolderPageIdChanged(Folder folder, int oldPageId);
}
public static final int NO_ID = -1;
public enum Type {
SHORTCUT,
WIDGET,
FOLDER,
STOP_POINT,
DTEXT,
EFOLDER,
UNLOCKER,
PAGE_INDICATOR,
CUSTOM_VIEW
}
public static final int APP_DRAWER_HIDDEN_ALL = 0;
public static final int APP_DRAWER_HIDDEN_ONLY_VISIBLE = 1;
public static final int APP_DRAWER_HIDDEN_ONLY_HIDDEN = 2;
private static final RectF mTempRectF = new RectF();
private static String[] sItemNames;
// rather a hack: saved here to ease sorting of items
public int mLaunchCount;
public long mLastUpdateTime;
protected Page mPage;
protected int mId;
protected HashMap<String, String> mTags;
protected String mName;
// used in grid layout mode
protected Rect mCell;
protected Rect mCellP;
protected Rect mCellL;
protected Rect mCellT;
// used in free layout mode
protected Matrix mTransform;
protected Matrix mTransformP;
protected Matrix mTransformL;
protected Point mViewSize;
protected Point mViewSizeP;
protected Point mViewSizeL;
public static final int APP_DRAWER_HIDDEN_ALL = 0;
public static final int APP_DRAWER_HIDDEN_ONLY_VISIBLE = 1;
public static final int APP_DRAWER_HIDDEN_ONLY_HIDDEN = 2;
protected ItemConfig mItemConfig;
private boolean mAppDrawerHidden; // persistently hidden app in the app drawer
private int mAppDrawerHiddenHandling = Item.APP_DRAWER_HIDDEN_ONLY_VISIBLE;
private boolean mVisible = true;
private int mAlpha = -1;
protected ItemConfig mItemConfig;
private boolean mSharedItemConfig;
// rather a hack: saved here to ease sorting of items
public int mLaunchCount;
public long mLastUpdateTime;
public Item(Page page) {
mPage = page;
}
public static File getDefaultIconFile(File icon_dir, int id) {
return new File(icon_dir, String.valueOf(id));
}
public static File getCustomIconFile(File icon_dir, int id) {
return new File(icon_dir, id + "c");
}
public static Item loadItemFromJSONObject(Page page, JSONObject o) throws JSONException {
Type type;
try {
type = Type.valueOf(o.getString(JsonFields.ITEM_TYPE));
} catch (Exception e) {
return null;
}
Item item;
switch (type) {
case SHORTCUT:
item = new Shortcut(page);
break;
case WIDGET:
item = new Widget(page);
break;
case FOLDER:
item = new Folder(page);
break;
case STOP_POINT:
item = new StopPoint(page);
break;
case DTEXT:
item = new DynamicText(page);
break;
case EFOLDER:
item = new EmbeddedFolder(page);
break;
case UNLOCKER:
item = new Unlocker(page);
break;
case PAGE_INDICATOR:
item = new PageIndicator(page);
break;
case CUSTOM_VIEW:
item = new CustomView(page);
break;
default:
return null;
}
item.createFromJSONObject(o);
return item;
}
public static void loadItemNames(Resources resources) {
String[] some_names = resources.getStringArray(R.array.dialog_action_values);
sItemNames = new String[]{
some_names[1],
some_names[2],
some_names[4],
some_names[5],
resources.getString(R.string.efolder),
resources.getString(R.string.dtext),
resources.getString(R.string.i_ul),
resources.getString(R.string.pi),
resources.getString(R.string.cv),
};
}
public Page getPage() {
return mPage;
}
@ -167,32 +197,24 @@ public abstract class Item implements ItemConfigStylable {
mId = id;
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
mPage.setModified();
}
public String getName() {
return mName;
}
@Override
public String toString() {
return formatForDisplay(false, 0);
}
public static File getDefaultIconFile(File icon_dir, int id) {
return new File(icon_dir, String.valueOf(id));
}
public File getDefaultIconFile() {
return getDefaultIconFile(mPage.getIconDir(), mId);
}
public static File getCustomIconFile(File icon_dir, int id) {
return new File(icon_dir, id+"c");
}
public File getCustomIconFile() {
return getCustomIconFile(mPage.getIconDir(), mId);
}
@ -240,6 +262,10 @@ public abstract class Item implements ItemConfigStylable {
}
}
public boolean isVisible() {
return mVisible;
}
public void setVisible(boolean visible) {
if (visible != mVisible) {
mVisible = visible;
@ -247,11 +273,10 @@ public abstract class Item implements ItemConfigStylable {
}
}
public boolean isVisible() {
return mVisible;
public int getAlpha() {
return mAlpha;
}
public void setAlpha(int alpha) {
if (alpha != mAlpha) {
mAlpha = alpha;
@ -259,10 +284,6 @@ public abstract class Item implements ItemConfigStylable {
}
}
public int getAlpha() {
return mAlpha;
}
public Matrix getTransform() {
return mTransform;
}
@ -301,7 +322,6 @@ public abstract class Item implements ItemConfigStylable {
mPage.onItemTransformChanged(this, fast);
}
private static RectF mTempRectF = new RectF();
public void updateGeometryValue(int what, float value_x, float value_y, boolean fast) {
float sx, sy;
float[] values = new float[9];
@ -528,8 +548,6 @@ public abstract class Item implements ItemConfigStylable {
return m;
}
public void setTag(String id, String tag) {
if (id == null) id = "_";
if (tag == null) {
@ -548,40 +566,6 @@ public abstract class Item implements ItemConfigStylable {
return mTags == null ? null : mTags.get(id);
}
public static Item loadItemFromJSONObject(Page page, JSONObject o) throws JSONException {
Type type;
try {
type = Type.valueOf(o.getString(JsonFields.ITEM_TYPE));
} catch (Exception e) {
return null;
}
Item item;
switch (type) {
case SHORTCUT: item = new Shortcut(page); break;
case WIDGET: item = new Widget(page); break;
case FOLDER: item = new Folder(page); break;
case STOP_POINT: item = new StopPoint(page); break;
case DTEXT: item = new DynamicText(page); break;
case EFOLDER: item = new EmbeddedFolder(page); break;
case UNLOCKER: item = new Unlocker(page); break;
case PAGE_INDICATOR: item = new PageIndicator(page); break;
case CUSTOM_VIEW: item = new CustomView(page); break;
default: return null;
}
item.createFromJSONObject(o);
return item;
}
public JSONObject toJSONObject() throws JSONException {
JSONObject json_item = new JSONObject();
@ -711,23 +695,6 @@ public abstract class Item implements ItemConfigStylable {
return json_item;
}
private static String[] sItemNames;
public static void loadItemNames(Resources resources) {
String[] some_names = resources.getStringArray(R.array.dialog_action_values);
sItemNames = new String[] {
some_names[1],
some_names[2],
some_names[4],
some_names[5],
resources.getString(R.string.efolder),
resources.getString(R.string.dtext),
resources.getString(R.string.i_ul),
resources.getString(R.string.pi),
resources.getString(R.string.cv),
};
}
public String formatForDisplay(boolean id_after, int maxLength) {
String type;
Class<?> cls = getClass();
@ -776,4 +743,38 @@ public abstract class Item implements ItemConfigStylable {
public void notifyChanged() {
mPage.notifyItemChanged(this);
}
public enum Type {
SHORTCUT,
WIDGET,
FOLDER,
STOP_POINT,
DTEXT,
EFOLDER,
UNLOCKER,
PAGE_INDICATOR,
CUSTOM_VIEW
}
public interface OnItemEventListener {
void onItemPaused(Item item);
void onItemResumed(Item item);
void onItemVisibilityChanged(Item item);
void onItemAlphaChanged(Item item);
void onItemTransformChanged(Item item, boolean fast);
void onItemCellChanged(Item item);
void onItemBindingsChanged(Item item, boolean apply);
void onItemError(Item item, Error error);
void onShortcutLabelChanged(Shortcut shortcut);
void onFolderPageIdChanged(Folder folder, int oldPageId);
}
}

View file

@ -16,7 +16,9 @@ import java.lang.reflect.Modifier;
import java.util.HashMap;
public class JsonLoader {
/** Specialized for configuration objects, not a multi-purpose tool. */
/**
* Specialized for configuration objects, not a multi-purpose tool.
*/
public static JSONObject toJSONObject(Object o, Object default_value) {
JSONObject json_object = new JSONObject();
@ -25,7 +27,9 @@ public class JsonLoader {
return json_object;
}
/** Specialized for configuration objects, not a multi-purpose tool. */
/**
* Specialized for configuration objects, not a multi-purpose tool.
*/
public static void toJSONObject(JSONObject json_object, Object o, Object default_value) {
for (Field f : o.getClass().getFields()) {
if (Modifier.isFinal(f.getModifiers())) continue;
@ -61,9 +65,9 @@ public class JsonLoader {
json_object.put(name, jai);
}
} else if (cls == float.class) {
json_object.put(name, (double)f.getFloat(o));
json_object.put(name, f.getFloat(o));
} else if (cls == String.class) {
json_object.put(name, (String)f.get(o));
json_object.put(name, f.get(o));
} else if (cls == String[].class) {
String[] as = (String[]) f.get(o);
if (as != null) {
@ -113,10 +117,6 @@ public class JsonLoader {
}
}
public void loadFieldsFromJSONObject(JSONObject json, Object d) {
loadFieldsFromJSONObject(this, json, d);
}
@SuppressWarnings({"rawtypes", "unchecked"})
public static void loadFieldsFromJSONObject(Object thiz, JSONObject json, Object d) {
if (d == null) {
@ -234,14 +234,6 @@ public class JsonLoader {
}
}
public void copyFrom(JsonLoader o) {
try {
loadFieldsFromJSONObject(toJSONObject(o, null), o);
} catch (Exception e) {
e.printStackTrace();
}
}
public static <T extends JsonLoader> T readObject(Class<T> cls, File from) {
T instance;
try {
@ -270,6 +262,18 @@ public class JsonLoader {
}
}
public void loadFieldsFromJSONObject(JSONObject json, Object d) {
loadFieldsFromJSONObject(this, json, d);
}
public void copyFrom(JsonLoader o) {
try {
loadFieldsFromJSONObject(toJSONObject(o, null), o);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return JsonLoader.toJSONObject(this, null).toString();

View file

@ -3,12 +3,18 @@ package net.pierrox.lightning_launcher.data;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.os.SystemClock;
import android.util.Log;
import net.pierrox.lightning_launcher.configuration.*;
import net.pierrox.lightning_launcher.BuildConfig;
import net.pierrox.lightning_launcher.configuration.FolderConfig;
import net.pierrox.lightning_launcher.configuration.FolderConfigStylable;
import net.pierrox.lightning_launcher.configuration.ItemConfig;
import net.pierrox.lightning_launcher.configuration.ItemConfigStylable;
import net.pierrox.lightning_launcher.configuration.JsonFields;
import net.pierrox.lightning_launcher.configuration.PageConfig;
import net.pierrox.lightning_launcher.configuration.ShortcutConfig;
import net.pierrox.lightning_launcher.configuration.ShortcutConfigStylable;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher.views.ItemLayout;
import net.pierrox.lightning_launcher.views.item.ItemView;
@ -36,74 +42,35 @@ public class Page implements Item.OnItemEventListener, ItemConfigStylable, Short
public static final int LAST_FOLDER_PAGE = 999;
public static final int USER_MENU_PAGE = 0x7fff;
public static final int MERGED_APP_DRAWER_PAGE = 0x7ffe;
public interface PageListener extends Item.OnItemEventListener{
public void onPageLoaded(Page page);
public void onPageRemoved(Page page);
public void onPagePaused(Page page);
public void onPageResumed(Page page);
public void onPageModified(Page page);
// TODO move this to engine, this is not a page specific data
public void onPageEditModeEntered(Page page);
public void onPageEditModeLeaved(Page page);
public void onPageItemLoaded(Item item);
public void onPageItemDestroyed(Item item);
public void onPageItemAdded(Item item);
public void onPageItemBeforeRemove(Item item);
public void onPageItemRemoved(Page page, Item item);
public void onPageItemChanged(Page page, Item item);
public void onPageItemZIndexChanged(Page page, int old_index, int new_index);
public void onPageFolderWindowChanged(Page page, Folder folder);
}
public static class EmptyPageListener implements PageListener {
@Override public void onPageLoaded(Page page) { }
@Override public void onPageRemoved(Page page) { }
@Override public void onPagePaused(Page page) { }
@Override public void onPageResumed(Page page) { }
@Override public void onPageModified(Page page) { }
@Override public void onPageEditModeEntered(Page page) { }
@Override public void onPageEditModeLeaved(Page page) { }
@Override public void onPageItemLoaded(Item item) { }
@Override public void onPageItemDestroyed(Item item) { }
@Override public void onPageItemAdded(Item item) { }
@Override public void onPageItemBeforeRemove(Item item) { }
@Override public void onPageItemRemoved(Page page, Item item) { }
@Override public void onPageItemChanged(Page page, Item item) { }
@Override public void onPageItemZIndexChanged(Page page, int old_index, int new_index) { }
@Override public void onPageFolderWindowChanged(Page page, Folder folder) { }
@Override public void onItemPaused(Item item) { }
@Override public void onItemResumed(Item item) { }
@Override public void onItemVisibilityChanged(Item item) { }
@Override public void onItemAlphaChanged(Item item) { }
@Override public void onItemTransformChanged(Item item, boolean fast) { }
@Override public void onItemCellChanged(Item item) { }
@Override public void onItemBindingsChanged(Item item, boolean apply) { }
@Override public void onItemError(Item item, Error error) { }
@Override public void onShortcutLabelChanged(Shortcut shortcut) { }
@Override public void onFolderPageIdChanged(Folder folder, int oldPageId) { }
}
// TODO both fields are the same
private LightningEngine mLightningEngine;
protected PageListener mListener;
private File mIconDir;
private boolean modified;
private static final String _backgroundColor = "backgroundColor";
private static final String _backgroundWallpaper = "backgroundWallpaper";
private static final String _backgroundWallpaperScroll = "backgroundWallpaperScroll";
private static final String _backgroundWallpaperTintColor = "backgroundWallpaperTintColor";
private static final String _backgroundWallpaperWidth = "backgroundWallpaperWidth";
private static final String _backgroundWallpaperHeight = "backgroundWallpaperHeight";
private static final String _gridColumnMode = "gridColumnMode";
private static final String _gridColumnNum = "gridColumnNum";
private static final String _gridColumnSize = "gridColumnSize";
private static final String _gridRowMode = "gridRowMode";
private static final String _gridRowNum = "gridRowNum";
private static final String _gridRowSize = "gridRowSize";
private static final String _layoutMode = "layoutMode";
private static final String _transpBarOverlap = "transpBarOverlap";
private static final String _statusBarTransparent = "statusBarTransparent";
private static final String _navigationBarTransparent = "navigationBarTransparent";
private static final String _wrap = "wrap";
private final File mIconDir;
public int id;
public PageConfig config;
public ArrayList<Item> items;
protected PageListener mListener;
// TODO both fields are the same
private LightningEngine mLightningEngine;
private boolean modified;
private float mCurrentViewCellWidth;
private float mCurrentViewCellHeight;
private int mResumeCount;
private boolean mIsBeingRemoved; // prevent endless recursion
public Page(LightningEngine lightningEngine, int id) {
mLightningEngine = lightningEngine;
@ -112,36 +79,104 @@ public class Page implements Item.OnItemEventListener, ItemConfigStylable, Short
mIconDir = getIconDir(mLightningEngine.getBaseDir(), id);
}
@Override
public String toString() {
return "Page:"+id+" ("+hashCode()+")";
}
public static boolean isDashboard(int p) {
return p >= FIRST_DASHBOARD_PAGE && p <= LAST_DASHBOARD_PAGE;
}
public boolean isDashboard() {
return isDashboard(id);
}
public static boolean isFolder(int p) {
return (p >= FIRST_FOLDER_PAGE && p <= LAST_FOLDER_PAGE) || p == USER_MENU_PAGE;
}
public static int composeItemId(int page, int item_id) {
return page << 16 | (item_id & 0xffff);
}
public static int getBaseItemId(int item_id) {
return item_id & 0xffff;
}
public static boolean exists(File base_dir, int id) {
return getPageDir(base_dir, id).exists();
}
// static versions
// TODO: remove when possible
public static File getPageDir(File base_dir, int id) {
return new File(FileUtils.getPagesDir(base_dir), String.valueOf(id));
}
public static File getIconDir(File base_dir, int id) {
return new File(getPageDir(base_dir, id), "icon");
}
public static File getAndCreateIconDir(File base_dir, int id) {
File icon_dir = getIconDir(base_dir, id);
if (!icon_dir.exists()) {
icon_dir.mkdirs();
}
return icon_dir;
}
// TODO: remove when possible, or move to PageManager
public static File getItemsFile(File base_dir, int id) {
return new File(getPageDir(base_dir, id), "items");
}
public static File getPageIconFile(File base_dir, int id) {
return new File(getPageDir(base_dir, id), "i");
}
public static File getWallpaperFile(File base_dir, int id) {
return new File(getPageDir(base_dir, id), "wp");
}
public static File getPageConfigFile(File base_dir, int id) {
return new File(getPageDir(base_dir, id), "conf");
}
// TODO: move this into PageManager
public static int reservePage(File base_dir, boolean folder) {
int start, end;
if (folder) {
start = FIRST_FOLDER_PAGE;
end = LAST_FOLDER_PAGE;
} else {
start = FIRST_DASHBOARD_PAGE;
end = LAST_DASHBOARD_PAGE;
}
for (int i = start; i <= end; i++) {
File page_dir = getPageDir(base_dir, i);
if (!page_dir.exists()) {
page_dir.mkdirs();
return i;
}
}
return NONE;
}
@Override
public String toString() {
return "Page:" + id + " (" + hashCode() + ")";
}
public boolean isDashboard() {
return isDashboard(id);
}
public boolean isFolder() {
return isFolder(id);
}
public LightningEngine getEngine() {
return mLightningEngine;
}
public void setEngine(LightningEngine lightningEngine) {
mLightningEngine = lightningEngine;
}
public LightningEngine getEngine() {
return mLightningEngine;
}
public void pause() {
mResumeCount--;
// Log.i("XXX", "pause page "+id+" "+mResumeCount);
@ -210,7 +245,6 @@ public class Page implements Item.OnItemEventListener, ItemConfigStylable, Short
}
}
private boolean mIsBeingRemoved; // prevent endless recursion
public void remove() {
if (!mIsBeingRemoved) {
mIsBeingRemoved = true;
@ -248,14 +282,6 @@ public class Page implements Item.OnItemEventListener, ItemConfigStylable, Short
}
}
public static int composeItemId(int page, int item_id) {
return page<<16 | (item_id&0xffff);
}
public static int getBaseItemId(int item_id) {
return item_id&0xffff;
}
public int findFreeItemId() {
// linked with Utils.getPageForItemId
int max = 0;
@ -300,65 +326,9 @@ public class Page implements Item.OnItemEventListener, ItemConfigStylable, Short
return getAndCreateIconDir(mLightningEngine.getBaseDir(), id);
}
public static boolean exists(File base_dir, int id) {
return getPageDir(base_dir, id).exists();
}
// static versions
// TODO: remove when possible
public static File getPageDir(File base_dir, int id) {
return new File(FileUtils.getPagesDir(base_dir), String.valueOf(id));
}
public static File getIconDir(File base_dir, int id) {
return new File(getPageDir(base_dir, id), "icon");
}
public static File getAndCreateIconDir(File base_dir, int id) {
File icon_dir = getIconDir(base_dir, id);
if(!icon_dir.exists()) {
icon_dir.mkdirs();
}
return icon_dir;
}
// TODO: remove when possible, or move to PageManager
public static File getItemsFile(File base_dir, int id) {
return new File(getPageDir(base_dir, id), "items");
}
public static File getPageIconFile(File base_dir, int id) {
return new File(getPageDir(base_dir, id), "i");
}
public static File getWallpaperFile(File base_dir, int id) {
return new File(getPageDir(base_dir, id), "wp");
}
public static File getPageConfigFile(File base_dir, int id) {
return new File(getPageDir(base_dir, id), "conf");
}
// TODO: move this into PageManager
public static int reservePage(File base_dir, boolean folder) {
int start, end;
if(folder) {
start = FIRST_FOLDER_PAGE;
end = LAST_FOLDER_PAGE;
} else {
start = FIRST_DASHBOARD_PAGE;
end = LAST_DASHBOARD_PAGE;
}
for(int i=start; i<=end; i++) {
File page_dir=getPageDir(base_dir, i);
if(!page_dir.exists()) {
page_dir.mkdirs();
return i;
}
}
return NONE;
@Override
public ItemConfig getItemConfig() {
return config.defaultItemConfig;
}
@Override
@ -366,11 +336,6 @@ public class Page implements Item.OnItemEventListener, ItemConfigStylable, Short
config.defaultItemConfig = c;
}
@Override
public ItemConfig getItemConfig() {
return config.defaultItemConfig;
}
@Override
public ItemConfig modifyItemConfig() {
return config.defaultItemConfig;
@ -406,7 +371,6 @@ public class Page implements Item.OnItemEventListener, ItemConfigStylable, Short
return config.defaultFolderConfig;
}
@Override
public void onItemPaused(Item item) {
mListener.onItemPaused(item);
@ -565,24 +529,6 @@ public class Page implements Item.OnItemEventListener, ItemConfigStylable, Short
notifyModified();
}
private static final String _backgroundColor = "backgroundColor";
private static final String _backgroundWallpaper = "backgroundWallpaper";
private static final String _backgroundWallpaperScroll = "backgroundWallpaperScroll";
private static final String _backgroundWallpaperTintColor = "backgroundWallpaperTintColor";
private static final String _backgroundWallpaperWidth = "backgroundWallpaperWidth";
private static final String _backgroundWallpaperHeight = "backgroundWallpaperHeight";
private static final String _gridColumnMode = "gridColumnMode";
private static final String _gridColumnNum = "gridColumnNum";
private static final String _gridColumnSize = "gridColumnSize";
private static final String _gridRowMode = "gridRowMode";
private static final String _gridRowNum = "gridRowNum";
private static final String _gridRowSize = "gridRowSize";
private static final String _layoutMode = "layoutMode";
private static final String _transpBarOverlap = "transpBarOverlap";
private static final String _statusBarTransparent = "statusBarTransparent";
private static final String _navigationBarTransparent = "navigationBarTransparent";
private static final String _wrap = "wrap";
private void loadConfig() {
File json_file = getPageConfigFile();
JSONObject json = FileUtils.readJSONObjectFromFile(json_file);
@ -751,7 +697,10 @@ public class Page implements Item.OnItemEventListener, ItemConfigStylable, Short
} catch (Throwable e) {
e.printStackTrace();
} finally {
if(os != null) try { os.close(); } catch(IOException e) {}
if (os != null) try {
os.close();
} catch (IOException e) {
}
}
}
}
@ -766,4 +715,139 @@ public class Page implements Item.OnItemEventListener, ItemConfigStylable, Short
}
//Log.i("LL", "saveItems in "+(SystemClock.uptimeMillis()-t1));
}
public interface PageListener extends Item.OnItemEventListener {
void onPageLoaded(Page page);
void onPageRemoved(Page page);
void onPagePaused(Page page);
void onPageResumed(Page page);
void onPageModified(Page page);
// TODO move this to engine, this is not a page specific data
void onPageEditModeEntered(Page page);
void onPageEditModeLeaved(Page page);
void onPageItemLoaded(Item item);
void onPageItemDestroyed(Item item);
void onPageItemAdded(Item item);
void onPageItemBeforeRemove(Item item);
void onPageItemRemoved(Page page, Item item);
void onPageItemChanged(Page page, Item item);
void onPageItemZIndexChanged(Page page, int old_index, int new_index);
void onPageFolderWindowChanged(Page page, Folder folder);
}
public static class EmptyPageListener implements PageListener {
@Override
public void onPageLoaded(Page page) {
}
@Override
public void onPageRemoved(Page page) {
}
@Override
public void onPagePaused(Page page) {
}
@Override
public void onPageResumed(Page page) {
}
@Override
public void onPageModified(Page page) {
}
@Override
public void onPageEditModeEntered(Page page) {
}
@Override
public void onPageEditModeLeaved(Page page) {
}
@Override
public void onPageItemLoaded(Item item) {
}
@Override
public void onPageItemDestroyed(Item item) {
}
@Override
public void onPageItemAdded(Item item) {
}
@Override
public void onPageItemBeforeRemove(Item item) {
}
@Override
public void onPageItemRemoved(Page page, Item item) {
}
@Override
public void onPageItemChanged(Page page, Item item) {
}
@Override
public void onPageItemZIndexChanged(Page page, int old_index, int new_index) {
}
@Override
public void onPageFolderWindowChanged(Page page, Folder folder) {
}
@Override
public void onItemPaused(Item item) {
}
@Override
public void onItemResumed(Item item) {
}
@Override
public void onItemVisibilityChanged(Item item) {
}
@Override
public void onItemAlphaChanged(Item item) {
}
@Override
public void onItemTransformChanged(Item item, boolean fast) {
}
@Override
public void onItemCellChanged(Item item) {
}
@Override
public void onItemBindingsChanged(Item item, boolean apply) {
}
@Override
public void onItemError(Item item, Error error) {
}
@Override
public void onShortcutLabelChanged(Shortcut shortcut) {
}
@Override
public void onFolderPageIdChanged(Folder folder, int oldPageId) {
}
}
}

View file

@ -24,10 +24,10 @@ import java.io.IOException;
import java.util.ArrayList;
public class PageProcessor {
private ComponentName drawer_from;
private ComponentName drawer_to;
private String pkg_name_from;
private String pkg_name_to;
private final ComponentName drawer_from;
private final ComponentName drawer_to;
private final String pkg_name_from;
private final String pkg_name_to;
private boolean do_scale;
private float sx;

View file

@ -18,13 +18,13 @@ import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.Drawable;
import net.pierrox.android.lsvg.SvgDrawable;
import net.pierrox.lightning_launcher.configuration.JsonFields;
import net.pierrox.lightning_launcher.configuration.ShortcutConfig;
import net.pierrox.lightning_launcher.configuration.ShortcutConfigStylable;
import net.pierrox.lightning_launcher.util.AnimationDecoder;
import net.pierrox.lightning_launcher.views.Graphics;
import net.pierrox.lightning_launcher.views.SharedAsyncGraphicsDrawable;
import net.pierrox.android.lsvg.SvgDrawable;
import net.pierrox.lightning_launcher.views.item.ItemView;
import net.pierrox.lightning_launcher.views.item.ShortcutView;
@ -42,28 +42,30 @@ public class Shortcut extends Item implements ShortcutConfigStylable, SharedAsyn
public static final String INTENT_EXTRA_APP_SHORTCUT_ID = "id";
public static final String INTENT_EXTRA_APP_SHORTCUT_PKG = "pkg";
public static final String INTENT_EXTRA_APP_SHORTCUT_DISABLED_MSG = "dis_msg";
private String mLabel;
private Intent mIntent;
private static final int[] mTmpSize = new int[2];
protected ShortcutConfig mShortcutConfig;
protected boolean mSharedShortcutConfig;
private String mLabel;
private Intent mIntent;
private SharedAsyncGraphicsDrawable mSharedAsyncGraphicsDrawable;
private Matrix mNormalizationMatrix;
public Shortcut(Page page) {
super(page);
}
public String getLabel() {
return mLabel;
}
public void setLabel(String label) {
mLabel = label;
mPage.setModified();
mPage.onShortcutLabelChanged(this);
}
public String getLabel() {
return mLabel;
public Intent getIntent() {
return mIntent;
}
public void setIntent(Intent intent) {
@ -71,10 +73,6 @@ public class Shortcut extends Item implements ShortcutConfigStylable, SharedAsyn
mPage.setModified();
}
public Intent getIntent() {
return mIntent;
}
public boolean hasSharedShortcutConfig() {
return mSharedShortcutConfig;
}
@ -117,8 +115,6 @@ public class Shortcut extends Item implements ShortcutConfigStylable, SharedAsyn
ShortcutConfig.getIconMaskFile(icon_dir, mId).delete();
}
@Override
public void createFromJSONObject(JSONObject o) throws JSONException {
readItemFromJSONObject(o);
@ -337,7 +333,6 @@ public class Shortcut extends Item implements ShortcutConfigStylable, SharedAsyn
return t && l && b && r ? null : box;
}
private static int[] mTmpSize = new int[2];
private int[] getComposedImageSize(Bitmap baseBitmap, int maxWidth, int maxHeight) {
int width, height;
switch (mShortcutConfig.iconSizeMode) {
@ -498,7 +493,6 @@ public class Shortcut extends Item implements ShortcutConfigStylable, SharedAsyn
}
Canvas canvas = new Canvas(finalIcon);
Paint paint = new Paint();

View file

@ -51,6 +51,7 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;
import net.pierrox.android.lsvg.SvgDrawable;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.R;
import net.pierrox.lightning_launcher.Version;
@ -72,7 +73,6 @@ import net.pierrox.lightning_launcher.views.BoxLayout;
import net.pierrox.lightning_launcher.views.Graphics;
import net.pierrox.lightning_launcher.views.ItemLayout;
import net.pierrox.lightning_launcher.views.SharedAsyncGraphicsDrawable;
import net.pierrox.android.lsvg.SvgDrawable;
import net.pierrox.lightning_launcher.views.item.ItemView;
import net.pierrox.lightning_launcher.views.item.StopPointView;
@ -115,23 +115,48 @@ public class Utils {
public static final int LAYOUT_MODE_LAST = LAYOUT_MODE_RUNNING;
public static final Collator sItemNameCollator = Collator.getInstance(Locale.getDefault());
static {
sItemNameCollator.setStrength(Collator.PRIMARY);
try {
sGetDrawableForDensity=Resources.class.getMethod("getDrawableForDensity", int.class, int.class);
} catch (NoSuchMethodException e) {
// API level 15
public static final Comparator<Item> sItemComparatorByNameAsc = new Comparator<Item>() {
@Override
public int compare(Item arg0, Item arg1) {
return compareItemName(arg0, arg1, 1);
}
};
public static final Comparator<Item> sItemComparatorByNameDesc = new Comparator<Item>() {
@Override
public int compare(Item arg0, Item arg1) {
return compareItemName(arg0, arg1, -1);
}
private static int sStandardIconSize;
private static int sLauncherIconDensity;
public static Method sGetDrawableForDensity;
private static Bitmap sDefaultIcon;
private static Rect sTmpRect1=new Rect();
};
public static final Comparator<Item> sItemComparatorByLaunchCount = new Comparator<Item>() {
@Override
public int compare(Item arg0, Item arg1) {
if (arg0.mLaunchCount > arg1.mLaunchCount) return -1;
if (arg0.mLaunchCount < arg1.mLaunchCount) return 1;
Class<?> c0 = arg0.getClass();
if (c0 != Shortcut.class && c0 != Folder.class) return -1;
Class<?> c1 = arg1.getClass();
if (c1 != Shortcut.class && c1 != Folder.class) return 1;
Shortcut s0 = (Shortcut) arg0;
Shortcut s1 = (Shortcut) arg1;
return s0.getLabel().compareToIgnoreCase(s1.getLabel());
}
};
public static final Comparator<Item> sItemComparatorByLastUpdateTime = new Comparator<Item>() {
@Override
public int compare(Item arg0, Item arg1) {
if (arg0.mLastUpdateTime > arg1.mLastUpdateTime) return -1;
if (arg0.mLastUpdateTime < arg1.mLastUpdateTime) return 1;
Class<?> c0 = arg0.getClass();
if (c0 != Shortcut.class && c0 != Folder.class) return -1;
Class<?> c1 = arg1.getClass();
if (c1 != Shortcut.class && c1 != Folder.class) return 1;
Shortcut s0 = (Shortcut) arg0;
Shortcut s1 = (Shortcut) arg1;
return s0.getLabel().compareToIgnoreCase(s1.getLabel());
}
};
public static final String INTENT_EXTRA_ITEM_ID = "i";
public static final int POSITION_AUTO = Integer.MIN_VALUE;
// public static int getNextDashboardPage(int p, int direction) {
// int o=p/ORIENTATION_SHIFT;
@ -148,6 +173,33 @@ public class Utils {
// public static int getPageForOrientation(int p, int degrees) {
// return p%ORIENTATION_SHIFT + ORIENTATION_SHIFT*degrees;
// }
public static final int APP_THEME = 0;
public static final int APP_THEME_TRANSLUCENT = 1;
public static final int APP_THEME_NO_ACTION_BAR = 2;
public static final int APP_THEME_NO_ACTION_BAR_WALLPAPER = 3;
private static final Rect sTmpRect1 = new Rect();
private static final float DYNAMIC_FOLDER_BG_MARGIN = 0.03125f;
private static final Matrix sTempMatrix = new Matrix();
private static final RectF sTempRectF = new RectF();
private static final int[] sThemes = new int[]{
R.style.AppLight, R.style.AppDark,
R.style.AppLightTranslucent, R.style.AppDarkTranslucent,
R.style.AppLightNoActionBar, R.style.AppDarkNoActionBar,
R.style.AppLightNoActionBarWallpaper, R.style.AppDarkNoActionBarWallpaper,
};
public static Method sGetDrawableForDensity;
private static int sStandardIconSize;
private static int sLauncherIconDensity;
private static Bitmap sDefaultIcon;
static {
sItemNameCollator.setStrength(Collator.PRIMARY);
try {
sGetDrawableForDensity = Resources.class.getMethod("getDrawableForDensity", int.class, int.class);
} catch (NoSuchMethodException e) {
// API level 15
}
}
public static int getPageForItemId(int item_id) {
// linked with SetupUtils.findFreeItemId
@ -159,13 +211,6 @@ public class Utils {
return getPageForItemId(item.getId());
}
public static final Comparator<Item> sItemComparatorByNameAsc =new Comparator<Item>() {
@Override
public int compare(Item arg0, Item arg1) {
return compareItemName(arg0, arg1, 1);
}
};
private static int compareItemName(Item arg0, Item arg1, int sign) {
Class<?> c0 = arg0.getClass();
if (c0 != Shortcut.class && c0 != Folder.class) return -1;
@ -186,43 +231,6 @@ public class Utils {
}
public static final Comparator<Item> sItemComparatorByNameDesc=new Comparator<Item>() {
@Override
public int compare(Item arg0, Item arg1) {
return compareItemName(arg0, arg1, -1);
}
};
public static final Comparator<Item> sItemComparatorByLaunchCount=new Comparator<Item>() {
@Override
public int compare(Item arg0, Item arg1) {
if(arg0.mLaunchCount>arg1.mLaunchCount) return -1;
if(arg0.mLaunchCount<arg1.mLaunchCount) return 1;
Class<?> c0=arg0.getClass();
if(c0!=Shortcut.class && c0!=Folder.class) return -1;
Class<?> c1=arg1.getClass();
if(c1!=Shortcut.class && c1!=Folder.class) return 1;
Shortcut s0=(Shortcut)arg0;
Shortcut s1=(Shortcut)arg1;
return s0.getLabel().compareToIgnoreCase(s1.getLabel());
}
};
public static final Comparator<Item> sItemComparatorByLastUpdateTime=new Comparator<Item>() {
@Override
public int compare(Item arg0, Item arg1) {
if(arg0.mLastUpdateTime>arg1.mLastUpdateTime) return -1;
if(arg0.mLastUpdateTime<arg1.mLastUpdateTime) return 1;
Class<?> c0=arg0.getClass();
if(c0!=Shortcut.class && c0!=Folder.class) return -1;
Class<?> c1=arg1.getClass();
if(c1!=Shortcut.class && c1!=Folder.class) return 1;
Shortcut s0=(Shortcut)arg0;
Shortcut s1=(Shortcut)arg1;
return s0.getLabel().compareToIgnoreCase(s1.getLabel());
}
};
public static void sortScripts(List<Script> scripts) {
Collections.sort(scripts, new Comparator<Script>() {
@Override
@ -373,8 +381,14 @@ public class Utils {
to.delete();
throw e;
} finally {
if(fis!=null) try { fis.close(); } catch(Exception e) {}
if(fos!=null) try { fos.close(); } catch(Exception e) {}
if (fis != null) try {
fis.close();
} catch (Exception e) {
}
if (fos != null) try {
fos.close();
} catch (Exception e) {
}
}
}
@ -430,7 +444,6 @@ public class Utils {
return sDefaultIcon;
}
public static ArrayList<Item> loadAppDrawerShortcuts(Page appDrawerPage) {
long now = System.currentTimeMillis();
@ -665,7 +678,10 @@ public class Utils {
} catch (Exception e) {
icon_file.delete();
} finally {
if(fos!=null) try { fos.close(); } catch(Exception e) {}
if (fos != null) try {
fos.close();
} catch (Exception e) {
}
}
}
@ -913,7 +929,10 @@ public class Utils {
file.delete();
return false;
} finally {
if(fos != null) try { fos.close(); } catch (IOException e) {}
if (fos != null) try {
fos.close();
} catch (IOException e) {
}
}
}
@ -933,7 +952,10 @@ public class Utils {
} catch (IOException e) {
return false;
} finally {
if(fis != null) try { fis.close(); } catch(IOException e) {}
if (fis != null) try {
fis.close();
} catch (IOException e) {
}
}
}
@ -948,7 +970,10 @@ public class Utils {
} catch (IOException e) {
return false;
} finally {
if(fis != null) try { fis.close(); } catch(IOException e) {}
if (fis != null) try {
fis.close();
} catch (IOException e) {
}
}
}
@ -1019,13 +1044,6 @@ public class Utils {
return eventAction;
}
public static final class ShortcutDescription {
public String name;
public Bitmap icon;
public Intent intent;
}
public static ShortcutDescription createShortcutFromIntent(Context context, Intent data, int max_icon_size) {
// this comes from Launcher2
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
@ -1133,7 +1151,18 @@ public class Utils {
}
}
private static final float DYNAMIC_FOLDER_BG_MARGIN=0.03125f;
/*public static int findRootPage(Page page) {
if(page.isFolder() && page.id != Page.USER_MENU_PAGE) {
Folder f = page.findFirstOpener();
if(f != null) {
return findRootPage(f.getPage());
} else {
return Page.FIRST_DASHBOARD_PAGE;
}
} else {
return page.id;
}
}*/
private static void buildDynamicFolderBackground(Canvas canvas, int icon_width, int icon_height) {
canvas.drawARGB(0, 0, 0, 0);
@ -1208,8 +1237,9 @@ public class Utils {
final float ch = folder_page.getCurrentViewCellHeight();
Collections.sort(folder_items, new Comparator<Item>() {
private float[] pos_l=new float[2];
private float[] pos_r=new float[2];
private final float[] pos_l = new float[2];
private final float[] pos_r = new float[2];
@Override
public int compare(Item lhs, Item rhs) {
if (lhs.getItemConfig().onGrid) {
@ -1358,9 +1388,14 @@ public class Utils {
//bitmap_paint.setAlpha(170);
float scale;
switch (n) {
case 2 : scale=0.7f; break;
case 3 : scale=0.6f; break;
default: scale=0.5f;
case 2:
scale = 0.7f;
break;
case 3:
scale = 0.6f;
break;
default:
scale = 0.5f;
}
final float dx = -(icon_width - mw * 2 - icon_width * scale) / (n - 1);
@ -1461,19 +1496,6 @@ public class Utils {
return b;
}
/*public static int findRootPage(Page page) {
if(page.isFolder() && page.id != Page.USER_MENU_PAGE) {
Folder f = page.findFirstOpener();
if(f != null) {
return findRootPage(f.getPage());
} else {
return Page.FIRST_DASHBOARD_PAGE;
}
} else {
return page.id;
}
}*/
public static String getPackageNameForItem(Item item) {
String pkg = null;
ComponentName cn = null;
@ -1516,10 +1538,6 @@ public class Utils {
}
}
public static final String INTENT_EXTRA_ITEM_ID="i";
public static Item cloneItem(Item from) {
Page page = from.getPage();
@ -1561,7 +1579,6 @@ public class Utils {
}
}
public static Shortcut copyShortcut(Item shortcut, Page pageTo, int x, int y, float scale) {
Page pageFrom = shortcut.getPage();
@ -1987,7 +2004,6 @@ public class Utils {
item.setItemConfig(ic);
}
public static final int POSITION_AUTO = Integer.MIN_VALUE;
public static void setItemPosition(Page page, Item item, float x, float y, float scale, boolean center) {
int w, h;
if (item.getItemConfig().onGrid) {
@ -2093,10 +2109,6 @@ public class Utils {
}
}
public interface OnTextInputDialogDone {
public void onTextInputDone(String value);
}
public static Dialog createTextInputDialog(Context context, int message_res, String value, final OnTextInputDialogDone listener) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(message_res);
@ -2121,11 +2133,6 @@ public class Utils {
return builder.create();
}
public interface OnFolderSelectionDialogDone {
void onFolderSelected(String name, int page);
void onNoFolderSelected();
}
public static Dialog createFolderSelectionDialog(Context context, LightningEngine engine, final OnFolderSelectionDialogDone listener) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
final ArrayList<String> folders_name = new ArrayList<String>();
@ -2185,15 +2192,13 @@ public class Utils {
}
}
private static Matrix sTempMatrix = new Matrix();
private static RectF sTempRectF = new RectF();
public static float getRotateForMatrix(Matrix from) {
sTempMatrix.set(from);
float[] point = new float[]{0, 0};
sTempMatrix.mapPoints(point);
sTempMatrix.postTranslate(-point[0], -point[1]);
point[0] = 1; point[1] = 0;
point[0] = 1;
point[1] = 0;
sTempMatrix.mapPoints(point);
return (float) (Math.atan2(point[1], point[0]) * 180 / Math.PI);
}
@ -2205,7 +2210,8 @@ public class Utils {
sTempMatrix.postRotate(-rotate);
sTempMatrix.mapPoints(point);
sTempMatrix.postTranslate(-point[0], -point[1]);
point[0] = 1; point[1] = 1;
point[0] = 1;
point[1] = 1;
sTempMatrix.mapPoints(point);
return point[x ? 0 : 1];
}
@ -2423,18 +2429,6 @@ public class Utils {
return 0;
}
public static final int APP_THEME = 0;
public static final int APP_THEME_TRANSLUCENT = 1;
public static final int APP_THEME_NO_ACTION_BAR = 2;
public static final int APP_THEME_NO_ACTION_BAR_WALLPAPER = 3;
private static int[] sThemes = new int[] {
R.style.AppLight, R.style.AppDark,
R.style.AppLightTranslucent, R.style.AppDarkTranslucent,
R.style.AppLightNoActionBar, R.style.AppDarkNoActionBar,
R.style.AppLightNoActionBarWallpaper, R.style.AppDarkNoActionBarWallpaper,
};
public static void setTheme(Context context, int theme) {
boolean is_light = LLApp.get().getSystemConfig().appStyle == SystemConfig.AppStyle.LIGHT;
int style = sThemes[theme * 2 + (is_light ? 0 : 1)];
@ -2453,8 +2447,14 @@ public class Utils {
os.write(buffer, 0, n);
}
} catch (Exception e) {
if(is!=null) try { is.close(); } catch(Exception e1) {}
if(os!=null) try { os.close(); } catch(Exception e1) {}
if (is != null) try {
is.close();
} catch (Exception e1) {
}
if (os != null) try {
os.close();
} catch (Exception e1) {
}
}
}
@ -2520,4 +2520,20 @@ public class Utils {
}
return text;
}
public interface OnTextInputDialogDone {
void onTextInputDone(String value);
}
public interface OnFolderSelectionDialogDone {
void onFolderSelected(String name, int page);
void onNoFolderSelected();
}
public static final class ShortcutDescription {
public String name;
public Bitmap icon;
public Intent intent;
}
}

View file

@ -5,7 +5,7 @@ import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.*;
import android.graphics.Rect;
import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.configuration.JsonFields;
@ -29,6 +29,23 @@ public class Widget extends Item {
super(page);
}
public static Widget createStatic(Page page, int id, Rect cell_p, Rect cell_l, ComponentName cn, int app_widget_id) {
Widget widget = new Widget(page);
widget.init(id, cell_p, cell_l);
widget.mComponentName = cn;
widget.mAppWidgetId = app_widget_id;
if (app_widget_id != NO_APP_WIDGET_ID) {
AppWidgetProviderInfo app_widget_info = AppWidgetManager.getInstance(LLApp.get()).getAppWidgetInfo(app_widget_id);
if (app_widget_info != null) {
widget.mAppWidgetLabel = app_widget_info.label;
}
}
return widget;
}
protected void copyTo(Item item) {
super.copyTo(item);
Widget w = (Widget) item;
@ -51,14 +68,14 @@ public class Widget extends Item {
mAppWidgetId = id;
}
public void setAppWidgetLabel(String label) {
mAppWidgetLabel = label;
}
public String getAppWidgetLabel() {
return mAppWidgetLabel;
}
public void setAppWidgetLabel(String label) {
mAppWidgetLabel = label;
}
public ComponentName getComponentName() {
return mComponentName;
}
@ -70,11 +87,7 @@ public class Widget extends Item {
public boolean hasConfigurationScreen() {
AppWidgetManager app_widget_manager = AppWidgetManager.getInstance(LLApp.get());
AppWidgetProviderInfo app_widget_info = app_widget_manager.getAppWidgetInfo(mAppWidgetId);
if (app_widget_info!=null && app_widget_info.configure != null) {
return true;
} else {
return false;
}
return app_widget_info != null && app_widget_info.configure != null;
}
public void onConfigure(Context context) {
@ -113,23 +126,6 @@ public class Widget extends Item {
mAppWidgetLabel = o.optString(JsonFields.WIDGET_LABEL, null);
}
public static Widget createStatic(Page page, int id, Rect cell_p, Rect cell_l, ComponentName cn, int app_widget_id) {
Widget widget=new Widget(page);
widget.init(id, cell_p, cell_l);
widget.mComponentName=cn;
widget.mAppWidgetId=app_widget_id;
if(app_widget_id != NO_APP_WIDGET_ID) {
AppWidgetProviderInfo app_widget_info = AppWidgetManager.getInstance(LLApp.get()).getAppWidgetInfo(app_widget_id);
if(app_widget_info != null) {
widget.mAppWidgetLabel = app_widget_info.label;
}
}
return widget;
}
@Override
public ItemView createView(Context context) {
return new WidgetView(context, this);

View file

@ -41,35 +41,42 @@ import java.util.Iterator;
import java.util.List;
public class LightningEngine implements Page.PageListener {
public interface GlobalConfigListener {
void onGlobalConfigChanged(GlobalConfig newGlobalConfig);
}
private static final int GLOBAL_CONFIG_FILE_VERSION = 7;
/************************************** ANDROID 7.1 APP SHORTCUTS *************************************/
private static final String TOKEN_PIN_COUNT = "pinCount";
private final File mBaseDir;
private final PageManager mPageManager;
private final ScriptManager mScriptManager;
private final ScriptExecutor mScriptExecutor;
private final VariableManager mVariableManager;
private final BuiltinDataCollectors mBuiltinDataCollectors;
private final ArrayList<GlobalConfigListener> mGlobalConfigListeners = new ArrayList<>();
private final ArrayList<Page.PageListener> mPageListeners = new ArrayList<>();
private final Handler mHandler;
protected Context mContext;
private File mBaseDir;
private PageManager mPageManager;
private ScriptManager mScriptManager;
private ScriptExecutor mScriptExecutor;
private VariableManager mVariableManager;
private BuiltinDataCollectors mBuiltinDataCollectors;
private GlobalConfig mGlobalConfig;
private ArrayList<GlobalConfigListener> mGlobalConfigListeners = new ArrayList<>();
private ArrayList<Page.PageListener> mPageListeners = new ArrayList<>();
private Handler mHandler;
private int mResumedPagesCount;
private JSONObject mLaunchStatistics;
private JSONObject mAppShortcuts;
/***************************************** SAVE DATA ***********************************/
private final Runnable mSaveDataRunnable = new Runnable() {
@Override
public void run() {
mVariableManager.saveValues();
saveGlobalConfig();
saveLaunchStatistics();
saveAppShortcuts();
mPageManager.savePagesSync();
}
};
public LightningEngine(Context context, File baseDir) {
mContext = context;
@ -105,7 +112,6 @@ public class LightningEngine implements Page.PageListener {
}
/**
*
* @return true if upgrade of old free version
*/
public void migrate() {
@ -226,7 +232,6 @@ public class LightningEngine implements Page.PageListener {
return mGlobalConfig.runScripts;
}
@Override
public void onPageModified(Page page) {
Utils.updateContainerIconIfNeeded(page);
@ -299,7 +304,8 @@ public class LightningEngine implements Page.PageListener {
@Override
public void onPageItemZIndexChanged(Page page, int old_index, int new_index) {
Utils.updateContainerIconIfNeeded(page);
for (Page.PageListener listener : mPageListeners) listener.onPageItemZIndexChanged(page, old_index, new_index);
for (Page.PageListener listener : mPageListeners)
listener.onPageItemZIndexChanged(page, old_index, new_index);
}
@Override
@ -324,7 +330,8 @@ public class LightningEngine implements Page.PageListener {
@Override
public void onPageFolderWindowChanged(Page page, Folder folder) {
for (Page.PageListener listener : mPageListeners) listener.onPageFolderWindowChanged(page, folder);
for (Page.PageListener listener : mPageListeners)
listener.onPageFolderWindowChanged(page, folder);
}
@Override
@ -363,7 +370,8 @@ public class LightningEngine implements Page.PageListener {
@Override
public void onItemTransformChanged(Item item, boolean fast) {
for (Page.PageListener listener : mPageListeners) listener.onItemTransformChanged(item, fast);
for (Page.PageListener listener : mPageListeners)
listener.onItemTransformChanged(item, fast);
}
@Override
@ -373,7 +381,8 @@ public class LightningEngine implements Page.PageListener {
@Override
public void onItemBindingsChanged(Item item, boolean apply) {
for (Page.PageListener listener : mPageListeners) listener.onItemBindingsChanged(item, apply);
for (Page.PageListener listener : mPageListeners)
listener.onItemBindingsChanged(item, apply);
}
@Override
@ -389,7 +398,8 @@ public class LightningEngine implements Page.PageListener {
@Override
public void onFolderPageIdChanged(Folder folder, int oldPageId) {
Utils.updateFolderIcon(folder);
for (Page.PageListener listener : mPageListeners) listener.onFolderPageIdChanged(folder, oldPageId);
for (Page.PageListener listener : mPageListeners)
listener.onFolderPageIdChanged(folder, oldPageId);
}
@Override
@ -406,23 +416,6 @@ public class LightningEngine implements Page.PageListener {
for (Page.PageListener listener : mPageListeners) listener.onPageLoaded(page);
}
/***************************************** SAVE DATA ***********************************/
private Runnable mSaveDataRunnable = new Runnable() {
@Override
public void run() {
mVariableManager.saveValues();
saveGlobalConfig();
saveLaunchStatistics();
saveAppShortcuts();
mPageManager.savePagesSync();
}
};
public void saveData() {
cancelDelayedSaveData();
mSaveDataRunnable.run();
@ -524,7 +517,10 @@ public class LightningEngine implements Page.PageListener {
if (cn != null) {
String key = cn.flattenToShortString();
int count = mLaunchStatistics.optInt(key);
try { mLaunchStatistics.put(key, count+1); } catch (JSONException e) { }
try {
mLaunchStatistics.put(key, count + 1);
} catch (JSONException e) {
}
}
}
@ -557,10 +553,6 @@ public class LightningEngine implements Page.PageListener {
}
}
/************************************** ANDROID 7.1 APP SHORTCUTS *************************************/
private static final String TOKEN_PIN_COUNT = "pinCount";
private void pinAppShortcut(String pkg, String id) {
int pinCount = adjustAppShortcutPinCount(pkg, id, 1);
if (pinCount == 1) {
@ -642,7 +634,9 @@ public class LightningEngine implements Page.PageListener {
}
}
/** Return null if this isn't a Android 7.1 app shortcut */
/**
* Return null if this isn't a Android 7.1 app shortcut
*/
private Intent getAppShortcutIntent(Item item) {
if (item.getClass() == Shortcut.class) {
Shortcut shortcut = (Shortcut) item;
@ -760,8 +754,12 @@ public class LightningEngine implements Page.PageListener {
}
}
public interface GlobalConfigListener {
void onGlobalConfigChanged(GlobalConfig newGlobalConfig);
}
public class PageManager {
private ArrayList<Page> mPages = new ArrayList<>();
private final ArrayList<Page> mPages = new ArrayList<>();
private PageManager() {
}

View file

@ -97,22 +97,19 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
private static final String SIS_LAST_TOUCHED_Y = "sc";
private static final String SIS_LAST_TOUCHED_ITEM_ID = "sd";
private static final String SIS_LAST_TOUCHED_ITEM_IL = "se";
private final ViewGroup mFolderContainer;
private final ArrayList<FolderView> mFolderViews;
private final ArrayList<ItemLayout> mRootItemLayouts = new ArrayList<>();
private final ArrayList<ItemLayout> mItemLayouts = new ArrayList<>();
protected Context mContext;
protected SystemBarTintManager mSystemBarTintManager;
private Window mWindow;
private boolean mHasWindowFocus;
protected SystemBarTintManager mSystemBarTintManager;
private ViewGroup mContentView;
private View mDesktopView;
private WallpaperView mWallpaperView;
private ViewGroup mFolderContainer;
private ArrayList<FolderView> mFolderViews;
private int mCustomScreenWidth;
private int mCustomScreenHeight;
// currently focused container / touch position
private ItemLayout mTargetItemLayout = null;
private int mLastTouchedAddX = Utils.POSITION_AUTO;
@ -120,28 +117,25 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
private int mLastTouchedMenuX = Utils.POSITION_AUTO;
private int mLastTouchedMenuY = Utils.POSITION_AUTO;
private ItemView mLastTouchedItemView;
private boolean mItemSwipeCaught = true;
private boolean mIsResumed;
// in degrees, not Configuration.ORIENTATION_{LANDSCAPE/PORTRAIT}
private int mDisplayOrientation;
private boolean mIsPortrait;
private boolean mStatusBarHide; // as selected per configuration
private boolean mIsStatusBarHidden; // current status
private boolean mForceDisplayStatusBar; // transcient forced visibility
private int mCurrentOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
private final Runnable mApplyOrientationChangedRunnable = new Runnable() {
@Override
public void run() {
onOrientationChanged(mCurrentOrientation);
}
};
private OrientationEventListener mOrientationEventListener;
private ArrayList<ItemLayout> mRootItemLayouts = new ArrayList<>();
private ItemLayout mCurrentRootItemLayout;
private ArrayList<ItemLayout> mItemLayouts = new ArrayList<>();
private ArrayList<Error> mErrors;
private long mPreviousPositionChangeDate;
public Screen(Context context, int content_view) {
LLApp app = LLApp.get();
@ -154,8 +148,8 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
mContentView = (ViewGroup) LayoutInflater.from(context).inflate(content_view, null);
mDesktopView = mContentView.findViewById(R.id.desktop);
mWallpaperView = (WallpaperView) mContentView.findViewById(R.id.wp);
mFolderContainer = (ViewGroup) mContentView.findViewById(R.id.folder_container);
mWallpaperView = mContentView.findViewById(R.id.wp);
mFolderContainer = mContentView.findViewById(R.id.folder_container);
} else {
mFolderContainer = new FrameLayout(context);
}
@ -176,9 +170,15 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
int rotation = mWindow == null ? Surface.ROTATION_0 : mWindow.getWindowManager().getDefaultDisplay().getRotation();
switch (rotation) {
case Surface.ROTATION_90: i+=90; break;
case Surface.ROTATION_180: i+=180; break;
case Surface.ROTATION_270: i+=270; break;
case Surface.ROTATION_90:
i += 90;
break;
case Surface.ROTATION_180:
i += 180;
break;
case Surface.ROTATION_270:
i += 270;
break;
}
if (mCurrentOrientation != i) {
@ -202,6 +202,7 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
}
}
}
@Override
public void onViewDetachedFromWindow(View view) {
@ -341,6 +342,7 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
/**
* Hook for the script executor
* TODO document this, should be balanced with...
*
* @param scriptExecutor
*/
public void displayScriptPickImageDialog(ScriptExecutor scriptExecutor) {
@ -465,8 +467,6 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
}
}
@Override
public void onItemViewPressed(ItemView itemView) {
itemView.setHighlightedLater(true);
@ -631,17 +631,17 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
setLastTouchedItemAndPosition(null, il, Utils.POSITION_AUTO, Utils.POSITION_AUTO, Utils.POSITION_AUTO, Utils.POSITION_AUTO);
}
public void setTargetItemLayout(ItemLayout targetItemLayout) {
mTargetItemLayout = targetItemLayout;
}
// public Page getTargetPage() {
// return mTargetPage;
// }
public ItemLayout getTargetItemLayout() {
return mTargetItemLayout;
}
// public Page getTargetPage() {
// return mTargetPage;
// }
public void setTargetItemLayout(ItemLayout targetItemLayout) {
mTargetItemLayout = targetItemLayout;
}
// TODO rename as getLastTouchedPositionX
public int getLastTouchedAddX() {
@ -691,6 +691,7 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
/**
* Find a folder view given its opener item view
*
* @param opener the item view used to open the folder
* @param open true to look for open folder, false to look for closed folder, null to look for both
* @return
@ -708,6 +709,7 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
return null;
}
public FolderView findFolderView(ItemLayout il, boolean open) {
if (mFolderContainer == null) {
return null;
@ -776,6 +778,7 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
/**
* Open a folder with an optional item view as opener
*
* @param folder mandatory folder to open
* @param folderItemView optional item view used to open the folder
* @param from optional starting point for the animation
@ -1050,7 +1053,6 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
return rounded_bounds;
}
private void traverseViews(View v, RectF r) {
if (v == null) {
return;
@ -1079,7 +1081,6 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public float[] translateItemLayoutCoordsIntoScreenCoords(ItemLayout il, float x, float y) {
RectF r = new RectF(x, y, x, y);
@ -1139,7 +1140,6 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
return itemLayout;
}
public void executeGoToDesktopPositionIntent(Intent intent) {
int page = intent.getIntExtra(LightningIntent.INTENT_EXTRA_DESKTOP, Page.FIRST_DASHBOARD_PAGE);
if (Page.isDashboard(page) && page != getCurrentRootPage().id) {
@ -1272,6 +1272,7 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
/**
* Prepare all item layouts to display a given page, using the first path found
*
* @param page
* @return the item layout prepared for the page
*/
@ -1395,6 +1396,10 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
return result;
}
// public Page getTopmostPage() {
// return getTopmostItemLayout().getPage();
// }
public ItemView[] getItemViewsForItem(Item item) {
return getItemViewsForItem(item.getId());
}
@ -1409,9 +1414,7 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
return getCurrentRootItemLayout();
}
// public Page getTopmostPage() {
// return getTopmostItemLayout().getPage();
// }
/***************************************** BACKGROUND WALLPAPER AND COLOR ***********************************/
public ItemLayout getTargetOrTopmostItemLayout() {
if (mTargetItemLayout == null) {
@ -1443,7 +1446,6 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
return p;
}
/***************************************** BACKGROUND WALLPAPER AND COLOR ***********************************/
/**
* This is called for desktop and app drawer pages only, not folders nor panels since they have their own box options.
*/
@ -1969,19 +1971,9 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
// default is empty
}
/***************************************** UPDATE OF VIEWS REFERENCES ***********************************/
private static class ItemViewUpdate {
ItemView oldItemView;
ItemView newItemView;
net.pierrox.lightning_launcher.script.api.Item cachedItem;
ArrayList<ItemViewUpdate> children;
ItemLayout oldChildItemLayout;
ItemLayout newChildItemLayout;
Container cachedContainer;
}
/**
* Build the list of old views
*
* @param updates
* @param itemView
*/
@ -2008,6 +2000,7 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
/**
* Match old item views with new ones
*
* @param update
* @param itemView
*/
@ -2140,13 +2133,6 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
return getResourcesOrientation() == Configuration.ORIENTATION_LANDSCAPE ? 90 : 0;
}
private Runnable mApplyOrientationChangedRunnable = new Runnable() {
@Override
public void run() {
onOrientationChanged(mCurrentOrientation);
}
};
protected void onOrientationChanged(int orientation) {
for (ItemLayout il : mItemLayouts) {
il.updateItemsOrientation(orientation);
@ -2557,7 +2543,6 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
}
}
private long mPreviousPositionChangeDate;
@Override
public void onItemLayoutPositionChanged(ItemLayout il, float mCurrentDx, float mCurrentDy, float mCurrentScale) {
long now = System.currentTimeMillis();
@ -2633,4 +2618,15 @@ public abstract class Screen implements ItemLayout.ItemLayoutListener, ItemView.
public void onHandleLongClicked(HandleView.Handle h) {
}
/***************************************** UPDATE OF VIEWS REFERENCES ***********************************/
private static class ItemViewUpdate {
ItemView oldItemView;
ItemView newItemView;
net.pierrox.lightning_launcher.script.api.Item cachedItem;
ArrayList<ItemViewUpdate> children;
ItemLayout oldChildItemLayout;
ItemLayout newChildItemLayout;
Container cachedContainer;
}
}

View file

@ -15,8 +15,8 @@ import net.pierrox.lightning_launcher.R;
private static final String VAR_VOLTAGE = "bat_voltage";
private static final String VAR_PLUGGED = "bat_plugged";
private Context mContext;
private BroadcastReceiver mBatteryReceiver;
private final Context mContext;
private final BroadcastReceiver mBatteryReceiver;
/*package*/ BatteryDataCollector(Context context, final VariableManager vm) {
mContext = context;

View file

@ -12,8 +12,8 @@ public final class Binding {
}
public boolean equals(Binding other) {
if(target == null && other.target!=null || (target != null && !target.equals(other.target))) return false;
if(formula == null && other.formula!=null || (formula != null && !formula.equals(other.formula))) return false;
return true;
if (target == null && other.target != null || (target != null && !target.equals(other.target)))
return false;
return (formula != null || other.formula == null) && (formula == null || formula.equals(other.formula));
}
}

View file

@ -12,10 +12,10 @@ public class BuiltinDataCollectors {
private static final String VAR_SCREEN_WIDTH = "screen_width";
private static final String VAR_SCREEN_HEIGHT = "screen_height";
private Pair<String,BuiltinVariable[]>[] mBuiltinVariables;
private Handler mHandler;
private VariableManager mVariableManager;
private DataCollector[] mDataCollectors;
private final Pair<String, BuiltinVariable[]>[] mBuiltinVariables;
private final Handler mHandler;
private final VariableManager mVariableManager;
private final DataCollector[] mDataCollectors;
private int mResumedCount;
public BuiltinDataCollectors(Context context, VariableManager vm) {

View file

@ -11,28 +11,39 @@ import java.io.IOException;
public class CpuDataCollector extends PollingDataCollector {
// private static String VAR_COUNT = "cpu_count";
private static String VAR_USAGE = "cpu_usage";
private static String VAR_USER = "cpu_user";
private static String VAR_NICE = "cpu_nice";
private static String VAR_SYSTEM = "cpu_system";
private static String VAR_IDLE = "cpu_idle";
private static String VAR_IOWAIT = "cpu_iowait";
private static String VAR_IRQ = "cpu_irq";
private static String VAR_SOFTIRQ = "cpu_softirq";
private static class CpuUsage {
long user;
long nice;
long system;
long idle;
long iowait;
long irq;
long softirq;
long total;
}
private static final String VAR_USAGE = "cpu_usage";
private static final String VAR_USER = "cpu_user";
private static final String VAR_NICE = "cpu_nice";
private static final String VAR_SYSTEM = "cpu_system";
private static final String VAR_IDLE = "cpu_idle";
private static final String VAR_IOWAIT = "cpu_iowait";
private static final String VAR_IRQ = "cpu_irq";
private static final String VAR_SOFTIRQ = "cpu_softirq";
private CpuUsage mPreviousUsage;
private CpuUsage mCurrentUsage;
private final Runnable mSetVariablesRunnable = new Runnable() {
@Override
public void run() {
long delta = mCurrentUsage.total - mPreviousUsage.total;
if (delta != 0) {
long user = (mCurrentUsage.total - mCurrentUsage.idle) - (mPreviousUsage.total - mPreviousUsage.idle);
mVariableManager.edit();
mVariableManager.setVariable(VAR_USAGE, percent(user, delta));
mVariableManager.setVariable(VAR_USER, percent(mCurrentUsage.user - mPreviousUsage.user, delta));
mVariableManager.setVariable(VAR_NICE, percent(mCurrentUsage.nice - mPreviousUsage.nice, delta));
mVariableManager.setVariable(VAR_SYSTEM, percent(mCurrentUsage.system - mPreviousUsage.system, delta));
mVariableManager.setVariable(VAR_IDLE, percent(mCurrentUsage.idle - mPreviousUsage.idle, delta));
mVariableManager.setVariable(VAR_IOWAIT, percent(mCurrentUsage.iowait - mPreviousUsage.iowait, delta));
mVariableManager.setVariable(VAR_IRQ, percent(mCurrentUsage.irq - mPreviousUsage.irq, delta));
mVariableManager.setVariable(VAR_SOFTIRQ, percent(mCurrentUsage.softirq - mPreviousUsage.softirq, delta));
mVariableManager.commit();
CpuUsage tmp = mPreviousUsage;
mPreviousUsage = mCurrentUsage;
mCurrentUsage = tmp;
}
}
};
public CpuDataCollector(Handler handler, VariableManager vm) {
super(2500, handler, vm);
@ -42,6 +53,10 @@ public class CpuDataCollector extends PollingDataCollector {
readProcStat(mPreviousUsage);
}
private static int percent(long value, long total) {
return (int) (value * 100 / total);
}
@Override
protected void collectData() {
try {
@ -69,34 +84,6 @@ public class CpuDataCollector extends PollingDataCollector {
};
}
private Runnable mSetVariablesRunnable = new Runnable() {
@Override
public void run() {
long delta = mCurrentUsage.total - mPreviousUsage.total;
if(delta != 0) {
long user = (mCurrentUsage.total - mCurrentUsage.idle) - (mPreviousUsage.total - mPreviousUsage.idle);
mVariableManager.edit();
mVariableManager.setVariable(VAR_USAGE, percent(user, delta));
mVariableManager.setVariable(VAR_USER, percent(mCurrentUsage.user - mPreviousUsage.user, delta));
mVariableManager.setVariable(VAR_NICE, percent(mCurrentUsage.nice - mPreviousUsage.nice, delta));
mVariableManager.setVariable(VAR_SYSTEM, percent(mCurrentUsage.system - mPreviousUsage.system, delta));
mVariableManager.setVariable(VAR_IDLE, percent(mCurrentUsage.idle - mPreviousUsage.idle, delta));
mVariableManager.setVariable(VAR_IOWAIT, percent(mCurrentUsage.iowait - mPreviousUsage.iowait, delta));
mVariableManager.setVariable(VAR_IRQ, percent(mCurrentUsage.irq - mPreviousUsage.irq, delta));
mVariableManager.setVariable(VAR_SOFTIRQ, percent(mCurrentUsage.softirq - mPreviousUsage.softirq, delta));
mVariableManager.commit();
CpuUsage tmp = mPreviousUsage;
mPreviousUsage = mCurrentUsage;
mCurrentUsage = tmp;
}
}
};
private static int percent(long value, long total) {
return (int)(value*100/total);
}
private void readProcStat(CpuUsage out) {
BufferedReader br = null;
@ -115,7 +102,20 @@ public class CpuDataCollector extends PollingDataCollector {
} catch (IOException e) {
// pass
} finally {
if(br != null) try { br.close(); } catch (IOException e) { /*pass*/ }
if (br != null) try {
br.close();
} catch (IOException e) { /*pass*/ }
}
}
private static class CpuUsage {
long user;
long nice;
long system;
long idle;
long iowait;
long irq;
long softirq;
long total;
}
}

View file

@ -3,8 +3,11 @@ package net.pierrox.lightning_launcher.engine.variable;
import android.content.res.Resources;
public interface DataCollector {
public void onPause();
public void onResume();
public void end();
public BuiltinVariable[] getBuiltinVariables(Resources resources);
void onPause();
void onResume();
void end();
BuiltinVariable[] getBuiltinVariables(Resources resources);
}

View file

@ -3,7 +3,7 @@ package net.pierrox.lightning_launcher.engine.variable;
import android.os.Handler;
/*package*/ abstract class PollingDataCollector extends Thread implements DataCollector {
private int mPeriod;
private final int mPeriod;
protected Handler mHandler;
protected VariableManager mVariableManager;
private boolean mPaused;

View file

@ -21,34 +21,8 @@ import java.io.File;
private static final String VAR_INT_TOTAL_H = "int_total_h";
private static final String VAR_INT_FREE_H = "int_free_h";
private Context mContext;
public StorageDataCollector(Context context, Handler handler, VariableManager vm) {
super(10000, handler, vm);
mContext = context;
mSetVariablesRunnable.run();
}
@Override
protected void collectData() {
mHandler.post(mSetVariablesRunnable);
}
public BuiltinVariable[] getBuiltinVariables(Resources resources) {
return new BuiltinVariable[] {
new BuiltinVariable(VAR_EXT_TOTAL_H, resources.getString(R.string.bv_eth)),
new BuiltinVariable(VAR_EXT_FREE_H, resources.getString(R.string.bv_efh)),
new BuiltinVariable(VAR_INT_TOTAL_H, resources.getString(R.string.bv_ith)),
new BuiltinVariable(VAR_INT_FREE_H, resources.getString(R.string.bv_ifh)),
new BuiltinVariable(VAR_EXT_TOTAL, resources.getString(R.string.bv_et)),
new BuiltinVariable(VAR_EXT_FREE, resources.getString(R.string.bv_ef)),
new BuiltinVariable(VAR_INT_TOTAL, resources.getString(R.string.bv_it)),
new BuiltinVariable(VAR_INT_FREE, resources.getString(R.string.bv_if)),
};
}
private Runnable mSetVariablesRunnable = new Runnable() {
private final Context mContext;
private final Runnable mSetVariablesRunnable = new Runnable() {
@Override
public void run() {
long int_free;
@ -100,4 +74,29 @@ import java.io.File;
mVariableManager.commit();
}
};
public StorageDataCollector(Context context, Handler handler, VariableManager vm) {
super(10000, handler, vm);
mContext = context;
mSetVariablesRunnable.run();
}
@Override
protected void collectData() {
mHandler.post(mSetVariablesRunnable);
}
public BuiltinVariable[] getBuiltinVariables(Resources resources) {
return new BuiltinVariable[]{
new BuiltinVariable(VAR_EXT_TOTAL_H, resources.getString(R.string.bv_eth)),
new BuiltinVariable(VAR_EXT_FREE_H, resources.getString(R.string.bv_efh)),
new BuiltinVariable(VAR_INT_TOTAL_H, resources.getString(R.string.bv_ith)),
new BuiltinVariable(VAR_INT_FREE_H, resources.getString(R.string.bv_ifh)),
new BuiltinVariable(VAR_EXT_TOTAL, resources.getString(R.string.bv_et)),
new BuiltinVariable(VAR_EXT_FREE, resources.getString(R.string.bv_ef)),
new BuiltinVariable(VAR_INT_TOTAL, resources.getString(R.string.bv_it)),
new BuiltinVariable(VAR_INT_FREE, resources.getString(R.string.bv_if)),
};
}
}

View file

@ -22,19 +22,44 @@ public class TimeDataCollector extends PollingDataCollector {
private static final String VAR_DAY_NAME = "ll_day_name";
private static final String VAR_MONTH_NAME = "ll_month_name";
private SimpleDateFormat mDfSecond = new SimpleDateFormat("ss");
private SimpleDateFormat mDfMinute = new SimpleDateFormat("mm");
private SimpleDateFormat mDfHour12 = new SimpleDateFormat("hh");
private SimpleDateFormat mDfHour24 = new SimpleDateFormat("HH");
private SimpleDateFormat mDfDay = new SimpleDateFormat("dd");
private SimpleDateFormat mDfMonth = new SimpleDateFormat("MM");
private SimpleDateFormat mDfWeek = new SimpleDateFormat("w");
private SimpleDateFormat mDfYear = new SimpleDateFormat("yyyy");
private SimpleDateFormat mDfAmPm = new SimpleDateFormat("a");
private SimpleDateFormat mDfDayName = new SimpleDateFormat("EEEE");
private SimpleDateFormat mDfMonthName = new SimpleDateFormat("MMMM");
private final SimpleDateFormat mDfSecond = new SimpleDateFormat("ss");
private final SimpleDateFormat mDfMinute = new SimpleDateFormat("mm");
private final SimpleDateFormat mDfHour12 = new SimpleDateFormat("hh");
private final SimpleDateFormat mDfHour24 = new SimpleDateFormat("HH");
private final SimpleDateFormat mDfDay = new SimpleDateFormat("dd");
private final SimpleDateFormat mDfMonth = new SimpleDateFormat("MM");
private final SimpleDateFormat mDfWeek = new SimpleDateFormat("w");
private final SimpleDateFormat mDfYear = new SimpleDateFormat("yyyy");
private final SimpleDateFormat mDfAmPm = new SimpleDateFormat("a");
private final SimpleDateFormat mDfDayName = new SimpleDateFormat("EEEE");
private final SimpleDateFormat mDfMonthName = new SimpleDateFormat("MMMM");
private int mPreviousSecond = -1;
private final Runnable mSetVariablesRunnable = new Runnable() {
@Override
public void run() {
// text fields, but some of them can be converted to integer
Date now = new Date();
int second = now.getSeconds();
mVariableManager.edit();
mVariableManager.setVariable(VAR_SECOND, mDfSecond.format(now));
mVariableManager.setVariable(VAR_TIMESTAMP, now.getTime() / 1000);
if (mPreviousSecond == -1 || second < mPreviousSecond) {
mVariableManager.setVariable(VAR_MINUTE, mDfMinute.format(now));
mVariableManager.setVariable(VAR_HOUR12, mDfHour12.format(now));
mVariableManager.setVariable(VAR_HOUR24, mDfHour24.format(now));
mVariableManager.setVariable(VAR_DAY, mDfDay.format(now));
mVariableManager.setVariable(VAR_WEEK, mDfWeek.format(now));
mVariableManager.setVariable(VAR_MONTH, mDfMonth.format(now));
mVariableManager.setVariable(VAR_YEAR, mDfYear.format(now));
mVariableManager.setVariable(VAR_AM_PM, mDfAmPm.format(now));
mVariableManager.setVariable(VAR_DAY_NAME, mDfDayName.format(now));
mVariableManager.setVariable(VAR_MONTH_NAME, mDfMonthName.format(now));
}
mPreviousSecond = second;
mVariableManager.commit();
}
};
public TimeDataCollector(Handler handler, VariableManager vm) {
super(1000, handler, vm);
@ -64,32 +89,6 @@ public class TimeDataCollector extends PollingDataCollector {
};
}
private Runnable mSetVariablesRunnable = new Runnable() {
@Override
public void run() {
// text fields, but some of them can be converted to integer
Date now = new Date();
int second = now.getSeconds();
mVariableManager.edit();
mVariableManager.setVariable(VAR_SECOND, mDfSecond.format(now));
mVariableManager.setVariable(VAR_TIMESTAMP, now.getTime()/1000);
if(mPreviousSecond == -1 || second<mPreviousSecond) {
mVariableManager.setVariable(VAR_MINUTE, mDfMinute.format(now));
mVariableManager.setVariable(VAR_HOUR12, mDfHour12.format(now));
mVariableManager.setVariable(VAR_HOUR24, mDfHour24.format(now));
mVariableManager.setVariable(VAR_DAY, mDfDay.format(now));
mVariableManager.setVariable(VAR_WEEK, mDfWeek.format(now));
mVariableManager.setVariable(VAR_MONTH, mDfMonth.format(now));
mVariableManager.setVariable(VAR_YEAR, mDfYear.format(now));
mVariableManager.setVariable(VAR_AM_PM, mDfAmPm.format(now));
mVariableManager.setVariable(VAR_DAY_NAME, mDfDayName.format(now));
mVariableManager.setVariable(VAR_MONTH_NAME, mDfMonthName.format(now));
}
mPreviousSecond = second;
mVariableManager.commit();
}
};
@Override
public void onResume() {
// force an immediate update

View file

@ -17,9 +17,9 @@ import net.pierrox.lightning_launcher.LLApp;
import net.pierrox.lightning_launcher.data.FileUtils;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher.engine.Screen;
import net.pierrox.lightning_launcher.script.ScriptManager;
import net.pierrox.lightning_launcher.script.Script;
import net.pierrox.lightning_launcher.script.ScriptExecutor;
import net.pierrox.lightning_launcher.script.ScriptManager;
import net.pierrox.lightning_launcher.script.api.Lightning;
import net.pierrox.lightning_launcher.script.api.Property;
import net.pierrox.lightning_launcher.script.api.PropertyEditor;
@ -40,16 +40,11 @@ import java.util.HashMap;
import java.util.HashSet;
public class VariableManager {
private LightningEngine mEngine;
private int mDate;
private HashMap<String,Variable> mVariables;
private HashMap<String, ArrayList<Target>> mVariableTargets;
private HashSet<Variable> mModifiedVariables;
private StringBuilder mTmpStringBuilder = new StringBuilder();
private boolean mUpdatesPaused;
private static final String TOK_VARIABLES = "v";
private static final String TOK_NAME = "n";
private static final String TOK_VALUE = "v";
public static Pair<String, ? extends Interpolator> DEFAULT_INTERPOLATOR = new Pair<>("ad", new AccelerateDecelerateInterpolator());
private static Pair<String,Interpolator>[] sInterpolators = new Pair[] {
private static final Pair<String, Interpolator>[] sInterpolators = new Pair[]{
DEFAULT_INTERPOLATOR,
new Pair<>("ac", new AccelerateInterpolator()),
new Pair<>("de", new DecelerateInterpolator()),
@ -59,64 +54,18 @@ public class VariableManager {
new Pair<>("bo", new BounceInterpolator()),
new Pair<>("ov", new OvershootInterpolator()),
};
private static class Animator {
Interpolator interpolator;
long start;
long duration;
long offset;
double fromValue;
double toValue;
String name;
String varName;
double lastValue;
int lastValueDate = -1;
boolean done;
private Animator(String var_name, long duration, String interpolator_name, long offset) {
this.name = name(var_name, duration, interpolator_name, offset);
this.varName = var_name;
this.duration = duration;
this.interpolator = getInterpolatorByName(interpolator_name);
this.offset = offset;
}
public void start(double fromValue, double toValue, int date) {
this.fromValue = this.lastValue = fromValue;
this.toValue = toValue;
this.lastValueDate = date;
this.start = AnimationUtils.currentAnimationTimeMillis();
this.done = false;
}
public void setLastValue(double value, int date) {
lastValue = value;
lastValueDate = date;
}
private Interpolator getInterpolatorByName(String interpolator_name) {
for(Pair<String,Interpolator> p : sInterpolators) {
if(p.first.equals(interpolator_name)) {
return p.second;
}
}
return DEFAULT_INTERPOLATOR.second;
}
public static String name(String var_name, long duration, String interpolator, long offset) {
return var_name+duration+interpolator+offset;
}
}
private Handler mHandler;
private ArrayList<Animator> mAnimators;
private final LightningEngine mEngine;
private final HashMap<String, Variable> mVariables;
private final HashMap<String, ArrayList<Target>> mVariableTargets;
private final StringBuilder mTmpStringBuilder = new StringBuilder();
private final Handler mHandler;
private final ArrayList<Animator> mAnimators;
private final File mValuesFile;
private int mDate;
private HashSet<Variable> mModifiedVariables;
private boolean mUpdatesPaused;
private boolean mAnimateScheduled;
private File mValuesFile;
private static final String TOK_VARIABLES = "v";
private static final String TOK_NAME = "n";
private static final String TOK_VALUE = "v";
private ArrayList<Target> mTmpModifiedTargets = new ArrayList<>(); // limit allocations
public VariableManager(LightningEngine engine, File load_values_from) {
mEngine = engine;
@ -143,6 +92,19 @@ public class VariableManager {
}
}
private static String getIdentifier(String text, int start) {
int pos = start + 1;
int l = text.length();
while (pos < l && isIdentifierChar(text.charAt(pos))) {
pos++;
}
return pos > l ? null : text.substring(start, pos);
}
private static boolean isIdentifierChar(char c) {
return c == '_' || Character.isLetterOrDigit(c);
}
public void saveValues() {
try {
JSONArray jvariables = new JSONArray();
@ -291,17 +253,7 @@ public class VariableManager {
return result;
}
private Animator findAnimator(String name) {
for(Animator a : mAnimators) {
if(name.equals(a.name)) {
return a;
}
}
return null;
}
private Runnable mAnimate = new Runnable() {
private final Runnable mAnimate = new Runnable() {
@Override
public void run() {
edit();
@ -324,7 +276,16 @@ public class VariableManager {
}
};
private ArrayList<Target> mTmpModifiedTargets = new ArrayList<>(); // limit allocations
private Animator findAnimator(String name) {
for (Animator a : mAnimators) {
if (name.equals(a.name)) {
return a;
}
}
return null;
}
public void commit() {
if (!mUpdatesPaused) {
if (mTmpModifiedTargets == null) {
@ -370,10 +331,18 @@ public class VariableManager {
PropertyEditor editor = ps.edit();
try {
switch (Property.getType(field)) {
case Property.TYPE_BOOLEAN: editor.setBoolean(field, Value.asBoolean(value)); break;
case Property.TYPE_INTEGER: editor.setInteger(field, Value.asInteger(value)); break;
case Property.TYPE_FLOAT: editor.setFloat(field, Value.asFloat(value)); break;
case Property.TYPE_STRING: editor.setString(field, Value.asString(value)); break;
case Property.TYPE_BOOLEAN:
editor.setBoolean(field, Value.asBoolean(value));
break;
case Property.TYPE_INTEGER:
editor.setInteger(field, Value.asInteger(value));
break;
case Property.TYPE_FLOAT:
editor.setFloat(field, Value.asFloat(value));
break;
case Property.TYPE_STRING:
editor.setString(field, Value.asString(value));
break;
}
} catch (RhinoException e) {
se.displayScriptError(e);
@ -512,19 +481,6 @@ public class VariableManager {
return target;
}
private static String getIdentifier(String text, int start) {
int pos = start+1;
int l = text.length();
while(pos < l && isIdentifierChar(text.charAt(pos))) {
pos++;
}
return pos > l ? null : text.substring(start, pos);
}
private static boolean isIdentifierChar(char c) {
return c=='_' || Character.isLetterOrDigit(c);
}
private ArrayList<Target> getTargetsForVariable(String name) {
ArrayList<Target> targets = mVariableTargets.get(name);
if (targets == null) {
@ -562,4 +518,55 @@ public class VariableManager {
}
target.dateComputed = mDate;
}
private static class Animator {
Interpolator interpolator;
long start;
long duration;
long offset;
double fromValue;
double toValue;
String name;
String varName;
double lastValue;
int lastValueDate = -1;
boolean done;
private Animator(String var_name, long duration, String interpolator_name, long offset) {
this.name = name(var_name, duration, interpolator_name, offset);
this.varName = var_name;
this.duration = duration;
this.interpolator = getInterpolatorByName(interpolator_name);
this.offset = offset;
}
public static String name(String var_name, long duration, String interpolator, long offset) {
return var_name + duration + interpolator + offset;
}
public void start(double fromValue, double toValue, int date) {
this.fromValue = this.lastValue = fromValue;
this.toValue = toValue;
this.lastValueDate = date;
this.start = AnimationUtils.currentAnimationTimeMillis();
this.done = false;
}
public void setLastValue(double value, int date) {
lastValue = value;
lastValueDate = date;
}
private Interpolator getInterpolatorByName(String interpolator_name) {
for (Pair<String, Interpolator> p : sInterpolators) {
if (p.first.equals(interpolator_name)) {
return p.second;
}
}
return DEFAULT_INTERPOLATOR.second;
}
}
}

View file

@ -12,9 +12,7 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.IBinder;
import android.provider.Settings;
import android.util.DisplayMetrics;
@ -172,7 +170,7 @@ public class WindowService extends Service implements LightningEngine.GlobalConf
mHideHandle = mContentView.findViewById(R.id.hide_handle);
mHideHandle.setVisibility(View.GONE);
mItemLayout=(ItemLayout) mWorkspaceView.findViewById(R.id.window_il);
mItemLayout = mWorkspaceView.findViewById(R.id.window_il);
mScreen.takeItemLayoutOwnership(mItemLayout);
mItemLayout.setHonourFocusChange(false);
@ -831,16 +829,24 @@ public class WindowService extends Service implements LightningEngine.GlobalConf
boolean visible = mWorkspaceView.getVisibility() == View.VISIBLE;
switch (mOverlayShowHandlePosition) {
// FIXME I don't understand why X and Y are inverted, as if not everything was rotated at this time
case LEFT_TOP: case LEFT_MIDDLE: case LEFT_BOTTOM:
case LEFT_TOP:
case LEFT_MIDDLE:
case LEFT_BOTTOM:
mWorkspaceView.setTranslationX(visible ? 0 : -mScreenWidth);
break;
case RIGHT_TOP: case RIGHT_MIDDLE: case RIGHT_BOTTOM:
case RIGHT_TOP:
case RIGHT_MIDDLE:
case RIGHT_BOTTOM:
mWorkspaceView.setTranslationX(visible ? 0 : mScreenWidth);
break;
case TOP_LEFT: case TOP_CENTER: case TOP_RIGHT:
case TOP_LEFT:
case TOP_CENTER:
case TOP_RIGHT:
mWorkspaceView.setTranslationY(visible ? 0 : -mScreenHeight);
break;
case BOTTOM_LEFT: case BOTTOM_CENTER: case BOTTOM_RIGHT:
case BOTTOM_LEFT:
case BOTTOM_CENTER:
case BOTTOM_RIGHT:
mWorkspaceView.setTranslationY(visible ? 0 : mScreenHeight);
break;
}
@ -854,13 +860,21 @@ public class WindowService extends Service implements LightningEngine.GlobalConf
animator.alpha(1);
} else {
switch (from) {
case LEFT_TOP: case LEFT_MIDDLE: case LEFT_BOTTOM:
case RIGHT_TOP: case RIGHT_MIDDLE: case RIGHT_BOTTOM:
case LEFT_TOP:
case LEFT_MIDDLE:
case LEFT_BOTTOM:
case RIGHT_TOP:
case RIGHT_MIDDLE:
case RIGHT_BOTTOM:
animator.translationX(0);
break;
case TOP_LEFT: case TOP_CENTER: case TOP_RIGHT:
case BOTTOM_LEFT: case BOTTOM_CENTER: case BOTTOM_RIGHT:
case TOP_LEFT:
case TOP_CENTER:
case TOP_RIGHT:
case BOTTOM_LEFT:
case BOTTOM_CENTER:
case BOTTOM_RIGHT:
animator.translationY(0);
break;
}
@ -871,19 +885,27 @@ public class WindowService extends Service implements LightningEngine.GlobalConf
} else {
boolean is_show_handle = from == mOverlayShowHandlePosition;
switch (from) {
case LEFT_TOP: case LEFT_MIDDLE: case LEFT_BOTTOM:
case LEFT_TOP:
case LEFT_MIDDLE:
case LEFT_BOTTOM:
animator.translationX(is_show_handle ? -mScreenWidth - 1 : mScreenWidth + 1);
break;
case RIGHT_TOP: case RIGHT_MIDDLE: case RIGHT_BOTTOM:
case RIGHT_TOP:
case RIGHT_MIDDLE:
case RIGHT_BOTTOM:
animator.translationX(is_show_handle ? mScreenWidth + 1 : -mScreenWidth - 1);
break;
case TOP_LEFT: case TOP_CENTER: case TOP_RIGHT:
case TOP_LEFT:
case TOP_CENTER:
case TOP_RIGHT:
animator.translationY(is_show_handle ? -mScreenHeight - 1 : mScreenHeight + 1);
break;
case BOTTOM_LEFT: case BOTTOM_CENTER: case BOTTOM_RIGHT:
case BOTTOM_LEFT:
case BOTTOM_CENTER:
case BOTTOM_RIGHT:
animator.translationY(is_show_handle ? mScreenHeight + 1 : -mScreenHeight - 1);
break;
}

View file

@ -18,21 +18,17 @@ import net.pierrox.lightning_launcher.R;
import java.text.DecimalFormat;
public class DialogPreferenceSlider extends AlertDialog implements SeekBar.OnSeekBarChangeListener, View.OnClickListener, DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
public interface OnDialogPreferenceSliderListener {
public void onDialogPreferenceSliderValueSet(float value);
public void onDialogPreferenceSliderCancel();
}
private boolean mIsFloat;
private float mMinValue;
private float mMaxValue;
private float mInterval;
private String mUnit;
private static final DecimalFormat sFloatFormat0 = new DecimalFormat("0.#");
private static final DecimalFormat sFloatFormat1 = new DecimalFormat("0.0");
private final boolean mIsFloat;
private final float mMinValue;
private final float mMaxValue;
private final float mInterval;
private final String mUnit;
private final OnDialogPreferenceSliderListener mListener;
private SeekBar mDialogSeekBar;
private EditText mDialogEditText;
private float mDialogValue;
private OnDialogPreferenceSliderListener mListener;
public DialogPreferenceSlider(Context context, float value, boolean is_float, float min, float max, float interval, String unit, OnDialogPreferenceSliderListener listener) {
super(context);
@ -46,6 +42,22 @@ public class DialogPreferenceSlider extends AlertDialog implements SeekBar.OnSee
mListener = listener;
}
/*package*/
static String valueAsText(boolean is_float, String unit, float value, float interval) {
String text;
if (is_float) {
if (unit != null && unit.equals("%")) {
text = String.valueOf(Math.round(value * 100));
} else {
DecimalFormat format = interval < 1 ? sFloatFormat1 : sFloatFormat0;
text = format.format(value);
}
} else {
text = String.valueOf(Math.round(value));
}
return text;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@ -54,11 +66,11 @@ public class DialogPreferenceSlider extends AlertDialog implements SeekBar.OnSee
view.findViewById(R.id.minus).setOnClickListener(this);
view.findViewById(R.id.plus).setOnClickListener(this);
mDialogSeekBar = (SeekBar) view.findViewById(R.id.seek_bar);
mDialogSeekBar = view.findViewById(R.id.seek_bar);
mDialogSeekBar.setMax((int) ((mMaxValue - mMinValue) / mInterval));
mDialogSeekBar.setProgress(getProgressForValue(mDialogValue));
mDialogSeekBar.setOnSeekBarChangeListener(this);
mDialogEditText = (EditText) view.findViewById(R.id.value);
mDialogEditText = view.findViewById(R.id.value);
if (mIsFloat) {
mDialogEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | (mMinValue < 0 ? InputType.TYPE_NUMBER_FLAG_SIGNED : InputType.TYPE_NUMBER_VARIATION_NORMAL));
} else {
@ -94,7 +106,7 @@ public class DialogPreferenceSlider extends AlertDialog implements SeekBar.OnSee
}
});
TextView unitv = (TextView) view.findViewById(R.id.unit);
TextView unitv = view.findViewById(R.id.unit);
unitv.setText(mUnit);
setView(view);
@ -106,7 +118,6 @@ public class DialogPreferenceSlider extends AlertDialog implements SeekBar.OnSee
super.onCreate(savedInstanceState);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.minus) {
@ -166,20 +177,9 @@ public class DialogPreferenceSlider extends AlertDialog implements SeekBar.OnSee
return (int) ((value - mMinValue) / (mMaxValue - mMinValue) * mDialogSeekBar.getMax());
}
private static DecimalFormat sFloatFormat0 = new DecimalFormat("0.#");
private static DecimalFormat sFloatFormat1 = new DecimalFormat("0.0");
/*package*/ static String valueAsText(boolean is_float, String unit, float value, float interval) {
String text;
if (is_float) {
if(unit!=null && unit.equals("%")) {
text=String.valueOf(Math.round(value*100));
} else {
DecimalFormat format=interval<1 ? sFloatFormat1 : sFloatFormat0;
text=format.format(value);
}
} else {
text=String.valueOf(Math.round(value));
}
return text;
public interface OnDialogPreferenceSliderListener {
void onDialogPreferenceSliderValueSet(float value);
void onDialogPreferenceSliderCancel();
}
}

Some files were not shown because too many files have changed in this diff Show more