chore: initial padel scaffold + design docs
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
bin/
|
||||||
|
*.prg
|
||||||
|
*.prg.debug.xml
|
||||||
|
developer_key
|
||||||
|
.DS_Store
|
||||||
36
CLAUDE.md
Normal file
36
CLAUDE.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## What this is
|
||||||
|
|
||||||
|
A Garmin Connect IQ watch-app for padel, written in **Monkey C**. It is currently the default scaffold generated by the VS Code "Monkey C: New Project" command — a single view with a menu — and has not yet been customized beyond the template.
|
||||||
|
|
||||||
|
- App entry: `garmin_padelApp` (set in `manifest.xml` via `entry="garmin_padelApp"`).
|
||||||
|
- Build target: a single product, `venu445mm` (Venu 4, 45mm), with `minApiLevel="6.0.2"`.
|
||||||
|
|
||||||
|
## Build, run, and test
|
||||||
|
|
||||||
|
There is no shell-script build harness; this project is built and run through the **Monkey C VS Code extension** (Connect IQ SDK), driven from the command palette:
|
||||||
|
|
||||||
|
- **Build / run in simulator**: `Monkey C: Build for Device` then `Monkey C: Run App`, or just press `F5` (the simulator launches `connectiq` + `monkeydo`).
|
||||||
|
- **Edit build targets / products**: `Monkey C: Edit Products` or `Monkey C: Set Products by Product Category`.
|
||||||
|
- **Edit app attributes, permissions, languages**: the corresponding `Monkey C: Edit ...` palette commands. These regenerate `manifest.xml` — do not hand-edit it (it is marked generated).
|
||||||
|
- **Package for the store**: `Monkey C: Export Project` (produces a `.iq` file).
|
||||||
|
|
||||||
|
CLI equivalents (if the SDK `bin` is on PATH) use `monkeyc` to compile against a device + SDK, `connectiq`/`monkeydo` to run in the simulator, and `monkeyc --unit-test` (with a test runner view) for unit tests. There are currently no tests in this repo.
|
||||||
|
|
||||||
|
## Code architecture
|
||||||
|
|
||||||
|
Connect IQ apps follow a fixed MVC-ish lifecycle. The four `source/*.mc` files map to the standard roles:
|
||||||
|
|
||||||
|
- **`garmin-padelApp.mc`** — `AppBase` subclass. `getInitialView()` returns the initial `[View, InputDelegate]` pair. App-wide start/stop hooks live here. `getApp()` is the global accessor.
|
||||||
|
- **`garmin-padelView.mc`** — `WatchUi.View`. `onLayout` binds `Rez.Layouts.MainLayout`; `onShow`/`onUpdate`/`onHide` are the render/visibility lifecycle.
|
||||||
|
- **`garmin-padelDelegate.mc`** — `BehaviorDelegate` for the main view. `onMenu()` pushes the menu (`Rez.Menus.MainMenu`) with its delegate.
|
||||||
|
- **`garmin-padelMenuDelegate.mc`** — `MenuInputDelegate`. `onMenuItem(item as Symbol)` dispatches on menu-item symbols (`:item_1`, `:item_2`).
|
||||||
|
|
||||||
|
Key conventions:
|
||||||
|
- **Resources are referenced via the generated `Rez` namespace** (`Rez.Layouts.*`, `Rez.Menus.*`, `Rez.Strings.*`, `Rez.Drawables.*`). These symbols are generated at build time from the XML in `resources/` — you do not write them by hand.
|
||||||
|
- **`resources/`** holds the declarative UI and assets: `layouts/layout.xml`, `menus/menu.xml`, `strings/strings.xml`, `drawables/`. Menu item ids in `menu.xml` must match the `:symbol` names handled in the menu delegate, and string ids must match `@Strings.*` references.
|
||||||
|
- **`monkey.jungle`** is the build config; it currently only points at `manifest.xml`. Per-device resource overrides and source paths would be added here.
|
||||||
|
- **`bin/`** is generated build output (`.mir`, `.mbc`, `Rez.mcgen`) — never edit; safe to delete and regenerate.
|
||||||
1016
docs/superpowers/plans/2026-07-02-padel-scoring.md
Normal file
1016
docs/superpowers/plans/2026-07-02-padel-scoring.md
Normal file
File diff suppressed because it is too large
Load Diff
166
docs/superpowers/specs/2026-07-02-padel-scoring-design.md
Normal file
166
docs/superpowers/specs/2026-07-02-padel-scoring-design.md
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
# Padel Scoring App — Design Spec
|
||||||
|
|
||||||
|
**Date:** 2026-07-02
|
||||||
|
**Target:** Garmin Connect IQ watch-app (Monkey C), product `venu445mm` (Venu 4, 45mm, round AMOLED), minApiLevel 6.0.2.
|
||||||
|
**Status:** Approved design, pre-implementation.
|
||||||
|
|
||||||
|
## 1. Purpose
|
||||||
|
|
||||||
|
A padel score tracker for the watch. It shows the live score (sets / games / points) and a
|
||||||
|
top-down court diagram whose highlighted quadrant tells you who serves the next point. Points
|
||||||
|
are recorded by swiping. No GPS, no recorded Garmin activity, no match history in v1.
|
||||||
|
|
||||||
|
## 2. Screen layout
|
||||||
|
|
||||||
|
Round screen. A top band (heart rate) and a bottom band (time) frame a central row split into
|
||||||
|
three columns: **left** = sets + games, **center** = court, **right** = current-game points.
|
||||||
|
|
||||||
|
```
|
||||||
|
♥ 142 ▮▮▮▯▯ ← heart rate + zone (top band)
|
||||||
|
|
||||||
|
S G pts
|
||||||
|
2 4 +------+------+ 15 ← your team (upper number in each column)
|
||||||
|
1 3 | | | 40 ← opponents (lower number)
|
||||||
|
+------+------+ net
|
||||||
|
| | ● ← yellow ball = next server
|
||||||
|
+------+------+
|
||||||
|
|
||||||
|
14:32 ← current time (bottom band)
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Left column — sets & games.** Two mini-columns: **S** (sets) and **G** (games). A small
|
||||||
|
label (`S`, `G`) sits above each pair of numbers; under it, two stacked numbers — **your team
|
||||||
|
on top**, opponents below. Sets in **bold accent color**, games in **accent color**.
|
||||||
|
- **Right column — points.** A small `pts` label (same small font as `S`/`G`) above two stacked
|
||||||
|
numbers for the current game — your team on top, opponents below — in **white**
|
||||||
|
(`0 / 15 / 30 / 40`, and `AD` if advantage is enabled).
|
||||||
|
- **Center — court.** Simplified top-down padel court, your team the **bottom** half and
|
||||||
|
opponents the **top** half. A small **yellow ball** is drawn in the quadrant of the **next
|
||||||
|
server** (see §4); it moves as serve rotates. Nothing else is highlighted.
|
||||||
|
- **Top band — heart rate.** Current heart rate (bpm) with a **zone indicator** (the current HR
|
||||||
|
zone 1–5, shown as a short colored bar / zone number). Requires a heart-rate sensor reading
|
||||||
|
(see Permissions below).
|
||||||
|
- **Bottom band — time.** Current time (`HH:MM`), refreshed by a 1-second timer.
|
||||||
|
|
||||||
|
The small `S` / `G` / `pts` labels share one small font and a muted (dim grey) color so the
|
||||||
|
numbers stay dominant.
|
||||||
|
|
||||||
|
**Accent color.** A single constant (proposed: a vivid padel green/teal) used for the sets and
|
||||||
|
games numbers, so it can be changed in one place. The serve ball is **yellow** (its own constant).
|
||||||
|
|
||||||
|
**Permissions.** Reading live heart rate requires the **Sensor** permission; deriving the zone
|
||||||
|
from the user's profile requires the **UserProfile** permission. Both are added via the
|
||||||
|
`Monkey C: Edit Permissions` palette command (which regenerates `manifest.xml`).
|
||||||
|
|
||||||
|
## 3. Interaction model
|
||||||
|
|
||||||
|
**During play (gestures):**
|
||||||
|
- **Swipe up** → point to **your team**.
|
||||||
|
- **Swipe down** → point to the **opponents**.
|
||||||
|
- **Swipe left** → **undo** the last recorded point (steps back through game/set boundaries too).
|
||||||
|
|
||||||
|
**Before the first point (tap):**
|
||||||
|
- A **tap** toggles the starting server between **bottom-right** (your team serves first) and
|
||||||
|
**upper-left** (opponents serve first) — the yellow ball jumps between those two quadrants.
|
||||||
|
These are the only two options because the first point
|
||||||
|
of any game is served from the deuce (right) court, and the opponents' right-hand court maps to
|
||||||
|
the screen's upper-left. Tapping is only accepted while the match is at its very start (no points
|
||||||
|
recorded yet).
|
||||||
|
|
||||||
|
**At match end:**
|
||||||
|
- The court shows a "won by *your team* / *opponents*" state and stops accepting points; **undo
|
||||||
|
still works**. A **tap** starts a fresh match, returning to server-positioning.
|
||||||
|
|
||||||
|
## 4. Serving / court geometry
|
||||||
|
|
||||||
|
Your team = bottom half, opponents = top half. The yellow ball is drawn in the quadrant
|
||||||
|
determined by (serving team) × (serve side):
|
||||||
|
|
||||||
|
| Serving team | Serve side | Quadrant |
|
||||||
|
|--------------|------------|--------------|
|
||||||
|
| Your team | deuce (right) | bottom-right |
|
||||||
|
| Your team | ad (left) | bottom-left |
|
||||||
|
| Opponents | deuce (their right) | upper-left |
|
||||||
|
| Opponents | ad (their left) | upper-right |
|
||||||
|
|
||||||
|
**Serve side by point parity.** Even number of points played so far in the current game →
|
||||||
|
deuce (right); odd → ad (left). Game start (0-0) is always deuce.
|
||||||
|
|
||||||
|
**Serving team.**
|
||||||
|
- Normal game: one team serves the entire game; the serving team alternates after each completed game.
|
||||||
|
- The first server of the match is chosen by tap (see §3).
|
||||||
|
|
||||||
|
**Tiebreak serving** (when tiebreak is enabled and reached, see §5):
|
||||||
|
- Serve side still follows point parity: even total tiebreak points → deuce, odd → ad.
|
||||||
|
- The first server serves 1 point, then service alternates every 2 points. (Server for the point
|
||||||
|
with `P` points already played = the team given by `floor((P+1)/2) mod 2` offset from the
|
||||||
|
team due to serve at 6-6.)
|
||||||
|
|
||||||
|
## 5. Scoring rules
|
||||||
|
|
||||||
|
Rules are held in a `RulesConfig` object that the engine reads as parameters, so the future
|
||||||
|
settings screen can drive them without an engine rewrite. **v1 defaults** (all overridable later):
|
||||||
|
|
||||||
|
- **Points in a game:** `0 / 15 / 30 / 40`.
|
||||||
|
- **40-40 resolution:** **golden point** (default). Next point at 40-40 wins the game. When
|
||||||
|
`RulesConfig` is set to advantage instead, 40-40 = deuce, then advantage (`AD`), then game;
|
||||||
|
must win by two points.
|
||||||
|
- **Set:** first to **6 games, win by 2**.
|
||||||
|
- **6-6:** **7-point tiebreak** (win by 2). When tiebreak is disabled in `RulesConfig`, the set
|
||||||
|
continues until a team leads by 2 games.
|
||||||
|
- **Match:** **best of 3 sets** (first to 2 sets).
|
||||||
|
|
||||||
|
## 6. Architecture (Monkey C)
|
||||||
|
|
||||||
|
Keeps the scaffold's file-per-role split; adds two logic-only files. The scoring engine imports no
|
||||||
|
`WatchUi`/`Graphics`, so it is unit-testable in isolation.
|
||||||
|
|
||||||
|
- **`source/PadelMatch.mc`** — the scoring engine. Holds points/games/sets for both teams, the
|
||||||
|
serving team, tiebreak state, and match-over/winner. Public surface:
|
||||||
|
- `pointTo(team)` — record a point, advancing game/set/match as needed.
|
||||||
|
- `undo()` — revert the last recorded point.
|
||||||
|
- `servingQuadrant()` — returns which of the four quadrants holds the serve ball.
|
||||||
|
- `setStartingServer(team)` / toggle — only valid at match start.
|
||||||
|
- accessors for the display: points (per team, formatted), games, sets, `isMatchOver()`, `winner()`.
|
||||||
|
- **Undo strategy:** push a full state snapshot onto a stack before each `pointTo`; `undo` pops
|
||||||
|
and restores. This makes swipe-left correct across point/game/set boundaries with no special-casing.
|
||||||
|
- **`source/RulesConfig.mc`** — the rules struct (golden-point flag, sets-to-win, games-per-set,
|
||||||
|
tiebreak flag/target) plus the v1 defaults.
|
||||||
|
- **`source/CourtRenderer.mc`** — draws the top-down court and the yellow serve ball in a given
|
||||||
|
quadrant, so the view stays focused on layout. Pure drawing against a `Dc`.
|
||||||
|
- **`source/HeartRateProvider.mc`** — wraps the heart-rate sensor and zone lookup. Enables
|
||||||
|
`Sensor.SENSOR_HEARTRATE`, exposes the latest bpm, and maps it to a zone 1–5 using
|
||||||
|
`UserProfile.getHeartRateZones`. Returns a "no reading" state when HR is unavailable
|
||||||
|
(simulator / no strap) so the view can render a placeholder.
|
||||||
|
- **`source/garmin-padelView.mc`** — `WatchUi.View`. `onUpdate` draws the top HR band, the left
|
||||||
|
sets/games column, the center court (via `CourtRenderer`), the right points column, and the
|
||||||
|
bottom time band. A 1-second `Timer` calls `requestUpdate` to keep the clock (and HR) live.
|
||||||
|
- **`source/garmin-padelDelegate.mc`** — `BehaviorDelegate`. Maps `onSwipe` (up/down/left) and
|
||||||
|
`onTap` (pre-match server toggle; new match after match end) to the engine, then `requestUpdate`.
|
||||||
|
- **`source/garmin-padelApp.mc`** — owns the `PadelMatch`, `RulesConfig`, and `HeartRateProvider`
|
||||||
|
instances; wires the view + delegate; enables sensors on start and disables them on stop.
|
||||||
|
|
||||||
|
Resources (`resources/`): the whole screen is drawn programmatically in `onUpdate` rather than via
|
||||||
|
a static layout, since positions depend on state. `strings.xml` holds team labels and the
|
||||||
|
match-end text; the template menu can be removed or repurposed later. Sensor + UserProfile
|
||||||
|
permissions are declared in `manifest.xml` via the Edit Permissions command.
|
||||||
|
|
||||||
|
## 7. Testing
|
||||||
|
|
||||||
|
- **Engine unit tests** (`monkeyc --unit-test` with a test runner) cover `PadelMatch`:
|
||||||
|
- point → game → set → match progression (golden point and advantage modes),
|
||||||
|
- tiebreak entry at 6-6, tiebreak win-by-2,
|
||||||
|
- serving team alternation between games and serve-side parity within a game,
|
||||||
|
- tiebreak serving rotation,
|
||||||
|
- `servingQuadrant()` mapping for all four cases,
|
||||||
|
- `undo()` across point/game/set boundaries and at match start (no-op).
|
||||||
|
- Rendering (`CourtRenderer`, view, HR band) is verified in the simulator (HR via the
|
||||||
|
simulator's data-simulation, since there is no real strap).
|
||||||
|
|
||||||
|
## 8. Deferred (not in v1)
|
||||||
|
|
||||||
|
- Settings screen (drives `RulesConfig`; makes the top/bottom info slots configurable).
|
||||||
|
- Match history / saved matches.
|
||||||
|
- Resume-after-close persistence (engine state is in memory only for v1).
|
||||||
|
- Recorded Garmin activity, GPS. (Heart rate **is** in v1 as a read-only display, but the match is
|
||||||
|
still not recorded as a Garmin activity.)
|
||||||
35
manifest.xml
Normal file
35
manifest.xml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This is a generated file. It is highly recommended that you DO NOT edit this file. -->
|
||||||
|
<iq:manifest version="3" xmlns:iq="http://www.garmin.com/xml/connectiq">
|
||||||
|
<!--
|
||||||
|
Use "Monkey C: Edit Application" from the Visual Studio Code command palette
|
||||||
|
to update the application attributes.
|
||||||
|
-->
|
||||||
|
<iq:application id="0e742fe4-203e-4dbe-a0c0-5dcb26aac685" type="watch-app" name="@Strings.AppName" entry="garmin_padelApp" launcherIcon="@Drawables.LauncherIcon" minApiLevel="6.0.2">
|
||||||
|
<!--
|
||||||
|
Use the following from the Visual Studio Code comand palette to edit
|
||||||
|
the build targets:
|
||||||
|
"Monkey C: Set Products by Product Category" - Lets you add all products
|
||||||
|
that belong to the same product category
|
||||||
|
"Monkey C: Edit Products" - Lets you add or remove any product
|
||||||
|
-->
|
||||||
|
<iq:products>
|
||||||
|
<iq:product id="venu445mm"/>
|
||||||
|
</iq:products>
|
||||||
|
<!--
|
||||||
|
Use "Monkey C: Edit Permissions" from the Visual Studio Code command
|
||||||
|
palette to update permissions.
|
||||||
|
-->
|
||||||
|
<iq:permissions/>
|
||||||
|
<!--
|
||||||
|
Use "Monkey C: Edit Languages" from the Visual Studio Code command
|
||||||
|
palette to edit your compatible language list.
|
||||||
|
-->
|
||||||
|
<iq:languages/>
|
||||||
|
<!--
|
||||||
|
Use "Monkey C: Configure Monkey Barrel" from the Visual Studio Code
|
||||||
|
command palette to edit the included barrels.
|
||||||
|
-->
|
||||||
|
<iq:barrels/>
|
||||||
|
</iq:application>
|
||||||
|
</iq:manifest>
|
||||||
1
monkey.jungle
Normal file
1
monkey.jungle
Normal file
@@ -0,0 +1 @@
|
|||||||
|
project.manifest = manifest.xml
|
||||||
3
resources/drawables/drawables.xml
Normal file
3
resources/drawables/drawables.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<drawables xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://developer.garmin.com/downloads/connect-iq/resources.xsd">
|
||||||
|
<bitmap id="LauncherIcon" filename="launcher_icon.svg" dithering="none" />
|
||||||
|
</drawables>
|
||||||
7
resources/drawables/launcher_icon.svg
Normal file
7
resources/drawables/launcher_icon.svg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="24" height="24" fill="#000000"/>
|
||||||
|
<path d="M3 4C3 3.44772 3.44772 3 4 3H10C10.5523 3 11 3.44772 11 4V10C11 10.5523 10.5523 11 10 11H4C3.44772 11 3 10.5523 3 10V4Z" fill="#F4F4F4"/>
|
||||||
|
<path d="M3 14C3 13.4477 3.44772 13 4 13H10C10.5523 13 11 13.4477 11 14V20C11 20.5523 10.5523 21 10 21H4C3.44772 21 3 20.5523 3 20V14Z" fill="#F4F4F4"/>
|
||||||
|
<path d="M13 4C13 3.44772 13.4477 3 14 3H20C20.5523 3 21 3.44772 21 4V10C21 10.5523 20.5523 11 20 11H14C13.4477 11 13 10.5523 13 10V4Z" fill="#F4F4F4"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.3 14.3V19.7H19.7V14.3H14.3ZM14 13C13.4477 13 13 13.4477 13 14V20C13 20.5523 13.4477 21 14 21H20C20.5523 21 21 20.5523 21 20V14C21 13.4477 20.5523 13 20 13H14Z" fill="#F4F4F4"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 832 B |
BIN
resources/drawables/monkey.png
Normal file
BIN
resources/drawables/monkey.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
4
resources/layouts/layout.xml
Normal file
4
resources/layouts/layout.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<layout id="MainLayout" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://developer.garmin.com/downloads/connect-iq/resources.xsd">
|
||||||
|
<label x="center" y="5" text="@Strings.prompt" color="Graphics.COLOR_WHITE" justification="Graphics.TEXT_JUSTIFY_CENTER" />
|
||||||
|
<bitmap id="id_monkey" x="center" y="30" filename="../drawables/monkey.png" />
|
||||||
|
</layout>
|
||||||
4
resources/menus/menu.xml
Normal file
4
resources/menus/menu.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<menu id="MainMenu" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://developer.garmin.com/downloads/connect-iq/resources.xsd">
|
||||||
|
<menu-item id="item_1" label="@Strings.menu_label_1" />
|
||||||
|
<menu-item id="item_2" label="@Strings.menu_label_2" />
|
||||||
|
</menu>
|
||||||
8
resources/strings/strings.xml
Normal file
8
resources/strings/strings.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<strings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://developer.garmin.com/downloads/connect-iq/resources.xsd">
|
||||||
|
<string id="AppName">garmin-padel</string>
|
||||||
|
|
||||||
|
<string id="prompt">Click the menu button</string>
|
||||||
|
|
||||||
|
<string id="menu_label_1">Item 1</string>
|
||||||
|
<string id="menu_label_2">Item 2</string>
|
||||||
|
</strings>
|
||||||
28
source/garmin-padelApp.mc
Normal file
28
source/garmin-padelApp.mc
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import Toybox.Application;
|
||||||
|
import Toybox.Lang;
|
||||||
|
import Toybox.WatchUi;
|
||||||
|
|
||||||
|
class garmin_padelApp extends Application.AppBase {
|
||||||
|
|
||||||
|
function initialize() {
|
||||||
|
AppBase.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// onStart() is called on application start up
|
||||||
|
function onStart(state as Dictionary?) as Void {
|
||||||
|
}
|
||||||
|
|
||||||
|
// onStop() is called when your application is exiting
|
||||||
|
function onStop(state as Dictionary?) as Void {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the initial view of your application here
|
||||||
|
function getInitialView() as [Views] or [Views, InputDelegates] {
|
||||||
|
return [ new garmin_padelView(), new garmin_padelDelegate() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getApp() as garmin_padelApp {
|
||||||
|
return Application.getApp() as garmin_padelApp;
|
||||||
|
}
|
||||||
15
source/garmin-padelDelegate.mc
Normal file
15
source/garmin-padelDelegate.mc
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import Toybox.Lang;
|
||||||
|
import Toybox.WatchUi;
|
||||||
|
|
||||||
|
class garmin_padelDelegate extends WatchUi.BehaviorDelegate {
|
||||||
|
|
||||||
|
function initialize() {
|
||||||
|
BehaviorDelegate.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMenu() as Boolean {
|
||||||
|
WatchUi.pushView(new Rez.Menus.MainMenu(), new garmin_padelMenuDelegate(), WatchUi.SLIDE_UP);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
19
source/garmin-padelMenuDelegate.mc
Normal file
19
source/garmin-padelMenuDelegate.mc
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import Toybox.Lang;
|
||||||
|
import Toybox.System;
|
||||||
|
import Toybox.WatchUi;
|
||||||
|
|
||||||
|
class garmin_padelMenuDelegate extends WatchUi.MenuInputDelegate {
|
||||||
|
|
||||||
|
function initialize() {
|
||||||
|
MenuInputDelegate.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMenuItem(item as Symbol) as Void {
|
||||||
|
if (item == :item_1) {
|
||||||
|
System.println("item 1");
|
||||||
|
} else if (item == :item_2) {
|
||||||
|
System.println("item 2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
33
source/garmin-padelView.mc
Normal file
33
source/garmin-padelView.mc
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import Toybox.Graphics;
|
||||||
|
import Toybox.WatchUi;
|
||||||
|
|
||||||
|
class garmin_padelView extends WatchUi.View {
|
||||||
|
|
||||||
|
function initialize() {
|
||||||
|
View.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load your resources here
|
||||||
|
function onLayout(dc as Dc) as Void {
|
||||||
|
setLayout(Rez.Layouts.MainLayout(dc));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when this View is brought to the foreground. Restore
|
||||||
|
// the state of this View and prepare it to be shown. This includes
|
||||||
|
// loading resources into memory.
|
||||||
|
function onShow() as Void {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the view
|
||||||
|
function onUpdate(dc as Dc) as Void {
|
||||||
|
// Call the parent onUpdate function to redraw the layout
|
||||||
|
View.onUpdate(dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when this View is removed from the screen. Save the
|
||||||
|
// state of this View here. This includes freeing resources from
|
||||||
|
// memory.
|
||||||
|
function onHide() as Void {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user