Use dark theme for widget colors

pull/84/merge
Alinson S. Xavier 10 years ago
parent 3bba75ff50
commit dbcad9a5f4

@ -25,7 +25,7 @@ import android.test.suitebuilder.annotation.SmallTest;
import org.isoron.uhabits.helpers.DateHelper;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.unit.HabitFixtures;
import org.isoron.uhabits.views.CheckmarkView;
import org.isoron.uhabits.views.CheckmarkWidgetView;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -34,9 +34,9 @@ import java.io.IOException;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class CheckmarkViewTest extends ViewTest
public class CheckmarkWidgetViewTest extends ViewTest
{
private CheckmarkView view;
private CheckmarkWidgetView view;
private Habit habit;
@Before
@ -45,7 +45,7 @@ public class CheckmarkViewTest extends ViewTest
super.setup();
habit = HabitFixtures.createShortHabit();
view = new CheckmarkView(targetContext);
view = new CheckmarkWidgetView(targetContext);
view.setHabit(habit);
refreshData(view);
measureView(dpToPixels(100), dpToPixels(200), view);

@ -21,15 +21,9 @@ package org.isoron.uhabits.views;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import org.isoron.uhabits.R;
@ -39,19 +33,8 @@ import org.isoron.uhabits.models.Checkmark;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.models.Score;
import java.util.Arrays;
public class CheckmarkView extends FrameLayout implements HabitDataView
public class CheckmarkWidgetView extends HabitWidgetView implements HabitDataView
{
@Nullable
private InsetDrawable background;
@Nullable
private Paint backgroundPaint;
@Nullable
private Habit habit;
private int activeColor;
private float percentage;
@ -60,18 +43,17 @@ public class CheckmarkView extends FrameLayout implements HabitDataView
@Nullable
private RingView ring;
private ViewGroup frame;
private TextView label;
private int checkmarkValue;
private int inactiveColor;
public CheckmarkView(Context context)
public CheckmarkWidgetView(Context context)
{
super(context);
init();
}
public CheckmarkView(Context context, AttributeSet attrs)
public CheckmarkWidgetView(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
@ -79,35 +61,10 @@ public class CheckmarkView extends FrameLayout implements HabitDataView
private void init()
{
inflate(getContext(), R.layout.widget_checkmark_inner, this);
int shadowRadius = (int) UIHelper.dpToPixels(getContext(), 2);
int shadowOffset = (int) UIHelper.dpToPixels(getContext(), 1);
int shadowColor = Color.argb(96, 0, 0, 0);
float cornerRadius = UIHelper.dpToPixels(getContext(), 5);
float[] radii = new float[8];
Arrays.fill(radii, cornerRadius);
RoundRectShape shape = new RoundRectShape(radii, null, null);
ShapeDrawable innerDrawable = new ShapeDrawable(shape);
int insetLeftTop = Math.max(shadowRadius - shadowOffset, 0);
int insetRightBottom = shadowRadius + shadowOffset;
background = new InsetDrawable(innerDrawable, insetLeftTop, insetLeftTop, insetRightBottom,
insetRightBottom);
backgroundPaint = innerDrawable.getPaint();
backgroundPaint.setAlpha(100);
if (backgroundPaint != null)
backgroundPaint.setShadowLayer(shadowRadius, shadowOffset, shadowOffset, shadowColor);
ring = (RingView) findViewById(R.id.scoreRing);
frame = (ViewGroup) findViewById(R.id.frame);
label = (TextView) findViewById(R.id.label);
inactiveColor = ColorHelper.CSV_PALETTE[11];
inactiveColor = UIHelper.getStyledColor(getContext(), R.attr.cardBackgroundColor);
if(isInEditMode())
{
@ -122,9 +79,9 @@ public class CheckmarkView extends FrameLayout implements HabitDataView
@Override
public void setHabit(@NonNull Habit habit)
{
this.habit = habit;
super.setHabit(habit);
this.name = habit.name;
this.activeColor = ColorHelper.getColor(getContext(), habit.color);
this.activeColor = ColorHelper.CSV_PALETTE[habit.color];
refresh();
}
@ -133,36 +90,42 @@ public class CheckmarkView extends FrameLayout implements HabitDataView
if (backgroundPaint == null || frame == null || ring == null) return;
String text;
int color;
int backgroundColor;
int foregroundColor;
switch (checkmarkValue)
{
case Checkmark.CHECKED_EXPLICITLY:
text = getResources().getString(R.string.fa_check);
color = activeColor;
backgroundColor = activeColor;
foregroundColor = Color.WHITE;
break;
case Checkmark.CHECKED_IMPLICITLY:
text = getResources().getString(R.string.fa_check);
color = inactiveColor;
backgroundColor = inactiveColor;
foregroundColor = UIHelper.getStyledColor(getContext(), R.attr.mediumContrastTextColor);
break;
case Checkmark.UNCHECKED:
default:
text = getResources().getString(R.string.fa_times);
color = inactiveColor;
backgroundColor = inactiveColor;
foregroundColor = UIHelper.getStyledColor(getContext(), R.attr.mediumContrastTextColor);
break;
}
backgroundPaint.setColor(color);
backgroundPaint.setColor(backgroundColor);
frame.setBackgroundDrawable(background);
ring.setPercentage(percentage);
ring.setPrecision(0.125f);
ring.setColor(Color.WHITE);
ring.setBackgroundColor(color);
ring.setColor(foregroundColor);
ring.setBackgroundColor(backgroundColor);
ring.setText(text);
label.setText(name);
label.setTextColor(foregroundColor);
requestLayout();
postInvalidate();
@ -192,7 +155,12 @@ public class CheckmarkView extends FrameLayout implements HabitDataView
if(habit == null) return;
this.percentage = (float) habit.scores.getTodayValue() / Score.MAX_VALUE;
this.checkmarkValue = habit.checkmarks.getTodayValue();
refresh();
}
@NonNull
protected Integer getInnerLayoutId()
{
return R.layout.widget_checkmark;
}
}

@ -0,0 +1,78 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.views;
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
public class GraphWidgetView extends HabitWidgetView implements HabitDataView
{
private final HabitDataView dataView;
private TextView title;
public GraphWidgetView(Context context, HabitDataView dataView)
{
super(context);
this.dataView = dataView;
init();
}
private void init()
{
ViewGroup.LayoutParams params =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
((View) dataView).setLayoutParams(params);
ViewGroup innerFrame = (ViewGroup) findViewById(R.id.innerFrame);
innerFrame.addView(((View) dataView));
title = (TextView) findViewById(R.id.title);
title.setVisibility(VISIBLE);
}
@Override
public void setHabit(@NonNull Habit habit)
{
super.setHabit(habit);
dataView.setHabit(habit);
title.setText(habit.name);
}
@Override
public void refreshData()
{
if(habit == null) return;
dataView.refreshData();
}
@NonNull
protected Integer getInnerLayoutId()
{
return R.layout.widget_graph;
}
}

@ -0,0 +1,106 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.views;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import org.isoron.uhabits.R;
import org.isoron.uhabits.helpers.UIHelper;
import org.isoron.uhabits.models.Habit;
import java.util.Arrays;
public abstract class HabitWidgetView extends FrameLayout implements HabitDataView
{
@Nullable
protected InsetDrawable background;
@Nullable
protected Paint backgroundPaint;
@Nullable
protected Habit habit;
protected ViewGroup frame;
public HabitWidgetView(Context context)
{
super(context);
init();
}
public HabitWidgetView(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}
private void init()
{
inflate(getContext(), getInnerLayoutId(), this);
initBackground();
}
protected abstract @NonNull Integer getInnerLayoutId();
private void initBackground()
{
Context context = getContext();
context.setTheme(R.style.AppBaseThemeDark);
int shadowRadius = (int) UIHelper.dpToPixels(context, 2);
int shadowOffset = (int) UIHelper.dpToPixels(context, 1);
int shadowColor = Color.argb(96, 0, 0, 0);
float cornerRadius = UIHelper.dpToPixels(context, 5);
float[] radii = new float[8];
Arrays.fill(radii, cornerRadius);
RoundRectShape shape = new RoundRectShape(radii, null, null);
ShapeDrawable innerDrawable = new ShapeDrawable(shape);
int insetLeftTop = Math.max(shadowRadius - shadowOffset, 0);
int insetRightBottom = shadowRadius + shadowOffset;
background = new InsetDrawable(innerDrawable, insetLeftTop, insetLeftTop, insetRightBottom,
insetRightBottom);
backgroundPaint = innerDrawable.getPaint();
backgroundPaint.setShadowLayer(shadowRadius, shadowOffset, shadowOffset, shadowColor);
backgroundPaint.setColor(UIHelper.getStyledColor(context, R.attr.cardBackgroundColor));
frame = (ViewGroup) findViewById(R.id.frame);
frame.setBackgroundDrawable(background);
}
@Override
public void setHabit(@NonNull Habit habit)
{
this.habit = habit;
}
}

@ -25,7 +25,7 @@ import android.view.View;
import org.isoron.uhabits.HabitBroadcastReceiver;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.views.CheckmarkView;
import org.isoron.uhabits.views.CheckmarkWidgetView;
import org.isoron.uhabits.views.HabitDataView;
public class CheckmarkWidgetProvider extends BaseWidgetProvider
@ -33,7 +33,7 @@ public class CheckmarkWidgetProvider extends BaseWidgetProvider
@Override
protected View buildCustomView(Context context, Habit habit)
{
CheckmarkView view = new CheckmarkView(context);
CheckmarkWidgetView view = new CheckmarkWidgetView(context);
view.setHabit(habit);
return view;
}
@ -65,7 +65,7 @@ public class CheckmarkWidgetProvider extends BaseWidgetProvider
@Override
protected int getLayoutId()
{
return R.layout.widget_checkmark;
return R.layout.widget_wrapper;
}

@ -26,6 +26,7 @@ import android.view.View;
import org.isoron.uhabits.HabitBroadcastReceiver;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.views.GraphWidgetView;
import org.isoron.uhabits.views.HabitDataView;
import org.isoron.uhabits.views.HabitFrequencyView;
@ -34,8 +35,8 @@ public class FrequencyWidgetProvider extends BaseWidgetProvider
@Override
protected View buildCustomView(Context context, Habit habit)
{
HabitFrequencyView view = new HabitFrequencyView(context, null);
view.setIsBackgroundTransparent(true);
HabitFrequencyView dataView = new HabitFrequencyView(context);
GraphWidgetView view = new GraphWidgetView(context, dataView);
view.setHabit(habit);
return view;
}
@ -67,6 +68,6 @@ public class FrequencyWidgetProvider extends BaseWidgetProvider
@Override
protected int getLayoutId()
{
return R.layout.widget_graph;
return R.layout.widget_wrapper;
}
}

@ -25,6 +25,7 @@ import android.view.View;
import org.isoron.uhabits.HabitBroadcastReceiver;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.views.GraphWidgetView;
import org.isoron.uhabits.views.HabitDataView;
import org.isoron.uhabits.views.HabitHistoryView;
@ -33,9 +34,9 @@ public class HistoryWidgetProvider extends BaseWidgetProvider
@Override
protected View buildCustomView(Context context, Habit habit)
{
HabitHistoryView view = new HabitHistoryView(context, null);
HabitHistoryView dataView = new HabitHistoryView(context);
GraphWidgetView view = new GraphWidgetView(context, dataView);
view.setHabit(habit);
view.setIsBackgroundTransparent(true);
return view;
}
@ -66,6 +67,6 @@ public class HistoryWidgetProvider extends BaseWidgetProvider
@Override
protected int getLayoutId()
{
return R.layout.widget_graph;
return R.layout.widget_wrapper;
}
}

@ -25,16 +25,17 @@ import android.view.View;
import org.isoron.uhabits.HabitBroadcastReceiver;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.views.GraphWidgetView;
import org.isoron.uhabits.views.HabitDataView;
import org.isoron.uhabits.views.HabitScoreView;
public class ScoreWidgetProvider extends BaseWidgetProvider
public class ScoreWidgetProvider extends BaseWidgetProvider
{
@Override
protected View buildCustomView(Context context, Habit habit)
{
HabitScoreView view = new HabitScoreView(context, null);
view.setIsBackgroundTransparent(true);
HabitScoreView dataView = new HabitScoreView(context);
GraphWidgetView view = new GraphWidgetView(context, dataView);
view.setHabit(habit);
return view;
}
@ -66,6 +67,6 @@ public class ScoreWidgetProvider extends BaseWidgetProvider
@Override
protected int getLayoutId()
{
return R.layout.widget_graph;
return R.layout.widget_wrapper;
}
}

@ -25,6 +25,7 @@ import android.view.View;
import org.isoron.uhabits.HabitBroadcastReceiver;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.views.GraphWidgetView;
import org.isoron.uhabits.views.HabitDataView;
import org.isoron.uhabits.views.HabitStreakView;
@ -33,8 +34,8 @@ public class StreakWidgetProvider extends BaseWidgetProvider
@Override
protected View buildCustomView(Context context, Habit habit)
{
HabitStreakView view = new HabitStreakView(context, null);
view.setIsBackgroundTransparent(true);
HabitStreakView dataView = new HabitStreakView(context);
GraphWidgetView view = new GraphWidgetView(context, dataView);
view.setHabit(habit);
return view;
}
@ -66,6 +67,6 @@ public class StreakWidgetProvider extends BaseWidgetProvider
@Override
protected int getLayoutId()
{
return R.layout.widget_graph;
return R.layout.widget_wrapper;
}
}

@ -18,32 +18,47 @@
~ with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<RelativeLayout
<LinearLayout
android:id="@+id/frame"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:habit="http://isoron.org/android"
android:gravity="center"
android:padding="0dp">
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
<org.isoron.uhabits.views.RingView
android:id="@+id/scoreRing"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
/>
android:layout_height="0dp"
android:layout_weight="1"
habit:percentage="0.25"
habit:thickness="2"
habit:textSize="16"
habit:color="@color/white"
habit:inactiveColor="@color/white"
habit:enableFontAwesome="true"
habit:text="@string/fa_check"
android:layout_marginTop="8dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"/>
<FrameLayout
android:id="@+id/buttonOverlay"
<TextView
android:id="@+id/label"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="wrap_content"
android:layout_weight="0"
android:textSize="12sp"
android:textColor="@color/white"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:gravity="center"
android:scrollHorizontally="true"
android:ellipsize="end"
android:maxLines="2"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:fontFamily="sans-serif-condensed"
android:breakStrategy="balanced" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/widget_button_background"
/>
</FrameLayout>
</RelativeLayout>
</LinearLayout>

@ -1,64 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
~
~ This file is part of Loop Habit Tracker.
~
~ Loop Habit Tracker is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by the
~ Free Software Foundation, either version 3 of the License, or (at your
~ option) any later version.
~
~ Loop Habit Tracker is distributed in the hope that it will be useful, but
~ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
~ more details.
~
~ You should have received a copy of the GNU General Public License along
~ with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout
android:id="@+id/frame"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:habit="http://isoron.org/android"
android:gravity="center"
android:orientation="vertical">
<org.isoron.uhabits.views.RingView
android:id="@+id/scoreRing"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
habit:percentage="0.25"
habit:thickness="2"
habit:textSize="16"
habit:color="@color/white"
habit:inactiveColor="@color/white"
habit:enableFontAwesome="true"
habit:text="@string/fa_check"
android:layout_marginTop="8dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"/>
<TextView
android:id="@+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:textSize="12sp"
android:textColor="@color/white"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:gravity="center"
android:scrollHorizontally="true"
android:ellipsize="end"
android:maxLines="2"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:fontFamily="sans-serif-condensed"
android:breakStrategy="balanced" />
</LinearLayout>

@ -18,29 +18,33 @@
~ with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout
<FrameLayout
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/frame"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/widget_background"
android:gravity="center"
android:orientation="vertical"
android:padding="4dp">
android:orientation="vertical">
<TextView
android:id="@+id/label"
<LinearLayout
android:id="@+id/innerFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#ffffff"/>
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="4dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingBottom="4dp"
tools:ignore="UselessParent">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:adjustViewBounds="true"
/>
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="?highContrastTextColor"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>

@ -18,19 +18,32 @@
~ with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="4dp">
android:padding="0dp">
<org.isoron.uhabits.views.CheckmarkView
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
/>
</LinearLayout>
<FrameLayout
android:id="@+id/buttonOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/widget_button_background"
/>
</FrameLayout>
</RelativeLayout>

@ -21,7 +21,7 @@
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="40dp"
android:minWidth="40dp"
android:initialLayout="@layout/widget_checkmark"
android:initialLayout="@layout/widget_wrapper"
android:previewImage="@drawable/widget_preview_checkmark"
android:resizeMode="none"
android:updatePeriodMillis="3600000"

Loading…
Cancel
Save