Split InterfaceUtils

pull/151/head
Alinson S. Xavier 9 years ago
parent 748cec06a8
commit ebd294be63

@ -61,7 +61,8 @@ public abstract class BaseRootView extends FrameLayout
return getContext().getResources().getColor(R.color.grey_900);
}
return InterfaceUtils.getStyledColor(getContext(), R.attr.colorPrimary);
StyledResources res = new StyledResources(getContext());
return res.getColor(R.attr.colorPrimary);
}
protected void initToolbar()

@ -108,6 +108,25 @@ public abstract class BaseScreen
rootView.invalidate();
}
public void invalidateToolbar()
{
if (rootView == null) return;
activity.runOnUiThread(() -> {
Toolbar toolbar = rootView.getToolbar();
activity.setSupportActionBar(toolbar);
ActionBar actionBar = activity.getSupportActionBar();
if (actionBar == null) return;
actionBar.setDisplayHomeAsUpEnabled(rootView.getDisplayHomeAsUp());
int color = rootView.getToolbarColor();
setActionBarColor(actionBar, color);
setStatusBarColor(color);
setupToolbarElevation(toolbar);
});
}
/**
* Called when another Activity has finished, and has returned some result.
*
@ -136,25 +155,6 @@ public abstract class BaseScreen
activity.setBaseMenu(menu);
}
public void showMessage(@StringRes int stringId)
{
activity.showMessage(stringId);
}
/**
* Sets the root view for this screen.
*
* @param rootView the root view for this screen.
*/
protected void setRootView(@Nullable BaseRootView rootView)
{
this.rootView = rootView;
activity.setContentView(rootView);
if (rootView == null) return;
invalidateToolbar();
}
/**
* Sets the menu to be shown when a selection is active on the screen.
*
@ -165,12 +165,22 @@ public abstract class BaseScreen
this.selectionMenu = menu;
}
public void showSendEmailScreen(String to, String subject, String content)
public void showMessage(@StringRes int stringId)
{
activity.showMessage(stringId);
}
public void showSendEmailScreen(@StringRes int toId,
@StringRes int subjectId,
String content)
{
String to = activity.getString(toId);
String subject = activity.getString(subjectId);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{to});
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{ to });
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, content);
activity.startActivity(intent);
@ -197,23 +207,18 @@ public abstract class BaseScreen
activity.startSupportActionMode(new ActionModeWrapper());
}
public void invalidateToolbar()
/**
* Sets the root view for this screen.
*
* @param rootView the root view for this screen.
*/
protected void setRootView(@Nullable BaseRootView rootView)
{
this.rootView = rootView;
activity.setContentView(rootView);
if (rootView == null) return;
activity.runOnUiThread(() -> {
Toolbar toolbar = rootView.getToolbar();
activity.setSupportActionBar(toolbar);
ActionBar actionBar = activity.getSupportActionBar();
if (actionBar == null) return;
actionBar.setDisplayHomeAsUpEnabled(rootView.getDisplayHomeAsUp());
int color = rootView.getToolbarColor();
setActionBarColor(actionBar, color);
setStatusBarColor(color);
setupToolbarElevation(toolbar);
});
invalidateToolbar();
}
private void setActionBarColor(@NonNull ActionBar actionBar, int color)

@ -74,16 +74,16 @@ public class BaseSystem
@NonNull
public File dumpBugReportToFile() throws IOException
{
String date = DateFormats.getBackupDateFormat().format(
DateUtils.getLocalTime());
String date =
DateFormats.getBackupDateFormat().format(DateUtils.getLocalTime());
if (context == null) throw new RuntimeException(
"application context should not be null");
"application context should not be null");
File dir = FileUtils.getFilesDir("Logs");
if (dir == null) throw new IOException("log dir should not be null");
File logFile = new File(
String.format("%s/Log %s.txt", dir.getPath(), date));
File logFile =
new File(String.format("%s/Log %s.txt", dir.getPath(), date));
FileWriter output = new FileWriter(logFile);
output.write(getBugReport());
output.close();
@ -104,7 +104,12 @@ public class BaseSystem
{
String logcat = getLogcat();
String deviceInfo = getDeviceInfo();
return deviceInfo + "\n" + logcat;
String log = "---------- BUG REPORT BEGINS ----------\n";
log += deviceInfo + "\n" + logcat;
log += "---------- BUG REPORT ENDS ------------\n";
return log;
}
public String getLogcat() throws IOException
@ -140,27 +145,25 @@ public class BaseSystem
{
if (context == null) return "null context\n";
WindowManager wm = (WindowManager) context.getSystemService(
Context.WINDOW_SERVICE);
return String.format("App Version Name: %s\n",
BuildConfig.VERSION_NAME) +
String.format("App Version Code: %s\n",
BuildConfig.VERSION_CODE) +
String.format("OS Version: %s (%s)\n",
System.getProperty("os.version"),
Build.VERSION.INCREMENTAL) +
String.format("OS API Level: %s\n", Build.VERSION.SDK) +
String.format("Device: %s\n", Build.DEVICE) +
String.format("Model (Product): %s (%s)\n", Build.MODEL,
Build.PRODUCT) +
String.format("Manufacturer: %s\n", Build.MANUFACTURER) +
String.format("Other tags: %s\n", Build.TAGS) +
String.format("Screen Width: %s\n",
wm.getDefaultDisplay().getWidth()) +
String.format("Screen Height: %s\n",
wm.getDefaultDisplay().getHeight()) +
String.format("External storage state: %s\n\n",
Environment.getExternalStorageState());
WindowManager wm =
(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
return
String.format("App Version Name: %s\n", BuildConfig.VERSION_NAME) +
String.format("App Version Code: %s\n", BuildConfig.VERSION_CODE) +
String.format("OS Version: %s (%s)\n",
System.getProperty("os.version"), Build.VERSION.INCREMENTAL) +
String.format("OS API Level: %s\n", Build.VERSION.SDK) +
String.format("Device: %s\n", Build.DEVICE) +
String.format("Model (Product): %s (%s)\n", Build.MODEL,
Build.PRODUCT) +
String.format("Manufacturer: %s\n", Build.MANUFACTURER) +
String.format("Other tags: %s\n", Build.TAGS) +
String.format("Screen Width: %s\n",
wm.getDefaultDisplay().getWidth()) +
String.format("Screen Height: %s\n",
wm.getDefaultDisplay().getHeight()) +
String.format("External storage state: %s\n\n",
Environment.getExternalStorageState());
}
}

@ -76,8 +76,8 @@ public class AboutActivity extends BaseActivity implements View.OnClickListener
setContentView(R.layout.about);
int color =
InterfaceUtils.getStyledColor(this, R.attr.aboutScreenColor);
StyledResources res = new StyledResources(this);
int color = res.getColor(R.attr.aboutScreenColor);
BaseScreen.setupActionBarColor(this, color);

@ -33,12 +33,12 @@ public class ColorPickerDialog extends com.android.colorpicker.ColorPickerDialog
{
ColorPickerDialog dialog = new ColorPickerDialog();
Context context = dialog.getContext();
StyledResources res = new StyledResources(context);
int color = ColorUtils.getColor(context, paletteColor);
dialog.initialize(R.string.color_picker_default_title,
ColorUtils.getPalette(context), color, 4,
com.android.colorpicker.ColorPickerDialog.SIZE_SMALL);
dialog.initialize(R.string.color_picker_default_title, res.getPalette(),
color, 4, com.android.colorpicker.ColorPickerDialog.SIZE_SMALL);
return dialog;
}

@ -267,10 +267,9 @@ public class FrequencyChart extends ScrollableChart
private void initColors()
{
textColor = InterfaceUtils.getStyledColor(getContext(),
R.attr.mediumContrastTextColor);
gridColor = InterfaceUtils.getStyledColor(getContext(),
R.attr.lowContrastTextColor);
StyledResources res = new StyledResources(getContext());
textColor = res.getColor(R.attr.mediumContrastTextColor);
gridColor = res.getColor(R.attr.lowContrastTextColor);
colors = new int[4];
colors[0] = gridColor;

@ -353,6 +353,8 @@ public class HistoryChart extends ScrollableChart
private void initColors()
{
StyledResources res = new StyledResources(getContext());
if (isBackgroundTransparent)
primaryColor = ColorUtils.setMinValue(primaryColor, 0.75f);
@ -372,14 +374,12 @@ public class HistoryChart extends ScrollableChart
else
{
colors = new int[3];
colors[0] = InterfaceUtils.getStyledColor(getContext(),
R.attr.lowContrastTextColor);
colors[0] = res.getColor(R.attr.lowContrastTextColor);
colors[1] = Color.argb(127, red, green, blue);
colors[2] = primaryColor;
textColor = InterfaceUtils.getStyledColor(getContext(),
R.attr.mediumContrastTextColor);
reverseTextColor = InterfaceUtils.getStyledColor(getContext(),
R.attr.highContrastReverseTextColor);
textColor = res.getColor(R.attr.mediumContrastTextColor);
reverseTextColor =
res.getColor(R.attr.highContrastReverseTextColor);
}
}

@ -29,6 +29,7 @@ import android.view.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.*;
import static org.isoron.uhabits.utils.AttributeSetUtils.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*;
public class RingView extends View
@ -91,8 +92,7 @@ public class RingView extends View
precision = getFloatAttribute(ctx, attrs, "precision", 0.01f);
color = getColorAttribute(ctx, attrs, "color", 0);
backgroundColor =
getColorAttribute(ctx, attrs, "backgroundColor", null);
backgroundColor = getColorAttribute(ctx, attrs, "backgroundColor", null);
inactiveColor = getColorAttribute(ctx, attrs, "inactiveColor", null);
thickness = getFloatAttribute(ctx, attrs, "thickness", 0);
@ -102,10 +102,10 @@ public class RingView extends View
ctx.getResources().getDimension(R.dimen.smallTextSize);
textSize = getFloatAttribute(ctx, attrs, "textSize", defaultTextSize);
textSize = spToPixels(ctx, textSize);
text = getAttribute(ctx, attrs, "text", "");
text = AttributeSetUtils.getAttribute(ctx, attrs, "text", "");
enableFontAwesome =
getBooleanAttribute(ctx, attrs, "enableFontAwesome", false);
enableFontAwesome = AttributeSetUtils.getBooleanAttribute(ctx, attrs,
"enableFontAwesome", false);
init();
}
@ -234,13 +234,13 @@ public class RingView extends View
pRing.setColor(color);
pRing.setTextAlign(Paint.Align.CENTER);
if (backgroundColor == null) backgroundColor =
InterfaceUtils.getStyledColor(getContext(),
R.attr.cardBackgroundColor);
StyledResources res = new StyledResources(getContext());
if (inactiveColor == null) inactiveColor =
InterfaceUtils.getStyledColor(getContext(),
R.attr.highContrastTextColor);
if (backgroundColor == null)
backgroundColor = res.getColor(R.attr.cardBackgroundColor);
if (inactiveColor == null)
inactiveColor = res.getColor(R.attr.highContrastTextColor);
inactiveColor = ColorUtils.setAlpha(inactiveColor, 0.1f);

@ -402,12 +402,12 @@ public class ScoreChart extends ScrollableChart
private void initColors()
{
Context context = getContext();
StyledResources res = new StyledResources(getContext());
primaryColor = Color.BLACK;
textColor = getStyledColor(context, R.attr.mediumContrastTextColor);
gridColor = getStyledColor(context, R.attr.lowContrastTextColor);
backgroundColor = getStyledColor(context, R.attr.cardBackgroundColor);
textColor = res.getColor(R.attr.mediumContrastTextColor);
gridColor = res.getColor(R.attr.lowContrastTextColor);
backgroundColor = res.getColor(R.attr.cardBackgroundColor);
}
private void initDateFormats()

@ -244,16 +244,15 @@ public class StreakChart extends View
int green = Color.green(primaryColor);
int blue = Color.blue(primaryColor);
StyledResources res = new StyledResources(getContext());
colors = new int[4];
colors[3] = primaryColor;
colors[2] = Color.argb(192, red, green, blue);
colors[1] = Color.argb(96, red, green, blue);
colors[0] = InterfaceUtils.getStyledColor(getContext(),
R.attr.lowContrastTextColor);
textColor = InterfaceUtils.getStyledColor(getContext(),
R.attr.mediumContrastTextColor);
reverseTextColor = InterfaceUtils.getStyledColor(getContext(),
R.attr.highContrastReverseTextColor);
colors[0] = res.getColor(R.attr.lowContrastTextColor);
textColor = res.getColor(R.attr.mediumContrastTextColor);
reverseTextColor = res.getColor(R.attr.highContrastReverseTextColor);
}
private void initPaints()

@ -55,9 +55,6 @@ public class ListHabitsController
@NonNull
private final CommandRunner commandRunner;
@NonNull
private final ReminderScheduler reminderScheduler;
@NonNull
private final TaskRunner taskRunner;
@ -75,7 +72,6 @@ public class ListHabitsController
prefs = component.getPreferences();
taskRunner = component.getTaskRunner();
commandRunner = component.getCommandRunner();
reminderScheduler = component.getReminderScheduler();
}
public void onExportCSV()
@ -150,12 +146,10 @@ public class ListHabitsController
try
{
String log = "---------- BUG REPORT BEGINS ----------\n";
log += system.getBugReport();
log += "---------- BUG REPORT ENDS ------------\n";
String to = "dev@loophabits.org";
String subject = "Bug Report - Loop Habit Tracker";
screen.showSendEmailScreen(log, to, subject);
String log = system.getBugReport();
int to = R.string.bugReportTo;
int subject = R.string.bugReportSubject;
screen.showSendEmailScreen(to, subject, log);
}
catch (IOException e)
{
@ -172,6 +166,8 @@ public class ListHabitsController
if (prefs.isFirstRun()) onFirstRun();
new Handler().postDelayed(() -> {
ReminderScheduler reminderScheduler =
HabitsApplication.getComponent().getReminderScheduler();
taskRunner.execute(() -> reminderScheduler.schedule(habitList));
HabitsApplication.getWidgetUpdater().updateWidgets();
}, 1000);

@ -40,6 +40,8 @@ public class CheckmarkButtonView extends FrameLayout
@BindView(R.id.tvCheck)
TextView tvCheck;
private StyledResources res;
public CheckmarkButtonView(Context context)
{
super(context);
@ -76,8 +78,7 @@ public class CheckmarkButtonView extends FrameLayout
@Override
protected void onDraw(Canvas canvas)
{
int lowContrastColor = InterfaceUtils.getStyledColor(getContext(),
R.attr.lowContrastTextColor);
int lowContrastColor = res.getColor(R.attr.lowContrastTextColor);
if (value == Checkmark.CHECKED_EXPLICITLY)
{
@ -106,6 +107,8 @@ public class CheckmarkButtonView extends FrameLayout
inflate(getContext(), R.layout.list_habits_card_checkmark, null));
ButterKnife.bind(this);
res = new StyledResources(getContext());
setWillNotDraw(false);
setHapticFeedbackEnabled(false);

@ -36,11 +36,11 @@ import java.util.*;
import butterknife.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*;
import static android.os.Build.VERSION.*;
import static android.os.Build.VERSION_CODES.*;
public class HabitCardView extends FrameLayout
{
private Habit habit;
@BindView(R.id.checkmarkPanel)
CheckmarkPanelView checkmarkPanel;
@ -56,6 +56,8 @@ public class HabitCardView extends FrameLayout
private final Context context = getContext();
private StyledResources res;
public HabitCardView(Context context)
{
super(context);
@ -68,12 +70,6 @@ public class HabitCardView extends FrameLayout
init();
}
public HabitCardView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
init();
}
public void setCheckmarkValues(int checkmarks[])
{
checkmarkPanel.setCheckmarkValues(checkmarks);
@ -89,7 +85,6 @@ public class HabitCardView extends FrameLayout
public void setHabit(Habit habit)
{
this.habit = habit;
int color = getActiveColor(habit);
label.setText(habit.getName());
@ -130,8 +125,7 @@ public class HabitCardView extends FrameLayout
private int getActiveColor(Habit habit)
{
int mediumContrastColor =
getStyledColor(context, R.attr.mediumContrastTextColor);
int mediumContrastColor = res.getColor(R.attr.mediumContrastTextColor);
int activeColor = ColorUtils.getColor(context, habit.getColor());
if (habit.isArchived()) activeColor = mediumContrastColor;
@ -143,11 +137,13 @@ public class HabitCardView extends FrameLayout
setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
res = new StyledResources(getContext());
inflate(context, R.layout.list_habits_card, this);
ButterKnife.bind(this);
innerFrame.setOnTouchListener((v, event) -> {
if (android.os.Build.VERSION.SDK_INT >= 21)
if (SDK_INT >= LOLLIPOP)
v.getBackground().setHotspot(event.getX(), event.getY());
return false;
});
@ -189,7 +185,7 @@ public class HabitCardView extends FrameLayout
private void triggerRipple(final float x, final float y)
{
final Drawable background = innerFrame.getBackground();
if (android.os.Build.VERSION.SDK_INT >= 21) background.setHotspot(x, y);
if (SDK_INT >= LOLLIPOP) background.setHotspot(x, y);
background.setState(new int[]{
android.R.attr.state_pressed, android.R.attr.state_enabled
});
@ -198,7 +194,7 @@ public class HabitCardView extends FrameLayout
private void updateBackground(boolean isSelected)
{
if (android.os.Build.VERSION.SDK_INT >= 21)
if (SDK_INT >= LOLLIPOP)
{
if (isSelected)
innerFrame.setBackgroundResource(R.drawable.selected_box);
@ -208,11 +204,11 @@ public class HabitCardView extends FrameLayout
{
Drawable background;
if (isSelected) background =
getStyledDrawable(context, R.attr.selectedBackground);
else background = getStyledDrawable(context, R.attr.cardBackground);
if (isSelected)
background = res.getDrawable(R.attr.selectedBackground);
else background = res.getDrawable(R.attr.cardBackground);
innerFrame.setBackgroundDrawable(background);
innerFrame.setBackground(background);
}
}

@ -31,8 +31,6 @@ import org.isoron.uhabits.utils.*;
import butterknife.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*;
public class ShowHabitRootView extends BaseRootView
implements ModelObservable.Listener
{
@ -63,8 +61,7 @@ public class ShowHabitRootView extends BaseRootView
@NonNull
private Controller controller;
public ShowHabitRootView(@NonNull Context context,
@NonNull Habit habit)
public ShowHabitRootView(@NonNull Context context, @NonNull Habit habit)
{
super(context);
this.habit = habit;
@ -91,16 +88,11 @@ public class ShowHabitRootView extends BaseRootView
return toolbar;
}
public void setController(@NonNull Controller controller)
{
this.controller = controller;
historyCard.setController(controller);
}
@Override
public int getToolbarColor()
{
if (!getStyledBoolean(getContext(), R.attr.useHabitColorAsPrimary))
StyledResources res = new StyledResources(getContext());
if (!res.getBoolean(R.attr.useHabitColorAsPrimary))
return super.getToolbarColor();
return ColorUtils.getColor(getContext(), habit.getColor());
@ -112,6 +104,12 @@ public class ShowHabitRootView extends BaseRootView
controller.onToolbarChanged();
}
public void setController(@NonNull Controller controller)
{
this.controller = controller;
historyCard.setController(controller);
}
@Override
protected void initToolbar()
{
@ -145,6 +143,6 @@ public class ShowHabitRootView extends BaseRootView
public interface Controller extends HistoryCard.Controller
{
default void onToolbarChanged(){}
default void onToolbarChanged() {}
}
}

@ -121,8 +121,8 @@ public class OverviewCard extends HabitCard
monthDiffLabel.setText(formatPercentageDiff(monthDiff));
yearDiffLabel.setText(formatPercentageDiff(yearDiff));
int inactiveColor = InterfaceUtils.getStyledColor(getContext(),
R.attr.mediumContrastTextColor);
StyledResources res = new StyledResources(getContext());
int inactiveColor = res.getColor(R.attr.mediumContrastTextColor);
monthDiffLabel.setTextColor(monthDiff >= 0 ? color : inactiveColor);
yearDiffLabel.setTextColor(yearDiff >= 0 ? color : inactiveColor);

@ -51,6 +51,8 @@ public class ScoreCard extends HabitCard
private TaskRunner taskRunner;
private Preferences prefs;
public ScoreCard(Context context)
{
super(context);
@ -94,12 +96,13 @@ public class ScoreCard extends HabitCard
private int getDefaultSpinnerPosition()
{
if (isInEditMode()) return 0;
return InterfaceUtils.getDefaultScoreSpinnerPosition(getContext());
return prefs.getDefaultScoreSpinnerPosition();
}
private void init()
{
taskRunner = HabitsApplication.getComponent().getTaskRunner();
prefs = HabitsApplication.getComponent().getPreferences();
inflate(getContext(), R.layout.show_habit_score, this);
ButterKnife.bind(this);
@ -121,7 +124,7 @@ public class ScoreCard extends HabitCard
{
if (isInEditMode()) return;
InterfaceUtils.setDefaultScoreSpinnerPosition(getContext(), position);
prefs.setDefaultScoreSpinnerPosition(position);
bucketSize = BUCKET_SIZES[position];
}

@ -36,8 +36,8 @@ public class SettingsActivity extends BaseActivity
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_activity);
int color =
InterfaceUtils.getStyledColor(this, R.attr.aboutScreenColor);
StyledResources res = new StyledResources(this);
int color = res.getColor(R.attr.aboutScreenColor);
BaseScreen.setupActionBarColor(this, color);
}
}

@ -24,6 +24,7 @@ import android.content.*;
import android.support.annotation.*;
import android.view.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.common.views.*;
@ -38,10 +39,13 @@ public class ScoreWidget extends BaseWidget
@NonNull
private Habit habit;
private final Preferences prefs;
public ScoreWidget(@NonNull Context context, int id, @NonNull Habit habit)
{
super(context, id);
this.habit = habit;
prefs = HabitsApplication.getComponent().getPreferences();
}
@Override
@ -54,8 +58,7 @@ public class ScoreWidget extends BaseWidget
@Override
public void refreshData(View view)
{
int defaultScoreInterval =
InterfaceUtils.getDefaultScoreSpinnerPosition(getContext());
int defaultScoreInterval = prefs.getDefaultScoreSpinnerPosition();
int size = ScoreCard.BUCKET_SIZES[defaultScoreInterval];
GraphWidgetView widgetView = (GraphWidgetView) view;

@ -60,33 +60,30 @@ public class CheckmarkWidgetView extends HabitWidgetView
{
if (backgroundPaint == null || frame == null || ring == null) return;
Context context = getContext();
StyledResources res = new StyledResources(getContext());
String text;
int backgroundColor;
int foregroundColor;
int bgColor;
int fgColor;
switch (checkmarkValue)
{
case Checkmark.CHECKED_EXPLICITLY:
text = getResources().getString(R.string.fa_check);
backgroundColor = activeColor;
foregroundColor = InterfaceUtils.getStyledColor(context,
R.attr.highContrastReverseTextColor);
bgColor = activeColor;
fgColor = res.getColor(R.attr.highContrastReverseTextColor);
setShadowAlpha(0x4f);
rebuildBackground();
backgroundPaint.setColor(backgroundColor);
backgroundPaint.setColor(bgColor);
frame.setBackgroundDrawable(background);
break;
case Checkmark.CHECKED_IMPLICITLY:
text = getResources().getString(R.string.fa_check);
backgroundColor = InterfaceUtils.getStyledColor(context,
R.attr.cardBackgroundColor);
foregroundColor = InterfaceUtils.getStyledColor(context,
R.attr.mediumContrastTextColor);
bgColor = res.getColor(R.attr.cardBackgroundColor);
fgColor = res.getColor(R.attr.mediumContrastTextColor);
setShadowAlpha(0x00);
rebuildBackground();
@ -96,10 +93,8 @@ public class CheckmarkWidgetView extends HabitWidgetView
case Checkmark.UNCHECKED:
default:
text = getResources().getString(R.string.fa_times);
backgroundColor = InterfaceUtils.getStyledColor(context,
R.attr.cardBackgroundColor);
foregroundColor = InterfaceUtils.getStyledColor(context,
R.attr.mediumContrastTextColor);
bgColor = res.getColor(R.attr.cardBackgroundColor);
fgColor = res.getColor(R.attr.mediumContrastTextColor);
setShadowAlpha(0x00);
rebuildBackground();
@ -108,17 +103,22 @@ public class CheckmarkWidgetView extends HabitWidgetView
}
ring.setPercentage(percentage);
ring.setColor(foregroundColor);
ring.setBackgroundColor(backgroundColor);
ring.setColor(fgColor);
ring.setBackgroundColor(bgColor);
ring.setText(text);
label.setText(name);
label.setTextColor(foregroundColor);
label.setTextColor(fgColor);
requestLayout();
postInvalidate();
}
public void setActiveColor(int activeColor)
{
this.activeColor = activeColor;
}
public void setCheckmarkValue(int checkmarkValue)
{
this.checkmarkValue = checkmarkValue;
@ -134,11 +134,6 @@ public class CheckmarkWidgetView extends HabitWidgetView
this.percentage = percentage;
}
public void setActiveColor(int activeColor)
{
this.activeColor = activeColor;
}
@Override
@NonNull
protected Integer getInnerLayoutId()

@ -33,6 +33,8 @@ import org.isoron.uhabits.utils.*;
import java.util.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*;
public abstract class HabitWidgetView extends FrameLayout
{
@Nullable
@ -45,6 +47,8 @@ public abstract class HabitWidgetView extends FrameLayout
private int shadowAlpha;
private StyledResources res;
public HabitWidgetView(Context context)
{
super(context);
@ -70,15 +74,14 @@ public abstract class HabitWidgetView extends FrameLayout
{
Context context = getContext();
int backgroundAlpha = (int) (255 *
InterfaceUtils.getStyledFloat(context,
R.attr.widgetBackgroundAlpha));
int backgroundAlpha =
(int) (255 * res.getFloat(R.attr.widgetBackgroundAlpha));
int shadowRadius = (int) InterfaceUtils.dpToPixels(context, 2);
int shadowOffset = (int) InterfaceUtils.dpToPixels(context, 1);
int shadowRadius = (int) dpToPixels(context, 2);
int shadowOffset = (int) dpToPixels(context, 1);
int shadowColor = Color.argb(shadowAlpha, 0, 0, 0);
float cornerRadius = InterfaceUtils.dpToPixels(context, 5);
float cornerRadius = dpToPixels(context, 5);
float[] radii = new float[8];
Arrays.fill(radii, cornerRadius);
@ -94,8 +97,7 @@ public abstract class HabitWidgetView extends FrameLayout
backgroundPaint = innerDrawable.getPaint();
backgroundPaint.setShadowLayer(shadowRadius, shadowOffset, shadowOffset,
shadowColor);
backgroundPaint.setColor(
InterfaceUtils.getStyledColor(context, R.attr.cardBackgroundColor));
backgroundPaint.setColor(res.getColor(R.attr.cardBackgroundColor));
backgroundPaint.setAlpha(backgroundAlpha);
frame = (ViewGroup) findViewById(R.id.frame);
@ -105,8 +107,8 @@ public abstract class HabitWidgetView extends FrameLayout
private void init()
{
inflate(getContext(), getInnerLayoutId(), this);
shadowAlpha = (int) (255 * InterfaceUtils.getStyledFloat(getContext(),
R.attr.widgetShadowAlpha));
res = new StyledResources(getContext());
shadowAlpha = (int) (255 * res.getFloat(R.attr.widgetShadowAlpha));
rebuildBackground();
}
}

@ -0,0 +1,77 @@
/*
* 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.utils;
import android.content.*;
import android.support.annotation.*;
import android.support.annotation.Nullable;
import android.util.*;
import org.jetbrains.annotations.*;
public class AttributeSetUtils
{
public static final String ISORON_NAMESPACE = "http://isoron.org/android";
@Nullable
public static String getAttribute(@NonNull Context context,
@NonNull AttributeSet attrs,
@NonNull String name,
@Nullable String defaultValue)
{
int resId = attrs.getAttributeResourceValue(ISORON_NAMESPACE, name, 0);
if (resId != 0) return context.getResources().getString(resId);
String value = attrs.getAttributeValue(ISORON_NAMESPACE, name);
if (value != null) return value;
else return defaultValue;
}
public static boolean getBooleanAttribute(@NonNull Context context,
@NonNull AttributeSet attrs,
@NonNull String name,
boolean defaultValue)
{
String boolText = getAttribute(context, attrs, name, null);
if (boolText != null) return Boolean.parseBoolean(boolText);
else return defaultValue;
}
@Contract("_,_,_,!null -> !null")
public static Integer getColorAttribute(@NonNull Context context,
@NonNull AttributeSet attrs,
@NonNull String name,
@Nullable Integer defaultValue)
{
int resId = attrs.getAttributeResourceValue(ISORON_NAMESPACE, name, 0);
if (resId != 0) return context.getResources().getColor(resId);
else return defaultValue;
}
public static float getFloatAttribute(@NonNull Context context,
@NonNull AttributeSet attrs,
@NonNull String name,
float defaultValue)
{
String number = getAttribute(context, attrs, name, null);
if (number != null) return Float.parseFloat(number);
else return defaultValue;
}
}

@ -23,8 +23,6 @@ import android.content.*;
import android.graphics.*;
import android.util.*;
import org.isoron.uhabits.*;
public abstract class ColorUtils
{
public static String CSV_PALETTE[] = {
@ -45,7 +43,8 @@ public abstract class ColorUtils
public static int colorToPaletteIndex(Context context, int color)
{
int[] palette = getPalette(context);
StyledResources res = new StyledResources(context);
int[] palette = res.getPalette();
for (int k = 0; k < palette.length; k++)
if (palette[k] == color) return k;
@ -79,7 +78,8 @@ public abstract class ColorUtils
if (context == null)
throw new IllegalArgumentException("Context is null");
int palette[] = getPalette(context);
StyledResources res = new StyledResources(context);
int palette[] = res.getPalette();
if (paletteColor < 0 || paletteColor >= palette.length)
{
Log.w("ColorHelper",
@ -91,15 +91,6 @@ public abstract class ColorUtils
return palette[paletteColor];
}
public static int[] getPalette(Context context)
{
int resourceId =
InterfaceUtils.getStyleResource(context, R.attr.palette);
if (resourceId < 0) throw new RuntimeException("resource not found");
return context.getResources().getIntArray(resourceId);
}
public static int mixColors(int color1, int color2, float amount)
{
final byte ALPHA_CHANNEL = 24;

@ -20,7 +20,6 @@
package org.isoron.uhabits.utils;
import android.content.*;
import android.database.*;
import android.support.annotation.*;
import com.activeandroid.*;
@ -51,23 +50,20 @@ public abstract class DatabaseUtils
public static File getDatabaseFile()
{
Context context = HabitsApplication.getContext();
if (context == null)
throw new RuntimeException("No application context found");
String databaseFilename = getDatabaseFilename();
String root = context.getFilesDir().getPath();
String format = "%s/../databases/%s";
String filename = String.format(format, root, databaseFilename);
return new File(String.format("%s/../databases/%s",
context.getApplicationContext().getFilesDir().getPath(),
databaseFilename));
return new File(filename);
}
@NonNull
public static String getDatabaseFilename()
{
String databaseFilename = BuildConfig.databaseFilename;
if (HabitsApplication.isTestMode()) databaseFilename = "test.db";
return databaseFilename;
}
@ -75,9 +71,6 @@ public abstract class DatabaseUtils
public static void initializeActiveAndroid()
{
Context context = HabitsApplication.getContext();
if (context == null) throw new RuntimeException(
"application context should not be null");
Configuration dbConfig = new Configuration.Builder(context)
.setDatabaseName(getDatabaseFilename())
.setDatabaseVersion(BuildConfig.databaseVersion)
@ -88,33 +81,16 @@ public abstract class DatabaseUtils
ActiveAndroid.initialize(dbConfig);
}
public static long longQuery(String query, String args[])
{
Cursor c = null;
try
{
c = Cache.openDatabase().rawQuery(query, args);
if (!c.moveToFirst()) return 0;
return c.getLong(0);
}
finally
{
if (c != null) c.close();
}
}
@SuppressWarnings("ResultOfMethodCallIgnored")
public static String saveDatabaseCopy(File dir) throws IOException
{
File db = getDatabaseFile();
SimpleDateFormat dateFormat = DateFormats.getBackupDateFormat();
String date = dateFormat.format(DateUtils.getLocalTime());
File dbCopy = new File(
String.format("%s/Loop Habits Backup %s.db", dir.getAbsolutePath(),
date));
String format = "%s/Loop Habits Backup %s.db";
String filename = String.format(format, dir.getAbsolutePath(), date);
File db = getDatabaseFile();
File dbCopy = new File(filename);
FileUtils.copy(db, dbCopy);
return dbCopy.getAbsolutePath();

@ -30,7 +30,6 @@ import static java.util.Calendar.*;
public abstract class DateUtils
{
private static Long fixedLocalTime = null;
/**

@ -19,35 +19,33 @@
package org.isoron.uhabits.utils;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Debug;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.app.*;
import android.content.*;
import android.content.res.*;
import android.graphics.*;
import android.preference.*;
import android.util.*;
import org.isoron.uhabits.HabitsApplication;
import org.isoron.uhabits.R;
import org.isoron.uhabits.*;
import java.util.Locale;
import java.util.*;
public abstract class InterfaceUtils
{
public static final String ISORON_NAMESPACE = "http://isoron.org/android";
public static final int THEME_LIGHT = 0;
// TODO: Move this to another place, or detect automatically
private static String fullyTranslatedLanguages[] = {
"ca", "zh", "en", "de", "in", "it", "ko", "pl", "pt", "es", "tk", "uk",
"ja", "fr", "hr", "sl"
};
public static final int THEME_DARK = 1;
public static final int THEME_LIGHT = 0;
public static Integer fixedTheme;
private static Typeface fontAwesome;
private static Integer fixedTheme;
public static void setFixedTheme(Integer fixedTheme)
{
@ -62,49 +60,6 @@ public abstract class InterfaceUtils
return fontAwesome;
}
public static String getAttribute(Context context, AttributeSet attrs, String name,
String defaultValue)
{
int resId = attrs.getAttributeResourceValue(ISORON_NAMESPACE, name, 0);
if (resId != 0) return context.getResources().getString(resId);
String value = attrs.getAttributeValue(ISORON_NAMESPACE, name);
if(value != null) return value;
else return defaultValue;
}
public static Integer getColorAttribute(Context context, AttributeSet attrs, String name,
Integer defaultValue)
{
int resId = attrs.getAttributeResourceValue(ISORON_NAMESPACE, name, 0);
if (resId != 0) return context.getResources().getColor(resId);
else return defaultValue;
}
public static int getIntAttribute(Context context, AttributeSet attrs, String name,
int defaultValue)
{
String number = getAttribute(context, attrs, name, null);
if(number != null) return Integer.parseInt(number);
else return defaultValue;
}
public static boolean getBooleanAttribute(Context context, AttributeSet attrs, String name,
boolean defaultValue)
{
String boolText = getAttribute(context, attrs, name, null);
if(boolText != null) return Boolean.parseBoolean(boolText);
else return defaultValue;
}
public static float getFloatAttribute(Context context, AttributeSet attrs, String name,
float defaultValue)
{
String number = getAttribute(context, attrs, name, null);
if(number != null) return Float.parseFloat(number);
else return defaultValue;
}
public static float dpToPixels(Context context, float dp)
{
Resources resources = context.getResources();
@ -119,45 +74,8 @@ public abstract class InterfaceUtils
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, metrics);
}
/**
* Throws a runtime exception if called from the main thread. Useful to make sure that
* slow methods never accidentally slow the application down.
*
* @throws RuntimeException when run from main thread
*/
public static void throwIfMainThread() throws RuntimeException
{
Looper looper = Looper.myLooper();
if(looper == null) return;
if(looper == Looper.getMainLooper())
throw new RuntimeException("This method should never be called from the main thread");
}
public static void startTracing()
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
{
throw new UnsupportedOperationException();
}
else
{
Debug.startMethodTracingSampling("Android/data/org.isoron.uhabits/perf",
32 * 1024 * 1024, 100);
}
}
public static void stopTracing()
{
Debug.stopMethodTracing();
}
public static boolean isLocaleFullyTranslated()
{
// TODO: Move this to another place, or detect automatically
String fullyTranslatedLanguages[] = { "ca", "zh", "en", "de", "in", "it", "ko", "pl", "pt",
"es", "tk", "uk", "ja", "fr", "hr", "sl"};
final String currentLanguage = Locale.getDefault().getLanguage();
for(String lang : fullyTranslatedLanguages)
@ -166,65 +84,6 @@ public abstract class InterfaceUtils
return false;
}
public static float getScreenWidth(Context context)
{
return context.getResources().getDisplayMetrics().widthPixels;
}
public static int getStyledColor(Context context, int attrId)
{
TypedArray ta = getTypedArray(context, attrId);
int color = ta.getColor(0, 0);
ta.recycle();
return color;
}
private static TypedArray getTypedArray(Context context, int attrId)
{
int[] attrs = new int[]{ attrId };
if(fixedTheme != null)
return context.getTheme().obtainStyledAttributes(fixedTheme, attrs);
else
return context.obtainStyledAttributes(attrs);
}
public static Drawable getStyledDrawable(Context context, int attrId)
{
TypedArray ta = getTypedArray(context, attrId);
Drawable drawable = ta.getDrawable(0);
ta.recycle();
return drawable;
}
public static boolean getStyledBoolean(Context context, int attrId)
{
TypedArray ta = getTypedArray(context, attrId);
boolean bool = ta.getBoolean(0, false);
ta.recycle();
return bool;
}
public static float getStyledFloat(Context context, int attrId)
{
TypedArray ta = getTypedArray(context, attrId);
float f = ta.getFloat(0, 0);
ta.recycle();
return f;
}
static int getStyleResource(Context context, int attrId)
{
TypedArray ta = getTypedArray(context, attrId);
int resourceId = ta.getResourceId(0, -1);
ta.recycle();
return resourceId;
}
public static void applyCurrentTheme(Activity activity)
{
switch(getCurrentTheme())
@ -267,20 +126,4 @@ public abstract class InterfaceUtils
{
return getCurrentTheme() == THEME_DARK;
}
public static void setDefaultScoreSpinnerPosition(Context context, int position)
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putInt("pref_score_view_interval", position).apply();
}
public static int getDefaultScoreSpinnerPosition(Context context)
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
int defaultScoreInterval = prefs.getInt("pref_score_view_interval", 1);
if(defaultScoreInterval > 5 || defaultScoreInterval < 0) defaultScoreInterval = 1;
return defaultScoreInterval;
}
}

@ -45,6 +45,19 @@ public class Preferences
return prefs.getInt("pref_default_habit_palette_color", fallbackColor);
}
public int getDefaultScoreSpinnerPosition()
{
int defaultScoreInterval = prefs.getInt("pref_score_view_interval", 1);
if (defaultScoreInterval > 5 || defaultScoreInterval < 0)
defaultScoreInterval = 1;
return defaultScoreInterval;
}
public void setDefaultScoreSpinnerPosition(int position)
{
prefs.edit().putInt("pref_score_view_interval", position).apply();
}
/**
* Returns the number of the last hint shown to the user.
*
@ -70,11 +83,21 @@ public class Preferences
return prefs.getBoolean("pref_show_archived", false);
}
public void setShowArchived(boolean showArchived)
{
prefs.edit().putBoolean("pref_show_archived", showArchived).apply();
}
public boolean getShowCompleted()
{
return prefs.getBoolean("pref_show_completed", true);
}
public void setShowCompleted(boolean showCompleted)
{
prefs.edit().putBoolean("pref_show_completed", showCompleted).apply();
}
public void incrementLaunchCount()
{
int count = prefs.getInt("launch_count", 0);
@ -119,16 +142,6 @@ public class Preferences
.apply();
}
public void setShowCompleted(boolean showCompleted)
{
prefs.edit().putBoolean("pref_show_completed", showCompleted).apply();
}
public void setShowArchived(boolean showArchived)
{
prefs.edit().putBoolean("pref_show_archived", showArchived).apply();
}
public boolean shouldReverseCheckmarks()
{
return prefs.getBoolean("pref_checkmark_reverse_order", false);

@ -0,0 +1,101 @@
/*
* 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.utils;
import android.content.*;
import android.content.res.*;
import android.graphics.drawable.*;
import android.support.annotation.*;
import org.isoron.uhabits.*;
public class StyledResources
{
private final Context context;
public StyledResources(@NonNull Context context)
{
this.context = context;
}
public boolean getBoolean(@AttrRes int attrId)
{
TypedArray ta = getTypedArray(attrId);
boolean bool = ta.getBoolean(0, false);
ta.recycle();
return bool;
}
public int getColor(@AttrRes int attrId)
{
TypedArray ta = getTypedArray(attrId);
int color = ta.getColor(0, 0);
ta.recycle();
return color;
}
public Drawable getDrawable(@AttrRes int attrId)
{
TypedArray ta = getTypedArray(attrId);
Drawable drawable = ta.getDrawable(0);
ta.recycle();
return drawable;
}
public float getFloat(@AttrRes int attrId)
{
TypedArray ta = getTypedArray(attrId);
float f = ta.getFloat(0, 0);
ta.recycle();
return f;
}
public int[] getPalette()
{
int resourceId = getStyleResource(R.attr.palette);
if (resourceId < 0) throw new RuntimeException("resource not found");
return context.getResources().getIntArray(resourceId);
}
int getStyleResource(@AttrRes int attrId)
{
TypedArray ta = getTypedArray(attrId);
int resourceId = ta.getResourceId(0, -1);
ta.recycle();
return resourceId;
}
private TypedArray getTypedArray(@AttrRes int attrId)
{
int[] attrs = new int[]{ attrId };
Integer fixedTheme = InterfaceUtils.fixedTheme;
if (fixedTheme != null)
return context.getTheme().obtainStyledAttributes(fixedTheme, attrs);
return context.obtainStyledAttributes(attrs);
}
}

@ -27,26 +27,28 @@ import android.widget.*;
import org.isoron.uhabits.ui.widgets.*;
import static android.appwidget.AppWidgetManager.*;
import static android.os.Build.VERSION.*;
import static android.os.Build.VERSION_CODES.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*;
public abstract class WidgetUtils
{
@NonNull
public static WidgetDimensions getDimensionsFromOptions(
@NonNull Context context, @NonNull Bundle options)
@NonNull Context ctx, @NonNull Bundle options)
{
if (SDK_INT < JELLY_BEAN)
throw new AssertionError("method requires jelly-bean");
int maxWidth = (int) InterfaceUtils.dpToPixels(context,
options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH));
int maxHeight = (int) InterfaceUtils.dpToPixels(context,
options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT));
int minWidth = (int) InterfaceUtils.dpToPixels(context,
options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH));
int minHeight = (int) InterfaceUtils.dpToPixels(context,
options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT));
int maxWidth =
(int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MAX_WIDTH));
int maxHeight =
(int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MAX_HEIGHT));
int minWidth =
(int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MIN_WIDTH));
int minHeight =
(int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MIN_HEIGHT));
return new WidgetDimensions(minWidth, maxHeight, maxWidth, minHeight);
}

@ -24,6 +24,8 @@
<string name="bugReportURL" formatted="false">mailto:dev@loophabits.org?subject=Bug%20Report%20-%20Loop%20Habit%20Tracker</string>
<string name="sourceCodeURL">https://github.com/iSoron/uhabits</string>
<string name="translateURL">https://poeditor.com/join/project/8DWX5pfjS0</string>
<string name="bugReportTo">dev@loophabits.org</string>
<string name="bugReportSubject">Bug Report - Loop Habit Tracker</string>
<string-array name="snooze_interval_names">
<item>@string/interval_15_minutes</item>

Loading…
Cancel
Save