Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,27 @@ package cc.unitmesh.devins.idea.editor

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import cc.unitmesh.devins.idea.toolwindow.IdeaComposeIcons
import cc.unitmesh.devins.ui.compose.theme.AutoDevColors
import cc.unitmesh.llm.NamedModelConfig
import org.jetbrains.jewel.foundation.theme.JewelTheme
import org.jetbrains.jewel.ui.component.*
import org.jetbrains.jewel.ui.component.Icon

/**
* Bottom toolbar for the input section.
* Provides send/stop buttons, @ trigger for agent completion, settings, and token info.
*
* Provides send/stop buttons, @ trigger for agent completion, / command trigger, model selector, settings, and token info.
*
* Layout: Workspace - Token Info - ModelSelector - @ Symbol - / Symbol - Settings - Send Button
*
* Uses Jewel components for native IntelliJ IDEA look and feel.
*/
@Composable
Expand All @@ -25,9 +32,15 @@ fun IdeaBottomToolbar(
isExecuting: Boolean = false,
onStopClick: () -> Unit = {},
onAtClick: () -> Unit = {},
onSlashClick: () -> Unit = {},
onSettingsClick: () -> Unit = {},
workspacePath: String? = null,
totalTokens: Int? = null,
// Model selector props
availableConfigs: List<NamedModelConfig> = emptyList(),
currentConfigName: String? = null,
onConfigSelect: (NamedModelConfig) -> Unit = {},
onConfigureClick: () -> Unit = {},
modifier: Modifier = Modifier
) {
Row(
Expand All @@ -53,18 +66,19 @@ fun IdeaBottomToolbar(

Box(
modifier = Modifier
.background(
JewelTheme.globalColors.panelBackground.copy(alpha = 0.8f)
)
.clip(RoundedCornerShape(4.dp))
.background(JewelTheme.globalColors.panelBackground.copy(alpha = 0.8f))
.padding(horizontal = 8.dp, vertical = 4.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
Text(
text = "📁",
style = JewelTheme.defaultTextStyle.copy(fontSize = 12.sp)
Icon(
imageVector = IdeaComposeIcons.Folder,
contentDescription = null,
tint = JewelTheme.globalColors.text.normal,
modifier = Modifier.size(12.dp)
)
Text(
text = projectName,
Expand All @@ -79,6 +93,7 @@ fun IdeaBottomToolbar(
if (totalTokens != null && totalTokens > 0) {
Box(
modifier = Modifier
.clip(RoundedCornerShape(4.dp))
.background(AutoDevColors.Blue.c400.copy(alpha = 0.2f))
.padding(horizontal = 8.dp, vertical = 4.dp)
) {
Expand Down Expand Up @@ -107,13 +122,34 @@ fun IdeaBottomToolbar(
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically
) {
// Model selector
IdeaModelSelector(
availableConfigs = availableConfigs,
currentConfigName = currentConfigName,
onConfigSelect = onConfigSelect,
onConfigureClick = onConfigureClick
)

// @ trigger button for agent completion
IconButton(
onClick = onAtClick,
modifier = Modifier.size(32.dp)
) {
Icon(
imageVector = IdeaComposeIcons.AlternateEmail,
contentDescription = "@ Agent",
tint = JewelTheme.globalColors.text.normal,
modifier = Modifier.size(18.dp)
)
}

// / trigger button for slash commands
IconButton(
onClick = onSlashClick,
modifier = Modifier.size(32.dp)
) {
Text(
text = "@",
text = "/",
style = JewelTheme.defaultTextStyle.copy(
fontSize = 16.sp,
fontWeight = FontWeight.Bold
Expand All @@ -126,9 +162,11 @@ fun IdeaBottomToolbar(
onClick = onSettingsClick,
modifier = Modifier.size(32.dp)
) {
Text(
text = "⚙",
style = JewelTheme.defaultTextStyle.copy(fontSize = 14.sp)
Icon(
imageVector = IdeaComposeIcons.Settings,
contentDescription = "Settings",
tint = JewelTheme.globalColors.text.normal,
modifier = Modifier.size(16.dp)
)
}

Expand All @@ -138,23 +176,45 @@ fun IdeaBottomToolbar(
onClick = onStopClick,
modifier = Modifier.height(32.dp)
) {
Text(
text = "⏹ Stop",
style = JewelTheme.defaultTextStyle.copy(
color = AutoDevColors.Red.c400
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
Icon(
imageVector = IdeaComposeIcons.Stop,
contentDescription = "Stop",
tint = AutoDevColors.Red.c400,
modifier = Modifier.size(14.dp)
)
)
Text(
text = "Stop",
style = JewelTheme.defaultTextStyle.copy(
color = AutoDevColors.Red.c400
)
)
}
}
} else {
DefaultButton(
onClick = onSendClick,
enabled = sendEnabled,
modifier = Modifier.height(32.dp)
) {
Text(
text = "Send",
style = JewelTheme.defaultTextStyle
)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
Icon(
imageVector = IdeaComposeIcons.Send,
contentDescription = "Send",
tint = JewelTheme.globalColors.text.normal,
modifier = Modifier.size(14.dp)
)
Text(
text = "Send",
style = JewelTheme.defaultTextStyle
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ fun IdeaInputSection(
onSend: (String) -> Unit,
onStop: () -> Unit = {},
onAtClick: () -> Unit = {},
onSlashClick: () -> Unit = {},
onSettingsClick: () -> Unit = {},
workspacePath: String? = null,
totalTokens: Int? = null,
Expand Down Expand Up @@ -124,6 +125,13 @@ fun IdeaInputSection(
}
onAtClick()
},
onSlashClick = {
// Insert / character and trigger slash commands
textFieldState.edit {
append("/")
}
onSlashClick()
},
onSettingsClick = onSettingsClick,
workspacePath = workspacePath,
totalTokens = totalTokens
Expand Down
Loading
Loading