Add icons for eraser, select, and move tools
- Eraser: angled rectangle with dividing line (eraser tip) - Select: dashed rectangle (marquee selection) - Move: four-way arrow cross with arrowheads All icons match the existing pen dot, line, and box icon style. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user