73 |
74 |
--------------------------------------------------------------------------------
/blueprint/src/commonMain/kotlin/com/popovanton0/blueprint/BlueprintId.kt:
--------------------------------------------------------------------------------
1 | package com.popovanton0.blueprint
2 |
3 | import androidx.compose.runtime.Stable
4 | import androidx.compose.ui.Modifier
5 | import androidx.compose.ui.layout.LayoutCoordinates
6 | import androidx.compose.ui.modifier.ModifierLocalModifierNode
7 | import androidx.compose.ui.node.GlobalPositionAwareModifierNode
8 | import androidx.compose.ui.node.ModifierNodeElement
9 | import androidx.compose.ui.platform.InspectorInfo
10 | import com.popovanton0.blueprint.dsl.SizeUnits
11 |
12 | /**
13 | * This modifier marks a UI-composable with an [id] that can be used in blueprintBuilder to define
14 | * dimension lines between this composable and others.
15 | *
16 | * [id] must be **unique** for all children of the [Blueprint] composable.
17 | *
18 | * @param id *unique* identifier for this composable. Use it in
19 | * blueprintBuilder to define dimension lines.
20 | * @param sizeUnits if non-null, size label is drawn over the composable.
21 | *
22 | * @see blueprintEnabled
23 | */
24 | @Stable
25 | public fun Modifier.blueprintId(
26 | id: String,
27 | sizeUnits: SizeUnits? = null
28 | ): Modifier = if (blueprintEnabled) {
29 | this then BlueprintMarkerElement(
30 | id = id,
31 | sizeUnits = sizeUnits,
32 | inspectorInfo = {
33 | name = "blueprintId"
34 | properties["id"] = id
35 | properties["sizeUnits"] = sizeUnits
36 | }
37 | )
38 | } else {
39 | this
40 | }
41 |
42 | private class BlueprintMarkerElement(
43 | val id: String,
44 | val sizeUnits: SizeUnits?,
45 | val inspectorInfo: InspectorInfo.() -> Unit,
46 | ) : ModifierNodeElement() {
47 | override fun create(): BlueprintMarkerNode = BlueprintMarkerNode(id, sizeUnits)
48 |
49 | override fun update(node: BlueprintMarkerNode) {
50 | node.id = id
51 | node.sizeUnits = sizeUnits
52 | }
53 |
54 | override fun equals(other: Any?): Boolean {
55 | val otherModifierElement = other as? BlueprintMarkerElement ?: return false
56 | return id == otherModifierElement.id && sizeUnits == otherModifierElement.sizeUnits
57 | }
58 |
59 | override fun hashCode(): Int {
60 | var result = id.hashCode()
61 | result = 31 * result + (sizeUnits?.hashCode() ?: 0)
62 | return result
63 | }
64 |
65 | override fun InspectorInfo.inspectableProperties() {
66 | inspectorInfo()
67 | }
68 | }
69 |
70 | private class BlueprintMarkerNode(
71 | var id: String,
72 | var sizeUnits: SizeUnits?,
73 | ) : Modifier.Node(), ModifierLocalModifierNode, GlobalPositionAwareModifierNode {
74 |
75 | override fun onGloballyPositioned(coordinates: LayoutCoordinates) {
76 | val markers = ModifierLocalBlueprintMarkers.current ?: return
77 | markers.remove(id)
78 | if (coordinates.isAttached) markers[id] = BlueprintMarker(coordinates, sizeUnits)
79 | }
80 | }
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/blueprint/build.gradle.kts:
--------------------------------------------------------------------------------
1 | @file:Suppress("UnstableApiUsage")
2 |
3 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
4 |
5 |
6 | plugins {
7 | alias(libs.plugins.kotlin.multiplatform)
8 | alias(libs.plugins.kotlin.plugin.compose)
9 | alias(libs.plugins.compose)
10 | alias(libs.plugins.android.library)
11 | alias(libs.plugins.paparazzi)
12 | alias(libs.plugins.binaryCompatibility)
13 | id("maven-publish")
14 | }
15 |
16 | kotlin {
17 | androidTarget {
18 | publishLibraryVariants("release")
19 | compilations.all {
20 | compileTaskProvider.configure {
21 | compilerOptions {
22 | jvmTarget.set(JvmTarget.JVM_17)
23 | }
24 | }
25 | }
26 | }
27 | jvm("desktop")
28 | listOf(
29 | iosX64(),
30 | iosArm64(),
31 | iosSimulatorArm64()
32 | ).forEach { iosTarget ->
33 | iosTarget.binaries.framework {
34 | baseName = "blueprint"
35 | isStatic = true
36 | }
37 | }
38 |
39 | applyDefaultHierarchyTemplate()
40 |
41 | sourceSets {
42 | all {
43 | languageSettings {
44 | optIn("com.popovanton0.blueprint.ExperimentalBlueprintApi")
45 | }
46 | }
47 | commonMain {
48 | dependencies {
49 | implementation(compose.runtime)
50 | implementation(compose.foundation)
51 | implementation(libs.androidx.annotation)
52 | }
53 | }
54 | commonTest {
55 |
56 | }
57 | androidUnitTest {
58 | dependencies {
59 | implementation(libs.junit)
60 | implementation(compose.material3)
61 | implementation(libs.testParameterInjector)
62 | implementation(libs.equalsverifier)
63 | implementation(libs.androidx.testJunit)
64 | implementation(libs.androidx.compose.ui.testJunit)
65 | implementation(libs.androidx.compose.ui.tooling)
66 | }
67 | }
68 | androidInstrumentedTest {
69 |
70 | }
71 | }
72 | }
73 |
74 | android {
75 | namespace = "com.popovanton0.blueprint"
76 | compileSdk = libs.versions.compileSdk.get().toInt()
77 |
78 | defaultConfig {
79 | minSdk = 21
80 |
81 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
82 | consumerProguardFiles("consumer-rules.pro")
83 | }
84 |
85 | buildTypes {
86 | release {
87 | isMinifyEnabled = false
88 | proguardFiles("proguard-android-optimize.txt", "proguard-rules.pro")
89 | }
90 | }
91 | compileOptions {
92 | sourceCompatibility = JavaVersion.VERSION_17
93 | targetCompatibility = JavaVersion.VERSION_17
94 | }
95 | kotlin {
96 | explicitApi()
97 | }
98 | }
99 |
100 | tasks.named("assemble") {
101 | dependsOn("check")
102 | }
103 |
104 | group = "com.popovanton0.blueprint"
105 | version = libs.versions.blueprint.get()
106 |
107 | publishing {
108 | }
109 |
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | @file:Suppress("UnstableApiUsage")
2 |
3 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
4 |
5 | plugins {
6 | alias(libs.plugins.kotlin.multiplatform)
7 | alias(libs.plugins.kotlin.plugin.compose)
8 | alias(libs.plugins.android.application)
9 | alias(libs.plugins.compose)
10 | }
11 |
12 | kotlin {
13 | androidTarget {
14 | compilations.all {
15 | compileTaskProvider.configure {
16 | compilerOptions {
17 | jvmTarget.set(JvmTarget.JVM_17)
18 | }
19 | }
20 | }
21 | }
22 | jvm("desktop")
23 | listOf(
24 | iosX64(),
25 | iosArm64(),
26 | iosSimulatorArm64()
27 | ).forEach {
28 | it.binaries.framework {
29 | baseName = "blueprintDemoCompose"
30 | isStatic = true
31 | }
32 | }
33 |
34 | applyDefaultHierarchyTemplate()
35 |
36 | sourceSets {
37 | all {
38 | languageSettings {
39 | optIn("androidx.compose.ui.ExperimentalComposeUiApi")
40 | optIn("com.popovanton0.blueprint.ExperimentalBlueprintApi")
41 | }
42 | }
43 |
44 | commonMain.dependencies {
45 | implementation(project(":blueprint"))
46 | implementation(compose.foundation)
47 | implementation(compose.material3)
48 | implementation(compose.materialIconsExtended)
49 | }
50 |
51 | androidMain.dependencies {
52 | implementation(compose.preview)
53 | implementation(compose.uiTooling)
54 | implementation(compose.uiUtil)
55 |
56 | implementation(libs.androidx.coreKtx)
57 | implementation(libs.androidx.lifecycleRuntimeKtx)
58 | implementation(libs.androidx.activityCompose)
59 | // note, these should have been debugImplementations,
60 | // but that does not seem to work
61 | implementation(libs.androidx.compose.ui.tooling)
62 | implementation(libs.androidx.compose.ui.testManifest)
63 | }
64 |
65 | val desktopMain by getting
66 | desktopMain.dependencies {
67 | implementation(compose.desktop.currentOs)
68 | implementation(compose.preview)
69 | implementation(compose.uiTooling)
70 | implementation(compose.uiUtil)
71 | }
72 | }
73 |
74 | }
75 |
76 | android {
77 | namespace = "com.popovanton0.blueprint.app"
78 | compileSdk = libs.versions.compileSdk.get().toInt()
79 |
80 | defaultConfig {
81 | applicationId = "com.popovanton0.blueprint.app"
82 | minSdk = 21
83 | targetSdk = libs.versions.compileSdk.get().toInt()
84 | versionCode = 1
85 | versionName = "1.0"
86 |
87 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
88 | vectorDrawables.useSupportLibrary = true
89 | }
90 |
91 | buildTypes {
92 | release {
93 | isMinifyEnabled = true
94 | proguardFiles("proguard-android-optimize.txt", "proguard-rules.pro")
95 | }
96 | }
97 | compileOptions {
98 | sourceCompatibility = JavaVersion.VERSION_17
99 | targetCompatibility = JavaVersion.VERSION_17
100 | }
101 |
102 | packagingOptions.resources.excludes += "/META-INF/{AL2.0,LGPL2.1}"
103 | }
104 |
105 | compose.desktop {
106 | application {
107 | mainClass = "com.popovanton0.blueprint.app.MainKt"
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | xmlns:android
15 |
16 | ^$
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | xmlns:.*
26 |
27 | ^$
28 |
29 |
30 | BY_NAME
31 |
32 |
33 |
34 |
35 |
36 |
37 | .*:id
38 |
39 | http://schemas.android.com/apk/res/android
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | .*:name
49 |
50 | http://schemas.android.com/apk/res/android
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | name
60 |
61 | ^$
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | style
71 |
72 | ^$
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | .*
82 |
83 | ^$
84 |
85 |
86 | BY_NAME
87 |
88 |
89 |
90 |
91 |
92 |
93 | .*
94 |
95 | http://schemas.android.com/apk/res/android
96 |
97 |
98 | ANDROID_ATTRIBUTE_ORDER
99 |
100 |
101 |
102 |
103 |
104 |
105 | .*
106 |
107 | .*
108 |
109 |
110 | BY_NAME
111 |
112 |
113 |
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 | blueprint = "2.0.0-alpha01"
3 | compileSdk = "35"
4 | gradlePlugin = "8.7.3"
5 | kotlin = "2.1.0"
6 | compose = "1.7.3"
7 | composeCompiler = "1.5.8"
8 | paparazzi = "1.3.2"
9 | junit = "4.13.2"
10 | testParameterInjector = "1.12"
11 | equalsverifier = "3.14.2"
12 | androidxTestJunit = "1.1.5"
13 | androidxCoreKtx = "1.12.0"
14 | lifecycleRuntimeKtx = "2.7.0"
15 | androidxActivityCompose = "1.8.2"
16 | androidx-benchmark = "1.2.3"
17 | test-runner = "1.5.2"
18 | test-rules = "1.5.0"
19 | benchmark-junit4 = "1.2.3"
20 | uiAndroidStubs = "1.6.0"
21 | androidxAnnotation = "1.9.1"
22 | composeMaterial = "1.3.2"
23 | binaryCompatibility = "0.17.0"
24 | composeIcons = "1.7.8"
25 | composeAndroidx = "1.8.1"
26 |
27 | [libraries]
28 | androidx-coreKtx = { module = "androidx.core:core-ktx", version.ref = "androidxCoreKtx" }
29 | androidx-lifecycleRuntimeKtx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
30 | androidx-activityCompose = { module = "androidx.activity:activity-compose", version.ref = "androidxActivityCompose" }
31 | androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidxAnnotation" }
32 |
33 | androidx-compose-icons = { module = "androidx.compose.material:material-icons-extended", version.ref = "composeIcons" }
34 | androidx-compose-material = { module = "androidx.compose.material3:material3", version.ref = "composeMaterial" }
35 | androidx-compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "composeAndroidx" }
36 | androidx-compose-ui = { module = "androidx.compose.ui:ui", version.ref = "composeAndroidx" }
37 | androidx-compose-ui-util = { module = "androidx.compose.ui:ui-util", version.ref = "composeAndroidx" }
38 | androidx-compose-ui-testManifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "composeAndroidx" }
39 | androidx-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "composeAndroidx" }
40 | androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "composeAndroidx" }
41 | androidx-compose-ui-testJunit = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "composeAndroidx" }
42 |
43 | androidx-ui-android-stubs = { group = "androidx.compose.ui", name = "ui-android-stubs", version.ref = "uiAndroidStubs" }
44 | androidx-runner = { group = "androidx.test", name = "runner", version.ref = "test-runner" }
45 | androidx-rules = { group = "androidx.test", name = "rules", version.ref = "test-rules" }
46 | androidx-testJunit = { module = "androidx.test.ext:junit", version.ref = "androidxTestJunit" }
47 | androidx-benchmark-junit4 = { group = "androidx.benchmark", name = "benchmark-junit4", version.ref = "benchmark-junit4" }
48 | junit = { module = "junit:junit", version.ref = "junit" }
49 | equalsverifier = { module = "nl.jqno.equalsverifier:equalsverifier", version.ref = "equalsverifier" }
50 | testParameterInjector = { module = "com.google.testparameterinjector:test-parameter-injector", version.ref = "testParameterInjector" }
51 |
52 |
53 | [plugins]
54 | android-application = { id = "com.android.application", version.ref = "gradlePlugin" }
55 | android-library = { id = "com.android.library", version.ref = "gradlePlugin" }
56 | kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
57 | paparazzi = { id = "app.cash.paparazzi", version.ref = "paparazzi" }
58 | androidx-benchmark = { id = "androidx.benchmark", version.ref = "androidx-benchmark" }
59 | binaryCompatibility = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binaryCompatibility" }
60 |
61 | kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
62 | kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
63 | kotlin-plugin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
64 |
65 | compose = { id = "org.jetbrains.compose", version.ref = "compose" }
66 |
67 | [bundles]
68 |
69 |
--------------------------------------------------------------------------------
/app/src/androidMain/kotlin/com/popovanton0/blueprint/app/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.popovanton0.blueprint.app
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import androidx.compose.foundation.background
7 | import androidx.compose.foundation.isSystemInDarkTheme
8 | import androidx.compose.foundation.layout.Arrangement
9 | import androidx.compose.foundation.layout.Box
10 | import androidx.compose.foundation.layout.Row
11 | import androidx.compose.foundation.layout.fillMaxSize
12 | import androidx.compose.foundation.layout.padding
13 | import androidx.compose.foundation.layout.size
14 | import androidx.compose.material.icons.Icons
15 | import androidx.compose.material.icons.filled.Home
16 | import androidx.compose.material3.Icon
17 | import androidx.compose.material3.MaterialTheme
18 | import androidx.compose.material3.Surface
19 | import androidx.compose.material3.darkColorScheme
20 | import androidx.compose.material3.lightColorScheme
21 | import androidx.compose.runtime.Composable
22 | import androidx.compose.runtime.LaunchedEffect
23 | import androidx.compose.runtime.getValue
24 | import androidx.compose.runtime.mutableFloatStateOf
25 | import androidx.compose.runtime.remember
26 | import androidx.compose.runtime.setValue
27 | import androidx.compose.ui.Modifier
28 | import androidx.compose.ui.graphics.Color
29 | import androidx.compose.ui.graphics.vector.rememberVectorPainter
30 | import androidx.compose.ui.unit.dp
31 | import com.popovanton0.blueprint.Blueprint
32 | import com.popovanton0.blueprint.blueprintId
33 | import com.popovanton0.blueprint.dsl.Position
34 | import kotlinx.coroutines.delay
35 |
36 | class MainActivity : ComponentActivity() {
37 | override fun onCreate(savedInstanceState: Bundle?) {
38 | super.onCreate(savedInstanceState)
39 | setContent {
40 | MaterialTheme(if (isSystemInDarkTheme()) darkColorScheme() else lightColorScheme()) {
41 | // A surface container using the 'background' color from the theme
42 | Surface(
43 | modifier = Modifier.fillMaxSize(),
44 | color = MaterialTheme.colorScheme.background
45 | ) {
46 | Lab()
47 | return@Surface
48 | val case = remember { RecreateLayersTestCase() }
49 | case.Content()
50 | LaunchedEffect(Unit) {
51 | if (false)repeat(1000000) {
52 | case.toggleState()
53 | delay(25)
54 | }
55 | }
56 | }
57 | }
58 | }
59 | }
60 | }
61 |
62 | private class RecreateLayersTestCase {
63 |
64 | private val range = 1f..50f
65 | private var size by mutableFloatStateOf(range.start)
66 | private var increase = true
67 | private val step = 0.5f
68 |
69 | fun toggleState() {
70 | if (size >= range.endInclusive) increase = false
71 | else if (size <= range.start) increase = true
72 | if (increase) size += step else size -= step
73 | println("size = $size")
74 | }
75 |
76 | @Composable
77 | fun Content() = Box {
78 | Blueprint(
79 | modifier = Modifier.padding(12.dp),
80 | // fontColor = Color.Blue,
81 | // fontSize = 20.sp,
82 | blueprintBuilder = {
83 | widths {
84 | group {
85 | "icon" lineTo "icon"
86 | "box" lineTo "box"
87 | }
88 | group { "icon" lineTo "text" }
89 | group(Position.Vertical.Top) { "icon".center lineTo "box".center }
90 | group(Position.Vertical.Top) { "icon".center lineTo "box".center }
91 | }
92 | if (true) heights {
93 | group { "icon" lineTo "icon" }
94 | group { "icon" lineTo "icon" }
95 | group(Position.Horizontal.End) { "box" lineTo "box" }
96 | group(Position.Horizontal.End) { "box" lineTo "box" }
97 | }
98 | }
99 | ) {
100 | Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
101 | if (size < 25f) Icon(
102 | modifier = Modifier
103 | .size(20.dp)
104 | .blueprintId("icon"),
105 | painter = rememberVectorPainter(Icons.Default.Home),
106 | contentDescription = null
107 | )
108 | Box(
109 | modifier = Modifier
110 | .size(size.dp)
111 | .background(Color.Blue)
112 | .blueprintId("box"),
113 | )
114 | }
115 | }
116 | }
117 | }
--------------------------------------------------------------------------------
/blueprint/src/androidUnitTest/kotlin/com/popovanton0/blueprint/Dsl.kt:
--------------------------------------------------------------------------------
1 | package com.popovanton0.blueprint
2 |
3 | import com.google.testing.junit.testparameterinjector.TestParameter
4 | import com.google.testing.junit.testparameterinjector.TestParameterInjector
5 | import com.popovanton0.blueprint.dsl.Anchor
6 | import com.popovanton0.blueprint.dsl.BlueprintBuilderScope
7 | import com.popovanton0.blueprint.dsl.Dimension
8 | import com.popovanton0.blueprint.dsl.MeasureUnit
9 | import com.popovanton0.blueprint.dsl.Position.Horizontal.Companion.End
10 | import com.popovanton0.blueprint.dsl.Position.Horizontal.Companion.Start
11 | import com.popovanton0.blueprint.dsl.Position.Vertical.Companion.Bottom
12 | import com.popovanton0.blueprint.dsl.Position.Vertical.Companion.Top
13 | import org.junit.Assert.assertEquals
14 | import org.junit.Assert.assertTrue
15 | import org.junit.Test
16 | import org.junit.runner.RunWith
17 |
18 | @RunWith(TestParameterInjector::class)
19 | internal class Dsl {
20 |
21 | @Suppress("JUnitMalformedDeclaration")
22 | @Test
23 | fun `empty dsl produces empty blueprint`(
24 | @TestParameter("0", "1", "2") horizontalBlockCalls: Int,
25 | @TestParameter("0", "1", "2") verticalBlockCalls: Int,
26 | @TestParameter("0", "1", "2") horizontalGroupBlockCalls: Int,
27 | @TestParameter("0", "1", "2") verticalGroupBlockCalls: Int,
28 | ) {
29 | println("Blueprint")
30 | val actual = BlueprintBuilder {
31 | repeat(horizontalBlockCalls) {
32 | widths {
33 | println(" horizontal")
34 | repeat(horizontalGroupBlockCalls) {
35 | group { }
36 | println(" group")
37 | }
38 | }
39 | }
40 | repeat(verticalBlockCalls) {
41 | heights {
42 | println(" vertical")
43 | repeat(verticalGroupBlockCalls) {
44 | group { }
45 | println(" group")
46 | }
47 | }
48 | }
49 | }
50 | println("=======================\n")
51 | assertTrue(actual.groupCollection.flatMap { it }.isEmpty())
52 | }
53 |
54 | @Test
55 | fun `typical dsl usage`() {
56 | val actual = BlueprintBuilder {
57 | widths {
58 | group {
59 | "one" lineTo "two"
60 | "two".center lineTo "three".right
61 | }
62 | group(Top) {
63 | "Apple" lineTo "Banana"
64 | "Mango".center lineTo "Avocado".right
65 | }
66 | }
67 | heights {
68 | group {
69 | "Car" lineTo "Bike"
70 | "Plane".center lineTo "Helicopter".bottom
71 | }
72 | group(End) {
73 | "Sock" lineTo "Blouse"
74 | "Shirt".center lineTo "Bow-tie".bottom
75 | }
76 | }
77 | }
78 |
79 | assertEquals(Bottom, actual.horizontalBottomGroups.single().position)
80 | assertEquals(Top, actual.horizontalTopGroups.single().position)
81 | assertEquals(Start, actual.verticalLeftGroups.single().position)
82 | assertEquals(End, actual.verticalRightGroups.single().position)
83 |
84 | assertEquals(
85 | Dimension(Anchor("one", 0f), Anchor("two", 1f), MeasureUnit.Dp),
86 | actual.horizontalBottomGroups.single().dimensions[0],
87 | )
88 | assertEquals(
89 | Dimension(Anchor("Apple", 0f), Anchor("Banana", 1f), MeasureUnit.Dp),
90 | actual.horizontalTopGroups.single().dimensions[0],
91 | )
92 | assertEquals(
93 | Dimension(Anchor("Car", 0f), Anchor("Bike", 1f), MeasureUnit.Dp),
94 | actual.verticalLeftGroups.single().dimensions[0],
95 | )
96 | assertEquals(
97 | Dimension(Anchor("Sock", 0f), Anchor("Blouse", 1f), MeasureUnit.Dp),
98 | actual.verticalRightGroups.single().dimensions[0],
99 | )
100 |
101 | // second dimension
102 |
103 | assertEquals(
104 | Dimension(Anchor("two", 0.5f), Anchor("three", 1f), MeasureUnit.Dp),
105 | actual.horizontalBottomGroups.single().dimensions[1],
106 | )
107 | assertEquals(
108 | Dimension(Anchor("Mango", 0.5f), Anchor("Avocado", 1f), MeasureUnit.Dp),
109 | actual.horizontalTopGroups.single().dimensions[1],
110 | )
111 | assertEquals(
112 | Dimension(Anchor("Plane", 0.5f), Anchor("Helicopter", 1f), MeasureUnit.Dp),
113 | actual.verticalLeftGroups.single().dimensions[1],
114 | )
115 | assertEquals(
116 | Dimension(Anchor("Shirt", 0.5f), Anchor("Bow-tie", 1f), MeasureUnit.Dp),
117 | actual.verticalRightGroups.single().dimensions[1],
118 | )
119 | }
120 |
121 | @Suppress("TestFunctionName")
122 | private fun BlueprintBuilder(block: BlueprintBuilderScope.() -> Unit) =
123 | BlueprintBuilderScope().apply(block).toBlueprint()
124 | }
125 |
--------------------------------------------------------------------------------
/app/src/androidMain/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/.idea/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/blueprint/api/blueprint.api:
--------------------------------------------------------------------------------
1 | public final class com/popovanton0/blueprint/BlueprintIdKt {
2 | public static final fun blueprintId (Landroidx/compose/ui/Modifier;Ljava/lang/String;Lcom/popovanton0/blueprint/dsl/SizeUnits;)Landroidx/compose/ui/Modifier;
3 | public static synthetic fun blueprintId$default (Landroidx/compose/ui/Modifier;Ljava/lang/String;Lcom/popovanton0/blueprint/dsl/SizeUnits;ILjava/lang/Object;)Landroidx/compose/ui/Modifier;
4 | }
5 |
6 | public final class com/popovanton0/blueprint/BlueprintKt {
7 | public static final fun Blueprint-clabC8w (Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/BorderStroke;Landroidx/compose/foundation/BorderStroke;JJLcom/popovanton0/blueprint/dsl/Arrow;IZZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V
8 | public static final fun getBlueprintEnabled ()Z
9 | public static final fun setBlueprintEnabled (Z)V
10 | }
11 |
12 | public abstract interface annotation class com/popovanton0/blueprint/ExperimentalBlueprintApi : java/lang/annotation/Annotation {
13 | }
14 |
15 | public final class com/popovanton0/blueprint/dsl/Anchor {
16 | public static final field $stable I
17 | public fun equals (Ljava/lang/Object;)Z
18 | public fun hashCode ()I
19 | }
20 |
21 | public final class com/popovanton0/blueprint/dsl/Arrow {
22 | public static final field $stable I
23 | public synthetic fun (FFZILkotlin/jvm/internal/DefaultConstructorMarker;)V
24 | public synthetic fun (FFZLkotlin/jvm/internal/DefaultConstructorMarker;)V
25 | public fun equals (Ljava/lang/Object;)Z
26 | public final fun getAngle ()F
27 | public final fun getLength-D9Ej5fM ()F
28 | public final fun getRoundCap ()Z
29 | public fun hashCode ()I
30 | }
31 |
32 | public final class com/popovanton0/blueprint/dsl/BlueprintBuilderScope {
33 | public static final field $stable I
34 | public final fun heights (Lkotlin/jvm/functions/Function1;)V
35 | public final fun widths (Lkotlin/jvm/functions/Function1;)V
36 | }
37 |
38 | public abstract class com/popovanton0/blueprint/dsl/GroupScope {
39 | public static final field $stable I
40 | public final fun lineTo (Lcom/popovanton0/blueprint/dsl/Anchor;Lcom/popovanton0/blueprint/dsl/Anchor;)V
41 | public final fun spLineTo (Lcom/popovanton0/blueprint/dsl/Anchor;Lcom/popovanton0/blueprint/dsl/Anchor;)V
42 | }
43 |
44 | public final class com/popovanton0/blueprint/dsl/HorizontalGroupScope : com/popovanton0/blueprint/dsl/GroupScope {
45 | public static final field $stable I
46 | public final fun getCenter (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
47 | public final fun getLeft (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
48 | public final fun getRight (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
49 | public final fun lineTo (Ljava/lang/String;Ljava/lang/String;)V
50 | public final fun spLineTo (Ljava/lang/String;Ljava/lang/String;)V
51 | }
52 |
53 | public final class com/popovanton0/blueprint/dsl/HorizontalScope {
54 | public static final field $stable I
55 | public final fun group-QjWXQlE (ILkotlin/jvm/functions/Function1;)V
56 | public static synthetic fun group-QjWXQlE$default (Lcom/popovanton0/blueprint/dsl/HorizontalScope;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
57 | }
58 |
59 | public final class com/popovanton0/blueprint/dsl/MeasureUnit {
60 | public static final field Companion Lcom/popovanton0/blueprint/dsl/MeasureUnit$Companion;
61 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/MeasureUnit;
62 | public fun equals (Ljava/lang/Object;)Z
63 | public static fun equals-impl (ILjava/lang/Object;)Z
64 | public static final fun equals-impl0 (II)Z
65 | public fun hashCode ()I
66 | public static fun hashCode-impl (I)I
67 | public fun toString ()Ljava/lang/String;
68 | public static fun toString-impl (I)Ljava/lang/String;
69 | public final synthetic fun unbox-impl ()I
70 | }
71 |
72 | public final class com/popovanton0/blueprint/dsl/MeasureUnit$Companion {
73 | public final fun getDp-kfOZ-k0 ()I
74 | public final fun getSp-kfOZ-k0 ()I
75 | }
76 |
77 | public abstract interface class com/popovanton0/blueprint/dsl/Position {
78 | }
79 |
80 | public final class com/popovanton0/blueprint/dsl/Position$Horizontal : com/popovanton0/blueprint/dsl/Position {
81 | public static final field Companion Lcom/popovanton0/blueprint/dsl/Position$Horizontal$Companion;
82 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/Position$Horizontal;
83 | public fun equals (Ljava/lang/Object;)Z
84 | public static fun equals-impl (ILjava/lang/Object;)Z
85 | public static final fun equals-impl0 (II)Z
86 | public fun hashCode ()I
87 | public static fun hashCode-impl (I)I
88 | public fun toString ()Ljava/lang/String;
89 | public static fun toString-impl (I)Ljava/lang/String;
90 | public final synthetic fun unbox-impl ()I
91 | }
92 |
93 | public final class com/popovanton0/blueprint/dsl/Position$Horizontal$Companion {
94 | public final fun getEnd-o_BGRZA ()I
95 | public final fun getStart-o_BGRZA ()I
96 | }
97 |
98 | public final class com/popovanton0/blueprint/dsl/Position$Vertical : com/popovanton0/blueprint/dsl/Position {
99 | public static final field Companion Lcom/popovanton0/blueprint/dsl/Position$Vertical$Companion;
100 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/Position$Vertical;
101 | public fun equals (Ljava/lang/Object;)Z
102 | public static fun equals-impl (ILjava/lang/Object;)Z
103 | public static final fun equals-impl0 (II)Z
104 | public fun hashCode ()I
105 | public static fun hashCode-impl (I)I
106 | public fun toString ()Ljava/lang/String;
107 | public static fun toString-impl (I)Ljava/lang/String;
108 | public final synthetic fun unbox-impl ()I
109 | }
110 |
111 | public final class com/popovanton0/blueprint/dsl/Position$Vertical$Companion {
112 | public final fun getBottom-6W8Q2GU ()I
113 | public final fun getTop-6W8Q2GU ()I
114 | }
115 |
116 | public final class com/popovanton0/blueprint/dsl/SizeUnits {
117 | public static final field $stable I
118 | public static final field Companion Lcom/popovanton0/blueprint/dsl/SizeUnits$Companion;
119 | public synthetic fun (IIILkotlin/jvm/internal/DefaultConstructorMarker;)V
120 | public synthetic fun (IILkotlin/jvm/internal/DefaultConstructorMarker;)V
121 | public fun equals (Ljava/lang/Object;)Z
122 | public final fun getXUnit-kfOZ-k0 ()I
123 | public final fun getYUnit-kfOZ-k0 ()I
124 | public fun hashCode ()I
125 | }
126 |
127 | public final class com/popovanton0/blueprint/dsl/SizeUnits$Companion {
128 | public final fun getDp ()Lcom/popovanton0/blueprint/dsl/SizeUnits;
129 | public final fun getSp ()Lcom/popovanton0/blueprint/dsl/SizeUnits;
130 | }
131 |
132 | public final class com/popovanton0/blueprint/dsl/VerticalGroupScope : com/popovanton0/blueprint/dsl/GroupScope {
133 | public static final field $stable I
134 | public final fun getBottom (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
135 | public final fun getCenter (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
136 | public final fun getTop (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
137 | public final fun lineTo (Ljava/lang/String;Ljava/lang/String;)V
138 | public final fun spLineTo (Ljava/lang/String;Ljava/lang/String;)V
139 | }
140 |
141 | public final class com/popovanton0/blueprint/dsl/VerticalScope {
142 | public static final field $stable I
143 | public final fun group-a3hqG0I (ILkotlin/jvm/functions/Function1;)V
144 | public static synthetic fun group-a3hqG0I$default (Lcom/popovanton0/blueprint/dsl/VerticalScope;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
145 | }
146 |
147 |
--------------------------------------------------------------------------------
/blueprint/api/android/blueprint.api:
--------------------------------------------------------------------------------
1 | public final class com/popovanton0/blueprint/BlueprintIdKt {
2 | public static final fun blueprintId (Landroidx/compose/ui/Modifier;Ljava/lang/String;Lcom/popovanton0/blueprint/dsl/SizeUnits;)Landroidx/compose/ui/Modifier;
3 | public static synthetic fun blueprintId$default (Landroidx/compose/ui/Modifier;Ljava/lang/String;Lcom/popovanton0/blueprint/dsl/SizeUnits;ILjava/lang/Object;)Landroidx/compose/ui/Modifier;
4 | }
5 |
6 | public final class com/popovanton0/blueprint/BlueprintKt {
7 | public static final fun Blueprint-clabC8w (Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/BorderStroke;Landroidx/compose/foundation/BorderStroke;JJLcom/popovanton0/blueprint/dsl/Arrow;IZZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V
8 | public static final fun getBlueprintEnabled ()Z
9 | public static final fun setBlueprintEnabled (Z)V
10 | }
11 |
12 | public abstract interface annotation class com/popovanton0/blueprint/ExperimentalBlueprintApi : java/lang/annotation/Annotation {
13 | }
14 |
15 | public final class com/popovanton0/blueprint/dsl/Anchor {
16 | public static final field $stable I
17 | public fun equals (Ljava/lang/Object;)Z
18 | public fun hashCode ()I
19 | }
20 |
21 | public final class com/popovanton0/blueprint/dsl/Arrow {
22 | public static final field $stable I
23 | public synthetic fun (FFZILkotlin/jvm/internal/DefaultConstructorMarker;)V
24 | public synthetic fun (FFZLkotlin/jvm/internal/DefaultConstructorMarker;)V
25 | public fun equals (Ljava/lang/Object;)Z
26 | public final fun getAngle ()F
27 | public final fun getLength-D9Ej5fM ()F
28 | public final fun getRoundCap ()Z
29 | public fun hashCode ()I
30 | }
31 |
32 | public final class com/popovanton0/blueprint/dsl/BlueprintBuilderScope {
33 | public static final field $stable I
34 | public final fun heights (Lkotlin/jvm/functions/Function1;)V
35 | public final fun widths (Lkotlin/jvm/functions/Function1;)V
36 | }
37 |
38 | public abstract class com/popovanton0/blueprint/dsl/GroupScope {
39 | public static final field $stable I
40 | public final fun lineTo (Lcom/popovanton0/blueprint/dsl/Anchor;Lcom/popovanton0/blueprint/dsl/Anchor;)V
41 | public final fun spLineTo (Lcom/popovanton0/blueprint/dsl/Anchor;Lcom/popovanton0/blueprint/dsl/Anchor;)V
42 | }
43 |
44 | public final class com/popovanton0/blueprint/dsl/HorizontalGroupScope : com/popovanton0/blueprint/dsl/GroupScope {
45 | public static final field $stable I
46 | public final fun getCenter (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
47 | public final fun getLeft (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
48 | public final fun getRight (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
49 | public final fun lineTo (Ljava/lang/String;Ljava/lang/String;)V
50 | public final fun spLineTo (Ljava/lang/String;Ljava/lang/String;)V
51 | }
52 |
53 | public final class com/popovanton0/blueprint/dsl/HorizontalScope {
54 | public static final field $stable I
55 | public final fun group-QjWXQlE (ILkotlin/jvm/functions/Function1;)V
56 | public static synthetic fun group-QjWXQlE$default (Lcom/popovanton0/blueprint/dsl/HorizontalScope;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
57 | }
58 |
59 | public final class com/popovanton0/blueprint/dsl/MeasureUnit {
60 | public static final field Companion Lcom/popovanton0/blueprint/dsl/MeasureUnit$Companion;
61 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/MeasureUnit;
62 | public fun equals (Ljava/lang/Object;)Z
63 | public static fun equals-impl (ILjava/lang/Object;)Z
64 | public static final fun equals-impl0 (II)Z
65 | public fun hashCode ()I
66 | public static fun hashCode-impl (I)I
67 | public fun toString ()Ljava/lang/String;
68 | public static fun toString-impl (I)Ljava/lang/String;
69 | public final synthetic fun unbox-impl ()I
70 | }
71 |
72 | public final class com/popovanton0/blueprint/dsl/MeasureUnit$Companion {
73 | public final fun getDp-kfOZ-k0 ()I
74 | public final fun getSp-kfOZ-k0 ()I
75 | }
76 |
77 | public abstract interface class com/popovanton0/blueprint/dsl/Position {
78 | }
79 |
80 | public final class com/popovanton0/blueprint/dsl/Position$Horizontal : com/popovanton0/blueprint/dsl/Position {
81 | public static final field Companion Lcom/popovanton0/blueprint/dsl/Position$Horizontal$Companion;
82 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/Position$Horizontal;
83 | public fun equals (Ljava/lang/Object;)Z
84 | public static fun equals-impl (ILjava/lang/Object;)Z
85 | public static final fun equals-impl0 (II)Z
86 | public fun hashCode ()I
87 | public static fun hashCode-impl (I)I
88 | public fun toString ()Ljava/lang/String;
89 | public static fun toString-impl (I)Ljava/lang/String;
90 | public final synthetic fun unbox-impl ()I
91 | }
92 |
93 | public final class com/popovanton0/blueprint/dsl/Position$Horizontal$Companion {
94 | public final fun getEnd-o_BGRZA ()I
95 | public final fun getStart-o_BGRZA ()I
96 | }
97 |
98 | public final class com/popovanton0/blueprint/dsl/Position$Vertical : com/popovanton0/blueprint/dsl/Position {
99 | public static final field Companion Lcom/popovanton0/blueprint/dsl/Position$Vertical$Companion;
100 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/Position$Vertical;
101 | public fun equals (Ljava/lang/Object;)Z
102 | public static fun equals-impl (ILjava/lang/Object;)Z
103 | public static final fun equals-impl0 (II)Z
104 | public fun hashCode ()I
105 | public static fun hashCode-impl (I)I
106 | public fun toString ()Ljava/lang/String;
107 | public static fun toString-impl (I)Ljava/lang/String;
108 | public final synthetic fun unbox-impl ()I
109 | }
110 |
111 | public final class com/popovanton0/blueprint/dsl/Position$Vertical$Companion {
112 | public final fun getBottom-6W8Q2GU ()I
113 | public final fun getTop-6W8Q2GU ()I
114 | }
115 |
116 | public final class com/popovanton0/blueprint/dsl/SizeUnits {
117 | public static final field $stable I
118 | public static final field Companion Lcom/popovanton0/blueprint/dsl/SizeUnits$Companion;
119 | public synthetic fun (IIILkotlin/jvm/internal/DefaultConstructorMarker;)V
120 | public synthetic fun (IILkotlin/jvm/internal/DefaultConstructorMarker;)V
121 | public fun equals (Ljava/lang/Object;)Z
122 | public final fun getXUnit-kfOZ-k0 ()I
123 | public final fun getYUnit-kfOZ-k0 ()I
124 | public fun hashCode ()I
125 | }
126 |
127 | public final class com/popovanton0/blueprint/dsl/SizeUnits$Companion {
128 | public final fun getDp ()Lcom/popovanton0/blueprint/dsl/SizeUnits;
129 | public final fun getSp ()Lcom/popovanton0/blueprint/dsl/SizeUnits;
130 | }
131 |
132 | public final class com/popovanton0/blueprint/dsl/VerticalGroupScope : com/popovanton0/blueprint/dsl/GroupScope {
133 | public static final field $stable I
134 | public final fun getBottom (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
135 | public final fun getCenter (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
136 | public final fun getTop (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
137 | public final fun lineTo (Ljava/lang/String;Ljava/lang/String;)V
138 | public final fun spLineTo (Ljava/lang/String;Ljava/lang/String;)V
139 | }
140 |
141 | public final class com/popovanton0/blueprint/dsl/VerticalScope {
142 | public static final field $stable I
143 | public final fun group-a3hqG0I (ILkotlin/jvm/functions/Function1;)V
144 | public static synthetic fun group-a3hqG0I$default (Lcom/popovanton0/blueprint/dsl/VerticalScope;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
145 | }
146 |
147 |
--------------------------------------------------------------------------------
/blueprint/api/desktop/blueprint.api:
--------------------------------------------------------------------------------
1 | public final class com/popovanton0/blueprint/BlueprintIdKt {
2 | public static final fun blueprintId (Landroidx/compose/ui/Modifier;Ljava/lang/String;Lcom/popovanton0/blueprint/dsl/SizeUnits;)Landroidx/compose/ui/Modifier;
3 | public static synthetic fun blueprintId$default (Landroidx/compose/ui/Modifier;Ljava/lang/String;Lcom/popovanton0/blueprint/dsl/SizeUnits;ILjava/lang/Object;)Landroidx/compose/ui/Modifier;
4 | }
5 |
6 | public final class com/popovanton0/blueprint/BlueprintKt {
7 | public static final fun Blueprint-clabC8w (Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/BorderStroke;Landroidx/compose/foundation/BorderStroke;JJLcom/popovanton0/blueprint/dsl/Arrow;IZZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V
8 | public static final fun getBlueprintEnabled ()Z
9 | public static final fun setBlueprintEnabled (Z)V
10 | }
11 |
12 | public abstract interface annotation class com/popovanton0/blueprint/ExperimentalBlueprintApi : java/lang/annotation/Annotation {
13 | }
14 |
15 | public final class com/popovanton0/blueprint/dsl/Anchor {
16 | public static final field $stable I
17 | public fun equals (Ljava/lang/Object;)Z
18 | public fun hashCode ()I
19 | }
20 |
21 | public final class com/popovanton0/blueprint/dsl/Arrow {
22 | public static final field $stable I
23 | public synthetic fun (FFZILkotlin/jvm/internal/DefaultConstructorMarker;)V
24 | public synthetic fun (FFZLkotlin/jvm/internal/DefaultConstructorMarker;)V
25 | public fun equals (Ljava/lang/Object;)Z
26 | public final fun getAngle ()F
27 | public final fun getLength-D9Ej5fM ()F
28 | public final fun getRoundCap ()Z
29 | public fun hashCode ()I
30 | }
31 |
32 | public final class com/popovanton0/blueprint/dsl/BlueprintBuilderScope {
33 | public static final field $stable I
34 | public final fun heights (Lkotlin/jvm/functions/Function1;)V
35 | public final fun widths (Lkotlin/jvm/functions/Function1;)V
36 | }
37 |
38 | public abstract class com/popovanton0/blueprint/dsl/GroupScope {
39 | public static final field $stable I
40 | public final fun lineTo (Lcom/popovanton0/blueprint/dsl/Anchor;Lcom/popovanton0/blueprint/dsl/Anchor;)V
41 | public final fun spLineTo (Lcom/popovanton0/blueprint/dsl/Anchor;Lcom/popovanton0/blueprint/dsl/Anchor;)V
42 | }
43 |
44 | public final class com/popovanton0/blueprint/dsl/HorizontalGroupScope : com/popovanton0/blueprint/dsl/GroupScope {
45 | public static final field $stable I
46 | public final fun getCenter (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
47 | public final fun getLeft (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
48 | public final fun getRight (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
49 | public final fun lineTo (Ljava/lang/String;Ljava/lang/String;)V
50 | public final fun spLineTo (Ljava/lang/String;Ljava/lang/String;)V
51 | }
52 |
53 | public final class com/popovanton0/blueprint/dsl/HorizontalScope {
54 | public static final field $stable I
55 | public final fun group-QjWXQlE (ILkotlin/jvm/functions/Function1;)V
56 | public static synthetic fun group-QjWXQlE$default (Lcom/popovanton0/blueprint/dsl/HorizontalScope;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
57 | }
58 |
59 | public final class com/popovanton0/blueprint/dsl/MeasureUnit {
60 | public static final field Companion Lcom/popovanton0/blueprint/dsl/MeasureUnit$Companion;
61 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/MeasureUnit;
62 | public fun equals (Ljava/lang/Object;)Z
63 | public static fun equals-impl (ILjava/lang/Object;)Z
64 | public static final fun equals-impl0 (II)Z
65 | public fun hashCode ()I
66 | public static fun hashCode-impl (I)I
67 | public fun toString ()Ljava/lang/String;
68 | public static fun toString-impl (I)Ljava/lang/String;
69 | public final synthetic fun unbox-impl ()I
70 | }
71 |
72 | public final class com/popovanton0/blueprint/dsl/MeasureUnit$Companion {
73 | public final fun getDp-kfOZ-k0 ()I
74 | public final fun getSp-kfOZ-k0 ()I
75 | }
76 |
77 | public abstract interface class com/popovanton0/blueprint/dsl/Position {
78 | }
79 |
80 | public final class com/popovanton0/blueprint/dsl/Position$Horizontal : com/popovanton0/blueprint/dsl/Position {
81 | public static final field Companion Lcom/popovanton0/blueprint/dsl/Position$Horizontal$Companion;
82 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/Position$Horizontal;
83 | public fun equals (Ljava/lang/Object;)Z
84 | public static fun equals-impl (ILjava/lang/Object;)Z
85 | public static final fun equals-impl0 (II)Z
86 | public fun hashCode ()I
87 | public static fun hashCode-impl (I)I
88 | public fun toString ()Ljava/lang/String;
89 | public static fun toString-impl (I)Ljava/lang/String;
90 | public final synthetic fun unbox-impl ()I
91 | }
92 |
93 | public final class com/popovanton0/blueprint/dsl/Position$Horizontal$Companion {
94 | public final fun getEnd-o_BGRZA ()I
95 | public final fun getStart-o_BGRZA ()I
96 | }
97 |
98 | public final class com/popovanton0/blueprint/dsl/Position$Vertical : com/popovanton0/blueprint/dsl/Position {
99 | public static final field Companion Lcom/popovanton0/blueprint/dsl/Position$Vertical$Companion;
100 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/Position$Vertical;
101 | public fun equals (Ljava/lang/Object;)Z
102 | public static fun equals-impl (ILjava/lang/Object;)Z
103 | public static final fun equals-impl0 (II)Z
104 | public fun hashCode ()I
105 | public static fun hashCode-impl (I)I
106 | public fun toString ()Ljava/lang/String;
107 | public static fun toString-impl (I)Ljava/lang/String;
108 | public final synthetic fun unbox-impl ()I
109 | }
110 |
111 | public final class com/popovanton0/blueprint/dsl/Position$Vertical$Companion {
112 | public final fun getBottom-6W8Q2GU ()I
113 | public final fun getTop-6W8Q2GU ()I
114 | }
115 |
116 | public final class com/popovanton0/blueprint/dsl/SizeUnits {
117 | public static final field $stable I
118 | public static final field Companion Lcom/popovanton0/blueprint/dsl/SizeUnits$Companion;
119 | public synthetic fun (IIILkotlin/jvm/internal/DefaultConstructorMarker;)V
120 | public synthetic fun (IILkotlin/jvm/internal/DefaultConstructorMarker;)V
121 | public fun equals (Ljava/lang/Object;)Z
122 | public final fun getXUnit-kfOZ-k0 ()I
123 | public final fun getYUnit-kfOZ-k0 ()I
124 | public fun hashCode ()I
125 | }
126 |
127 | public final class com/popovanton0/blueprint/dsl/SizeUnits$Companion {
128 | public final fun getDp ()Lcom/popovanton0/blueprint/dsl/SizeUnits;
129 | public final fun getSp ()Lcom/popovanton0/blueprint/dsl/SizeUnits;
130 | }
131 |
132 | public final class com/popovanton0/blueprint/dsl/VerticalGroupScope : com/popovanton0/blueprint/dsl/GroupScope {
133 | public static final field $stable I
134 | public final fun getBottom (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
135 | public final fun getCenter (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
136 | public final fun getTop (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
137 | public final fun lineTo (Ljava/lang/String;Ljava/lang/String;)V
138 | public final fun spLineTo (Ljava/lang/String;Ljava/lang/String;)V
139 | }
140 |
141 | public final class com/popovanton0/blueprint/dsl/VerticalScope {
142 | public static final field $stable I
143 | public final fun group-a3hqG0I (ILkotlin/jvm/functions/Function1;)V
144 | public static synthetic fun group-a3hqG0I$default (Lcom/popovanton0/blueprint/dsl/VerticalScope;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
145 | }
146 |
147 |
--------------------------------------------------------------------------------
/blueprint-no-op/api/android/blueprint-no-op.api:
--------------------------------------------------------------------------------
1 | public final class com/popovanton0/blueprint/BlueprintIdKt {
2 | public static final fun blueprintId (Landroidx/compose/ui/Modifier;Ljava/lang/String;Lcom/popovanton0/blueprint/dsl/SizeUnits;)Landroidx/compose/ui/Modifier;
3 | public static synthetic fun blueprintId$default (Landroidx/compose/ui/Modifier;Ljava/lang/String;Lcom/popovanton0/blueprint/dsl/SizeUnits;ILjava/lang/Object;)Landroidx/compose/ui/Modifier;
4 | }
5 |
6 | public final class com/popovanton0/blueprint/BlueprintKt {
7 | public static final fun Blueprint-clabC8w (Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/BorderStroke;Landroidx/compose/foundation/BorderStroke;JJLcom/popovanton0/blueprint/dsl/Arrow;IZZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V
8 | public static final fun getBlueprintEnabled ()Z
9 | public static final fun setBlueprintEnabled (Z)V
10 | }
11 |
12 | public abstract interface annotation class com/popovanton0/blueprint/ExperimentalBlueprintApi : java/lang/annotation/Annotation {
13 | }
14 |
15 | public final class com/popovanton0/blueprint/dsl/Anchor {
16 | public static final field $stable I
17 | public fun equals (Ljava/lang/Object;)Z
18 | public fun hashCode ()I
19 | }
20 |
21 | public final class com/popovanton0/blueprint/dsl/Arrow {
22 | public static final field $stable I
23 | public synthetic fun (FFZILkotlin/jvm/internal/DefaultConstructorMarker;)V
24 | public synthetic fun (FFZLkotlin/jvm/internal/DefaultConstructorMarker;)V
25 | public fun equals (Ljava/lang/Object;)Z
26 | public final fun getAngle ()F
27 | public final fun getLength-D9Ej5fM ()F
28 | public final fun getRoundCap ()Z
29 | public fun hashCode ()I
30 | }
31 |
32 | public final class com/popovanton0/blueprint/dsl/BlueprintBuilderScope {
33 | public static final field $stable I
34 | public final fun heights (Lkotlin/jvm/functions/Function1;)V
35 | public final fun widths (Lkotlin/jvm/functions/Function1;)V
36 | }
37 |
38 | public abstract class com/popovanton0/blueprint/dsl/GroupScope {
39 | public static final field $stable I
40 | public final fun lineTo (Lcom/popovanton0/blueprint/dsl/Anchor;Lcom/popovanton0/blueprint/dsl/Anchor;)V
41 | public final fun spLineTo (Lcom/popovanton0/blueprint/dsl/Anchor;Lcom/popovanton0/blueprint/dsl/Anchor;)V
42 | }
43 |
44 | public final class com/popovanton0/blueprint/dsl/HorizontalGroupScope : com/popovanton0/blueprint/dsl/GroupScope {
45 | public static final field $stable I
46 | public final fun getCenter (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
47 | public final fun getLeft (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
48 | public final fun getRight (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
49 | public final fun lineTo (Ljava/lang/String;Ljava/lang/String;)V
50 | public final fun spLineTo (Ljava/lang/String;Ljava/lang/String;)V
51 | }
52 |
53 | public final class com/popovanton0/blueprint/dsl/HorizontalScope {
54 | public static final field $stable I
55 | public final fun group-QjWXQlE (ILkotlin/jvm/functions/Function1;)V
56 | public static synthetic fun group-QjWXQlE$default (Lcom/popovanton0/blueprint/dsl/HorizontalScope;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
57 | }
58 |
59 | public final class com/popovanton0/blueprint/dsl/MeasureUnit {
60 | public static final field Companion Lcom/popovanton0/blueprint/dsl/MeasureUnit$Companion;
61 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/MeasureUnit;
62 | public fun equals (Ljava/lang/Object;)Z
63 | public static fun equals-impl (ILjava/lang/Object;)Z
64 | public static final fun equals-impl0 (II)Z
65 | public fun hashCode ()I
66 | public static fun hashCode-impl (I)I
67 | public fun toString ()Ljava/lang/String;
68 | public static fun toString-impl (I)Ljava/lang/String;
69 | public final synthetic fun unbox-impl ()I
70 | }
71 |
72 | public final class com/popovanton0/blueprint/dsl/MeasureUnit$Companion {
73 | public final fun getDp-kfOZ-k0 ()I
74 | public final fun getSp-kfOZ-k0 ()I
75 | }
76 |
77 | public abstract interface class com/popovanton0/blueprint/dsl/Position {
78 | }
79 |
80 | public final class com/popovanton0/blueprint/dsl/Position$Horizontal : com/popovanton0/blueprint/dsl/Position {
81 | public static final field Companion Lcom/popovanton0/blueprint/dsl/Position$Horizontal$Companion;
82 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/Position$Horizontal;
83 | public fun equals (Ljava/lang/Object;)Z
84 | public static fun equals-impl (ILjava/lang/Object;)Z
85 | public static final fun equals-impl0 (II)Z
86 | public fun hashCode ()I
87 | public static fun hashCode-impl (I)I
88 | public fun toString ()Ljava/lang/String;
89 | public static fun toString-impl (I)Ljava/lang/String;
90 | public final synthetic fun unbox-impl ()I
91 | }
92 |
93 | public final class com/popovanton0/blueprint/dsl/Position$Horizontal$Companion {
94 | public final fun getEnd-o_BGRZA ()I
95 | public final fun getStart-o_BGRZA ()I
96 | }
97 |
98 | public final class com/popovanton0/blueprint/dsl/Position$Vertical : com/popovanton0/blueprint/dsl/Position {
99 | public static final field Companion Lcom/popovanton0/blueprint/dsl/Position$Vertical$Companion;
100 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/Position$Vertical;
101 | public fun equals (Ljava/lang/Object;)Z
102 | public static fun equals-impl (ILjava/lang/Object;)Z
103 | public static final fun equals-impl0 (II)Z
104 | public fun hashCode ()I
105 | public static fun hashCode-impl (I)I
106 | public fun toString ()Ljava/lang/String;
107 | public static fun toString-impl (I)Ljava/lang/String;
108 | public final synthetic fun unbox-impl ()I
109 | }
110 |
111 | public final class com/popovanton0/blueprint/dsl/Position$Vertical$Companion {
112 | public final fun getBottom-6W8Q2GU ()I
113 | public final fun getTop-6W8Q2GU ()I
114 | }
115 |
116 | public final class com/popovanton0/blueprint/dsl/SizeUnits {
117 | public static final field $stable I
118 | public static final field Companion Lcom/popovanton0/blueprint/dsl/SizeUnits$Companion;
119 | public synthetic fun (IIILkotlin/jvm/internal/DefaultConstructorMarker;)V
120 | public synthetic fun (IILkotlin/jvm/internal/DefaultConstructorMarker;)V
121 | public fun equals (Ljava/lang/Object;)Z
122 | public final fun getXUnit-kfOZ-k0 ()I
123 | public final fun getYUnit-kfOZ-k0 ()I
124 | public fun hashCode ()I
125 | }
126 |
127 | public final class com/popovanton0/blueprint/dsl/SizeUnits$Companion {
128 | public final fun getDp ()Lcom/popovanton0/blueprint/dsl/SizeUnits;
129 | public final fun getSp ()Lcom/popovanton0/blueprint/dsl/SizeUnits;
130 | }
131 |
132 | public final class com/popovanton0/blueprint/dsl/VerticalGroupScope : com/popovanton0/blueprint/dsl/GroupScope {
133 | public static final field $stable I
134 | public final fun getBottom (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
135 | public final fun getCenter (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
136 | public final fun getTop (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
137 | public final fun lineTo (Ljava/lang/String;Ljava/lang/String;)V
138 | public final fun spLineTo (Ljava/lang/String;Ljava/lang/String;)V
139 | }
140 |
141 | public final class com/popovanton0/blueprint/dsl/VerticalScope {
142 | public static final field $stable I
143 | public final fun group-a3hqG0I (ILkotlin/jvm/functions/Function1;)V
144 | public static synthetic fun group-a3hqG0I$default (Lcom/popovanton0/blueprint/dsl/VerticalScope;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
145 | }
146 |
147 |
--------------------------------------------------------------------------------
/blueprint-no-op/api/desktop/blueprint-no-op.api:
--------------------------------------------------------------------------------
1 | public final class com/popovanton0/blueprint/BlueprintIdKt {
2 | public static final fun blueprintId (Landroidx/compose/ui/Modifier;Ljava/lang/String;Lcom/popovanton0/blueprint/dsl/SizeUnits;)Landroidx/compose/ui/Modifier;
3 | public static synthetic fun blueprintId$default (Landroidx/compose/ui/Modifier;Ljava/lang/String;Lcom/popovanton0/blueprint/dsl/SizeUnits;ILjava/lang/Object;)Landroidx/compose/ui/Modifier;
4 | }
5 |
6 | public final class com/popovanton0/blueprint/BlueprintKt {
7 | public static final fun Blueprint-clabC8w (Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/BorderStroke;Landroidx/compose/foundation/BorderStroke;JJLcom/popovanton0/blueprint/dsl/Arrow;IZZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V
8 | public static final fun getBlueprintEnabled ()Z
9 | public static final fun setBlueprintEnabled (Z)V
10 | }
11 |
12 | public abstract interface annotation class com/popovanton0/blueprint/ExperimentalBlueprintApi : java/lang/annotation/Annotation {
13 | }
14 |
15 | public final class com/popovanton0/blueprint/dsl/Anchor {
16 | public static final field $stable I
17 | public fun equals (Ljava/lang/Object;)Z
18 | public fun hashCode ()I
19 | }
20 |
21 | public final class com/popovanton0/blueprint/dsl/Arrow {
22 | public static final field $stable I
23 | public synthetic fun (FFZILkotlin/jvm/internal/DefaultConstructorMarker;)V
24 | public synthetic fun (FFZLkotlin/jvm/internal/DefaultConstructorMarker;)V
25 | public fun equals (Ljava/lang/Object;)Z
26 | public final fun getAngle ()F
27 | public final fun getLength-D9Ej5fM ()F
28 | public final fun getRoundCap ()Z
29 | public fun hashCode ()I
30 | }
31 |
32 | public final class com/popovanton0/blueprint/dsl/BlueprintBuilderScope {
33 | public static final field $stable I
34 | public final fun heights (Lkotlin/jvm/functions/Function1;)V
35 | public final fun widths (Lkotlin/jvm/functions/Function1;)V
36 | }
37 |
38 | public abstract class com/popovanton0/blueprint/dsl/GroupScope {
39 | public static final field $stable I
40 | public final fun lineTo (Lcom/popovanton0/blueprint/dsl/Anchor;Lcom/popovanton0/blueprint/dsl/Anchor;)V
41 | public final fun spLineTo (Lcom/popovanton0/blueprint/dsl/Anchor;Lcom/popovanton0/blueprint/dsl/Anchor;)V
42 | }
43 |
44 | public final class com/popovanton0/blueprint/dsl/HorizontalGroupScope : com/popovanton0/blueprint/dsl/GroupScope {
45 | public static final field $stable I
46 | public final fun getCenter (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
47 | public final fun getLeft (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
48 | public final fun getRight (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
49 | public final fun lineTo (Ljava/lang/String;Ljava/lang/String;)V
50 | public final fun spLineTo (Ljava/lang/String;Ljava/lang/String;)V
51 | }
52 |
53 | public final class com/popovanton0/blueprint/dsl/HorizontalScope {
54 | public static final field $stable I
55 | public final fun group-QjWXQlE (ILkotlin/jvm/functions/Function1;)V
56 | public static synthetic fun group-QjWXQlE$default (Lcom/popovanton0/blueprint/dsl/HorizontalScope;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
57 | }
58 |
59 | public final class com/popovanton0/blueprint/dsl/MeasureUnit {
60 | public static final field Companion Lcom/popovanton0/blueprint/dsl/MeasureUnit$Companion;
61 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/MeasureUnit;
62 | public fun equals (Ljava/lang/Object;)Z
63 | public static fun equals-impl (ILjava/lang/Object;)Z
64 | public static final fun equals-impl0 (II)Z
65 | public fun hashCode ()I
66 | public static fun hashCode-impl (I)I
67 | public fun toString ()Ljava/lang/String;
68 | public static fun toString-impl (I)Ljava/lang/String;
69 | public final synthetic fun unbox-impl ()I
70 | }
71 |
72 | public final class com/popovanton0/blueprint/dsl/MeasureUnit$Companion {
73 | public final fun getDp-kfOZ-k0 ()I
74 | public final fun getSp-kfOZ-k0 ()I
75 | }
76 |
77 | public abstract interface class com/popovanton0/blueprint/dsl/Position {
78 | }
79 |
80 | public final class com/popovanton0/blueprint/dsl/Position$Horizontal : com/popovanton0/blueprint/dsl/Position {
81 | public static final field Companion Lcom/popovanton0/blueprint/dsl/Position$Horizontal$Companion;
82 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/Position$Horizontal;
83 | public fun equals (Ljava/lang/Object;)Z
84 | public static fun equals-impl (ILjava/lang/Object;)Z
85 | public static final fun equals-impl0 (II)Z
86 | public fun hashCode ()I
87 | public static fun hashCode-impl (I)I
88 | public fun toString ()Ljava/lang/String;
89 | public static fun toString-impl (I)Ljava/lang/String;
90 | public final synthetic fun unbox-impl ()I
91 | }
92 |
93 | public final class com/popovanton0/blueprint/dsl/Position$Horizontal$Companion {
94 | public final fun getEnd-o_BGRZA ()I
95 | public final fun getStart-o_BGRZA ()I
96 | }
97 |
98 | public final class com/popovanton0/blueprint/dsl/Position$Vertical : com/popovanton0/blueprint/dsl/Position {
99 | public static final field Companion Lcom/popovanton0/blueprint/dsl/Position$Vertical$Companion;
100 | public static final synthetic fun box-impl (I)Lcom/popovanton0/blueprint/dsl/Position$Vertical;
101 | public fun equals (Ljava/lang/Object;)Z
102 | public static fun equals-impl (ILjava/lang/Object;)Z
103 | public static final fun equals-impl0 (II)Z
104 | public fun hashCode ()I
105 | public static fun hashCode-impl (I)I
106 | public fun toString ()Ljava/lang/String;
107 | public static fun toString-impl (I)Ljava/lang/String;
108 | public final synthetic fun unbox-impl ()I
109 | }
110 |
111 | public final class com/popovanton0/blueprint/dsl/Position$Vertical$Companion {
112 | public final fun getBottom-6W8Q2GU ()I
113 | public final fun getTop-6W8Q2GU ()I
114 | }
115 |
116 | public final class com/popovanton0/blueprint/dsl/SizeUnits {
117 | public static final field $stable I
118 | public static final field Companion Lcom/popovanton0/blueprint/dsl/SizeUnits$Companion;
119 | public synthetic fun (IIILkotlin/jvm/internal/DefaultConstructorMarker;)V
120 | public synthetic fun (IILkotlin/jvm/internal/DefaultConstructorMarker;)V
121 | public fun equals (Ljava/lang/Object;)Z
122 | public final fun getXUnit-kfOZ-k0 ()I
123 | public final fun getYUnit-kfOZ-k0 ()I
124 | public fun hashCode ()I
125 | }
126 |
127 | public final class com/popovanton0/blueprint/dsl/SizeUnits$Companion {
128 | public final fun getDp ()Lcom/popovanton0/blueprint/dsl/SizeUnits;
129 | public final fun getSp ()Lcom/popovanton0/blueprint/dsl/SizeUnits;
130 | }
131 |
132 | public final class com/popovanton0/blueprint/dsl/VerticalGroupScope : com/popovanton0/blueprint/dsl/GroupScope {
133 | public static final field $stable I
134 | public final fun getBottom (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
135 | public final fun getCenter (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
136 | public final fun getTop (Ljava/lang/String;)Lcom/popovanton0/blueprint/dsl/Anchor;
137 | public final fun lineTo (Ljava/lang/String;Ljava/lang/String;)V
138 | public final fun spLineTo (Ljava/lang/String;Ljava/lang/String;)V
139 | }
140 |
141 | public final class com/popovanton0/blueprint/dsl/VerticalScope {
142 | public static final field $stable I
143 | public final fun group-a3hqG0I (ILkotlin/jvm/functions/Function1;)V
144 | public static synthetic fun group-a3hqG0I$default (Lcom/popovanton0/blueprint/dsl/VerticalScope;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
145 | }
146 |
147 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 📐 Blueprint
2 |
3 | [](https://jitpack.io/#popovanton0/blueprint)
4 | [](https://proandroiddev.com/blueprint-visualizing-paddings-in-jetpack-compose-eb62413c6d74)
5 | 
6 |
7 | Visualize the dimensions of your composables on a blueprint
8 |
9 | 
10 | 
11 |
12 | [Introductory Medium Article](https://proandroiddev.com/blueprint-visualizing-paddings-in-jetpack-compose-eb62413c6d74)
13 |
14 | ## The Problem
15 |
16 | Have you ever desired to see, what *exactly* is that padding's value while looking at the composable
17 | preview window? Especially when you are developing a button with 5 color styles, 3 sizes, and 2
18 | optional icons; and each combination of these parameters has different paddings?
19 |
20 | Combinatorial explosion of UI components in design systems requires having a lot of context about
21 | paddings, dp's, sizes, corner radiuses, and other dimensional information in your head at the
22 | same time.
23 |
24 | 
25 | 
26 |
27 | In addition, code to produce those combinations can get tricky to analyze. So, verification also
28 | becomes hard: you make screenshots, move them to Figma, overlay them on top, and try to see the
29 | difference. Tedious 😩!
30 |
31 | ## The Solution
32 |
33 | The Blueprint library provides a way to visualize dimensional information in your UI using a simple
34 | DSL-based definition:
35 |
36 | 1. Just wrap your target UI in a `Blueprint` composable
37 | 2. Mark children
38 | with [`Modifier.blueprintId(id: String)`](https://github.com/popovanton0/Blueprint/blob/main/blueprint/src/main/java/com/popovanton0/blueprint/BlueprintId.kt)
39 | modifier
40 | 3. Write the blueprint definition
41 |
42 | ```kotlin
43 | Blueprint(
44 | blueprintBuilder = {
45 | widths {
46 | group {
47 | "item0".right lineTo "item1".left
48 | "item0" lineTo "item0"
49 | "item2" lineTo "item3"
50 | }
51 | }
52 | heights {
53 | group { "item0Icon" lineTo "item0Text" }
54 | group { "item0" lineTo "item0" }
55 | group(End) { "item3Icon".bottom lineTo "item3Text".top }
56 | }
57 | }
58 | ) {
59 | val items = remember { listOf("Songs", "Artists", "Playlists", "Settings") }
60 | NavigationBar {
61 | items.forEachIndexed { index, item ->
62 | NavigationBarItem(
63 | modifier = Modifier.blueprintId("item$index"),
64 | icon = { Icon(Modifier.blueprintId("item${index}Icon"), TODO()) },
65 | label = { Text(Modifier.blueprintId("item${index}Text"), TODO()) },
66 | selected = index == 0,
67 | onClick = { TODO() }
68 | )
69 | }
70 | }
71 | }
72 | ```
73 |
74 | ### Preview
75 |
76 | 
77 | 
78 |
79 | ### And another example:
80 |
81 | 
82 | 
83 |
84 | ### Correct arrow padding rendering animation
85 |
86 | https://github.com/popovanton0/Blueprint/assets/15000556/7a90b534-3c7e-437a-8e08-1fdd4329c752
87 |
88 |
89 | Debug
90 |
91 | https://github.com/popovanton0/Blueprint/assets/15000556/535a016f-0ca9-41d2-8e52-2ed7b36fbdc0
92 |
93 |
94 |
95 |
96 | More examples
97 |
98 | These are snapshots from snapshot testing:
99 |
100 | | | |
101 | |----------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
102 | |  |  |
103 | |  |  |
104 | |  |  |
105 | |  | .png) |
106 | |  | .png) |
107 | |  |  |
108 | |  |  |
109 | |  |  |
110 | |  | .png) |
111 | |  | .png) |
112 |
113 |
114 |
115 | ## Features
116 |
117 | You can customize
118 |
119 | 1. Line and border strokes (width and color)
120 | 2. Font size and color
121 | 3. Arrow style (length, angle, round or square cap)
122 | 4. Decimal precision of the dimensional values
123 |
124 | Of course, Blueprint works in Android Studio's Preview✨!
125 |
126 | Also, you can disable all the overhead of this library in your release builds by either:
127 |
128 | 1. Disabling blueprint rendering
129 | using [`blueprintEnabled`](https://github.com/popovanton0/Blueprint/blob/main/blueprint/src/main/java/com/popovanton0/blueprint/Blueprint.kt)
130 | property.
131 | 2. Using the `no-op` version of the library:
132 | ```kotlin
133 | dependencies {
134 | debugImplementation("com.github.popovanton0.blueprint:blueprint:1.0.0-alpha05")
135 | releaseImplementation("com.github.popovanton0.blueprint:blueprint-no-op:1.0.0-alpha05")
136 | }
137 | ```
138 |
139 | ## Getting Started
140 |
141 | [](https://jitpack.io/#popovanton0/blueprint)
142 |
143 |
144 | Groovy
145 |
146 | Add the following code to your project's *root* `build.gradle` file:
147 |
148 | ```groovy
149 | repositories {
150 | maven { url "https://jitpack.io" }
151 | }
152 | ```
153 |
154 | Next, add the dependency below to your _module_'s `build.gradle` file:
155 |
156 | ```gradle
157 | dependencies {
158 | implementation "com.github.popovanton0.blueprint:blueprint:1.0.0-alpha05"
159 | }
160 | ```
161 |
162 |
163 |
164 |
165 | Kotlin
166 |
167 | Add the following code to your project's *root* `settings.gradle.kts` file:
168 |
169 | ```kotlin
170 | dependencyResolutionManagement {
171 | // ...
172 | repositories {
173 | // ...
174 | maven { url = uri("https://jitpack.io") }
175 | }
176 | }
177 | ```
178 |
179 | Next, add the dependency below to your _module_'s `build.gradle.kts` file:
180 |
181 | ```kotlin
182 | dependencies {
183 | implementation("com.github.popovanton0.blueprint:blueprint:1.0.0-alpha05")
184 | }
185 | ```
186 |
187 | Or using Gradle Version Catalog:
188 |
189 | ```toml
190 | [versions]
191 | blueprint = "1.0.0-alpha05"
192 |
193 | [libraries]
194 | blueprint = { module = "com.github.popovanton0.blueprint:blueprint", version.ref = "blueprint" }
195 | ```
196 |
197 |
198 |
199 | > [!WARNING]
200 | > Do not use this dependency notation: `com.github.popovanton0:blueprint:1.0.0-alpha05`.
201 | > It doesn't work!
202 |
203 | ### Licence
204 |
205 | ```
206 | Copyright 2023 Anton Popov
207 |
208 | Licensed under the Apache License, Version 2.0 (the "License");
209 | you may not use this file except in compliance with the License.
210 | You may obtain a copy of the License at
211 |
212 | http://www.apache.org/licenses/LICENSE-2.0
213 |
214 | Unless required by applicable law or agreed to in writing, software
215 | distributed under the License is distributed on an "AS IS" BASIS,
216 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
217 | See the License for the specific language governing permissions and
218 | limitations under the License.
219 | ```
--------------------------------------------------------------------------------
/blueprint/src/androidUnitTest/kotlin/com/popovanton0/blueprint/BlueprintScreenshotTest.kt:
--------------------------------------------------------------------------------
1 | package com.popovanton0.blueprint
2 |
3 | import androidx.compose.foundation.BorderStroke
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.border
6 | import androidx.compose.foundation.layout.Box
7 | import androidx.compose.foundation.layout.Column
8 | import androidx.compose.foundation.layout.Row
9 | import androidx.compose.foundation.layout.fillMaxSize
10 | import androidx.compose.foundation.layout.fillMaxWidth
11 | import androidx.compose.foundation.layout.padding
12 | import androidx.compose.foundation.layout.requiredSize
13 | import androidx.compose.foundation.layout.size
14 | import androidx.compose.material.icons.Icons
15 | import androidx.compose.material.icons.filled.Home
16 | import androidx.compose.material3.Button
17 | import androidx.compose.material3.Icon
18 | import androidx.compose.material3.MaterialTheme
19 | import androidx.compose.material3.Surface
20 | import androidx.compose.material3.Text
21 | import androidx.compose.runtime.Composable
22 | import androidx.compose.runtime.getValue
23 | import androidx.compose.runtime.mutableStateOf
24 | import androidx.compose.runtime.setValue
25 | import androidx.compose.ui.Alignment
26 | import androidx.compose.ui.BiasAlignment
27 | import androidx.compose.ui.Modifier
28 | import androidx.compose.ui.graphics.Color
29 | import androidx.compose.ui.graphics.vector.rememberVectorPainter
30 | import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
31 | import androidx.compose.ui.unit.Dp
32 | import androidx.compose.ui.unit.dp
33 | import androidx.compose.ui.unit.sp
34 | import app.cash.paparazzi.DeviceConfig.Companion.PIXEL_5
35 | import app.cash.paparazzi.Paparazzi
36 | import com.android.resources.Density
37 | import com.google.testing.junit.testparameterinjector.TestParameter
38 | import com.google.testing.junit.testparameterinjector.TestParameterInjector
39 | import com.popovanton0.blueprint.dsl.Arrow
40 | import com.popovanton0.blueprint.dsl.Position.Horizontal.Companion.End
41 | import com.popovanton0.blueprint.dsl.Position.Horizontal.Companion.Start
42 | import com.popovanton0.blueprint.dsl.Position.Vertical.Companion.Bottom
43 | import com.popovanton0.blueprint.dsl.Position.Vertical.Companion.Top
44 | import com.popovanton0.blueprint.dsl.SizeUnits
45 | import org.junit.Rule
46 | import org.junit.Test
47 | import org.junit.runner.RunWith
48 | import kotlin.math.roundToInt
49 |
50 | @RunWith(TestParameterInjector::class)
51 | internal class BlueprintScreenshotTest {
52 | @get:Rule
53 | val paparazzi = Paparazzi(
54 | deviceConfig = PIXEL_5.copy(
55 | screenWidth = 1800,
56 | screenHeight = 1800,
57 | density = Density.XXXHIGH,
58 | softButtons = false,
59 | ),
60 | )
61 |
62 | @Test
63 | fun basicTest() = paparazzi.snapshotWrapper {
64 | Blueprint(blueprintBuilder = {
65 | widths {
66 | group {
67 | "icon" lineTo "icon"
68 | "text" lineTo "text"
69 | }
70 | group { "icon" lineTo "text" }
71 | group(Top) { "icon".center lineTo "text".center }
72 | group(Top) { "icon".center lineTo "text".center }
73 | }
74 | heights {
75 | group { "icon" lineTo "icon" }
76 | group { "icon" lineTo "icon" }
77 | group(End) { "text" lineTo "text" }
78 | group(End) { "text" lineTo "text" }
79 | }
80 | }) {
81 | TestButton()
82 | }
83 | }
84 |
85 | @Test
86 | fun customFontSizeAndColor() = paparazzi.snapshotWrapper {
87 | Blueprint(blueprintBuilder = {
88 | widths {
89 | group {
90 | "icon" lineTo "icon"
91 | "text" lineTo "text"
92 | }
93 | group { "icon" lineTo "text" }
94 | group(Top) { "icon".center lineTo "text".center }
95 | group(Top) { "icon".center lineTo "text".center }
96 | }
97 | heights {
98 | group { "icon" lineTo "icon" }
99 | group { "icon" lineTo "icon" }
100 | group(End) { "text" lineTo "text" }
101 | group(End) { "text" lineTo "text" }
102 | }
103 | }, fontSize = 14.sp, fontColor = Color.Blue) {
104 | TestButton()
105 | }
106 | }
107 |
108 | @Test
109 | fun emptyBlueprint() = paparazzi.snapshotWrapper {
110 | Blueprint(blueprintBuilder = {}) {
111 | TestButton()
112 | }
113 | }
114 |
115 | @Test
116 | fun when_blueprint_is_disabled_it_is_not_shown() = paparazzi.snapshotWrapper {
117 | Blueprint(
118 | enabled = false,
119 | blueprintBuilder = { widths { group(Top) { "icon" lineTo "icon" } } },
120 | content = { TestButton() }
121 | )
122 | }
123 |
124 | @Test
125 | fun when_specifying_blueprint_ids_that_are_not_referenced_in_the_composable_no_dimensions_are_shown() =
126 | paparazzi.snapshotWrapper {
127 | Blueprint(blueprintBuilder = { widths { group { "lorem1" lineTo "lorem2" } } }) {
128 | TestButton()
129 | }
130 | }
131 |
132 | @Test
133 | fun correct_line_widths_and_alignments() = paparazzi.snapshotWrapper {
134 | Blueprint(
135 | lineStroke = BorderStroke(3.dp, Color.Red),
136 | blueprintBuilder = {
137 | widths {
138 | group { "2".right lineTo "3".left }
139 | group { "2".center lineTo "3".center }
140 | group { "2".center lineTo "3".left }
141 | group { "2".left lineTo "3".center }
142 | group { "2".center lineTo "3".right }
143 | group { "2" lineTo "3" }
144 |
145 | group(Top) {
146 | "1".left lineTo "1".center
147 | "1".right lineTo "3".left
148 | "3".center lineTo "3".right
149 | }
150 | group(Top) { "1".center lineTo "3".left }
151 | group(Top) { "1".left lineTo "3".left }
152 | group(Top) { "1".center lineTo "3".center }
153 | group(Top) { "1" lineTo "3" }
154 | }
155 | heights {
156 | group {
157 | "1".top lineTo "1".center
158 | "1".center lineTo "1".bottom
159 | "1".bottom lineTo "2".top
160 | "2".top lineTo "2".center
161 | }
162 | group { "1".center lineTo "2".center }
163 | group { "1" lineTo "1" }
164 |
165 | group(End) { "1".bottom lineTo "3".bottom }
166 | }
167 | }
168 | ) {
169 | TestUI()
170 | }
171 | }
172 |
173 | @Suppress("JUnitMalformedDeclaration")
174 | @Test
175 | fun arrow_customization(
176 | @TestParameter("0", "15", "45", "90") angle: Float,
177 | ) {
178 | paparazzi.snapshotWrapper {
179 | Blueprint(
180 | lineStroke = BorderStroke(6.dp, Color.Red),
181 | arrow = Arrow(length = 6.dp * 3, angle = angle, roundCap = true),
182 | blueprintBuilder = {
183 | widths {
184 | group(Top) { "1" lineTo "3" }
185 | group(Bottom) { "1" lineTo "3" }
186 | }
187 | heights {
188 | group(Start) { "1".bottom lineTo "3".bottom }
189 | group(End) { "1".bottom lineTo "3".bottom }
190 | }
191 | },
192 | content = { TestUI() }
193 | )
194 | }
195 | }
196 |
197 | @Test
198 | fun not_enough_space_to_draw() = paparazzi.snapshotWrapper {
199 | Box(
200 | modifier = Modifier
201 | .requiredSize(50.dp)
202 | .border(1.dp, Color.Magenta)
203 | ) {
204 | Blueprint(blueprintBuilder = {
205 | widths { group(Top) { "1" lineTo "3" } }
206 | heights { group { "1".bottom lineTo "3".bottom } }
207 | }, content = { TestUI() })
208 | }
209 | }
210 |
211 | @Test
212 | fun almost_none_space_to_draw() = paparazzi.snapshotWrapper {
213 | Box(
214 | modifier = Modifier
215 | .requiredSize(10.dp)
216 | .border(1.dp, Color.Magenta)
217 | ) {
218 | Blueprint(blueprintBuilder = {
219 | widths {
220 | group(Top) { "1" lineTo "3" }
221 | group { "2" lineTo "3" }
222 | }
223 | heights { group { "1".bottom lineTo "3".bottom } }
224 | }, content = { TestUI() })
225 | }
226 | }
227 |
228 | @Test
229 | fun fractional_dp_values_rendering() = paparazzi.snapshotWrapper {
230 | Blueprint(blueprintBuilder = {
231 | widths { group { "1" lineTo "1" } }
232 | heights { group { "1" lineTo "1" } }
233 | }, precision = 3) {
234 | Box(
235 | modifier = Modifier
236 | .size(41.5.dp, 29.5.dp)
237 | .background(Color.Green)
238 | .blueprintId("1")
239 | )
240 | }
241 | }
242 |
243 | @Composable
244 | private fun LoremText(modifier: Modifier = Modifier, words: Int = 10) =
245 | Text(
246 | modifier = modifier, text = LoremIpsum(words).values.joinToString(separator = " ")
247 | )
248 |
249 | @Test
250 | fun padding_not_applied() = paparazzi.snapshotWrapper {
251 | Row(modifier = Modifier.fillMaxWidth()) {
252 | LoremText(modifier = Modifier.weight(1f), words = 20)
253 | Column(modifier = Modifier.weight(1f)) {
254 | LoremText()
255 | Blueprint(
256 | blueprintBuilder = {
257 | widths {
258 | repeat(2) { group { "icon" lineTo "text" } }
259 | repeat(2) { group(Top) { "icon" lineTo "text" } }
260 | }
261 | heights {
262 | repeat(2) { group { "icon" lineTo "icon" } }
263 | repeat(2) { group(End) { "icon" lineTo "icon" } }
264 | }
265 | },
266 | applyPadding = false,
267 | fontColor = Color.Blue,
268 | ) {
269 | TestButton()
270 | }
271 | LoremText()
272 | }
273 | LoremText(modifier = Modifier.weight(1f), words = 20)
274 | }
275 | }
276 |
277 | @Test
278 | fun size_labels() = paparazzi.snapshotWrapper {
279 | Blueprint(blueprintBuilder = {
280 | widths { group { "1" lineTo "1" } }
281 | heights { group { "1" lineTo "1" } }
282 | }, content = { TestUI(showSizeLabels = true) })
283 | }
284 |
285 | @Test
286 | fun no_blueprint_if_globally_disabled() {
287 | blueprintEnabled = false
288 | paparazzi.snapshotWrapper {
289 | Blueprint(blueprintBuilder = {
290 | widths { group { "1" lineTo "1" } }
291 | heights { group { "1" lineTo "1" } }
292 | }, content = { TestUI() })
293 | }
294 | blueprintEnabled = true
295 | }
296 |
297 | @Test
298 | fun when_specifying_blueprint_ids_that_are_then_removed_from_the_composition_dimensions_are_shown_and_then_hidden() {
299 | var showGreen by mutableStateOf(true)
300 | val content = @Composable {
301 | Blueprint(blueprintBuilder = {
302 | widths {
303 | group(Top) { "green" lineTo "green" }
304 | group { "blue" lineTo "blue" }
305 | }
306 | }) {
307 | Column {
308 | if (showGreen) Box(
309 | modifier = Modifier
310 | .size(20.dp)
311 | .background(Color.Green)
312 | .blueprintId("green")
313 | )
314 | Box(
315 | modifier = Modifier
316 | .size(30.dp)
317 | .background(Color.Blue)
318 | .blueprintId("blue")
319 | )
320 | }
321 | }
322 | }
323 | paparazzi.snapshotWrapper(name = "(with green)") { content() }
324 | showGreen = false
325 | paparazzi.snapshotWrapper(name = "(without green)") { content() }
326 | }
327 |
328 | // todo add tests for absent arrow when dimension label does not fit
329 |
330 | @Test
331 | fun reacts_to_blueprint_builder_update() {
332 | var showGreenSize by mutableStateOf(true)
333 | val content = @Composable {
334 | Blueprint(blueprintBuilder = {
335 | widths {
336 | group { "2" lineTo "2" }
337 | if (showGreenSize) group { "1" lineTo "1" }
338 | }
339 | }) {
340 | TestUI()
341 | }
342 | }
343 | paparazzi.snapshotWrapper(name = "(with green)") { content() }
344 | showGreenSize = false
345 | paparazzi.snapshotWrapper(name = "(without green)") { content() }
346 | }
347 |
348 | private fun Paparazzi.snapshotWrapper(
349 | name: String? = null,
350 | composable: @Composable () -> Unit
351 | ): Unit = snapshot(name) {
352 | MaterialTheme {
353 | Surface(modifier = Modifier.fillMaxSize(), color = Color.White) {
354 | Box(modifier = Modifier.padding(8.dp)) {
355 | composable()
356 | }
357 | }
358 | }
359 | }
360 |
361 | @Composable
362 | private fun TestUI(showSizeLabels: Boolean = false) {
363 | val spacerWidth = 20.dp
364 | Column {
365 | val size = 40.dp
366 | Box(
367 | modifier = Modifier
368 | .size(size)
369 | .background(Color.Green)
370 | .blueprintId("1", if (showSizeLabels) SizeUnits.Dp else null),
371 | contentAlignment = Alignment.Center
372 | ) {
373 | Text(text = "${size.value.roundToInt()}dp", fontSize = 6.sp)
374 | }
375 | Spacer(Modifier.align(BiasAlignment.Horizontal(0.7f)), spacerWidth)
376 | Row {
377 | val size1 = 50.dp
378 | Box(
379 | modifier = Modifier
380 | .size(size1)
381 | .background(Color.Blue)
382 | .blueprintId("2", if (showSizeLabels) SizeUnits.Dp else null),
383 | contentAlignment = Alignment.Center
384 | ) {
385 | Text(text = "${size1.value.roundToInt()}dp", fontSize = 6.sp)
386 | }
387 | Spacer(modifier = Modifier.align(Alignment.CenterVertically), spacerWidth = spacerWidth)
388 | Box(
389 | modifier = Modifier
390 | .size(size1)
391 | .background(Color.Yellow)
392 | .blueprintId("3", if (showSizeLabels) SizeUnits.Dp else null),
393 | contentAlignment = Alignment.Center
394 | ) {
395 | Text(text = "${size1.value.roundToInt()}dp", fontSize = 6.sp)
396 | }
397 | }
398 | }
399 | }
400 |
401 | @Composable
402 | private fun Spacer(modifier: Modifier = Modifier, spacerWidth: Dp) {
403 | Box(
404 | modifier = modifier
405 | .size(spacerWidth)
406 | .background(Color.Green.copy(alpha = 0.2f)),
407 | contentAlignment = Alignment.Center
408 | ) {
409 | Text(text = "${spacerWidth.value.roundToInt()}dp", fontSize = 6.sp)
410 | }
411 | }
412 |
413 | @Composable
414 | private fun TestButton() = Button(onClick = { }) {
415 | Icon(
416 | modifier = Modifier
417 | .size(20.dp)
418 | .blueprintId("icon"),
419 | painter = rememberVectorPainter(Icons.Default.Home),
420 | contentDescription = null
421 | )
422 | Text(
423 | modifier = Modifier.blueprintId("text"),
424 | text = "Lorem",
425 | )
426 | }
427 | }
--------------------------------------------------------------------------------