Search code examples
androidkotlinandroid-jetpack-composecompose-desktop

Why are my vertical lines not lining up like the horizontal lines in Jetpack Compose for desktop?


I'm learning Kotlin and Jetpack Compose desktop. I've made a Sudoku solver and am now trying to make it graphical. My window dimensions are 800 X 800. I have 20.dp padding around all sides. My formula for placing the horizontal lines works perfect. I would think it would be the same for the vertical lines but they are offset. I found it interesting that the canvas width and height are less than what I declared the window dimensions to be. I played around with the height of the columns and it always drew the line as desired. puzzle Window attributes

@Composable
fun displayPuzzle(answer: Array<Array<IntArray>>) {
    var list = mutableStateListOf<String>()
    for (x in answer[0]) list.addAll(x.map { it.toString() })

    var columnHeighty by remember { mutableStateOf(0F) }
    var columnWidthx by remember { mutableStateOf(0f) }
    var pad = 20

    LazyVerticalGrid(

        columns = GridCells.Fixed(9),
        contentPadding = PaddingValues(
            start = pad.dp,
            top = pad.dp,
            end = pad.dp,
            bottom = pad.dp
        )

    ) {
        items(list.size) { index ->
            Card(
                backgroundColor = Color.Red,
                modifier = Modifier
                    .fillMaxWidth()
                    .fillMaxHeight()
                    .onGloballyPositioned { coordinates ->
                        columnWidthx = coordinates.size.width.toFloat()
                        columnHeighty = coordinates.size.height.toFloat()
                    },

                border = BorderStroke(width = 1.dp, color = Color.White)
            ) {
                Text(
                    text = list[index],
                    fontWeight = FontWeight.Bold,
                    fontSize = 30.sp,
                    color = Color(0xFF000000),
                    textAlign = TextAlign.Center,
                    modifier = Modifier.padding(23.dp)
                )
            }

        }

    }

    Canvas(modifier = Modifier.fillMaxSize()) {
        val canvasWidth = size.width
        val canvasHeight = size.height
        val strokeWidth = 5.0F

        println("Canvas Width $canvasWidth")
        println("Canvas Height $canvasHeight")
        println("Column Width $columnWidthx")
        println("Column Height $columnHeighty")

        //Draw 1st vertical separator
        drawLine(
            start = Offset(x = columnWidthx * 3 + pad.toFloat(), y = pad.toFloat()),
            end = Offset(x = columnWidthx * 3 + pad.toFloat(), y = canvasHeight - pad.toFloat()),
            color = Color.Black,
            strokeWidth = strokeWidth
        )
        //Draw 2nd vertical separator
        drawLine(
            start = Offset(x = columnWidthx * 6 + pad.toFloat(), y = pad.toFloat()),
            end = Offset(x = columnWidthx * 6 + pad.toFloat(), y = canvasHeight - pad.toFloat()),
            color = Color.Black,
            strokeWidth = strokeWidth
        )
        //Draw 1st horizontal separator
        drawLine(
            start = Offset(x = pad.toFloat(), y = columnHeighty * 3 + pad.toFloat()),
            end = Offset(x = canvasWidth - pad.toFloat() , y = columnHeighty * 3 + pad.toFloat()),
            color = Color.Black,
            strokeWidth = strokeWidth
        )
        //Draw 2nd horizontal seperator
        drawLine(
            start = Offset(x = pad.toFloat(), y = columnHeighty * 6 + pad.toFloat()),
            end = Offset(x = canvasWidth - pad.toFloat() , y = columnHeighty * 6 + pad.toFloat()),
            color = Color.Black,
            strokeWidth = strokeWidth
        )
        //Draw top border
        drawLine(
            start = Offset(x = pad.toFloat(), y = pad.toFloat() + strokeWidth / 2),
            end = Offset(x = canvasWidth - pad.toFloat() , y = pad.toFloat() + strokeWidth / 2),
            color = Color.Black,
            strokeWidth = strokeWidth
        )
        //Draw bottom border
        drawLine(
            start = Offset(x = pad.toFloat(), y = canvasHeight - pad.toFloat() - strokeWidth / 2),
            end = Offset(x = canvasWidth - pad.toFloat() , y = canvasHeight - pad.toFloat() - strokeWidth / 2),
            color = Color.Black,
            strokeWidth = strokeWidth
        )
        //Draw left border
        drawLine(
            start = Offset(x = pad.toFloat(), y = pad.toFloat()),
            end = Offset(x = pad.toFloat() , y = canvasHeight - pad.toFloat()),
            color = Color.Black,
            strokeWidth = strokeWidth
        )
        //Draw right border
        drawLine(
            start = Offset(x = canvasWidth - pad.toFloat(), y = pad.toFloat()),
            end = Offset(x = canvasWidth - pad.toFloat() , y = canvasHeight - pad.toFloat()),
            color = Color.Black,
            strokeWidth = strokeWidth
        )

    }

}
   Window(onCloseRequest = ::exitApplication) {
        window.minimumSize = Dimension(800,800)
        displayPuzzle(finalAnswer[0])
    }

Solution

  • I figured out the width of the cells was varying by 1 dp. I used Modifier.requiredWidth and it works as desired.