diff --git a/app/src/main/kotlin/net/metacircular/engpad/ui/editor/Toolbar.kt b/app/src/main/kotlin/net/metacircular/engpad/ui/editor/Toolbar.kt index 438418c..392307d 100644 --- a/app/src/main/kotlin/net/metacircular/engpad/ui/editor/Toolbar.kt +++ b/app/src/main/kotlin/net/metacircular/engpad/ui/editor/Toolbar.kt @@ -111,6 +111,79 @@ private fun BoxIcon(selected: Boolean) { } } +/** Eraser icon — rectangle at an angle with a line underneath. */ +@Composable +private fun EraserIcon(selected: Boolean) { + val color = if (selected) Color.White else Color.Black + Canvas(modifier = Modifier.size(18.dp)) { + val w = size.width + val h = size.height + val path = androidx.compose.ui.graphics.Path().apply { + // Angled eraser body + moveTo(w * 0.6f, h * 0.15f) + lineTo(w * 0.9f, h * 0.45f) + lineTo(w * 0.5f, h * 0.85f) + lineTo(w * 0.2f, h * 0.55f) + close() + } + drawPath(path, color = color, style = Stroke(width = 1.5f * density, cap = StrokeCap.Round)) + // Dividing line between eraser tip and body + drawLine(color, Offset(w * 0.55f, h * 0.5f), Offset(w * 0.35f, h * 0.7f), 1.5f * density) + } +} + +/** Select icon — dashed rectangle (marquee). */ +@Composable +private fun SelectIcon(selected: Boolean) { + val color = if (selected) Color.White else Color.Black + Canvas(modifier = Modifier.size(18.dp)) { + val inset = 2f + drawRect( + color = color, + topLeft = Offset(inset, inset), + size = androidx.compose.ui.geometry.Size(size.width - inset * 2, size.height - inset * 2), + style = Stroke( + width = 1.5f * density, + pathEffect = androidx.compose.ui.graphics.PathEffect.dashPathEffect( + floatArrayOf(4f * density, 3f * density), 0f, + ), + ), + ) + } +} + +/** Move icon — four-way arrow (cross with arrowheads). */ +@Composable +private fun MoveIcon(selected: Boolean) { + val color = if (selected) Color.White else Color.Black + Canvas(modifier = Modifier.size(18.dp)) { + val w = size.width + val h = size.height + val cx = w / 2f + val cy = h / 2f + val arm = w * 0.35f + val head = w * 0.12f + val sw = 1.5f * density + + // Cross lines + drawLine(color, Offset(cx, cy - arm), Offset(cx, cy + arm), sw, StrokeCap.Round) + drawLine(color, Offset(cx - arm, cy), Offset(cx + arm, cy), sw, StrokeCap.Round) + + // Up arrow + drawLine(color, Offset(cx, cy - arm), Offset(cx - head, cy - arm + head), sw, StrokeCap.Round) + drawLine(color, Offset(cx, cy - arm), Offset(cx + head, cy - arm + head), sw, StrokeCap.Round) + // Down arrow + drawLine(color, Offset(cx, cy + arm), Offset(cx - head, cy + arm - head), sw, StrokeCap.Round) + drawLine(color, Offset(cx, cy + arm), Offset(cx + head, cy + arm - head), sw, StrokeCap.Round) + // Left arrow + drawLine(color, Offset(cx - arm, cy), Offset(cx - arm + head, cy - head), sw, StrokeCap.Round) + drawLine(color, Offset(cx - arm, cy), Offset(cx - arm + head, cy + head), sw, StrokeCap.Round) + // Right arrow + drawLine(color, Offset(cx + arm, cy), Offset(cx + arm - head, cy - head), sw, StrokeCap.Round) + drawLine(color, Offset(cx + arm, cy), Offset(cx + arm - head, cy + head), sw, StrokeCap.Round) + } +} + /** Undo arrow icon (curved left arrow). */ @Composable private fun UndoIcon(enabled: Boolean) { @@ -319,9 +392,15 @@ fun EditorToolbar( BoxIcon(currentTool == Tool.BOX) } - TextToolButton("Eraser", currentTool == Tool.ERASER, { onToolSelected(Tool.ERASER) }) - TextToolButton("Select", currentTool == Tool.SELECT, { onToolSelected(Tool.SELECT) }) - TextToolButton("Move", currentTool == Tool.MOVE, { onToolSelected(Tool.MOVE) }) + ToolButton(selected = currentTool == Tool.ERASER, onClick = { onToolSelected(Tool.ERASER) }) { + EraserIcon(currentTool == Tool.ERASER) + } + ToolButton(selected = currentTool == Tool.SELECT, onClick = { onToolSelected(Tool.SELECT) }) { + SelectIcon(currentTool == Tool.SELECT) + } + ToolButton(selected = currentTool == Tool.MOVE, onClick = { onToolSelected(Tool.MOVE) }) { + MoveIcon(currentTool == Tool.MOVE) + } // Selection operations if (hasSelection || canPaste) {