1
1
package cc.unitmesh.devti.gui.planner
2
2
3
+ import cc.unitmesh.devti.inline.AutoDevLineBorder
3
4
import cc.unitmesh.devti.util.relativePath
4
5
import com.intellij.icons.AllIcons
6
+ import com.intellij.openapi.actionSystem.ActionToolbar
7
+ import com.intellij.openapi.actionSystem.AnAction
8
+ import com.intellij.openapi.actionSystem.AnActionEvent
9
+ import com.intellij.openapi.actionSystem.impl.ActionButton
5
10
import com.intellij.openapi.fileEditor.FileEditorManager
6
11
import com.intellij.openapi.project.Project
7
12
import com.intellij.openapi.vcs.changes.Change
8
13
import com.intellij.openapi.vcs.changes.ui.RollbackWorker
9
14
import com.intellij.ui.HyperlinkLabel
15
+ import com.intellij.ui.JBColor
10
16
import com.intellij.ui.components.JBLabel
11
17
import com.intellij.ui.components.JBScrollPane
12
18
import com.intellij.util.ui.JBUI
13
19
import com.intellij.util.ui.UIUtil
20
+ import io.modelcontextprotocol.kotlin.sdk.UnknownReference
21
+ import org.jetbrains.annotations.NotNull
14
22
import java.awt.BorderLayout
15
23
import java.awt.FlowLayout
16
24
import java.awt.GridLayout
17
- import javax.swing.Box
18
- import javax.swing.BoxLayout
19
- import javax.swing.Icon
20
- import javax.swing.JButton
21
- import javax.swing.JPanel
25
+ import java.awt.event.ActionEvent
26
+ import java.awt.event.FocusEvent
27
+ import java.awt.event.FocusListener
28
+ import java.awt.event.KeyEvent
29
+ import java.beans.PropertyChangeEvent
30
+ import java.beans.PropertyChangeListener
31
+ import javax.swing.*
32
+ import javax.swing.border.Border
22
33
import javax.swing.event.HyperlinkEvent
23
34
import javax.swing.event.HyperlinkListener
24
35
@@ -189,10 +200,10 @@ class PlannerResultSummary(
189
200
}
190
201
})
191
202
}
192
-
203
+
193
204
add(fileLabel)
194
205
add(Box .createHorizontalStrut(5 ))
195
-
206
+
196
207
val pathLabel = JBLabel (filePath).apply {
197
208
foreground = UIUtil .getLabelDisabledForeground()
198
209
toolTipText = filePath
@@ -205,15 +216,14 @@ class PlannerResultSummary(
205
216
preferredSize = JBUI .size(100 , preferredSize.height)
206
217
maximumSize = JBUI .size(Int .MAX_VALUE , preferredSize.height)
207
218
}
208
-
219
+
209
220
add(pathLabel)
210
221
add(Box .createHorizontalGlue()) // This pushes the action buttons to the right
211
-
212
- // Action buttons
222
+
213
223
val actionsPanel = JPanel ().apply {
214
224
isOpaque = false
215
225
layout = BoxLayout (this , BoxLayout .X_AXIS )
216
-
226
+
217
227
val viewButton = createActionButton(
218
228
AllIcons .Actions .Preview ,
219
229
" View changes"
@@ -228,7 +238,7 @@ class PlannerResultSummary(
228
238
add(Box .createHorizontalStrut(2 ))
229
239
add(discardButton)
230
240
}
231
-
241
+
232
242
add(actionsPanel)
233
243
}
234
244
}
@@ -237,14 +247,66 @@ class PlannerResultSummary(
237
247
icon : Icon ,
238
248
tooltip : String ,
239
249
action : () -> Unit
240
- ): JButton = JButton ().apply {
241
- this .icon = icon
242
- toolTipText = tooltip
243
- isBorderPainted = false
244
- isContentAreaFilled = false
245
- isFocusPainted = false
246
- margin = JBUI .emptyInsets()
247
- preferredSize = JBUI .size(20 , 20 )
248
- addActionListener { action() }
250
+ ): JComponent {
251
+ val anAction = object : AnAction (tooltip, tooltip, icon) {
252
+ override fun actionPerformed (e : AnActionEvent ) {
253
+ action()
254
+ }
255
+ }
256
+ return KeyboardAccessibleActionButton (anAction)
257
+ }
258
+
259
+ private class KeyboardAccessibleActionButton (@NotNull action : AnAction ) : ActionButton(
260
+ action,
261
+ action.templatePresentation.clone(),
262
+ " unknown" ,
263
+ ActionToolbar .DEFAULT_MINIMUM_BUTTON_SIZE
264
+ ) {
265
+ init {
266
+ isFocusable = true
267
+ inputMap.put(KeyStroke .getKeyStroke(" ENTER" ), " executeAction" )
268
+ actionMap.put(" executeAction" , object : AbstractAction () {
269
+ override fun actionPerformed (e : ActionEvent ) {
270
+ click()
271
+ }
272
+ })
273
+ val focusListener = AccessibleFocusListener ()
274
+ addPropertyChangeListener(" border" , focusListener)
275
+ addFocusListener(focusListener)
276
+ }
277
+
278
+ override fun processKeyEvent (e : KeyEvent ? ) {
279
+ if (e != null && e.keyCode == KeyEvent .VK_ENTER && e.id == KeyEvent .KEY_PRESSED ) {
280
+ click()
281
+ } else {
282
+ super .processKeyEvent(e)
283
+ }
284
+ }
285
+
286
+ private inner class AccessibleFocusListener : FocusListener , PropertyChangeListener {
287
+ private var originalBorder: Border ? = null
288
+ private var focusedBorder: Border ? = null
289
+
290
+ override fun focusGained (e : FocusEvent ? ) {
291
+ val insideBorder = AutoDevLineBorder (JBColor .namedColor(" Focus.borderColor" , JBColor .BLUE ), 1 , true , 4 )
292
+ focusedBorder = BorderFactory .createCompoundBorder(originalBorder, insideBorder)
293
+ border = focusedBorder
294
+ repaint()
295
+ }
296
+
297
+ override fun focusLost (e : FocusEvent ? ) {
298
+ border = originalBorder
299
+ repaint()
300
+ }
301
+
302
+ override fun propertyChange (evt : PropertyChangeEvent ? ) {
303
+ if (originalBorder == null && evt?.propertyName == " border" ) {
304
+ val newBorder = evt.newValue as ? Border
305
+ if (newBorder != null && newBorder != focusedBorder) {
306
+ originalBorder = newBorder
307
+ }
308
+ }
309
+ }
310
+ }
249
311
}
250
312
}
0 commit comments