mirror of
https://github.com/bitsycore/compose-desktop-native.git
synced 2026-10-05 18:57:26 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b2e83a155 | ||
|
|
8a6cb868d9 | ||
|
|
4a7080b313 | ||
|
|
1afb13aae0 | ||
|
|
3d519bcfcd | ||
|
|
72287fc995 | ||
|
|
0b4a170910 | ||
|
|
72e6f145b3 | ||
|
|
367ed94c01 | ||
|
|
fa9bd93ada | ||
|
|
d1551bc9c1 | ||
|
|
e9527ee8c2 | ||
|
|
6040816cf7 | ||
|
|
6f3bc915b2 | ||
|
|
1ba84a3a2c | ||
|
|
e807ecf973 | ||
|
|
dc35f5bd37 | ||
|
|
4888fdcda0 | ||
|
|
85e0179590 |
@@ -31,9 +31,16 @@ jobs:
|
||||
host: macos
|
||||
target: MacosArm64
|
||||
exe_ext: kexe
|
||||
# jvm publication: only :material-symbols declares a jvm() target
|
||||
# (its common API renders via upstream Compose on JVM) — publish
|
||||
# its host-independent jar from the same host as the metadata.
|
||||
# :compose-desktop-native-bridge (the consumer-side bridge Gradle plugin +
|
||||
# its plugin marker) is host-independent too — same job.
|
||||
tasks: >-
|
||||
publishKotlinMultiplatformPublicationToGitHubPackagesRepository
|
||||
publishMacosArm64PublicationToGitHubPackagesRepository
|
||||
publishJvmPublicationToGitHubPackagesRepository
|
||||
:compose-desktop-native-bridge:publishAllPublicationsToGitHubPackagesRepository
|
||||
- runner: ubuntu-22.04
|
||||
host: linux
|
||||
target: LinuxX64
|
||||
@@ -95,23 +102,33 @@ jobs:
|
||||
# intrinsic K/N's LLD can't resolve is aliased to msvcrt's _setjmpex at
|
||||
# link time via --defsym in sdl3.def.
|
||||
|
||||
# Build static SDL3 / SDL3_ttf / SDL3_image / FreeType from
|
||||
# scripts/build-sdl/build-sdl.properties. Cached against the manifest +
|
||||
# scripts so version bumps invalidate cleanly.
|
||||
# `cache_version` is a manual bump for when the toolchain (runner OS,
|
||||
# compiler flavour, K/N sysroot expectations) changes without any
|
||||
# scripts/build-sdl/ file changing. Increment to force a rebuild.
|
||||
# Build the static native deps from scripts/build-sdl/build-sdl.properties.
|
||||
# Only Windows ships the SDL3 renderer (no Skiko on mingw), so only it needs
|
||||
# SDL3_ttf / SDL3_image / FreeType (SDL3_ttf text, SDL3_image decode, FreeType
|
||||
# icon-axis rasterisation). macOS / Linux publish the Skia renderer — Skiko
|
||||
# handles text / images / icons — so they only need base SDL3 for the main
|
||||
# loop (windowing / input / audio / filesystem). Matches the cinterop guard
|
||||
# in compose/ui/ui/build.gradle.kts, which skips those three cinterops on the
|
||||
# Skia targets. Cached against the manifest + scripts so version bumps
|
||||
# invalidate cleanly; bump the `v3` key when the toolchain (runner OS,
|
||||
# compiler flavour, K/N sysroot) changes without a scripts/build-sdl/ edit.
|
||||
- name: Cache libs/
|
||||
id: cache-libs
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: libs
|
||||
key: sdl-libs-v2-${{ matrix.host }}-${{ hashFiles('scripts/build-sdl/**') }}
|
||||
key: sdl-libs-v3-${{ matrix.host }}-${{ hashFiles('scripts/build-sdl/**') }}
|
||||
|
||||
- name: Build static SDL / TTF / image / FreeType
|
||||
# Windows: full SDL3 renderer stack. macOS / Linux (Skia): base SDL3 only.
|
||||
- name: Build static native deps
|
||||
if: steps.cache-libs.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: bash scripts/build-sdl/build-all.sh
|
||||
run: |
|
||||
if [ "${{ matrix.host }}" = "windows" ]; then
|
||||
python3 scripts/build-sdl/build-all.py
|
||||
else
|
||||
python3 scripts/build-sdl/build-all.py sdl3
|
||||
fi
|
||||
|
||||
# src/vendor/ trees are gitignored — a fresh checkout has zero vendored
|
||||
# androidx.compose.* files. Sync copies them in from the upstream refs
|
||||
@@ -121,16 +138,65 @@ jobs:
|
||||
shell: bash
|
||||
run: bash scripts/compose-fork/sync.sh
|
||||
|
||||
# GitHub Packages sometimes returns 409 Conflict on a fresh upload when
|
||||
# the same coordinate was recently deleted (soft-delete propagation).
|
||||
# `--continue` lets Gradle finish the rest of the publish tasks past a
|
||||
# single 409, and the outer retry re-runs the whole thing (Gradle skips
|
||||
# already-uploaded artifacts). Two attempts is enough for the transient
|
||||
# cases we've hit; the third pass falls through as a hard failure.
|
||||
# GitHub Packages FORBIDS overwriting a file that already exists in a
|
||||
# version, and maven-publish uploads each publication's files
|
||||
# SEQUENTIALLY from the first one. So when an upload dies mid-publication
|
||||
# (the v0.1.13 macOS run lost DNS mid-publish), a blind retry hits 409
|
||||
# Conflict on the first already-uploaded file and aborts BEFORE reaching
|
||||
# the missing tail files — the version is poisoned and can never
|
||||
# complete. A 409 is therefore only benign when the publication had
|
||||
# already completed; you can't tell from the 409 alone. The fix: between
|
||||
# attempts, DELETE this host's package versions for the current release
|
||||
# and re-upload from a clean slate. Each host owns DISJOINT package
|
||||
# names (roots / -macosarm64 / -jvm / bridge on macOS, -mingwx64 on
|
||||
# Windows, -linuxx64/-linuxarm64 on Linux), so parallel jobs never touch
|
||||
# each other's uploads. Uses the run's GITHUB_TOKEN (packages: write);
|
||||
# a 403 on delete just degrades to the old blind-retry behaviour.
|
||||
- name: Publish to GitHub Packages
|
||||
shell: bash
|
||||
run: |
|
||||
set -e
|
||||
VER="${PUBLISH_VERSION#v}"
|
||||
OWNER="${GITHUB_REPOSITORY%%/*}"
|
||||
# Keep in sync with the module list in settings.gradle.kts.
|
||||
MODULES="ui ui-util ui-geometry ui-unit ui-backhandler ui-tooling-preview animation animation-core animation-graphics foundation foundation-layout material3 material-ripple window material-symbols navigation3-ui components-resources"
|
||||
case "${{ matrix.host }}" in
|
||||
macos) SUFFIXES="_ROOT_ -macosarm64" ;;
|
||||
linux) SUFFIXES="-linuxx64 -linuxarm64" ;;
|
||||
windows) SUFFIXES="-mingwx64" ;;
|
||||
esac
|
||||
host_packages() {
|
||||
for m in $MODULES; do
|
||||
for s in $SUFFIXES; do
|
||||
if [ "$s" = "_ROOT_" ]; then echo "com.bitsycore.compose.sdl.$m"; else echo "com.bitsycore.compose.sdl.$m$s"; fi
|
||||
done
|
||||
done
|
||||
if [ "${{ matrix.host }}" = "macos" ]; then
|
||||
echo "com.bitsycore.compose.sdl.material-symbols-jvm"
|
||||
echo "com.bitsycore.compose.sdl.compose-desktop-native-bridge"
|
||||
echo "com.bitsycore.compose-desktop-native.bridge.com.bitsycore.compose-desktop-native.bridge.gradle.plugin"
|
||||
fi
|
||||
}
|
||||
cleanup_host_versions() {
|
||||
echo "Deleting this host's partially-published $VER package versions"
|
||||
host_packages | while read -r pkg; do
|
||||
vid=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
|
||||
"https://api.github.com/users/$OWNER/packages/maven/$pkg/versions?per_page=100" \
|
||||
| jq -r --arg v "$VER" '[.[]? | select(.name==$v) | .id] | first // empty')
|
||||
[ -z "$vid" ] && continue
|
||||
code=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
|
||||
-H "Authorization: Bearer $GITHUB_TOKEN" \
|
||||
"https://api.github.com/users/$OWNER/packages/maven/$pkg/versions/$vid")
|
||||
if [ "$code" != "204" ]; then
|
||||
# Deleting the LAST version of a package is refused (400) —
|
||||
# a package new in this release: drop the whole package.
|
||||
code=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
|
||||
-H "Authorization: Bearer $GITHUB_TOKEN" \
|
||||
"https://api.github.com/users/$OWNER/packages/maven/$pkg")
|
||||
fi
|
||||
echo " $pkg@$VER -> HTTP $code"
|
||||
done
|
||||
}
|
||||
for attempt in 1 2 3; do
|
||||
echo "::group::Publish attempt $attempt"
|
||||
if ./gradlew ${{ matrix.tasks }} --continue --no-daemon --stacktrace; then
|
||||
@@ -138,7 +204,11 @@ jobs:
|
||||
exit 0
|
||||
fi
|
||||
echo "::endgroup::"
|
||||
[ $attempt -lt 3 ] && { echo "::warning::Publish attempt $attempt failed — sleeping 60s and retrying"; sleep 60; }
|
||||
if [ $attempt -lt 3 ]; then
|
||||
echo "::warning::Publish attempt $attempt failed — cleaning this host's $VER packages and retrying"
|
||||
cleanup_host_versions || true
|
||||
sleep 30
|
||||
fi
|
||||
done
|
||||
echo "::error::Publish failed after 3 attempts"
|
||||
exit 1
|
||||
@@ -167,15 +237,11 @@ jobs:
|
||||
target_dir=$(echo "${{ matrix.target }}" | awk '{print tolower(substr($0,1,1)) substr($0,2)}')
|
||||
version="${GITHUB_REF_NAME#v}"
|
||||
mkdir -p dist
|
||||
# Windows Git Bash has no `zip`; every runner has JDK 21 → use `jar cf`
|
||||
# which writes a valid ZIP file. `-C dir file` = enter dir then add
|
||||
# `file` at the archive root, so the archive stays flat like `zip -j`.
|
||||
for app in demo apidemo; do
|
||||
src="$app/build/bin/$target_dir/releaseExecutable"
|
||||
zip_path="$(pwd)/dist/$app-$version-$target_dir.zip"
|
||||
jar --create --no-manifest --file "$zip_path" \
|
||||
-C "$src" "$app.${{ matrix.exe_ext }}" \
|
||||
-C "$src" "data.kres"
|
||||
python3 -c 'import sys,os,zipfile; z=zipfile.ZipFile(sys.argv[1],"w",zipfile.ZIP_DEFLATED,compresslevel=9); [z.write(f,os.path.basename(f)) for f in sys.argv[2:]]; z.close()' \
|
||||
"$zip_path" "$src/$app.${{ matrix.exe_ext }}" "$src/data.kres"
|
||||
done
|
||||
ls -la dist/
|
||||
|
||||
|
||||
@@ -42,7 +42,12 @@ compose/
|
||||
│ ├── ui-util/ → :ui-util — androidx.compose.ui.util.* (+ Experimental/InternalComposeUiApi)
|
||||
│ ├── ui-geometry/ → :ui-geometry — androidx.compose.ui.geometry.*
|
||||
│ ├── ui-unit/ → :ui-unit — androidx.compose.ui.unit.*
|
||||
│ └── ui-backhandler/ → :ui-backhandler — androidx.compose.ui.backhandler.*
|
||||
│ ├── ui-backhandler/ → :ui-backhandler — androidx.compose.ui.backhandler.*
|
||||
│ └── ui-tooling-preview/ → :ui-tooling-preview — androidx.compose.ui.tooling.preview.*
|
||||
│ (the common @Preview + PreviewParameterProvider,
|
||||
│ vendored verbatim; the Maven artifact ships no
|
||||
│ mingwX64/linux klibs). IDE-only metadata — previews
|
||||
│ render through the apps' jvm parity targets.
|
||||
├── animation/
|
||||
│ ├── animation-core/ → :animation-core — androidx.compose.animation.core.*
|
||||
│ ├── animation/ → :animation — androidx.compose.animation.* (non-core)
|
||||
@@ -60,8 +65,21 @@ compose/
|
||||
|
||||
utils/
|
||||
└── material-symbols/ → :material-symbols — codepoints + all three style objects
|
||||
(Outlined / Rounded / Sharp). Apps get one dep;
|
||||
the consumer Zip task bundles only the fonts used.
|
||||
(Outlined / Rounded / Sharp). COMMON API (usable from
|
||||
shared app code) + per-stack actuals: native renders
|
||||
via :foundation IconFontIcon (IconFont handles the
|
||||
SDL3/Skia split), jvm() via Skiko directly
|
||||
(Typeface.makeClone per axes — upstream's FontCache
|
||||
drops variationSettings from its key). Its commonMain
|
||||
declares official Maven compose coords — the root
|
||||
build's FULL-COMMONIZATION BRIDGE substitutes the
|
||||
whole ui / foundation / animation / material3 /
|
||||
nav3-ui family to project modules on native configs
|
||||
(:demo and :apidemo commonMains rely on the same
|
||||
bridge; :compose-desktop-native-bridge ships it to
|
||||
consumers). Apps get one dep; the consumer Zip task
|
||||
bundles only the fonts used (native) and
|
||||
jvmProcessResources stages the same fonts (jvm).
|
||||
|
||||
components/
|
||||
└── resources/library/ → :components-resources — the OFFICIAL Compose resources
|
||||
@@ -93,12 +111,28 @@ demo/ → :demo — flagship showcase app (30+ screens) + th
|
||||
MULTIPLATFORM: also has a jvm() target running the SAME shared
|
||||
screens on stock JVM Compose Desktop (`./gradlew :demo:run`,
|
||||
MainJvmKt) — the parity reference; differences vs native = port bugs
|
||||
apidemo/ → :apidemo — Postman-style REST API manager
|
||||
scripts/ → vendor-sync + python helper scripts (compose-fidelity/coverage,
|
||||
material-symbols generate/subset) + compose-fork/;
|
||||
scripts/build-sdl/ = Windows static-lib build scripts (bash)
|
||||
apidemo/ → :apidemo — Postman-style REST API manager. MULTIPLATFORM like :demo
|
||||
(`./gradlew :apidemo:run`): the whole UI lives in commonMain
|
||||
against the official Maven coords; SDL-backed APIs go through
|
||||
expect/actual seams (compat/Compat.kt — native actuals delegate
|
||||
to com.compose.sdl, jvm actuals use AWT + upstream desktop).
|
||||
mTLS / TLS-chain inspection stays native-only (bundled libcurl).
|
||||
gradle-plugin/
|
||||
└── compose-desktop-native-bridge/ → :compose-desktop-native-bridge — the CONSUMER-side bridge as a
|
||||
published Gradle plugin (id com.bitsycore.compose-desktop-native
|
||||
.bridge, applies to Settings or Project): substitution rules
|
||||
can't ship inside Maven artifacts, so third-party apps apply the
|
||||
plugin, declare OFFICIAL CMP coords in commonMain, and native
|
||||
configurations swap in the published com.bitsycore.compose.sdl
|
||||
klibs. Substituted version defaults to the plugin's own
|
||||
(override: composeDesktopNative.version property). Published by
|
||||
the macOS publish job.
|
||||
scripts/ → vendor-sync + python helper scripts (compose-coverage = API
|
||||
coverage/fidelity vs upstream, material-symbols generate/subset)
|
||||
+ compose-fork/;
|
||||
scripts/build-sdl/ = static-lib build script (python)
|
||||
libs/ → gitignored per-host static SDL3 / SDL3_ttf / SDL3_image / FreeType
|
||||
output of scripts/build-sdl/build-*.sh on Windows
|
||||
output of scripts/build-sdl/build-all.py on Windows
|
||||
```
|
||||
|
||||
Module PATHS stay short (`:ui`, `:foundation`, `:window`, …) —
|
||||
@@ -307,26 +341,28 @@ gradlew.bat :apidemo:runDebugExecutableMingwX64
|
||||
./gradlew :demo:runDebugExecutableMacosArm64 -Prenderer=sdl3
|
||||
|
||||
# Stock JVM Compose Desktop (any host) — the parity reference: the SAME shared
|
||||
# demo screens on upstream Compose; differences vs the native build = port bugs.
|
||||
# screens on upstream Compose; differences vs the native build = port bugs.
|
||||
./gradlew :demo:run
|
||||
./gradlew :apidemo:run
|
||||
```
|
||||
|
||||
### System dependencies
|
||||
|
||||
**macOS (default Skia build):** `brew install sdl3`. Only need `sdl3_ttf`
|
||||
if you set `-Prenderer=sdl3`. Skiko klibs come from Maven.
|
||||
SDL3 + SDL3_ttf + SDL3_image + FreeType (+ image codecs) are **built from
|
||||
source as static libraries on every OS** and linked straight into the
|
||||
executable — no brew/apt SDL packages, no runtime .dll/.so/.dylib;
|
||||
a distributable is `<app>` + `data.kres`. One script does it all:
|
||||
`python scripts/build-sdl/build-all.py` (plain Python 3, no Git Bash needed)
|
||||
builds into the gitignored, in-repo `libs/` folder. Versions/URLs pinned in
|
||||
`scripts/build-sdl/build-sdl.properties`. Steps run in order freetype → sdl3
|
||||
→ sdl3-image → sdl3-ttf; pass step names to rebuild a subset
|
||||
(`python scripts/build-sdl/build-all.py sdl3-ttf`).
|
||||
|
||||
**Linux (default Skia build):** `sudo apt install libsdl3-dev`. Same caveat
|
||||
for SDL3_ttf.
|
||||
|
||||
**Windows (mingwX64 — always uses SDL3 + SDL3_ttf + SDL3_image + FreeType):**
|
||||
these four libraries + image codecs are **linked statically into the
|
||||
executable** — no runtime DLLs, distributable is just `<app>.exe` +
|
||||
`data.kres`. They're not downloaded — `scripts/build-sdl/build-all.sh` (from Git
|
||||
Bash) builds them from source as static libs into a gitignored, in-repo `libs/`
|
||||
folder. Needs: git, cmake, mingw-w64 gcc/g++ on PATH, plus curl + python for
|
||||
ninja fetch. `scripts/build-sdl/build-all.sh` = `build-freetype.sh` → `build-sdl3.sh` →
|
||||
`build-sdl3-image.sh` → `build-sdl3-ttf.sh`.
|
||||
Needs everywhere: git, cmake, python 3 (ninja fetched automatically). Per
|
||||
host: macOS = Xcode CLT (Skia default; Skiko klibs from Maven); Linux =
|
||||
gcc/g++ + the X11/Wayland/audio dev headers SDL3's configure detects (apt
|
||||
list in .github/workflows/publish.yml); Windows = mingw-w64 g++ on PATH
|
||||
(C compiles with K/N's bundled mingw).
|
||||
|
||||
## Runtime bundling — data.kres
|
||||
|
||||
@@ -469,6 +505,15 @@ that should surface in tooling.
|
||||
toggling the renderer property may not invalidate it. Delete
|
||||
`.gradle/configuration-cache/` between switches if you see weird
|
||||
"couldn't find sdl3_ttf" errors.
|
||||
- **Substituted Maven modules hide their transitives from common metadata** —
|
||||
when the bridge swaps an official coord for a project module on native
|
||||
configs, KGP's granular-metadata visibility check drops that Maven module's
|
||||
TRANSITIVES from the commonMain classpath (symptom: `Unresolved reference
|
||||
'Color'` / `Cannot access class ...` in `compileCommonMainKotlinMetadata`,
|
||||
while per-target compilation is fine). Declare EVERY artifact the common
|
||||
code touches DIRECTLY (ui-graphics, ui-text, ui-unit, …) and give each its
|
||||
own bridge rule. Note only the macOS publish job compiles common metadata —
|
||||
test with `gradlew :<module>:compileCommonMainKotlinMetadata` before tagging.
|
||||
- **`Path()` in commonMain returns different actuals per renderer** —
|
||||
the Skia renderer produces a `SkiaBackedPath` (wraps
|
||||
`org.jetbrains.skia.Path`), the SDL renderer produces a project
|
||||
|
||||
@@ -32,7 +32,9 @@ compose/
|
||||
│ ├── ui-util/ → :ui-util
|
||||
│ ├── ui-geometry/ → :ui-geometry
|
||||
│ ├── ui-unit/ → :ui-unit
|
||||
│ └── ui-backhandler/ → :ui-backhandler
|
||||
│ ├── ui-backhandler/ → :ui-backhandler
|
||||
│ └── ui-tooling-preview/ → :ui-tooling-preview (common @Preview + PreviewParameterProvider —
|
||||
│ IDE-only metadata; previews render via the apps' jvm targets)
|
||||
├── animation/
|
||||
│ ├── animation-core/ → :animation-core
|
||||
│ ├── animation/ → :animation
|
||||
@@ -47,7 +49,11 @@ compose/
|
||||
per-window Lifecycle/ViewModelStore/SavedState owners)
|
||||
|
||||
utils/
|
||||
└── material-symbols/ → :material-symbols (codepoints + Outlined/Rounded/Sharp icon fonts)
|
||||
└── material-symbols/ → :material-symbols (Material Symbols: 4200+ codepoints + Outlined/Rounded/
|
||||
Sharp composables with the variable-font axes as
|
||||
parameters (FILL/wght/GRAD/opsz). Common API — native
|
||||
draws via the port's icon-font engine, the jvm target
|
||||
via Skiko, so shared app code uses it on both stacks)
|
||||
|
||||
components/
|
||||
└── resources/library/ → :components-resources (vendored official compose resources runtime —
|
||||
@@ -58,9 +64,13 @@ navigation3/
|
||||
└── navigation3-ui/ → :navigation3-ui (vendored NavDisplay + scene machinery — the one
|
||||
Navigation 3 layer without a K/N desktop artifact)
|
||||
|
||||
gradle-plugin/
|
||||
└── compose-desktop-native-bridge/ → :compose-desktop-native-bridge (the consumer-side bridge, published
|
||||
as a Gradle plugin — see "Using it from your own build")
|
||||
|
||||
demo/ → :demo (showcase + CLI probe suite; multiplatform — the same screens
|
||||
also build for stock JVM Compose Desktop as a parity reference)
|
||||
apidemo/ → :apidemo (Postman-style REST client)
|
||||
apidemo/ → :apidemo (Postman-style REST client; multiplatform — same UI on JVM too)
|
||||
```
|
||||
|
||||
## demo — widget & feature showcase
|
||||
@@ -102,8 +112,13 @@ file-based sessions.
|
||||
./gradlew :apidemo:runDebugExecutableMacosArm64
|
||||
./gradlew :apidemo:runDebugExecutableLinuxX64
|
||||
gradlew.bat :apidemo:runDebugExecutableMingwX64
|
||||
./gradlew :apidemo:run # stock JVM Compose Desktop (parity reference)
|
||||
```
|
||||
|
||||
Like the demo, the whole UI lives in `commonMain` and also runs on upstream
|
||||
Compose Desktop (JVM); only the mTLS / TLS-chain features are native-only —
|
||||
they drive the bundled libcurl directly.
|
||||
|
||||
Add `-Prenderer=sdl3` on macOS/Linux to drop Skiko and use the pure-SDL3
|
||||
renderer everywhere.
|
||||
|
||||
@@ -131,15 +146,60 @@ implementation(project(":material3")) // Material 3 widgets
|
||||
implementation(project(":material-symbols")) // icon-font composables (optional)
|
||||
```
|
||||
|
||||
## Using it from your own build — the bridge plugin
|
||||
|
||||
The klibs publish to GitHub Packages under `com.bitsycore.compose.sdl:*`, and
|
||||
a companion Gradle plugin ships the "redirect trick" this repo uses
|
||||
internally: apply **`com.bitsycore.compose-desktop-native.bridge`** once in
|
||||
`settings.gradle.kts` and declare the **official Compose Multiplatform
|
||||
coordinates** in `commonMain` — the plugin substitutes the port's klibs on
|
||||
every native desktop configuration (mingwX64 / linuxX64 / linuxArm64 /
|
||||
macosArm64), while android / jvm / iOS / wasm keep resolving the official
|
||||
artifacts. One dependency list, all CMP platforms + the port's new ones.
|
||||
|
||||
```kotlin
|
||||
// settings.gradle.kts
|
||||
plugins { id("com.bitsycore.compose-desktop-native.bridge") version "<release>" }
|
||||
|
||||
// build.gradle.kts — official coords, everywhere
|
||||
commonMain.dependencies {
|
||||
implementation("org.jetbrains.compose.runtime:runtime:<runtime-version>")
|
||||
implementation("org.jetbrains.compose.ui:ui:<cmp-version>")
|
||||
implementation("org.jetbrains.compose.foundation:foundation:<cmp-version>")
|
||||
implementation("org.jetbrains.compose.material3:material3:<cmp-m3-version>")
|
||||
}
|
||||
```
|
||||
|
||||
Setup details (repositories, credentials, version pinning):
|
||||
[gradle-plugin/compose-desktop-native-bridge/README.md](gradle-plugin/compose-desktop-native-bridge/README.md).
|
||||
|
||||
## Building
|
||||
|
||||
- **macOS:** `brew install sdl3` (Skia is the default; Skiko klibs come from
|
||||
Maven).
|
||||
- **Linux:** `sudo apt install libsdl3-dev`.
|
||||
- **Windows:** SDL3, SDL3_ttf, SDL3_image and FreeType are built from source
|
||||
as **static** libraries by `scripts/build-sdl/build-all.sh` into the gitignored
|
||||
in-repo `libs/`, then linked into the executable — the Windows
|
||||
distributable is just `<app>.exe` + `data.kres`, no runtime DLLs.
|
||||
All four native dependencies — **SDL3**, **SDL3_ttf** (the in-house
|
||||
variable-font-axes fork), **SDL3_image** (+ vendored PNG/WEBP codecs) and
|
||||
**FreeType** — are built from source as **static** libraries by one script,
|
||||
on every OS, and linked straight into the executable. No `brew install`, no
|
||||
`apt install libsdl3-dev`, no runtime `.dll` / `.so` / `.dylib` next to the
|
||||
binary — a distributable is just `<app>` + `data.kres`.
|
||||
|
||||
```bash
|
||||
python3 scripts/build-sdl/build-all.py # freetype → sdl3 → sdl3-image → sdl3-ttf
|
||||
python3 scripts/build-sdl/build-all.py sdl3-ttf # rebuild a subset
|
||||
```
|
||||
|
||||
Library versions / URLs are pinned in `scripts/build-sdl/build-sdl.properties`;
|
||||
output lands in the gitignored in-repo `libs/`. Required on every host: `git`,
|
||||
`cmake`, Python 3 (`ninja` is fetched automatically when absent). Per host:
|
||||
|
||||
- **macOS** — Xcode command line tools. Skia is the default renderer; Skiko
|
||||
klibs come from Maven.
|
||||
- **Linux** — gcc/g++ plus the X11 / Wayland / audio dev headers SDL3's
|
||||
configure detects (the exact apt list is in
|
||||
`.github/workflows/publish.yml`).
|
||||
- **Windows** — a mingw-w64 g++ on PATH (the C side compiles with
|
||||
Kotlin/Native's bundled mingw).
|
||||
|
||||
Then build any app target — see the demo / apidemo commands above.
|
||||
|
||||
## Vendoring
|
||||
|
||||
@@ -158,6 +218,15 @@ Upstream ref pinned in `scripts/compose-fork/compose.properties`; manifests can
|
||||
pin additional upstream repos inline (`SET_REPO=<url>@<ref>` — the resources
|
||||
runtime vendors from the compose-multiplatform umbrella repo this way).
|
||||
|
||||
How much of upstream's public API the port actually covers is measured, not
|
||||
guessed — `scripts/compose-coverage.py` diffs this repo's klib ABI dumps
|
||||
against upstream's, per vendored module:
|
||||
|
||||
```bash
|
||||
./gradlew apiDump && python3 scripts/compose-coverage.py # per-module coverage tables
|
||||
python3 scripts/compose-coverage.py --missing ui-text # list the exact uncovered decls
|
||||
```
|
||||
|
||||
See [CLAUDE.md](CLAUDE.md) for the full architecture, source-set hierarchy,
|
||||
vendoring rules, density flow (physical-pixel Option B), and per-area file
|
||||
map.
|
||||
|
||||
+101
-13
@@ -16,12 +16,38 @@ plugins {
|
||||
// Skip mingwX64 on non-Windows hosts; see root build.gradle.kts.
|
||||
val vHostSupportsMingw: Boolean by rootProject.extra
|
||||
|
||||
// JVM parity target's Compose version — the dev build matching the pinned
|
||||
// COMPOSE_CORE_REF (see scripts/compose-fork/compose.properties); mirrors
|
||||
// :demo's forcing (Gradle orders "+dev" BELOW the plain version, so the
|
||||
// plugin's beta01 would win conflict resolution without it).
|
||||
val vComposeJvmVersion = "1.12.0-beta01+dev4324"
|
||||
val vComposeM3JvmVersion = "1.12.0-alpha03+dev4324"
|
||||
val vComposeJvmForced = mapOf(
|
||||
"org.jetbrains.compose.runtime" to vComposeJvmVersion,
|
||||
"org.jetbrains.compose.ui" to vComposeJvmVersion,
|
||||
"org.jetbrains.compose.foundation" to vComposeJvmVersion,
|
||||
"org.jetbrains.compose.animation" to vComposeJvmVersion,
|
||||
"org.jetbrains.compose.material" to vComposeJvmVersion,
|
||||
"org.jetbrains.compose.material3" to vComposeM3JvmVersion,
|
||||
)
|
||||
configurations.configureEach {
|
||||
if (name.startsWith("jvm")) {
|
||||
resolutionStrategy.eachDependency {
|
||||
vComposeJvmForced[requested.group]?.let { useVersion(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
|
||||
linuxArm64()
|
||||
linuxX64()
|
||||
macosArm64()
|
||||
if (vHostSupportsMingw) mingwX64()
|
||||
|
||||
applyDefaultHierarchyTemplate()
|
||||
|
||||
targets.withType<KotlinNativeTarget>().all {
|
||||
val isMingw = name == "mingwX64"
|
||||
val isLinux = name.startsWith("linux")
|
||||
@@ -68,9 +94,31 @@ kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation(project(":window"))
|
||||
implementation(project(":material3"))
|
||||
// Common API on both stacks — usable from shared code.
|
||||
implementation(project(":material-symbols"))
|
||||
|
||||
// Official Maven coords for everything the shared UI touches,
|
||||
// so commonMain metadata (and the IDE's common analysis)
|
||||
// resolve. Metadata + jvm resolve them from Maven; the NATIVE
|
||||
// configurations substitute each for its port module (root
|
||||
// build's FULL-COMMONIZATION BRIDGE). Every artifact must be
|
||||
// declared DIRECTLY: transitives of a substituted module are
|
||||
// invisible to the granular-metadata visibility check. The
|
||||
// runtime is the official klib everywhere, never substituted
|
||||
// (jvm configs force the +dev build above).
|
||||
implementation("org.jetbrains.compose.runtime:runtime:1.11.1")
|
||||
implementation("org.jetbrains.compose.ui:ui:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.ui:ui-graphics:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.ui:ui-text:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.ui:ui-unit:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.ui:ui-geometry:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.ui:ui-util:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.foundation:foundation:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.foundation:foundation-layout:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.animation:animation:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.animation:animation-core:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.material3:material3:$vComposeM3JvmVersion")
|
||||
|
||||
implementation(libs.ktor.client.core)
|
||||
implementation(libs.ktor.client.content.negotiation)
|
||||
implementation(libs.ktor.serialization.kotlinx.json)
|
||||
@@ -80,17 +128,32 @@ kotlin {
|
||||
implementation(libs.kotlinx.datetime)
|
||||
}
|
||||
}
|
||||
// Single HTTP engine on every desktop target: Ktor's Curl engine. It
|
||||
// bundles a static libcurl per target (Schannel on Windows, OpenSSL on
|
||||
// macOS/Linux) embedded in its cinterop klib — no runtime DLL, one copy.
|
||||
// We use Curl everywhere (not WinHttp/Darwin) so that an upcoming
|
||||
// client-certificate (mTLS) path — which calls the same bundled libcurl
|
||||
// directly, since Ktor's engines expose no client-cert API — shares the
|
||||
// exact same TLS stack as ordinary requests.
|
||||
if (vHostSupportsMingw) getByName("mingwX64Main").dependencies { implementation(libs.ktor.client.curl) }
|
||||
getByName("macosArm64Main").dependencies { implementation(libs.ktor.client.curl) }
|
||||
getByName("linuxX64Main").dependencies { implementation(libs.ktor.client.curl) }
|
||||
getByName("linuxArm64Main").dependencies { implementation(libs.ktor.client.curl) }
|
||||
nativeMain {
|
||||
dependencies {
|
||||
// The SDL window shell + main loop (native-only).
|
||||
implementation(project(":window"))
|
||||
// Single HTTP engine on every native target: Ktor's Curl
|
||||
// engine. It bundles a static libcurl per target (Schannel on
|
||||
// Windows, OpenSSL on macOS/Linux) embedded in its cinterop
|
||||
// klib — no runtime DLL, one copy. Curl everywhere (not
|
||||
// WinHttp/Darwin) so the client-certificate (mTLS) path —
|
||||
// which calls the same bundled libcurl directly, since Ktor's
|
||||
// engines expose no client-cert API — shares the exact same
|
||||
// TLS stack as ordinary requests.
|
||||
implementation(libs.ktor.client.curl)
|
||||
}
|
||||
}
|
||||
jvmMain {
|
||||
dependencies {
|
||||
// Upstream Compose Desktop — the parity stack.
|
||||
implementation(compose.desktop.currentOs)
|
||||
// Coroutine-based engine on JVM; native targets keep Curl.
|
||||
implementation(libs.ktor.client.cio)
|
||||
// Dispatchers.Main provider on desktop JVM (must match
|
||||
// kotlinx-coroutines-core's version — the catalog pins both).
|
||||
implementation(libs.kotlinx.coroutines.swing)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compilerOptions {
|
||||
@@ -99,6 +162,12 @@ kotlin {
|
||||
}
|
||||
}
|
||||
|
||||
compose.desktop {
|
||||
application {
|
||||
mainClass = "apidemo.MainJvmKt"
|
||||
}
|
||||
}
|
||||
|
||||
// SDL3 / SDL3_ttf / SDL3_image / FreeType are linked statically into the
|
||||
// executable (see the mingw linkerOpts above), so there are no runtime DLLs to
|
||||
// bundle — the distributable is just <app>.exe + data.kres.
|
||||
@@ -277,3 +346,22 @@ for (variant in variants) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================
|
||||
// MARK: Stage fonts onto the JVM classpath
|
||||
// ==================
|
||||
// The JVM analog of the data.kres font/ entries: :material-symbols' JVM actual
|
||||
// loads each style's font from the classpath at font/<Style>.ttf, and the
|
||||
// jvm Fonts actual loads the mono body font at font/NotoSansMono.ttf.
|
||||
tasks.named<ProcessResources>("jvmProcessResources") {
|
||||
from(notoMonoFile) { into("font") }
|
||||
dependsOn(":ui:downloadNotoFonts")
|
||||
val vSymbolsProject = rootProject.project(":material-symbols")
|
||||
for (vStyle in vUsedStyles) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val vFontFile = vSymbolsProject.extra["iconFontFile$vStyle"] as org.gradle.api.provider.Provider<org.gradle.api.file.RegularFile>
|
||||
val vDownloadTask = vSymbolsProject.extra["iconFontDownloadTask$vStyle"] as TaskProvider<*>
|
||||
from(vFontFile) { into("font") }
|
||||
dependsOn(vDownloadTask)
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
package apidemo
|
||||
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
|
||||
// ==================
|
||||
// MARK: Monospace body font (seam)
|
||||
// ==================
|
||||
// Family name the body editor passes for monospace text. Resolves to the
|
||||
// bundled Noto Sans Mono once registered; null means the font isn't shipped
|
||||
// (data.kres on native, classpath font/ on jvm), in which case the body falls
|
||||
// back to the default proportional font.
|
||||
const val kMonoFamily = "noto-mono"
|
||||
|
||||
/* The raw family name string — used by wrappedRowCount, which measures via the
|
||||
platform text pipeline (accepts a name string). Null when not bundled. */
|
||||
expect val monoFontFamilyName: String?
|
||||
|
||||
/* The material3 Text / BasicTextField-shaped FontFamily for the mono family.
|
||||
Null when not bundled. */
|
||||
expect val monoFontFamily: FontFamily?
|
||||
@@ -1,7 +1,6 @@
|
||||
package apidemo
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.curl.Curl
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.*
|
||||
import io.ktor.http.*
|
||||
@@ -23,7 +22,7 @@ import kotlin.time.TimeSource
|
||||
run() is a suspend fun — call it off the UI dispatcher. */
|
||||
class HttpRunner {
|
||||
|
||||
private val fClient = HttpClient(Curl)
|
||||
private val fClient = createApiHttpClient()
|
||||
|
||||
init {
|
||||
// Clear any temporary client certs a prior crash left in the Windows
|
||||
@@ -140,7 +139,7 @@ private fun isGzip(inEncoding: String?, inBytes: ByteArray): Boolean =
|
||||
|
||||
/* Read a file's raw bytes (used for a FILE request body). */
|
||||
internal fun readFileBytes(inPath: String): ByteArray =
|
||||
FileSystem.SYSTEM.read(inPath.trim().toPath()) { readByteArray() }
|
||||
systemFileSystem.read(inPath.trim().toPath()) { readByteArray() }
|
||||
|
||||
/* Inflate a gzip stream to its original bytes via okio's GzipSource. */
|
||||
private fun gunzip(inBytes: ByteArray): ByteArray {
|
||||
@@ -19,7 +19,7 @@ private val fJson = Json {
|
||||
/* Write the pack as pretty JSON to inPath. Returns null on success, else the
|
||||
error message. */
|
||||
fun exportPack(inPack: Pack, inPath: String): String? = try {
|
||||
FileSystem.SYSTEM.write(inPath.trim().toPath()) {
|
||||
systemFileSystem.write(inPath.trim().toPath()) {
|
||||
writeUtf8(fJson.encodeToString(inPack))
|
||||
}
|
||||
null
|
||||
@@ -29,7 +29,7 @@ fun exportPack(inPack: Pack, inPath: String): String? = try {
|
||||
|
||||
/* Read a pack back from inPath. */
|
||||
fun importPack(inPath: String): Result<Pack> = try {
|
||||
val vText = FileSystem.SYSTEM.read(inPath.trim().toPath()) { readUtf8() }
|
||||
val vText = systemFileSystem.read(inPath.trim().toPath()) { readUtf8() }
|
||||
Result.success(fJson.decodeFromString<Pack>(vText))
|
||||
} catch (e: Throwable) {
|
||||
Result.failure(e)
|
||||
@@ -37,7 +37,7 @@ fun importPack(inPath: String): Result<Pack> = try {
|
||||
|
||||
/* Write a whole self-contained session to inPath. Returns null on success. */
|
||||
fun exportSession(inSession: Session, inPath: String): String? = try {
|
||||
FileSystem.SYSTEM.write(inPath.trim().toPath()) {
|
||||
systemFileSystem.write(inPath.trim().toPath()) {
|
||||
writeUtf8(fJson.encodeToString(inSession))
|
||||
}
|
||||
null
|
||||
@@ -47,7 +47,7 @@ fun exportSession(inSession: Session, inPath: String): String? = try {
|
||||
|
||||
/* Read a session back from inPath. */
|
||||
fun importSession(inPath: String): Result<Session> = try {
|
||||
val vText = FileSystem.SYSTEM.read(inPath.trim().toPath()) { readUtf8() }
|
||||
val vText = systemFileSystem.read(inPath.trim().toPath()) { readUtf8() }
|
||||
Result.success(fJson.decodeFromString<Session>(vText))
|
||||
} catch (e: Throwable) {
|
||||
Result.failure(e)
|
||||
@@ -59,7 +59,7 @@ fun renameFile(inPath: String, inNewName: String): Result<String> = try {
|
||||
val vSrc = inPath.trim().toPath()
|
||||
val vLeaf = inNewName.trim().let { if (it.contains('.')) it else "$it.json" }
|
||||
val vDst = vSrc.parent?.div(vLeaf) ?: vLeaf.toPath()
|
||||
FileSystem.SYSTEM.atomicMove(vSrc, vDst)
|
||||
systemFileSystem.atomicMove(vSrc, vDst)
|
||||
Result.success(vDst.toString())
|
||||
} catch (e: Throwable) {
|
||||
Result.failure(e)
|
||||
@@ -68,7 +68,7 @@ fun renameFile(inPath: String, inNewName: String): Result<String> = try {
|
||||
/* Write arbitrary text (a response body / headers dump) to inPath. Returns null
|
||||
on success, else the error message. */
|
||||
fun writeTextFile(inPath: String, inText: String): String? = try {
|
||||
FileSystem.SYSTEM.write(inPath.trim().toPath()) { writeUtf8(inText) }
|
||||
systemFileSystem.write(inPath.trim().toPath()) { writeUtf8(inText) }
|
||||
null
|
||||
} catch (e: Throwable) {
|
||||
e.message ?: e.toString()
|
||||
@@ -76,7 +76,7 @@ fun writeTextFile(inPath: String, inText: String): String? = try {
|
||||
|
||||
/* Write raw bytes (a binary response body, e.g. an image) to inPath. */
|
||||
fun writeBytesFile(inPath: String, inBytes: ByteArray): String? = try {
|
||||
FileSystem.SYSTEM.write(inPath.trim().toPath()) { write(inBytes) }
|
||||
systemFileSystem.write(inPath.trim().toPath()) { write(inBytes) }
|
||||
null
|
||||
} catch (e: Throwable) {
|
||||
e.message ?: e.toString()
|
||||
+2
-4
@@ -1,7 +1,5 @@
|
||||
package apidemo
|
||||
|
||||
import com.compose.sdl.appDataDir
|
||||
import com.compose.sdl.revealInFileManager
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import okio.FileSystem
|
||||
@@ -86,7 +84,7 @@ private fun stateFilePath(): String? {
|
||||
fun loadAppState(): AppState {
|
||||
val vPath = stateFilePath() ?: return AppState()
|
||||
return try {
|
||||
val vText = FileSystem.SYSTEM.read(vPath.toPath()) { readUtf8() }
|
||||
val vText = systemFileSystem.read(vPath.toPath()) { readUtf8() }
|
||||
fStateJson.decodeFromString<AppState>(vText)
|
||||
} catch (e: Throwable) {
|
||||
AppState()
|
||||
@@ -98,7 +96,7 @@ fun loadAppState(): AppState {
|
||||
fun saveAppState(inState: AppState) {
|
||||
val vPath = stateFilePath() ?: return
|
||||
try {
|
||||
FileSystem.SYSTEM.write(vPath.toPath()) { writeUtf8(fStateJson.encodeToString(inState)) }
|
||||
systemFileSystem.write(vPath.toPath()) { writeUtf8(fStateJson.encodeToString(inState)) }
|
||||
} catch (e: Throwable) {
|
||||
// ignore — nothing the user can act on, and packs can still be exported
|
||||
}
|
||||
+2
-4
@@ -17,10 +17,8 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.compose.sdl.TextLayoutConfig
|
||||
import com.compose.sdl.icons.MaterialSymbols
|
||||
import com.compose.sdl.icons.material.symbols.MaterialSymbolsOutlined
|
||||
import com.compose.sdl.showOpenFileDialog
|
||||
|
||||
// ==================
|
||||
// MARK: Panel 3 — request builder (Query / Headers / Body)
|
||||
@@ -219,7 +217,7 @@ internal fun TabSizeSelector() {
|
||||
var vOpen by remember { mutableStateOf(false) }
|
||||
val vHoverSrc = remember { MutableInteractionSource() }
|
||||
val vHover by vHoverSrc.collectIsHoveredAsState()
|
||||
val vSize = TextLayoutConfig.tabWidth
|
||||
val vSize = editorTabWidth
|
||||
TooltipBox(
|
||||
positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
|
||||
tooltip = { PlainTooltip { Text("Editor tab size") } },
|
||||
@@ -243,7 +241,7 @@ internal fun TabSizeSelector() {
|
||||
for (vN in listOf(2, 4, 8)) {
|
||||
DropdownMenuItem(text = {
|
||||
Text("$vN spaces", color = if (vN == vSize) c.accent else c.text)
|
||||
}, onClick = { TextLayoutConfig.tabWidth = vN; vOpen = false })
|
||||
}, onClick = { editorTabWidth = vN; vOpen = false })
|
||||
}
|
||||
}
|
||||
}
|
||||
-1
@@ -25,7 +25,6 @@ import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.zIndex
|
||||
import com.compose.sdl.icons.MaterialSymbols
|
||||
import com.compose.sdl.icons.material.symbols.MaterialSymbolsOutlined
|
||||
import com.compose.sdl.layout.x
|
||||
|
||||
// ==================
|
||||
// MARK: Request tab strip (open requests; drag a tab to reorder)
|
||||
@@ -31,11 +31,8 @@ import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.zIndex
|
||||
import com.compose.sdl.fileManagerName
|
||||
import com.compose.sdl.icons.MaterialSymbols
|
||||
import com.compose.sdl.icons.material.symbols.MaterialSymbolsOutlined
|
||||
import com.compose.sdl.layout.y
|
||||
import com.compose.sdl.revealInFileManager
|
||||
|
||||
// ==================
|
||||
// MARK: Pack colour (palette dot + picker)
|
||||
+1
-3
@@ -23,8 +23,6 @@ import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.Popup
|
||||
import com.compose.sdl.icons.MaterialSymbols
|
||||
import com.compose.sdl.icons.material.symbols.MaterialSymbolsOutlined
|
||||
import com.compose.sdl.layout.x
|
||||
import com.compose.sdl.layout.y
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -141,7 +139,7 @@ internal fun CopyButton(inText: String, inLabel: String? = null) {
|
||||
.background(if (vHover) c.accent.copy(alpha = 0.18f) else Color.Transparent, RoundedCornerShape(7.dp))
|
||||
.hoverable(vHoverSrc)
|
||||
.clickable {
|
||||
vScope.launch { vClipboard.setClipEntry(ClipEntry.withPlainText(inText)) }
|
||||
vScope.launch { vClipboard.setClipEntry(clipEntryOfText(inText)) }
|
||||
vCopied = true
|
||||
}
|
||||
.padding(horizontal = if (inLabel != null) 10.dp else 5.dp, vertical = 5.dp),
|
||||
@@ -0,0 +1,29 @@
|
||||
package apidemo
|
||||
|
||||
// ==================
|
||||
// MARK: TLS chain / client-certificate seam
|
||||
// ==================
|
||||
// The real implementations drive the bundled libcurl directly (CurlMtls.kt,
|
||||
// nativeMain) — Ktor's engines expose no client-cert / CERTINFO API. The jvm
|
||||
// parity app has no bundled libcurl, so its actuals report the feature as
|
||||
// native-only instead.
|
||||
|
||||
/* One certificate in the chain: its CURLINFO_CERTINFO-style fields (Subject /
|
||||
Issuer / the PEM under "Cert" / dates …) and whether the server actually
|
||||
presented it. Derived certs — an issuer resolved from the OS store, or a
|
||||
name-only placeholder — have fromServer = false and are drawn dotted. */
|
||||
class ChainCert(val fields: List<Pair<String, String>>, val fromServer: Boolean)
|
||||
|
||||
/* The server's TLS certificate chain. error is set instead when it couldn't be
|
||||
fetched; fields vary by TLS backend. */
|
||||
class TlsChain(val certs: List<ChainCert>, val error: String?)
|
||||
|
||||
/* Fetch the TLS certificate chain the request's server presents. */
|
||||
expect fun inspectTlsChain(inReq: ApiRequest): TlsChain
|
||||
|
||||
/* Send the request with its client certificate attached (mTLS). */
|
||||
expect fun curlSendWithClientCert(inReq: ApiRequest): ApiResponse
|
||||
|
||||
/* Remove temp client certs a previous crashed run left behind. Call once at
|
||||
startup; no-op where the OS store isn't used. */
|
||||
expect fun sweepTempClientCerts()
|
||||
+10
-18
@@ -39,14 +39,6 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.compose.sdl.icons.MaterialSymbols
|
||||
import com.compose.sdl.icons.material.symbols.MaterialSymbolsOutlined
|
||||
import com.compose.sdl.removeMemoryResource
|
||||
import com.compose.sdl.res.ResourceKind
|
||||
import com.compose.sdl.res.painterResource
|
||||
import com.compose.sdl.scrollbar.ScrollbarStyle
|
||||
import com.compose.sdl.scrollbar.VerticalScrollbar
|
||||
import com.compose.sdl.scrollbar.rememberScrollbarAdapter
|
||||
import com.compose.sdl.showSaveFileDialog
|
||||
import com.compose.sdl.text.currentTextMeasurer
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
// ==================
|
||||
@@ -169,8 +161,8 @@ internal fun ViewerPanel(inRs: ReqState, inResolved: ApiRequest) {
|
||||
inBody = if (vRespImage) null else vBody,
|
||||
inIsImage = vRespImage && !vLoading,
|
||||
inImagePainter = if (vRespImage && !vLoading) {
|
||||
val vKind = if (vResp?.contentType?.contains("svg", ignoreCase = true) == true) ResourceKind.Svg else ResourceKind.Raster
|
||||
painterResource(inRs.imageKey!!, vKind)
|
||||
val vSvg = vResp?.contentType?.contains("svg", ignoreCase = true) == true
|
||||
memoryImagePainter(inRs.imageKey!!, vSvg)
|
||||
} else null,
|
||||
inHeadersCollapsed = vHeadersCollapsed,
|
||||
inOnToggleCollapse = { vHeadersCollapsed = !vHeadersCollapsed },
|
||||
@@ -247,7 +239,7 @@ internal fun ViewerPanel(inRs: ReqState, inResolved: ApiRequest) {
|
||||
inResponseBody = vRespBody,
|
||||
inOnMessage = { vMsg = it },
|
||||
inOnClear = {
|
||||
inRs.imageKey?.let { removeMemoryResource(it) }
|
||||
inRs.imageKey?.let { removeMemoryImage(it) }
|
||||
inRs.imageKey = null
|
||||
inRs.response = null
|
||||
inRs.sentReq = null
|
||||
@@ -508,7 +500,7 @@ internal fun HttpFlowView(
|
||||
val vS = vSel
|
||||
if (vS != null && !vS.isEmpty) {
|
||||
val vText = vBody.substring(vS.start, vS.end)
|
||||
vScope.launch { vClipboard.setClipEntry(ClipEntry.withPlainText(vText)) }
|
||||
vScope.launch { vClipboard.setClipEntry(clipEntryOfText(vText)) }
|
||||
true
|
||||
} else false
|
||||
}
|
||||
@@ -974,18 +966,18 @@ internal fun BodyView(
|
||||
// also use it for the first frame, before the body reports its width).
|
||||
val vNumColor = c.dim.copy(alpha = 0.45f)
|
||||
val vNumbers = remember(inText, vBodyWidthPx, inSoftWrap, vFontPx) {
|
||||
val vM = if (inSoftWrap && vBodyWidthPx > 0) currentTextMeasurer else null
|
||||
val vWrapRows = inSoftWrap && vBodyWidthPx > 0
|
||||
buildString {
|
||||
for ((vIdx, vSrc) in vLines.withIndex()) {
|
||||
if (vIdx > 0) append('\n')
|
||||
append(vIdx + 1)
|
||||
if (vM != null) {
|
||||
if (vWrapRows) {
|
||||
// Pass the density-scaled font size so this wrap matches the body's
|
||||
// actual glyph pixel widths — passing 12 (sp) here counted each
|
||||
// char as half its rendered size, so long lines that visually
|
||||
// wrapped into 3 rows in the body were estimated as 1 or 2 rows
|
||||
// here and the gutter numbers drifted upward.
|
||||
val vRows = vM.wrap(vSrc, vFontPx, vBodyWidthPx, monoFontFamilyName).lines.size.coerceAtLeast(1)
|
||||
val vRows = wrappedRowCount(vSrc, vFontPx, vBodyWidthPx, monoFontFamilyName).coerceAtLeast(1)
|
||||
repeat(vRows - 1) { append('\n') }
|
||||
}
|
||||
}
|
||||
@@ -1309,18 +1301,18 @@ internal fun ViewerOverflowMenu(
|
||||
}
|
||||
DropdownMenu(expanded = vOpen, onDismissRequest = { vOpen = false }) {
|
||||
DropdownMenuItem(text = { Text("Copy all") }, onClick = {
|
||||
vScope.launch { vClipboard.setClipEntry(ClipEntry.withPlainText(copyAll())) }
|
||||
vScope.launch { vClipboard.setClipEntry(clipEntryOfText(copyAll())) }
|
||||
inOnMessage("Copied all.")
|
||||
vOpen = false
|
||||
})
|
||||
DropdownMenuItem(text = { Text("Copy headers") }, onClick = {
|
||||
vScope.launch { vClipboard.setClipEntry(ClipEntry.withPlainText(vHeadersText)) }
|
||||
vScope.launch { vClipboard.setClipEntry(clipEntryOfText(vHeadersText)) }
|
||||
inOnMessage("Copied headers.")
|
||||
vOpen = false
|
||||
})
|
||||
if (vCanCopyBody) {
|
||||
DropdownMenuItem(text = { Text("Copy body") }, onClick = {
|
||||
vScope.launch { vClipboard.setClipEntry(ClipEntry.withPlainText(vBodyText)) }
|
||||
vScope.launch { vClipboard.setClipEntry(clipEntryOfText(vBodyText)) }
|
||||
inOnMessage("Copied body.")
|
||||
vOpen = false
|
||||
})
|
||||
@@ -0,0 +1,77 @@
|
||||
package apidemo
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.input.key.KeyEvent
|
||||
import androidx.compose.ui.platform.ClipEntry
|
||||
import io.ktor.client.HttpClient
|
||||
import okio.FileSystem
|
||||
|
||||
// ==================
|
||||
// MARK: Platform seams (native = com.compose.sdl / SDL3, jvm = AWT + upstream desktop)
|
||||
// ==================
|
||||
// The port modules are native-only, so shared code can't call com.compose.sdl
|
||||
// directly — every SDL-backed API the app uses goes through these expects.
|
||||
// Signatures mirror the native originals so the native actuals are pure
|
||||
// delegation (same pattern as :demo's demo.shim package).
|
||||
|
||||
/* Per-user app-data dir (created on demand, ends with a separator) or null. */
|
||||
expect fun appDataDir(inOrg: String, inApp: String): String?
|
||||
|
||||
/* Open the OS file manager showing the given path. Fire-and-forget. */
|
||||
expect fun revealInFileManager(inPath: String, inOnResult: ((Boolean) -> Unit)? = null)
|
||||
|
||||
/* "Explorer" / "Finder" / "Files" — for menu labels. */
|
||||
expect fun fileManagerName(): String
|
||||
|
||||
/* Async save-file dialog; the callback gets the chosen absolute path or null. */
|
||||
expect fun showSaveFileDialog(inDefaultName: String? = null, inOnResult: (String?) -> Unit)
|
||||
|
||||
/* Async open-file dialog; the callback gets the chosen absolute path or null. */
|
||||
expect fun showOpenFileDialog(inOnResult: (String?) -> Unit)
|
||||
|
||||
/* A plain-text clipboard entry (ClipEntry construction differs per stack). */
|
||||
expect fun clipEntryOfText(inText: String): ClipEntry
|
||||
|
||||
// ============
|
||||
// In-memory response images
|
||||
|
||||
/* Register/replace decoded-image source bytes under a key (resp-image://N). */
|
||||
expect fun registerMemoryImage(inKey: String, inBytes: ByteArray)
|
||||
|
||||
/* Drop a registered image's bytes. */
|
||||
expect fun removeMemoryImage(inKey: String)
|
||||
|
||||
/* Painter for a registered image key (raster or SVG). */
|
||||
@Composable
|
||||
expect fun memoryImagePainter(inKey: String, inSvg: Boolean): Painter
|
||||
|
||||
// ============
|
||||
// Text layout
|
||||
|
||||
/* Rows the given line occupies when soft-wrapped to inMaxWidthPx at
|
||||
inFontPx (already density-scaled). Used by the body gutter so its line
|
||||
numbers stay aligned with the wrapped body text. */
|
||||
expect fun wrappedRowCount(inText: String, inFontPx: Int, inMaxWidthPx: Int, inFamilyName: String?): Int
|
||||
|
||||
/* Editor tab width in spaces — how wide a typed '\t' renders. On the native
|
||||
stack this drives the project text pipeline (TextLayoutConfig); the jvm
|
||||
parity app only stores the preference. */
|
||||
expect var editorTabWidth: Int
|
||||
|
||||
// ============
|
||||
// Infrastructure
|
||||
|
||||
/* okio's FileSystem.SYSTEM is declared per-platform, not in its common
|
||||
metadata — surface it through a seam. */
|
||||
internal expect val systemFileSystem: FileSystem
|
||||
|
||||
/* The app's Ktor client: Curl on native (bundled libcurl — same TLS stack as
|
||||
the mTLS path), CIO on the jvm parity target. */
|
||||
expect fun createApiHttpClient(): HttpClient
|
||||
|
||||
/* Window-shell integration: an intercepting close handler (return true to
|
||||
allow the close) and an app-wide key-shortcut handler; both cleared when
|
||||
the composition leaves. */
|
||||
@Composable
|
||||
expect fun InstallWindowHooks(inOnCloseRequest: () -> Boolean, inOnKeyShortcut: (KeyEvent) -> Boolean)
|
||||
@@ -0,0 +1,16 @@
|
||||
package apidemo
|
||||
|
||||
import androidx.compose.ui.layout.LayoutCoordinates
|
||||
import androidx.compose.ui.layout.positionInWindow
|
||||
|
||||
// COPY of the port's com.compose.sdl.layout LayoutCoordinates sugar so the
|
||||
// same helpers resolve on the jvm parity target (the port modules are
|
||||
// native-only). Guards `isAttached`: a menu/tooltip anchor can be read while
|
||||
// its node is mid-recycle, and positionInWindow() throws on a detached
|
||||
// coordinator.
|
||||
|
||||
/* Logical-point X of this layout in the window. */
|
||||
val LayoutCoordinates.x: Int get() = if (isAttached) positionInWindow().x.toInt() else 0
|
||||
|
||||
/* Logical-point Y of this layout in the window. */
|
||||
val LayoutCoordinates.y: Int get() = if (isAttached) positionInWindow().y.toInt() else 0
|
||||
@@ -0,0 +1,333 @@
|
||||
// COPY of the port's Scrollbar (package com.compose.sdl.scrollbar) so the SAME
|
||||
// implementation runs on the jvm parity target — the port modules are
|
||||
// native-only, so apidemo's commonMain cannot reference them directly.
|
||||
// Keep in sync with the original when it changes.
|
||||
package apidemo
|
||||
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.hoverable
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsHoveredAsState
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.layout.onSizeChanged
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.foundation.gestures.awaitEachGesture
|
||||
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||
import androidx.compose.foundation.gestures.scrollBy
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
// ==================
|
||||
// MARK: Scrollbar (Compose Desktop-style)
|
||||
// ==================
|
||||
|
||||
/* A faithful subset of Compose Desktop's scrollbar (androidx.compose.foundation).
|
||||
You overlay a VerticalScrollbar / HorizontalScrollbar on a scrollable and feed
|
||||
it a ScrollbarAdapter built from the same ScrollState. This project's Box has
|
||||
no BoxScope (so no Modifier.align) — pin the bar with the Box's
|
||||
contentAlignment; the fillMaxSize content fills the rest:
|
||||
|
||||
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.CenterEnd) {
|
||||
val state = rememberScrollState()
|
||||
Column(Modifier.fillMaxSize().verticalScroll(state)) { ... }
|
||||
VerticalScrollbar(
|
||||
adapter = rememberScrollbarAdapter(state),
|
||||
modifier = Modifier.fillMaxHeight(),
|
||||
)
|
||||
}
|
||||
|
||||
Always visible (no auto-hide); the thumb tweens unhoverColor -> hoverColor on
|
||||
hover over hoverDurationMillis, matching upstream. Drag the thumb to scroll;
|
||||
click the track to page. */
|
||||
|
||||
@Immutable
|
||||
class ScrollbarStyle(
|
||||
val minimalHeight: Dp,
|
||||
val thickness: Dp,
|
||||
val shape: Shape,
|
||||
val hoverDurationMillis: Int,
|
||||
val unhoverColor: Color,
|
||||
val hoverColor: Color,
|
||||
)
|
||||
|
||||
/* Upstream default: an 8dp black thumb that's faint until hovered. Dark UIs
|
||||
provide a white-tinted style via LocalScrollbarStyle or the `style` param. */
|
||||
fun defaultScrollbarStyle(): ScrollbarStyle = ScrollbarStyle(
|
||||
minimalHeight = 16.dp,
|
||||
thickness = 8.dp,
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
hoverDurationMillis = 300,
|
||||
unhoverColor = Color.Black.copy(alpha = 0.12f),
|
||||
hoverColor = Color.Black.copy(alpha = 0.50f),
|
||||
)
|
||||
|
||||
val LocalScrollbarStyle = compositionLocalOf { defaultScrollbarStyle() }
|
||||
|
||||
// ==================
|
||||
// MARK: ScrollbarAdapter
|
||||
// ==================
|
||||
|
||||
/* Bridges a scrollable's state to the scrollbar in pixels. scrollOffset /
|
||||
contentSize / viewportSize are along the scroll axis; the thumb is sized by
|
||||
viewportSize / contentSize and positioned by scrollOffset / (content - viewport). */
|
||||
interface ScrollbarAdapter {
|
||||
val scrollOffset: Double
|
||||
val contentSize: Double
|
||||
val viewportSize: Double
|
||||
suspend fun scrollTo(scrollOffset: Double)
|
||||
}
|
||||
|
||||
// (The port also ships a ScrollState-based adapter; it reads foundation
|
||||
// internals (ScrollState.contentSize/viewportSize) that a copy outside
|
||||
// :foundation cannot access. apidemo only scrollbars a LazyColumn.)
|
||||
|
||||
/* Adapter for a virtualized LazyColumn / LazyRow. A lazy list only knows the
|
||||
size of its VISIBLE items, so exact pixel geometry of off-screen content is
|
||||
unknowable — we estimate it from the average visible item size × total item
|
||||
count (the same approach as Compose Desktop). Accurate enough for a thumb
|
||||
whose length/position track the scroll position; the estimate self-corrects
|
||||
as items of different sizes scroll through the viewport. */
|
||||
@Composable
|
||||
fun rememberScrollbarAdapter(scrollState: LazyListState): ScrollbarAdapter =
|
||||
remember(scrollState) { LazyListScrollbarAdapter(scrollState) }
|
||||
|
||||
private class LazyListScrollbarAdapter(private val state: LazyListState) : ScrollbarAdapter {
|
||||
// Mean main-axis size of the currently-visible items, in px (>= 1 to avoid /0).
|
||||
private fun averageItemSize(): Double {
|
||||
val vVisible = state.layoutInfo.visibleItemsInfo
|
||||
if (vVisible.isEmpty()) return 0.0
|
||||
val vSpan = (vVisible.last().offset + vVisible.last().size) - vVisible.first().offset
|
||||
return (vSpan.toDouble() / vVisible.size).coerceAtLeast(1.0)
|
||||
}
|
||||
|
||||
override val scrollOffset: Double
|
||||
get() = averageItemSize() * state.firstVisibleItemIndex + state.firstVisibleItemScrollOffset
|
||||
|
||||
override val contentSize: Double
|
||||
get() = averageItemSize() * state.layoutInfo.totalItemsCount
|
||||
|
||||
override val viewportSize: Double
|
||||
get() = (state.layoutInfo.viewportEndOffset - state.layoutInfo.viewportStartOffset).toDouble()
|
||||
|
||||
override suspend fun scrollTo(scrollOffset: Double) {
|
||||
val vDistance = scrollOffset - this.scrollOffset
|
||||
// Within a viewport, scroll by EXACT pixels so a drag stays smooth. A lazy
|
||||
// list's pixel geometry is only ESTIMATED (average visible item size), and
|
||||
// that estimate drifts as differently-sized items scroll through the
|
||||
// viewport — so index-snapping every frame makes the thumb jump. scrollBy
|
||||
// sidesteps the estimate entirely. This is what Compose Desktop's own
|
||||
// LazyListScrollbarAdapter does, and for the same reason.
|
||||
if (abs(vDistance) <= viewportSize) {
|
||||
state.scrollBy(vDistance.toFloat())
|
||||
return
|
||||
}
|
||||
// Far jump (track-click paging past a viewport): no exact geometry to lean
|
||||
// on, so estimate an index/offset from the average and snap to it.
|
||||
val vAvg = averageItemSize()
|
||||
if (vAvg <= 0.0) return
|
||||
val vTarget = scrollOffset.coerceAtLeast(0.0)
|
||||
val vTotal = state.layoutInfo.totalItemsCount
|
||||
val vIndex = (vTarget / vAvg).toInt().coerceIn(0, (vTotal - 1).coerceAtLeast(0))
|
||||
val vItemOffset = (vTarget - vIndex * vAvg).toInt().coerceAtLeast(0)
|
||||
state.scrollToItem(vIndex, vItemOffset)
|
||||
}
|
||||
}
|
||||
|
||||
// ==================
|
||||
// MARK: VerticalScrollbar / HorizontalScrollbar
|
||||
// ==================
|
||||
|
||||
@Composable
|
||||
fun VerticalScrollbar(
|
||||
adapter: ScrollbarAdapter,
|
||||
modifier: Modifier = Modifier,
|
||||
reverseLayout: Boolean = false,
|
||||
style: ScrollbarStyle = LocalScrollbarStyle.current,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
) = Scrollbar(adapter, modifier, reverseLayout, style, interactionSource, isVertical = true)
|
||||
|
||||
@Composable
|
||||
fun HorizontalScrollbar(
|
||||
adapter: ScrollbarAdapter,
|
||||
modifier: Modifier = Modifier,
|
||||
reverseLayout: Boolean = false,
|
||||
style: ScrollbarStyle = LocalScrollbarStyle.current,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
) = Scrollbar(adapter, modifier, reverseLayout, style, interactionSource, isVertical = false)
|
||||
|
||||
/* Shared impl. The root Box is the track (fixed thickness on the cross axis,
|
||||
filling the main axis from the caller's modifier); a child Box is the thumb,
|
||||
positioned with an offset. Drag + track-click are handled on the track in
|
||||
track-relative coordinates (a stable origin), so the grab point stays under
|
||||
the pointer with no feedback from the thumb moving. interactionSource is
|
||||
accepted for API parity; hover here is driven by Modifier.hoverable. */
|
||||
@Composable
|
||||
private fun Scrollbar(
|
||||
adapter: ScrollbarAdapter,
|
||||
modifier: Modifier,
|
||||
reverseLayout: Boolean,
|
||||
style: ScrollbarStyle,
|
||||
@Suppress("UNUSED_PARAMETER") interactionSource: MutableInteractionSource,
|
||||
isVertical: Boolean,
|
||||
) {
|
||||
val vScope = rememberCoroutineScope()
|
||||
var vTrackPx by remember { mutableStateOf(0) }
|
||||
val vHoverSource = remember { MutableInteractionSource() }
|
||||
val vHovered by vHoverSource.collectIsHoveredAsState()
|
||||
var vDraggingThumb by remember { mutableStateOf(false) }
|
||||
// onSizeChanged reports PHYSICAL pixels (Option-B density flow), so every
|
||||
// int/px carried through here — vTrackPx, vThumbLen, vThumbPos — is in
|
||||
// physical pixels. Passing them into `.dp` doubles again through
|
||||
// density.toPx() on Retina, which visibly bloated the thumb (filled the
|
||||
// whole track) and made drag/track-click positions land 2Ă— too far down.
|
||||
// Route pixel-sized modifiers through the current density so `.dp` and the
|
||||
// pixel value stay in the same coord space.
|
||||
val vDensity = LocalDensity.current
|
||||
|
||||
val vContent = adapter.contentSize
|
||||
val vViewport = adapter.viewportSize
|
||||
val vOffset = adapter.scrollOffset
|
||||
val vMaxScroll = vContent - vViewport
|
||||
val vScrollable = vMaxScroll > 0.5 && vViewport > 0.0
|
||||
|
||||
val vColor by animateColorAsState(
|
||||
targetValue = if (vHovered || vDraggingThumb) style.hoverColor else style.unhoverColor,
|
||||
animationSpec = tween(style.hoverDurationMillis),
|
||||
)
|
||||
|
||||
val vRoot = (if (isVertical) modifier.width(style.thickness) else modifier.height(style.thickness))
|
||||
.onSizeChanged { vTrackPx = if (isVertical) it.height else it.width }
|
||||
.hoverable(vHoverSource)
|
||||
|
||||
Box(modifier = vRoot) {
|
||||
if (!vScrollable || vTrackPx <= 0) return@Box
|
||||
|
||||
// ============
|
||||
// Thumb metrics (px)
|
||||
val vMinLen = style.minimalHeight.value.toInt()
|
||||
val vThumbLen = (vTrackPx * (vViewport / vContent)).roundToInt()
|
||||
.coerceIn(vMinLen.coerceAtMost(vTrackPx), vTrackPx)
|
||||
val vTravel = vTrackPx - vThumbLen
|
||||
val vRawPos = if (vTravel <= 0) 0 else (vTravel * (vOffset / vMaxScroll)).roundToInt()
|
||||
val vThumbPos = (if (reverseLayout) vTravel - vRawPos else vRawPos).coerceIn(0, vTravel)
|
||||
|
||||
val vThumbLenDp = with(vDensity) { vThumbLen.toDp() }
|
||||
val vThumbMod = (
|
||||
if (isVertical) Modifier.offset { IntOffset(0, vThumbPos) }.width(style.thickness).height(vThumbLenDp)
|
||||
else Modifier.offset { IntOffset(vThumbPos, 0) }.height(style.thickness).width(vThumbLenDp)
|
||||
)
|
||||
.clip(style.shape)
|
||||
.background(vColor)
|
||||
|
||||
Box(modifier = vThumbMod)
|
||||
|
||||
// ============
|
||||
// Drag the thumb / page on track click — handled on the track so the
|
||||
// coordinates have a stable (non-moving) origin. The press is CONSUMED:
|
||||
// a scrollbar owns the pointer input it handles, so content sharing this
|
||||
// region (the scrollable beneath, or a parent that also reads pointer
|
||||
// input) never reacts to the same press. Geometry is read LIVE from the
|
||||
// adapter at press time — not from the captured render metrics above,
|
||||
// which go stale between pointerInput relaunches — so a grab after a
|
||||
// wheel-scroll still hit-tests against the thumb's current position.
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.matchTrackSize(isVertical, with(vDensity) { vTrackPx.toDp() }, style.thickness)
|
||||
.pointerInput(isVertical, adapter, vTrackPx, reverseLayout) {
|
||||
awaitEachGesture {
|
||||
val vDown = awaitFirstDown(requireUnconsumed = false)
|
||||
vDown.consume()
|
||||
|
||||
// Live geometry — stable for the drag's duration (content /
|
||||
// viewport / track sizes don't change mid-drag).
|
||||
val vContentPx = adapter.contentSize
|
||||
val vViewportPx = adapter.viewportSize
|
||||
val vMaxScrollPx = vContentPx - vViewportPx
|
||||
if (vMaxScrollPx <= 0.0 || vTrackPx <= 0) return@awaitEachGesture
|
||||
val vMinLen = style.minimalHeight.value.toInt()
|
||||
val vLen = (vTrackPx * (vViewportPx / vContentPx)).roundToInt()
|
||||
.coerceIn(vMinLen.coerceAtMost(vTrackPx), vTrackPx)
|
||||
val vTravelPx = vTrackPx - vLen
|
||||
val vRaw = if (vTravelPx <= 0) 0
|
||||
else (vTravelPx * (adapter.scrollOffset / vMaxScrollPx)).roundToInt()
|
||||
val vPos = (if (reverseLayout) vTravelPx - vRaw else vRaw).coerceIn(0, vTravelPx)
|
||||
|
||||
// Map a track-relative thumb-top to a scroll offset. The
|
||||
// target uses the LIVE max scroll (read fresh each move),
|
||||
// not the press-time value — the adapter compares it against
|
||||
// its live scrollOffset, and mixing a stale scale with a live
|
||||
// one makes the delta run away (grab at the bottom, drag up,
|
||||
// and the list overshoots to the middle).
|
||||
fun scrollToTrackPos(inThumbTop: Int) {
|
||||
if (vTravelPx <= 0) return
|
||||
val vLiveMax = adapter.contentSize - adapter.viewportSize
|
||||
if (vLiveMax <= 0.0) return
|
||||
val vClamped = inThumbTop.coerceIn(0, vTravelPx)
|
||||
val vFrac = (if (reverseLayout) vTravelPx - vClamped else vClamped).toDouble() / vTravelPx
|
||||
vScope.launch { adapter.scrollTo(vFrac * vLiveMax) }
|
||||
}
|
||||
|
||||
val vPress = (if (isVertical) vDown.position.y else vDown.position.x).toInt()
|
||||
val vGrab: Int
|
||||
if (vPress in vPos..(vPos + vLen)) {
|
||||
vDraggingThumb = true
|
||||
vGrab = vPress - vPos
|
||||
} else {
|
||||
// Page toward the click by one viewport.
|
||||
vDraggingThumb = false
|
||||
vGrab = 0
|
||||
val vDir = if (vPress < vPos) -1.0 else 1.0
|
||||
vScope.launch { adapter.scrollTo(adapter.scrollOffset + vDir * vViewportPx) }
|
||||
}
|
||||
|
||||
// Follow the pressed pointer to release, consuming every
|
||||
// change so the interaction can't leak. Only a thumb grab
|
||||
// drags-to-scroll; a track press just consumes.
|
||||
do {
|
||||
val vEvent = awaitPointerEvent()
|
||||
val vChange = vEvent.changes.firstOrNull { it.id == vDown.id } ?: break
|
||||
if (vDraggingThumb) {
|
||||
val vCur = (if (isVertical) vChange.position.y else vChange.position.x).toInt()
|
||||
scrollToTrackPos(vCur - vGrab)
|
||||
}
|
||||
vChange.consume()
|
||||
} while (vEvent.changes.any { it.id == vDown.id && it.pressed })
|
||||
|
||||
vDraggingThumb = false
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/* Sizes the invisible drag-capture overlay to the full track. `inTrackDp`
|
||||
comes from the caller pre-converted via LocalDensity (Option-B: layout
|
||||
coords are physical px, so px-to-dp goes through the current density). */
|
||||
private fun Modifier.matchTrackSize(inVertical: Boolean, inTrackDp: Dp, inThickness: Dp): Modifier =
|
||||
if (inVertical) this.width(inThickness).height(inTrackDp)
|
||||
else this.height(inThickness).width(inTrackDp)
|
||||
@@ -0,0 +1,172 @@
|
||||
// COPY of the port's SplitPane (package com.compose.sdl.widgets) so the SAME
|
||||
// implementation runs on the jvm parity target — the port modules are
|
||||
// native-only, so apidemo's commonMain cannot reference them directly.
|
||||
// Keep in sync with the original when it changes.
|
||||
package apidemo
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.hoverable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsHoveredAsState
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.ui.layout.onSizeChanged
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.foundation.gestures.detectDragGestures
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
// ==================
|
||||
// MARK: SplitPane
|
||||
// ==================
|
||||
|
||||
/** Two-pane resizable split. `initialFirstSize` seeds the first pane's width
|
||||
* (horizontal split) or height (vertical split); after first layout it tracks
|
||||
* the user's drag. `minFirstSize` / `minSecondSize` clamp so neither pane can
|
||||
* shrink past its minimum.
|
||||
*
|
||||
* Internal sizing is in **pixels** to match this port's pixel-space layout
|
||||
* tree (Option-B density flow). `Modifier.width((px / density).dp)` converts
|
||||
* back at the modifier boundary. */
|
||||
@Composable
|
||||
fun HorizontalSplitPane(
|
||||
modifier: Modifier = Modifier,
|
||||
initialFirstSize: Dp = 200.dp,
|
||||
minFirstSize: Dp = 50.dp,
|
||||
minSecondSize: Dp = 50.dp,
|
||||
dividerColor: Color = Color(0x33FFFFFFL),
|
||||
dividerHoverColor: Color = Color(0x66FFFFFFL),
|
||||
first: @Composable () -> Unit,
|
||||
second: @Composable () -> Unit,
|
||||
) {
|
||||
val vDensity = LocalDensity.current
|
||||
val vDividerPx = with(vDensity) { SplitPaneDefaults.DividerThickness.toPx().toInt() }
|
||||
val vMinFirstPx = with(vDensity) { minFirstSize.toPx().toInt() }
|
||||
val vMinSecondPx = with(vDensity) { minSecondSize.toPx().toInt() }
|
||||
val vInitialFirstPx = with(vDensity) { initialFirstSize.toPx().toInt() }
|
||||
|
||||
var vTotalWidthPx by remember { mutableStateOf(0) }
|
||||
var vFirstWidthPx by remember { mutableStateOf(vInitialFirstPx) }
|
||||
val vDividerSource = remember { MutableInteractionSource() }
|
||||
val vDividerHover by vDividerSource.collectIsHoveredAsState()
|
||||
var vDragging by remember { mutableStateOf(false) }
|
||||
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.onSizeChanged { vTotalWidthPx = it.width },
|
||||
) {
|
||||
val vClampedFirstPx = if (vTotalWidthPx > 0)
|
||||
vFirstWidthPx.coerceIn(vMinFirstPx, (vTotalWidthPx - vDividerPx - vMinSecondPx).coerceAtLeast(vMinFirstPx))
|
||||
else vFirstWidthPx
|
||||
val vSecondWidthPx = (vTotalWidthPx - vClampedFirstPx - vDividerPx).coerceAtLeast(0)
|
||||
|
||||
Box(modifier = Modifier.width(with(vDensity) { vClampedFirstPx.toDp() }).fillMaxHeight()) { first() }
|
||||
|
||||
// Solid divider that fills its own slot — what you see is exactly what
|
||||
// you can grab. Hover or an in-progress drag just changes the colour (no
|
||||
// size change → no layout shift, and no flicker when the pointer briefly
|
||||
// leaves the slot mid-drag).
|
||||
val vActive = vDividerHover || vDragging
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(SplitPaneDefaults.DividerThickness)
|
||||
.fillMaxHeight()
|
||||
.background(if (vActive) dividerHoverColor else dividerColor)
|
||||
.hoverable(vDividerSource)
|
||||
.pointerInput(Unit) {
|
||||
detectDragGestures(
|
||||
onDragStart = { vDragging = true },
|
||||
onDragEnd = { vDragging = false },
|
||||
onDragCancel = { vDragging = false },
|
||||
onDrag = { _, delta ->
|
||||
val vMax = (vTotalWidthPx - vDividerPx - vMinSecondPx).coerceAtLeast(vMinFirstPx)
|
||||
vFirstWidthPx = (vFirstWidthPx + delta.x.toInt()).coerceIn(vMinFirstPx, vMax)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
Box(modifier = Modifier.width(with(vDensity) { vSecondWidthPx.toDp() }).fillMaxHeight()) { second() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun VerticalSplitPane(
|
||||
modifier: Modifier = Modifier,
|
||||
initialFirstSize: Dp = 150.dp,
|
||||
minFirstSize: Dp = 50.dp,
|
||||
minSecondSize: Dp = 50.dp,
|
||||
dividerColor: Color = Color(0x33FFFFFFL),
|
||||
dividerHoverColor: Color = Color(0x66FFFFFFL),
|
||||
first: @Composable () -> Unit,
|
||||
second: @Composable () -> Unit,
|
||||
) {
|
||||
val vDensity = LocalDensity.current
|
||||
val vDividerPx = with(vDensity) { SplitPaneDefaults.DividerThickness.toPx().toInt() }
|
||||
val vMinFirstPx = with(vDensity) { minFirstSize.toPx().toInt() }
|
||||
val vMinSecondPx = with(vDensity) { minSecondSize.toPx().toInt() }
|
||||
val vInitialFirstPx = with(vDensity) { initialFirstSize.toPx().toInt() }
|
||||
|
||||
var vTotalHeightPx by remember { mutableStateOf(0) }
|
||||
var vFirstHeightPx by remember { mutableStateOf(vInitialFirstPx) }
|
||||
val vDividerSource = remember { MutableInteractionSource() }
|
||||
val vDividerHover by vDividerSource.collectIsHoveredAsState()
|
||||
var vDragging by remember { mutableStateOf(false) }
|
||||
var vPressStartFirstPx by remember { mutableStateOf(0) }
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.onSizeChanged { vTotalHeightPx = it.height },
|
||||
) {
|
||||
val vClampedFirstPx = if (vTotalHeightPx > 0)
|
||||
vFirstHeightPx.coerceIn(vMinFirstPx, (vTotalHeightPx - vDividerPx - vMinSecondPx).coerceAtLeast(vMinFirstPx))
|
||||
else vFirstHeightPx
|
||||
val vSecondHeightPx = (vTotalHeightPx - vClampedFirstPx - vDividerPx).coerceAtLeast(0)
|
||||
|
||||
Box(modifier = Modifier.height(with(vDensity) { vClampedFirstPx.toDp() }).fillMaxWidth()) { first() }
|
||||
|
||||
// Solid divider that fills its slot; hover/drag only changes the colour
|
||||
// (no size change → no layout shift, no flicker mid-drag).
|
||||
val vActive = vDividerHover || vDragging
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(SplitPaneDefaults.DividerThickness)
|
||||
.fillMaxWidth()
|
||||
.background(if (vActive) dividerHoverColor else dividerColor)
|
||||
.hoverable(vDividerSource)
|
||||
.pointerInput(Unit) {
|
||||
detectDragGestures(
|
||||
onDragStart = { vDragging = true },
|
||||
onDragEnd = { vDragging = false },
|
||||
onDragCancel = { vDragging = false },
|
||||
onDrag = { _, delta ->
|
||||
val vMax = (vTotalHeightPx - vDividerPx - vMinSecondPx).coerceAtLeast(vMinFirstPx)
|
||||
vFirstHeightPx = (vFirstHeightPx + delta.y.toInt()).coerceIn(vMinFirstPx, vMax)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
Box(modifier = Modifier.height(with(vDensity) { vSecondHeightPx.toDp() }).fillMaxWidth()) { second() }
|
||||
}
|
||||
}
|
||||
|
||||
object SplitPaneDefaults {
|
||||
val DividerThickness: Dp = 4.dp // divider width = hit/drag area (solid; what you see is what you grab)
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
@file:OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class)
|
||||
|
||||
package apidemo
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.graphics.toComposeImageBitmap
|
||||
import androidx.compose.ui.input.key.KeyEvent
|
||||
import androidx.compose.ui.platform.ClipEntry
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.loadSvgPainter
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.TextMeasurer
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.createFontFamilyResolver
|
||||
import androidx.compose.ui.unit.Constraints
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.sp
|
||||
import java.awt.Desktop
|
||||
import java.awt.EventQueue
|
||||
import java.awt.FileDialog
|
||||
import java.awt.Frame
|
||||
import java.awt.datatransfer.StringSelection
|
||||
import java.io.File
|
||||
import org.jetbrains.skia.Image
|
||||
|
||||
// ==================
|
||||
// MARK: JVM actuals — AWT + upstream Compose Desktop
|
||||
// ==================
|
||||
|
||||
private val kIsWindows = System.getProperty("os.name").startsWith("Windows")
|
||||
private val kIsMac = System.getProperty("os.name").startsWith("Mac")
|
||||
|
||||
internal actual val systemFileSystem: okio.FileSystem = okio.FileSystem.SYSTEM
|
||||
|
||||
actual fun createApiHttpClient(): io.ktor.client.HttpClient =
|
||||
io.ktor.client.HttpClient(io.ktor.client.engine.cio.CIO)
|
||||
|
||||
// ============
|
||||
// Window hooks — the shared App installs them; MainJvm wires them into the
|
||||
// upstream Window() (onCloseRequest / onPreviewKeyEvent).
|
||||
|
||||
internal var jvmOnCloseRequest: (() -> Boolean)? = null
|
||||
internal var jvmOnKeyShortcut: ((KeyEvent) -> Boolean)? = null
|
||||
|
||||
@Composable
|
||||
actual fun InstallWindowHooks(inOnCloseRequest: () -> Boolean, inOnKeyShortcut: (KeyEvent) -> Boolean) {
|
||||
androidx.compose.runtime.DisposableEffect(inOnCloseRequest, inOnKeyShortcut) {
|
||||
jvmOnCloseRequest = inOnCloseRequest
|
||||
jvmOnKeyShortcut = inOnKeyShortcut
|
||||
onDispose { jvmOnCloseRequest = null; jvmOnKeyShortcut = null }
|
||||
}
|
||||
}
|
||||
|
||||
/* Mirrors SDL_GetPrefPath's layout: <os user-data dir>/<org>/<app>/ with a
|
||||
trailing separator, created on demand. */
|
||||
actual fun appDataDir(inOrg: String, inApp: String): String? {
|
||||
val vHome = System.getProperty("user.home") ?: return null
|
||||
val vBase = when {
|
||||
kIsWindows -> System.getenv("APPDATA") ?: "$vHome/AppData/Roaming"
|
||||
kIsMac -> "$vHome/Library/Application Support"
|
||||
else -> System.getenv("XDG_DATA_HOME") ?: "$vHome/.local/share"
|
||||
}
|
||||
val vDir = File(File(vBase, inOrg), inApp)
|
||||
if (!vDir.exists() && !vDir.mkdirs()) return null
|
||||
return vDir.absolutePath + File.separator
|
||||
}
|
||||
|
||||
/* Opens the path's containing folder (AWT has no cross-platform "select in
|
||||
file manager"); fire-and-forget off the EDT. */
|
||||
actual fun revealInFileManager(inPath: String, inOnResult: ((Boolean) -> Unit)?) {
|
||||
Thread {
|
||||
val vOk = runCatching {
|
||||
val vFile = File(inPath)
|
||||
Desktop.getDesktop().open(if (vFile.isDirectory) vFile else vFile.parentFile ?: vFile)
|
||||
}.isSuccess
|
||||
inOnResult?.invoke(vOk)
|
||||
}.apply { isDaemon = true }.start()
|
||||
}
|
||||
|
||||
actual fun fileManagerName(): String = when {
|
||||
kIsWindows -> "Explorer"
|
||||
kIsMac -> "Finder"
|
||||
else -> "Files"
|
||||
}
|
||||
|
||||
/* AWT FileDialog runs its own nested event loop, so invoking from the EDT
|
||||
(where Compose Desktop also runs) keeps the UI serviced while modal. */
|
||||
actual fun showSaveFileDialog(inDefaultName: String?, inOnResult: (String?) -> Unit) {
|
||||
EventQueue.invokeLater {
|
||||
val vDlg = FileDialog(null as Frame?, "Save", FileDialog.SAVE)
|
||||
inDefaultName?.let { vDlg.file = it }
|
||||
vDlg.isVisible = true
|
||||
inOnResult(vDlg.file?.let { vDlg.directory + it })
|
||||
}
|
||||
}
|
||||
|
||||
actual fun showOpenFileDialog(inOnResult: (String?) -> Unit) {
|
||||
EventQueue.invokeLater {
|
||||
val vDlg = FileDialog(null as Frame?, "Open", FileDialog.LOAD)
|
||||
vDlg.isVisible = true
|
||||
inOnResult(vDlg.file?.let { vDlg.directory + it })
|
||||
}
|
||||
}
|
||||
|
||||
/* Upstream desktop's ClipEntry wraps an AWT Transferable. */
|
||||
actual fun clipEntryOfText(inText: String): ClipEntry = ClipEntry(StringSelection(inText))
|
||||
|
||||
// ============
|
||||
// In-memory response images
|
||||
|
||||
private val kMemoryImages = HashMap<String, ByteArray>()
|
||||
|
||||
actual fun registerMemoryImage(inKey: String, inBytes: ByteArray) { kMemoryImages[inKey] = inBytes }
|
||||
|
||||
actual fun removeMemoryImage(inKey: String) { kMemoryImages.remove(inKey) }
|
||||
|
||||
@Composable
|
||||
actual fun memoryImagePainter(inKey: String, inSvg: Boolean): Painter {
|
||||
val vDensity = LocalDensity.current
|
||||
return remember(inKey, inSvg) {
|
||||
val vBytes = kMemoryImages[inKey]
|
||||
runCatching {
|
||||
if (vBytes == null) error("no bytes for $inKey")
|
||||
if (inSvg) loadSvgPainter(vBytes.inputStream(), vDensity)
|
||||
else BitmapPainter(Image.makeFromEncoded(vBytes).toComposeImageBitmap())
|
||||
}.getOrElse { BitmapPainter(ImageBitmap(1, 1)) }
|
||||
}
|
||||
}
|
||||
|
||||
// ============
|
||||
// Text layout
|
||||
|
||||
/* Upstream TextMeasurer at density 1 so the px-valued font size maps 1:1
|
||||
(the caller passes an already density-scaled size). */
|
||||
private val kRowMeasurer: TextMeasurer by lazy {
|
||||
TextMeasurer(createFontFamilyResolver(), Density(1f), LayoutDirection.Ltr)
|
||||
}
|
||||
|
||||
actual fun wrappedRowCount(inText: String, inFontPx: Int, inMaxWidthPx: Int, inFamilyName: String?): Int =
|
||||
runCatching {
|
||||
kRowMeasurer.measure(
|
||||
AnnotatedString(inText),
|
||||
TextStyle(fontSize = inFontPx.sp, fontFamily = monoFontFamily ?: FontFamily.Monospace),
|
||||
constraints = Constraints(maxWidth = inMaxWidthPx),
|
||||
).lineCount
|
||||
}.getOrDefault(1)
|
||||
|
||||
/* The jvm parity app only stores the preference — upstream's text pipeline has
|
||||
no global tab-width knob. Backed by state so menu checkmarks recompose. */
|
||||
private var fTabWidth by mutableStateOf(4)
|
||||
actual var editorTabWidth: Int
|
||||
get() = fTabWidth
|
||||
set(value) { fTabWidth = value }
|
||||
@@ -0,0 +1,23 @@
|
||||
package apidemo
|
||||
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.platform.Font
|
||||
|
||||
// ==================
|
||||
// MARK: Monospace body font — JVM actuals (classpath font/ staged by
|
||||
// jvmProcessResources)
|
||||
// ==================
|
||||
|
||||
actual val monoFontFamily: FontFamily? by lazy {
|
||||
val vBytes = object {}.javaClass.getResourceAsStream("/font/NotoSansMono.ttf")?.use { it.readBytes() }
|
||||
if (vBytes == null) {
|
||||
println("apidemo: NotoSansMono.ttf not on the classpath — body uses the default font")
|
||||
null
|
||||
} else {
|
||||
FontFamily(Font(identity = kMonoFamily, data = vBytes))
|
||||
}
|
||||
}
|
||||
|
||||
actual val monoFontFamilyName: String? by lazy {
|
||||
if (monoFontFamily != null) kMonoFamily else null
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package apidemo
|
||||
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import androidx.compose.ui.window.rememberWindowState
|
||||
|
||||
// The JVM comparison app's entry point. Runs the SAME shared App() as the
|
||||
// native :apidemo, but on Compose Desktop (JVM) against upstream
|
||||
// org.jetbrains.compose. Client-certificate (mTLS) features are native-only
|
||||
// (they drive the bundled libcurl); the jvm actuals report that instead.
|
||||
fun main() = application {
|
||||
Window(
|
||||
// The shared App installs a persist-then-close hook (InstallWindowHooks).
|
||||
onCloseRequest = { if (jvmOnCloseRequest?.invoke() != false) exitApplication() },
|
||||
onPreviewKeyEvent = { jvmOnKeyShortcut?.invoke(it) ?: false },
|
||||
title = "API Manager — JVM (upstream Compose)",
|
||||
state = rememberWindowState(width = 1240.dp, height = 820.dp),
|
||||
) {
|
||||
App()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package apidemo
|
||||
|
||||
// ==================
|
||||
// MARK: TLS chain / client-certificate — JVM actuals (native-only feature)
|
||||
// ==================
|
||||
// The native builds drive the bundled libcurl (CURLOPT_SSLCERT / CERTINFO);
|
||||
// there is no libcurl on the jvm parity stack, so both entry points report
|
||||
// the limitation instead of half-implementing it over JSSE.
|
||||
|
||||
private const val kNativeOnly =
|
||||
"Client-certificate (mTLS) features need the native build — they drive the bundled libcurl directly."
|
||||
|
||||
actual fun inspectTlsChain(inReq: ApiRequest): TlsChain = TlsChain(emptyList(), kNativeOnly)
|
||||
|
||||
actual fun curlSendWithClientCert(inReq: ApiRequest): ApiResponse = ApiResponse(
|
||||
ok = false,
|
||||
status = 0,
|
||||
statusText = "",
|
||||
timeMs = 0,
|
||||
sizeBytes = 0,
|
||||
headers = emptyList(),
|
||||
body = "",
|
||||
error = kNativeOnly,
|
||||
)
|
||||
|
||||
actual fun sweepTempClientCerts() {}
|
||||
@@ -0,0 +1,63 @@
|
||||
package apidemo
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.ui.input.key.KeyEvent
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.platform.ClipEntry
|
||||
import com.compose.sdl.LocalComposeNativeWindow
|
||||
import com.compose.sdl.TextLayoutConfig
|
||||
import com.compose.sdl.registerMemoryResource
|
||||
import com.compose.sdl.removeMemoryResource
|
||||
import com.compose.sdl.res.ResourceKind
|
||||
import com.compose.sdl.text.currentTextMeasurer
|
||||
|
||||
// ==================
|
||||
// MARK: Native actuals — pure delegation to the port's SDL-backed APIs
|
||||
// ==================
|
||||
|
||||
actual fun appDataDir(inOrg: String, inApp: String): String? =
|
||||
com.compose.sdl.appDataDir(inOrg, inApp)
|
||||
|
||||
actual fun revealInFileManager(inPath: String, inOnResult: ((Boolean) -> Unit)?) =
|
||||
com.compose.sdl.revealInFileManager(inPath, inOnResult)
|
||||
|
||||
actual fun fileManagerName(): String = com.compose.sdl.fileManagerName()
|
||||
|
||||
actual fun showSaveFileDialog(inDefaultName: String?, inOnResult: (String?) -> Unit) =
|
||||
com.compose.sdl.showSaveFileDialog(inDefaultName, inOnResult)
|
||||
|
||||
actual fun showOpenFileDialog(inOnResult: (String?) -> Unit) =
|
||||
com.compose.sdl.showOpenFileDialog(inOnResult)
|
||||
|
||||
actual fun clipEntryOfText(inText: String): ClipEntry = ClipEntry.withPlainText(inText)
|
||||
|
||||
actual fun registerMemoryImage(inKey: String, inBytes: ByteArray) = registerMemoryResource(inKey, inBytes)
|
||||
|
||||
actual fun removeMemoryImage(inKey: String) = removeMemoryResource(inKey)
|
||||
|
||||
@Composable
|
||||
actual fun memoryImagePainter(inKey: String, inSvg: Boolean): Painter =
|
||||
com.compose.sdl.res.painterResource(inKey, if (inSvg) ResourceKind.Svg else ResourceKind.Raster)
|
||||
|
||||
actual fun wrappedRowCount(inText: String, inFontPx: Int, inMaxWidthPx: Int, inFamilyName: String?): Int =
|
||||
currentTextMeasurer.wrap(inText, inFontPx, inMaxWidthPx, inFamilyName).lines.size
|
||||
|
||||
actual var editorTabWidth: Int
|
||||
get() = TextLayoutConfig.tabWidth
|
||||
set(value) { TextLayoutConfig.tabWidth = value }
|
||||
|
||||
internal actual val systemFileSystem: okio.FileSystem = okio.FileSystem.SYSTEM
|
||||
|
||||
actual fun createApiHttpClient(): io.ktor.client.HttpClient =
|
||||
io.ktor.client.HttpClient(io.ktor.client.engine.curl.Curl)
|
||||
|
||||
@Composable
|
||||
actual fun InstallWindowHooks(inOnCloseRequest: () -> Boolean, inOnKeyShortcut: (KeyEvent) -> Boolean) {
|
||||
val vWindow = LocalComposeNativeWindow.current
|
||||
DisposableEffect(inOnCloseRequest, inOnKeyShortcut) {
|
||||
vWindow.setOnCloseRequest(inOnCloseRequest)
|
||||
vWindow.setOnKeyShortcut(inOnKeyShortcut)
|
||||
onDispose { vWindow.setOnCloseRequest(null); vWindow.setOnKeyShortcut(null) }
|
||||
}
|
||||
}
|
||||
@@ -39,21 +39,10 @@ class PreparedCert(
|
||||
Throws with a user-facing message if the cert/key can't be loaded. */
|
||||
expect fun prepareClientCert(inReq: ApiRequest): PreparedCert
|
||||
|
||||
/* Remove any temporary client certs (and their key containers) a previous run
|
||||
left behind in the Windows store after a crash — identified by our prefix, so
|
||||
the user's own certificates are never touched. No-op off Windows. Call once
|
||||
at startup. */
|
||||
expect fun sweepTempClientCerts()
|
||||
|
||||
/* One certificate in the chain: its CURLINFO_CERTINFO-style fields (Subject /
|
||||
Issuer / the PEM under "Cert" / dates …) and whether the server actually
|
||||
presented it. Derived certs — an issuer resolved from the OS store, or a
|
||||
name-only placeholder — have fromServer = false and are drawn dotted. */
|
||||
class ChainCert(val fields: List<Pair<String, String>>, val fromServer: Boolean)
|
||||
|
||||
/* The server's TLS certificate chain. error is set instead when it couldn't be
|
||||
fetched; fields vary by TLS backend. */
|
||||
class TlsChain(val certs: List<ChainCert>, val error: String?)
|
||||
// ChainCert / TlsChain and the sweepTempClientCerts / inspectTlsChain /
|
||||
// curlSendWithClientCert expects live in commonMain (TlsCommon.kt) — the UI
|
||||
// consumes them from shared code; the per-OS ClientCert*.kt actuals below the
|
||||
// native tree actualize sweepTempClientCerts directly.
|
||||
|
||||
/* Continue a server-presented chain with its issuer(s). Where possible the
|
||||
issuer is resolved from the OS certificate store with full info; otherwise the
|
||||
@@ -120,7 +109,7 @@ private fun onCurlDiscard(inBuffer: CPointer<ByteVar>, inSize: size_t, inCount:
|
||||
request's client certificate if it has one (so mTLS endpoints work too).
|
||||
inReq is already var-resolved. */
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
fun inspectTlsChain(inReq: ApiRequest): TlsChain
|
||||
actual fun inspectTlsChain(inReq: ApiRequest): TlsChain
|
||||
{
|
||||
val vCert = try { if (inReq.hasClientCert) prepareClientCert(inReq) else null }
|
||||
catch (e: Throwable) { return TlsChain(emptyList(), e.message ?: "Client certificate error") }
|
||||
@@ -185,7 +174,7 @@ private fun readCertInfo(inCurl: COpaquePointer): List<List<Pair<String, String>
|
||||
/* Send a client-certificate request through libcurl and adapt the result into
|
||||
the same ApiResponse the Ktor path produces. inReq is already var-resolved. */
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
fun curlSendWithClientCert(inReq: ApiRequest): ApiResponse
|
||||
actual fun curlSendWithClientCert(inReq: ApiRequest): ApiResponse
|
||||
{
|
||||
val vMark = TimeSource.Monotonic.markNow()
|
||||
val vCert = try { prepareClientCert(inReq) }
|
||||
|
||||
@@ -6,17 +6,10 @@ import com.compose.sdl.loadComposeResourceBytes
|
||||
import com.compose.sdl.text.namedFontFamily
|
||||
|
||||
// ==================
|
||||
// MARK: Monospace body font
|
||||
// MARK: Monospace body font — native actuals (data.kres + IconFont)
|
||||
// ==================
|
||||
|
||||
// Family name the body editor passes for monospace text. Resolves to the bundled
|
||||
// Noto Sans Mono once registered; null means the font isn't in data.kres, in
|
||||
// which case the body falls back to the default (proportional Noto Sans).
|
||||
const val kMonoFamily = "noto-mono"
|
||||
|
||||
// The raw project family name string — used by the SyntaxHighlight tokeniser's
|
||||
// wrap() call which measures via NativeTextMeasurer (accepts a name string).
|
||||
val monoFontFamilyName: String? by lazy {
|
||||
actual val monoFontFamilyName: String? by lazy {
|
||||
val vBytes = loadComposeResourceBytes("font/NotoSansMono.ttf")
|
||||
if (vBytes == null) {
|
||||
println("apidemo: NotoSansMono.ttf not bundled — body uses the default font")
|
||||
@@ -27,9 +20,6 @@ val monoFontFamilyName: String? by lazy {
|
||||
}
|
||||
}
|
||||
|
||||
// The material3 Text / BasicTextField-shaped FontFamily wrapper. Wraps the
|
||||
// registered project family in a `NamedFont`-backed FontFamily so the m3 Text
|
||||
// signature (which takes `FontFamily?` proper) can be given the mono family.
|
||||
val monoFontFamily: FontFamily? by lazy {
|
||||
actual val monoFontFamily: FontFamily? by lazy {
|
||||
monoFontFamilyName?.let { namedFontFamily(it) }
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+41
-4
@@ -5,11 +5,12 @@
|
||||
// apply the multiplatform plugin. Each subproject still applies the ones it needs.
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.multiplatform) apply false
|
||||
alias(libs.plugins.kotlin.jvm) apply false
|
||||
alias(libs.plugins.kotlin.plugin.compose) apply false
|
||||
alias(libs.plugins.kotlin.plugin.serialization) apply false
|
||||
alias(libs.plugins.compose.multiplatform) apply false
|
||||
// Public-ABI dumps (api/<module>.klib.api). Used by scripts/compose-fidelity-check.py
|
||||
// to diff our androidx.compose.* surface against the official Compose klib ABI.
|
||||
// Public-ABI dumps (api/<module>.klib.api). Used by scripts/compose-coverage.py
|
||||
// to diff our mirrored API surface against the official upstream klib ABI dumps.
|
||||
alias(libs.plugins.binary.compatibility.validator)
|
||||
}
|
||||
|
||||
@@ -17,7 +18,8 @@ plugins {
|
||||
// surface worth tracking, so skip them.
|
||||
apiValidation {
|
||||
klib { enabled = true }
|
||||
ignoredProjects.addAll(listOf("demo", "apidemo"))
|
||||
// compose-desktop-native-bridge is a plain JVM Gradle plugin — no klib ABI to track.
|
||||
ignoredProjects.addAll(listOf("demo", "apidemo", "compose-desktop-native-bridge"))
|
||||
}
|
||||
|
||||
// Project coordinates. `group` is baked into every module's Kotlin/Native klib
|
||||
@@ -47,6 +49,7 @@ allprojects {
|
||||
val kAppModules = setOf(":demo", ":apidemo")
|
||||
val kPublishedLibs = setOf(
|
||||
":ui", ":ui-util", ":ui-geometry", ":ui-unit", ":ui-backhandler",
|
||||
":ui-tooling-preview",
|
||||
":animation-core", ":animation", ":animation-graphics",
|
||||
":foundation", ":foundation-layout",
|
||||
":material3", ":material-ripple",
|
||||
@@ -108,10 +111,44 @@ subprojects {
|
||||
}
|
||||
}
|
||||
|
||||
// FULL-COMMONIZATION BRIDGE (repo-wide): a module may declare the OFFICIAL
|
||||
// Maven Compose artifacts in its commonMain so metadata + jvm resolve them
|
||||
// (e.g. :material-symbols' common API); every NATIVE target configuration
|
||||
// swaps those modules for the port's project equivalents — the Maven
|
||||
// artifacts ship no mingwX64/linux klibs. org.jetbrains.compose.runtime is
|
||||
// deliberately NOT here: the port uses the official runtime klibs everywhere.
|
||||
// (:demo carries the same pattern locally for components-resources.)
|
||||
val vNativeTargetTokens = listOf("mingwX64", "linuxX64", "linuxArm64", "macosArm64")
|
||||
allprojects {
|
||||
configurations.configureEach {
|
||||
if (vNativeTargetTokens.any { name.contains(it, ignoreCase = true) }) {
|
||||
resolutionStrategy.dependencySubstitution {
|
||||
substitute(module("org.jetbrains.compose.ui:ui")).using(project(":ui"))
|
||||
// ui's split artifacts: ui-graphics + ui-text are merged INTO
|
||||
// :ui in the port; ui-unit / ui-geometry have their own modules.
|
||||
substitute(module("org.jetbrains.compose.ui:ui-graphics")).using(project(":ui"))
|
||||
substitute(module("org.jetbrains.compose.ui:ui-text")).using(project(":ui"))
|
||||
substitute(module("org.jetbrains.compose.ui:ui-unit")).using(project(":ui-unit"))
|
||||
substitute(module("org.jetbrains.compose.ui:ui-geometry")).using(project(":ui-geometry"))
|
||||
substitute(module("org.jetbrains.compose.ui:ui-util")).using(project(":ui-util"))
|
||||
substitute(module("org.jetbrains.compose.ui:ui-tooling-preview")).using(project(":ui-tooling-preview"))
|
||||
substitute(module("org.jetbrains.compose.foundation:foundation")).using(project(":foundation"))
|
||||
substitute(module("org.jetbrains.compose.foundation:foundation-layout")).using(project(":foundation-layout"))
|
||||
substitute(module("org.jetbrains.compose.animation:animation")).using(project(":animation"))
|
||||
substitute(module("org.jetbrains.compose.animation:animation-core")).using(project(":animation-core"))
|
||||
substitute(module("org.jetbrains.compose.material3:material3")).using(project(":material3"))
|
||||
// navigation3-ui: the JB Maven artifact has no K/N desktop
|
||||
// klibs — the port vendors it as :navigation3-ui.
|
||||
substitute(module("org.jetbrains.androidx.navigation3:navigation3-ui")).using(project(":navigation3-ui"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Whether the current host can build the mingwX64 target. Kotlin/Native can
|
||||
// only cross-compile mingwX64 cinterops from a Windows host — the sdl3_ttf /
|
||||
// sdl3_image cinterops need Windows SDL3 headers under libs/ (produced by
|
||||
// scripts/build-sdl/build-*.sh, which only runs on Windows). Declaring `mingwX64()` on
|
||||
// scripts/build-sdl/build-all.py run on a Windows host). Declaring `mingwX64()` on
|
||||
// a non-Windows host is safe for pure-Kotlin modules but blows up the moment
|
||||
// a `depends = sdl3` cinterop tries to include SDL3_ttf/SDL_ttf.h.
|
||||
// Override with `-PforceMingw=true` if you actually have the headers wired.
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
// Klib ABI Dump
|
||||
// Targets: [linuxArm64, linuxX64, macosArm64, mingwX64]
|
||||
// Rendering settings:
|
||||
// - Signature version: 2
|
||||
// - Show manifest properties: true
|
||||
// - Show declarations: true
|
||||
|
||||
// Library unique name: <com.bitsycore.compose.sdl:components-resources>
|
||||
open annotation class org.jetbrains.compose.resources/ExperimentalResourceApi : kotlin/Annotation { // org.jetbrains.compose.resources/ExperimentalResourceApi|null[0]
|
||||
constructor <init>() // org.jetbrains.compose.resources/ExperimentalResourceApi.<init>|<init>(){}[0]
|
||||
}
|
||||
|
||||
open annotation class org.jetbrains.compose.resources/InternalResourceApi : kotlin/Annotation { // org.jetbrains.compose.resources/InternalResourceApi|null[0]
|
||||
constructor <init>() // org.jetbrains.compose.resources/InternalResourceApi.<init>|<init>(){}[0]
|
||||
}
|
||||
|
||||
open annotation class org.jetbrains.compose.resources/ResourceContentHash : kotlin/Annotation { // org.jetbrains.compose.resources/ResourceContentHash|null[0]
|
||||
constructor <init>(kotlin/Int) // org.jetbrains.compose.resources/ResourceContentHash.<init>|<init>(kotlin.Int){}[0]
|
||||
|
||||
final val hash // org.jetbrains.compose.resources/ResourceContentHash.hash|{}hash[0]
|
||||
final fun <get-hash>(): kotlin/Int // org.jetbrains.compose.resources/ResourceContentHash.hash.<get-hash>|<get-hash>(){}[0]
|
||||
}
|
||||
|
||||
final enum class org.jetbrains.compose.resources/DensityQualifier : kotlin/Enum<org.jetbrains.compose.resources/DensityQualifier>, org.jetbrains.compose.resources/Qualifier { // org.jetbrains.compose.resources/DensityQualifier|null[0]
|
||||
enum entry HDPI // org.jetbrains.compose.resources/DensityQualifier.HDPI|null[0]
|
||||
enum entry LDPI // org.jetbrains.compose.resources/DensityQualifier.LDPI|null[0]
|
||||
enum entry MDPI // org.jetbrains.compose.resources/DensityQualifier.MDPI|null[0]
|
||||
enum entry XHDPI // org.jetbrains.compose.resources/DensityQualifier.XHDPI|null[0]
|
||||
enum entry XXHDPI // org.jetbrains.compose.resources/DensityQualifier.XXHDPI|null[0]
|
||||
enum entry XXXHDPI // org.jetbrains.compose.resources/DensityQualifier.XXXHDPI|null[0]
|
||||
|
||||
final val dpi // org.jetbrains.compose.resources/DensityQualifier.dpi|{}dpi[0]
|
||||
final fun <get-dpi>(): kotlin/Int // org.jetbrains.compose.resources/DensityQualifier.dpi.<get-dpi>|<get-dpi>(){}[0]
|
||||
final val entries // org.jetbrains.compose.resources/DensityQualifier.entries|#static{}entries[0]
|
||||
final fun <get-entries>(): kotlin.enums/EnumEntries<org.jetbrains.compose.resources/DensityQualifier> // org.jetbrains.compose.resources/DensityQualifier.entries.<get-entries>|<get-entries>#static(){}[0]
|
||||
|
||||
final fun valueOf(kotlin/String): org.jetbrains.compose.resources/DensityQualifier // org.jetbrains.compose.resources/DensityQualifier.valueOf|valueOf#static(kotlin.String){}[0]
|
||||
final fun values(): kotlin/Array<org.jetbrains.compose.resources/DensityQualifier> // org.jetbrains.compose.resources/DensityQualifier.values|values#static(){}[0]
|
||||
|
||||
final object Companion { // org.jetbrains.compose.resources/DensityQualifier.Companion|null[0]
|
||||
final fun selectByDensity(kotlin/Float): org.jetbrains.compose.resources/DensityQualifier // org.jetbrains.compose.resources/DensityQualifier.Companion.selectByDensity|selectByDensity(kotlin.Float){}[0]
|
||||
final fun selectByValue(kotlin/Int): org.jetbrains.compose.resources/DensityQualifier // org.jetbrains.compose.resources/DensityQualifier.Companion.selectByValue|selectByValue(kotlin.Int){}[0]
|
||||
}
|
||||
}
|
||||
|
||||
final enum class org.jetbrains.compose.resources/ThemeQualifier : kotlin/Enum<org.jetbrains.compose.resources/ThemeQualifier>, org.jetbrains.compose.resources/Qualifier { // org.jetbrains.compose.resources/ThemeQualifier|null[0]
|
||||
enum entry DARK // org.jetbrains.compose.resources/ThemeQualifier.DARK|null[0]
|
||||
enum entry LIGHT // org.jetbrains.compose.resources/ThemeQualifier.LIGHT|null[0]
|
||||
|
||||
final val entries // org.jetbrains.compose.resources/ThemeQualifier.entries|#static{}entries[0]
|
||||
final fun <get-entries>(): kotlin.enums/EnumEntries<org.jetbrains.compose.resources/ThemeQualifier> // org.jetbrains.compose.resources/ThemeQualifier.entries.<get-entries>|<get-entries>#static(){}[0]
|
||||
|
||||
final fun valueOf(kotlin/String): org.jetbrains.compose.resources/ThemeQualifier // org.jetbrains.compose.resources/ThemeQualifier.valueOf|valueOf#static(kotlin.String){}[0]
|
||||
final fun values(): kotlin/Array<org.jetbrains.compose.resources/ThemeQualifier> // org.jetbrains.compose.resources/ThemeQualifier.values|values#static(){}[0]
|
||||
|
||||
final object Companion { // org.jetbrains.compose.resources/ThemeQualifier.Companion|null[0]
|
||||
final fun selectByValue(kotlin/Boolean): org.jetbrains.compose.resources/ThemeQualifier // org.jetbrains.compose.resources/ThemeQualifier.Companion.selectByValue|selectByValue(kotlin.Boolean){}[0]
|
||||
}
|
||||
}
|
||||
|
||||
abstract interface org.jetbrains.compose.resources/Qualifier // org.jetbrains.compose.resources/Qualifier|null[0]
|
||||
|
||||
abstract interface org.jetbrains.compose.resources/ResourceReader { // org.jetbrains.compose.resources/ResourceReader|null[0]
|
||||
abstract fun getUri(kotlin/String): kotlin/String // org.jetbrains.compose.resources/ResourceReader.getUri|getUri(kotlin.String){}[0]
|
||||
abstract suspend fun read(kotlin/String): kotlin/ByteArray // org.jetbrains.compose.resources/ResourceReader.read|read(kotlin.String){}[0]
|
||||
abstract suspend fun readPart(kotlin/String, kotlin/Long, kotlin/Long): kotlin/ByteArray // org.jetbrains.compose.resources/ResourceReader.readPart|readPart(kotlin.String;kotlin.Long;kotlin.Long){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources.vector.xmldom/MalformedXMLException : kotlin/Exception { // org.jetbrains.compose.resources.vector.xmldom/MalformedXMLException|null[0]
|
||||
constructor <init>(kotlin/String?) // org.jetbrains.compose.resources.vector.xmldom/MalformedXMLException.<init>|<init>(kotlin.String?){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources/DrawableResource : org.jetbrains.compose.resources/Resource { // org.jetbrains.compose.resources/DrawableResource|null[0]
|
||||
constructor <init>(kotlin/String, kotlin.collections/Set<org.jetbrains.compose.resources/ResourceItem>) // org.jetbrains.compose.resources/DrawableResource.<init>|<init>(kotlin.String;kotlin.collections.Set<org.jetbrains.compose.resources.ResourceItem>){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources/FontResource : org.jetbrains.compose.resources/Resource { // org.jetbrains.compose.resources/FontResource|null[0]
|
||||
constructor <init>(kotlin/String, kotlin.collections/Set<org.jetbrains.compose.resources/ResourceItem>) // org.jetbrains.compose.resources/FontResource.<init>|<init>(kotlin.String;kotlin.collections.Set<org.jetbrains.compose.resources.ResourceItem>){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources/LanguageQualifier : org.jetbrains.compose.resources/Qualifier { // org.jetbrains.compose.resources/LanguageQualifier|null[0]
|
||||
constructor <init>(kotlin/String) // org.jetbrains.compose.resources/LanguageQualifier.<init>|<init>(kotlin.String){}[0]
|
||||
|
||||
final val language // org.jetbrains.compose.resources/LanguageQualifier.language|{}language[0]
|
||||
final fun <get-language>(): kotlin/String // org.jetbrains.compose.resources/LanguageQualifier.language.<get-language>|<get-language>(){}[0]
|
||||
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // org.jetbrains.compose.resources/LanguageQualifier.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // org.jetbrains.compose.resources/LanguageQualifier.hashCode|hashCode(){}[0]
|
||||
final fun toString(): kotlin/String // org.jetbrains.compose.resources/LanguageQualifier.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources/MissingResourceException : kotlin/Exception { // org.jetbrains.compose.resources/MissingResourceException|null[0]
|
||||
constructor <init>(kotlin/String) // org.jetbrains.compose.resources/MissingResourceException.<init>|<init>(kotlin.String){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources/PluralStringResource : org.jetbrains.compose.resources/Resource { // org.jetbrains.compose.resources/PluralStringResource|null[0]
|
||||
constructor <init>(kotlin/String, kotlin/String, kotlin.collections/Set<org.jetbrains.compose.resources/ResourceItem>) // org.jetbrains.compose.resources/PluralStringResource.<init>|<init>(kotlin.String;kotlin.String;kotlin.collections.Set<org.jetbrains.compose.resources.ResourceItem>){}[0]
|
||||
|
||||
final val key // org.jetbrains.compose.resources/PluralStringResource.key|{}key[0]
|
||||
final fun <get-key>(): kotlin/String // org.jetbrains.compose.resources/PluralStringResource.key.<get-key>|<get-key>(){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources/RegionQualifier : org.jetbrains.compose.resources/Qualifier { // org.jetbrains.compose.resources/RegionQualifier|null[0]
|
||||
constructor <init>(kotlin/String) // org.jetbrains.compose.resources/RegionQualifier.<init>|<init>(kotlin.String){}[0]
|
||||
|
||||
final val region // org.jetbrains.compose.resources/RegionQualifier.region|{}region[0]
|
||||
final fun <get-region>(): kotlin/String // org.jetbrains.compose.resources/RegionQualifier.region.<get-region>|<get-region>(){}[0]
|
||||
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // org.jetbrains.compose.resources/RegionQualifier.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // org.jetbrains.compose.resources/RegionQualifier.hashCode|hashCode(){}[0]
|
||||
final fun toString(): kotlin/String // org.jetbrains.compose.resources/RegionQualifier.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources/ResourceEnvironment { // org.jetbrains.compose.resources/ResourceEnvironment|null[0]
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // org.jetbrains.compose.resources/ResourceEnvironment.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // org.jetbrains.compose.resources/ResourceEnvironment.hashCode|hashCode(){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources/ResourceItem { // org.jetbrains.compose.resources/ResourceItem|null[0]
|
||||
constructor <init>(kotlin.collections/Set<org.jetbrains.compose.resources/Qualifier>, kotlin/String, kotlin/Long, kotlin/Long) // org.jetbrains.compose.resources/ResourceItem.<init>|<init>(kotlin.collections.Set<org.jetbrains.compose.resources.Qualifier>;kotlin.String;kotlin.Long;kotlin.Long){}[0]
|
||||
|
||||
final fun copy(kotlin.collections/Set<org.jetbrains.compose.resources/Qualifier> = ..., kotlin/String = ..., kotlin/Long = ..., kotlin/Long = ...): org.jetbrains.compose.resources/ResourceItem // org.jetbrains.compose.resources/ResourceItem.copy|copy(kotlin.collections.Set<org.jetbrains.compose.resources.Qualifier>;kotlin.String;kotlin.Long;kotlin.Long){}[0]
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // org.jetbrains.compose.resources/ResourceItem.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // org.jetbrains.compose.resources/ResourceItem.hashCode|hashCode(){}[0]
|
||||
final fun toString(): kotlin/String // org.jetbrains.compose.resources/ResourceItem.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources/ScriptQualifier : org.jetbrains.compose.resources/Qualifier { // org.jetbrains.compose.resources/ScriptQualifier|null[0]
|
||||
constructor <init>(kotlin/String) // org.jetbrains.compose.resources/ScriptQualifier.<init>|<init>(kotlin.String){}[0]
|
||||
|
||||
final val script // org.jetbrains.compose.resources/ScriptQualifier.script|{}script[0]
|
||||
final fun <get-script>(): kotlin/String // org.jetbrains.compose.resources/ScriptQualifier.script.<get-script>|<get-script>(){}[0]
|
||||
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // org.jetbrains.compose.resources/ScriptQualifier.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // org.jetbrains.compose.resources/ScriptQualifier.hashCode|hashCode(){}[0]
|
||||
final fun isEmpty(): kotlin/Boolean // org.jetbrains.compose.resources/ScriptQualifier.isEmpty|isEmpty(){}[0]
|
||||
final fun toString(): kotlin/String // org.jetbrains.compose.resources/ScriptQualifier.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources/StringArrayResource : org.jetbrains.compose.resources/Resource { // org.jetbrains.compose.resources/StringArrayResource|null[0]
|
||||
constructor <init>(kotlin/String, kotlin/String, kotlin.collections/Set<org.jetbrains.compose.resources/ResourceItem>) // org.jetbrains.compose.resources/StringArrayResource.<init>|<init>(kotlin.String;kotlin.String;kotlin.collections.Set<org.jetbrains.compose.resources.ResourceItem>){}[0]
|
||||
|
||||
final val key // org.jetbrains.compose.resources/StringArrayResource.key|{}key[0]
|
||||
final fun <get-key>(): kotlin/String // org.jetbrains.compose.resources/StringArrayResource.key.<get-key>|<get-key>(){}[0]
|
||||
}
|
||||
|
||||
final class org.jetbrains.compose.resources/StringResource : org.jetbrains.compose.resources/Resource { // org.jetbrains.compose.resources/StringResource|null[0]
|
||||
constructor <init>(kotlin/String, kotlin/String, kotlin.collections/Set<org.jetbrains.compose.resources/ResourceItem>) // org.jetbrains.compose.resources/StringResource.<init>|<init>(kotlin.String;kotlin.String;kotlin.collections.Set<org.jetbrains.compose.resources.ResourceItem>){}[0]
|
||||
|
||||
final val key // org.jetbrains.compose.resources/StringResource.key|{}key[0]
|
||||
final fun <get-key>(): kotlin/String // org.jetbrains.compose.resources/StringResource.key.<get-key>|<get-key>(){}[0]
|
||||
}
|
||||
|
||||
sealed class org.jetbrains.compose.resources/Resource { // org.jetbrains.compose.resources/Resource|null[0]
|
||||
open fun equals(kotlin/Any?): kotlin/Boolean // org.jetbrains.compose.resources/Resource.equals|equals(kotlin.Any?){}[0]
|
||||
open fun hashCode(): kotlin/Int // org.jetbrains.compose.resources/Resource.hashCode|hashCode(){}[0]
|
||||
}
|
||||
|
||||
final object org.jetbrains.compose.resources/ResourceCaches // org.jetbrains.compose.resources/ResourceCaches|null[0]
|
||||
|
||||
final val org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_And$stableprop // org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_And$stableprop|#static{}org_jetbrains_compose_resources_plural_PluralRule_Condition_And$stableprop[0]
|
||||
final val org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_Or$stableprop // org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_Or$stableprop|#static{}org_jetbrains_compose_resources_plural_PluralRule_Condition_Or$stableprop[0]
|
||||
final val org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_Relation$stableprop // org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_Relation$stableprop|#static{}org_jetbrains_compose_resources_plural_PluralRule_Condition_Relation$stableprop[0]
|
||||
final val org.jetbrains.compose.resources.vector.xmldom/org_jetbrains_compose_resources_vector_xmldom_MalformedXMLException$stableprop // org.jetbrains.compose.resources.vector.xmldom/org_jetbrains_compose_resources_vector_xmldom_MalformedXMLException$stableprop|#static{}org_jetbrains_compose_resources_vector_xmldom_MalformedXMLException$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/LocalResourceReader // org.jetbrains.compose.resources/LocalResourceReader|{}LocalResourceReader[0]
|
||||
final fun <get-LocalResourceReader>(): androidx.compose.runtime/ProvidableCompositionLocal<org.jetbrains.compose.resources/ResourceReader> // org.jetbrains.compose.resources/LocalResourceReader.<get-LocalResourceReader>|<get-LocalResourceReader>(){}[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_DrawableResource$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_DrawableResource$stableprop|#static{}org_jetbrains_compose_resources_DrawableResource$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_FontResource$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_FontResource$stableprop|#static{}org_jetbrains_compose_resources_FontResource$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Bitmap$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Bitmap$stableprop|#static{}org_jetbrains_compose_resources_ImageCache_Bitmap$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Svg$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Svg$stableprop|#static{}org_jetbrains_compose_resources_ImageCache_Svg$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Vector$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Vector$stableprop|#static{}org_jetbrains_compose_resources_ImageCache_Vector$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_LanguageQualifier$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_LanguageQualifier$stableprop|#static{}org_jetbrains_compose_resources_LanguageQualifier$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_MissingResourceException$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_MissingResourceException$stableprop|#static{}org_jetbrains_compose_resources_MissingResourceException$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_PluralStringResource$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_PluralStringResource$stableprop|#static{}org_jetbrains_compose_resources_PluralStringResource$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_RegionQualifier$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_RegionQualifier$stableprop|#static{}org_jetbrains_compose_resources_RegionQualifier$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_Resource$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_Resource$stableprop|#static{}org_jetbrains_compose_resources_Resource$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceCaches$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceCaches$stableprop|#static{}org_jetbrains_compose_resources_ResourceCaches$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceEnvironment$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceEnvironment$stableprop|#static{}org_jetbrains_compose_resources_ResourceEnvironment$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceItem$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceItem$stableprop|#static{}org_jetbrains_compose_resources_ResourceItem$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_ScriptQualifier$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ScriptQualifier$stableprop|#static{}org_jetbrains_compose_resources_ScriptQualifier$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringArrayResource$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringArrayResource$stableprop|#static{}org_jetbrains_compose_resources_StringArrayResource$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Array$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Array$stableprop|#static{}org_jetbrains_compose_resources_StringItem_Array$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Plurals$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Plurals$stableprop|#static{}org_jetbrains_compose_resources_StringItem_Plurals$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Value$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Value$stableprop|#static{}org_jetbrains_compose_resources_StringItem_Value$stableprop[0]
|
||||
final val org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringResource$stableprop // org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringResource$stableprop|#static{}org_jetbrains_compose_resources_StringResource$stableprop[0]
|
||||
|
||||
final fun (kotlin/ByteArray).org.jetbrains.compose.resources/decodeToImageBitmap(): androidx.compose.ui.graphics/ImageBitmap // org.jetbrains.compose.resources/decodeToImageBitmap|decodeToImageBitmap@kotlin.ByteArray(){}[0]
|
||||
final fun (kotlin/ByteArray).org.jetbrains.compose.resources/decodeToImageVector(androidx.compose.ui.unit/Density): androidx.compose.ui.graphics.vector/ImageVector // org.jetbrains.compose.resources/decodeToImageVector|decodeToImageVector@kotlin.ByteArray(androidx.compose.ui.unit.Density){}[0]
|
||||
final fun (kotlin/ByteArray).org.jetbrains.compose.resources/decodeToSvgPainter(androidx.compose.ui.unit/Density): androidx.compose.ui.graphics.painter/Painter // org.jetbrains.compose.resources/decodeToSvgPainter|decodeToSvgPainter@kotlin.ByteArray(androidx.compose.ui.unit.Density){}[0]
|
||||
final fun org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_And$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_And$stableprop_getter|org_jetbrains_compose_resources_plural_PluralRule_Condition_And$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_Or$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_Or$stableprop_getter|org_jetbrains_compose_resources_plural_PluralRule_Condition_Or$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_Relation$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources.plural/org_jetbrains_compose_resources_plural_PluralRule_Condition_Relation$stableprop_getter|org_jetbrains_compose_resources_plural_PluralRule_Condition_Relation$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources.vector.xmldom/org_jetbrains_compose_resources_vector_xmldom_MalformedXMLException$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources.vector.xmldom/org_jetbrains_compose_resources_vector_xmldom_MalformedXMLException$stableprop_getter|org_jetbrains_compose_resources_vector_xmldom_MalformedXMLException$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/Font(org.jetbrains.compose.resources/FontResource, androidx.compose.ui.text.font/FontWeight?, androidx.compose.ui.text.font/FontStyle, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.ui.text.font/Font // org.jetbrains.compose.resources/Font|Font(org.jetbrains.compose.resources.FontResource;androidx.compose.ui.text.font.FontWeight?;androidx.compose.ui.text.font.FontStyle;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
|
||||
final fun org.jetbrains.compose.resources/Font(org.jetbrains.compose.resources/FontResource, androidx.compose.ui.text.font/FontWeight?, androidx.compose.ui.text.font/FontStyle, androidx.compose.ui.text.font/FontVariation.Settings?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.ui.text.font/Font // org.jetbrains.compose.resources/Font|Font(org.jetbrains.compose.resources.FontResource;androidx.compose.ui.text.font.FontWeight?;androidx.compose.ui.text.font.FontStyle;androidx.compose.ui.text.font.FontVariation.Settings?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
|
||||
final fun org.jetbrains.compose.resources/getResourceUri(kotlin/String): kotlin/String // org.jetbrains.compose.resources/getResourceUri|getResourceUri(kotlin.String){}[0]
|
||||
final fun org.jetbrains.compose.resources/getSystemResourceEnvironment(): org.jetbrains.compose.resources/ResourceEnvironment // org.jetbrains.compose.resources/getSystemResourceEnvironment|getSystemResourceEnvironment(){}[0]
|
||||
final fun org.jetbrains.compose.resources/imageResource(org.jetbrains.compose.resources/DrawableResource, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.ui.graphics/ImageBitmap // org.jetbrains.compose.resources/imageResource|imageResource(org.jetbrains.compose.resources.DrawableResource;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_DrawableResource$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_DrawableResource$stableprop_getter|org_jetbrains_compose_resources_DrawableResource$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_FontResource$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_FontResource$stableprop_getter|org_jetbrains_compose_resources_FontResource$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Bitmap$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Bitmap$stableprop_getter|org_jetbrains_compose_resources_ImageCache_Bitmap$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Svg$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Svg$stableprop_getter|org_jetbrains_compose_resources_ImageCache_Svg$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Vector$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ImageCache_Vector$stableprop_getter|org_jetbrains_compose_resources_ImageCache_Vector$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_LanguageQualifier$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_LanguageQualifier$stableprop_getter|org_jetbrains_compose_resources_LanguageQualifier$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_MissingResourceException$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_MissingResourceException$stableprop_getter|org_jetbrains_compose_resources_MissingResourceException$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_PluralStringResource$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_PluralStringResource$stableprop_getter|org_jetbrains_compose_resources_PluralStringResource$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_RegionQualifier$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_RegionQualifier$stableprop_getter|org_jetbrains_compose_resources_RegionQualifier$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_Resource$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_Resource$stableprop_getter|org_jetbrains_compose_resources_Resource$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceCaches$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceCaches$stableprop_getter|org_jetbrains_compose_resources_ResourceCaches$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceEnvironment$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceEnvironment$stableprop_getter|org_jetbrains_compose_resources_ResourceEnvironment$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceItem$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ResourceItem$stableprop_getter|org_jetbrains_compose_resources_ResourceItem$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_ScriptQualifier$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_ScriptQualifier$stableprop_getter|org_jetbrains_compose_resources_ScriptQualifier$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringArrayResource$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringArrayResource$stableprop_getter|org_jetbrains_compose_resources_StringArrayResource$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Array$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Array$stableprop_getter|org_jetbrains_compose_resources_StringItem_Array$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Plurals$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Plurals$stableprop_getter|org_jetbrains_compose_resources_StringItem_Plurals$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Value$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringItem_Value$stableprop_getter|org_jetbrains_compose_resources_StringItem_Value$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringResource$stableprop_getter(): kotlin/Int // org.jetbrains.compose.resources/org_jetbrains_compose_resources_StringResource$stableprop_getter|org_jetbrains_compose_resources_StringResource$stableprop_getter(){}[0]
|
||||
final fun org.jetbrains.compose.resources/painterResource(org.jetbrains.compose.resources/DrawableResource, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.ui.graphics.painter/Painter // org.jetbrains.compose.resources/painterResource|painterResource(org.jetbrains.compose.resources.DrawableResource;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun org.jetbrains.compose.resources/pluralStringResource(org.jetbrains.compose.resources/PluralStringResource, kotlin/Int, androidx.compose.runtime/Composer?, kotlin/Int): kotlin/String // org.jetbrains.compose.resources/pluralStringResource|pluralStringResource(org.jetbrains.compose.resources.PluralStringResource;kotlin.Int;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun org.jetbrains.compose.resources/pluralStringResource(org.jetbrains.compose.resources/PluralStringResource, kotlin/Int, kotlin/Array<out kotlin/Any>..., androidx.compose.runtime/Composer?, kotlin/Int): kotlin/String // org.jetbrains.compose.resources/pluralStringResource|pluralStringResource(org.jetbrains.compose.resources.PluralStringResource;kotlin.Int;kotlin.Array<out|kotlin.Any>...;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun org.jetbrains.compose.resources/rememberResourceEnvironment(androidx.compose.runtime/Composer?, kotlin/Int): org.jetbrains.compose.resources/ResourceEnvironment // org.jetbrains.compose.resources/rememberResourceEnvironment|rememberResourceEnvironment(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun org.jetbrains.compose.resources/stringArrayResource(org.jetbrains.compose.resources/StringArrayResource, androidx.compose.runtime/Composer?, kotlin/Int): kotlin.collections/List<kotlin/String> // org.jetbrains.compose.resources/stringArrayResource|stringArrayResource(org.jetbrains.compose.resources.StringArrayResource;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun org.jetbrains.compose.resources/stringResource(org.jetbrains.compose.resources/StringResource, androidx.compose.runtime/Composer?, kotlin/Int): kotlin/String // org.jetbrains.compose.resources/stringResource|stringResource(org.jetbrains.compose.resources.StringResource;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun org.jetbrains.compose.resources/stringResource(org.jetbrains.compose.resources/StringResource, kotlin/Array<out kotlin/Any>..., androidx.compose.runtime/Composer?, kotlin/Int): kotlin/String // org.jetbrains.compose.resources/stringResource|stringResource(org.jetbrains.compose.resources.StringResource;kotlin.Array<out|kotlin.Any>...;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun org.jetbrains.compose.resources/vectorResource(org.jetbrains.compose.resources/DrawableResource, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.ui.graphics.vector/ImageVector // org.jetbrains.compose.resources/vectorResource|vectorResource(org.jetbrains.compose.resources.DrawableResource;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getDrawableResourceBytes(org.jetbrains.compose.resources/ResourceEnvironment, org.jetbrains.compose.resources/DrawableResource): kotlin/ByteArray // org.jetbrains.compose.resources/getDrawableResourceBytes|getDrawableResourceBytes(org.jetbrains.compose.resources.ResourceEnvironment;org.jetbrains.compose.resources.DrawableResource){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getFontResourceBytes(org.jetbrains.compose.resources/ResourceEnvironment, org.jetbrains.compose.resources/FontResource): kotlin/ByteArray // org.jetbrains.compose.resources/getFontResourceBytes|getFontResourceBytes(org.jetbrains.compose.resources.ResourceEnvironment;org.jetbrains.compose.resources.FontResource){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getPluralString(org.jetbrains.compose.resources/PluralStringResource, kotlin/Int): kotlin/String // org.jetbrains.compose.resources/getPluralString|getPluralString(org.jetbrains.compose.resources.PluralStringResource;kotlin.Int){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getPluralString(org.jetbrains.compose.resources/PluralStringResource, kotlin/Int, kotlin/Array<out kotlin/Any>...): kotlin/String // org.jetbrains.compose.resources/getPluralString|getPluralString(org.jetbrains.compose.resources.PluralStringResource;kotlin.Int;kotlin.Array<out|kotlin.Any>...){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getPluralString(org.jetbrains.compose.resources/ResourceEnvironment, org.jetbrains.compose.resources/PluralStringResource, kotlin/Int): kotlin/String // org.jetbrains.compose.resources/getPluralString|getPluralString(org.jetbrains.compose.resources.ResourceEnvironment;org.jetbrains.compose.resources.PluralStringResource;kotlin.Int){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getPluralString(org.jetbrains.compose.resources/ResourceEnvironment, org.jetbrains.compose.resources/PluralStringResource, kotlin/Int, kotlin/Array<out kotlin/Any>...): kotlin/String // org.jetbrains.compose.resources/getPluralString|getPluralString(org.jetbrains.compose.resources.ResourceEnvironment;org.jetbrains.compose.resources.PluralStringResource;kotlin.Int;kotlin.Array<out|kotlin.Any>...){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getString(org.jetbrains.compose.resources/ResourceEnvironment, org.jetbrains.compose.resources/StringResource): kotlin/String // org.jetbrains.compose.resources/getString|getString(org.jetbrains.compose.resources.ResourceEnvironment;org.jetbrains.compose.resources.StringResource){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getString(org.jetbrains.compose.resources/ResourceEnvironment, org.jetbrains.compose.resources/StringResource, kotlin/Array<out kotlin/Any>...): kotlin/String // org.jetbrains.compose.resources/getString|getString(org.jetbrains.compose.resources.ResourceEnvironment;org.jetbrains.compose.resources.StringResource;kotlin.Array<out|kotlin.Any>...){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getString(org.jetbrains.compose.resources/StringResource): kotlin/String // org.jetbrains.compose.resources/getString|getString(org.jetbrains.compose.resources.StringResource){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getString(org.jetbrains.compose.resources/StringResource, kotlin/Array<out kotlin/Any>...): kotlin/String // org.jetbrains.compose.resources/getString|getString(org.jetbrains.compose.resources.StringResource;kotlin.Array<out|kotlin.Any>...){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getStringArray(org.jetbrains.compose.resources/ResourceEnvironment, org.jetbrains.compose.resources/StringArrayResource): kotlin.collections/List<kotlin/String> // org.jetbrains.compose.resources/getStringArray|getStringArray(org.jetbrains.compose.resources.ResourceEnvironment;org.jetbrains.compose.resources.StringArrayResource){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/getStringArray(org.jetbrains.compose.resources/StringArrayResource): kotlin.collections/List<kotlin/String> // org.jetbrains.compose.resources/getStringArray|getStringArray(org.jetbrains.compose.resources.StringArrayResource){}[0]
|
||||
final suspend fun org.jetbrains.compose.resources/readResourceBytes(kotlin/String): kotlin/ByteArray // org.jetbrains.compose.resources/readResourceBytes|readResourceBytes(kotlin.String){}[0]
|
||||
+2
-2
@@ -21,7 +21,7 @@ import com.compose.sdl.graphics.decodeEncodedImageBitmap
|
||||
drawables ship at a single density, so no decode-time rescale applies. */
|
||||
internal actual fun ByteArray.toImageBitmap(resourceDensity: Int, targetDensity: Int): ImageBitmap =
|
||||
decodeEncodedImageBitmap(this)
|
||||
?: error("Image decode failed — is the SDL renderer initialised before painterResource ran?")
|
||||
?: error("Image decode failed — is the render backend initialised before painterResource ran?")
|
||||
|
||||
/* SVG on SDL: SDL3_image rasterises SVG at its intrinsic size (IMG_LoadSVG),
|
||||
so the "element" is just the raw bytes and the painter is the rasterised
|
||||
@@ -34,5 +34,5 @@ internal actual fun ByteArray.toSvgElement(): SvgElement = SvgElement(this)
|
||||
internal actual fun SvgElement.toSvgPainter(density: Density): Painter =
|
||||
BitmapPainter(
|
||||
decodeEncodedImageBitmap(bytes)
|
||||
?: error("SVG rasterisation failed — is the SDL renderer initialised before painterResource ran?")
|
||||
?: error("SVG rasterisation failed — is the render backend initialised before painterResource ran?")
|
||||
)
|
||||
|
||||
@@ -2078,17 +2078,6 @@ final object com.compose.sdl.icons/IconDefaults { // com.compose.sdl.icons/IconD
|
||||
final fun <get-LocalContentColor>(): androidx.compose.ui.graphics/Color // com.compose.sdl.icons/IconDefaults.LocalContentColor.<get-LocalContentColor>|<get-LocalContentColor>(){}[0]
|
||||
}
|
||||
|
||||
final object com.compose.sdl.icons/MaterialIconAxisDefaults { // com.compose.sdl.icons/MaterialIconAxisDefaults|null[0]
|
||||
final const val Fill // com.compose.sdl.icons/MaterialIconAxisDefaults.Fill|{}Fill[0]
|
||||
final fun <get-Fill>(): kotlin/Float // com.compose.sdl.icons/MaterialIconAxisDefaults.Fill.<get-Fill>|<get-Fill>(){}[0]
|
||||
final const val Grade // com.compose.sdl.icons/MaterialIconAxisDefaults.Grade|{}Grade[0]
|
||||
final fun <get-Grade>(): kotlin/Int // com.compose.sdl.icons/MaterialIconAxisDefaults.Grade.<get-Grade>|<get-Grade>(){}[0]
|
||||
final const val OpticalSize // com.compose.sdl.icons/MaterialIconAxisDefaults.OpticalSize|{}OpticalSize[0]
|
||||
final fun <get-OpticalSize>(): kotlin/Int // com.compose.sdl.icons/MaterialIconAxisDefaults.OpticalSize.<get-OpticalSize>|<get-OpticalSize>(){}[0]
|
||||
final const val Weight // com.compose.sdl.icons/MaterialIconAxisDefaults.Weight|{}Weight[0]
|
||||
final fun <get-Weight>(): kotlin/Int // com.compose.sdl.icons/MaterialIconAxisDefaults.Weight.<get-Weight>|<get-Weight>(){}[0]
|
||||
}
|
||||
|
||||
final object com.compose.sdl.widgets/SplitPaneDefaults { // com.compose.sdl.widgets/SplitPaneDefaults|null[0]
|
||||
final val DividerThickness // com.compose.sdl.widgets/SplitPaneDefaults.DividerThickness|{}DividerThickness[0]
|
||||
final fun <get-DividerThickness>(): androidx.compose.ui.unit/Dp // com.compose.sdl.widgets/SplitPaneDefaults.DividerThickness.<get-DividerThickness>|<get-DividerThickness>(){}[0]
|
||||
@@ -2220,7 +2209,6 @@ final val androidx.compose.foundation/androidx_compose_foundation_MarqueeDefault
|
||||
final val androidx.compose.foundation/androidx_compose_foundation_MutatorMutex$stableprop // androidx.compose.foundation/androidx_compose_foundation_MutatorMutex$stableprop|#static{}androidx_compose_foundation_MutatorMutex$stableprop[0]
|
||||
final val androidx.compose.foundation/androidx_compose_foundation_ScrollState$stableprop // androidx.compose.foundation/androidx_compose_foundation_ScrollState$stableprop|#static{}androidx_compose_foundation_ScrollState$stableprop[0]
|
||||
final val com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop // com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop|#static{}com_compose_sdl_icons_IconDefaults$stableprop[0]
|
||||
final val com.compose.sdl.icons/com_compose_sdl_icons_MaterialIconAxisDefaults$stableprop // com.compose.sdl.icons/com_compose_sdl_icons_MaterialIconAxisDefaults$stableprop|#static{}com_compose_sdl_icons_MaterialIconAxisDefaults$stableprop[0]
|
||||
final val com.compose.sdl.scrollbar/LocalScrollbarStyle // com.compose.sdl.scrollbar/LocalScrollbarStyle|{}LocalScrollbarStyle[0]
|
||||
final fun <get-LocalScrollbarStyle>(): androidx.compose.runtime/ProvidableCompositionLocal<com.compose.sdl.scrollbar/ScrollbarStyle> // com.compose.sdl.scrollbar/LocalScrollbarStyle.<get-LocalScrollbarStyle>|<get-LocalScrollbarStyle>(){}[0]
|
||||
final val com.compose.sdl.scrollbar/com_compose_sdl_scrollbar_ScrollbarStyle$stableprop // com.compose.sdl.scrollbar/com_compose_sdl_scrollbar_ScrollbarStyle$stableprop|#static{}com_compose_sdl_scrollbar_ScrollbarStyle$stableprop[0]
|
||||
@@ -2294,6 +2282,8 @@ final fun (androidx.compose.ui.input.pointer/PointerEvent).androidx.compose.foun
|
||||
final fun (androidx.compose.ui.input.pointer/PointerEvent).androidx.compose.foundation.gestures/calculateZoom(): kotlin/Float // androidx.compose.foundation.gestures/calculateZoom|calculateZoom@androidx.compose.ui.input.pointer.PointerEvent(){}[0]
|
||||
final fun (androidx.compose.ui.text/AnnotatedString.Builder).androidx.compose.foundation.text/appendInlineContent(kotlin/String, kotlin/String = ...) // androidx.compose.foundation.text/appendInlineContent|appendInlineContent@androidx.compose.ui.text.AnnotatedString.Builder(kotlin.String;kotlin.String){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).androidx.compose.foundation.content/contentReceiver(androidx.compose.foundation.content/ReceiveContentListener): androidx.compose.ui/Modifier // androidx.compose.foundation.content/contentReceiver|contentReceiver@androidx.compose.ui.Modifier(androidx.compose.foundation.content.ReceiveContentListener){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).androidx.compose.foundation.draganddrop/dragAndDropSource(kotlin/Function1<androidx.compose.ui.geometry/Offset, androidx.compose.ui.draganddrop/DragAndDropTransferData?>): androidx.compose.ui/Modifier // androidx.compose.foundation.draganddrop/dragAndDropSource|dragAndDropSource@androidx.compose.ui.Modifier(kotlin.Function1<androidx.compose.ui.geometry.Offset,androidx.compose.ui.draganddrop.DragAndDropTransferData?>){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).androidx.compose.foundation.draganddrop/dragAndDropSource(kotlin/Function1<androidx.compose.ui.graphics.drawscope/DrawScope, kotlin/Unit>, kotlin/Function1<androidx.compose.ui.geometry/Offset, androidx.compose.ui.draganddrop/DragAndDropTransferData?>): androidx.compose.ui/Modifier // androidx.compose.foundation.draganddrop/dragAndDropSource|dragAndDropSource@androidx.compose.ui.Modifier(kotlin.Function1<androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit>;kotlin.Function1<androidx.compose.ui.geometry.Offset,androidx.compose.ui.draganddrop.DragAndDropTransferData?>){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).androidx.compose.foundation.draganddrop/dragAndDropTarget(kotlin/Function1<androidx.compose.ui.draganddrop/DragAndDropEvent, kotlin/Boolean>, androidx.compose.ui.draganddrop/DragAndDropTarget): androidx.compose.ui/Modifier // androidx.compose.foundation.draganddrop/dragAndDropTarget|dragAndDropTarget@androidx.compose.ui.Modifier(kotlin.Function1<androidx.compose.ui.draganddrop.DragAndDropEvent,kotlin.Boolean>;androidx.compose.ui.draganddrop.DragAndDropTarget){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).androidx.compose.foundation.gestures/draggable(androidx.compose.foundation.gestures/DraggableState, androidx.compose.foundation.gestures/Orientation, kotlin/Boolean = ..., androidx.compose.foundation.interaction/MutableInteractionSource? = ..., kotlin/Boolean = ..., kotlin.coroutines/SuspendFunction2<kotlinx.coroutines/CoroutineScope, androidx.compose.ui.geometry/Offset, kotlin/Unit> = ..., kotlin.coroutines/SuspendFunction2<kotlinx.coroutines/CoroutineScope, kotlin/Float, kotlin/Unit> = ..., kotlin/Boolean = ...): androidx.compose.ui/Modifier // androidx.compose.foundation.gestures/draggable|draggable@androidx.compose.ui.Modifier(androidx.compose.foundation.gestures.DraggableState;androidx.compose.foundation.gestures.Orientation;kotlin.Boolean;androidx.compose.foundation.interaction.MutableInteractionSource?;kotlin.Boolean;kotlin.coroutines.SuspendFunction2<kotlinx.coroutines.CoroutineScope,androidx.compose.ui.geometry.Offset,kotlin.Unit>;kotlin.coroutines.SuspendFunction2<kotlinx.coroutines.CoroutineScope,kotlin.Float,kotlin.Unit>;kotlin.Boolean){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).androidx.compose.foundation.gestures/draggable2D(androidx.compose.foundation.gestures/Draggable2DState, kotlin/Boolean = ..., androidx.compose.foundation.interaction/MutableInteractionSource? = ..., kotlin/Boolean = ..., kotlin/Function1<androidx.compose.ui.geometry/Offset, kotlin/Unit> = ..., kotlin/Function1<androidx.compose.ui.unit/Velocity, kotlin/Unit> = ..., kotlin/Boolean = ...): androidx.compose.ui/Modifier // androidx.compose.foundation.gestures/draggable2D|draggable2D@androidx.compose.ui.Modifier(androidx.compose.foundation.gestures.Draggable2DState;kotlin.Boolean;androidx.compose.foundation.interaction.MutableInteractionSource?;kotlin.Boolean;kotlin.Function1<androidx.compose.ui.geometry.Offset,kotlin.Unit>;kotlin.Function1<androidx.compose.ui.unit.Velocity,kotlin.Unit>;kotlin.Boolean){}[0]
|
||||
@@ -2620,14 +2610,13 @@ final fun androidx.compose.foundation/rememberBasicTooltipState(kotlin/Boolean,
|
||||
final fun androidx.compose.foundation/rememberOverscrollEffect(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation/OverscrollEffect? // androidx.compose.foundation/rememberOverscrollEffect|rememberOverscrollEffect(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun androidx.compose.foundation/rememberScrollState(kotlin/Int, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation/ScrollState // androidx.compose.foundation/rememberScrollState|rememberScrollState(kotlin.Int;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
|
||||
final fun com.compose.sdl.icons/IconFontIcon(kotlin/Int, kotlin/String, kotlin/String?, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics/Color, androidx.compose.ui.unit/Dp, kotlin.collections/List<androidx.compose.ui.text.font/FontVariation.Setting>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.icons/IconFontIcon|IconFontIcon(kotlin.Int;kotlin.String;kotlin.String?;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.Color;androidx.compose.ui.unit.Dp;kotlin.collections.List<androidx.compose.ui.text.font.FontVariation.Setting>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
|
||||
final fun com.compose.sdl.icons/MaterialIconAxes(kotlin/Float = ..., kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ...): kotlin.collections/List<androidx.compose.ui.text.font/FontVariation.Setting> // com.compose.sdl.icons/MaterialIconAxes|MaterialIconAxes(kotlin.Float;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
|
||||
final fun com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop_getter(): kotlin/Int // com.compose.sdl.icons/com_compose_sdl_icons_IconDefaults$stableprop_getter|com_compose_sdl_icons_IconDefaults$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.icons/com_compose_sdl_icons_MaterialIconAxisDefaults$stableprop_getter(): kotlin/Int // com.compose.sdl.icons/com_compose_sdl_icons_MaterialIconAxisDefaults$stableprop_getter|com_compose_sdl_icons_MaterialIconAxisDefaults$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.modifier/rememberMutableInteractionSource(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.foundation.interaction/MutableInteractionSource // com.compose.sdl.modifier/rememberMutableInteractionSource|rememberMutableInteractionSource(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun com.compose.sdl.scrollbar/HorizontalScrollbar(com.compose.sdl.scrollbar/ScrollbarAdapter, androidx.compose.ui/Modifier?, kotlin/Boolean, com.compose.sdl.scrollbar/ScrollbarStyle?, androidx.compose.foundation.interaction/MutableInteractionSource?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.scrollbar/HorizontalScrollbar|HorizontalScrollbar(com.compose.sdl.scrollbar.ScrollbarAdapter;androidx.compose.ui.Modifier?;kotlin.Boolean;com.compose.sdl.scrollbar.ScrollbarStyle?;androidx.compose.foundation.interaction.MutableInteractionSource?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
|
||||
final fun com.compose.sdl.scrollbar/VerticalScrollbar(com.compose.sdl.scrollbar/ScrollbarAdapter, androidx.compose.ui/Modifier?, kotlin/Boolean, com.compose.sdl.scrollbar/ScrollbarStyle?, androidx.compose.foundation.interaction/MutableInteractionSource?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.scrollbar/VerticalScrollbar|VerticalScrollbar(com.compose.sdl.scrollbar.ScrollbarAdapter;androidx.compose.ui.Modifier?;kotlin.Boolean;com.compose.sdl.scrollbar.ScrollbarStyle?;androidx.compose.foundation.interaction.MutableInteractionSource?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
|
||||
final fun com.compose.sdl.scrollbar/com_compose_sdl_scrollbar_ScrollbarStyle$stableprop_getter(): kotlin/Int // com.compose.sdl.scrollbar/com_compose_sdl_scrollbar_ScrollbarStyle$stableprop_getter|com_compose_sdl_scrollbar_ScrollbarStyle$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.scrollbar/defaultScrollbarStyle(): com.compose.sdl.scrollbar/ScrollbarStyle // com.compose.sdl.scrollbar/defaultScrollbarStyle|defaultScrollbarStyle(){}[0]
|
||||
final fun com.compose.sdl.scrollbar/rememberScrollbarAdapter(androidx.compose.foundation.lazy/LazyListState, androidx.compose.runtime/Composer?, kotlin/Int): com.compose.sdl.scrollbar/ScrollbarAdapter // com.compose.sdl.scrollbar/rememberScrollbarAdapter|rememberScrollbarAdapter(androidx.compose.foundation.lazy.LazyListState;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun com.compose.sdl.scrollbar/rememberScrollbarAdapter(androidx.compose.foundation/ScrollState, androidx.compose.runtime/Composer?, kotlin/Int): com.compose.sdl.scrollbar/ScrollbarAdapter // com.compose.sdl.scrollbar/rememberScrollbarAdapter|rememberScrollbarAdapter(androidx.compose.foundation.ScrollState;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun com.compose.sdl.text/IconText(kotlin/String, kotlin/String, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics/Color, androidx.compose.ui.unit/TextUnit, androidx.compose.ui.text.style/TextAlign, kotlin.collections/List<androidx.compose.ui.text.font/FontVariation.Setting>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.text/IconText|IconText(kotlin.String;kotlin.String;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.Color;androidx.compose.ui.unit.TextUnit;androidx.compose.ui.text.style.TextAlign;kotlin.collections.List<androidx.compose.ui.text.font.FontVariation.Setting>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
|
||||
final fun com.compose.sdl.text/IconText(kotlin/String, kotlin/String, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics/Color, androidx.compose.ui.unit/TextUnit, androidx.compose.ui.text.style/TextAlign?, kotlin.collections/List<androidx.compose.ui.text.font/FontVariation.Setting>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.compose.sdl.text/IconText|IconText(kotlin.String;kotlin.String;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.Color;androidx.compose.ui.unit.TextUnit;androidx.compose.ui.text.style.TextAlign?;kotlin.collections.List<androidx.compose.ui.text.font.FontVariation.Setting>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
|
||||
|
||||
+83
-32
@@ -30,9 +30,12 @@ import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.foundation.gestures.detectDragGestures
|
||||
import androidx.compose.foundation.gestures.awaitEachGesture
|
||||
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||
import androidx.compose.foundation.gestures.scrollBy
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
// ==================
|
||||
@@ -141,6 +144,19 @@ private class LazyListScrollbarAdapter(private val state: LazyListState) : Scrol
|
||||
get() = (state.layoutInfo.viewportEndOffset - state.layoutInfo.viewportStartOffset).toDouble()
|
||||
|
||||
override suspend fun scrollTo(scrollOffset: Double) {
|
||||
val vDistance = scrollOffset - this.scrollOffset
|
||||
// Within a viewport, scroll by EXACT pixels so a drag stays smooth. A lazy
|
||||
// list's pixel geometry is only ESTIMATED (average visible item size), and
|
||||
// that estimate drifts as differently-sized items scroll through the
|
||||
// viewport — so index-snapping every frame makes the thumb jump. scrollBy
|
||||
// sidesteps the estimate entirely. This is what Compose Desktop's own
|
||||
// LazyListScrollbarAdapter does, and for the same reason.
|
||||
if (abs(vDistance) <= viewportSize) {
|
||||
state.scrollBy(vDistance.toFloat())
|
||||
return
|
||||
}
|
||||
// Far jump (track-click paging past a viewport): no exact geometry to lean
|
||||
// on, so estimate an index/offset from the average and snap to it.
|
||||
val vAvg = averageItemSize()
|
||||
if (vAvg <= 0.0) return
|
||||
val vTarget = scrollOffset.coerceAtLeast(0.0)
|
||||
@@ -193,7 +209,6 @@ private fun Scrollbar(
|
||||
val vHoverSource = remember { MutableInteractionSource() }
|
||||
val vHovered by vHoverSource.collectIsHoveredAsState()
|
||||
var vDraggingThumb by remember { mutableStateOf(false) }
|
||||
var vGrab by remember { mutableStateOf(0) }
|
||||
// onSizeChanged reports PHYSICAL pixels (Option-B density flow), so every
|
||||
// int/px carried through here — vTrackPx, vThumbLen, vThumbPos — is in
|
||||
// physical pixels. Passing them into `.dp` doubles again through
|
||||
@@ -230,15 +245,6 @@ private fun Scrollbar(
|
||||
val vRawPos = if (vTravel <= 0) 0 else (vTravel * (vOffset / vMaxScroll)).roundToInt()
|
||||
val vThumbPos = (if (reverseLayout) vTravel - vRawPos else vRawPos).coerceIn(0, vTravel)
|
||||
|
||||
// ============
|
||||
// Map a track-relative position to a scroll offset and apply it.
|
||||
fun scrollToTrackPos(inThumbTop: Int) {
|
||||
if (vTravel <= 0) return
|
||||
val vPos = inThumbTop.coerceIn(0, vTravel)
|
||||
val vFrac = (if (reverseLayout) vTravel - vPos else vPos).toDouble() / vTravel
|
||||
vScope.launch { adapter.scrollTo(vFrac * vMaxScroll) }
|
||||
}
|
||||
|
||||
val vThumbLenDp = with(vDensity) { vThumbLen.toDp() }
|
||||
val vThumbMod = (
|
||||
if (isVertical) Modifier.offset { IntOffset(0, vThumbPos) }.width(style.thickness).height(vThumbLenDp)
|
||||
@@ -251,33 +257,78 @@ private fun Scrollbar(
|
||||
|
||||
// ============
|
||||
// Drag the thumb / page on track click — handled on the track so the
|
||||
// coordinates have a stable (non-moving) origin.
|
||||
// coordinates have a stable (non-moving) origin. The press is CONSUMED:
|
||||
// a scrollbar owns the pointer input it handles, so content sharing this
|
||||
// region (the scrollable beneath, or a parent that also reads pointer
|
||||
// input) never reacts to the same press. Geometry is read LIVE from the
|
||||
// adapter at press time — not from the captured render metrics above,
|
||||
// which go stale between pointerInput relaunches — so a grab after a
|
||||
// wheel-scroll still hit-tests against the thumb's current position.
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.matchTrackSize(isVertical, with(vDensity) { vTrackPx.toDp() }, style.thickness)
|
||||
.pointerInput(isVertical, adapter, vTrackPx) {
|
||||
detectDragGestures(
|
||||
onDragStart = { offset ->
|
||||
val vPress = (if (isVertical) offset.y else offset.x).toInt()
|
||||
if (vPress in vThumbPos..(vThumbPos + vThumbLen)) {
|
||||
vDraggingThumb = true
|
||||
vGrab = vPress - vThumbPos
|
||||
} else {
|
||||
// Page toward the click by one viewport.
|
||||
vDraggingThumb = false
|
||||
val vDir = if (vPress < vThumbPos) -1.0 else 1.0
|
||||
vScope.launch { adapter.scrollTo(vOffset + vDir * vViewport) }
|
||||
}
|
||||
},
|
||||
onDrag = { change, _ ->
|
||||
.pointerInput(isVertical, adapter, vTrackPx, reverseLayout) {
|
||||
awaitEachGesture {
|
||||
val vDown = awaitFirstDown(requireUnconsumed = false)
|
||||
vDown.consume()
|
||||
|
||||
// Live geometry — stable for the drag's duration (content /
|
||||
// viewport / track sizes don't change mid-drag).
|
||||
val vContentPx = adapter.contentSize
|
||||
val vViewportPx = adapter.viewportSize
|
||||
val vMaxScrollPx = vContentPx - vViewportPx
|
||||
if (vMaxScrollPx <= 0.0 || vTrackPx <= 0) return@awaitEachGesture
|
||||
val vMinLen = style.minimalHeight.value.toInt()
|
||||
val vLen = (vTrackPx * (vViewportPx / vContentPx)).roundToInt()
|
||||
.coerceIn(vMinLen.coerceAtMost(vTrackPx), vTrackPx)
|
||||
val vTravelPx = vTrackPx - vLen
|
||||
val vRaw = if (vTravelPx <= 0) 0
|
||||
else (vTravelPx * (adapter.scrollOffset / vMaxScrollPx)).roundToInt()
|
||||
val vPos = (if (reverseLayout) vTravelPx - vRaw else vRaw).coerceIn(0, vTravelPx)
|
||||
|
||||
// Map a track-relative thumb-top to a scroll offset. The
|
||||
// target uses the LIVE max scroll (read fresh each move),
|
||||
// not the press-time value — the adapter compares it against
|
||||
// its live scrollOffset, and mixing a stale scale with a live
|
||||
// one makes the delta run away (grab at the bottom, drag up,
|
||||
// and the list overshoots to the middle).
|
||||
fun scrollToTrackPos(inThumbTop: Int) {
|
||||
if (vTravelPx <= 0) return
|
||||
val vLiveMax = adapter.contentSize - adapter.viewportSize
|
||||
if (vLiveMax <= 0.0) return
|
||||
val vClamped = inThumbTop.coerceIn(0, vTravelPx)
|
||||
val vFrac = (if (reverseLayout) vTravelPx - vClamped else vClamped).toDouble() / vTravelPx
|
||||
vScope.launch { adapter.scrollTo(vFrac * vLiveMax) }
|
||||
}
|
||||
|
||||
val vPress = (if (isVertical) vDown.position.y else vDown.position.x).toInt()
|
||||
val vGrab: Int
|
||||
if (vPress in vPos..(vPos + vLen)) {
|
||||
vDraggingThumb = true
|
||||
vGrab = vPress - vPos
|
||||
} else {
|
||||
// Page toward the click by one viewport.
|
||||
vDraggingThumb = false
|
||||
vGrab = 0
|
||||
val vDir = if (vPress < vPos) -1.0 else 1.0
|
||||
vScope.launch { adapter.scrollTo(adapter.scrollOffset + vDir * vViewportPx) }
|
||||
}
|
||||
|
||||
// Follow the pressed pointer to release, consuming every
|
||||
// change so the interaction can't leak. Only a thumb grab
|
||||
// drags-to-scroll; a track press just consumes.
|
||||
do {
|
||||
val vEvent = awaitPointerEvent()
|
||||
val vChange = vEvent.changes.firstOrNull { it.id == vDown.id } ?: break
|
||||
if (vDraggingThumb) {
|
||||
val vCur = (if (isVertical) change.position.y else change.position.x).toInt()
|
||||
val vCur = (if (isVertical) vChange.position.y else vChange.position.x).toInt()
|
||||
scrollToTrackPos(vCur - vGrab)
|
||||
}
|
||||
},
|
||||
onDragEnd = { vDraggingThumb = false },
|
||||
onDragCancel = { vDraggingThumb = false },
|
||||
)
|
||||
vChange.consume()
|
||||
} while (vEvent.changes.any { it.id == vDown.id && it.pressed })
|
||||
|
||||
vDraggingThumb = false
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// Klib ABI Dump
|
||||
// Targets: [linuxArm64, linuxX64, macosArm64, mingwX64]
|
||||
// Rendering settings:
|
||||
// - Signature version: 2
|
||||
// - Show manifest properties: true
|
||||
// - Show declarations: true
|
||||
|
||||
// Library unique name: <com.bitsycore.compose.sdl:material-ripple>
|
||||
abstract interface androidx.compose.material.ripple/RippleTheme { // androidx.compose.material.ripple/RippleTheme|null[0]
|
||||
abstract fun defaultColor(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.ui.graphics/Color // androidx.compose.material.ripple/RippleTheme.defaultColor|defaultColor(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
abstract fun rippleAlpha(androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.material.ripple/RippleAlpha // androidx.compose.material.ripple/RippleTheme.rippleAlpha|rippleAlpha(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
|
||||
final object Companion { // androidx.compose.material.ripple/RippleTheme.Companion|null[0]
|
||||
final fun defaultRippleAlpha(androidx.compose.ui.graphics/Color, kotlin/Boolean): androidx.compose.material.ripple/RippleAlpha // androidx.compose.material.ripple/RippleTheme.Companion.defaultRippleAlpha|defaultRippleAlpha(androidx.compose.ui.graphics.Color;kotlin.Boolean){}[0]
|
||||
final fun defaultRippleColor(androidx.compose.ui.graphics/Color, kotlin/Boolean): androidx.compose.ui.graphics/Color // androidx.compose.material.ripple/RippleTheme.Companion.defaultRippleColor|defaultRippleColor(androidx.compose.ui.graphics.Color;kotlin.Boolean){}[0]
|
||||
}
|
||||
}
|
||||
|
||||
final class androidx.compose.material.ripple/RippleAlpha { // androidx.compose.material.ripple/RippleAlpha|null[0]
|
||||
constructor <init>(kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float) // androidx.compose.material.ripple/RippleAlpha.<init>|<init>(kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float){}[0]
|
||||
|
||||
final val draggedAlpha // androidx.compose.material.ripple/RippleAlpha.draggedAlpha|{}draggedAlpha[0]
|
||||
final fun <get-draggedAlpha>(): kotlin/Float // androidx.compose.material.ripple/RippleAlpha.draggedAlpha.<get-draggedAlpha>|<get-draggedAlpha>(){}[0]
|
||||
final val focusedAlpha // androidx.compose.material.ripple/RippleAlpha.focusedAlpha|{}focusedAlpha[0]
|
||||
final fun <get-focusedAlpha>(): kotlin/Float // androidx.compose.material.ripple/RippleAlpha.focusedAlpha.<get-focusedAlpha>|<get-focusedAlpha>(){}[0]
|
||||
final val hoveredAlpha // androidx.compose.material.ripple/RippleAlpha.hoveredAlpha|{}hoveredAlpha[0]
|
||||
final fun <get-hoveredAlpha>(): kotlin/Float // androidx.compose.material.ripple/RippleAlpha.hoveredAlpha.<get-hoveredAlpha>|<get-hoveredAlpha>(){}[0]
|
||||
final val pressedAlpha // androidx.compose.material.ripple/RippleAlpha.pressedAlpha|{}pressedAlpha[0]
|
||||
final fun <get-pressedAlpha>(): kotlin/Float // androidx.compose.material.ripple/RippleAlpha.pressedAlpha.<get-pressedAlpha>|<get-pressedAlpha>(){}[0]
|
||||
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // androidx.compose.material.ripple/RippleAlpha.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // androidx.compose.material.ripple/RippleAlpha.hashCode|hashCode(){}[0]
|
||||
final fun toString(): kotlin/String // androidx.compose.material.ripple/RippleAlpha.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final val androidx.compose.material.ripple/LocalRippleTheme // androidx.compose.material.ripple/LocalRippleTheme|{}LocalRippleTheme[0]
|
||||
final fun <get-LocalRippleTheme>(): androidx.compose.runtime/ProvidableCompositionLocal<androidx.compose.material.ripple/RippleTheme> // androidx.compose.material.ripple/LocalRippleTheme.<get-LocalRippleTheme>|<get-LocalRippleTheme>(){}[0]
|
||||
final val androidx.compose.material.ripple/androidx_compose_material_ripple_RippleAlpha$stableprop // androidx.compose.material.ripple/androidx_compose_material_ripple_RippleAlpha$stableprop|#static{}androidx_compose_material_ripple_RippleAlpha$stableprop[0]
|
||||
|
||||
final fun androidx.compose.material.ripple/androidx_compose_material_ripple_RippleAlpha$stableprop_getter(): kotlin/Int // androidx.compose.material.ripple/androidx_compose_material_ripple_RippleAlpha$stableprop_getter|androidx_compose_material_ripple_RippleAlpha$stableprop_getter(){}[0]
|
||||
final fun androidx.compose.material.ripple/createRippleModifierNode(androidx.compose.foundation.interaction/InteractionSource, kotlin/Boolean, androidx.compose.ui.unit/Dp, androidx.compose.ui.graphics/ColorProducer, kotlin/Function0<androidx.compose.material.ripple/RippleAlpha>): androidx.compose.ui.node/DelegatableNode // androidx.compose.material.ripple/createRippleModifierNode|createRippleModifierNode(androidx.compose.foundation.interaction.InteractionSource;kotlin.Boolean;androidx.compose.ui.unit.Dp;androidx.compose.ui.graphics.ColorProducer;kotlin.Function0<androidx.compose.material.ripple.RippleAlpha>){}[0]
|
||||
final fun androidx.compose.material.ripple/rememberRipple(kotlin/Boolean, androidx.compose.ui.unit/Dp, androidx.compose.ui.graphics/Color, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.foundation/Indication // androidx.compose.material.ripple/rememberRipple|rememberRipple(kotlin.Boolean;androidx.compose.ui.unit.Dp;androidx.compose.ui.graphics.Color;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -146,6 +146,8 @@ fun nativeComposeApp(content: @Composable ApplicationScope.() -> Unit) {
|
||||
|
||||
// ============
|
||||
// Main loop
|
||||
var vGcLastTicks = SDL_GetTicks()
|
||||
var vRenderedSinceGc = false
|
||||
while (!runtime.exitRequested) {
|
||||
Snapshot.sendApplyNotifications()
|
||||
|
||||
@@ -224,6 +226,23 @@ fun nativeComposeApp(content: @Composable ApplicationScope.() -> Unit) {
|
||||
SDL_WaitEventTimeout(null, 10)
|
||||
for (vW in runtime.windows) vW.resetFpsWindow()
|
||||
}
|
||||
|
||||
// ============
|
||||
// Native-memory nudge. Renderer resources (Skia surfaces / images /
|
||||
// fonts, SDL textures) are freed by Cleaners that only run when the
|
||||
// Kotlin/Native GC collects — and a Compose app's Kotlin heap is
|
||||
// small enough that the allocation-driven scheduler can starve them
|
||||
// for minutes while the NATIVE heap balloons (issue #2: memory
|
||||
// "never released" while navigating). Collect periodically, only
|
||||
// after rendering activity, between frames; costs ~ms at these
|
||||
// heap sizes and keeps RSS tracking real usage.
|
||||
if (vAnyRendered) vRenderedSinceGc = true
|
||||
val vNowTicks = SDL_GetTicks()
|
||||
if (vRenderedSinceGc && vNowTicks - vGcLastTicks >= 10_000uL) {
|
||||
vGcLastTicks = vNowTicks
|
||||
vRenderedSinceGc = false
|
||||
collectNativeGarbage()
|
||||
}
|
||||
}
|
||||
|
||||
// ============
|
||||
@@ -243,6 +262,11 @@ fun nativeComposeApp(content: @Composable ApplicationScope.() -> Unit) {
|
||||
SDL_Quit()
|
||||
}
|
||||
|
||||
/* Trigger a Kotlin/Native GC so Cleaner-managed renderer resources release
|
||||
their native memory (see the main loop's native-memory nudge). */
|
||||
@OptIn(kotlin.native.runtime.NativeRuntimeApi::class)
|
||||
private fun collectNativeGarbage() = kotlin.native.runtime.GC.collect()
|
||||
|
||||
/* Single-window compatibility wrapper — the pre-multi-window entry point.
|
||||
Closing the window exits the app, exactly as before. */
|
||||
fun nativeComposeWindow(
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
// Klib ABI Dump
|
||||
// Targets: [linuxArm64, linuxX64, macosArm64, mingwX64]
|
||||
// Rendering settings:
|
||||
// - Signature version: 2
|
||||
// - Show manifest properties: true
|
||||
// - Show declarations: true
|
||||
|
||||
// Library unique name: <com.bitsycore.compose.sdl:ui-tooling-preview>
|
||||
open annotation class androidx.compose.ui.tooling.preview/AndroidUiMode : kotlin/Annotation { // androidx.compose.ui.tooling.preview/AndroidUiMode|null[0]
|
||||
constructor <init>() // androidx.compose.ui.tooling.preview/AndroidUiMode.<init>|<init>(){}[0]
|
||||
}
|
||||
|
||||
open annotation class androidx.compose.ui.tooling.preview/Preview : kotlin/Annotation { // androidx.compose.ui.tooling.preview/Preview|null[0]
|
||||
constructor <init>(kotlin/String = ..., kotlin/String = ..., kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ..., kotlin/String = ..., kotlin/Float = ..., kotlin/Boolean = ..., kotlin/Boolean = ..., kotlin/Long = ..., kotlin/Int = ..., kotlin/String = ..., kotlin/Int = ...) // androidx.compose.ui.tooling.preview/Preview.<init>|<init>(kotlin.String;kotlin.String;kotlin.Int;kotlin.Int;kotlin.Int;kotlin.String;kotlin.Float;kotlin.Boolean;kotlin.Boolean;kotlin.Long;kotlin.Int;kotlin.String;kotlin.Int){}[0]
|
||||
|
||||
final val apiLevel // androidx.compose.ui.tooling.preview/Preview.apiLevel|{}apiLevel[0]
|
||||
final fun <get-apiLevel>(): kotlin/Int // androidx.compose.ui.tooling.preview/Preview.apiLevel.<get-apiLevel>|<get-apiLevel>(){}[0]
|
||||
final val backgroundColor // androidx.compose.ui.tooling.preview/Preview.backgroundColor|{}backgroundColor[0]
|
||||
final fun <get-backgroundColor>(): kotlin/Long // androidx.compose.ui.tooling.preview/Preview.backgroundColor.<get-backgroundColor>|<get-backgroundColor>(){}[0]
|
||||
final val device // androidx.compose.ui.tooling.preview/Preview.device|{}device[0]
|
||||
final fun <get-device>(): kotlin/String // androidx.compose.ui.tooling.preview/Preview.device.<get-device>|<get-device>(){}[0]
|
||||
final val fontScale // androidx.compose.ui.tooling.preview/Preview.fontScale|{}fontScale[0]
|
||||
final fun <get-fontScale>(): kotlin/Float // androidx.compose.ui.tooling.preview/Preview.fontScale.<get-fontScale>|<get-fontScale>(){}[0]
|
||||
final val group // androidx.compose.ui.tooling.preview/Preview.group|{}group[0]
|
||||
final fun <get-group>(): kotlin/String // androidx.compose.ui.tooling.preview/Preview.group.<get-group>|<get-group>(){}[0]
|
||||
final val heightDp // androidx.compose.ui.tooling.preview/Preview.heightDp|{}heightDp[0]
|
||||
final fun <get-heightDp>(): kotlin/Int // androidx.compose.ui.tooling.preview/Preview.heightDp.<get-heightDp>|<get-heightDp>(){}[0]
|
||||
final val locale // androidx.compose.ui.tooling.preview/Preview.locale|{}locale[0]
|
||||
final fun <get-locale>(): kotlin/String // androidx.compose.ui.tooling.preview/Preview.locale.<get-locale>|<get-locale>(){}[0]
|
||||
final val name // androidx.compose.ui.tooling.preview/Preview.name|{}name[0]
|
||||
final fun <get-name>(): kotlin/String // androidx.compose.ui.tooling.preview/Preview.name.<get-name>|<get-name>(){}[0]
|
||||
final val showBackground // androidx.compose.ui.tooling.preview/Preview.showBackground|{}showBackground[0]
|
||||
final fun <get-showBackground>(): kotlin/Boolean // androidx.compose.ui.tooling.preview/Preview.showBackground.<get-showBackground>|<get-showBackground>(){}[0]
|
||||
final val showSystemUi // androidx.compose.ui.tooling.preview/Preview.showSystemUi|{}showSystemUi[0]
|
||||
final fun <get-showSystemUi>(): kotlin/Boolean // androidx.compose.ui.tooling.preview/Preview.showSystemUi.<get-showSystemUi>|<get-showSystemUi>(){}[0]
|
||||
final val uiMode // androidx.compose.ui.tooling.preview/Preview.uiMode|{}uiMode[0]
|
||||
final fun <get-uiMode>(): kotlin/Int // androidx.compose.ui.tooling.preview/Preview.uiMode.<get-uiMode>|<get-uiMode>(){}[0]
|
||||
final val wallpaper // androidx.compose.ui.tooling.preview/Preview.wallpaper|{}wallpaper[0]
|
||||
final fun <get-wallpaper>(): kotlin/Int // androidx.compose.ui.tooling.preview/Preview.wallpaper.<get-wallpaper>|<get-wallpaper>(){}[0]
|
||||
final val widthDp // androidx.compose.ui.tooling.preview/Preview.widthDp|{}widthDp[0]
|
||||
final fun <get-widthDp>(): kotlin/Int // androidx.compose.ui.tooling.preview/Preview.widthDp.<get-widthDp>|<get-widthDp>(){}[0]
|
||||
}
|
||||
|
||||
open annotation class androidx.compose.ui.tooling.preview/PreviewDynamicColors : kotlin/Annotation { // androidx.compose.ui.tooling.preview/PreviewDynamicColors|null[0]
|
||||
constructor <init>() // androidx.compose.ui.tooling.preview/PreviewDynamicColors.<init>|<init>(){}[0]
|
||||
}
|
||||
|
||||
open annotation class androidx.compose.ui.tooling.preview/PreviewFontScale : kotlin/Annotation { // androidx.compose.ui.tooling.preview/PreviewFontScale|null[0]
|
||||
constructor <init>() // androidx.compose.ui.tooling.preview/PreviewFontScale.<init>|<init>(){}[0]
|
||||
}
|
||||
|
||||
open annotation class androidx.compose.ui.tooling.preview/PreviewLightDark : kotlin/Annotation { // androidx.compose.ui.tooling.preview/PreviewLightDark|null[0]
|
||||
constructor <init>() // androidx.compose.ui.tooling.preview/PreviewLightDark.<init>|<init>(){}[0]
|
||||
}
|
||||
|
||||
open annotation class androidx.compose.ui.tooling.preview/PreviewParameter : kotlin/Annotation { // androidx.compose.ui.tooling.preview/PreviewParameter|null[0]
|
||||
constructor <init>(kotlin.reflect/KClass<out androidx.compose.ui.tooling.preview/PreviewParameterProvider<*>>, kotlin/Int = ...) // androidx.compose.ui.tooling.preview/PreviewParameter.<init>|<init>(kotlin.reflect.KClass<out|androidx.compose.ui.tooling.preview.PreviewParameterProvider<*>>;kotlin.Int){}[0]
|
||||
|
||||
final val limit // androidx.compose.ui.tooling.preview/PreviewParameter.limit|{}limit[0]
|
||||
final fun <get-limit>(): kotlin/Int // androidx.compose.ui.tooling.preview/PreviewParameter.limit.<get-limit>|<get-limit>(){}[0]
|
||||
final val provider // androidx.compose.ui.tooling.preview/PreviewParameter.provider|{}provider[0]
|
||||
final fun <get-provider>(): kotlin.reflect/KClass<out androidx.compose.ui.tooling.preview/PreviewParameterProvider<*>> // androidx.compose.ui.tooling.preview/PreviewParameter.provider.<get-provider>|<get-provider>(){}[0]
|
||||
}
|
||||
|
||||
open annotation class androidx.compose.ui.tooling.preview/PreviewScreenSizes : kotlin/Annotation { // androidx.compose.ui.tooling.preview/PreviewScreenSizes|null[0]
|
||||
constructor <init>() // androidx.compose.ui.tooling.preview/PreviewScreenSizes.<init>|<init>(){}[0]
|
||||
}
|
||||
|
||||
open annotation class androidx.compose.ui.tooling.preview/PreviewWrapper : kotlin/Annotation { // androidx.compose.ui.tooling.preview/PreviewWrapper|null[0]
|
||||
constructor <init>(kotlin.reflect/KClass<out androidx.compose.ui.tooling.preview/PreviewWrapperProvider>) // androidx.compose.ui.tooling.preview/PreviewWrapper.<init>|<init>(kotlin.reflect.KClass<out|androidx.compose.ui.tooling.preview.PreviewWrapperProvider>){}[0]
|
||||
|
||||
final val wrapper // androidx.compose.ui.tooling.preview/PreviewWrapper.wrapper|{}wrapper[0]
|
||||
final fun <get-wrapper>(): kotlin.reflect/KClass<out androidx.compose.ui.tooling.preview/PreviewWrapperProvider> // androidx.compose.ui.tooling.preview/PreviewWrapper.wrapper.<get-wrapper>|<get-wrapper>(){}[0]
|
||||
}
|
||||
|
||||
abstract interface <#A: kotlin/Any?> androidx.compose.ui.tooling.preview/PreviewParameterProvider { // androidx.compose.ui.tooling.preview/PreviewParameterProvider|null[0]
|
||||
abstract val values // androidx.compose.ui.tooling.preview/PreviewParameterProvider.values|{}values[0]
|
||||
abstract fun <get-values>(): kotlin.sequences/Sequence<#A> // androidx.compose.ui.tooling.preview/PreviewParameterProvider.values.<get-values>|<get-values>(){}[0]
|
||||
open val count // androidx.compose.ui.tooling.preview/PreviewParameterProvider.count|{}count[0]
|
||||
open fun <get-count>(): kotlin/Int // androidx.compose.ui.tooling.preview/PreviewParameterProvider.count.<get-count>|<get-count>(){}[0]
|
||||
|
||||
open fun getDisplayName(kotlin/Int): kotlin/String? // androidx.compose.ui.tooling.preview/PreviewParameterProvider.getDisplayName|getDisplayName(kotlin.Int){}[0]
|
||||
}
|
||||
|
||||
abstract interface androidx.compose.ui.tooling.preview/PreviewWrapperProvider { // androidx.compose.ui.tooling.preview/PreviewWrapperProvider|null[0]
|
||||
abstract fun Wrap(kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int) // androidx.compose.ui.tooling.preview/PreviewWrapperProvider.Wrap|Wrap(kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
}
|
||||
|
||||
open class <#A: kotlin/Any?> androidx.compose.ui.tooling.preview.datasource/CollectionPreviewParameterProvider : androidx.compose.ui.tooling.preview/PreviewParameterProvider<#A> { // androidx.compose.ui.tooling.preview.datasource/CollectionPreviewParameterProvider|null[0]
|
||||
constructor <init>(kotlin.collections/Collection<#A>) // androidx.compose.ui.tooling.preview.datasource/CollectionPreviewParameterProvider.<init>|<init>(kotlin.collections.Collection<1:0>){}[0]
|
||||
|
||||
open val values // androidx.compose.ui.tooling.preview.datasource/CollectionPreviewParameterProvider.values|{}values[0]
|
||||
open fun <get-values>(): kotlin.sequences/Sequence<#A> // androidx.compose.ui.tooling.preview.datasource/CollectionPreviewParameterProvider.values.<get-values>|<get-values>(){}[0]
|
||||
}
|
||||
|
||||
open class androidx.compose.ui.tooling.preview.datasource/LoremIpsum : androidx.compose.ui.tooling.preview/PreviewParameterProvider<kotlin/String> { // androidx.compose.ui.tooling.preview.datasource/LoremIpsum|null[0]
|
||||
constructor <init>() // androidx.compose.ui.tooling.preview.datasource/LoremIpsum.<init>|<init>(){}[0]
|
||||
constructor <init>(kotlin/Int) // androidx.compose.ui.tooling.preview.datasource/LoremIpsum.<init>|<init>(kotlin.Int){}[0]
|
||||
|
||||
open val values // androidx.compose.ui.tooling.preview.datasource/LoremIpsum.values|{}values[0]
|
||||
open fun <get-values>(): kotlin.sequences/Sequence<kotlin/String> // androidx.compose.ui.tooling.preview.datasource/LoremIpsum.values.<get-values>|<get-values>(){}[0]
|
||||
}
|
||||
|
||||
final object androidx.compose.ui.tooling.preview/AndroidUiModes { // androidx.compose.ui.tooling.preview/AndroidUiModes|null[0]
|
||||
final const val UI_MODE_NIGHT_MASK // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_NIGHT_MASK|{}UI_MODE_NIGHT_MASK[0]
|
||||
final fun <get-UI_MODE_NIGHT_MASK>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_NIGHT_MASK.<get-UI_MODE_NIGHT_MASK>|<get-UI_MODE_NIGHT_MASK>(){}[0]
|
||||
final const val UI_MODE_NIGHT_NO // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_NIGHT_NO|{}UI_MODE_NIGHT_NO[0]
|
||||
final fun <get-UI_MODE_NIGHT_NO>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_NIGHT_NO.<get-UI_MODE_NIGHT_NO>|<get-UI_MODE_NIGHT_NO>(){}[0]
|
||||
final const val UI_MODE_NIGHT_UNDEFINED // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_NIGHT_UNDEFINED|{}UI_MODE_NIGHT_UNDEFINED[0]
|
||||
final fun <get-UI_MODE_NIGHT_UNDEFINED>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_NIGHT_UNDEFINED.<get-UI_MODE_NIGHT_UNDEFINED>|<get-UI_MODE_NIGHT_UNDEFINED>(){}[0]
|
||||
final const val UI_MODE_NIGHT_YES // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_NIGHT_YES|{}UI_MODE_NIGHT_YES[0]
|
||||
final fun <get-UI_MODE_NIGHT_YES>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_NIGHT_YES.<get-UI_MODE_NIGHT_YES>|<get-UI_MODE_NIGHT_YES>(){}[0]
|
||||
final const val UI_MODE_TYPE_APPLIANCE // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_APPLIANCE|{}UI_MODE_TYPE_APPLIANCE[0]
|
||||
final fun <get-UI_MODE_TYPE_APPLIANCE>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_APPLIANCE.<get-UI_MODE_TYPE_APPLIANCE>|<get-UI_MODE_TYPE_APPLIANCE>(){}[0]
|
||||
final const val UI_MODE_TYPE_CAR // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_CAR|{}UI_MODE_TYPE_CAR[0]
|
||||
final fun <get-UI_MODE_TYPE_CAR>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_CAR.<get-UI_MODE_TYPE_CAR>|<get-UI_MODE_TYPE_CAR>(){}[0]
|
||||
final const val UI_MODE_TYPE_DESK // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_DESK|{}UI_MODE_TYPE_DESK[0]
|
||||
final fun <get-UI_MODE_TYPE_DESK>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_DESK.<get-UI_MODE_TYPE_DESK>|<get-UI_MODE_TYPE_DESK>(){}[0]
|
||||
final const val UI_MODE_TYPE_MASK // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_MASK|{}UI_MODE_TYPE_MASK[0]
|
||||
final fun <get-UI_MODE_TYPE_MASK>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_MASK.<get-UI_MODE_TYPE_MASK>|<get-UI_MODE_TYPE_MASK>(){}[0]
|
||||
final const val UI_MODE_TYPE_NORMAL // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_NORMAL|{}UI_MODE_TYPE_NORMAL[0]
|
||||
final fun <get-UI_MODE_TYPE_NORMAL>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_NORMAL.<get-UI_MODE_TYPE_NORMAL>|<get-UI_MODE_TYPE_NORMAL>(){}[0]
|
||||
final const val UI_MODE_TYPE_TELEVISION // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_TELEVISION|{}UI_MODE_TYPE_TELEVISION[0]
|
||||
final fun <get-UI_MODE_TYPE_TELEVISION>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_TELEVISION.<get-UI_MODE_TYPE_TELEVISION>|<get-UI_MODE_TYPE_TELEVISION>(){}[0]
|
||||
final const val UI_MODE_TYPE_UNDEFINED // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_UNDEFINED|{}UI_MODE_TYPE_UNDEFINED[0]
|
||||
final fun <get-UI_MODE_TYPE_UNDEFINED>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_UNDEFINED.<get-UI_MODE_TYPE_UNDEFINED>|<get-UI_MODE_TYPE_UNDEFINED>(){}[0]
|
||||
final const val UI_MODE_TYPE_VR_HEADSET // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_VR_HEADSET|{}UI_MODE_TYPE_VR_HEADSET[0]
|
||||
final fun <get-UI_MODE_TYPE_VR_HEADSET>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_VR_HEADSET.<get-UI_MODE_TYPE_VR_HEADSET>|<get-UI_MODE_TYPE_VR_HEADSET>(){}[0]
|
||||
final const val UI_MODE_TYPE_WATCH // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_WATCH|{}UI_MODE_TYPE_WATCH[0]
|
||||
final fun <get-UI_MODE_TYPE_WATCH>(): kotlin/Int // androidx.compose.ui.tooling.preview/AndroidUiModes.UI_MODE_TYPE_WATCH.<get-UI_MODE_TYPE_WATCH>|<get-UI_MODE_TYPE_WATCH>(){}[0]
|
||||
}
|
||||
|
||||
final object androidx.compose.ui.tooling.preview/Devices { // androidx.compose.ui.tooling.preview/Devices|null[0]
|
||||
final const val AUTOMOTIVE_1024p // androidx.compose.ui.tooling.preview/Devices.AUTOMOTIVE_1024p|{}AUTOMOTIVE_1024p[0]
|
||||
final fun <get-AUTOMOTIVE_1024p>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.AUTOMOTIVE_1024p.<get-AUTOMOTIVE_1024p>|<get-AUTOMOTIVE_1024p>(){}[0]
|
||||
final const val DEFAULT // androidx.compose.ui.tooling.preview/Devices.DEFAULT|{}DEFAULT[0]
|
||||
final fun <get-DEFAULT>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.DEFAULT.<get-DEFAULT>|<get-DEFAULT>(){}[0]
|
||||
final const val DESKTOP // androidx.compose.ui.tooling.preview/Devices.DESKTOP|{}DESKTOP[0]
|
||||
final fun <get-DESKTOP>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.DESKTOP.<get-DESKTOP>|<get-DESKTOP>(){}[0]
|
||||
final const val FOLDABLE // androidx.compose.ui.tooling.preview/Devices.FOLDABLE|{}FOLDABLE[0]
|
||||
final fun <get-FOLDABLE>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.FOLDABLE.<get-FOLDABLE>|<get-FOLDABLE>(){}[0]
|
||||
final const val NEXUS_10 // androidx.compose.ui.tooling.preview/Devices.NEXUS_10|{}NEXUS_10[0]
|
||||
final fun <get-NEXUS_10>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.NEXUS_10.<get-NEXUS_10>|<get-NEXUS_10>(){}[0]
|
||||
final const val NEXUS_5 // androidx.compose.ui.tooling.preview/Devices.NEXUS_5|{}NEXUS_5[0]
|
||||
final fun <get-NEXUS_5>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.NEXUS_5.<get-NEXUS_5>|<get-NEXUS_5>(){}[0]
|
||||
final const val NEXUS_5X // androidx.compose.ui.tooling.preview/Devices.NEXUS_5X|{}NEXUS_5X[0]
|
||||
final fun <get-NEXUS_5X>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.NEXUS_5X.<get-NEXUS_5X>|<get-NEXUS_5X>(){}[0]
|
||||
final const val NEXUS_6 // androidx.compose.ui.tooling.preview/Devices.NEXUS_6|{}NEXUS_6[0]
|
||||
final fun <get-NEXUS_6>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.NEXUS_6.<get-NEXUS_6>|<get-NEXUS_6>(){}[0]
|
||||
final const val NEXUS_6P // androidx.compose.ui.tooling.preview/Devices.NEXUS_6P|{}NEXUS_6P[0]
|
||||
final fun <get-NEXUS_6P>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.NEXUS_6P.<get-NEXUS_6P>|<get-NEXUS_6P>(){}[0]
|
||||
final const val NEXUS_7 // androidx.compose.ui.tooling.preview/Devices.NEXUS_7|{}NEXUS_7[0]
|
||||
final fun <get-NEXUS_7>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.NEXUS_7.<get-NEXUS_7>|<get-NEXUS_7>(){}[0]
|
||||
final const val NEXUS_7_2013 // androidx.compose.ui.tooling.preview/Devices.NEXUS_7_2013|{}NEXUS_7_2013[0]
|
||||
final fun <get-NEXUS_7_2013>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.NEXUS_7_2013.<get-NEXUS_7_2013>|<get-NEXUS_7_2013>(){}[0]
|
||||
final const val NEXUS_9 // androidx.compose.ui.tooling.preview/Devices.NEXUS_9|{}NEXUS_9[0]
|
||||
final fun <get-NEXUS_9>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.NEXUS_9.<get-NEXUS_9>|<get-NEXUS_9>(){}[0]
|
||||
final const val PHONE // androidx.compose.ui.tooling.preview/Devices.PHONE|{}PHONE[0]
|
||||
final fun <get-PHONE>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PHONE.<get-PHONE>|<get-PHONE>(){}[0]
|
||||
final const val PIXEL // androidx.compose.ui.tooling.preview/Devices.PIXEL|{}PIXEL[0]
|
||||
final fun <get-PIXEL>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL.<get-PIXEL>|<get-PIXEL>(){}[0]
|
||||
final const val PIXEL_2 // androidx.compose.ui.tooling.preview/Devices.PIXEL_2|{}PIXEL_2[0]
|
||||
final fun <get-PIXEL_2>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_2.<get-PIXEL_2>|<get-PIXEL_2>(){}[0]
|
||||
final const val PIXEL_2_XL // androidx.compose.ui.tooling.preview/Devices.PIXEL_2_XL|{}PIXEL_2_XL[0]
|
||||
final fun <get-PIXEL_2_XL>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_2_XL.<get-PIXEL_2_XL>|<get-PIXEL_2_XL>(){}[0]
|
||||
final const val PIXEL_3 // androidx.compose.ui.tooling.preview/Devices.PIXEL_3|{}PIXEL_3[0]
|
||||
final fun <get-PIXEL_3>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_3.<get-PIXEL_3>|<get-PIXEL_3>(){}[0]
|
||||
final const val PIXEL_3A // androidx.compose.ui.tooling.preview/Devices.PIXEL_3A|{}PIXEL_3A[0]
|
||||
final fun <get-PIXEL_3A>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_3A.<get-PIXEL_3A>|<get-PIXEL_3A>(){}[0]
|
||||
final const val PIXEL_3A_XL // androidx.compose.ui.tooling.preview/Devices.PIXEL_3A_XL|{}PIXEL_3A_XL[0]
|
||||
final fun <get-PIXEL_3A_XL>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_3A_XL.<get-PIXEL_3A_XL>|<get-PIXEL_3A_XL>(){}[0]
|
||||
final const val PIXEL_3_XL // androidx.compose.ui.tooling.preview/Devices.PIXEL_3_XL|{}PIXEL_3_XL[0]
|
||||
final fun <get-PIXEL_3_XL>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_3_XL.<get-PIXEL_3_XL>|<get-PIXEL_3_XL>(){}[0]
|
||||
final const val PIXEL_4 // androidx.compose.ui.tooling.preview/Devices.PIXEL_4|{}PIXEL_4[0]
|
||||
final fun <get-PIXEL_4>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_4.<get-PIXEL_4>|<get-PIXEL_4>(){}[0]
|
||||
final const val PIXEL_4A // androidx.compose.ui.tooling.preview/Devices.PIXEL_4A|{}PIXEL_4A[0]
|
||||
final fun <get-PIXEL_4A>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_4A.<get-PIXEL_4A>|<get-PIXEL_4A>(){}[0]
|
||||
final const val PIXEL_4_XL // androidx.compose.ui.tooling.preview/Devices.PIXEL_4_XL|{}PIXEL_4_XL[0]
|
||||
final fun <get-PIXEL_4_XL>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_4_XL.<get-PIXEL_4_XL>|<get-PIXEL_4_XL>(){}[0]
|
||||
final const val PIXEL_5 // androidx.compose.ui.tooling.preview/Devices.PIXEL_5|{}PIXEL_5[0]
|
||||
final fun <get-PIXEL_5>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_5.<get-PIXEL_5>|<get-PIXEL_5>(){}[0]
|
||||
final const val PIXEL_6 // androidx.compose.ui.tooling.preview/Devices.PIXEL_6|{}PIXEL_6[0]
|
||||
final fun <get-PIXEL_6>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_6.<get-PIXEL_6>|<get-PIXEL_6>(){}[0]
|
||||
final const val PIXEL_6A // androidx.compose.ui.tooling.preview/Devices.PIXEL_6A|{}PIXEL_6A[0]
|
||||
final fun <get-PIXEL_6A>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_6A.<get-PIXEL_6A>|<get-PIXEL_6A>(){}[0]
|
||||
final const val PIXEL_6_PRO // androidx.compose.ui.tooling.preview/Devices.PIXEL_6_PRO|{}PIXEL_6_PRO[0]
|
||||
final fun <get-PIXEL_6_PRO>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_6_PRO.<get-PIXEL_6_PRO>|<get-PIXEL_6_PRO>(){}[0]
|
||||
final const val PIXEL_7 // androidx.compose.ui.tooling.preview/Devices.PIXEL_7|{}PIXEL_7[0]
|
||||
final fun <get-PIXEL_7>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_7.<get-PIXEL_7>|<get-PIXEL_7>(){}[0]
|
||||
final const val PIXEL_7A // androidx.compose.ui.tooling.preview/Devices.PIXEL_7A|{}PIXEL_7A[0]
|
||||
final fun <get-PIXEL_7A>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_7A.<get-PIXEL_7A>|<get-PIXEL_7A>(){}[0]
|
||||
final const val PIXEL_7_PRO // androidx.compose.ui.tooling.preview/Devices.PIXEL_7_PRO|{}PIXEL_7_PRO[0]
|
||||
final fun <get-PIXEL_7_PRO>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_7_PRO.<get-PIXEL_7_PRO>|<get-PIXEL_7_PRO>(){}[0]
|
||||
final const val PIXEL_8 // androidx.compose.ui.tooling.preview/Devices.PIXEL_8|{}PIXEL_8[0]
|
||||
final fun <get-PIXEL_8>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_8.<get-PIXEL_8>|<get-PIXEL_8>(){}[0]
|
||||
final const val PIXEL_8A // androidx.compose.ui.tooling.preview/Devices.PIXEL_8A|{}PIXEL_8A[0]
|
||||
final fun <get-PIXEL_8A>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_8A.<get-PIXEL_8A>|<get-PIXEL_8A>(){}[0]
|
||||
final const val PIXEL_8_PRO // androidx.compose.ui.tooling.preview/Devices.PIXEL_8_PRO|{}PIXEL_8_PRO[0]
|
||||
final fun <get-PIXEL_8_PRO>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_8_PRO.<get-PIXEL_8_PRO>|<get-PIXEL_8_PRO>(){}[0]
|
||||
final const val PIXEL_9 // androidx.compose.ui.tooling.preview/Devices.PIXEL_9|{}PIXEL_9[0]
|
||||
final fun <get-PIXEL_9>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_9.<get-PIXEL_9>|<get-PIXEL_9>(){}[0]
|
||||
final const val PIXEL_9_PRO // androidx.compose.ui.tooling.preview/Devices.PIXEL_9_PRO|{}PIXEL_9_PRO[0]
|
||||
final fun <get-PIXEL_9_PRO>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_9_PRO.<get-PIXEL_9_PRO>|<get-PIXEL_9_PRO>(){}[0]
|
||||
final const val PIXEL_9_PRO_FOLD // androidx.compose.ui.tooling.preview/Devices.PIXEL_9_PRO_FOLD|{}PIXEL_9_PRO_FOLD[0]
|
||||
final fun <get-PIXEL_9_PRO_FOLD>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_9_PRO_FOLD.<get-PIXEL_9_PRO_FOLD>|<get-PIXEL_9_PRO_FOLD>(){}[0]
|
||||
final const val PIXEL_9_PRO_XL // androidx.compose.ui.tooling.preview/Devices.PIXEL_9_PRO_XL|{}PIXEL_9_PRO_XL[0]
|
||||
final fun <get-PIXEL_9_PRO_XL>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_9_PRO_XL.<get-PIXEL_9_PRO_XL>|<get-PIXEL_9_PRO_XL>(){}[0]
|
||||
final const val PIXEL_C // androidx.compose.ui.tooling.preview/Devices.PIXEL_C|{}PIXEL_C[0]
|
||||
final fun <get-PIXEL_C>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_C.<get-PIXEL_C>|<get-PIXEL_C>(){}[0]
|
||||
final const val PIXEL_FOLD // androidx.compose.ui.tooling.preview/Devices.PIXEL_FOLD|{}PIXEL_FOLD[0]
|
||||
final fun <get-PIXEL_FOLD>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_FOLD.<get-PIXEL_FOLD>|<get-PIXEL_FOLD>(){}[0]
|
||||
final const val PIXEL_TABLET // androidx.compose.ui.tooling.preview/Devices.PIXEL_TABLET|{}PIXEL_TABLET[0]
|
||||
final fun <get-PIXEL_TABLET>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_TABLET.<get-PIXEL_TABLET>|<get-PIXEL_TABLET>(){}[0]
|
||||
final const val PIXEL_XL // androidx.compose.ui.tooling.preview/Devices.PIXEL_XL|{}PIXEL_XL[0]
|
||||
final fun <get-PIXEL_XL>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.PIXEL_XL.<get-PIXEL_XL>|<get-PIXEL_XL>(){}[0]
|
||||
final const val TABLET // androidx.compose.ui.tooling.preview/Devices.TABLET|{}TABLET[0]
|
||||
final fun <get-TABLET>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.TABLET.<get-TABLET>|<get-TABLET>(){}[0]
|
||||
final const val TV_1080p // androidx.compose.ui.tooling.preview/Devices.TV_1080p|{}TV_1080p[0]
|
||||
final fun <get-TV_1080p>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.TV_1080p.<get-TV_1080p>|<get-TV_1080p>(){}[0]
|
||||
final const val TV_720p // androidx.compose.ui.tooling.preview/Devices.TV_720p|{}TV_720p[0]
|
||||
final fun <get-TV_720p>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.TV_720p.<get-TV_720p>|<get-TV_720p>(){}[0]
|
||||
final const val WEAR_OS_LARGE_ROUND // androidx.compose.ui.tooling.preview/Devices.WEAR_OS_LARGE_ROUND|{}WEAR_OS_LARGE_ROUND[0]
|
||||
final fun <get-WEAR_OS_LARGE_ROUND>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.WEAR_OS_LARGE_ROUND.<get-WEAR_OS_LARGE_ROUND>|<get-WEAR_OS_LARGE_ROUND>(){}[0]
|
||||
final const val WEAR_OS_RECT // androidx.compose.ui.tooling.preview/Devices.WEAR_OS_RECT|{}WEAR_OS_RECT[0]
|
||||
final fun <get-WEAR_OS_RECT>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.WEAR_OS_RECT.<get-WEAR_OS_RECT>|<get-WEAR_OS_RECT>(){}[0]
|
||||
final const val WEAR_OS_SMALL_ROUND // androidx.compose.ui.tooling.preview/Devices.WEAR_OS_SMALL_ROUND|{}WEAR_OS_SMALL_ROUND[0]
|
||||
final fun <get-WEAR_OS_SMALL_ROUND>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.WEAR_OS_SMALL_ROUND.<get-WEAR_OS_SMALL_ROUND>|<get-WEAR_OS_SMALL_ROUND>(){}[0]
|
||||
final const val WEAR_OS_SQUARE // androidx.compose.ui.tooling.preview/Devices.WEAR_OS_SQUARE|{}WEAR_OS_SQUARE[0]
|
||||
final fun <get-WEAR_OS_SQUARE>(): kotlin/String // androidx.compose.ui.tooling.preview/Devices.WEAR_OS_SQUARE.<get-WEAR_OS_SQUARE>|<get-WEAR_OS_SQUARE>(){}[0]
|
||||
}
|
||||
|
||||
final object androidx.compose.ui.tooling.preview/Wallpapers { // androidx.compose.ui.tooling.preview/Wallpapers|null[0]
|
||||
final const val BLUE_DOMINATED_EXAMPLE // androidx.compose.ui.tooling.preview/Wallpapers.BLUE_DOMINATED_EXAMPLE|{}BLUE_DOMINATED_EXAMPLE[0]
|
||||
final fun <get-BLUE_DOMINATED_EXAMPLE>(): kotlin/Int // androidx.compose.ui.tooling.preview/Wallpapers.BLUE_DOMINATED_EXAMPLE.<get-BLUE_DOMINATED_EXAMPLE>|<get-BLUE_DOMINATED_EXAMPLE>(){}[0]
|
||||
final const val GREEN_DOMINATED_EXAMPLE // androidx.compose.ui.tooling.preview/Wallpapers.GREEN_DOMINATED_EXAMPLE|{}GREEN_DOMINATED_EXAMPLE[0]
|
||||
final fun <get-GREEN_DOMINATED_EXAMPLE>(): kotlin/Int // androidx.compose.ui.tooling.preview/Wallpapers.GREEN_DOMINATED_EXAMPLE.<get-GREEN_DOMINATED_EXAMPLE>|<get-GREEN_DOMINATED_EXAMPLE>(){}[0]
|
||||
final const val NONE // androidx.compose.ui.tooling.preview/Wallpapers.NONE|{}NONE[0]
|
||||
final fun <get-NONE>(): kotlin/Int // androidx.compose.ui.tooling.preview/Wallpapers.NONE.<get-NONE>|<get-NONE>(){}[0]
|
||||
final const val RED_DOMINATED_EXAMPLE // androidx.compose.ui.tooling.preview/Wallpapers.RED_DOMINATED_EXAMPLE|{}RED_DOMINATED_EXAMPLE[0]
|
||||
final fun <get-RED_DOMINATED_EXAMPLE>(): kotlin/Int // androidx.compose.ui.tooling.preview/Wallpapers.RED_DOMINATED_EXAMPLE.<get-RED_DOMINATED_EXAMPLE>|<get-RED_DOMINATED_EXAMPLE>(){}[0]
|
||||
final const val YELLOW_DOMINATED_EXAMPLE // androidx.compose.ui.tooling.preview/Wallpapers.YELLOW_DOMINATED_EXAMPLE|{}YELLOW_DOMINATED_EXAMPLE[0]
|
||||
final fun <get-YELLOW_DOMINATED_EXAMPLE>(): kotlin/Int // androidx.compose.ui.tooling.preview/Wallpapers.YELLOW_DOMINATED_EXAMPLE.<get-YELLOW_DOMINATED_EXAMPLE>|<get-YELLOW_DOMINATED_EXAMPLE>(){}[0]
|
||||
}
|
||||
|
||||
final val androidx.compose.ui.tooling.preview.datasource/androidx_compose_ui_tooling_preview_datasource_CollectionPreviewParameterProvider$stableprop // androidx.compose.ui.tooling.preview.datasource/androidx_compose_ui_tooling_preview_datasource_CollectionPreviewParameterProvider$stableprop|#static{}androidx_compose_ui_tooling_preview_datasource_CollectionPreviewParameterProvider$stableprop[0]
|
||||
final val androidx.compose.ui.tooling.preview.datasource/androidx_compose_ui_tooling_preview_datasource_LoremIpsum$stableprop // androidx.compose.ui.tooling.preview.datasource/androidx_compose_ui_tooling_preview_datasource_LoremIpsum$stableprop|#static{}androidx_compose_ui_tooling_preview_datasource_LoremIpsum$stableprop[0]
|
||||
final val androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_AndroidUiModes$stableprop // androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_AndroidUiModes$stableprop|#static{}androidx_compose_ui_tooling_preview_AndroidUiModes$stableprop[0]
|
||||
final val androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_Devices$stableprop // androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_Devices$stableprop|#static{}androidx_compose_ui_tooling_preview_Devices$stableprop[0]
|
||||
final val androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_Wallpapers$stableprop // androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_Wallpapers$stableprop|#static{}androidx_compose_ui_tooling_preview_Wallpapers$stableprop[0]
|
||||
|
||||
final fun androidx.compose.ui.tooling.preview.datasource/androidx_compose_ui_tooling_preview_datasource_CollectionPreviewParameterProvider$stableprop_getter(): kotlin/Int // androidx.compose.ui.tooling.preview.datasource/androidx_compose_ui_tooling_preview_datasource_CollectionPreviewParameterProvider$stableprop_getter|androidx_compose_ui_tooling_preview_datasource_CollectionPreviewParameterProvider$stableprop_getter(){}[0]
|
||||
final fun androidx.compose.ui.tooling.preview.datasource/androidx_compose_ui_tooling_preview_datasource_LoremIpsum$stableprop_getter(): kotlin/Int // androidx.compose.ui.tooling.preview.datasource/androidx_compose_ui_tooling_preview_datasource_LoremIpsum$stableprop_getter|androidx_compose_ui_tooling_preview_datasource_LoremIpsum$stableprop_getter(){}[0]
|
||||
final fun androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_AndroidUiModes$stableprop_getter(): kotlin/Int // androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_AndroidUiModes$stableprop_getter|androidx_compose_ui_tooling_preview_AndroidUiModes$stableprop_getter(){}[0]
|
||||
final fun androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_Devices$stableprop_getter(): kotlin/Int // androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_Devices$stableprop_getter|androidx_compose_ui_tooling_preview_Devices$stableprop_getter(){}[0]
|
||||
final fun androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_Wallpapers$stableprop_getter(): kotlin/Int // androidx.compose.ui.tooling.preview/androidx_compose_ui_tooling_preview_Wallpapers$stableprop_getter|androidx_compose_ui_tooling_preview_Wallpapers$stableprop_getter(){}[0]
|
||||
@@ -0,0 +1,34 @@
|
||||
// :ui-tooling-preview — androidx.compose.ui.tooling.preview.* (the common
|
||||
// @Preview annotation + PreviewParameterProvider), vendored VERBATIM from
|
||||
// upstream (compose/ui/ui-tooling-preview). The Maven artifact ships no
|
||||
// mingwX64/linux klibs — apps declare the OFFICIAL coords in commonMain and
|
||||
// the root bridge substitutes this module on native configurations. The
|
||||
// annotations are IDE-only metadata: previews render through the app's JVM
|
||||
// target against upstream Compose Desktop.
|
||||
// Never hand-edit src/vendor/ — change the manifest + `python scripts/compose-fork/sync.py compose/ui/ui-tooling-preview`.
|
||||
// Publication artifactId: ui-tooling-preview.
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.multiplatform)
|
||||
alias(libs.plugins.kotlin.plugin.compose)
|
||||
}
|
||||
|
||||
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
|
||||
|
||||
kotlin {
|
||||
linuxArm64(); linuxX64(); macosArm64(); if (vHostSupportsMingw) mingwX64()
|
||||
applyDefaultHierarchyTemplate()
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api("org.jetbrains.compose.runtime:runtime:1.11.1")
|
||||
}
|
||||
kotlin.srcDir("src/vendor/common/kotlin")
|
||||
}
|
||||
nativeMain { kotlin.srcDir("src/vendor/native/kotlin") }
|
||||
}
|
||||
compilerOptions {
|
||||
freeCompilerArgs.addAll(
|
||||
"-Xexpect-actual-classes",
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
SET_REPO=https://github.com/JetBrains/compose-multiplatform-core@<COMPOSE_CORE_REF>
|
||||
SET_FOLDER=compose/ui/ui-tooling-preview/src
|
||||
|
||||
commonMain/kotlin/ -> src/vendor/common/kotlin/
|
||||
# | commonMain/kotlin/androidx/compose/ui/tooling/preview/AndroidUiMode.kt -> src/vendor/common/kotlin/androidx/compose/ui/tooling/preview/AndroidUiMode.kt
|
||||
# | commonMain/kotlin/androidx/compose/ui/tooling/preview/Device.kt -> src/vendor/common/kotlin/androidx/compose/ui/tooling/preview/Device.kt
|
||||
# | commonMain/kotlin/androidx/compose/ui/tooling/preview/MultiPreviews.kt -> src/vendor/common/kotlin/androidx/compose/ui/tooling/preview/MultiPreviews.kt
|
||||
# | commonMain/kotlin/androidx/compose/ui/tooling/preview/Preview.kt -> src/vendor/common/kotlin/androidx/compose/ui/tooling/preview/Preview.kt
|
||||
# | commonMain/kotlin/androidx/compose/ui/tooling/preview/PreviewParameter.kt -> src/vendor/common/kotlin/androidx/compose/ui/tooling/preview/PreviewParameter.kt
|
||||
# | commonMain/kotlin/androidx/compose/ui/tooling/preview/PreviewWrapper.kt -> src/vendor/common/kotlin/androidx/compose/ui/tooling/preview/PreviewWrapper.kt
|
||||
# | commonMain/kotlin/androidx/compose/ui/tooling/preview/Wallpaper.kt -> src/vendor/common/kotlin/androidx/compose/ui/tooling/preview/Wallpaper.kt
|
||||
# | commonMain/kotlin/androidx/compose/ui/tooling/preview/datasource/CollectionPreviewParameterProvider.kt -> src/vendor/common/kotlin/androidx/compose/ui/tooling/preview/datasource/CollectionPreviewParameterProvider.kt
|
||||
# | commonMain/kotlin/androidx/compose/ui/tooling/preview/datasource/LoremIpsum.kt -> src/vendor/common/kotlin/androidx/compose/ui/tooling/preview/datasource/LoremIpsum.kt
|
||||
# | commonMain/kotlin/androidx/compose/ui/tooling/preview/internal/JvmDefaultWithCompatibility.kt -> src/vendor/common/kotlin/androidx/compose/ui/tooling/preview/internal/JvmDefaultWithCompatibility.kt
|
||||
|
||||
nonJvmMain/kotlin/androidx/compose/ui/tooling/preview/internal/JvmDefaultWithCompatibility.nonJvm.kt -> src/vendor/native/kotlin/androidx/compose/ui/tooling/preview/internal/JvmDefaultWithCompatibility.native.kt
|
||||
|
||||
# >>> ---- DIAGNOSTIC GAPS ---- <<<<
|
||||
# desktopMain (1)
|
||||
# | desktopMain/kotlin/androidx/compose/desktop/ui/tooling/preview/Preview.kt -> src/vendor/desktop/kotlin/androidx/compose/desktop/ui/tooling/preview/Preview.kt
|
||||
# jvmAndAndroidMain (1)
|
||||
# | jvmAndAndroidMain/kotlin/androidx/compose/ui/tooling/preview/internal/JvmDefaultWithCompatibility.jvmAndAndroid.kt -> src/vendor/jvmAndAndroid/kotlin/androidx/compose/ui/tooling/preview/internal/JvmDefaultWithCompatibility.jvmAndAndroid.kt
|
||||
# <<< ---- DIAGNOSTIC GAPS ---- >>>>
|
||||
+93
-189
@@ -1834,6 +1834,10 @@ abstract interface androidx.compose.ui/UiMediaScope { // androidx.compose.ui/UiM
|
||||
}
|
||||
}
|
||||
|
||||
abstract interface com.compose.sdl.graphics/EncodedImageDecoder { // com.compose.sdl.graphics/EncodedImageDecoder|null[0]
|
||||
abstract fun decode(kotlin/ByteArray): androidx.compose.ui.graphics/ImageBitmap? // com.compose.sdl.graphics/EncodedImageDecoder.decode|decode(kotlin.ByteArray){}[0]
|
||||
}
|
||||
|
||||
abstract interface com.compose.sdl.graphics/NativePainterCanvas { // com.compose.sdl.graphics/NativePainterCanvas|null[0]
|
||||
abstract fun drawNativePainter(kotlin/String, com.compose.sdl.res/ResourceKind, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, androidx.compose.ui.layout/ContentScale, kotlin/Float) // com.compose.sdl.graphics/NativePainterCanvas.drawNativePainter|drawNativePainter(kotlin.String;com.compose.sdl.res.ResourceKind;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;androidx.compose.ui.layout.ContentScale;kotlin.Float){}[0]
|
||||
}
|
||||
@@ -2522,9 +2526,23 @@ final class androidx.compose.ui.autofill/AutofillTree { // androidx.compose.ui.a
|
||||
final fun plusAssign(androidx.compose.ui.autofill/AutofillNode) // androidx.compose.ui.autofill/AutofillTree.plusAssign|plusAssign(androidx.compose.ui.autofill.AutofillNode){}[0]
|
||||
}
|
||||
|
||||
final class androidx.compose.ui.draganddrop/DragAndDropEvent // androidx.compose.ui.draganddrop/DragAndDropEvent|null[0]
|
||||
final class androidx.compose.ui.draganddrop/DragAndDropEvent { // androidx.compose.ui.draganddrop/DragAndDropEvent|null[0]
|
||||
final val position // androidx.compose.ui.draganddrop/DragAndDropEvent.position|{}position[0]
|
||||
final fun <get-position>(): androidx.compose.ui.geometry/Offset // androidx.compose.ui.draganddrop/DragAndDropEvent.position.<get-position>|<get-position>(){}[0]
|
||||
final val transferData // androidx.compose.ui.draganddrop/DragAndDropEvent.transferData|{}transferData[0]
|
||||
final fun <get-transferData>(): androidx.compose.ui.draganddrop/DragAndDropTransferData // androidx.compose.ui.draganddrop/DragAndDropEvent.transferData.<get-transferData>|<get-transferData>(){}[0]
|
||||
}
|
||||
|
||||
final class androidx.compose.ui.draganddrop/DragAndDropTransferData // androidx.compose.ui.draganddrop/DragAndDropTransferData|null[0]
|
||||
final class androidx.compose.ui.draganddrop/DragAndDropTransferData { // androidx.compose.ui.draganddrop/DragAndDropTransferData|null[0]
|
||||
final val filePaths // androidx.compose.ui.draganddrop/DragAndDropTransferData.filePaths|{}filePaths[0]
|
||||
final fun <get-filePaths>(): kotlin.collections/List<kotlin/String> // androidx.compose.ui.draganddrop/DragAndDropTransferData.filePaths.<get-filePaths>|<get-filePaths>(){}[0]
|
||||
final val hasFiles // androidx.compose.ui.draganddrop/DragAndDropTransferData.hasFiles|{}hasFiles[0]
|
||||
final fun <get-hasFiles>(): kotlin/Boolean // androidx.compose.ui.draganddrop/DragAndDropTransferData.hasFiles.<get-hasFiles>|<get-hasFiles>(){}[0]
|
||||
final val hasText // androidx.compose.ui.draganddrop/DragAndDropTransferData.hasText|{}hasText[0]
|
||||
final fun <get-hasText>(): kotlin/Boolean // androidx.compose.ui.draganddrop/DragAndDropTransferData.hasText.<get-hasText>|<get-hasText>(){}[0]
|
||||
final val text // androidx.compose.ui.draganddrop/DragAndDropTransferData.text|{}text[0]
|
||||
final fun <get-text>(): kotlin/String? // androidx.compose.ui.draganddrop/DragAndDropTransferData.text.<get-text>|<get-text>(){}[0]
|
||||
}
|
||||
|
||||
final class androidx.compose.ui.draw/CacheDrawScope : androidx.compose.ui.unit/Density { // androidx.compose.ui.draw/CacheDrawScope|null[0]
|
||||
final val density // androidx.compose.ui.draw/CacheDrawScope.density|{}density[0]
|
||||
@@ -3654,9 +3672,11 @@ final class androidx.compose.ui.platform/ClipEntry { // androidx.compose.ui.plat
|
||||
final val clipMetadata // androidx.compose.ui.platform/ClipEntry.clipMetadata|{}clipMetadata[0]
|
||||
final fun <get-clipMetadata>(): androidx.compose.ui.platform/ClipMetadata // androidx.compose.ui.platform/ClipEntry.clipMetadata.<get-clipMetadata>|<get-clipMetadata>(){}[0]
|
||||
|
||||
final fun getImage(): kotlin/ByteArray? // androidx.compose.ui.platform/ClipEntry.getImage|getImage(){}[0]
|
||||
final fun getPlainText(): kotlin/String? // androidx.compose.ui.platform/ClipEntry.getPlainText|getPlainText(){}[0]
|
||||
|
||||
final object Companion { // androidx.compose.ui.platform/ClipEntry.Companion|null[0]
|
||||
final fun withImage(kotlin/ByteArray): androidx.compose.ui.platform/ClipEntry // androidx.compose.ui.platform/ClipEntry.Companion.withImage|withImage(kotlin.ByteArray){}[0]
|
||||
final fun withPlainText(kotlin/String): androidx.compose.ui.platform/ClipEntry // androidx.compose.ui.platform/ClipEntry.Companion.withPlainText|withPlainText(kotlin.String){}[0]
|
||||
}
|
||||
}
|
||||
@@ -5348,136 +5368,6 @@ final class com.compose.sdl.element/GraphicsLayerNode : androidx.compose.ui/Modi
|
||||
final fun <set-translationY>(kotlin/Float) // com.compose.sdl.element/GraphicsLayerNode.translationY.<set-translationY>|<set-translationY>(kotlin.Float){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/MiddleClickModifier : androidx.compose.ui.node/ModifierNodeElement<com.compose.sdl.element/MiddleClickNode> { // com.compose.sdl.element/MiddleClickModifier|null[0]
|
||||
constructor <init>(kotlin/Function0<kotlin/Unit>) // com.compose.sdl.element/MiddleClickModifier.<init>|<init>(kotlin.Function0<kotlin.Unit>){}[0]
|
||||
|
||||
final val onClick // com.compose.sdl.element/MiddleClickModifier.onClick|{}onClick[0]
|
||||
final fun <get-onClick>(): kotlin/Function0<kotlin/Unit> // com.compose.sdl.element/MiddleClickModifier.onClick.<get-onClick>|<get-onClick>(){}[0]
|
||||
|
||||
final fun create(): com.compose.sdl.element/MiddleClickNode // com.compose.sdl.element/MiddleClickModifier.create|create(){}[0]
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl.element/MiddleClickModifier.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // com.compose.sdl.element/MiddleClickModifier.hashCode|hashCode(){}[0]
|
||||
final fun update(com.compose.sdl.element/MiddleClickNode) // com.compose.sdl.element/MiddleClickModifier.update|update(com.compose.sdl.element.MiddleClickNode){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/MiddleClickNode : androidx.compose.ui/Modifier.Node { // com.compose.sdl.element/MiddleClickNode|null[0]
|
||||
constructor <init>(kotlin/Function0<kotlin/Unit>) // com.compose.sdl.element/MiddleClickNode.<init>|<init>(kotlin.Function0<kotlin.Unit>){}[0]
|
||||
|
||||
final var onClick // com.compose.sdl.element/MiddleClickNode.onClick|{}onClick[0]
|
||||
final fun <get-onClick>(): kotlin/Function0<kotlin/Unit> // com.compose.sdl.element/MiddleClickNode.onClick.<get-onClick>|<get-onClick>(){}[0]
|
||||
final fun <set-onClick>(kotlin/Function0<kotlin/Unit>) // com.compose.sdl.element/MiddleClickNode.onClick.<set-onClick>|<set-onClick>(kotlin.Function0<kotlin.Unit>){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/OnDragModifier : androidx.compose.ui.node/ModifierNodeElement<com.compose.sdl.element/OnDragNode> { // com.compose.sdl.element/OnDragModifier|null[0]
|
||||
constructor <init>(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>, kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>, kotlin/Function0<kotlin/Unit>) // com.compose.sdl.element/OnDragModifier.<init>|<init>(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>;kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>;kotlin.Function0<kotlin.Unit>){}[0]
|
||||
|
||||
final val onDrag // com.compose.sdl.element/OnDragModifier.onDrag|{}onDrag[0]
|
||||
final fun <get-onDrag>(): kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit> // com.compose.sdl.element/OnDragModifier.onDrag.<get-onDrag>|<get-onDrag>(){}[0]
|
||||
final val onEnd // com.compose.sdl.element/OnDragModifier.onEnd|{}onEnd[0]
|
||||
final fun <get-onEnd>(): kotlin/Function0<kotlin/Unit> // com.compose.sdl.element/OnDragModifier.onEnd.<get-onEnd>|<get-onEnd>(){}[0]
|
||||
final val onStart // com.compose.sdl.element/OnDragModifier.onStart|{}onStart[0]
|
||||
final fun <get-onStart>(): kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit> // com.compose.sdl.element/OnDragModifier.onStart.<get-onStart>|<get-onStart>(){}[0]
|
||||
|
||||
final fun create(): com.compose.sdl.element/OnDragNode // com.compose.sdl.element/OnDragModifier.create|create(){}[0]
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl.element/OnDragModifier.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // com.compose.sdl.element/OnDragModifier.hashCode|hashCode(){}[0]
|
||||
final fun update(com.compose.sdl.element/OnDragNode) // com.compose.sdl.element/OnDragModifier.update|update(com.compose.sdl.element.OnDragNode){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/OnDragNode : androidx.compose.ui/Modifier.Node { // com.compose.sdl.element/OnDragNode|null[0]
|
||||
constructor <init>(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>, kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>, kotlin/Function0<kotlin/Unit>) // com.compose.sdl.element/OnDragNode.<init>|<init>(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>;kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>;kotlin.Function0<kotlin.Unit>){}[0]
|
||||
|
||||
final var onDrag // com.compose.sdl.element/OnDragNode.onDrag|{}onDrag[0]
|
||||
final fun <get-onDrag>(): kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit> // com.compose.sdl.element/OnDragNode.onDrag.<get-onDrag>|<get-onDrag>(){}[0]
|
||||
final fun <set-onDrag>(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>) // com.compose.sdl.element/OnDragNode.onDrag.<set-onDrag>|<set-onDrag>(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>){}[0]
|
||||
final var onEnd // com.compose.sdl.element/OnDragNode.onEnd|{}onEnd[0]
|
||||
final fun <get-onEnd>(): kotlin/Function0<kotlin/Unit> // com.compose.sdl.element/OnDragNode.onEnd.<get-onEnd>|<get-onEnd>(){}[0]
|
||||
final fun <set-onEnd>(kotlin/Function0<kotlin/Unit>) // com.compose.sdl.element/OnDragNode.onEnd.<set-onEnd>|<set-onEnd>(kotlin.Function0<kotlin.Unit>){}[0]
|
||||
final var onStart // com.compose.sdl.element/OnDragNode.onStart|{}onStart[0]
|
||||
final fun <get-onStart>(): kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit> // com.compose.sdl.element/OnDragNode.onStart.<get-onStart>|<get-onStart>(){}[0]
|
||||
final fun <set-onStart>(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>) // com.compose.sdl.element/OnDragNode.onStart.<set-onStart>|<set-onStart>(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/OnPressedModifier : androidx.compose.ui.node/ModifierNodeElement<com.compose.sdl.element/OnPressedNode> { // com.compose.sdl.element/OnPressedModifier|null[0]
|
||||
constructor <init>(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>) // com.compose.sdl.element/OnPressedModifier.<init>|<init>(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>){}[0]
|
||||
|
||||
final val handler // com.compose.sdl.element/OnPressedModifier.handler|{}handler[0]
|
||||
final fun <get-handler>(): kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit> // com.compose.sdl.element/OnPressedModifier.handler.<get-handler>|<get-handler>(){}[0]
|
||||
|
||||
final fun create(): com.compose.sdl.element/OnPressedNode // com.compose.sdl.element/OnPressedModifier.create|create(){}[0]
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl.element/OnPressedModifier.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // com.compose.sdl.element/OnPressedModifier.hashCode|hashCode(){}[0]
|
||||
final fun update(com.compose.sdl.element/OnPressedNode) // com.compose.sdl.element/OnPressedModifier.update|update(com.compose.sdl.element.OnPressedNode){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/OnPressedNode : androidx.compose.ui/Modifier.Node { // com.compose.sdl.element/OnPressedNode|null[0]
|
||||
constructor <init>(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>) // com.compose.sdl.element/OnPressedNode.<init>|<init>(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>){}[0]
|
||||
|
||||
final var handler // com.compose.sdl.element/OnPressedNode.handler|{}handler[0]
|
||||
final fun <get-handler>(): kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit> // com.compose.sdl.element/OnPressedNode.handler.<get-handler>|<get-handler>(){}[0]
|
||||
final fun <set-handler>(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>) // com.compose.sdl.element/OnPressedNode.handler.<set-handler>|<set-handler>(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/OnTextInputModifier : androidx.compose.ui.node/ModifierNodeElement<com.compose.sdl.element/OnTextInputNode> { // com.compose.sdl.element/OnTextInputModifier|null[0]
|
||||
constructor <init>(kotlin/Function1<kotlin/String, kotlin/Unit>) // com.compose.sdl.element/OnTextInputModifier.<init>|<init>(kotlin.Function1<kotlin.String,kotlin.Unit>){}[0]
|
||||
|
||||
final val handler // com.compose.sdl.element/OnTextInputModifier.handler|{}handler[0]
|
||||
final fun <get-handler>(): kotlin/Function1<kotlin/String, kotlin/Unit> // com.compose.sdl.element/OnTextInputModifier.handler.<get-handler>|<get-handler>(){}[0]
|
||||
|
||||
final fun create(): com.compose.sdl.element/OnTextInputNode // com.compose.sdl.element/OnTextInputModifier.create|create(){}[0]
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl.element/OnTextInputModifier.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // com.compose.sdl.element/OnTextInputModifier.hashCode|hashCode(){}[0]
|
||||
final fun update(com.compose.sdl.element/OnTextInputNode) // com.compose.sdl.element/OnTextInputModifier.update|update(com.compose.sdl.element.OnTextInputNode){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/OnTextInputNode : androidx.compose.ui/Modifier.Node { // com.compose.sdl.element/OnTextInputNode|null[0]
|
||||
constructor <init>(kotlin/Function1<kotlin/String, kotlin/Unit>) // com.compose.sdl.element/OnTextInputNode.<init>|<init>(kotlin.Function1<kotlin.String,kotlin.Unit>){}[0]
|
||||
|
||||
final var handler // com.compose.sdl.element/OnTextInputNode.handler|{}handler[0]
|
||||
final fun <get-handler>(): kotlin/Function1<kotlin/String, kotlin/Unit> // com.compose.sdl.element/OnTextInputNode.handler.<get-handler>|<get-handler>(){}[0]
|
||||
final fun <set-handler>(kotlin/Function1<kotlin/String, kotlin/Unit>) // com.compose.sdl.element/OnTextInputNode.handler.<set-handler>|<set-handler>(kotlin.Function1<kotlin.String,kotlin.Unit>){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/PressableModifier : androidx.compose.ui.node/ModifierNodeElement<com.compose.sdl.element/PressableNode> { // com.compose.sdl.element/PressableModifier|null[0]
|
||||
constructor <init>(kotlin/Function1<kotlin/Boolean, kotlin/Unit>) // com.compose.sdl.element/PressableModifier.<init>|<init>(kotlin.Function1<kotlin.Boolean,kotlin.Unit>){}[0]
|
||||
|
||||
final val onChange // com.compose.sdl.element/PressableModifier.onChange|{}onChange[0]
|
||||
final fun <get-onChange>(): kotlin/Function1<kotlin/Boolean, kotlin/Unit> // com.compose.sdl.element/PressableModifier.onChange.<get-onChange>|<get-onChange>(){}[0]
|
||||
|
||||
final fun create(): com.compose.sdl.element/PressableNode // com.compose.sdl.element/PressableModifier.create|create(){}[0]
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl.element/PressableModifier.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // com.compose.sdl.element/PressableModifier.hashCode|hashCode(){}[0]
|
||||
final fun update(com.compose.sdl.element/PressableNode) // com.compose.sdl.element/PressableModifier.update|update(com.compose.sdl.element.PressableNode){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/PressableNode : androidx.compose.ui/Modifier.Node { // com.compose.sdl.element/PressableNode|null[0]
|
||||
constructor <init>(kotlin/Function1<kotlin/Boolean, kotlin/Unit>) // com.compose.sdl.element/PressableNode.<init>|<init>(kotlin.Function1<kotlin.Boolean,kotlin.Unit>){}[0]
|
||||
|
||||
final var onChange // com.compose.sdl.element/PressableNode.onChange|{}onChange[0]
|
||||
final fun <get-onChange>(): kotlin/Function1<kotlin/Boolean, kotlin/Unit> // com.compose.sdl.element/PressableNode.onChange.<get-onChange>|<get-onChange>(){}[0]
|
||||
final fun <set-onChange>(kotlin/Function1<kotlin/Boolean, kotlin/Unit>) // com.compose.sdl.element/PressableNode.onChange.<set-onChange>|<set-onChange>(kotlin.Function1<kotlin.Boolean,kotlin.Unit>){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/SecondaryClickModifier : androidx.compose.ui.node/ModifierNodeElement<com.compose.sdl.element/SecondaryClickNode> { // com.compose.sdl.element/SecondaryClickModifier|null[0]
|
||||
constructor <init>(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>) // com.compose.sdl.element/SecondaryClickModifier.<init>|<init>(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>){}[0]
|
||||
|
||||
final val onClick // com.compose.sdl.element/SecondaryClickModifier.onClick|{}onClick[0]
|
||||
final fun <get-onClick>(): kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit> // com.compose.sdl.element/SecondaryClickModifier.onClick.<get-onClick>|<get-onClick>(){}[0]
|
||||
|
||||
final fun create(): com.compose.sdl.element/SecondaryClickNode // com.compose.sdl.element/SecondaryClickModifier.create|create(){}[0]
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl.element/SecondaryClickModifier.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // com.compose.sdl.element/SecondaryClickModifier.hashCode|hashCode(){}[0]
|
||||
final fun update(com.compose.sdl.element/SecondaryClickNode) // com.compose.sdl.element/SecondaryClickModifier.update|update(com.compose.sdl.element.SecondaryClickNode){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.element/SecondaryClickNode : androidx.compose.ui/Modifier.Node { // com.compose.sdl.element/SecondaryClickNode|null[0]
|
||||
constructor <init>(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>) // com.compose.sdl.element/SecondaryClickNode.<init>|<init>(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>){}[0]
|
||||
|
||||
final var onClick // com.compose.sdl.element/SecondaryClickNode.onClick|{}onClick[0]
|
||||
final fun <get-onClick>(): kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit> // com.compose.sdl.element/SecondaryClickNode.onClick.<get-onClick>|<get-onClick>(){}[0]
|
||||
final fun <set-onClick>(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>) // com.compose.sdl.element/SecondaryClickNode.onClick.<set-onClick>|<set-onClick>(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>){}[0]
|
||||
}
|
||||
|
||||
final class com.compose.sdl.graphics/ProjectCanvas : androidx.compose.ui.graphics/Canvas { // com.compose.sdl.graphics/ProjectCanvas|null[0]
|
||||
constructor <init>() // com.compose.sdl.graphics/ProjectCanvas.<init>|<init>(){}[0]
|
||||
|
||||
@@ -5649,8 +5539,6 @@ final class com.compose.sdl.node/ComposeRootHost { // com.compose.sdl.node/Compo
|
||||
|
||||
final val applier // com.compose.sdl.node/ComposeRootHost.applier|{}applier[0]
|
||||
final fun <get-applier>(): androidx.compose.runtime/Applier<*> // com.compose.sdl.node/ComposeRootHost.applier.<get-applier>|<get-applier>(){}[0]
|
||||
final val autofillTree // com.compose.sdl.node/ComposeRootHost.autofillTree|{}autofillTree[0]
|
||||
final fun <get-autofillTree>(): androidx.compose.ui.autofill/AutofillTree // com.compose.sdl.node/ComposeRootHost.autofillTree.<get-autofillTree>|<get-autofillTree>(){}[0]
|
||||
final val density // com.compose.sdl.node/ComposeRootHost.density|{}density[0]
|
||||
final fun <get-density>(): androidx.compose.ui.unit/Density // com.compose.sdl.node/ComposeRootHost.density.<get-density>|<get-density>(){}[0]
|
||||
final val focusManager // com.compose.sdl.node/ComposeRootHost.focusManager|{}focusManager[0]
|
||||
@@ -5665,8 +5553,6 @@ final class com.compose.sdl.node/ComposeRootHost { // com.compose.sdl.node/Compo
|
||||
final fun <get-layoutDirection>(): androidx.compose.ui.unit/LayoutDirection // com.compose.sdl.node/ComposeRootHost.layoutDirection.<get-layoutDirection>|<get-layoutDirection>(){}[0]
|
||||
final val softwareKeyboardController // com.compose.sdl.node/ComposeRootHost.softwareKeyboardController|{}softwareKeyboardController[0]
|
||||
final fun <get-softwareKeyboardController>(): androidx.compose.ui.platform/SoftwareKeyboardController // com.compose.sdl.node/ComposeRootHost.softwareKeyboardController.<get-softwareKeyboardController>|<get-softwareKeyboardController>(){}[0]
|
||||
final val textInputService // com.compose.sdl.node/ComposeRootHost.textInputService|{}textInputService[0]
|
||||
final fun <get-textInputService>(): androidx.compose.ui.text.input/TextInputService // com.compose.sdl.node/ComposeRootHost.textInputService.<get-textInputService>|<get-textInputService>(){}[0]
|
||||
final val textToolbar // com.compose.sdl.node/ComposeRootHost.textToolbar|{}textToolbar[0]
|
||||
final fun <get-textToolbar>(): androidx.compose.ui.platform/TextToolbar // com.compose.sdl.node/ComposeRootHost.textToolbar.<get-textToolbar>|<get-textToolbar>(){}[0]
|
||||
final val viewConfiguration // com.compose.sdl.node/ComposeRootHost.viewConfiguration|{}viewConfiguration[0]
|
||||
@@ -5676,9 +5562,12 @@ final class com.compose.sdl.node/ComposeRootHost { // com.compose.sdl.node/Compo
|
||||
|
||||
final fun attach() // com.compose.sdl.node/ComposeRootHost.attach|attach(){}[0]
|
||||
final fun dispatchKeyEvent(androidx.compose.ui.input.key/KeyEvent): kotlin/Boolean // com.compose.sdl.node/ComposeRootHost.dispatchKeyEvent|dispatchKeyEvent(androidx.compose.ui.input.key.KeyEvent){}[0]
|
||||
final fun dispatchTextInput(kotlin/String): kotlin/Boolean // com.compose.sdl.node/ComposeRootHost.dispatchTextInput|dispatchTextInput(kotlin.String){}[0]
|
||||
final fun measureAndLayout() // com.compose.sdl.node/ComposeRootHost.measureAndLayout|measureAndLayout(){}[0]
|
||||
final fun onPointer(kotlin/Float, kotlin/Float, kotlin/Int, kotlin/Int) // com.compose.sdl.node/ComposeRootHost.onPointer|onPointer(kotlin.Float;kotlin.Float;kotlin.Int;kotlin.Int){}[0]
|
||||
final fun onDropBegin() // com.compose.sdl.node/ComposeRootHost.onDropBegin|onDropBegin(){}[0]
|
||||
final fun onDropComplete() // com.compose.sdl.node/ComposeRootHost.onDropComplete|onDropComplete(){}[0]
|
||||
final fun onDropFile(kotlin/String) // com.compose.sdl.node/ComposeRootHost.onDropFile|onDropFile(kotlin.String){}[0]
|
||||
final fun onDropPosition(kotlin/Float, kotlin/Float) // com.compose.sdl.node/ComposeRootHost.onDropPosition|onDropPosition(kotlin.Float;kotlin.Float){}[0]
|
||||
final fun onDropText(kotlin/String) // com.compose.sdl.node/ComposeRootHost.onDropText|onDropText(kotlin.String){}[0]
|
||||
final fun onPointerRaw(kotlin/Float, kotlin/Float, kotlin/Int, kotlin/Int, kotlin/Long) // com.compose.sdl.node/ComposeRootHost.onPointerRaw|onPointerRaw(kotlin.Float;kotlin.Float;kotlin.Int;kotlin.Int;kotlin.Long){}[0]
|
||||
final fun onWheel(kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Float, kotlin/Long) // com.compose.sdl.node/ComposeRootHost.onWheel|onWheel(kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Float;kotlin.Long){}[0]
|
||||
final fun sendAnimationFrame(kotlin/Long) // com.compose.sdl.node/ComposeRootHost.sendAnimationFrame|sendAnimationFrame(kotlin.Long){}[0]
|
||||
@@ -8387,6 +8276,45 @@ sealed class androidx.compose.ui.text.font/SystemFontFamily : androidx.compose.u
|
||||
sealed class androidx.compose.ui.text/TtsAnnotation : androidx.compose.ui.text/AnnotatedString.Annotation // androidx.compose.ui.text/TtsAnnotation|null[0]
|
||||
|
||||
sealed class com.compose.sdl/AppEvent { // com.compose.sdl/AppEvent|null[0]
|
||||
final enum class DropPhase : kotlin/Enum<com.compose.sdl/AppEvent.DropPhase> { // com.compose.sdl/AppEvent.DropPhase|null[0]
|
||||
enum entry BEGIN // com.compose.sdl/AppEvent.DropPhase.BEGIN|null[0]
|
||||
enum entry COMPLETE // com.compose.sdl/AppEvent.DropPhase.COMPLETE|null[0]
|
||||
enum entry FILE // com.compose.sdl/AppEvent.DropPhase.FILE|null[0]
|
||||
enum entry POSITION // com.compose.sdl/AppEvent.DropPhase.POSITION|null[0]
|
||||
enum entry TEXT // com.compose.sdl/AppEvent.DropPhase.TEXT|null[0]
|
||||
|
||||
final val entries // com.compose.sdl/AppEvent.DropPhase.entries|#static{}entries[0]
|
||||
final fun <get-entries>(): kotlin.enums/EnumEntries<com.compose.sdl/AppEvent.DropPhase> // com.compose.sdl/AppEvent.DropPhase.entries.<get-entries>|<get-entries>#static(){}[0]
|
||||
|
||||
final fun valueOf(kotlin/String): com.compose.sdl/AppEvent.DropPhase // com.compose.sdl/AppEvent.DropPhase.valueOf|valueOf#static(kotlin.String){}[0]
|
||||
final fun values(): kotlin/Array<com.compose.sdl/AppEvent.DropPhase> // com.compose.sdl/AppEvent.DropPhase.values|values#static(){}[0]
|
||||
}
|
||||
|
||||
final class Drop : com.compose.sdl/AppEvent { // com.compose.sdl/AppEvent.Drop|null[0]
|
||||
constructor <init>(kotlin/UInt, com.compose.sdl/AppEvent.DropPhase, kotlin/Float = ..., kotlin/Float = ..., kotlin/String? = ...) // com.compose.sdl/AppEvent.Drop.<init>|<init>(kotlin.UInt;com.compose.sdl.AppEvent.DropPhase;kotlin.Float;kotlin.Float;kotlin.String?){}[0]
|
||||
|
||||
final val data // com.compose.sdl/AppEvent.Drop.data|{}data[0]
|
||||
final fun <get-data>(): kotlin/String? // com.compose.sdl/AppEvent.Drop.data.<get-data>|<get-data>(){}[0]
|
||||
final val phase // com.compose.sdl/AppEvent.Drop.phase|{}phase[0]
|
||||
final fun <get-phase>(): com.compose.sdl/AppEvent.DropPhase // com.compose.sdl/AppEvent.Drop.phase.<get-phase>|<get-phase>(){}[0]
|
||||
final val windowId // com.compose.sdl/AppEvent.Drop.windowId|{}windowId[0]
|
||||
final fun <get-windowId>(): kotlin/UInt // com.compose.sdl/AppEvent.Drop.windowId.<get-windowId>|<get-windowId>(){}[0]
|
||||
final val x // com.compose.sdl/AppEvent.Drop.x|{}x[0]
|
||||
final fun <get-x>(): kotlin/Float // com.compose.sdl/AppEvent.Drop.x.<get-x>|<get-x>(){}[0]
|
||||
final val y // com.compose.sdl/AppEvent.Drop.y|{}y[0]
|
||||
final fun <get-y>(): kotlin/Float // com.compose.sdl/AppEvent.Drop.y.<get-y>|<get-y>(){}[0]
|
||||
|
||||
final fun component1(): kotlin/UInt // com.compose.sdl/AppEvent.Drop.component1|component1(){}[0]
|
||||
final fun component2(): com.compose.sdl/AppEvent.DropPhase // com.compose.sdl/AppEvent.Drop.component2|component2(){}[0]
|
||||
final fun component3(): kotlin/Float // com.compose.sdl/AppEvent.Drop.component3|component3(){}[0]
|
||||
final fun component4(): kotlin/Float // com.compose.sdl/AppEvent.Drop.component4|component4(){}[0]
|
||||
final fun component5(): kotlin/String? // com.compose.sdl/AppEvent.Drop.component5|component5(){}[0]
|
||||
final fun copy(kotlin/UInt = ..., com.compose.sdl/AppEvent.DropPhase = ..., kotlin/Float = ..., kotlin/Float = ..., kotlin/String? = ...): com.compose.sdl/AppEvent.Drop // com.compose.sdl/AppEvent.Drop.copy|copy(kotlin.UInt;com.compose.sdl.AppEvent.DropPhase;kotlin.Float;kotlin.Float;kotlin.String?){}[0]
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl/AppEvent.Drop.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // com.compose.sdl/AppEvent.Drop.hashCode|hashCode(){}[0]
|
||||
final fun toString(): kotlin/String // com.compose.sdl/AppEvent.Drop.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final class Key : com.compose.sdl/AppEvent { // com.compose.sdl/AppEvent.Key|null[0]
|
||||
constructor <init>(androidx.compose.ui.input.key/KeyEvent, kotlin/UInt = ...) // com.compose.sdl/AppEvent.Key.<init>|<init>(androidx.compose.ui.input.key.KeyEvent;kotlin.UInt){}[0]
|
||||
|
||||
@@ -8473,6 +8401,25 @@ sealed class com.compose.sdl/AppEvent { // com.compose.sdl/AppEvent|null[0]
|
||||
final fun toString(): kotlin/String // com.compose.sdl/AppEvent.TextInput.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final class WindowActivation : com.compose.sdl/AppEvent { // com.compose.sdl/AppEvent.WindowActivation|null[0]
|
||||
constructor <init>(kotlin/UInt = ..., kotlin/Boolean? = ..., kotlin/Boolean? = ...) // com.compose.sdl/AppEvent.WindowActivation.<init>|<init>(kotlin.UInt;kotlin.Boolean?;kotlin.Boolean?){}[0]
|
||||
|
||||
final val focused // com.compose.sdl/AppEvent.WindowActivation.focused|{}focused[0]
|
||||
final fun <get-focused>(): kotlin/Boolean? // com.compose.sdl/AppEvent.WindowActivation.focused.<get-focused>|<get-focused>(){}[0]
|
||||
final val visible // com.compose.sdl/AppEvent.WindowActivation.visible|{}visible[0]
|
||||
final fun <get-visible>(): kotlin/Boolean? // com.compose.sdl/AppEvent.WindowActivation.visible.<get-visible>|<get-visible>(){}[0]
|
||||
final val windowId // com.compose.sdl/AppEvent.WindowActivation.windowId|{}windowId[0]
|
||||
final fun <get-windowId>(): kotlin/UInt // com.compose.sdl/AppEvent.WindowActivation.windowId.<get-windowId>|<get-windowId>(){}[0]
|
||||
|
||||
final fun component1(): kotlin/UInt // com.compose.sdl/AppEvent.WindowActivation.component1|component1(){}[0]
|
||||
final fun component2(): kotlin/Boolean? // com.compose.sdl/AppEvent.WindowActivation.component2|component2(){}[0]
|
||||
final fun component3(): kotlin/Boolean? // com.compose.sdl/AppEvent.WindowActivation.component3|component3(){}[0]
|
||||
final fun copy(kotlin/UInt = ..., kotlin/Boolean? = ..., kotlin/Boolean? = ...): com.compose.sdl/AppEvent.WindowActivation // com.compose.sdl/AppEvent.WindowActivation.copy|copy(kotlin.UInt;kotlin.Boolean?;kotlin.Boolean?){}[0]
|
||||
final fun equals(kotlin/Any?): kotlin/Boolean // com.compose.sdl/AppEvent.WindowActivation.equals|equals(kotlin.Any?){}[0]
|
||||
final fun hashCode(): kotlin/Int // com.compose.sdl/AppEvent.WindowActivation.hashCode|hashCode(){}[0]
|
||||
final fun toString(): kotlin/String // com.compose.sdl/AppEvent.WindowActivation.toString|toString(){}[0]
|
||||
}
|
||||
|
||||
final class WindowClose : com.compose.sdl/AppEvent { // com.compose.sdl/AppEvent.WindowClose|null[0]
|
||||
constructor <init>(kotlin/UInt = ...) // com.compose.sdl/AppEvent.WindowClose.<init>|<init>(kotlin.UInt){}[0]
|
||||
|
||||
@@ -9299,16 +9246,6 @@ final val androidx.compose.ui.platform/androidx_compose_ui_platform_InspectorVal
|
||||
final val androidx.compose.ui.platform/androidx_compose_ui_platform_PlatformWindowInsetsProviderNode$stableprop // androidx.compose.ui.platform/androidx_compose_ui_platform_PlatformWindowInsetsProviderNode$stableprop|#static{}androidx_compose_ui_platform_PlatformWindowInsetsProviderNode$stableprop[0]
|
||||
final val androidx.compose.ui.platform/androidx_compose_ui_platform_ValueElement$stableprop // androidx.compose.ui.platform/androidx_compose_ui_platform_ValueElement$stableprop|#static{}androidx_compose_ui_platform_ValueElement$stableprop[0]
|
||||
final val androidx.compose.ui.platform/androidx_compose_ui_platform_ValueElementSequence$stableprop // androidx.compose.ui.platform/androidx_compose_ui_platform_ValueElementSequence$stableprop|#static{}androidx_compose_ui_platform_ValueElementSequence$stableprop[0]
|
||||
final val androidx.compose.ui.platform/currentClipboard // androidx.compose.ui.platform/currentClipboard|{}currentClipboard[0]
|
||||
final fun <get-currentClipboard>(): androidx.compose.ui.platform/ClipboardManager // androidx.compose.ui.platform/currentClipboard.<get-currentClipboard>|<get-currentClipboard>(){}[0]
|
||||
final val androidx.compose.ui.platform/defaultClipboard // androidx.compose.ui.platform/defaultClipboard|{}defaultClipboard[0]
|
||||
final fun <get-defaultClipboard>(): androidx.compose.ui.platform/Clipboard // androidx.compose.ui.platform/defaultClipboard.<get-defaultClipboard>|<get-defaultClipboard>(){}[0]
|
||||
final val androidx.compose.ui.platform/defaultClipboardManager // androidx.compose.ui.platform/defaultClipboardManager|{}defaultClipboardManager[0]
|
||||
final fun <get-defaultClipboardManager>(): androidx.compose.ui.platform/ClipboardManager // androidx.compose.ui.platform/defaultClipboardManager.<get-defaultClipboardManager>|<get-defaultClipboardManager>(){}[0]
|
||||
final val androidx.compose.ui.platform/platformClipboard // androidx.compose.ui.platform/platformClipboard|{}platformClipboard[0]
|
||||
final fun <get-platformClipboard>(): androidx.compose.ui.platform/Clipboard // androidx.compose.ui.platform/platformClipboard.<get-platformClipboard>|<get-platformClipboard>(){}[0]
|
||||
final val androidx.compose.ui.platform/platformClipboardManager // androidx.compose.ui.platform/platformClipboardManager|{}platformClipboardManager[0]
|
||||
final fun <get-platformClipboardManager>(): androidx.compose.ui.platform/ClipboardManager // androidx.compose.ui.platform/platformClipboardManager.<get-platformClipboardManager>|<get-platformClipboardManager>(){}[0]
|
||||
final val androidx.compose.ui.platform/safeContent // androidx.compose.ui.platform/safeContent|@androidx.compose.ui.platform.PlatformWindowInsets{}safeContent[0]
|
||||
final fun (androidx.compose.ui.platform/PlatformWindowInsets).<get-safeContent>(): androidx.compose.ui.platform/PlatformInsets // androidx.compose.ui.platform/safeContent.<get-safeContent>|<get-safeContent>@androidx.compose.ui.platform.PlatformWindowInsets(){}[0]
|
||||
final val androidx.compose.ui.platform/safeDrawing // androidx.compose.ui.platform/safeDrawing|@androidx.compose.ui.platform.PlatformWindowInsets{}safeDrawing[0]
|
||||
@@ -9424,22 +9361,6 @@ final val com.compose.sdl.element/com_compose_sdl_element_ClipModifier$stablepro
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_ClipNode$stableprop // com.compose.sdl.element/com_compose_sdl_element_ClipNode$stableprop|#static{}com_compose_sdl_element_ClipNode$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_GraphicsLayerModifier$stableprop // com.compose.sdl.element/com_compose_sdl_element_GraphicsLayerModifier$stableprop|#static{}com_compose_sdl_element_GraphicsLayerModifier$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_GraphicsLayerNode$stableprop // com.compose.sdl.element/com_compose_sdl_element_GraphicsLayerNode$stableprop|#static{}com_compose_sdl_element_GraphicsLayerNode$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_MiddleClickModifier$stableprop // com.compose.sdl.element/com_compose_sdl_element_MiddleClickModifier$stableprop|#static{}com_compose_sdl_element_MiddleClickModifier$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_MiddleClickNode$stableprop // com.compose.sdl.element/com_compose_sdl_element_MiddleClickNode$stableprop|#static{}com_compose_sdl_element_MiddleClickNode$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_OnDragModifier$stableprop // com.compose.sdl.element/com_compose_sdl_element_OnDragModifier$stableprop|#static{}com_compose_sdl_element_OnDragModifier$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_OnDragNode$stableprop // com.compose.sdl.element/com_compose_sdl_element_OnDragNode$stableprop|#static{}com_compose_sdl_element_OnDragNode$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_OnPressedModifier$stableprop // com.compose.sdl.element/com_compose_sdl_element_OnPressedModifier$stableprop|#static{}com_compose_sdl_element_OnPressedModifier$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_OnPressedNode$stableprop // com.compose.sdl.element/com_compose_sdl_element_OnPressedNode$stableprop|#static{}com_compose_sdl_element_OnPressedNode$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_OnTextInputModifier$stableprop // com.compose.sdl.element/com_compose_sdl_element_OnTextInputModifier$stableprop|#static{}com_compose_sdl_element_OnTextInputModifier$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_OnTextInputNode$stableprop // com.compose.sdl.element/com_compose_sdl_element_OnTextInputNode$stableprop|#static{}com_compose_sdl_element_OnTextInputNode$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_PressableModifier$stableprop // com.compose.sdl.element/com_compose_sdl_element_PressableModifier$stableprop|#static{}com_compose_sdl_element_PressableModifier$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_PressableNode$stableprop // com.compose.sdl.element/com_compose_sdl_element_PressableNode$stableprop|#static{}com_compose_sdl_element_PressableNode$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_SecondaryClickModifier$stableprop // com.compose.sdl.element/com_compose_sdl_element_SecondaryClickModifier$stableprop|#static{}com_compose_sdl_element_SecondaryClickModifier$stableprop[0]
|
||||
final val com.compose.sdl.element/com_compose_sdl_element_SecondaryClickNode$stableprop // com.compose.sdl.element/com_compose_sdl_element_SecondaryClickNode$stableprop|#static{}com_compose_sdl_element_SecondaryClickNode$stableprop[0]
|
||||
final val com.compose.sdl.graphics/a8 // com.compose.sdl.graphics/a8|@androidx.compose.ui.graphics.Color{}a8[0]
|
||||
final fun (androidx.compose.ui.graphics/Color).<get-a8>(): kotlin/Int // com.compose.sdl.graphics/a8.<get-a8>|<get-a8>@androidx.compose.ui.graphics.Color(){}[0]
|
||||
final val com.compose.sdl.graphics/b8 // com.compose.sdl.graphics/b8|@androidx.compose.ui.graphics.Color{}b8[0]
|
||||
final fun (androidx.compose.ui.graphics/Color).<get-b8>(): kotlin/Int // com.compose.sdl.graphics/b8.<get-b8>|<get-b8>@androidx.compose.ui.graphics.Color(){}[0]
|
||||
final val com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_Close$stableprop // com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_Close$stableprop|#static{}com_compose_sdl_graphics_PathCommand_Close$stableprop[0]
|
||||
final val com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_CubicTo$stableprop // com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_CubicTo$stableprop|#static{}com_compose_sdl_graphics_PathCommand_CubicTo$stableprop[0]
|
||||
final val com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_LineTo$stableprop // com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_LineTo$stableprop|#static{}com_compose_sdl_graphics_PathCommand_LineTo$stableprop[0]
|
||||
@@ -9450,8 +9371,6 @@ final val com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectImageBitmap$s
|
||||
final val com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPaint$stableprop // com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPaint$stableprop|#static{}com_compose_sdl_graphics_ProjectPaint$stableprop[0]
|
||||
final val com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPath$stableprop // com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPath$stableprop|#static{}com_compose_sdl_graphics_ProjectPath$stableprop[0]
|
||||
final val com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPathIterator$stableprop // com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPathIterator$stableprop|#static{}com_compose_sdl_graphics_ProjectPathIterator$stableprop[0]
|
||||
final val com.compose.sdl.graphics/g8 // com.compose.sdl.graphics/g8|@androidx.compose.ui.graphics.Color{}g8[0]
|
||||
final fun (androidx.compose.ui.graphics/Color).<get-g8>(): kotlin/Int // com.compose.sdl.graphics/g8.<get-g8>|<get-g8>@androidx.compose.ui.graphics.Color(){}[0]
|
||||
final val com.compose.sdl.graphics/gradientCenter // com.compose.sdl.graphics/gradientCenter|@androidx.compose.ui.graphics.RadialGradient{}gradientCenter[0]
|
||||
final fun (androidx.compose.ui.graphics/RadialGradient).<get-gradientCenter>(): androidx.compose.ui.geometry/Offset // com.compose.sdl.graphics/gradientCenter.<get-gradientCenter>|<get-gradientCenter>@androidx.compose.ui.graphics.RadialGradient(){}[0]
|
||||
final val com.compose.sdl.graphics/gradientCenter // com.compose.sdl.graphics/gradientCenter|@androidx.compose.ui.graphics.SweepGradient{}gradientCenter[0]
|
||||
@@ -9478,8 +9397,6 @@ final val com.compose.sdl.graphics/gradientTileMode // com.compose.sdl.graphics/
|
||||
final fun (androidx.compose.ui.graphics/LinearGradient).<get-gradientTileMode>(): androidx.compose.ui.graphics/TileMode // com.compose.sdl.graphics/gradientTileMode.<get-gradientTileMode>|<get-gradientTileMode>@androidx.compose.ui.graphics.LinearGradient(){}[0]
|
||||
final val com.compose.sdl.graphics/gradientTileMode // com.compose.sdl.graphics/gradientTileMode|@androidx.compose.ui.graphics.RadialGradient{}gradientTileMode[0]
|
||||
final fun (androidx.compose.ui.graphics/RadialGradient).<get-gradientTileMode>(): androidx.compose.ui.graphics/TileMode // com.compose.sdl.graphics/gradientTileMode.<get-gradientTileMode>|<get-gradientTileMode>@androidx.compose.ui.graphics.RadialGradient(){}[0]
|
||||
final val com.compose.sdl.graphics/r8 // com.compose.sdl.graphics/r8|@androidx.compose.ui.graphics.Color{}r8[0]
|
||||
final fun (androidx.compose.ui.graphics/Color).<get-r8>(): kotlin/Int // com.compose.sdl.graphics/r8.<get-r8>|<get-r8>@androidx.compose.ui.graphics.Color(){}[0]
|
||||
final val com.compose.sdl.icons/com_compose_sdl_icons_IconFont$stableprop // com.compose.sdl.icons/com_compose_sdl_icons_IconFont$stableprop|#static{}com_compose_sdl_icons_IconFont$stableprop[0]
|
||||
final val com.compose.sdl.input/com_compose_sdl_input_LegacyPointerEvent$stableprop // com.compose.sdl.input/com_compose_sdl_input_LegacyPointerEvent$stableprop|#static{}com_compose_sdl_input_LegacyPointerEvent$stableprop[0]
|
||||
final val com.compose.sdl.layout/intOffset // com.compose.sdl.layout/intOffset|@androidx.compose.ui.layout.LayoutCoordinates{}intOffset[0]
|
||||
@@ -9512,12 +9429,14 @@ final val com.compose.sdl.window/com_compose_sdl_window_PopupHostState$stablepro
|
||||
final val com.compose.sdl/LocalComposeNativeWindow // com.compose.sdl/LocalComposeNativeWindow|{}LocalComposeNativeWindow[0]
|
||||
final fun <get-LocalComposeNativeWindow>(): androidx.compose.runtime/ProvidableCompositionLocal<com.compose.sdl/ComposeNativeWindow> // com.compose.sdl/LocalComposeNativeWindow.<get-LocalComposeNativeWindow>|<get-LocalComposeNativeWindow>(){}[0]
|
||||
final val com.compose.sdl/com_compose_sdl_AppEvent$stableprop // com.compose.sdl/com_compose_sdl_AppEvent$stableprop|#static{}com_compose_sdl_AppEvent$stableprop[0]
|
||||
final val com.compose.sdl/com_compose_sdl_AppEvent_Drop$stableprop // com.compose.sdl/com_compose_sdl_AppEvent_Drop$stableprop|#static{}com_compose_sdl_AppEvent_Drop$stableprop[0]
|
||||
final val com.compose.sdl/com_compose_sdl_AppEvent_Key$stableprop // com.compose.sdl/com_compose_sdl_AppEvent_Key$stableprop|#static{}com_compose_sdl_AppEvent_Key$stableprop[0]
|
||||
final val com.compose.sdl/com_compose_sdl_AppEvent_MouseWheel$stableprop // com.compose.sdl/com_compose_sdl_AppEvent_MouseWheel$stableprop|#static{}com_compose_sdl_AppEvent_MouseWheel$stableprop[0]
|
||||
final val com.compose.sdl/com_compose_sdl_AppEvent_Pointer$stableprop // com.compose.sdl/com_compose_sdl_AppEvent_Pointer$stableprop|#static{}com_compose_sdl_AppEvent_Pointer$stableprop[0]
|
||||
final val com.compose.sdl/com_compose_sdl_AppEvent_Quit$stableprop // com.compose.sdl/com_compose_sdl_AppEvent_Quit$stableprop|#static{}com_compose_sdl_AppEvent_Quit$stableprop[0]
|
||||
final val com.compose.sdl/com_compose_sdl_AppEvent_RedrawNeeded$stableprop // com.compose.sdl/com_compose_sdl_AppEvent_RedrawNeeded$stableprop|#static{}com_compose_sdl_AppEvent_RedrawNeeded$stableprop[0]
|
||||
final val com.compose.sdl/com_compose_sdl_AppEvent_TextInput$stableprop // com.compose.sdl/com_compose_sdl_AppEvent_TextInput$stableprop|#static{}com_compose_sdl_AppEvent_TextInput$stableprop[0]
|
||||
final val com.compose.sdl/com_compose_sdl_AppEvent_WindowActivation$stableprop // com.compose.sdl/com_compose_sdl_AppEvent_WindowActivation$stableprop|#static{}com_compose_sdl_AppEvent_WindowActivation$stableprop[0]
|
||||
final val com.compose.sdl/com_compose_sdl_AppEvent_WindowClose$stableprop // com.compose.sdl/com_compose_sdl_AppEvent_WindowClose$stableprop|#static{}com_compose_sdl_AppEvent_WindowClose$stableprop[0]
|
||||
final val com.compose.sdl/com_compose_sdl_AppEvent_WindowResized$stableprop // com.compose.sdl/com_compose_sdl_AppEvent_WindowResized$stableprop|#static{}com_compose_sdl_AppEvent_WindowResized$stableprop[0]
|
||||
final val com.compose.sdl/com_compose_sdl_ComposeNativeWindow$stableprop // com.compose.sdl/com_compose_sdl_ComposeNativeWindow$stableprop|#static{}com_compose_sdl_ComposeNativeWindow$stableprop[0]
|
||||
@@ -9655,6 +9574,8 @@ final var androidx.compose.ui/isDialogAnimationEnabled // androidx.compose.ui/is
|
||||
final var androidx.compose.ui/useLegacyRenderNodeLayers // androidx.compose.ui/useLegacyRenderNodeLayers|@androidx.compose.ui.ComposeUiFlags{}useLegacyRenderNodeLayers[0]
|
||||
final fun (androidx.compose.ui/ComposeUiFlags).<get-useLegacyRenderNodeLayers>(): kotlin/Boolean // androidx.compose.ui/useLegacyRenderNodeLayers.<get-useLegacyRenderNodeLayers>|<get-useLegacyRenderNodeLayers>@androidx.compose.ui.ComposeUiFlags(){}[0]
|
||||
final fun (androidx.compose.ui/ComposeUiFlags).<set-useLegacyRenderNodeLayers>(kotlin/Boolean) // androidx.compose.ui/useLegacyRenderNodeLayers.<set-useLegacyRenderNodeLayers>|<set-useLegacyRenderNodeLayers>@androidx.compose.ui.ComposeUiFlags(kotlin.Boolean){}[0]
|
||||
final var com.compose.sdl.graphics/encodedImageDecoder // com.compose.sdl.graphics/encodedImageDecoder|{}encodedImageDecoder[0]
|
||||
final fun <get-encodedImageDecoder>(): com.compose.sdl.graphics/EncodedImageDecoder? // com.compose.sdl.graphics/encodedImageDecoder.<get-encodedImageDecoder>|<get-encodedImageDecoder>(){}[0]
|
||||
final var com.compose.sdl.res/currentImageLoader // com.compose.sdl.res/currentImageLoader|{}currentImageLoader[0]
|
||||
final fun <get-currentImageLoader>(): com.compose.sdl.res/ImageLoader // com.compose.sdl.res/currentImageLoader.<get-currentImageLoader>|<get-currentImageLoader>(){}[0]
|
||||
final fun <set-currentImageLoader>(com.compose.sdl.res/ImageLoader) // com.compose.sdl.res/currentImageLoader.<set-currentImageLoader>|<set-currentImageLoader>(com.compose.sdl.res.ImageLoader){}[0]
|
||||
@@ -9703,9 +9624,6 @@ final fun (androidx.compose.ui.graphics/Canvas).androidx.compose.ui.graphics/sca
|
||||
final fun (androidx.compose.ui.graphics/Color).androidx.compose.ui.graphics/compositeOver(androidx.compose.ui.graphics/Color): androidx.compose.ui.graphics/Color // androidx.compose.ui.graphics/compositeOver|compositeOver@androidx.compose.ui.graphics.Color(androidx.compose.ui.graphics.Color){}[0]
|
||||
final fun (androidx.compose.ui.graphics/Color).androidx.compose.ui.graphics/luminance(): kotlin/Float // androidx.compose.ui.graphics/luminance|luminance@androidx.compose.ui.graphics.Color(){}[0]
|
||||
final fun (androidx.compose.ui.graphics/Color).androidx.compose.ui.graphics/toArgb(): kotlin/Int // androidx.compose.ui.graphics/toArgb|toArgb@androidx.compose.ui.graphics.Color(){}[0]
|
||||
final fun (androidx.compose.ui.graphics/Color).com.compose.sdl.graphics/blend(androidx.compose.ui.graphics/Color, kotlin/Float): androidx.compose.ui.graphics/Color // com.compose.sdl.graphics/blend|blend@androidx.compose.ui.graphics.Color(androidx.compose.ui.graphics.Color;kotlin.Float){}[0]
|
||||
final fun (androidx.compose.ui.graphics/Color).com.compose.sdl.graphics/darken(kotlin/Float): androidx.compose.ui.graphics/Color // com.compose.sdl.graphics/darken|darken@androidx.compose.ui.graphics.Color(kotlin.Float){}[0]
|
||||
final fun (androidx.compose.ui.graphics/Color).com.compose.sdl.graphics/lighten(kotlin/Float): androidx.compose.ui.graphics/Color // com.compose.sdl.graphics/lighten|lighten@androidx.compose.ui.graphics.Color(kotlin.Float){}[0]
|
||||
final fun (androidx.compose.ui.graphics/ImageBitmap).androidx.compose.ui.graphics/toPixelMap(kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ..., kotlin/IntArray = ..., kotlin/Int = ..., kotlin/Int = ...): androidx.compose.ui.graphics/PixelMap // androidx.compose.ui.graphics/toPixelMap|toPixelMap@androidx.compose.ui.graphics.ImageBitmap(kotlin.Int;kotlin.Int;kotlin.Int;kotlin.Int;kotlin.IntArray;kotlin.Int;kotlin.Int){}[0]
|
||||
final fun (androidx.compose.ui.graphics/Matrix).androidx.compose.ui.graphics/isIdentity(): kotlin/Boolean // androidx.compose.ui.graphics/isIdentity|isIdentity@androidx.compose.ui.graphics.Matrix(){}[0]
|
||||
final fun (androidx.compose.ui.graphics/Path).androidx.compose.ui.graphics/addOutline(androidx.compose.ui.graphics/Outline) // androidx.compose.ui.graphics/addOutline|addOutline@androidx.compose.ui.graphics.Path(androidx.compose.ui.graphics.Outline){}[0]
|
||||
@@ -9908,12 +9826,6 @@ final fun (androidx.compose.ui/Modifier).androidx.compose.ui/preferredFrameRate(
|
||||
final fun (androidx.compose.ui/Modifier).androidx.compose.ui/preferredFrameRate(kotlin/Float): androidx.compose.ui/Modifier // androidx.compose.ui/preferredFrameRate|preferredFrameRate@androidx.compose.ui.Modifier(kotlin.Float){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).androidx.compose.ui/sensitiveContent(kotlin/Boolean = ...): androidx.compose.ui/Modifier // androidx.compose.ui/sensitiveContent|sensitiveContent@androidx.compose.ui.Modifier(kotlin.Boolean){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).androidx.compose.ui/zIndex(kotlin/Float): androidx.compose.ui/Modifier // androidx.compose.ui/zIndex|zIndex@androidx.compose.ui.Modifier(kotlin.Float){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).com.compose.sdl.modifier/onDrag(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit> = ..., kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit> = ..., kotlin/Function0<kotlin/Unit> = ...): androidx.compose.ui/Modifier // com.compose.sdl.modifier/onDrag|onDrag@androidx.compose.ui.Modifier(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>;kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>;kotlin.Function0<kotlin.Unit>){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).com.compose.sdl.modifier/onMiddleClick(kotlin/Function0<kotlin/Unit>): androidx.compose.ui/Modifier // com.compose.sdl.modifier/onMiddleClick|onMiddleClick@androidx.compose.ui.Modifier(kotlin.Function0<kotlin.Unit>){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).com.compose.sdl.modifier/onPressed(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>): androidx.compose.ui/Modifier // com.compose.sdl.modifier/onPressed|onPressed@androidx.compose.ui.Modifier(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).com.compose.sdl.modifier/onSecondaryClick(kotlin/Function2<kotlin/Int, kotlin/Int, kotlin/Unit>): androidx.compose.ui/Modifier // com.compose.sdl.modifier/onSecondaryClick|onSecondaryClick@androidx.compose.ui.Modifier(kotlin.Function2<kotlin.Int,kotlin.Int,kotlin.Unit>){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).com.compose.sdl.modifier/onTextInput(kotlin/Function1<kotlin/String, kotlin/Unit>): androidx.compose.ui/Modifier // com.compose.sdl.modifier/onTextInput|onTextInput@androidx.compose.ui.Modifier(kotlin.Function1<kotlin.String,kotlin.Unit>){}[0]
|
||||
final fun (androidx.compose.ui/Modifier).com.compose.sdl.modifier/pressable(kotlin/Function1<kotlin/Boolean, kotlin/Unit>): androidx.compose.ui/Modifier // com.compose.sdl.modifier/pressable|pressable@androidx.compose.ui.Modifier(kotlin.Function1<kotlin.Boolean,kotlin.Unit>){}[0]
|
||||
final fun (kotlin.collections/List<androidx.compose.ui.graphics.vector/PathNode>).androidx.compose.ui.graphics.vector/toPath(androidx.compose.ui.graphics/Path = ...): androidx.compose.ui.graphics/Path // androidx.compose.ui.graphics.vector/toPath|toPath@kotlin.collections.List<androidx.compose.ui.graphics.vector.PathNode>(androidx.compose.ui.graphics.Path){}[0]
|
||||
final fun (kotlin/ByteArray).androidx.compose.ui.graphics/decodeToImageBitmap(): androidx.compose.ui.graphics/ImageBitmap // androidx.compose.ui.graphics/decodeToImageBitmap|decodeToImageBitmap@kotlin.ByteArray(){}[0]
|
||||
final fun (kotlin/CharSequence).androidx.compose.ui.text/substring(androidx.compose.ui.text/TextRange): kotlin/String // androidx.compose.ui.text/substring|substring@kotlin.CharSequence(androidx.compose.ui.text.TextRange){}[0]
|
||||
@@ -10168,6 +10080,7 @@ final fun androidx.compose.ui.platform/androidx_compose_ui_platform_ValueElement
|
||||
final fun androidx.compose.ui.platform/androidx_compose_ui_platform_ValueElementSequence$stableprop_getter(): kotlin/Int // androidx.compose.ui.platform/androidx_compose_ui_platform_ValueElementSequence$stableprop_getter|androidx_compose_ui_platform_ValueElementSequence$stableprop_getter(){}[0]
|
||||
final fun androidx.compose.ui.platform/findComposeDefaultViewModelStoreOwner(androidx.compose.runtime/Composer?, kotlin/Int): androidx.lifecycle/ViewModelStoreOwner? // androidx.compose.ui.platform/findComposeDefaultViewModelStoreOwner|findComposeDefaultViewModelStoreOwner(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun androidx.compose.ui.platform/findDefaultNavigationEventDispatcherOwner(androidx.compose.runtime/Composer?, kotlin/Int): androidx.navigationevent/NavigationEventDispatcherOwner? // androidx.compose.ui.platform/findDefaultNavigationEventDispatcherOwner|findDefaultNavigationEventDispatcherOwner(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
|
||||
final fun androidx.compose.ui.platform/platformClipboard(): androidx.compose.ui.platform/Clipboard // androidx.compose.ui.platform/platformClipboard|platformClipboard(){}[0]
|
||||
final fun androidx.compose.ui.scene/androidx_compose_ui_scene_ComposeScenePointer$stableprop_getter(): kotlin/Int // androidx.compose.ui.scene/androidx_compose_ui_scene_ComposeScenePointer$stableprop_getter|androidx_compose_ui_scene_ComposeScenePointer$stableprop_getter(){}[0]
|
||||
final fun androidx.compose.ui.semantics/androidx_compose_ui_semantics_AccessibilityAction$stableprop_getter(): kotlin/Int // androidx.compose.ui.semantics/androidx_compose_ui_semantics_AccessibilityAction$stableprop_getter|androidx_compose_ui_semantics_AccessibilityAction$stableprop_getter(){}[0]
|
||||
final fun androidx.compose.ui.semantics/androidx_compose_ui_semantics_CollectionInfo$stableprop_getter(): kotlin/Int // androidx.compose.ui.semantics/androidx_compose_ui_semantics_CollectionInfo$stableprop_getter|androidx_compose_ui_semantics_CollectionInfo$stableprop_getter(){}[0]
|
||||
@@ -10303,18 +10216,6 @@ final fun com.compose.sdl.element/com_compose_sdl_element_ClipModifier$stablepro
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_ClipNode$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_ClipNode$stableprop_getter|com_compose_sdl_element_ClipNode$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_GraphicsLayerModifier$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_GraphicsLayerModifier$stableprop_getter|com_compose_sdl_element_GraphicsLayerModifier$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_GraphicsLayerNode$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_GraphicsLayerNode$stableprop_getter|com_compose_sdl_element_GraphicsLayerNode$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_MiddleClickModifier$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_MiddleClickModifier$stableprop_getter|com_compose_sdl_element_MiddleClickModifier$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_MiddleClickNode$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_MiddleClickNode$stableprop_getter|com_compose_sdl_element_MiddleClickNode$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_OnDragModifier$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_OnDragModifier$stableprop_getter|com_compose_sdl_element_OnDragModifier$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_OnDragNode$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_OnDragNode$stableprop_getter|com_compose_sdl_element_OnDragNode$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_OnPressedModifier$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_OnPressedModifier$stableprop_getter|com_compose_sdl_element_OnPressedModifier$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_OnPressedNode$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_OnPressedNode$stableprop_getter|com_compose_sdl_element_OnPressedNode$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_OnTextInputModifier$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_OnTextInputModifier$stableprop_getter|com_compose_sdl_element_OnTextInputModifier$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_OnTextInputNode$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_OnTextInputNode$stableprop_getter|com_compose_sdl_element_OnTextInputNode$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_PressableModifier$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_PressableModifier$stableprop_getter|com_compose_sdl_element_PressableModifier$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_PressableNode$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_PressableNode$stableprop_getter|com_compose_sdl_element_PressableNode$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_SecondaryClickModifier$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_SecondaryClickModifier$stableprop_getter|com_compose_sdl_element_SecondaryClickModifier$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.element/com_compose_sdl_element_SecondaryClickNode$stableprop_getter(): kotlin/Int // com.compose.sdl.element/com_compose_sdl_element_SecondaryClickNode$stableprop_getter|com_compose_sdl_element_SecondaryClickNode$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_Close$stableprop_getter(): kotlin/Int // com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_Close$stableprop_getter|com_compose_sdl_graphics_PathCommand_Close$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_CubicTo$stableprop_getter(): kotlin/Int // com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_CubicTo$stableprop_getter|com_compose_sdl_graphics_PathCommand_CubicTo$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_LineTo$stableprop_getter(): kotlin/Int // com.compose.sdl.graphics/com_compose_sdl_graphics_PathCommand_LineTo$stableprop_getter|com_compose_sdl_graphics_PathCommand_LineTo$stableprop_getter(){}[0]
|
||||
@@ -10325,6 +10226,7 @@ final fun com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectImageBitmap$s
|
||||
final fun com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPaint$stableprop_getter(): kotlin/Int // com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPaint$stableprop_getter|com_compose_sdl_graphics_ProjectPaint$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPath$stableprop_getter(): kotlin/Int // com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPath$stableprop_getter|com_compose_sdl_graphics_ProjectPath$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPathIterator$stableprop_getter(): kotlin/Int // com.compose.sdl.graphics/com_compose_sdl_graphics_ProjectPathIterator$stableprop_getter|com_compose_sdl_graphics_ProjectPathIterator$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.graphics/decodeEncodedImageBitmap(kotlin/ByteArray): androidx.compose.ui.graphics/ImageBitmap? // com.compose.sdl.graphics/decodeEncodedImageBitmap|decodeEncodedImageBitmap(kotlin.ByteArray){}[0]
|
||||
final fun com.compose.sdl.icons/com_compose_sdl_icons_IconFont$stableprop_getter(): kotlin/Int // com.compose.sdl.icons/com_compose_sdl_icons_IconFont$stableprop_getter|com_compose_sdl_icons_IconFont$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.input/com_compose_sdl_input_LegacyPointerEvent$stableprop_getter(): kotlin/Int // com.compose.sdl.input/com_compose_sdl_input_LegacyPointerEvent$stableprop_getter|com_compose_sdl_input_LegacyPointerEvent$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl.node/com_compose_sdl_node_ComposeRootHost$stableprop_getter(): kotlin/Int // com.compose.sdl.node/com_compose_sdl_node_ComposeRootHost$stableprop_getter|com_compose_sdl_node_ComposeRootHost$stableprop_getter(){}[0]
|
||||
@@ -10358,12 +10260,14 @@ final fun com.compose.sdl.window/com_compose_sdl_window_PopupHostState$stablepro
|
||||
final fun com.compose.sdl.window/createPopupHostState(): com.compose.sdl.window/PopupHostState // com.compose.sdl.window/createPopupHostState|createPopupHostState(){}[0]
|
||||
final fun com.compose.sdl/appDataDir(kotlin/String, kotlin/String): kotlin/String? // com.compose.sdl/appDataDir|appDataDir(kotlin.String;kotlin.String){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_AppEvent$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppEvent$stableprop_getter|com_compose_sdl_AppEvent$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_AppEvent_Drop$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppEvent_Drop$stableprop_getter|com_compose_sdl_AppEvent_Drop$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_AppEvent_Key$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppEvent_Key$stableprop_getter|com_compose_sdl_AppEvent_Key$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_AppEvent_MouseWheel$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppEvent_MouseWheel$stableprop_getter|com_compose_sdl_AppEvent_MouseWheel$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_AppEvent_Pointer$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppEvent_Pointer$stableprop_getter|com_compose_sdl_AppEvent_Pointer$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_AppEvent_Quit$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppEvent_Quit$stableprop_getter|com_compose_sdl_AppEvent_Quit$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_AppEvent_RedrawNeeded$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppEvent_RedrawNeeded$stableprop_getter|com_compose_sdl_AppEvent_RedrawNeeded$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_AppEvent_TextInput$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppEvent_TextInput$stableprop_getter|com_compose_sdl_AppEvent_TextInput$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_AppEvent_WindowActivation$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppEvent_WindowActivation$stableprop_getter|com_compose_sdl_AppEvent_WindowActivation$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_AppEvent_WindowClose$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppEvent_WindowClose$stableprop_getter|com_compose_sdl_AppEvent_WindowClose$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_AppEvent_WindowResized$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_AppEvent_WindowResized$stableprop_getter|com_compose_sdl_AppEvent_WindowResized$stableprop_getter(){}[0]
|
||||
final fun com.compose.sdl/com_compose_sdl_ComposeNativeWindow$stableprop_getter(): kotlin/Int // com.compose.sdl/com_compose_sdl_ComposeNativeWindow$stableprop_getter|com_compose_sdl_ComposeNativeWindow$stableprop_getter(){}[0]
|
||||
|
||||
@@ -32,7 +32,7 @@ plugins {
|
||||
val useSdl3Everywhere = (findProperty("renderer") as? String) == "sdl3"
|
||||
|
||||
// All targets pull headers from the in-repo static build tree at <repo>/libs,
|
||||
// populated by scripts/build-sdl/build-all.sh (or the per-library scripts).
|
||||
// populated by scripts/build-sdl/build-all.py (optionally one library at a time).
|
||||
// Same paths on macOS / Linux / Windows — the .def files are pathless and
|
||||
// rely on these -I injections. Cross-target cinterop indexing under
|
||||
// kotlin.mpp.enableCInteropCommonization is fine: clang silently ignores -I
|
||||
|
||||
@@ -6,7 +6,7 @@ headerFilter = SDL3/**
|
||||
# archive location comes from :ui build.gradle.kts (-libraryPath) because
|
||||
# .def files can't reference $rootDir. The linker options below list the
|
||||
# system frameworks / libs SDL3's static build depends on (see the Libs
|
||||
# line in libs/SDL3/lib/pkgconfig/sdl3.pc after build-sdl3.sh runs) —
|
||||
# line in libs/SDL3/lib/pkgconfig/sdl3.pc after build-all.py runs) —
|
||||
# cinterop propagates them through the klib to the final app link.
|
||||
|
||||
staticLibraries = libSDL3.a
|
||||
|
||||
@@ -5,6 +5,6 @@ depends = sdl3
|
||||
# libSDL3_image.a + its vendored codec archives (PNG/JPG built-in via stb,
|
||||
# WEBP, SVG built-in) are all baked into the cinterop klib. See sdl3.def —
|
||||
# the static archive location is injected via :ui build.gradle.kts
|
||||
# (-libraryPath). build-sdl3-image.sh normalises libzlibstatic.a → libz.a
|
||||
# on Windows so the same filename works everywhere.
|
||||
# (-libraryPath). build-all.py's sdl3-image step normalises libzlibstatic.a
|
||||
# → libz.a on Windows so the same filename works everywhere.
|
||||
staticLibraries = libSDL3_image.a libpng16.a libz.a libwebp.a libwebpdemux.a libwebpmux.a libsharpyuv.a
|
||||
|
||||
@@ -7,18 +7,22 @@ import androidx.compose.ui.graphics.ImageBitmap
|
||||
// ==================
|
||||
|
||||
/* Decodes an ENCODED image (png / jpg / webp / bmp / gif / svg bytes) into a
|
||||
drawable [ImageBitmap]. The active renderer registers its implementation —
|
||||
the SDL backend goes through SDL3_image (see Sdl3EncodedImageDecoder); the
|
||||
Skia renderer never registers because its resources pipeline decodes through
|
||||
Skia directly (vendored skikoRenderer actuals in :components-resources).
|
||||
drawable [ImageBitmap]. The active renderer registers its implementation at
|
||||
backend construction — the SDL backend goes through SDL3_image
|
||||
(Sdl3EncodedImageDecoder), the Skia backend through Image.makeFromEncoded /
|
||||
SVGDOM (SkiaEncodedImageDecoder). :components-resources' actuals share this
|
||||
hook under BOTH renderers (its skikoRendererMain reuses the SDL actuals).
|
||||
|
||||
Consumed by :components-resources' SDL actuals (`ByteArray.toImageBitmap`,
|
||||
`SvgElement.toSvgPainter`) so painterResource(Res.drawable.x) works without
|
||||
that module reaching into renderer internals. */
|
||||
Consumed by `ByteArray.toImageBitmap` / `SvgElement.toSvgPainter` so
|
||||
painterResource(Res.drawable.x) works without that module reaching into
|
||||
renderer internals. */
|
||||
interface EncodedImageDecoder {
|
||||
fun decode(inBytes: ByteArray): ImageBitmap?
|
||||
}
|
||||
|
||||
/* Volatile: written by the render backend on the main thread, read by the
|
||||
resources pipeline on Dispatchers.Default workers. */
|
||||
@kotlin.concurrent.Volatile
|
||||
var encodedImageDecoder: EncodedImageDecoder? = null
|
||||
internal set
|
||||
|
||||
|
||||
+31
-15
@@ -31,29 +31,47 @@ internal var currentMainCanvas: Sdl3Canvas? = null
|
||||
// blits it back — with the Icon tint applied through SDL_SetTextureColorMod.
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
internal class SdlImageBitmap(
|
||||
inRenderer: COpaquePointer,
|
||||
private val fRenderer: COpaquePointer,
|
||||
override val width: Int,
|
||||
override val height: Int,
|
||||
override val config: ImageBitmapConfig,
|
||||
override val hasAlpha: Boolean,
|
||||
override val colorSpace: ColorSpace,
|
||||
// A pre-made texture (the encoded-image decode path — see
|
||||
// Sdl3EncodedImageDecoder); null → create a render TARGET for the
|
||||
// vector-rasterisation path below.
|
||||
inDecodedTexture: COpaquePointer? = null,
|
||||
// A surface decoded OFF the main thread (the encoded-image path — see
|
||||
// Sdl3EncodedImageDecoder); converted to a texture on the first draw.
|
||||
// null → create a render TARGET for the vector-rasterisation path below
|
||||
// (that path always constructs on the main thread).
|
||||
private var fDecodedSurface: CPointer<SDL_Surface>? = null,
|
||||
) : ImageBitmap {
|
||||
|
||||
// RGBA render-target texture, premultiplied blend for compositing back (content
|
||||
// is drawn over a transparent clear with ordinary BLEND, leaving premultiplied
|
||||
// colours — see Sdl3ClipTargets for the same reasoning).
|
||||
val texture: COpaquePointer? = inDecodedTexture ?: SDL_CreateTexture(
|
||||
inRenderer.reinterpret(),
|
||||
private var fTexture: COpaquePointer? = if (fDecodedSurface != null) null else SDL_CreateTexture(
|
||||
fRenderer.reinterpret(),
|
||||
SDL_PIXELFORMAT_RGBA32,
|
||||
SDL_TextureAccess.SDL_TEXTUREACCESS_TARGET,
|
||||
maxOf(1, width),
|
||||
maxOf(1, height),
|
||||
)?.also { SDL_SetTextureBlendMode(it.reinterpret(), SDL_BLENDMODE_BLEND_PREMULTIPLIED) }
|
||||
|
||||
// SDL renderer calls are NOT thread-safe, and the resources pipeline
|
||||
// decodes on Dispatchers.Default workers — so the decode path hands over a
|
||||
// plain SDL_Surface and the texture is created here, lazily, on the first
|
||||
// access (createCanvas / the draw paths — main thread only). Decoded
|
||||
// surfaces carry STRAIGHT alpha → ordinary BLEND, unlike the premultiplied
|
||||
// render-target path above.
|
||||
val texture: COpaquePointer?
|
||||
get() {
|
||||
fDecodedSurface?.let { vSurface ->
|
||||
fTexture = SDL_CreateTextureFromSurface(fRenderer.reinterpret(), vSurface)
|
||||
?.also { SDL_SetTextureBlendMode(it.reinterpret(), SDL_BLENDMODE_BLEND) }
|
||||
SDL_DestroySurface(vSurface)
|
||||
fDecodedSurface = null
|
||||
}
|
||||
return fTexture
|
||||
}
|
||||
|
||||
override fun readPixels(
|
||||
buffer: IntArray,
|
||||
startX: Int,
|
||||
@@ -116,24 +134,22 @@ internal class Sdl3EncodedImageDecoder(
|
||||
|
||||
override fun decode(inBytes: ByteArray): ImageBitmap? {
|
||||
if (inBytes.isEmpty()) return null
|
||||
// Pure decode only — IMG_Load_IO touches no renderer state, so it is
|
||||
// safe on the resources pipeline's Dispatchers.Default workers. The
|
||||
// texture is created from this surface on the first MAIN-THREAD draw
|
||||
// (SdlImageBitmap.texture) — SDL renderer calls are not thread-safe.
|
||||
val vSurface = inBytes.usePinned { vPinned ->
|
||||
val vIo = SDL_IOFromConstMem(vPinned.addressOf(0), inBytes.size.convert())
|
||||
?: return@usePinned null
|
||||
sdl3_image.IMG_Load_IO(vIo.reinterpret(), true)
|
||||
} ?: return null
|
||||
val vSdlSurface = vSurface.reinterpret<SDL_Surface>()
|
||||
val vW = vSdlSurface.pointed.w
|
||||
val vH = vSdlSurface.pointed.h
|
||||
val vTex = SDL_CreateTextureFromSurface(fRenderer.reinterpret(), vSdlSurface)
|
||||
SDL_DestroySurface(vSdlSurface)
|
||||
if (vTex == null) return null
|
||||
SDL_SetTextureBlendMode(vTex.reinterpret(), SDL_BLENDMODE_BLEND)
|
||||
return SdlImageBitmap(
|
||||
fRenderer, vW, vH,
|
||||
fRenderer, vSdlSurface.pointed.w, vSdlSurface.pointed.h,
|
||||
config = ImageBitmapConfig.Argb8888,
|
||||
hasAlpha = true,
|
||||
colorSpace = androidx.compose.ui.graphics.colorspace.ColorSpaces.Srgb,
|
||||
inDecodedTexture = vTex,
|
||||
fDecodedSurface = vSdlSurface,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+20
-16
@@ -58,22 +58,6 @@ internal class SkiaImageCache {
|
||||
}
|
||||
}
|
||||
|
||||
/* SVGDOM → offscreen raster → Image. Falls back to a 100×100 canvas when
|
||||
the document declares no explicit width/height (the Android-vector path
|
||||
always supplies them). */
|
||||
private fun rasterizeSvg(inBytes: ByteArray): Image? = runCatching {
|
||||
val vDom = SVGDOM(Data.makeFromBytes(inBytes))
|
||||
val vRoot = vDom.root
|
||||
var vW = vRoot?.width?.value ?: 0f
|
||||
var vH = vRoot?.height?.value ?: 0f
|
||||
if (vW <= 0f) vW = 100f
|
||||
if (vH <= 0f) vH = 100f
|
||||
vDom.setContainerSize(vW, vH)
|
||||
val vSurface = Surface.makeRasterN32Premul(vW.toInt().coerceAtLeast(1), vH.toInt().coerceAtLeast(1))
|
||||
vDom.render(vSurface.canvas)
|
||||
vSurface.makeImageSnapshot()
|
||||
}.getOrNull()
|
||||
|
||||
// ==================
|
||||
// MARK: Draw
|
||||
// ==================
|
||||
@@ -133,3 +117,23 @@ internal class SkiaImageCache {
|
||||
fCache.clear()
|
||||
}
|
||||
}
|
||||
|
||||
// ==================
|
||||
// MARK: SVG rasterisation (shared with SkiaEncodedImageDecoder)
|
||||
// ==================
|
||||
|
||||
/* SVGDOM → offscreen raster → Image. Falls back to a 100×100 canvas when
|
||||
the document declares no explicit width/height (the Android-vector path
|
||||
always supplies them). */
|
||||
internal fun rasterizeSvg(inBytes: ByteArray): Image? = runCatching {
|
||||
val vDom = SVGDOM(Data.makeFromBytes(inBytes))
|
||||
val vRoot = vDom.root
|
||||
var vW = vRoot?.width?.value ?: 0f
|
||||
var vH = vRoot?.height?.value ?: 0f
|
||||
if (vW <= 0f) vW = 100f
|
||||
if (vH <= 0f) vH = 100f
|
||||
vDom.setContainerSize(vW, vH)
|
||||
val vSurface = Surface.makeRasterN32Premul(vW.toInt().coerceAtLeast(1), vH.toInt().coerceAtLeast(1))
|
||||
vDom.render(vSurface.canvas)
|
||||
vSurface.makeImageSnapshot()
|
||||
}.getOrNull()
|
||||
|
||||
+31
@@ -5,6 +5,8 @@ import androidx.compose.ui.graphics.Canvas
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.graphics.ImageBitmapConfig
|
||||
import androidx.compose.ui.graphics.colorspace.ColorSpace
|
||||
import androidx.compose.ui.graphics.colorspace.ColorSpaces
|
||||
import com.compose.sdl.graphics.EncodedImageDecoder
|
||||
import com.compose.sdl.graphics.OffscreenRenderer
|
||||
import org.jetbrains.skia.Image
|
||||
import org.jetbrains.skia.Surface
|
||||
@@ -86,3 +88,32 @@ internal class SkiaOffscreenRenderer(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ==================
|
||||
// MARK: SkiaEncodedImageDecoder
|
||||
// ==================
|
||||
|
||||
/* Encoded-image decode hook impl for the Skia renderer — the counterpart of
|
||||
Sdl3EncodedImageDecoder, consumed by :components-resources' actuals
|
||||
(painterResource / SVG). Raster formats go through Image.makeFromEncoded;
|
||||
when that fails the bytes are retried as SVG through the same SVGDOM
|
||||
rasterisation SkiaImageCache uses. Pure CPU raster (no GrContext), so it is
|
||||
safe on the resources pipeline's Dispatchers.Default workers. */
|
||||
internal class SkiaEncodedImageDecoder : EncodedImageDecoder {
|
||||
|
||||
override fun decode(inBytes: ByteArray): ImageBitmap? {
|
||||
if (inBytes.isEmpty()) return null
|
||||
val vImg = runCatching { Image.makeFromEncoded(inBytes) }.getOrNull()
|
||||
?: rasterizeSvg(inBytes)
|
||||
?: return null
|
||||
val vBmp = SkiaImageBitmap(
|
||||
vImg.width, vImg.height,
|
||||
config = ImageBitmapConfig.Argb8888,
|
||||
hasAlpha = true,
|
||||
colorSpace = ColorSpaces.Srgb,
|
||||
)
|
||||
vBmp.surface.canvas.drawImage(vImg, 0f, 0f)
|
||||
vImg.close()
|
||||
return vBmp
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -33,6 +33,18 @@ internal class SkiaRenderBackend(
|
||||
private val fSkiaImageCache = SkiaImageCache()
|
||||
private var fCurrentCanvas: Canvas? = null
|
||||
|
||||
init {
|
||||
// Encoded-image decode (painterResource / SVG in :components-resources).
|
||||
// Registered at CONSTRUCTION, not first frame: the official resources
|
||||
// pipeline decodes during COMPOSITION, which runs before beginFrame —
|
||||
// and on Dispatchers.Default workers, which the CPU-raster Skia decoder
|
||||
// tolerates. Without this the first painterResource on a Skia build
|
||||
// dies with "Image decode failed" (issue #1).
|
||||
if (com.compose.sdl.graphics.encodedImageDecoder == null) {
|
||||
com.compose.sdl.graphics.encodedImageDecoder = SkiaEncodedImageDecoder()
|
||||
}
|
||||
}
|
||||
|
||||
override val textMeasurer: TextMeasurer
|
||||
get() = fSkiaTextRenderer.textMeasurer
|
||||
|
||||
|
||||
+85
-13
@@ -13,6 +13,31 @@ plugins {
|
||||
// Skip mingwX64 on non-Windows hosts; see root build.gradle.kts.
|
||||
val vHostSupportsMingw = rootProject.extra["vHostSupportsMingw"] as Boolean
|
||||
|
||||
// JVM parity target's Compose version — the dev build matching the pinned
|
||||
// COMPOSE_CORE_REF (see scripts/compose-fork/compose.properties). material3
|
||||
// rides its OWN release train: same +dev build number, different base
|
||||
// version. Gradle orders "+dev" qualifiers BELOW the plain version, so
|
||||
// currentOs's beta01 would win conflict resolution — force the core-repo
|
||||
// groups on every jvm configuration. Umbrella-repo groups (desktop,
|
||||
// components) are NOT forced: their dev numbering differs.
|
||||
val vComposeJvmVersion = "1.12.0-beta01+dev4324"
|
||||
val vComposeM3JvmVersion = "1.12.0-alpha03+dev4324"
|
||||
val vComposeJvmForced = mapOf(
|
||||
"org.jetbrains.compose.runtime" to vComposeJvmVersion,
|
||||
"org.jetbrains.compose.ui" to vComposeJvmVersion,
|
||||
"org.jetbrains.compose.foundation" to vComposeJvmVersion,
|
||||
"org.jetbrains.compose.animation" to vComposeJvmVersion,
|
||||
"org.jetbrains.compose.material" to vComposeJvmVersion,
|
||||
"org.jetbrains.compose.material3" to vComposeM3JvmVersion,
|
||||
)
|
||||
configurations.configureEach {
|
||||
if (name.startsWith("jvm")) {
|
||||
resolutionStrategy.eachDependency {
|
||||
vComposeJvmForced[requested.group]?.let { useVersion(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
|
||||
@@ -72,30 +97,60 @@ kotlin {
|
||||
// substitute it for the vendored :components-resources below
|
||||
// (the Maven artifact ships no mingwX64/linux klibs).
|
||||
implementation(compose.components.resources)
|
||||
// Common API on both stacks (its native/jvm actuals pick the
|
||||
// right rendering pipeline) — usable from shared screens.
|
||||
implementation(project(":material-symbols"))
|
||||
|
||||
// Official Maven coords for everything the shared screens
|
||||
// touch, so commonMain metadata (and the IDE's common
|
||||
// analysis) resolve. Metadata + jvm resolve them from Maven;
|
||||
// the NATIVE configurations substitute each for its port
|
||||
// module (root build's FULL-COMMONIZATION BRIDGE). Every
|
||||
// artifact must be declared DIRECTLY: transitives of a
|
||||
// substituted module are invisible to the granular-metadata
|
||||
// visibility check. The runtime is the official klib
|
||||
// everywhere, never substituted (jvm configs force the +dev
|
||||
// build above).
|
||||
implementation("org.jetbrains.compose.runtime:runtime:1.11.1")
|
||||
implementation("org.jetbrains.compose.ui:ui:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.ui:ui-graphics:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.ui:ui-text:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.ui:ui-unit:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.ui:ui-geometry:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.ui:ui-util:$vComposeJvmVersion")
|
||||
// The common @Preview (androidx.compose.ui.tooling.preview) —
|
||||
// IDE-only metadata; previews render through the jvm target.
|
||||
implementation("org.jetbrains.compose.ui:ui-tooling-preview:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.foundation:foundation:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.foundation:foundation-layout:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.animation:animation:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.animation:animation-core:$vComposeJvmVersion")
|
||||
implementation("org.jetbrains.compose.material3:material3:$vComposeM3JvmVersion")
|
||||
|
||||
// nav3 + lifecycle: real KMP Maven artifacts on every target
|
||||
// (see "Known Compatible" in CLAUDE.md) — except navigation3-ui,
|
||||
// which the bridge substitutes for the vendored :navigation3-ui
|
||||
// on native.
|
||||
implementation("androidx.navigation3:navigation3-runtime:1.1.4")
|
||||
implementation("org.jetbrains.androidx.navigation3:navigation3-ui:1.2.0-alpha02")
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-navigation3:2.11.0")
|
||||
}
|
||||
}
|
||||
nativeMain {
|
||||
dependencies {
|
||||
implementation(project(":window"))
|
||||
implementation(project(":material3"))
|
||||
implementation(project(":material-symbols"))
|
||||
implementation(project(":navigation3-ui"))
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-navigation3:2.11.0")
|
||||
}
|
||||
}
|
||||
jvmMain {
|
||||
dependencies {
|
||||
implementation("org.jetbrains.compose.runtime:runtime:1.12.0-alpha03")
|
||||
implementation("org.jetbrains.compose.foundation:foundation:1.12.0-alpha03")
|
||||
implementation("org.jetbrains.compose.animation:animation:1.12.0-alpha03")
|
||||
implementation("org.jetbrains.compose.material3:material3:1.12.0-alpha03")
|
||||
implementation("org.jetbrains.compose.ui:ui:1.12.0-alpha03")
|
||||
|
||||
// The +dev builds matching scripts/compose-fork's pinned
|
||||
// COMPOSE_CORE_REF come from the version forcing above —
|
||||
// byte-exact parity with the vendored sources, and (unlike
|
||||
// the published beta01) desktop loadTypeface applies
|
||||
// Font.variationSettings, so the Material Symbols
|
||||
// variable-font axes work on JVM.
|
||||
implementation("androidx.navigation3:navigation3-runtime:1.2.0-alpha05")
|
||||
implementation("org.jetbrains.androidx.navigation3:navigation3-ui:1.2.0-alpha02")
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-navigation3:2.11.0")
|
||||
implementation(compose.desktop.currentOs)
|
||||
implementation("org.jetbrains.compose.material:material-icons-extended:1.7.3")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,3 +293,20 @@ for (variant in variants) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================
|
||||
// MARK: Stage Material Symbols fonts onto the JVM classpath
|
||||
// ==================
|
||||
// The :material-symbols JVM actual loads each style's font from the classpath
|
||||
// at font/<Style>.ttf — the JVM analog of the data.kres font/ entries above.
|
||||
// Same style detection: only the fonts the sources actually reference.
|
||||
tasks.named<ProcessResources>("jvmProcessResources") {
|
||||
val vSymbolsProject = rootProject.project(":material-symbols")
|
||||
for (vStyle in vUsedStyles) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val vFontFile = vSymbolsProject.extra["iconFontFile$vStyle"] as Provider<RegularFile>
|
||||
val vDownloadTask = vSymbolsProject.extra["iconFontDownloadTask$vStyle"] as TaskProvider<*>
|
||||
from(vFontFile) { into("font") }
|
||||
dependsOn(vDownloadTask)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ val CoreScreens: List<DemoScreen> = listOf(
|
||||
val Material3Screens: List<DemoScreen> = listOf(
|
||||
// Ordered by family: typography, buttons, inputs, containers, navigation, overlays.
|
||||
DemoScreen("Text") { TextScreen() },
|
||||
DemoScreen("Icons") { IconsScreen() },
|
||||
DemoScreen("Buttons") { ButtonsScreen() },
|
||||
DemoScreen("ButtonsExtra") { M3ButtonsExtraScreen() },
|
||||
DemoScreen("Fab") { FabScreen() },
|
||||
@@ -86,10 +87,17 @@ val Navigation3Screens: List<DemoScreen> = listOf(
|
||||
DemoScreen("Navigation3") { Navigation3Screen() },
|
||||
)
|
||||
|
||||
// Screens that aren't a Compose-artifact showcase: project utility modules
|
||||
// (Material Symbols engine, ...).
|
||||
val OthersScreens: List<DemoScreen> = listOf(
|
||||
DemoScreen("MaterialSymbols") { MaterialSymbolsScreen() },
|
||||
)
|
||||
|
||||
val commonCategories: List<DemoCategory> = listOf(
|
||||
DemoCategory("core", "Core", CoreScreens),
|
||||
DemoCategory("material3", "Material3", Material3Screens),
|
||||
DemoCategory("navigation3", "Navigation3", Navigation3Screens),
|
||||
DemoCategory("others", "Others", OthersScreens),
|
||||
)
|
||||
|
||||
/* Platform extras that fill the dropdown dynamically: screens that can't be
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package demo.shim
|
||||
|
||||
import androidx.compose.ui.platform.ClipEntry
|
||||
|
||||
// ==================
|
||||
// MARK: DemoClipboard — portable ClipEntry construction / reading
|
||||
// ==================
|
||||
|
||||
/* Upstream Compose has no COMMON way to build or read a ClipEntry — every
|
||||
platform actual differs. This port mirrors upstream's macOS actual
|
||||
(ClipEntry.withPlainText / getPlainText / getImage), while upstream JVM
|
||||
desktop wraps an AWT Transferable and exposes nothing text-typed. Shared
|
||||
screens go through these four helpers; each stack maps them 1:1 onto its
|
||||
native shape. */
|
||||
|
||||
/* A ClipEntry carrying plain text, for Clipboard.setClipEntry. */
|
||||
expect fun demoClipEntryOfText(text: String): ClipEntry
|
||||
|
||||
/* A ClipEntry carrying an image from already-PNG-encoded bytes. */
|
||||
expect fun demoClipEntryOfPng(pngBytes: ByteArray): ClipEntry
|
||||
|
||||
/* The entry's plain text, or null when it carries none. */
|
||||
expect fun ClipEntry.demoPlainText(): String?
|
||||
|
||||
/* The entry's image as PNG-encoded bytes, or null when it carries none. */
|
||||
expect fun ClipEntry.demoPngImage(): ByteArray?
|
||||
@@ -5,16 +5,18 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.compose.sdl.icons.MaterialSymbols
|
||||
import com.compose.sdl.icons.material.symbols.MaterialSymbolsOutlined
|
||||
|
||||
// ==================
|
||||
// MARK: DemoIcon — platform-neutral icon token
|
||||
// ==================
|
||||
|
||||
/* A platform-neutral icon reference for the shared demo screens. On native it
|
||||
maps to a Material Symbols codepoint rendered by the project icon-font engine
|
||||
(com.compose.sdl.icons); on a future jvm target it maps to an
|
||||
androidx.compose.material.icons ImageVector. Shared screens reference icons
|
||||
ONLY through this enum, so the exact same code compiles on both stacks. */
|
||||
/* A platform-neutral icon reference for the shared demo screens. Now that
|
||||
:material-symbols exposes its API from commonMain (native draws through the
|
||||
port's IconFont pipeline, JVM through upstream variable-font text), the
|
||||
token resolves to a Material Symbols codepoint on BOTH stacks — the same
|
||||
glyphs render everywhere, which is exactly what the parity build compares. */
|
||||
enum class DemoIcon {
|
||||
Home, Search, Person, Settings, Add, Edit, Favorite, Star, Close, Image,
|
||||
Delete, Share, Check, MoreVert, ContentCopy, KeyboardArrowDown, Bookmark,
|
||||
@@ -22,15 +24,50 @@ enum class DemoIcon {
|
||||
ExpandMore, ExpandLess,
|
||||
}
|
||||
|
||||
/* Renders [icon]. The portable stand-in for material3's Icon(imageVector, …) /
|
||||
the project's MaterialSymbolsOutlined(codepoint, …). Deliberately exposes no
|
||||
variable-font axes (fill / weight / grade / opticalSize) — those have no
|
||||
upstream analog. */
|
||||
/* Renders [icon] via MaterialSymbolsOutlined — the portable stand-in for
|
||||
material3's Icon(imageVector, …). Color.Unspecified tint falls back to
|
||||
material3's LocalContentColor inside MaterialSymbolsOutlined. */
|
||||
@Composable
|
||||
expect fun DemoIcon(
|
||||
fun DemoIcon(
|
||||
icon: DemoIcon,
|
||||
contentDescription: String? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
tint: Color = Color.Unspecified,
|
||||
size: Dp = 24.dp,
|
||||
)
|
||||
) {
|
||||
val codepoint = when (icon) {
|
||||
DemoIcon.Home -> MaterialSymbols.Home
|
||||
DemoIcon.Search -> MaterialSymbols.Search
|
||||
DemoIcon.Person -> MaterialSymbols.Person
|
||||
DemoIcon.Settings -> MaterialSymbols.Settings
|
||||
DemoIcon.Add -> MaterialSymbols.Add
|
||||
DemoIcon.Edit -> MaterialSymbols.Edit
|
||||
DemoIcon.Favorite -> MaterialSymbols.Favorite
|
||||
DemoIcon.Star -> MaterialSymbols.Star
|
||||
DemoIcon.Close -> MaterialSymbols.Close
|
||||
DemoIcon.Image -> MaterialSymbols.Image
|
||||
DemoIcon.Delete -> MaterialSymbols.Delete
|
||||
DemoIcon.Share -> MaterialSymbols.Share
|
||||
DemoIcon.Check -> MaterialSymbols.Check
|
||||
DemoIcon.MoreVert -> MaterialSymbols.MoreVert
|
||||
DemoIcon.ContentCopy -> MaterialSymbols.ContentCopy
|
||||
DemoIcon.KeyboardArrowDown -> MaterialSymbols.KeyboardArrowDown
|
||||
DemoIcon.Bookmark -> MaterialSymbols.Bookmark
|
||||
DemoIcon.Notifications -> MaterialSymbols.Notifications
|
||||
DemoIcon.Menu -> MaterialSymbols.Menu
|
||||
DemoIcon.ArrowBack -> MaterialSymbols.ArrowBack
|
||||
DemoIcon.Save -> MaterialSymbols.Save
|
||||
DemoIcon.Refresh -> MaterialSymbols.Refresh
|
||||
DemoIcon.Download -> MaterialSymbols.Download
|
||||
DemoIcon.Upload -> MaterialSymbols.Upload
|
||||
DemoIcon.ExpandMore -> MaterialSymbols.ExpandMore
|
||||
DemoIcon.ExpandLess -> MaterialSymbols.ExpandLess
|
||||
}
|
||||
MaterialSymbolsOutlined(
|
||||
icon = codepoint,
|
||||
contentDescription = contentDescription,
|
||||
modifier = modifier,
|
||||
tint = tint,
|
||||
size = size,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,42 +1,19 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.RepeatMode
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.animateFloat
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.animateIntAsState
|
||||
import androidx.compose.animation.core.infiniteRepeatable
|
||||
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.core.*
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
@@ -5,18 +5,17 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
@@ -4,22 +4,14 @@ package screens
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicSecureTextField
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.input.rememberTextFieldState
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@@ -20,12 +20,7 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.IntRect
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.unit.*
|
||||
import androidx.compose.ui.window.PopupPositionProvider
|
||||
|
||||
// Foundation — the undecorated text primitive below material3's Text, plus the
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.ui.*
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.text.style.*
|
||||
import androidx.compose.ui.unit.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
@Composable
|
||||
internal fun ButtonsScreen() {
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -18,8 +11,8 @@ import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.graphics.StrokeCap
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
|
||||
@@ -4,11 +4,7 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedCard
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@@ -3,19 +3,8 @@ package screens
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.AssistChip
|
||||
import androidx.compose.material3.ElevatedAssistChip
|
||||
import androidx.compose.material3.ElevatedFilterChip
|
||||
import androidx.compose.material3.ElevatedSuggestionChip
|
||||
import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.InputChip
|
||||
import androidx.compose.material3.SuggestionChip
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
|
||||
@@ -5,15 +5,12 @@ package screens
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -21,12 +18,11 @@ import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.ClipEntry
|
||||
import androidx.compose.ui.platform.Clipboard
|
||||
import androidx.compose.ui.platform.LocalClipboard
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import demo.shim.demoDecodeImage
|
||||
import demo.shim.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.readResourceBytes
|
||||
@@ -43,9 +39,10 @@ private const val kLogoResourcePath = "composeResources/demo.generated.resources
|
||||
// ==================
|
||||
|
||||
/* Round-trips text AND PNG images through the OS clipboard via LocalClipboard
|
||||
(suspend, ClipEntry-typed) over SDL3's SDL_[GS]etClipboardText and
|
||||
SDL_[GS]etClipboardData("image/png"). Text and images share one Compose
|
||||
ClipEntry: getPlainText() vs getImage() surface whichever is present.
|
||||
(suspend, ClipEntry-typed) — on native over SDL3's SDL_[GS]etClipboardText /
|
||||
SDL_[GS]etClipboardData("image/png"), on JVM over the AWT clipboard.
|
||||
ClipEntry construction/reading has NO common upstream API (each platform
|
||||
actual differs), so this screen goes through demo.shim.DemoClipboard.
|
||||
Non-composable callers reach it by capturing LocalClipboard.current +
|
||||
rememberCoroutineScope() in composition and passing both into the callback. */
|
||||
@Composable
|
||||
@@ -68,8 +65,9 @@ internal fun ClipboardScreen() {
|
||||
)
|
||||
|
||||
// ============
|
||||
// Text copy — ClipEntry.withPlainText / getPlainText.
|
||||
Section("Copy text", "scope.launch { clipboard.setClipEntry(ClipEntry.withPlainText(...)) }") {
|
||||
// Text copy — demoClipEntryOfText (ClipEntry.withPlainText on native,
|
||||
// AWT StringSelection on JVM).
|
||||
Section("Copy text", "scope.launch { clipboard.setClipEntry(demoClipEntryOfText(...)) }") {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
OutlinedTextField(
|
||||
value = draft,
|
||||
@@ -78,7 +76,7 @@ internal fun ClipboardScreen() {
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
Button(onClick = {
|
||||
scope.launch { clipboard.setClipEntry(ClipEntry.withPlainText(draft)) }
|
||||
scope.launch { clipboard.setClipEntry(demoClipEntryOfText(draft)) }
|
||||
note = "Copied ${draft.length} char(s) to the system clipboard."
|
||||
}) {
|
||||
Text("Copy text", color = MaterialTheme.colorScheme.onPrimary)
|
||||
@@ -92,7 +90,7 @@ internal fun ClipboardScreen() {
|
||||
// image-aware app (Preview / Paint / a browser tab) to verify.
|
||||
Section(
|
||||
"Copy image",
|
||||
"readResourceBytes(\"drawable/compose_logo.png\") → ClipEntry.withImage(pngBytes). " +
|
||||
"readResourceBytes(\"drawable/compose_logo.png\") → demoClipEntryOfPng(pngBytes). " +
|
||||
"Paste into another app to verify.",
|
||||
) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
@@ -115,7 +113,7 @@ internal fun ClipboardScreen() {
|
||||
scope.launch {
|
||||
val vBytes = runCatching { readResourceBytes(kLogoResourcePath) }.getOrNull()
|
||||
if (vBytes != null) {
|
||||
clipboard.setClipEntry(ClipEntry.withImage(vBytes))
|
||||
clipboard.setClipEntry(demoClipEntryOfPng(vBytes))
|
||||
note = "Copied ${vBytes.size} byte(s) of PNG to the system clipboard."
|
||||
} else {
|
||||
note = "Failed to load the source image."
|
||||
@@ -130,15 +128,15 @@ internal fun ClipboardScreen() {
|
||||
|
||||
// ============
|
||||
// Paste — surfaces whatever's on the clipboard: text OR image.
|
||||
Section("Paste", "clipboard.getClipEntry()?.getPlainText() / .getImage()") {
|
||||
Section("Paste", "clipboard.getClipEntry()?.demoPlainText() / .demoPngImage()") {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
Button(onClick = {
|
||||
pastedText = null; pastedImage = null; pastedNote = null
|
||||
scope.launch {
|
||||
val vEntry = clipboard.getClipEntry()
|
||||
val vImage = vEntry?.getImage()
|
||||
val vText = vEntry?.getPlainText()
|
||||
val vImage = vEntry?.demoPngImage()
|
||||
val vText = vEntry?.demoPlainText()
|
||||
when {
|
||||
vImage != null -> {
|
||||
pastedImage = demoDecodeImage(vImage)
|
||||
@@ -212,6 +210,6 @@ internal fun ClipboardScreen() {
|
||||
modern Clipboard is intentionally suspend-only. */
|
||||
private fun copyFromPlainFunction(scope: CoroutineScope, clipboard: Clipboard) {
|
||||
scope.launch {
|
||||
clipboard.setClipEntry(ClipEntry.withPlainText("Set from a plain, non-@Composable function."))
|
||||
clipboard.setClipEntry(demoClipEntryOfText("Set from a plain, non-@Composable function."))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
package screens
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.ui.*
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.unit.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
// ==================
|
||||
// MARK: Colors screen — Material palette swatches
|
||||
// ==================
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun ColorsScreen() {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
package screens
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.ui.*
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.text.style.*
|
||||
import androidx.compose.ui.unit.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
@Composable
|
||||
internal fun CounterScreen() {
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.layout.Layout
|
||||
import androidx.compose.ui.layout.layout
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@@ -6,26 +6,8 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.PlainTooltip
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TooltipBox
|
||||
import androidx.compose.material3.TooltipDefaults
|
||||
import androidx.compose.material3.rememberTooltipState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@@ -4,23 +4,13 @@ import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.draganddrop.dragAndDropTarget
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draganddrop.DragAndDropEvent
|
||||
|
||||
@@ -3,16 +3,7 @@ package screens
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.ElevatedButton
|
||||
import androidx.compose.material3.ExtendedFloatingActionButton
|
||||
import androidx.compose.material3.FilledIconButton
|
||||
import androidx.compose.material3.FilledTonalButton
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedIconButton
|
||||
import androidx.compose.material3.SmallFloatingActionButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@@ -3,15 +3,7 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.FlowColumn
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
|
||||
@@ -3,25 +3,16 @@ package screens
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.focusable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
|
||||
@@ -3,23 +3,12 @@ package screens
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.detectDragGestures
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@@ -2,23 +2,13 @@ package screens
|
||||
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
|
||||
import androidx.compose.foundation.lazy.staggeredgrid.LazyHorizontalStaggeredGrid
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.compose.sdl.icons.MaterialSymbols
|
||||
import com.compose.sdl.icons.material.symbols.MaterialSymbolsOutlined
|
||||
import com.compose.sdl.icons.material.symbols.MaterialSymbolsRounded
|
||||
import com.compose.sdl.icons.material.symbols.MaterialSymbolsSharp
|
||||
import demo.generated.resources.Res
|
||||
import demo.generated.resources.heart
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
|
||||
// ==================
|
||||
// MARK: Icons screen — material3 icon APIs
|
||||
// ==================
|
||||
|
||||
/* material3 icon APIs: Icon(painter) over compose resources and IconButton. */
|
||||
@Composable
|
||||
internal fun IconsScreen() {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
ScreenTitle(
|
||||
"Icons",
|
||||
"material3 Icon(painter) over compose resources + IconButton.",
|
||||
)
|
||||
|
||||
Section("Painter-based Icon", "Reads from composeResources/drawable/*.xml (Android vector) or *.svg.") {
|
||||
Row(verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
Icon(painter = painterResource(Res.drawable.heart), contentDescription = "Heart")
|
||||
Text("painterResource(Res.drawable.heart)", fontSize = 13.sp)
|
||||
}
|
||||
}
|
||||
|
||||
Section("IconButton", "40dp clickable circle. Hover overlay matches Material 1.") {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
IconButton(onClick = {}) {
|
||||
MaterialSymbolsOutlined(MaterialSymbols.Favorite,
|
||||
tint = MaterialTheme.colorScheme.primary, fill = 1f, weight = 600)
|
||||
}
|
||||
IconButton(onClick = {}) {
|
||||
MaterialSymbolsRounded(MaterialSymbols.Share,
|
||||
tint = MaterialTheme.colorScheme.onSurface)
|
||||
}
|
||||
IconButton(onClick = {}) {
|
||||
MaterialSymbolsSharp(MaterialSymbols.MoreVert,
|
||||
tint = MaterialTheme.colorScheme.onSurface)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
package screens
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.ui.*
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.graphics.painter.*
|
||||
import androidx.compose.ui.layout.*
|
||||
import androidx.compose.ui.unit.*
|
||||
import demo.generated.resources.Res
|
||||
import demo.generated.resources.compose_logo
|
||||
import demo.generated.resources.heart
|
||||
import demo.generated.resources.photo
|
||||
import demo.generated.resources.star
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import demo.generated.resources.*
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
|
||||
// ==================
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.ui.*
|
||||
import androidx.compose.ui.unit.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
// ==================
|
||||
// MARK: Interaction (hover / press / focus) screen
|
||||
|
||||
@@ -1,26 +1,21 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.hoverable
|
||||
import androidx.compose.foundation.interaction.HoverInteraction
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsHoveredAsState
|
||||
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package screens
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.ui.*
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.unit.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
internal fun LayoutScreen() {
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.ui.*
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.text.style.*
|
||||
import androidx.compose.ui.unit.*
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
// ==================
|
||||
// MARK: LazyColumn screen
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
||||
@@ -4,13 +4,7 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.material3.Badge
|
||||
import androidx.compose.material3.BadgedBox
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.VerticalDivider
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
@@ -2,33 +2,9 @@
|
||||
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.material3.AppBarColumn
|
||||
import androidx.compose.material3.AppBarOverflowIndicator
|
||||
import androidx.compose.material3.AppBarRow
|
||||
import androidx.compose.material3.BottomAppBar
|
||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.FlexibleBottomAppBar
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LargeFlexibleTopAppBar
|
||||
import androidx.compose.material3.LargeTopAppBar
|
||||
import androidx.compose.material3.MediumFlexibleTopAppBar
|
||||
import androidx.compose.material3.MediumTopAppBar
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TwoRowsTopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import demo.shim.DemoIcon
|
||||
|
||||
@@ -6,29 +6,8 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material3.ButtonGroup
|
||||
import androidx.compose.material3.ElevatedToggleButton
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.FilledIconToggleButton
|
||||
import androidx.compose.material3.FilledTonalIconButton
|
||||
import androidx.compose.material3.FilledTonalIconToggleButton
|
||||
import androidx.compose.material3.IconToggleButton
|
||||
import androidx.compose.material3.MultiChoiceSegmentedButtonRow
|
||||
import androidx.compose.material3.OutlinedIconToggleButton
|
||||
import androidx.compose.material3.OutlinedToggleButton
|
||||
import androidx.compose.material3.SegmentedButton
|
||||
import androidx.compose.material3.SegmentedButtonDefaults
|
||||
import androidx.compose.material3.SplitButtonDefaults
|
||||
import androidx.compose.material3.SplitButtonLayout
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.ToggleButton
|
||||
import androidx.compose.material3.TonalToggleButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@@ -3,14 +3,7 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
|
||||
@@ -2,34 +2,9 @@
|
||||
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.DismissibleDrawerSheet
|
||||
import androidx.compose.material3.DismissibleNavigationDrawer
|
||||
import androidx.compose.material3.DrawerValue
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.ModalDrawerSheet
|
||||
import androidx.compose.material3.ModalNavigationDrawer
|
||||
import androidx.compose.material3.NavigationDrawerItem
|
||||
import androidx.compose.material3.PermanentDrawerSheet
|
||||
import androidx.compose.material3.PermanentNavigationDrawer
|
||||
import androidx.compose.material3.Scrim
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.rememberDrawerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@@ -2,31 +2,9 @@
|
||||
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.FloatingActionButtonMenu
|
||||
import androidx.compose.material3.FloatingActionButtonMenuItem
|
||||
import androidx.compose.material3.HorizontalFloatingToolbar
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LargeExtendedFloatingActionButton
|
||||
import androidx.compose.material3.LargeFloatingActionButton
|
||||
import androidx.compose.material3.MediumExtendedFloatingActionButton
|
||||
import androidx.compose.material3.MediumFloatingActionButton
|
||||
import androidx.compose.material3.SmallExtendedFloatingActionButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.ToggleFloatingActionButton
|
||||
import androidx.compose.material3.VerticalFloatingToolbar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@@ -2,54 +2,10 @@
|
||||
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.text.input.rememberTextFieldState
|
||||
import androidx.compose.material3.BasicAlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.DropdownMenuGroup
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.DropdownMenuPopup
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.ExposedDropdownMenuAnchorType
|
||||
import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Label
|
||||
import androidx.compose.material3.ListItemDefaults
|
||||
import androidx.compose.material3.MaterialExpressiveTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.MenuDefaults
|
||||
import androidx.compose.material3.OutlinedSecureTextField
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.ProvideTextStyle
|
||||
import androidx.compose.material3.RangeSlider
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.ScrollField
|
||||
import androidx.compose.material3.ScrollFieldDefaults
|
||||
import androidx.compose.material3.SecureTextField
|
||||
import androidx.compose.material3.SegmentedListItem
|
||||
import androidx.compose.material3.Snackbar
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.VerticalSlider
|
||||
import androidx.compose.material3.rememberScrollFieldState
|
||||
import androidx.compose.material3.rememberSliderState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user