mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 01:08:50 -06:00
Split InterfaceUtils
This commit is contained in:
@@ -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);
|
||||
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());
|
||||
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();
|
||||
|
||||
return new File(String.format("%s/../databases/%s",
|
||||
context.getApplicationContext().getFilesDir().getPath(),
|
||||
databaseFilename));
|
||||
String format = "%s/../databases/%s";
|
||||
String filename = String.format(format, root, 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);
|
||||
|
||||
101
app/src/main/java/org/isoron/uhabits/utils/StyledResources.java
Normal file
101
app/src/main/java/org/isoron/uhabits/utils/StyledResources.java
Normal file
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user