profile editing. styling
This commit is contained in:
parent
d5ff6a1a0a
commit
f73be7184f
|
|
@ -1,5 +1,6 @@
|
|||
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
|
||||
import org.jetbrains.compose.internal.de.undercouch.gradle.tasks.download.Download
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
|
||||
plugins {
|
||||
val kotlinVersion = "2.0.21"
|
||||
|
|
@ -67,35 +68,53 @@ dependencies {
|
|||
val serializationVersion = "1.5.1"
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serializationVersion")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
|
||||
|
||||
//FileKit
|
||||
val fileKitVersion = "0.8.7"
|
||||
implementation("io.github.vinceglb:filekit-core:$fileKitVersion")
|
||||
implementation("io.github.vinceglb:filekit-compose:$fileKitVersion")
|
||||
}
|
||||
|
||||
val currentOs = OperatingSystem.current()
|
||||
|
||||
compose.desktop {
|
||||
application {
|
||||
mainClass = "MainKt"
|
||||
|
||||
nativeDistributions {
|
||||
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
||||
linux {
|
||||
modules("jdk.security.auth")
|
||||
}
|
||||
targetFormats(
|
||||
*listOf(
|
||||
TargetFormat.Dmg.takeIf { currentOs.isMacOsX },
|
||||
TargetFormat.Msi.takeIf { currentOs.isWindows },
|
||||
TargetFormat.Deb.takeIf { currentOs.isLinux }
|
||||
).filterNotNull().toTypedArray()
|
||||
)
|
||||
packageName = "mia"
|
||||
packageVersion = "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register("buildLite") {
|
||||
tasks.register("packageLiteInstaller") {
|
||||
group = "package project"
|
||||
description = "Build program with the small vosk STT model"
|
||||
dependsOn("prepareLiteResources", "build")
|
||||
dependsOn("prepareLiteResources", "package")
|
||||
}
|
||||
|
||||
tasks.register("buildFull") {
|
||||
tasks.register("packageFullInstaller") {
|
||||
group = "package project"
|
||||
description = "Build program with the large vosk STT model"
|
||||
dependsOn("prepareFullResources", "build")
|
||||
dependsOn("prepareFullResources", "package")
|
||||
}
|
||||
|
||||
|
||||
tasks.register("generateSemanticModel") {
|
||||
group = "package project"
|
||||
description = "Run DJL to generate Semantic model from HuggingFace (all-roberta-large-v1)"
|
||||
|
||||
val exeDir = ""
|
||||
val modelName = "sentence-transformers/all-roberta-large-v1"
|
||||
val djlOutputDir = project.file("src/main/resources/Semantic-model")
|
||||
|
||||
|
|
@ -106,9 +125,9 @@ tasks.register("generateSemanticModel") {
|
|||
doLast {
|
||||
val os = System.getProperty("os.name")
|
||||
val executable = when {
|
||||
os.contains("win") -> project.file("$exeDir/djl-windows.exe")
|
||||
os.contains("mac") -> project.file("$exeDir/djl-mac")
|
||||
os.contains("linux") || os.contains("nix") || os.contains("nux") -> project.file("$exeDir/djl-linux")
|
||||
currentOs.isWindows -> project.file("djl/windows.exe")
|
||||
currentOs.isMacOsX -> project.file("djl/mac")
|
||||
currentOs.isLinux -> project.file("djl/linux")
|
||||
else -> throw GradleException("Unsupported OS: $os")
|
||||
}
|
||||
|
||||
|
|
@ -123,6 +142,7 @@ val modelUrl = "https://alphacephei.com/vosk/models"
|
|||
val zipFile = layout.buildDirectory.file("STT-model.zip")
|
||||
|
||||
tasks.register<Download>("prepareLiteResources") {
|
||||
group = "package project"
|
||||
description = "Download small vosk model to resources"
|
||||
|
||||
val modelName = "vosk-model-small-en-us-0.15"
|
||||
|
|
@ -144,6 +164,7 @@ tasks.register<Download>("prepareLiteResources") {
|
|||
}
|
||||
|
||||
tasks.register<Download>("prepareFullResources") {
|
||||
group = "package project"
|
||||
description = "Download large vosk model to resources"
|
||||
|
||||
val modelName = "vosk-model-en-us-0.22"
|
||||
|
|
|
|||
|
|
@ -78,8 +78,4 @@ fun transparentButton(icon: ImageVector, contentDescription: String, onClick: ()
|
|||
contentDescription = contentDescription
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: If folders (Semantic-model/, STT-model/) don't exist on start-up install
|
||||
// Install Semantic-model by downloading, using djl-converter (look into using pip module from Java), move to resources
|
||||
// Install STT-model by downloading, move to resources
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@ import kotlinx.serialization.SerializationException
|
|||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.decodeFromStream
|
||||
import kotlinx.serialization.json.encodeToStream
|
||||
import logger
|
||||
import transparentButton
|
||||
import ui.Profiles.Companion.Dialogs.Companion.activateDialog
|
||||
import ui.Profiles.Companion.Dialogs.Companion.deleteDialog
|
||||
|
|
@ -102,9 +103,13 @@ class Profiles {
|
|||
@OptIn(ExperimentalSerializationApi::class)
|
||||
fun save(profile: Profile) {
|
||||
val stream = FileOutputStream(getProfileLocation(profile.name))
|
||||
Json.encodeToStream(profile, stream)
|
||||
val json = Json { prettyPrint = true }
|
||||
|
||||
json.encodeToStream(profile, stream)
|
||||
stream.flush()
|
||||
stream.close()
|
||||
logger.info { "Profile Saved: ${profile.name}.profile" }
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,18 +1,48 @@
|
|||
package ui.screens
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.TooltipArea
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextField
|
||||
import androidx.compose.material.TextFieldDefaults
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.FileOpen
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
import ui.Profiles.Companion.Dialogs.Companion.activateDialog
|
||||
import ui.Profiles.Companion.Buttons.Companion.activateButton
|
||||
import ui.Profiles.Companion.Buttons.Companion.saveButton
|
||||
import ui.Profiles.Companion.Buttons.Companion.deleteButton
|
||||
import ui.Profiles.Companion.Dialogs.Companion.deleteDialog
|
||||
import ui.Profiles.Companion.Entities.Profile
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.github.vinceglb.filekit.core.FileKit
|
||||
import io.github.vinceglb.filekit.core.PickerMode
|
||||
import io.github.vinceglb.filekit.core.PickerType
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.async
|
||||
import logger
|
||||
|
||||
class ProfileDetails(val profile: Profile): Screen {
|
||||
/**
|
||||
|
|
@ -23,22 +53,156 @@ class ProfileDetails(val profile: Profile): Screen {
|
|||
*
|
||||
*/
|
||||
@Composable
|
||||
override fun Content() { //TODO: Description of what each attribute represents
|
||||
Column {
|
||||
Text("Name: ${profile.name}") //TODO: Text Field
|
||||
Text("AI name: ${profile.aiName}") //TODO: Text Field
|
||||
Text("Program name: ${profile.programName}") //TODO: Text Field
|
||||
Text("Program path: ${profile.programPath}") //TODO: FileDialog
|
||||
override fun Content() {
|
||||
Row {
|
||||
generalAttributes()
|
||||
commands()
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
activateButton(profile)
|
||||
saveButton(profile)
|
||||
deleteButton(profile)
|
||||
activateDialog(profile)
|
||||
deleteDialog(profile)
|
||||
@Composable
|
||||
fun commands() {
|
||||
//TODO: Display commands
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun generalAttributes() {
|
||||
Column {
|
||||
textAttribute(
|
||||
title = "Name",
|
||||
tooltip = "This is the name of the profile. It also acts as the name of the saved file.",
|
||||
currentValue = profile.name,
|
||||
onValueChange = { newValue ->
|
||||
profile.name = newValue
|
||||
logger.info { "Profile Attribute Changed: name = $newValue" }
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
textAttribute(
|
||||
title = "AI name",
|
||||
tooltip = "This is the name you want to refer to the program as. It will also serve as the trigger word for commands.",
|
||||
currentValue = profile.aiName,
|
||||
onValueChange = { newValue ->
|
||||
profile.aiName = newValue
|
||||
logger.info { "Profile Attribute Changed: ai_name = $newValue" }
|
||||
}
|
||||
)
|
||||
|
||||
textAttribute(
|
||||
title = "Program name",
|
||||
tooltip = "This is the name of the window you want to control.",
|
||||
currentValue = profile.programName,
|
||||
onValueChange = { newValue ->
|
||||
profile.programName = newValue
|
||||
logger.info { "Profile Attribute Changed: program_name = $newValue" }
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
pathAttribute(
|
||||
title = "Program path",
|
||||
tooltip = "This is the absolute path to the program you want to control.",
|
||||
currentValue = profile.programPath,
|
||||
onValueChange = { newValue ->
|
||||
profile.programPath = newValue
|
||||
logger.info { "Profile Attribute Changed: program_path = $newValue" }
|
||||
}
|
||||
)
|
||||
|
||||
buttons()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun pathAttribute(title: String, currentValue: String, tooltip: String, onValueChange: (String) -> Unit) {
|
||||
var fieldValue by remember { mutableStateOf(currentValue) }
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
textAttribute(
|
||||
title = title,
|
||||
tooltip = tooltip,
|
||||
currentValue = profile.programName,
|
||||
onValueChange = onValueChange
|
||||
)
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
CoroutineScope(Dispatchers.IO + SupervisorJob()).async {
|
||||
fieldValue = FileKit.pickFile(
|
||||
title = "Pick program path",
|
||||
type = PickerType.File(),
|
||||
mode = PickerMode.Single,
|
||||
initialDirectory = null,
|
||||
)?.path.toString()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.FileOpen,
|
||||
contentDescription = "Choose File"
|
||||
)
|
||||
}
|
||||
}
|
||||
//TODO: Display commands
|
||||
// Allow editing. on unFocus, update profile entry
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun buttons() {
|
||||
Row {
|
||||
activateButton(profile)
|
||||
Spacer(Modifier.width(10.dp))
|
||||
saveButton(profile)
|
||||
Spacer(Modifier.width(10.dp))
|
||||
deleteButton(profile)
|
||||
|
||||
activateDialog(profile)
|
||||
deleteDialog(profile)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun textAttribute(title: String, currentValue: String, tooltip: String, onValueChange: (String) -> Unit) {
|
||||
var fieldText by remember { mutableStateOf(currentValue) }
|
||||
TooltipArea(
|
||||
tooltip = {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.wrapContentSize()
|
||||
.background(MaterialTheme.colors.primary, CircleShape)
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(10.dp),
|
||||
text = tooltip,
|
||||
color = MaterialTheme.colors.onPrimary
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
TextField(
|
||||
colors = TextFieldDefaults.textFieldColors(
|
||||
textColor = MaterialTheme.colors.onBackground,
|
||||
backgroundColor = Color.Transparent
|
||||
),
|
||||
value = fieldText,
|
||||
onValueChange = { newValue ->
|
||||
onValueChange(newValue)
|
||||
fieldText = newValue
|
||||
},
|
||||
label = {
|
||||
Text(
|
||||
text = "$title:"
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue