Skip to content

Commit 1ea63a7

Browse files
committed
feat(gui): improve file search popup in WorkspacePanel #358
- Refactor showFileSearchPopup to use a more suitable location for the popup - Enhance FileItemComponent to display file name and path inline with better styling - Add relative path display to make long paths more readable - Adjust layout and sizing of the file search popup for improved user experience
1 parent fe991d4 commit 1ea63a7

File tree

1 file changed

+40
-11
lines changed

1 file changed

+40
-11
lines changed

core/src/main/kotlin/cc/unitmesh/devti/gui/chat/ui/WorkspacePanel.kt

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ import com.intellij.openapi.ui.popup.JBPopupFactory
2525
import com.intellij.openapi.ui.popup.JBPopup
2626
import com.intellij.openapi.roots.ProjectRootManager
2727
import com.intellij.openapi.vfs.VfsUtil
28+
import com.intellij.ui.awt.RelativePoint
2829
import com.intellij.util.ui.UIUtil
2930
import org.jetbrains.annotations.NotNull
31+
import javax.swing.Box
32+
import javax.swing.BoxLayout
33+
import javax.swing.JComponent
3034

3135
class WorkspacePanel(
3236
private val project: Project,
@@ -52,15 +56,16 @@ class WorkspacePanel(
5256
addButton.border = JBUI.Borders.empty(2, 4)
5357
addButton.background = JBColor(0xEDF4FE, 0x313741)
5458
addButton.isOpaque = true
59+
5560
addButton.addMouseListener(object : MouseAdapter() {
5661
override fun mouseClicked(e: MouseEvent) {
57-
showFileSearchPopup(e.component)
62+
showFileSearchPopup(this@WorkspacePanel)
5863
}
5964
})
6065
return addButton
6166
}
6267

63-
private fun showFileSearchPopup(component: Component) {
68+
private fun showFileSearchPopup(component: JComponent) {
6469
val popup = FileSearchPopup(project) { files ->
6570
for (file in files) {
6671
addFileToWorkspace(file)
@@ -135,6 +140,7 @@ class FileSearchPopup(
135140
private val searchField = JTextField()
136141
private val contentPanel = JPanel(BorderLayout())
137142
private val allProjectFiles = mutableListOf<FileItem>()
143+
private val minPopupSize = Dimension(435, 300)
138144

139145
init {
140146
loadProjectFiles()
@@ -157,7 +163,6 @@ class FileSearchPopup(
157163
}
158164

159165
private fun setupUI() {
160-
// Setup search field
161166
searchField.document.addDocumentListener(object : DocumentListener {
162167
override fun insertUpdate(e: DocumentEvent) = updateSearch()
163168
override fun removeUpdate(e: DocumentEvent) = updateSearch()
@@ -185,7 +190,7 @@ class FileSearchPopup(
185190
// Layout components
186191
contentPanel.add(searchField, BorderLayout.NORTH)
187192
contentPanel.add(JScrollPane(fileList), BorderLayout.CENTER)
188-
contentPanel.preferredSize = Dimension(400, 300)
193+
contentPanel.preferredSize = minPopupSize
189194
}
190195

191196
private fun updateFileList(searchText: String) {
@@ -203,16 +208,21 @@ class FileSearchPopup(
203208
filteredFiles.forEach { fileListModel.addElement(it) }
204209
}
205210

206-
fun show(component: Component) {
211+
fun show(component: JComponent) {
207212
popup = JBPopupFactory.getInstance()
208213
.createComponentPopupBuilder(contentPanel, searchField)
209214
.setTitle("Search Files")
210215
.setMovable(true)
211216
.setResizable(true)
212217
.setRequestFocus(true)
218+
.setFocusable(true)
219+
.setMinSize(minPopupSize)
213220
.createPopup()
214221

215-
popup?.showUnderneathOf(component)
222+
val topOffset = (component.border?.getBorderInsets(component)?.top ?: 0)
223+
val leftOffset = (component.border?.getBorderInsets(component)?.left ?: 0)
224+
225+
popup?.show(RelativePoint(component, Point(leftOffset, -minPopupSize.height + topOffset)))
216226
}
217227

218228
data class FileItem(val file: VirtualFile) {
@@ -234,15 +244,23 @@ class FileSearchPopup(
234244
): Component {
235245
val panel = JPanel(BorderLayout())
236246
value?.let {
247+
// Create a panel with horizontal layout to display file name and path inline
248+
val infoPanel = JPanel()
249+
infoPanel.layout = BoxLayout(infoPanel, BoxLayout.X_AXIS)
250+
infoPanel.isOpaque = false
251+
252+
// File name with icon
237253
val fileLabel = JBLabel(it.name, it.icon, JBLabel.LEFT)
238-
val pathLabel = JBLabel(it.path, JBLabel.LEFT)
254+
fileLabel.border = JBUI.Borders.emptyRight(8)
255+
256+
// Path with smaller, grayed-out text
257+
val pathLabel = JBLabel(" - ${getRelativePath(it)}", JBLabel.LEFT)
239258
pathLabel.font = UIUtil.getFont(UIUtil.FontSize.SMALL, pathLabel.font)
240259
pathLabel.foreground = UIUtil.getContextHelpForeground()
241260

242-
val infoPanel = JPanel(BorderLayout())
243-
infoPanel.add(fileLabel, BorderLayout.NORTH)
244-
infoPanel.add(pathLabel, BorderLayout.SOUTH)
245-
infoPanel.isOpaque = false
261+
infoPanel.add(fileLabel)
262+
infoPanel.add(pathLabel)
263+
infoPanel.add(Box.createHorizontalGlue()) // This makes the layout adapt to width
246264

247265
panel.add(infoPanel, BorderLayout.CENTER)
248266

@@ -263,6 +281,16 @@ class FileSearchPopup(
263281

264282
return panel
265283
}
284+
285+
private fun getRelativePath(item: FileItem): String {
286+
// Try to make the path shorter for display purposes
287+
return try {
288+
val basePath = item.path.substringBeforeLast(item.name, "")
289+
if (basePath.isEmpty()) item.path else basePath
290+
} catch (e: Exception) {
291+
item.path
292+
}
293+
}
266294
}
267295
}
268296

@@ -382,3 +410,4 @@ class WrapLayout : FlowLayout {
382410
}
383411
}
384412
}
413+

0 commit comments

Comments
 (0)