package com.vgmlr.wedge
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ExitToApp
import androidx.compose.material.icons.automirrored.outlined.Sort
import androidx.compose.material.icons.automirrored.filled.Undo
import androidx.compose.material.icons.filled.Clear
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.outlined.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.KeyboardType
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun EditorTopBar(
menuExpanded: Boolean,
onMenuExpandedChange: (Boolean) -> Unit,
showCopyDot: Boolean,
showPasteDot: Boolean,
undoEnabled: Boolean,
onCopy: () -> Unit,
onPaste: () -> Unit,
onUndo: () -> Unit,
onSelectAll: () -> Unit,
onSort: () -> Unit,
onToggleCalc: () -> Unit,
showCalc: Boolean,
onShowData: () -> Unit,
onExport: () -> Unit,
onSettings: () -> Unit,
onShowVersion: () -> Unit,
isEncrypted: Boolean,
onSecurityAction: () -> Unit
) {
TopAppBar(
title = { },
colors = TopAppBarDefaults.topAppBarColors(containerColor = colorResource(id = R.color.primary_color)),
actions = {
Row(verticalAlignment = Alignment.CenterVertically) {
Text("wedge", color = colorResource(id = R.color.title_color), fontSize = 18.sp)
Spacer(Modifier.width(10.dp))
IconButton(
onClick = onUndo,
enabled = undoEnabled
) {
Icon(
Icons.AutoMirrored.Filled.Undo,
contentDescription = "Undo",
tint = if (undoEnabled) colorResource(id = R.color.title_color) else colorResource(id = R.color.title_color).copy(alpha = 0.3f)
)
}
IconButton(onClick = onCopy) {
Box {
Icon(Icons.Outlined.ContentCopy, "Copy", tint = colorResource(id = R.color.title_color))
if (showCopyDot) {
Box(
modifier = Modifier
.size(6.dp)
.align(Alignment.TopEnd)
.background(colorResource(id = R.color.title_color), shape = androidx.compose.foundation.shape.CircleShape)
)
}
}
}
IconButton(onClick = onPaste) {
Box {
Icon(Icons.Outlined.ContentPaste, "Paste", tint = colorResource(id = R.color.title_color))
if (showPasteDot) {
Box(
modifier = Modifier
.size(6.dp)
.align(Alignment.TopEnd)
.background(colorResource(id = R.color.title_color), shape = androidx.compose.foundation.shape.CircleShape)
)
}
}
}
IconButton(onClick = onSort) {
Box {
Icon(Icons.AutoMirrored.Outlined.Sort, "Sort", tint = colorResource(id = R.color.title_color))
}
}
Box {
IconButton(onClick = { onMenuExpandedChange(true) }) {
Icon(Icons.Default.MoreVert, null, tint = colorResource(id = R.color.title_color))
}
DropdownMenu(
expanded = menuExpanded,
onDismissRequest = { onMenuExpandedChange(false) },
modifier = Modifier.background(colorResource(id = R.color.menu_bg_color)).padding(horizontal = 6.dp)
) {
DropdownMenuItem(
text = { Text("Select All", color = colorResource(id = R.color.menu_color)) },
onClick = onSelectAll,
leadingIcon = { Icon(Icons.Outlined.SelectAll, null, tint = colorResource(id = R.color.menu_color)) }
)
DropdownMenuItem(
text = { Text(if (showCalc) "Collapse" else "Calculator", color = colorResource(id = R.color.menu_color)) },
onClick = onToggleCalc,
leadingIcon = { Icon(Icons.Outlined.AddCircleOutline, null, tint = colorResource(id = R.color.menu_color)) }
)
HorizontalDivider(
modifier = Modifier.padding(vertical = 8.dp),
color = colorResource(id = R.color.hr_color).copy(0.4f),
thickness = 1.dp
)
DropdownMenuItem(
text = { Text(if (isEncrypted) "Decrypt" else "Encrypt", color = colorResource(id = R.color.menu_color)) },
onClick = onSecurityAction,
leadingIcon = {
Icon(
if (isEncrypted) Icons.Outlined.LockOpen else Icons.Outlined.Lock,
null,
tint = colorResource(id = R.color.menu_color)
)
}
)
DropdownMenuItem(
text = { Text("Sync", color = colorResource(id = R.color.menu_color)) },
onClick = { onMenuExpandedChange(false) },
leadingIcon = { Icon(Icons.Outlined.Loop, null, tint = colorResource(id = R.color.menu_color)) }
)
DropdownMenuItem(
text = { Text("Export", color = colorResource(id = R.color.menu_color)) },
onClick = onExport,
leadingIcon = { Icon(Icons.AutoMirrored.Outlined.ExitToApp, null, tint = colorResource(id = R.color.menu_color)) }
)
HorizontalDivider(
modifier = Modifier.padding(vertical = 8.dp),
color = colorResource(id = R.color.hr_color).copy(0.4f),
thickness = 1.dp
)
DropdownMenuItem(
text = { Text("Data", color = colorResource(id = R.color.menu_color)) },
onClick = onShowData,
leadingIcon = { Icon(Icons.Outlined.DataArray, null, tint = colorResource(id = R.color.menu_color)) }
)
DropdownMenuItem(
text = { Text("Settings", color = colorResource(id = R.color.menu_color)) },
onClick = onSettings,
leadingIcon = { Icon(Icons.Outlined.Settings, null, tint = colorResource(id = R.color.menu_color)) }
)
DropdownMenuItem(
text = { Text("Version", color = colorResource(id = R.color.menu_color)) },
onClick = onShowVersion,
leadingIcon = { Icon(Icons.Outlined.History, null, tint = colorResource(id = R.color.menu_color)) }
)
}
}
}
}
)
}
@Composable
fun CalculatorOverlay(
calcValue: String,
onCalcValueChange: (String) -> Unit,
onDismiss: () -> Unit,
focusRequester: FocusRequester
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(52.dp)
.background(colorResource(id = R.color.calc_bg_color))
) {
IconButton(
onClick = { if (calcValue.isEmpty()) onDismiss() else onCalcValueChange("") },
modifier = Modifier.align(Alignment.CenterStart)
) { Icon(Icons.Default.Clear, null, tint = colorResource(id = R.color.calc_color).copy(alpha = 0.4f)) }
BasicTextField(
value = calcValue,
onValueChange = { onCalcValueChange(if (it.endsWith("=")) WedgeCalculator.doCalc(it.dropLast(1)) else it) },
modifier = Modifier
.fillMaxWidth()
.padding(start = 48.dp, end = 22.dp)
.align(Alignment.Center)
.focusRequester(focusRequester),
textStyle = TextStyle(colorResource(id = R.color.calc_color), fontSize = 19.sp, textAlign = TextAlign.End, fontFamily = FontFamily.Monospace),
cursorBrush = SolidColor(colorResource(id = R.color.calc_color)),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { onCalcValueChange(WedgeCalculator.doCalc(calcValue)) }),
singleLine = true,
decorationBox = { inner ->
Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.CenterEnd) {
if (calcValue.isEmpty()) Text("0", style = TextStyle(colorResource(id = R.color.calc_color).copy(alpha = 0.6f), fontSize = 19.sp, textAlign = TextAlign.End, fontFamily = FontFamily.Monospace))
inner()
}
}
)
}
}
@Composable
fun EncryptionOverlay(
passPhrase: String,
onPassPhraseChange: (String) -> Unit,
onAction: () -> Unit,
onDismiss: () -> Unit,
focusRequester: FocusRequester,
isDecrypt: Boolean = false
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(52.dp)
.background(colorResource(id = R.color.calc_bg_color))
) {
IconButton(
onClick = onAction,
enabled = passPhrase.isNotEmpty(),
modifier = Modifier.align(Alignment.CenterStart)
) {
Icon(
if (isDecrypt) Icons.Outlined.LockOpen else Icons.Outlined.Lock,
contentDescription = null,
modifier = Modifier.padding(start = 3.dp),
tint = if (passPhrase.isNotEmpty()) colorResource(id = R.color.calc_color) else colorResource(id = R.color.calc_color).copy(alpha = 0.4f)
)
}
BasicTextField(
value = passPhrase,
onValueChange = onPassPhraseChange,
modifier = Modifier
.fillMaxWidth()
.padding(start = 58.dp, end = 48.dp)
.align(Alignment.Center)
.focusRequester(focusRequester),
textStyle = TextStyle(
colorResource(id = R.color.calc_color),
fontSize = 16.sp,
textAlign = TextAlign.Start,
fontFamily = FontFamily.Monospace
),
cursorBrush = SolidColor(colorResource(id = R.color.calc_color)),
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done,
keyboardType = KeyboardType.Password
),
keyboardActions = KeyboardActions(onDone = { if(passPhrase.isNotEmpty()) onAction() }),
singleLine = true,
decorationBox = { inner ->
Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.CenterStart) {
if (passPhrase.isEmpty()) Text(
if (isDecrypt) "Pass Phrase" else "Pass Phrase",
style = TextStyle(
colorResource(id = R.color.calc_color).copy(alpha = 0.6f),
fontSize = 16.sp,
textAlign = TextAlign.Start,
fontFamily = FontFamily.Monospace
)
)
inner()
}
}
)
IconButton(
onClick = onDismiss,
modifier = Modifier.align(Alignment.CenterEnd).padding(end = 3.dp),
) { Icon(Icons.Default.Clear, null, tint = colorResource(id = R.color.calc_color).copy(alpha = 0.4f)) }
}
}