/* 2023-08-29 File created by Kari Laitinen (c) naturalprogramming.com This example demonstrates - Canvas drawings This is an Android app made of this single file. If you want to test this app, create an Android Compose project with the project name DrawingDemoC and the package name shown below. Then, store this file to the folder where MainActivity.kt is and make the following change to AndroidManifest.xml: android:name=".DrawingDemoCActivity" Imports may need to be modified if a new Android/Compose version is used. Some 'warnings': - tab size in this file is 3 spaces - underscores may be used in the names invented by the programmer */ package drawing.democ import android.os.Bundle import android.view.WindowManager import android.view.WindowMetrics import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.Canvas import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.text.ExperimentalTextApi import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.drawText import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.unit.sp import drawing.democ.ui.theme.DrawingDemoCTheme class DrawingDemoCActivity : ComponentActivity() { @OptIn( ExperimentalTextApi::class ) override fun onCreate( savedInstanceState : Bundle? ) { super.onCreate( savedInstanceState ) val metrics: WindowMetrics = getSystemService(WindowManager::class.java).currentWindowMetrics val raw_screen_width = metrics.bounds.width() val raw_screen_height = metrics.bounds.height() setContent { DrawingDemoCTheme { // A surface container using the 'background' color from the theme Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { val configuration = LocalConfiguration.current val screen_width_dp = configuration.screenWidthDp val screen_height_dp = configuration.screenHeightDp val textMeasurer = rememberTextMeasurer() Canvas( modifier = Modifier.fillMaxSize() ) { //val canvasSize = size val canvas_width = size.width val canvas_height = size.height drawText( textMeasurer = textMeasurer, text = "Canvas size: " + canvas_width + " x " + canvas_height, topLeft = Offset( x = 20F, y = 40F ), style = TextStyle( fontSize = 12.sp, fontWeight = FontWeight.Bold ) ) drawText( textMeasurer = textMeasurer, text = "Screen size (dp): " + screen_width_dp + " x " + screen_height_dp, topLeft = Offset( x = 20F, y = 70F ), style = TextStyle( fontSize = 12.sp, fontWeight = FontWeight.Bold ) ) drawText( textMeasurer = textMeasurer, text = "Raw screen size: " + raw_screen_width + " x " + raw_screen_height, topLeft = Offset( x = 20F, y = 100F ), style = TextStyle( fontSize = 12.sp, fontWeight = FontWeight.Bold ) ) drawLine( color = Color.Green, start = Offset( x = canvas_width / 6F, y = canvas_height / 8F ), end = Offset( x = canvas_width * 5F / 6F, y = canvas_height / 8F ), strokeWidth = 8F ) drawRect( color = Color.Cyan, topLeft = Offset( x = canvas_width / 2F - canvas_height / 8F, y = canvas_height / 4F - canvas_height / 20F ), size = Size(canvas_height / 4F, canvas_height / 10F ) ) // The following call draws a hollow rectangle around the Cyan rectangle, // so that there is a margin of 20 pixels. drawRect( color = Color.Blue, topLeft = Offset( x = canvas_width / 2F - canvas_height / 8F - 20, y = canvas_height / 4F - canvas_height / 20F - 20 ), size = Size(canvas_height / 4F + 40, canvas_height / 10F + 40 ), style = Stroke( width = 4F ) ) drawCircle( color = Color.Magenta, radius = canvas_height / 10F, center = Offset( x = canvas_width / 2F, y = canvas_height / 2F ) ) drawCircle( color = Color.Blue, radius = canvas_height / 10F, center = Offset( x = canvas_width / 2F, y = canvas_height / 2F ), style = Stroke( 4F ) ) // The following calls draw a 'pacman' drawArc( color = Color.Yellow, startAngle = 45F, sweepAngle = 270F, useCenter = true, topLeft = Offset( x = canvas_width / 2F - canvas_height / 8F - 60, y = canvas_height * 22 / 32F ), size = Size(canvas_height / 4F, canvas_height / 4F) ) drawArc( color = Color.Black, startAngle = 45F, sweepAngle = 270F, useCenter = true, topLeft = Offset( x = canvas_width / 2F - canvas_height / 8F - 60, y = canvas_height * 22 / 32F ), size = Size(canvas_height / 4F, canvas_height / 4F ), style = Stroke( 4F ) ) // The following method calls draw a 'pie'. drawArc( color = Color.Yellow, startAngle = 315F, sweepAngle = 90F, useCenter = true, topLeft = Offset( x = canvas_width / 2F - canvas_height / 8F + 60, y = canvas_height * 22 / 32F ), size = Size(canvas_height / 4F, canvas_height / 4F ) ) drawArc( color = Color.Black, startAngle = 315F, sweepAngle = 90F, useCenter = true, topLeft = Offset( x = canvas_width / 2F - canvas_height / 8F + 60, y = canvas_height * 22 / 32F ), size = Size(canvas_height / 4F, canvas_height / 4F ), style = Stroke( 4F ) ) } } } } } }