Skip to content

Commit dea4a84

Browse files
committed
1.1.0
1 parent bf0767a commit dea4a84

File tree

195 files changed

+10656
-1470
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

195 files changed

+10656
-1470
lines changed

Android/PROMPT_ANDROID.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ Since this is a multi-module project, you will need to add the AppDimens modules
1818
```kotlin
1919
dependencies {
2020
// Core (Dynamic + Fixed)
21-
implementation("io.github.bodenberg:appdimens-dynamic:1.0.9")
21+
implementation("io.github.bodenberg:appdimens-dynamic:1.1.0")
2222

2323
// SDP & SSP scaling (optional)
24-
implementation("io.github.bodenberg:appdimens-sdps:1.0.9")
25-
implementation("io.github.bodenberg:appdimens-ssps:1.0.9")
24+
implementation("io.github.bodenberg:appdimens-sdps:1.1.0")
25+
implementation("io.github.bodenberg:appdimens-ssps:1.1.0")
2626

2727
// All in one
28-
implementation("io.github.bodenberg:appdimens-all:1.0.9")
28+
implementation("io.github.bodenberg:appdimens-all:1.1.0")
2929

3030
// Game development (separate dependency)
31-
implementation("io.github.bodenberg:appdimens-games:1.0.9")
31+
implementation("io.github.bodenberg:appdimens-games:1.1.0")
3232
}
3333

3434
mavenCentral() // or maven { url 'https://jitpack.io' }
@@ -37,17 +37,17 @@ mavenCentral() // or maven { url 'https://jitpack.io' }
3737
```kotlin
3838
dependencies {
3939
// Core (Dynamic + Fixed)
40-
implementation("io.github.bodenberg:appdimens-dynamic:1.0.9")
40+
implementation("io.github.bodenberg:appdimens-dynamic:1.1.0")
4141

4242
// SDP & SSP scaling (optional)
43-
implementation("io.github.bodenberg:appdimens-sdps:1.0.9")
44-
implementation("io.github.bodenberg:appdimens-ssps:1.0.9")
43+
implementation("io.github.bodenberg:appdimens-sdps:1.1.0")
44+
implementation("io.github.bodenberg:appdimens-ssps:1.1.0")
4545

4646
// All in one
47-
implementation("io.github.bodenberg:appdimens-all:1.0.9")
47+
implementation("io.github.bodenberg:appdimens-all:1.1.0")
4848

4949
// Game development (separate dependency)
50-
implementation("io.github.bodenberg:appdimens-games:1.0.9")
50+
implementation("io.github.bodenberg:appdimens-games:1.1.0")
5151
}
5252

5353
mavenCentral()

Android/README.md

Lines changed: 185 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ layout: default
88
<p><strong>Smart and Responsive Dimensioning for Android</strong></p>
99
<p>Mathematically responsive scaling that ensures your UI design adapts perfectly to any screen size or aspect ratio — from phones to TVs, cars, and wearables.</p>
1010

11-
[![Version](https://img.shields.io/badge/version-1.0.9-blue.svg)](https://github.com/bodenberg/appdimens/releases)
11+
[![Version](https://img.shields.io/badge/version-1.1.0-blue.svg)](https://github.com/bodenberg/appdimens/releases)
1212
[![License](https://img.shields.io/badge/license-Apache%202.0-green.svg)](../LICENSE)
1313
[![Platform](https://img.shields.io/badge/platform-Android%2021+-orange.svg)](https://developer.android.com/)
1414
[![Documentation](https://img.shields.io/badge/docs-complete-brightgreen.svg)](https://appdimens-project.web.app/)
@@ -74,30 +74,30 @@ val scaledPosition = appDimensGames.calculateVector2D(position, GameDimensionTyp
7474

7575
```kotlin
7676
dependencies {
77-
// Core library (Dynamic + Fixed scaling)
78-
implementation("io.github.bodenberg:appdimens-dynamic:1.0.9")
77+
// Core library (Dynamic + Fixed scaling + Fluid)
78+
implementation("io.github.bodenberg:appdimens-dynamic:1.1.0")
7979

8080
// Optional: SDP & SSP scaling
81-
implementation("io.github.bodenberg:appdimens-sdps:1.0.9")
82-
implementation("io.github.bodenberg:appdimens-ssps:1.0.9")
81+
implementation("io.github.bodenberg:appdimens-sdps:1.1.0")
82+
implementation("io.github.bodenberg:appdimens-ssps:1.1.0")
8383

8484
// All-in-one package (does not include games module)
85-
implementation("io.github.bodenberg:appdimens-all:1.0.9")
85+
implementation("io.github.bodenberg:appdimens-all:1.1.0")
8686

8787
// Game development with C++/NDK support (separate dependency)
88-
implementation("io.github.bodenberg:appdimens-games:1.0.9")
88+
implementation("io.github.bodenberg:appdimens-games:1.1.0")
8989
}
9090
```
9191

9292
### Gradle (Groovy)
9393

9494
```groovy
9595
dependencies {
96-
implementation 'io.github.bodenberg:appdimens-dynamic:1.0.9'
97-
implementation 'io.github.bodenberg:appdimens-sdps:1.0.9'
98-
implementation 'io.github.bodenberg:appdimens-ssps:1.0.9'
99-
implementation 'io.github.bodenberg:appdimens-all:1.0.9'
100-
implementation 'io.github.bodenberg:appdimens-games:1.0.9'
96+
implementation 'io.github.bodenberg:appdimens-dynamic:1.1.0'
97+
implementation 'io.github.bodenberg:appdimens-sdps:1.1.0'
98+
implementation 'io.github.bodenberg:appdimens-ssps:1.1.0'
99+
implementation 'io.github.bodenberg:appdimens-all:1.1.0'
100+
implementation 'io.github.bodenberg:appdimens-games:1.1.0'
101101
}
102102
```
103103

@@ -118,15 +118,15 @@ repositories {
118118
### Required Versions
119119

120120
| Component | Minimum Version | Recommended |
121-
|-----------|----------------|-------------|
122-
| **Kotlin** | 2.2.20 | 2.2.20 |
123-
| **Android Gradle Plugin** | 8.13.0 | 8.13.0 |
124-
| **Gradle** | 8.5 | 8.5 |
125-
| **compileSdk** | 36 | 36 |
126-
| **minSdk** | 21 (Android 5.0) | 23 (Android 6.0) |
127-
| **targetSdk** | 36 | 36 |
128-
| **Java** | 17 | 17 |
129-
| **Jetpack Compose BOM** | 2025.01.00 | 2025.01.00 |
121+
|-----------|-----------------|-------------|
122+
| **Kotlin** | 2.2.20 | 2.2.20 |
123+
| **Android Gradle Plugin** | 8.13.0 | 8.13.0 |
124+
| **Gradle** | 8.5 | 8.5 |
125+
| **compileSdk** | 36 | 36 |
126+
| **minSdk** | 25 | 25 |
127+
| **targetSdk** | 36 | 36 |
128+
| **Java** | 17 | 17 |
129+
| **Jetpack Compose BOM** | 2025.01.00 | 2025.01.00 |
130130

131131
### Build Configuration Example
132132

@@ -147,7 +147,7 @@ android {
147147

148148
defaultConfig {
149149
applicationId = "com.example.app"
150-
minSdk = 23
150+
minSdk = 25
151151
targetSdk = 36
152152
versionCode = 1
153153
versionName = "1.0"
@@ -176,7 +176,7 @@ dependencies {
176176
implementation("androidx.compose.material3:material3")
177177

178178
// AppDimens
179-
implementation("io.github.bodenberg:appdimens-dynamic:1.0.9")
179+
implementation("io.github.bodenberg:appdimens-dynamic:1.1.0")
180180
}
181181
```
182182

@@ -232,12 +232,142 @@ android {
232232

233233
## 🧠 Core Dimension Models
234234

235-
| Model | Philosophy | Ideal Use Case | Supported In |
236-
|-------|------------|----------------|--------------|
237-
| **Fixed (FX)** | Logarithmic scaling (refined) | Buttons, paddings, margins, icons | Compose + Views + Data Binding |
238-
| **Dynamic (DY)** | Proportional scaling (aggressive) | Containers, grids, fluid fonts | Compose + Views + Data Binding |
239-
| **SDP / SSP** | Pre-calculated resources | Direct `@dimen` usage in XML | Compose + Views (XML) |
240-
| **Physical Units** | mm/cm/inch → Dp/Sp/Px | Wearables, printing, precision layouts | Compose + Views |
235+
| Model | Philosophy | Ideal Use Case | Supported In | Cache |
236+
|-------|------------|----------------|--------------|-------|
237+
| **Fixed (FX)**| Logarithmic scaling (refined) | Buttons, paddings, margins, icons, fonts, containers | Compose + Views + Data Binding | Individual + Global |
238+
| **Dynamic (DY)** | Proportional scaling (aggressive) | Large containers, grids, full-width layouts | Compose + Views + Data Binding | AutoCache + Global |
239+
| **Fluid (FL)** 🌊 | Smooth interpolation (min/max) | Typography, line heights, fluid spacing | **Compose only** | Built-in |
240+
| **SDP / SSP** | Pre-calculated resources | Direct `@dimen` usage in XML | Compose + Views (XML) | Resource-based |
241+
| **Physical Units** | mm/cm/inch → Dp/Sp/Px | Wearables, printing, precision layouts | Compose + Views | No cache needed |
242+
| **Games** 🎮 | Native C++/NDK | Game development, high performance | Separate module | Native LRU cache |
243+
244+
### 🌊 Fluid Model - Smooth Bounded Scaling (Compose Only)
245+
246+
The **Fluid** model provides smooth interpolation between minimum and maximum values based on screen width breakpoints. Perfect for typography and spacing that needs controlled growth.
247+
248+
**Key Features:**
249+
- 📏 **Bounded Growth**: Define min and max values with smooth transitions
250+
- 🎯 **Custom Breakpoints**: Set custom width ranges (default: 320-768dp)
251+
- 📱 **Device-Aware**: Different ranges for different device types
252+
-**Compose Native**: Built for Jetpack Compose
253+
254+
**Basic Usage:**
255+
256+
```kotlin
257+
@Composable
258+
fun FluidExample() {
259+
// Font size from 16 to 24 between 320-768dp width
260+
val fontSize = fluidSp(16f, 24f)
261+
val padding = fluidDp(8f, 16f)
262+
263+
Text(
264+
text = "Fluid Typography",
265+
fontSize = fontSize,
266+
modifier = Modifier.padding(padding)
267+
)
268+
}
269+
270+
// With device type qualifiers
271+
val fontSize = AppDimensFluid(16f, 24f)
272+
.device(FluidDeviceType.TABLET, 20f, 32f)
273+
.device(FluidDeviceType.TV, 24f, 40f)
274+
275+
// Multiple fluid values with shared breakpoints
276+
val (fontSize, padding, margin) = fluidMultipleDp(
277+
listOf(
278+
14f to 20f, // fontSize
279+
8f to 16f, // padding
280+
12f to 24f // margin
281+
)
282+
)
283+
284+
// Using extension methods
285+
val fluid = 16f.fluidTo(24f)
286+
val fontSize = fluid.calculate(screenWidthDp)
287+
```
288+
289+
**When to Use Fluid vs Fixed:**
290+
291+
| Aspect | Fluid | Fixed |
292+
|--------|-------|-------|
293+
| **Growth** | Linear between min/max | Logarithmic (slows on large screens) |
294+
| **Control** | Explicit bounds (min/max) | Automatic adaptive scaling |
295+
| **Best for** | Typography, line heights | UI elements, buttons, icons |
296+
| **Platform** | Compose only | Compose + Views + XML |
297+
298+
See [FluidExampleActivity.kt](./app/src/main/java/com/example/app/compose/FluidExampleActivity.kt) for complete examples.
299+
300+
### ⚡ Global Cache Control
301+
302+
Control caching behavior globally or per-instance:
303+
304+
```kotlin
305+
// Global cache control
306+
AppDimens.setGlobalCache(true) // Enable (default)
307+
AppDimens.setGlobalCache(false) // Disable and clear all caches
308+
AppDimens.clearAllCaches() // Clear all cached values
309+
val isEnabled = AppDimens.isGlobalCacheEnabled()
310+
311+
// Per-instance cache control
312+
val dimension = AppDimens.fixed(100)
313+
.cache(true) // Enable cache for this instance
314+
.toDp(resources)
315+
316+
val dynamicDim = AppDimens.dynamic(200)
317+
.cache(false) // Disable cache for this instance
318+
.toDp(resources)
319+
```
320+
321+
**Cache Systems:**
322+
- **Fixed**: Individual instance cache with configuration-based invalidation
323+
- **Dynamic**: Automatic AutoCache system with dependency tracking
324+
- **Global Control**: Affects all instances when `globalCacheEnabled = false`
325+
- **Per-Instance**: Override global settings for specific instances
326+
- **Smart Invalidation**: Automatic invalidation on configuration changes
327+
328+
### 🆕 Base Orientation Support (v1.2.0)
329+
330+
Auto-adapt to screen rotation - design for one orientation, automatically maintain proportions when rotated:
331+
332+
```kotlin
333+
// Explicit API
334+
val cardWidth = 300.fixedDp()
335+
.baseOrientation(BaseOrientation.PORTRAIT)
336+
.type(ScreenType.LOWEST)
337+
.dp
338+
339+
// Shorthand methods
340+
val width1 = 300.fixedDp().portraitLowest().dp // Portrait design, uses width
341+
val height1 = 200.fixedDp().portraitHighest().dp // Portrait design, uses height
342+
val width2 = 300.fixedDp().landscapeLowest().dp // Landscape design, uses height
343+
val height2 = 200.fixedDp().landscapeHighest().dp // Landscape design, uses width
344+
345+
// Compose extensions with Base Orientation
346+
@Composable
347+
fun ResponsiveCard() {
348+
Card(
349+
modifier = Modifier
350+
.width(300.fxPortraitLowest) // Auto-inverts in landscape
351+
.height(200.fxPortraitHighest) // Auto-inverts in landscape
352+
) {
353+
// Content
354+
}
355+
}
356+
357+
// Dynamic also supports Base Orientation
358+
val dynamicWidth = 0.8f.dynamicPer(type = ScreenType.LOWEST)
359+
.dynamic()
360+
.portraitLowest()
361+
.dp
362+
```
363+
364+
**How it works:**
365+
- **PORTRAIT Design**: When device is in landscape → LOWEST↔HIGHEST inverts
366+
- **LANDSCAPE Design**: When device is in portrait → LOWEST↔HIGHEST inverts
367+
- **AUTO** (default): No auto-inversion, uses types as-is
368+
- **Zero overhead**: When baseOrientation = AUTO (default)
369+
370+
See [FluidExampleActivity.kt](./app/src/main/java/com/example/app/compose/FluidExampleActivity.kt) for complete examples.
241371

242372
---
243373

@@ -458,10 +588,32 @@ class GameActivity : Activity() {
458588
appDimensGames.initialize(this)
459589

460590
// Calculate responsive dimensions for game elements
461-
val buttonSize = appDimensGames.calculateButtonSize(48.0f)
462-
val textSize = appDimensGames.calculateTextSize(16.0f)
463-
val playerSize = appDimensGames.calculatePlayerSize(64.0f)
464-
val enemySize = appDimensGames.calculateEnemySize(32.0f)
591+
val buttonSize = appDimensGames.calculateButtonSize(48.0f) // Fixed scaling for UI
592+
val textSize = appDimensGames.calculateTextSize(16.0f) // Fixed scaling for text
593+
val playerSize = appDimensGames.calculatePlayerSize(64.0f) // Game world scaling
594+
val enemySize = appDimensGames.calculateEnemySize(32.0f) // Game world scaling
595+
val uiOverlaySize = appDimensGames.calculateUISize(24.0f) // UI overlay scaling
596+
597+
// Physical units in games (NEW)
598+
val touchTargetWidth = appDimensGames.mm(10f) // 10mm touch target
599+
val cardWidth = appDimensGames.cm(8f) // 8cm card
600+
val screenSize = appDimensGames.inch(5f) // 5 inch element
601+
602+
// Vector operations
603+
val position = GameVector2D(100f, 200f)
604+
val scaledPosition = appDimensGames.calculateVector2D(position, GameDimensionType.GAME_WORLD)
605+
606+
// Rectangle/bounds operations
607+
val viewport = GameRectangle(0f, 0f, 800f, 600f)
608+
val scaledViewport = appDimensGames.calculateRectangle(viewport, GameDimensionType.DYNAMIC)
609+
610+
// Performance configuration
611+
appDimensGames.configurePerformance(
612+
GamePerformanceSettings.HIGH_PERFORMANCE // For demanding games
613+
)
614+
615+
// Cache management
616+
appDimensGames.clearCache() // Clear cached calculations when needed
465617
}
466618
}
467619
```

Android/app/build.gradle.kts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ android {
1313

1414
defaultConfig {
1515
applicationId = "com.example.app"
16-
minSdk = 23
16+
minSdk = 25
1717
targetSdk = 36
1818
versionCode = 1
1919
versionName = "1.0"
@@ -50,12 +50,12 @@ android {
5050
dependencies {
5151
api(project(":appdimens_all"))
5252
api(project(":appdimens_games"))
53-
api(project(":appdimens_dynamic"))
54-
api(project(":appdimens_sdps"))
55-
api(project(":appdimens_ssps"))
56-
//implementation("com.appdimens:appdimens-all:1.0.0")
53+
//api(project(":appdimens_dynamic"))
54+
//api(project(":appdimens_sdps"))
55+
//api(project(":appdimens_ssps"))
56+
//implementation("io.github.bodenberg:appdimens-all:1.0.8")
57+
//implementation("io.github.bodenberg:appdimens-games:1.0.8")
5758
//implementation("com.github.bodenberg.appdimens:appdimens-all:1.0.0")
58-
//implementation(libs.appdimens.all)
5959

6060
implementation(libs.androidx.core.ktx)
6161
implementation(libs.androidx.lifecycle.runtime.ktx)

0 commit comments

Comments
 (0)