Fossil Q: Improve time picker visuals

This commit is contained in:
Arjan Schrijver
2026-04-05 14:18:10 +02:00
committed by Arjan Schrijver
parent b6b9781f0b
commit 5015e3a7b7
@@ -1,4 +1,4 @@
/* Copyright (C) 2019-2024 Arjan Schrijver, Daniel Dakhno
/* Copyright (C) 2019-2024 Arjan Schrijver, Daniel Dakhno
This file is part of Gadgetbridge.
@@ -94,6 +94,7 @@ public class TimePicker extends MaterialAlertDialogBuilder {
drawClock();
// Main container for all UI elements
LinearLayout layout = new LinearLayout(context);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(pickerView);
@@ -126,11 +127,15 @@ public class TimePicker extends MaterialAlertDialogBuilder {
}
});
ScrollView scrollView = new ScrollView(context);
scrollView.addView(group);
layout.addView(scrollView);
// Add the RadioGroup directly to the LinearLayout
layout.addView(group);
setView(layout);
// Wrap the entire layout in a ScrollView so the whole dialog scrolls
ScrollView mainScrollView = new ScrollView(context);
mainScrollView.addView(layout);
// Set the ScrollView as the dialog's view
setView(mainScrollView);
@@ -161,6 +166,18 @@ public class TimePicker extends MaterialAlertDialogBuilder {
pickerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// Request the parent ScrollView not to intercept touch events
// while the user is actively dragging the clock hands.
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
view.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
view.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
handleTouch(dialog, motionEvent);
return true;
}
@@ -226,60 +243,98 @@ public class TimePicker extends MaterialAlertDialogBuilder {
private void drawClock() {
//pickerCanvas.drawColor(Color.WHITE);
// Clear background
Paint white = new Paint();
white.setColor(Color.WHITE);
white.setStyle(Paint.Style.FILL);
pickerCanvas.drawCircle(width / 2, width / 2, width / 2, white);
pickerCanvas.drawCircle(width / 2f, height / 2f, width / 2f, white);
Paint paint = new Paint();
int centerX = width / 2;
int centerY = height / 2;
// --- DRAW CLOCK LABELS ---
Paint labelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
labelPaint.setTextAlign(Paint.Align.CENTER);
// Calculate radii for the text rings
float minuteLabelRadius = (width / 2f) * 0.88f;
float hourLabelRadius = (width / 2f) * 0.65f;
// Draw outer minute labels (0, 5, 10... 55)
labelPaint.setTextSize(width * 0.045f);
labelPaint.setColor(Color.DKGRAY);
float minuteTextShiftY = (labelPaint.descent() + labelPaint.ascent()) / 2;
for (int i = 0; i < 60; i += 5) {
float angle = i * 6; // 360 degrees / 60 minutes
float x = (float) (centerX + Math.sin(Math.toRadians(angle)) * minuteLabelRadius);
float y = (float) (centerY - Math.cos(Math.toRadians(angle)) * minuteLabelRadius);
pickerCanvas.drawText(String.valueOf(i), x, y - minuteTextShiftY, labelPaint);
}
// Draw inner hour labels (1 to 12)
labelPaint.setTextSize(width * 0.065f);
labelPaint.setColor(Color.BLACK);
labelPaint.setFakeBoldText(true);
float hourTextShiftY = (labelPaint.descent() + labelPaint.ascent()) / 2;
for (int i = 1; i <= 12; i++) {
float angle = i * 30; // 360 degrees / 12 hours
float x = (float) (centerX + Math.sin(Math.toRadians(angle)) * hourLabelRadius);
float y = (float) (centerY - Math.cos(Math.toRadians(angle)) * hourLabelRadius);
pickerCanvas.drawText(String.valueOf(i), x, y - hourTextShiftY, labelPaint);
}
// -------------------------
// --- DRAW HANDS ---
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setColor(Color.BLUE);
Paint text = new Paint();
Paint text = new Paint(Paint.ANTI_ALIAS_FLAG);
text.setStyle(Paint.Style.FILL);
text.setTextSize(radius * 1.5f);
text.setColor(Color.BLACK);
text.setTextAlign(Paint.Align.CENTER);
int textShiftY = (int) ((text.descent() + text.ascent()) / 2);
Paint linePaint = new Paint();
Paint linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setStrokeWidth(10);
linePaint.setStyle(Paint.Style.FILL_AND_STROKE);
linePaint.setColor(Color.BLACK);
// Draw Minute Hand
if (settings.getMin() != -1) {
paint.setAlpha(255);
float x = (float) (width / 2f + Math.sin(Math.toRadians(settings.getMin())) * (float) radius3);
float y = (float) (height / 2f - Math.cos(Math.toRadians(settings.getMin())) * (float) radius3);
float x = (float) (centerX + Math.sin(Math.toRadians(settings.getMin())) * (float) radius3);
float y = (float) (centerY - Math.cos(Math.toRadians(settings.getMin())) * (float) radius3);
linePaint.setAlpha(255);
pickerCanvas.drawLine(width / 2, height / 2, x, y, linePaint);
pickerCanvas.drawCircle(
x,
y,
radius,
paint
);
pickerCanvas.drawLine(centerX, centerY, x, y, linePaint);
pickerCanvas.drawCircle(x, y, radius, paint);
// Floating exact minute text
pickerCanvas.drawText(String.valueOf(settings.getMin() / 6), x, y - textShiftY, text);
}
// Draw Hour Hand
if (settings.getHour() != -1) {
paint.setAlpha(255);
float x = (float) (width / 2f + Math.sin(Math.toRadians(settings.getHour())) * (float) radius2);
float y = (float) (height / 2f - Math.cos(Math.toRadians(settings.getHour())) * (float) radius2);
float x = (float) (centerX + Math.sin(Math.toRadians(settings.getHour())) * (float) radius2);
float y = (float) (centerY - Math.cos(Math.toRadians(settings.getHour())) * (float) radius2);
linePaint.setAlpha(255);
pickerCanvas.drawLine(width / 2, height / 2, x, y, linePaint);
pickerCanvas.drawCircle(
x,
y,
radius,
paint
);
pickerCanvas.drawLine(centerX, centerY, x, y, linePaint);
pickerCanvas.drawCircle(x, y, radius, paint);
// Floating exact hour text
pickerCanvas.drawText(settings.getHour() == 0 ? "12" : String.valueOf(settings.getHour() / 30), x, y - textShiftY, text);
}
Paint paint2 = new Paint();
// Draw Center Pin
Paint paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
paint2.setColor(Color.BLACK);
paint2.setStyle(Paint.Style.FILL_AND_STROKE);
pickerCanvas.drawCircle(width / 2, height / 2, 5, paint2);
pickerCanvas.drawCircle(centerX, centerY, 8, paint2);
pickerView.setImageBitmap(pickerBitmap);
}