subdivision, 'minute' hand

This commit is contained in:
Gyuri Horák 2025-11-03 19:10:16 +01:00
parent bd857a4e52
commit a54a66c419
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG Key ID: 4993F07B3EAE8D38
2 changed files with 223 additions and 28 deletions

168
IMPROVEMENT_IDEAS.md Normal file
View File

@ -0,0 +1,168 @@
# Metric Day Watchface - Improvement Ideas
This document contains potential enhancements and features to improve the decimal day progress watchface.
## Visual Enhancements
### 1. Better Graphics & Styling
- **Proper launcher icon** - Replace placeholder with actual designed icon
- **Sub-divisions/minor tick marks** - Add marks at 0.5 intervals for finer precision
- **Color themes**
- Dark mode / Light mode
- "Metric blue/orange" scheme
- Customizable user-selected colors
- **Multiple hands** - Add a second hand showing "decidays" or "centidays" (0-100 subdivisions)
- **Visual polish**
- Gradient backgrounds
- Geometric patterns
- Anti-aliasing for smoother lines
- Different hand styles (classic, modern, minimalist)
### 2. Lean Into the Joke
Make it more obviously a "metric time" parody:
- **Metric branding** - Labels like "decidays" or "centidays" for units
- **Display branding** - "METRIC TIME™" or "DECIMAL STANDARD TIME"
- **Conversion helper** - Small text showing "5.2 metric = 12:28 traditional"
- **Easter eggs at specific times**
- At exactly 5.0: "PEAK EFFICIENCY" or "HALFWAY THERE"
- At 0.0/10.0: "METRIC MIDNIGHT"
- At 2.5: "METRIC BREAKFAST TIME"
- At 7.5: "METRIC EVENING"
- **Motivational messages** - "You're 73.4% through the day!"
## Functional Improvements
### 3. Practical Additions
Make it actually usable as a daily driver:
- **Small actual time display** - For when you really need to know (corner or bottom)
- **Date display** - Consider metric format:
- "Day 307/365" (day of year)
- Traditional date as fallback
- **Battery indicator** - Show as decimal percentage (0.0-1.0 or 0-100)
- **Fitness data**
- Steps/goal as decimal progress (e.g., "0.73/1.00")
- Heart rate
- Calories burned
- Active minutes
- **Connection status** - Bluetooth, notifications indicator
- **Weather integration** - Temperature, conditions
### 4. Advanced Time Features
- **Sunrise/sunset markers** - Show on the decimal scale where sunrise/sunset occur
- **Work hours highlight** - Shade/highlight the 9-5 equivalent zone (3.75-7.08)
- **Alarm indicators** - Show alarm time positions on the face
- **Multiple timezones** - Other locations shown in decimal time
- **Calendar events** - Mark upcoming events on the time circle
- **Do Not Disturb** - Visual indicator when DND is active
## Technical Refinements
### 5. Device Optimization
- **Screen type detection**
- MIP display: Optimize for lower refresh, higher contrast
- AMOLED: Optimize for always-on mode, prevent burn-in
- **Screen shape handling**
- Round displays (most watches)
- Semi-round displays (Forerunner 645)
- Rectangular displays (if applicable)
- **Low power mode**
- Update less frequently (every minute instead of every second)
- Simpler graphics when in sleep mode
- Hide second hand in sleep mode
- **Memory optimization** - Support older devices with limited memory
- **Performance tuning** - Ensure smooth rendering across all devices
### 6. User Settings
Implement on-device settings menu:
- **Display options**
- Toggle digital display on/off
- Show/hide actual time
- Show/hide date
- Enable/disable easter eggs
- **Visual preferences**
- Choose color theme
- Select hand style
- Toggle minor tick marks
- Adjust font sizes
- **Complications**
- Select which metrics to display
- Position preferences for data fields
- **Power options**
- Update frequency
- Sleep mode behavior
## Alternative Display Modes
### 7. Different Variations
Create alternative interpretations of the concept:
- **Pure decimal mode** - No traditional time reference at all, fully commit to the joke
- **Hybrid mode** - Show both decimal and traditional time equally
- **French Revolutionary Time** - Implement the actual historical 10-hour decimal system
- 10 hours/day, 100 minutes/hour, 100 seconds/minute
- Day starts at midnight
- Reference: https://en.wikipedia.org/wiki/Decimal_time
- **Percentage mode** - Show day progress as 0-100% instead of 0-10
- **Swatch Internet Time** - Alternative decimal time system (.beats)
- **Hexadecimal time** - For the true nerds (0x0-0xF, or 0x00-0xFF)
## Implementation Priority
### Quick Wins (Low effort, high impact)
1. ✅ Create proper launcher icon
2. ✅ Add minor tick marks at 0.5 intervals
3. ✅ Add small actual time display
4. ✅ Add battery indicator
5. ✅ Improve visual polish (colors, spacing)
### Medium Effort
6. ⏳ Implement user settings menu
7. ⏳ Add color theme options
8. ⏳ Date display
9. ⏳ Fitness data integration
10. ⏳ Screen type optimization
### Advanced Features
11. 📋 Sunrise/sunset markers
12. 📋 Multiple timezone support
13. 📋 French Revolutionary Time mode
14. 📋 Advanced complications
15. 📋 Easter eggs and branding
### Fun Additions
- Better "metric time" branding/labels
- Easter eggs at specific decimal times
- Conversion helper text
- Motivational messages
## Community Ideas
Add ideas from users here:
- _[Space for future ideas]_
## Technical Debt
Track technical improvements needed:
- Replace placeholder launcher icon PNG with actual image
- Optimize polygon drawing for hand rotation
- Add error handling for edge cases
- Write unit tests for time conversion
## Resources
Links to helpful references:
- [Decimal time - Wikipedia](https://en.wikipedia.org/wiki/Decimal_time)
- [French Revolutionary Time](https://en.wikipedia.org/wiki/Decimal_time#France)
- [Swatch Internet Time](https://en.wikipedia.org/wiki/Swatch_Internet_Time)
- [Garmin Connect IQ API Docs](https://developer.garmin.com/connect-iq/api-docs/)

View File

@ -77,45 +77,54 @@ class MetricWatchFaceView extends WatchUi.WatchFace {
var centerY = height / 2;
var radius = (width < height ? width : height) / 2 - 10;
// Draw outer circle
dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT);
dc.setPenWidth(3);
dc.drawCircle(centerX, centerY, radius);
// Draw tick marks and numbers for each decimal position (0-9)
dc.setPenWidth(2);
for (var i = 0; i < 10; i++) {
var angle = (i / 10.0) * 360.0 - 90.0; // -90 to start at top
// Draw tick marks at 0.1 intervals (major at whole numbers, minor at 0.1)
for (var i = 0; i < 100; i++) {
var decimalValue = i * 0.1;
var angle = (decimalValue / 10.0) * 360.0 - 90.0; // -90 to start at top
var angleRad = Math.toRadians(angle);
// Determine if this is a major tick (whole number) or minor tick
var isMajor = (i % 10 == 0); // Every 10th position is a whole number
var tickLength = isMajor ? 15 : 8; // Major ticks are longer
var penWidth = isMajor ? 3 : 1; // Major ticks are thicker
// Calculate tick mark positions
var tickOuterX = centerX + radius * Math.cos(angleRad);
var tickOuterY = centerY + radius * Math.sin(angleRad);
var tickInnerX = centerX + (radius - 15) * Math.cos(angleRad);
var tickInnerY = centerY + (radius - 15) * Math.sin(angleRad);
var tickInnerX = centerX + (radius - tickLength) * Math.cos(angleRad);
var tickInnerY = centerY + (radius - tickLength) * Math.sin(angleRad);
// Draw tick mark
dc.setPenWidth(penWidth);
dc.drawLine(tickOuterX, tickOuterY, tickInnerX, tickInnerY);
// Draw number
var numberX = centerX + (radius - 35) * Math.cos(angleRad);
var numberY = centerY + (radius - 35) * Math.sin(angleRad);
// Draw number only for major ticks
if (isMajor) {
var numberX = centerX + (radius - 38) * Math.cos(angleRad);
var numberY = centerY + (radius - 38) * Math.sin(angleRad);
var numberValue = (i / 10).toNumber(); // Convert to 0-9
if (numberValue == 0) {
numberValue = 10; // Display 10 instead of 0
}
dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT);
dc.drawText(
numberX,
numberY,
Graphics.FONT_MEDIUM,
i.toString(),
numberValue.toString(),
Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER
);
}
}
// Draw center dot
dc.fillCircle(centerX, centerY, 5);
}
// Draw the hand pointing to current decimal time
// Draw both hour and minute hands for current decimal time
function drawHand(dc, decimalTime) {
var width = dc.getWidth();
var height = dc.getHeight();
@ -123,19 +132,37 @@ class MetricWatchFaceView extends WatchUi.WatchFace {
var centerY = height / 2;
var radius = (width < height ? width : height) / 2 - 10;
// Calculate hand angle (0-10 maps to 0-360 degrees, starting at top)
var angle = (decimalTime / 10.0) * 360.0 - 90.0; // -90 to start at top
var angleRad = Math.toRadians(angle);
// Calculate hour hand (shows which decimal unit 0-9, one rotation per day)
var hourAngle = (decimalTime / 10.0) * 360.0 - 90.0;
var hourAngleRad = Math.toRadians(hourAngle);
var hourHandLength = radius - 70; // Shorter hand
// Hand length (slightly shorter than radius to not overlap with numbers)
var handLength = radius - 50;
// Calculate minute hand (shows fractional part, 10 rotations per day)
var fractionalPart = decimalTime - decimalTime.toNumber(); // Get decimal part
var minuteAngle = fractionalPart * 360.0 - 90.0;
var minuteAngleRad = Math.toRadians(minuteAngle);
var minuteHandLength = radius - 45; // Longer hand
// Draw minute hand (longer, thinner)
drawSingleHand(dc, centerX, centerY, minuteAngle, minuteHandLength, 4, Graphics.COLOR_WHITE);
// Draw hour hand (shorter, wider)
drawSingleHand(dc, centerX, centerY, hourAngle, hourHandLength, 6, Graphics.COLOR_RED);
// Redraw center dot on top of hands
dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT);
dc.fillCircle(centerX, centerY, 5);
}
// Helper function to draw a single hand
function drawSingleHand(dc, centerX, centerY, angle, handLength, handWidth, color) {
var angleRad = Math.toRadians(angle);
// Calculate hand tip position
var handTipX = centerX + handLength * Math.cos(angleRad);
var handTipY = centerY + handLength * Math.sin(angleRad);
// Calculate hand base positions (for a triangle/arrow shape)
var handWidth = 6;
var perpAngleRad1 = angleRad + Math.toRadians(90);
var perpAngleRad2 = angleRad - Math.toRadians(90);
@ -145,7 +172,7 @@ class MetricWatchFaceView extends WatchUi.WatchFace {
var baseY2 = centerY + handWidth * Math.sin(perpAngleRad2);
// Draw the hand as a filled polygon
dc.setColor(Graphics.COLOR_RED, Graphics.COLOR_TRANSPARENT);
dc.setColor(color, Graphics.COLOR_TRANSPARENT);
dc.fillPolygon([
[handTipX, handTipY],
[baseX1, baseY1],