Add configurable statusbar clock outline
This commit is contained in:
+130
@@ -0,0 +1,130 @@
|
|||||||
|
package se.ajpanton.statusbartweak.runtime.render;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.text.Spannable;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import androidx.appcompat.widget.AppCompatTextView;
|
||||||
|
|
||||||
|
/** Draws the outline with one colour, then restores the original span colours for the text fill. */
|
||||||
|
final class ClockOutlineTextView extends AppCompatTextView {
|
||||||
|
private int sourcePaddingLeft;
|
||||||
|
private int sourcePaddingTop;
|
||||||
|
private int sourcePaddingRight;
|
||||||
|
private int sourcePaddingBottom;
|
||||||
|
private int outlineColor;
|
||||||
|
private float outlineThicknessPx;
|
||||||
|
private ForegroundColorSpan outlineSpan;
|
||||||
|
|
||||||
|
ClockOutlineTextView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean setSourcePadding(int left, int top, int right, int bottom) {
|
||||||
|
if (sourcePaddingLeft == left
|
||||||
|
&& sourcePaddingTop == top
|
||||||
|
&& sourcePaddingRight == right
|
||||||
|
&& sourcePaddingBottom == bottom) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sourcePaddingLeft = left;
|
||||||
|
sourcePaddingTop = top;
|
||||||
|
sourcePaddingRight = right;
|
||||||
|
sourcePaddingBottom = bottom;
|
||||||
|
applyPaddedInsets();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean setOutline(ClockOutlineSpec outline) {
|
||||||
|
int color = outline != null ? outline.color : 0;
|
||||||
|
float thickness = outline != null ? outline.thicknessPx : 0f;
|
||||||
|
if (outlineColor == color && outlineThicknessPx == thickness) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
outlineColor = color;
|
||||||
|
outlineThicknessPx = thickness;
|
||||||
|
outlineSpan = new ForegroundColorSpan(color);
|
||||||
|
applyPaddedInsets();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int outlineInsetPx() {
|
||||||
|
return enabled() ? (int) Math.ceil(outlineThicknessPx) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
if (!enabled()) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Paint paint = getPaint();
|
||||||
|
Paint.Style style = paint.getStyle();
|
||||||
|
float strokeWidth = paint.getStrokeWidth();
|
||||||
|
int color = paint.getColor();
|
||||||
|
ArrayList<SpanState> foregrounds = replaceForegroundColors();
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
paint.setStrokeWidth(outlineThicknessPx * 2f);
|
||||||
|
paint.setColor(outlineColor);
|
||||||
|
try {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
} finally {
|
||||||
|
restoreForegroundColors(foregrounds);
|
||||||
|
paint.setStyle(style);
|
||||||
|
paint.setStrokeWidth(strokeWidth);
|
||||||
|
paint.setColor(color);
|
||||||
|
}
|
||||||
|
super.onDraw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<SpanState> replaceForegroundColors() {
|
||||||
|
if (!(getText() instanceof Spannable text) || text.length() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ForegroundColorSpan[] spans = text.getSpans(0, text.length(), ForegroundColorSpan.class);
|
||||||
|
ArrayList<SpanState> states = new ArrayList<>(spans.length);
|
||||||
|
for (ForegroundColorSpan span : spans) {
|
||||||
|
states.add(new SpanState(
|
||||||
|
span,
|
||||||
|
text.getSpanStart(span),
|
||||||
|
text.getSpanEnd(span),
|
||||||
|
text.getSpanFlags(span)));
|
||||||
|
text.removeSpan(span);
|
||||||
|
}
|
||||||
|
text.setSpan(outlineSpan, 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
return states;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restoreForegroundColors(ArrayList<SpanState> states) {
|
||||||
|
if (!(getText() instanceof Spannable text) || outlineSpan == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
text.removeSpan(outlineSpan);
|
||||||
|
if (states == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (SpanState state : states) {
|
||||||
|
text.setSpan(state.span, state.start, state.end, state.flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean enabled() {
|
||||||
|
return outlineThicknessPx > 0f && ((outlineColor >>> 24) & 0xff) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyPaddedInsets() {
|
||||||
|
int inset = outlineInsetPx();
|
||||||
|
setPadding(
|
||||||
|
sourcePaddingLeft + inset,
|
||||||
|
sourcePaddingTop + inset,
|
||||||
|
sourcePaddingRight + inset,
|
||||||
|
sourcePaddingBottom + inset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private record SpanState(ForegroundColorSpan span, int start, int end, int flags) {
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
-20
@@ -1,7 +1,7 @@
|
|||||||
package se.ajpanton.statusbartweak.runtime.render;
|
package se.ajpanton.statusbartweak.runtime.render;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.text.style.ForegroundColorSpan;
|
import android.text.style.ForegroundColorSpan;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -19,6 +19,10 @@ final class ClockProxyRenderer {
|
|||||||
private final WeakHashMap<ViewGroup, ArrayList<TextView>> rowsByHost = new WeakHashMap<>();
|
private final WeakHashMap<ViewGroup, ArrayList<TextView>> rowsByHost = new WeakHashMap<>();
|
||||||
|
|
||||||
void render(ViewGroup host, ClockPlacement placement) {
|
void render(ViewGroup host, ClockPlacement placement) {
|
||||||
|
render(host, placement, ClockOutlineSpec.NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(ViewGroup host, ClockPlacement placement, ClockOutlineSpec outline) {
|
||||||
if (host == null || placement == null || placement.rows.isEmpty()) {
|
if (host == null || placement == null || placement.rows.isEmpty()) {
|
||||||
clear(host);
|
clear(host);
|
||||||
return;
|
return;
|
||||||
@@ -36,13 +40,8 @@ final class ClockProxyRenderer {
|
|||||||
views.clear();
|
views.clear();
|
||||||
hostChanged = true;
|
hostChanged = true;
|
||||||
}
|
}
|
||||||
while (views.size() > placement.rows.size()) {
|
|
||||||
TextView view = views.remove(views.size() - 1);
|
|
||||||
detachFromParent(view);
|
|
||||||
hostChanged = true;
|
|
||||||
}
|
|
||||||
while (views.size() < placement.rows.size()) {
|
while (views.size() < placement.rows.size()) {
|
||||||
TextView view = new TextView(host.getContext());
|
TextView view = new ClockOutlineTextView(host.getContext());
|
||||||
view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
|
view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
|
||||||
views.add(view);
|
views.add(view);
|
||||||
host.addView(view);
|
host.addView(view);
|
||||||
@@ -50,10 +49,13 @@ final class ClockProxyRenderer {
|
|||||||
}
|
}
|
||||||
for (int i = 0; i < placement.rows.size(); i++) {
|
for (int i = 0; i < placement.rows.size(); i++) {
|
||||||
ClockRow row = placement.rows.get(i);
|
ClockRow row = placement.rows.get(i);
|
||||||
TextView view = views.get(i);
|
ClockOutlineTextView view = (ClockOutlineTextView) views.get(i);
|
||||||
if (copyTextStyleIfChanged(placement.source, view, placement.textSizePx)) {
|
if (copyTextStyleIfChanged(placement.source, view, placement.textSizePx)) {
|
||||||
hostChanged = true;
|
hostChanged = true;
|
||||||
}
|
}
|
||||||
|
if (view.setOutline(outline)) {
|
||||||
|
hostChanged = true;
|
||||||
|
}
|
||||||
if (applyTextColorOverrideIfNeeded(view, placement.textColorOverride)) {
|
if (applyTextColorOverrideIfNeeded(view, placement.textColorOverride)) {
|
||||||
hostChanged = true;
|
hostChanged = true;
|
||||||
}
|
}
|
||||||
@@ -61,7 +63,7 @@ final class ClockProxyRenderer {
|
|||||||
hostChanged = true;
|
hostChanged = true;
|
||||||
}
|
}
|
||||||
if (!sameTextAndColorSpans(view.getText(), row.text)) {
|
if (!sameTextAndColorSpans(view.getText(), row.text)) {
|
||||||
view.setText(row.text);
|
view.setText(row.text, TextView.BufferType.SPANNABLE);
|
||||||
hostChanged = true;
|
hostChanged = true;
|
||||||
}
|
}
|
||||||
if (!Objects.equals(view.getContentDescription(), placement.contentDescription)) {
|
if (!Objects.equals(view.getContentDescription(), placement.contentDescription)) {
|
||||||
@@ -76,21 +78,24 @@ final class ClockProxyRenderer {
|
|||||||
view.setAlpha(1f);
|
view.setAlpha(1f);
|
||||||
hostChanged = true;
|
hostChanged = true;
|
||||||
}
|
}
|
||||||
int left = placement.bounds.left + row.x;
|
int inset = view.outlineInsetPx();
|
||||||
int top = placement.bounds.top + row.y;
|
int left = placement.bounds.left + row.x - inset;
|
||||||
|
int top = placement.bounds.top + row.y - inset;
|
||||||
|
int width = row.width + 2 * inset;
|
||||||
|
int height = row.height + 2 * inset;
|
||||||
int scrollX = Math.max(0, row.clipLeft);
|
int scrollX = Math.max(0, row.clipLeft);
|
||||||
if (view.getScrollX() != scrollX) {
|
if (view.getScrollX() != scrollX) {
|
||||||
view.setScrollX(scrollX);
|
view.setScrollX(scrollX);
|
||||||
hostChanged = true;
|
hostChanged = true;
|
||||||
}
|
}
|
||||||
if (applyTextLayoutParams(host, view, left, top, row.width, row.height)) {
|
if (applyTextLayoutParams(host, view, left, top, width, height)) {
|
||||||
hostChanged = true;
|
hostChanged = true;
|
||||||
}
|
}
|
||||||
if (view.getLeft() != left
|
if (view.getLeft() != left
|
||||||
|| view.getTop() != top
|
|| view.getTop() != top
|
||||||
|| view.getRight() != left + row.width
|
|| view.getRight() != left + width
|
||||||
|| view.getBottom() != top + row.height) {
|
|| view.getBottom() != top + height) {
|
||||||
view.layout(left, top, left + row.width, top + row.height);
|
view.layout(left, top, left + width, top + height);
|
||||||
hostChanged = true;
|
hostChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,7 +216,13 @@ final class ClockProxyRenderer {
|
|||||||
target.setHorizontallyScrolling(true);
|
target.setHorizontallyScrolling(true);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (target.getPaddingLeft() != source.getPaddingLeft()
|
if (target instanceof ClockOutlineTextView outlineTarget) {
|
||||||
|
changed |= outlineTarget.setSourcePadding(
|
||||||
|
source.getPaddingLeft(),
|
||||||
|
source.getPaddingTop(),
|
||||||
|
source.getPaddingRight(),
|
||||||
|
source.getPaddingBottom());
|
||||||
|
} else if (target.getPaddingLeft() != source.getPaddingLeft()
|
||||||
|| target.getPaddingTop() != source.getPaddingTop()
|
|| target.getPaddingTop() != source.getPaddingTop()
|
||||||
|| target.getPaddingRight() != source.getPaddingRight()
|
|| target.getPaddingRight() != source.getPaddingRight()
|
||||||
|| target.getPaddingBottom() != source.getPaddingBottom()) {
|
|| target.getPaddingBottom() != source.getPaddingBottom()) {
|
||||||
@@ -234,10 +245,7 @@ final class ClockProxyRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean applyTextColorOverrideIfNeeded(TextView view, int color) {
|
private static boolean applyTextColorOverrideIfNeeded(TextView view, int color) {
|
||||||
if (view == null || (color >>> 24) == 0) {
|
if (view == null || (color >>> 24) == 0 || view.getCurrentTextColor() == color) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (view.getCurrentTextColor() == color) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
view.setTextColor(color);
|
view.setTextColor(color);
|
||||||
@@ -276,3 +284,15 @@ final class ClockProxyRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class ClockOutlineSpec {
|
||||||
|
static final ClockOutlineSpec NONE = new ClockOutlineSpec(0, 0f);
|
||||||
|
|
||||||
|
final int color;
|
||||||
|
final float thicknessPx;
|
||||||
|
|
||||||
|
ClockOutlineSpec(int color, float thicknessPx) {
|
||||||
|
this.color = color;
|
||||||
|
this.thicknessPx = thicknessPx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+56
-6
@@ -12,6 +12,7 @@ import java.util.WeakHashMap;
|
|||||||
|
|
||||||
import se.ajpanton.statusbartweak.platform.SystemUiCapabilities;
|
import se.ajpanton.statusbartweak.platform.SystemUiCapabilities;
|
||||||
import se.ajpanton.statusbartweak.runtime.features.clock.ClockLayoutTextFactory;
|
import se.ajpanton.statusbartweak.runtime.features.clock.ClockLayoutTextFactory;
|
||||||
|
import se.ajpanton.statusbartweak.runtime.features.clock.ClockColorResolver;
|
||||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.Bounds;
|
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.Bounds;
|
||||||
import se.ajpanton.statusbartweak.runtime.mode.NotificationDisplayStyle;
|
import se.ajpanton.statusbartweak.runtime.mode.NotificationDisplayStyle;
|
||||||
import se.ajpanton.statusbartweak.runtime.mode.SceneKey;
|
import se.ajpanton.statusbartweak.runtime.mode.SceneKey;
|
||||||
@@ -29,6 +30,7 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
private final SnapshotRenderer notificationRenderer;
|
private final SnapshotRenderer notificationRenderer;
|
||||||
private final SnapshotRenderer chipRenderer;
|
private final SnapshotRenderer chipRenderer;
|
||||||
private final ClockProxyRenderer clockRenderer = new ClockProxyRenderer();
|
private final ClockProxyRenderer clockRenderer = new ClockProxyRenderer();
|
||||||
|
private final ClockColorResolver clockColorResolver = new ClockColorResolver();
|
||||||
private final ClockProxyRenderer carrierRenderer = new ClockProxyRenderer();
|
private final ClockProxyRenderer carrierRenderer = new ClockProxyRenderer();
|
||||||
private final UnlockedStockSourceCollector sourceCollector;
|
private final UnlockedStockSourceCollector sourceCollector;
|
||||||
private final TextVerticalOffsetScaler textOffsetScaler = new TextVerticalOffsetScaler();
|
private final TextVerticalOffsetScaler textOffsetScaler = new TextVerticalOffsetScaler();
|
||||||
@@ -154,7 +156,7 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
LayoutPlan updatedPlan = previousPlan.withClockPlacement(updatedClock);
|
LayoutPlan updatedPlan = previousPlan.withClockPlacement(updatedClock);
|
||||||
lastLayoutPlanByRoot.put(root, updatedPlan);
|
lastLayoutPlanByRoot.put(root, updatedPlan);
|
||||||
lastClockSourceGeometryByRoot.put(root, currentClockSourceGeometry);
|
lastClockSourceGeometryByRoot.put(root, currentClockSourceGeometry);
|
||||||
clockRenderer.render(clockHost, updatedClock);
|
renderClock(clockHost, updatedClock, settings);
|
||||||
return new RenderResult(false, false, false);
|
return new RenderResult(false, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +183,7 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
updatedClock)) {
|
updatedClock)) {
|
||||||
LayoutPlan updatedPlan = previousPlan.withClockPlacement(updatedClock);
|
LayoutPlan updatedPlan = previousPlan.withClockPlacement(updatedClock);
|
||||||
lastLayoutPlanByRoot.put(root, updatedPlan);
|
lastLayoutPlanByRoot.put(root, updatedPlan);
|
||||||
clockRenderer.render(clockHost, updatedClock);
|
renderClock(clockHost, updatedClock, settings);
|
||||||
return new RenderResult(false, false, false);
|
return new RenderResult(false, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,7 +241,7 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
layoutPlan = withCurrentCarrierAppearance(layoutPlan);
|
layoutPlan = withCurrentCarrierAppearance(layoutPlan);
|
||||||
lastLayoutPlanByRoot.put(root, layoutPlan);
|
lastLayoutPlanByRoot.put(root, layoutPlan);
|
||||||
if (clockEnabledForScene(settings, scene) && layoutPlan.clockPlacement != null) {
|
if (clockEnabledForScene(settings, scene) && layoutPlan.clockPlacement != null) {
|
||||||
clockRenderer.render(clockHost, layoutPlan.clockPlacement);
|
renderClock(clockHost, layoutPlan.clockPlacement, settings);
|
||||||
} else {
|
} else {
|
||||||
clockRenderer.clear(clockHost);
|
clockRenderer.clear(clockHost);
|
||||||
}
|
}
|
||||||
@@ -315,7 +317,7 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
layoutPlan = updatedPlan;
|
layoutPlan = updatedPlan;
|
||||||
}
|
}
|
||||||
if (settings.clockEnabledUnlocked && layoutPlan.clockPlacement != null) {
|
if (settings.clockEnabledUnlocked && layoutPlan.clockPlacement != null) {
|
||||||
clockRenderer.render(clockHost, layoutPlan.clockPlacement);
|
renderClock(clockHost, layoutPlan.clockPlacement, settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,7 +383,7 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
LayoutPlan updatedPlan = layoutPlan.withClockPlacement(updatedClock);
|
LayoutPlan updatedPlan = layoutPlan.withClockPlacement(updatedClock);
|
||||||
lastLayoutPlanByRoot.put(root, updatedPlan);
|
lastLayoutPlanByRoot.put(root, updatedPlan);
|
||||||
lastClockAppearanceByRoot.put(root, clockAppearanceSignature(updatedClock, referenceColor, settings));
|
lastClockAppearanceByRoot.put(root, clockAppearanceSignature(updatedClock, referenceColor, settings));
|
||||||
clockRenderer.render(clockHost, updatedClock);
|
renderClock(clockHost, updatedClock, settings);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,6 +656,51 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
return statusBarTintTargetEnabled ? StatusBarTintTarget.color() : android.graphics.Color.TRANSPARENT;
|
return statusBarTintTargetEnabled ? StatusBarTintTarget.color() : android.graphics.Color.TRANSPARENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderClock(
|
||||||
|
ViewGroup clockHost,
|
||||||
|
ClockPlacement placement,
|
||||||
|
SbtSettings settings
|
||||||
|
) {
|
||||||
|
clockRenderer.render(clockHost, placement, clockOutlineSpec(clockHost, placement, settings));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClockOutlineSpec clockOutlineSpec(
|
||||||
|
ViewGroup host,
|
||||||
|
ClockPlacement placement,
|
||||||
|
SbtSettings settings
|
||||||
|
) {
|
||||||
|
if (host == null
|
||||||
|
|| placement == null
|
||||||
|
|| settings == null
|
||||||
|
|| !settings.clockOutlineEnabled
|
||||||
|
|| settings.clockOutlineThicknessDp <= 0
|
||||||
|
|| settings.clockOutlineColor == null
|
||||||
|
|| settings.clockOutlineColor.trim().isEmpty()) {
|
||||||
|
return ClockOutlineSpec.NONE;
|
||||||
|
}
|
||||||
|
int referenceColor = hasAlpha(placement.textColorOverride)
|
||||||
|
? placement.textColorOverride
|
||||||
|
: placement.source != null
|
||||||
|
? placement.source.getCurrentTextColor()
|
||||||
|
: android.graphics.Color.WHITE;
|
||||||
|
try {
|
||||||
|
int color = clockColorResolver.resolveColor(
|
||||||
|
host.getContext(),
|
||||||
|
settings.clockOutlineColor,
|
||||||
|
referenceColor,
|
||||||
|
android.graphics.Color.TRANSPARENT,
|
||||||
|
ClockColorResolver.Options.clock());
|
||||||
|
if (!hasAlpha(color)) {
|
||||||
|
return ClockOutlineSpec.NONE;
|
||||||
|
}
|
||||||
|
return new ClockOutlineSpec(
|
||||||
|
color,
|
||||||
|
settings.clockOutlineThicknessDp * host.getResources().getDisplayMetrics().density);
|
||||||
|
} catch (IllegalArgumentException ignored) {
|
||||||
|
return ClockOutlineSpec.NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean hasAlpha(int color) {
|
private boolean hasAlpha(int color) {
|
||||||
return (color >>> 24) != 0;
|
return (color >>> 24) != 0;
|
||||||
}
|
}
|
||||||
@@ -689,7 +736,10 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
settings.clockShowSeconds,
|
settings.clockShowSeconds,
|
||||||
settings.clockShowDatePrefix,
|
settings.clockShowDatePrefix,
|
||||||
settings.clockCustomFormatEnabled,
|
settings.clockCustomFormatEnabled,
|
||||||
settings.clockCustomFormat);
|
settings.clockCustomFormat,
|
||||||
|
settings.clockOutlineEnabled,
|
||||||
|
settings.clockOutlineThicknessDp,
|
||||||
|
settings.clockOutlineColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearAll() {
|
public void clearAll() {
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ public final class SbtDefaults {
|
|||||||
public static final boolean CLOCK_SHOW_DATE_PREFIX_DEFAULT = false;
|
public static final boolean CLOCK_SHOW_DATE_PREFIX_DEFAULT = false;
|
||||||
public static final boolean CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT = false;
|
public static final boolean CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT = false;
|
||||||
public static final String CLOCK_CUSTOM_FORMAT_DEFAULT = "";
|
public static final String CLOCK_CUSTOM_FORMAT_DEFAULT = "";
|
||||||
|
public static final boolean CLOCK_OUTLINE_ENABLED_DEFAULT = false;
|
||||||
|
public static final int CLOCK_OUTLINE_THICKNESS_DP_DEFAULT = 1;
|
||||||
|
public static final int CLOCK_OUTLINE_THICKNESS_DP_MIN = 1;
|
||||||
|
public static final int CLOCK_OUTLINE_THICKNESS_DP_MAX = 6;
|
||||||
|
public static final String CLOCK_OUTLINE_COLOR_DEFAULT = "#000 ; #FFF";
|
||||||
public static final boolean DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT = false;
|
public static final boolean DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT = false;
|
||||||
public static final String DRAWER_CLOCK_CUSTOM_FORMAT_DEFAULT = "";
|
public static final String DRAWER_CLOCK_CUSTOM_FORMAT_DEFAULT = "";
|
||||||
public static final boolean DRAWER_DATE_CUSTOM_FORMAT_ENABLED_DEFAULT = false;
|
public static final boolean DRAWER_DATE_CUSTOM_FORMAT_ENABLED_DEFAULT = false;
|
||||||
|
|||||||
@@ -213,6 +213,9 @@ public final class SbtSettings {
|
|||||||
public static final String KEY_CLOCK_SHOW_DATE_PREFIX = "clock_show_date_prefix";
|
public static final String KEY_CLOCK_SHOW_DATE_PREFIX = "clock_show_date_prefix";
|
||||||
public static final String KEY_CLOCK_CUSTOM_FORMAT_ENABLED = "clock_custom_format_enabled";
|
public static final String KEY_CLOCK_CUSTOM_FORMAT_ENABLED = "clock_custom_format_enabled";
|
||||||
public static final String KEY_CLOCK_CUSTOM_FORMAT = "clock_custom_format";
|
public static final String KEY_CLOCK_CUSTOM_FORMAT = "clock_custom_format";
|
||||||
|
public static final String KEY_CLOCK_OUTLINE_ENABLED = "clock_outline_enabled";
|
||||||
|
public static final String KEY_CLOCK_OUTLINE_THICKNESS_DP = "clock_outline_thickness_dp";
|
||||||
|
public static final String KEY_CLOCK_OUTLINE_COLOR = "clock_outline_color";
|
||||||
public static final String KEY_DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED =
|
public static final String KEY_DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED =
|
||||||
"drawer_clock_custom_format_enabled";
|
"drawer_clock_custom_format_enabled";
|
||||||
public static final String KEY_DRAWER_CLOCK_CUSTOM_FORMAT = "drawer_clock_custom_format";
|
public static final String KEY_DRAWER_CLOCK_CUSTOM_FORMAT = "drawer_clock_custom_format";
|
||||||
@@ -454,6 +457,9 @@ public final class SbtSettings {
|
|||||||
public final boolean clockShowDatePrefix;
|
public final boolean clockShowDatePrefix;
|
||||||
public final boolean clockCustomFormatEnabled;
|
public final boolean clockCustomFormatEnabled;
|
||||||
public final String clockCustomFormat;
|
public final String clockCustomFormat;
|
||||||
|
public final boolean clockOutlineEnabled;
|
||||||
|
public final int clockOutlineThicknessDp;
|
||||||
|
public final String clockOutlineColor;
|
||||||
public final boolean drawerClockCustomFormatEnabled;
|
public final boolean drawerClockCustomFormatEnabled;
|
||||||
public final String drawerClockCustomFormat;
|
public final String drawerClockCustomFormat;
|
||||||
public final boolean drawerDateCustomFormatEnabled;
|
public final boolean drawerDateCustomFormatEnabled;
|
||||||
@@ -589,6 +595,9 @@ public final class SbtSettings {
|
|||||||
boolean clockShowDatePrefix,
|
boolean clockShowDatePrefix,
|
||||||
boolean clockCustomFormatEnabled,
|
boolean clockCustomFormatEnabled,
|
||||||
String clockCustomFormat,
|
String clockCustomFormat,
|
||||||
|
boolean clockOutlineEnabled,
|
||||||
|
int clockOutlineThicknessDp,
|
||||||
|
String clockOutlineColor,
|
||||||
boolean drawerClockCustomFormatEnabled,
|
boolean drawerClockCustomFormatEnabled,
|
||||||
String drawerClockCustomFormat,
|
String drawerClockCustomFormat,
|
||||||
boolean drawerDateCustomFormatEnabled,
|
boolean drawerDateCustomFormatEnabled,
|
||||||
@@ -762,6 +771,13 @@ public final class SbtSettings {
|
|||||||
this.clockCustomFormat = clockCustomFormat != null
|
this.clockCustomFormat = clockCustomFormat != null
|
||||||
? clockCustomFormat
|
? clockCustomFormat
|
||||||
: SbtDefaults.CLOCK_CUSTOM_FORMAT_DEFAULT;
|
: SbtDefaults.CLOCK_CUSTOM_FORMAT_DEFAULT;
|
||||||
|
this.clockOutlineEnabled = clockOutlineEnabled;
|
||||||
|
this.clockOutlineThicknessDp = Math.max(
|
||||||
|
SbtDefaults.CLOCK_OUTLINE_THICKNESS_DP_MIN,
|
||||||
|
Math.min(clockOutlineThicknessDp, SbtDefaults.CLOCK_OUTLINE_THICKNESS_DP_MAX));
|
||||||
|
this.clockOutlineColor = clockOutlineColor != null
|
||||||
|
? clockOutlineColor
|
||||||
|
: SbtDefaults.CLOCK_OUTLINE_COLOR_DEFAULT;
|
||||||
this.drawerClockCustomFormatEnabled = drawerClockCustomFormatEnabled;
|
this.drawerClockCustomFormatEnabled = drawerClockCustomFormatEnabled;
|
||||||
this.drawerClockCustomFormat = drawerClockCustomFormat != null
|
this.drawerClockCustomFormat = drawerClockCustomFormat != null
|
||||||
? drawerClockCustomFormat
|
? drawerClockCustomFormat
|
||||||
@@ -1219,6 +1235,9 @@ public final class SbtSettings {
|
|||||||
prefs.getBoolean(KEY_CLOCK_SHOW_DATE_PREFIX, SbtDefaults.CLOCK_SHOW_DATE_PREFIX_DEFAULT),
|
prefs.getBoolean(KEY_CLOCK_SHOW_DATE_PREFIX, SbtDefaults.CLOCK_SHOW_DATE_PREFIX_DEFAULT),
|
||||||
prefs.getBoolean(KEY_CLOCK_CUSTOM_FORMAT_ENABLED, SbtDefaults.CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT),
|
prefs.getBoolean(KEY_CLOCK_CUSTOM_FORMAT_ENABLED, SbtDefaults.CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT),
|
||||||
prefs.getString(KEY_CLOCK_CUSTOM_FORMAT, SbtDefaults.CLOCK_CUSTOM_FORMAT_DEFAULT),
|
prefs.getString(KEY_CLOCK_CUSTOM_FORMAT, SbtDefaults.CLOCK_CUSTOM_FORMAT_DEFAULT),
|
||||||
|
prefs.getBoolean(KEY_CLOCK_OUTLINE_ENABLED, SbtDefaults.CLOCK_OUTLINE_ENABLED_DEFAULT),
|
||||||
|
prefs.getInt(KEY_CLOCK_OUTLINE_THICKNESS_DP, SbtDefaults.CLOCK_OUTLINE_THICKNESS_DP_DEFAULT),
|
||||||
|
prefs.getString(KEY_CLOCK_OUTLINE_COLOR, SbtDefaults.CLOCK_OUTLINE_COLOR_DEFAULT),
|
||||||
prefs.getBoolean(KEY_DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED,
|
prefs.getBoolean(KEY_DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED,
|
||||||
SbtDefaults.DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT),
|
SbtDefaults.DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT),
|
||||||
prefs.getString(KEY_DRAWER_CLOCK_CUSTOM_FORMAT,
|
prefs.getString(KEY_DRAWER_CLOCK_CUSTOM_FORMAT,
|
||||||
|
|||||||
@@ -155,6 +155,15 @@ public class SbtSettingsProvider extends ContentProvider {
|
|||||||
prefs.getBoolean(SbtSettings.KEY_CLOCK_CUSTOM_FORMAT_ENABLED, SbtDefaults.CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT));
|
prefs.getBoolean(SbtSettings.KEY_CLOCK_CUSTOM_FORMAT_ENABLED, SbtDefaults.CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT));
|
||||||
out.putString(SbtSettings.KEY_CLOCK_CUSTOM_FORMAT,
|
out.putString(SbtSettings.KEY_CLOCK_CUSTOM_FORMAT,
|
||||||
prefs.getString(SbtSettings.KEY_CLOCK_CUSTOM_FORMAT, SbtDefaults.CLOCK_CUSTOM_FORMAT_DEFAULT));
|
prefs.getString(SbtSettings.KEY_CLOCK_CUSTOM_FORMAT, SbtDefaults.CLOCK_CUSTOM_FORMAT_DEFAULT));
|
||||||
|
out.putBoolean(SbtSettings.KEY_CLOCK_OUTLINE_ENABLED,
|
||||||
|
prefs.getBoolean(SbtSettings.KEY_CLOCK_OUTLINE_ENABLED,
|
||||||
|
SbtDefaults.CLOCK_OUTLINE_ENABLED_DEFAULT));
|
||||||
|
out.putInt(SbtSettings.KEY_CLOCK_OUTLINE_THICKNESS_DP,
|
||||||
|
prefs.getInt(SbtSettings.KEY_CLOCK_OUTLINE_THICKNESS_DP,
|
||||||
|
SbtDefaults.CLOCK_OUTLINE_THICKNESS_DP_DEFAULT));
|
||||||
|
out.putString(SbtSettings.KEY_CLOCK_OUTLINE_COLOR,
|
||||||
|
prefs.getString(SbtSettings.KEY_CLOCK_OUTLINE_COLOR,
|
||||||
|
SbtDefaults.CLOCK_OUTLINE_COLOR_DEFAULT));
|
||||||
out.putBoolean(SbtSettings.KEY_DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED,
|
out.putBoolean(SbtSettings.KEY_DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED,
|
||||||
prefs.getBoolean(
|
prefs.getBoolean(
|
||||||
SbtSettings.KEY_DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED,
|
SbtSettings.KEY_DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED,
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import androidx.fragment.app.Fragment;
|
|||||||
import com.google.android.material.button.MaterialButton;
|
import com.google.android.material.button.MaterialButton;
|
||||||
import com.google.android.material.card.MaterialCardView;
|
import com.google.android.material.card.MaterialCardView;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
import com.google.android.material.slider.Slider;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -93,6 +94,11 @@ public final class ClockFragment extends Fragment {
|
|||||||
EditText customFormatInput = root.findViewById(R.id.clock_custom_format_input);
|
EditText customFormatInput = root.findViewById(R.id.clock_custom_format_input);
|
||||||
ClockPatternPreviewView customFormatPreview =
|
ClockPatternPreviewView customFormatPreview =
|
||||||
root.findViewById(R.id.clock_custom_format_preview);
|
root.findViewById(R.id.clock_custom_format_preview);
|
||||||
|
CheckBox clockOutlineEnabled = root.findViewById(R.id.clock_outline_enabled);
|
||||||
|
View clockOutlineContainer = root.findViewById(R.id.clock_outline_container);
|
||||||
|
Slider clockOutlineThickness = root.findViewById(R.id.clock_outline_thickness);
|
||||||
|
TextView clockOutlineThicknessLabel = root.findViewById(R.id.clock_outline_thickness_value);
|
||||||
|
EditText clockOutlineColor = root.findViewById(R.id.clock_outline_color);
|
||||||
MaterialCardView drawerClockCustomFormatCard =
|
MaterialCardView drawerClockCustomFormatCard =
|
||||||
root.findViewById(R.id.drawer_clock_custom_format_card);
|
root.findViewById(R.id.drawer_clock_custom_format_card);
|
||||||
CheckBox drawerClockCustomFormatEnabled =
|
CheckBox drawerClockCustomFormatEnabled =
|
||||||
@@ -129,6 +135,12 @@ public final class ClockFragment extends Fragment {
|
|||||||
String customFormatValue = prefs.getString(
|
String customFormatValue = prefs.getString(
|
||||||
SbtSettings.KEY_CLOCK_CUSTOM_FORMAT,
|
SbtSettings.KEY_CLOCK_CUSTOM_FORMAT,
|
||||||
SbtDefaults.CLOCK_CUSTOM_FORMAT_DEFAULT);
|
SbtDefaults.CLOCK_CUSTOM_FORMAT_DEFAULT);
|
||||||
|
int clockOutlineThicknessDp = prefs.getInt(
|
||||||
|
SbtSettings.KEY_CLOCK_OUTLINE_THICKNESS_DP,
|
||||||
|
SbtDefaults.CLOCK_OUTLINE_THICKNESS_DP_DEFAULT);
|
||||||
|
String clockOutlineColorValue = prefs.getString(
|
||||||
|
SbtSettings.KEY_CLOCK_OUTLINE_COLOR,
|
||||||
|
SbtDefaults.CLOCK_OUTLINE_COLOR_DEFAULT);
|
||||||
boolean drawerClockCustomFormatEnabledValue = prefs.getBoolean(
|
boolean drawerClockCustomFormatEnabledValue = prefs.getBoolean(
|
||||||
SbtSettings.KEY_DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED,
|
SbtSettings.KEY_DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED,
|
||||||
SbtDefaults.DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT);
|
SbtDefaults.DRAWER_CLOCK_CUSTOM_FORMAT_ENABLED_DEFAULT);
|
||||||
@@ -160,6 +172,15 @@ public final class ClockFragment extends Fragment {
|
|||||||
customFormatValue,
|
customFormatValue,
|
||||||
18f,
|
18f,
|
||||||
true);
|
true);
|
||||||
|
bindClockOutline(
|
||||||
|
prefs,
|
||||||
|
clockOutlineEnabled,
|
||||||
|
clockOutlineContainer,
|
||||||
|
clockOutlineThickness,
|
||||||
|
clockOutlineThicknessLabel,
|
||||||
|
clockOutlineThicknessDp,
|
||||||
|
clockOutlineColor,
|
||||||
|
clockOutlineColorValue);
|
||||||
bindCustomFormat(
|
bindCustomFormat(
|
||||||
prefs,
|
prefs,
|
||||||
drawerClockCustomFormatCard,
|
drawerClockCustomFormatCard,
|
||||||
@@ -218,6 +239,69 @@ public final class ClockFragment extends Fragment {
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void bindClockOutline(
|
||||||
|
SharedPreferences prefs,
|
||||||
|
CheckBox enabledView,
|
||||||
|
View container,
|
||||||
|
Slider thicknessView,
|
||||||
|
TextView thicknessValueView,
|
||||||
|
int thicknessDp,
|
||||||
|
EditText colorView,
|
||||||
|
String colorExpression
|
||||||
|
) {
|
||||||
|
if (enabledView == null || thicknessView == null || colorView == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int clampedThickness = Math.max(
|
||||||
|
SbtDefaults.CLOCK_OUTLINE_THICKNESS_DP_MIN,
|
||||||
|
Math.min(thicknessDp, SbtDefaults.CLOCK_OUTLINE_THICKNESS_DP_MAX));
|
||||||
|
enabledView.setChecked(prefs.getBoolean(
|
||||||
|
SbtSettings.KEY_CLOCK_OUTLINE_ENABLED,
|
||||||
|
SbtDefaults.CLOCK_OUTLINE_ENABLED_DEFAULT));
|
||||||
|
thicknessView.setValue(clampedThickness);
|
||||||
|
updateClockOutlineThicknessLabel(thicknessValueView, clampedThickness);
|
||||||
|
colorView.setText(colorExpression != null ? colorExpression : "");
|
||||||
|
updateCustomFormatVisibility(container, enabledView.isChecked());
|
||||||
|
enabledView.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
updateCustomFormatVisibility(container, isChecked);
|
||||||
|
prefs.edit().putBoolean(SbtSettings.KEY_CLOCK_OUTLINE_ENABLED, isChecked).apply();
|
||||||
|
SbtSettings.ensureReadable(requireContext());
|
||||||
|
});
|
||||||
|
thicknessView.addOnChangeListener((slider, value, fromUser) -> {
|
||||||
|
int thickness = Math.round(value);
|
||||||
|
updateClockOutlineThicknessLabel(thicknessValueView, thickness);
|
||||||
|
if (!fromUser) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prefs.edit().putInt(SbtSettings.KEY_CLOCK_OUTLINE_THICKNESS_DP, thickness).apply();
|
||||||
|
SbtSettings.ensureReadable(requireContext());
|
||||||
|
});
|
||||||
|
colorView.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
prefs.edit()
|
||||||
|
.putString(SbtSettings.KEY_CLOCK_OUTLINE_COLOR,
|
||||||
|
s != null ? s.toString() : "")
|
||||||
|
.apply();
|
||||||
|
SbtSettings.ensureReadable(requireContext());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateClockOutlineThicknessLabel(TextView view, int thicknessDp) {
|
||||||
|
if (view != null) {
|
||||||
|
view.setText(getString(R.string.clock_outline_thickness_value, thicknessDp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateCustomFormatVisibility(View customFormatContainer, boolean enabled) {
|
private void updateCustomFormatVisibility(View customFormatContainer, boolean enabled) {
|
||||||
if (customFormatContainer == null) {
|
if (customFormatContainer == null) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -79,6 +79,71 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
app:cardUseCompatPadding="true"
|
||||||
|
app:strokeColor="@color/sbt_card_outline"
|
||||||
|
app:strokeWidth="1dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:letterSpacing="0.03"
|
||||||
|
android:text="@string/clock_outline_title"
|
||||||
|
android:textAllCaps="true"
|
||||||
|
android:textAppearance="?attr/textAppearanceSubtitle1"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/clock_outline_enabled"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/clock_outline_enabled" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/clock_outline_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/clock_outline_thickness_value"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:textAppearance="?attr/textAppearanceBody1" />
|
||||||
|
|
||||||
|
<com.google.android.material.slider.Slider
|
||||||
|
android:id="@+id/clock_outline_thickness"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:valueFrom="1"
|
||||||
|
android:valueTo="6"
|
||||||
|
android:stepSize="1" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/clock_outline_color"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:hint="@string/clock_outline_color_hint"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
|
android:singleLine="true" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/drawer_clock_custom_format_card"
|
android:id="@+id/drawer_clock_custom_format_card"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -212,6 +212,10 @@
|
|||||||
<string name="clock_custom_format_drawer_date_title">Drawer date</string>
|
<string name="clock_custom_format_drawer_date_title">Drawer date</string>
|
||||||
<string name="clock_custom_format_tools_title">Tools and instructions</string>
|
<string name="clock_custom_format_tools_title">Tools and instructions</string>
|
||||||
<string name="clock_custom_format_enabled">Enable custom date/time pattern</string>
|
<string name="clock_custom_format_enabled">Enable custom date/time pattern</string>
|
||||||
|
<string name="clock_outline_title">Statusbar clock outline</string>
|
||||||
|
<string name="clock_outline_enabled">Add outline</string>
|
||||||
|
<string name="clock_outline_thickness_value">Thickness: %1$d dp</string>
|
||||||
|
<string name="clock_outline_color_hint">Outline colour, for example #000 ; #FFF</string>
|
||||||
<string name="drawer_clock_custom_format_enabled">Enable custom date/time pattern</string>
|
<string name="drawer_clock_custom_format_enabled">Enable custom date/time pattern</string>
|
||||||
<string name="drawer_date_custom_format_enabled">Enable custom date/time pattern</string>
|
<string name="drawer_date_custom_format_enabled">Enable custom date/time pattern</string>
|
||||||
<string name="clock_custom_format_help_common">Date/time patterns:\n\u2022 Uses Java SimpleDateFormat-style pattern letters\n\u2022 Common symbols: yyyy yy MMMM MMM MM EEEE EEE dd d HH hh mm ss a\n\nTags:\n\u2022 Supported tags: <i>, <u>, <small>, <big>, <font color=\'...\'>, <font face=\'...\'>\n\u2022 <b> is not supported\n\u2022 Custom font tags: <sans>, <serif>, <mono>, <condensed>\n\u2022 {/font} closes any open <font ...> tag\n\u2022 Opening a new colour or font face automatically closes the previous one</string>
|
<string name="clock_custom_format_help_common">Date/time patterns:\n\u2022 Uses Java SimpleDateFormat-style pattern letters\n\u2022 Common symbols: yyyy yy MMMM MMM MM EEEE EEE dd d HH hh mm ss a\n\nTags:\n\u2022 Supported tags: <i>, <u>, <small>, <big>, <font color=\'...\'>, <font face=\'...\'>\n\u2022 <b> is not supported\n\u2022 Custom font tags: <sans>, <serif>, <mono>, <condensed>\n\u2022 {/font} closes any open <font ...> tag\n\u2022 Opening a new colour or font face automatically closes the previous one</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user