Commit 196d8566 authored by Amit Kumar's avatar Amit Kumar
Browse files

Add animated clock icon

parent 5b6c0a8d
......@@ -24,7 +24,7 @@
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
......
......@@ -14,6 +14,7 @@ public class AppItem {
private String componentName;
private boolean iconFromIconPack;
private boolean isSystemApp;
private boolean isClock;
// Folder specific
private boolean belongsToFolder;
......@@ -23,7 +24,8 @@ public class AppItem {
public AppItem(CharSequence label, String packageName, Drawable icon,
Intent intent, String componentName, boolean iconFromIconPack, boolean isSystemApp) {
Intent intent, String componentName, boolean iconFromIconPack, boolean isSystemApp,
boolean isClock) {
this.label = label;
this.packageName = packageName;
this.icon = icon;
......@@ -31,6 +33,7 @@ public class AppItem {
this.componentName = componentName;
this.iconFromIconPack = iconFromIconPack;
this.isSystemApp = isSystemApp;
this.isClock = isClock;
}
public CharSequence getLabel() {
......@@ -53,11 +56,15 @@ public class AppItem {
return icon;
}
public boolean isSystemApp(){
public boolean isSystemApp() {
return isSystemApp;
}
public void setSystemApp(boolean isSystemApp){
public boolean isClock() {
return isClock;
}
public void setSystemApp(boolean isSystemApp) {
this.isSystemApp = isSystemApp;
}
......@@ -106,8 +113,9 @@ public class AppItem {
}
public List<AppItem> getSubApps() {
if(subApps == null)
if (subApps == null) {
subApps = new ArrayList<>();
}
return subApps;
}
......
......@@ -36,11 +36,16 @@ public class AppUtil {
boolean iconFromIconPack = true;
Drawable appIcon = null;
boolean isClock = false;
// Load icon from icon pack if present
if (IconPackUtil.iconPackPresent) {
appIcon = IconPackUtil.getIconFromIconPack(context, componentName);
if (!IconPackUtil.isClock(componentName)) {
appIcon = IconPackUtil.getIconFromIconPack(context, componentName);
} else {
isClock = true;
}
}
if (appIcon == null) {
if (appIcon == null && !isClock) {
appIcon = appInfo.loadIcon(packageManager);
iconFromIconPack = false;
appIcon = GraphicsUtil.scaleImage(context, appIcon, 1f);
......@@ -60,7 +65,8 @@ public class AppUtil {
intent,
componentName,
iconFromIconPack,
isSystemApp
isSystemApp,
isClock
);
launchableApps.add(launchableApp);
}
......@@ -125,33 +131,35 @@ public class AppUtil {
ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
Intent intent = packageManager.getLaunchIntentForPackage(packageName);
if (intent == null) {
return null;
}
if (intent != null) {
String componentName = intent.getComponent().toString();
String componentName = intent.getComponent().toString();
Drawable appIcon;
boolean iconFromIconPack = true;
if (IconPackUtil.iconPackPresent) {
appIcon = IconPackUtil.getIconFromIconPack(context, componentName);
boolean iconFromIconPack = true;
Drawable appIcon = null;
boolean isClock = false;
// Load icon from icon pack if present
if (IconPackUtil.iconPackPresent) {
isClock = IconPackUtil.isClock(componentName);
appIcon = IconPackUtil.getIconFromIconPack(context, componentName);
}
if (appIcon == null) {
appIcon = appInfo.loadIcon(packageManager);
iconFromIconPack = false;
appIcon = GraphicsUtil.scaleImage(context, appIcon, 1f);
appIcon = GraphicsUtil.maskImage(context, appIcon);
}
return new AppItem(appInfo.loadLabel(packageManager),
packageName,
appIcon,
intent,
componentName,
iconFromIconPack,
(appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0,
isClock);
} else {
appIcon = appInfo.loadIcon(packageManager);
iconFromIconPack = false;
return null;
}
return new AppItem(appInfo.loadLabel(packageManager),
packageName,
appIcon,
intent,
componentName,
iconFromIconPack,
(appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
} catch (PackageManager.NameNotFoundException e) {
return null;
}
......
package org.indin.blisslaunchero;
/**
* Created by falcon on 8/3/18.
*/
public class Constants {
public static final int DEFAULT_CLOCK_ID = 971;
}
package org.indin.blisslaunchero;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.support.annotation.DrawableRes;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
import java.util.Calendar;
/**
* Created by falcon on 8/3/18.
*/
public class CustomAnalogClock extends View {
public static boolean is24;
public static boolean hourOnTop;
private final ArrayList<DialOverlay> mDialOverlay = new ArrayList<DialOverlay>();
private Calendar mCalendar;
private Drawable mFace;
private int mDialWidth;
private float sizeScale = 1f;
private int radius;
private int mDialHeight;
private int mBottom;
private int mTop;
private int mLeft;
private int mRight;
private boolean mSizeChanged;
private HandsOverlay mHandsOverlay;
private boolean autoUpdate;
private static final String TAG = "CustomAnalogClock";
public CustomAnalogClock(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
handleAttrs(context, attrs);
}
public CustomAnalogClock(Context context, AttributeSet attrs) {
super(context, attrs);
handleAttrs(context, attrs);
}
public CustomAnalogClock(Context context) {
super(context);
init(context);
}
private void handleAttrs(Context context, AttributeSet attrs) {
init(context);
}
public void init(Context context) {
init(context, R.drawable.clock, R.drawable.hours,
R.drawable.minutes, R.drawable.seconds, 0, false, false);
}
/**
* Will set the scale of the view, for example 0.5f will draw the clock with half of its radius
*
* @param scale the scale to render the view in
*/
public void setScale(float scale) {
if (scale <= 0) {
throw new IllegalArgumentException("Scale must be bigger than 0");
}
this.sizeScale = scale;
mHandsOverlay.withScale(sizeScale);
invalidate();
}
public void setFace(int drawableRes) {
final Resources r = getResources();
setFace(r.getDrawable(drawableRes));
}
public void init(Context context, @DrawableRes int watchFace, @DrawableRes int hourHand,
@DrawableRes int minuteHand, @DrawableRes int secHand, int alpha, boolean is24,
boolean hourOnTop) {
CustomAnalogClock.is24 = is24;
CustomAnalogClock.hourOnTop = hourOnTop;
setFace(watchFace);
Drawable Hhand = ContextCompat.getDrawable(context, hourHand);
assert Hhand != null;
if (alpha > 0) {
Hhand.setAlpha(alpha);
}
Drawable Mhand = ContextCompat.getDrawable(context, minuteHand);
Drawable SHand = ContextCompat.getDrawable(context, secHand);
mCalendar = Calendar.getInstance();
mHandsOverlay = new HandsOverlay(Hhand, Mhand, SHand).withScale(sizeScale);
mHandsOverlay.setShowSeconds(true);
}
public void setFace(Drawable face) {
mFace = face;
mSizeChanged = true;
mDialHeight = mFace.getIntrinsicHeight();
mDialWidth = mFace.getIntrinsicWidth();
radius = Math.max(mDialHeight, mDialWidth);
invalidate();
}
/**
* Sets the currently displayed time in {@link System#currentTimeMillis()}
* time.
*
* @param time the time to display on the clock
*/
public void setTime(long time) {
mCalendar.setTimeInMillis(time);
invalidate();
}
/**
* Sets the currently displayed time.
*
* @param calendar The time to display on the clock
*/
public void setTime(Calendar calendar) {
mCalendar = calendar;
invalidate();
if (autoUpdate) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
setTime(Calendar.getInstance());
}
}, 1000);
}
}
public void setAutoUpdate(boolean autoUpdate) {
this.autoUpdate = autoUpdate;
setTime(Calendar.getInstance());
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mSizeChanged = true;
}
// some parts from AnalogClock.java
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final boolean sizeChanged = mSizeChanged;
mSizeChanged = false;
final int availW = mRight - mLeft;
final int availH = mBottom - mTop;
final int cX = availW / 2;
final int cY = availH / 2;
final int w = (int) (mDialWidth * sizeScale);
final int h = (int) (mDialHeight * sizeScale);
Log.i(TAG, "w="+w+", h="+h+", aw="+availW+", ah="+availH);
boolean scaled = false;
if (availW < w || availH < h) {
scaled = true;
final float scale = Math.min((float) availW / (float) w,
(float) availH / (float) h);
canvas.save();
canvas.scale(scale, scale, cX, cY);
}
if (sizeChanged) {
mFace.setBounds(cX - (w / 2), cY - (h / 2), cX + (w / 2), cY
+ (h / 2));
}
mFace.draw(canvas);
for (final DialOverlay overlay : mDialOverlay) {
overlay.onDraw(canvas, cX, cY, w, h, mCalendar, sizeChanged);
}
mHandsOverlay.onDraw(canvas, cX, cY, w, h, mCalendar, sizeChanged);
if (scaled) {
canvas.restore();
}
}
// from AnalogClock.java
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int size = DesktopActivity.appIconWidth;
setMeasuredDimension(size, size);
}
@Override
protected int getSuggestedMinimumHeight() {
return (int) (mDialHeight * sizeScale);
}
@Override
protected int getSuggestedMinimumWidth() {
return (int) (mDialWidth * sizeScale);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
mRight = right;
mLeft = left;
mTop = top;
mBottom = bottom;
}
}
......@@ -48,6 +48,7 @@ import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;
......@@ -111,7 +112,7 @@ public class DesktopActivity extends AppCompatActivity {
private boolean longPressed;
private int x;
private int y;
private int appIconWidth;
public static int appIconWidth;
private CountDownTimer mWobblingCountDownTimer;
private long longPressedAt;
......@@ -593,7 +594,7 @@ public class DesktopActivity extends AppCompatActivity {
if (appView != null) {
addToDock(appView, INVALID);
}
} catch (Exception e) {
} catch (Exception ignored) {
}
}
......@@ -617,7 +618,7 @@ public class DesktopActivity extends AppCompatActivity {
addAppToPage(page, appView);
}
}
} catch (Exception e) {
} catch (Exception ignored) {
}
}
......@@ -728,7 +729,8 @@ public class DesktopActivity extends AppCompatActivity {
null,
"FOLDER",
false,
true);
true,
false);
folderItem.setFolder(true);
folderItem.setFolderID(currentItemData.getString("folderID"));
JSONArray subAppData = currentItemData.getJSONArray("subApps");
......@@ -776,9 +778,11 @@ public class DesktopActivity extends AppCompatActivity {
* The View object also has all the required listeners attached to it.
*/
private View prepareApp(final AppItem app) {
final View v = getLayoutInflater().inflate(R.layout.app_view, null);
final ViewGroup v = (ViewGroup) getLayoutInflater().inflate(R.layout.app_view, null);
final TextView label = v.findViewById(R.id.app_label);
final SquareImageView icon = v.findViewById(R.id.app_icon);
final View icon = v.findViewById(R.id.app_icon);
final SquareImageView squareImageView = v.findViewById(R.id.icon_image_view);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) icon.getLayoutParams();
if (nRows == 4) {
appIconMargin = getResources().getDimensionPixelSize(R.dimen.margin_inch1);
......@@ -797,8 +801,20 @@ public class DesktopActivity extends AppCompatActivity {
layoutParams.leftMargin = appIconMargin;
layoutParams.rightMargin = appIconMargin;
appIconWidth = iconWidth - 2 * appIconMargin;
Log.i(TAG, "appIconWidth " + appIconWidth);
if (app.isClock()) {
final CustomAnalogClock analogClock = v.findViewById(R.id.icon_clock);
analogClock.setVisibility(View.VISIBLE);
squareImageView.setVisibility(View.GONE);
analogClock.setAutoUpdate(true);
}
final Intent intent = app.getIntent();
icon.setImageDrawable(app.getIcon());
if (!app.isClock()) {
squareImageView.setImageDrawable(app.getIcon());
}
label.setText(app.getLabel());
if (nRows < 6) {
label.setTextSize(12);
......@@ -813,12 +829,13 @@ public class DesktopActivity extends AppCompatActivity {
if (IconPackUtil.iconPackPresent) {
if (app.isIconFromIconPack()) {
icon.setBackgroundResource(0);
squareImageView.setBackgroundResource(0);
} else {
if (!app.isFolder()) {
icon.setBackground(IconPackUtil.getIconBackground(app.getLabel().charAt(0)));
squareImageView.setBackground(
IconPackUtil.getIconBackground(app.getLabel().charAt(0)));
} else {
icon.setBackground(IconPackUtil.folderBackground);
squareImageView.setBackground(IconPackUtil.folderBackground);
}
}
}
......@@ -865,7 +882,8 @@ public class DesktopActivity extends AppCompatActivity {
&& System.currentTimeMillis() - longPressedAt > 200) {
longPressed = false;
movingApp = v;
View.DragShadowBuilder dragShadowBuilder = new BlissDragShadowBuilder(icon);
View.DragShadowBuilder dragShadowBuilder = new BlissDragShadowBuilder(
icon);
v.startDrag(null, dragShadowBuilder, v, 0);
if (v.getParent().getParent() instanceof HorizontalPager) {
......@@ -904,14 +922,6 @@ public class DesktopActivity extends AppCompatActivity {
}
});
icon.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
appIconWidth = icon.getWidth();
}
});
return v;
}
......@@ -965,7 +975,7 @@ public class DesktopActivity extends AppCompatActivity {
/**
* Toggle the wobbling animation.
*/
private void toggleWobbleAnimation(GridLayout gridLayout, boolean shouldPlayAnimation) {
private void toggleWobbleAnimation(GridLayout gridLayout, boolean shouldPlayAnimation){
for (int i = 0; i < gridLayout.getChildCount(); i++) {
ViewGroup viewGroup = (ViewGroup) gridLayout.getChildAt(i);
if (shouldPlayAnimation) {
......@@ -995,7 +1005,7 @@ public class DesktopActivity extends AppCompatActivity {
private void addUninstallIcon(ViewGroup viewGroup) {
final AppItem appItem = getAppDetails(viewGroup);
if (!appItem.isSystemApp()) {
ImageView appIcon = viewGroup.findViewById(R.id.app_icon);
FrameLayout appIcon = viewGroup.findViewById(R.id.app_icon);
int size = (appIcon.getRight() - appIcon.getLeft()) / 5;
if (size > appIcon.getTop() || size > appIcon.getLeft()) {
......@@ -1004,10 +1014,14 @@ public class DesktopActivity extends AppCompatActivity {
int paddingRight = appIconMargin - size;
int paddingLeft = paddingRight;
int paddingTop = appIcon.getTop() - size;
int paddingBottom = (paddingLeft + paddingRight - paddingTop);
int paddingBottom =
(2 * paddingLeft > paddingTop) ? (paddingLeft + paddingRight - paddingTop)
: paddingTop;
Log.i(TAG, "paddingBottom: " + paddingBottom);
ImageView imageView = new ImageView(this);
imageView.setId(R.id.uninstall_app);
imageView.setImageResource(R.drawable.ic_minus);
imageView.setImageResource(R.drawable.remove_icon_72);
imageView.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
imageView.setOnClickListener(new View.OnClickListener() {
......@@ -1444,7 +1458,8 @@ public class DesktopActivity extends AppCompatActivity {
null,
"FOLDER",
false,
true);
true,
false);
folder.setFolder(true);
folder.setFolderID(UUID.randomUUID().toString());
......
package org.indin.blisslaunchero;
import java.util.Calendar;
import android.graphics.Canvas;
/**
* An overlay for a clock dial.
*/
public interface DialOverlay {
/**
* Subclasses should implement this to draw the overlay.
*
* @param canvas the canvas onto which you must draw
* @param cX the x coordinate of the center
* @param cY the y coordinate of the center
* @param w the width of the canvas
* @param h the height of the canvas
* @param calendar the desired date/time
*/
public abstract void onDraw(Canvas canvas, int cX, int cY, int w, int h, Calendar calendar,
boolean sizeChanged);
}
package org.indin.blisslaunchero;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import java.util.Calendar;
/**
* Created by falcon on 8/3/18.
*/