Skip to content

fix(picker): propagate setX/getX to the live lightweight popup wheels (#4897)#4902

Merged
shai-almog merged 3 commits into
masterfrom
fix/4897-picker-live-value
May 9, 2026
Merged

fix(picker): propagate setX/getX to the live lightweight popup wheels (#4897)#4902
shai-almog merged 3 commits into
masterfrom
fix/4897-picker-live-value

Conversation

@shai-almog
Copy link
Copy Markdown
Collaborator

Summary

  • Resolves RFE: Add method to Picker to get or update internal value based on the Picker scroll wheel positions set by the user #4897 without adding a new public API. Instead of introducing getPickerValue(), the existing setDate / setSelectedString / setSelectedStringIndex / setTime / setDuration (and matching getters) now operate on the live spinner while the lightweight popup is on screen, so a custom popup button can do setDate(getDate() + 7d) and have the wheels track it.
  • Removes a workaround in the custom-button handler (spinner.setValue(value); updateValue();) that clobbered user scrolling when the action didn't touch value. Cleans up the now-unused spinner parameter on createLightweightPopupButtonRow.
  • Native picker semantics are unchanged - it has no in-progress wheel handle. Each setter/getter Javadoc spells out the lightweight vs native behavior explicitly.
  • Adds PickerLiveValueScreenshotTest: opens a date picker on April 11 2026, calls setDate(April 18 2026) after the slide-up, screenshots the wheels. Wired into Cn1ssDeviceRunner and the JS chunk-stream skip list (matches the other lightweight-picker tests).

Test plan

  • mvn -pl core compile -DskipTests (JDK 8, framework target)
  • mvn -pl common compile -DskipTests for scripts/hellocodenameone (JDK 17)
  • CI screenshot suite: PickerLiveValueScreenshotTest baseline gets generated and the existing LightweightPickerButtons* tests still match (the workaround removal does not change their visual output - those tests never click the buttons).
  • Manual: scroll the date wheels, press a custom "+7 Days" button that does picker.setDate(picker.getDate() + 7d) - wheels should now move 7 days forward from the visible position, not from the original base.

🤖 Generated with Claude Code

Setting Picker.setDate (and friends) while the lightweight popup was
showing only updated the hidden committed value; the visible wheels
stayed put. Custom popup buttons that read getDate() therefore worked
off a stale base, so a "+7 days" button computed from the original
date instead of the date the user had scrolled to (#4897).

Track the live InternalPickerWidget on Picker, and have setDate /
setSelectedString / setSelectedStringIndex / setTime / setDuration
forward to it while the popup is on screen. Mirror the change on
the getters so getDate() returns the current wheel value during edit;
clear the field early in endEditing so external action listeners
fired by Done see the just-committed value. The native picker has no
in-progress wheel handle, so its semantics are unchanged - the
Javadoc on each setter/getter spells out both behaviors.

Drops the spinner.setValue(value); updateValue(); workaround from the
custom-button handler. With propagating setters it is redundant, and
worse, it actively clobbered user scrolling when an action did not
touch value. The now-unused spinner parameter on
createLightweightPopupButtonRow is removed.

Adds PickerLiveValueScreenshotTest: opens a date picker on April 11,
calls setDate(April 18) after the slide-up, and screenshots the
wheels. Pre-fix the wheels stayed on April 11; post-fix they show
April 18, so a regression here will fail the diff. Registered in
Cn1ssDeviceRunner alongside the existing lightweight-picker tests
and added to the JS chunk-stream skip list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 9, 2026

✅ JavaScript-port screenshot tests passed.

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 9, 2026

Compared 90 screenshots: 90 matched.

Native Android coverage

  • 📊 Line coverage: 10.23% (5584/54605 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.04% (27396/340776), branch 3.67% (1197/32646), complexity 4.70% (1470/31277), method 8.26% (1208/14619), class 13.73% (270/1966)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 10.23% (5584/54605 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.04% (27396/340776), branch 3.67% (1197/32646), complexity 4.70% (1470/31277), method 8.26% (1208/14619), class 13.73% (270/1966)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 1041.000 ms
Base64 CN1 encode 178.000 ms
Base64 encode ratio (CN1/native) 0.171x (82.9% faster)
Base64 native decode 819.000 ms
Base64 CN1 decode 280.000 ms
Base64 decode ratio (CN1/native) 0.342x (65.8% faster)
Image encode benchmark status skipped (SIMD unsupported)

The anonymous ActionListener no longer references the enclosing
Picker (only the captured LightweightPopupButton entry), so SpotBugs
SIC_INNER_SHOULD_BE_STATIC_ANON correctly flags the implicit
Picker.this back-reference as unnecessary. Extract it to a private
static PopupButtonActionListener so the inner class stops retaining
the enclosing instance.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 9, 2026

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 9, 2026

Compared 90 screenshots: 90 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 224 seconds

Build and Run Timing

Metric Duration
Simulator Boot 63000 ms
Simulator Boot (Run) 1000 ms
App Install 13000 ms
App Launch 9000 ms
Test Execution 225000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 1642.000 ms
Base64 CN1 encode 1482.000 ms
Base64 encode ratio (CN1/native) 0.903x (9.7% faster)
Base64 native decode 993.000 ms
Base64 CN1 decode 966.000 ms
Base64 decode ratio (CN1/native) 0.973x (2.7% faster)
Base64 SIMD encode 447.000 ms
Base64 encode ratio (SIMD/native) 0.272x (72.8% faster)
Base64 encode ratio (SIMD/CN1) 0.302x (69.8% faster)
Base64 SIMD decode 504.000 ms
Base64 decode ratio (SIMD/native) 0.508x (49.2% faster)
Base64 decode ratio (SIMD/CN1) 0.522x (47.8% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 111.000 ms
Image createMask (SIMD on) 9.000 ms
Image createMask ratio (SIMD on/off) 0.081x (91.9% faster)
Image applyMask (SIMD off) 123.000 ms
Image applyMask (SIMD on) 56.000 ms
Image applyMask ratio (SIMD on/off) 0.455x (54.5% faster)
Image modifyAlpha (SIMD off) 131.000 ms
Image modifyAlpha (SIMD on) 51.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.389x (61.1% faster)
Image modifyAlpha removeColor (SIMD off) 138.000 ms
Image modifyAlpha removeColor (SIMD on) 96.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.696x (30.4% faster)
Image PNG encode (SIMD off) 1509.000 ms
Image PNG encode (SIMD on) 3623.000 ms
Image PNG encode ratio (SIMD on/off) 2.401x (140.1% slower)
Image JPEG encode 1038.000 ms

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 9, 2026

Compared 90 screenshots: 90 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 136 seconds

Build and Run Timing

Metric Duration
Simulator Boot 67000 ms
Simulator Boot (Run) 1000 ms
App Install 10000 ms
App Launch 3000 ms
Test Execution 243000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 1409.000 ms
Base64 CN1 encode 2225.000 ms
Base64 encode ratio (CN1/native) 1.579x (57.9% slower)
Base64 native decode 1006.000 ms
Base64 CN1 decode 1076.000 ms
Base64 decode ratio (CN1/native) 1.070x (7.0% slower)
Base64 SIMD encode 446.000 ms
Base64 encode ratio (SIMD/native) 0.317x (68.3% faster)
Base64 encode ratio (SIMD/CN1) 0.200x (80.0% faster)
Base64 SIMD decode 452.000 ms
Base64 decode ratio (SIMD/native) 0.449x (55.1% faster)
Base64 decode ratio (SIMD/CN1) 0.420x (58.0% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 72.000 ms
Image createMask (SIMD on) 11.000 ms
Image createMask ratio (SIMD on/off) 0.153x (84.7% faster)
Image applyMask (SIMD off) 131.000 ms
Image applyMask (SIMD on) 52.000 ms
Image applyMask ratio (SIMD on/off) 0.397x (60.3% faster)
Image modifyAlpha (SIMD off) 138.000 ms
Image modifyAlpha (SIMD on) 101.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.732x (26.8% faster)
Image modifyAlpha removeColor (SIMD off) 140.000 ms
Image modifyAlpha removeColor (SIMD on) 78.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.557x (44.3% faster)
Image PNG encode (SIMD off) 1200.000 ms
Image PNG encode (SIMD on) 1096.000 ms
Image PNG encode ratio (SIMD on/off) 0.913x (8.7% faster)
Image JPEG encode 522.000 ms

…ScreenshotTest

Drops the dedicated PickerLiveValueScreenshotTest and instead piggybacks
the #4897 propagation check on the existing custom-buttons test. Each
variant now opens the popup with new Date() (so the wheels start on
whatever day the test happens to run), then calls setDate(fixedDate)
after the slide-up to spin them to April 11 2026 via the new
live-propagation path. The committed baselines all show that fixed
date, so a propagation regression would leave the wheels on the
runtime "today" and fail the diff every day except by coincidence -
without us having to maintain a separate screenshot per port.

Adds a 400ms second-stage wait so the wheels settle at the new
month/day/year before the PNG is captured. Total per-variant cost
goes from ~6s to ~6.4s, still inside the 30s per-test deadline for
four variants.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shai-almog shai-almog merged commit 043bfb1 into master May 9, 2026
23 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RFE: Add method to Picker to get or update internal value based on the Picker scroll wheel positions set by the user

1 participant