Skip to content

Commit

Permalink
feat: align for input ui
Browse files Browse the repository at this point in the history
  • Loading branch information
phodal committed Aug 3, 2023
1 parent 4874767 commit 7543b15
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 4 deletions.
122 changes: 122 additions & 0 deletions src/main/kotlin/cc/unitmesh/devti/gui/chat/AutoDevCoolBorder.kt
@@ -0,0 +1,122 @@
package cc.unitmesh.devti.gui.chat

import com.intellij.ide.ui.laf.darcula.DarculaUIUtil
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ex.EditorEx
import com.intellij.openapi.editor.ex.FocusChangeListener
import com.intellij.openapi.ui.ErrorBorderCapable
import com.intellij.ui.scale.JBUIScale
import com.intellij.util.ObjectUtils
import com.intellij.util.ui.JBInsets
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.MacUIUtil
import com.intellij.util.ui.UIUtil
import java.awt.*
import java.awt.geom.Path2D
import java.awt.geom.Rectangle2D
import javax.swing.JComponent
import javax.swing.border.Border

class AutoDevCoolBorder(private val editor: EditorEx, parent: JComponent) : Border, ErrorBorderCapable {
init {
editor.addFocusListener(object : FocusChangeListener {
override fun focusGained(editor2: Editor) {
parent.repaint()
}

override fun focusLost(editor2: Editor) {
parent.repaint()
}
})
}

override fun paintBorder(c: Component, g: Graphics, x: Int, y: Int, width: Int, height: Int) {
val hasFocus = editor.contentComponent.hasFocus()
val r = Rectangle(x, y, width, height)
val g2 = g.create() as Graphics2D
try {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g2.setRenderingHint(
RenderingHints.KEY_STROKE_CONTROL,
if (MacUIUtil.USE_QUARTZ) RenderingHints.VALUE_STROKE_PURE else RenderingHints.VALUE_STROKE_NORMALIZE
)
JBInsets.removeFrom(r, JBUI.insets(1))
g2.translate(r.x, r.y)
val bw = DarculaUIUtil.BW.float
val shape: Shape = Rectangle2D.Float(bw, bw, r.width - bw * 2, r.height - bw * 2)
g2.color = c.getBackground()
g2.fill(shape)
if (editor.contentComponent.isEnabled && editor.contentComponent.isVisible) {
val op = getOutline((c as JComponent))
if (op == null) {
g2.color = if (hasFocus) JBUI.CurrentTheme.Focus.focusColor() else DarculaUIUtil.getOutlineColor(
editor.contentComponent.isEnabled,
false
)
} else {
op.setGraphicsColor(g2, hasFocus)
}
doPaint(g2, r.width, r.height, 5.0f, if (hasFocus) 1.0f else 0.5f, true)
}
} finally {
g2.dispose()
}
}

override fun getBorderInsets(c: Component): Insets {
return JBInsets.create(6, 8).asUIResource()
}

override fun isBorderOpaque(): Boolean {
return true
}
}

fun getOutline(component: JComponent): DarculaUIUtil.Outline? {
val outline = ObjectUtils.tryCast(component.getClientProperty("JComponent.outline"), String::class.java)
return if (outline == null) null else DarculaUIUtil.Outline.valueOf(outline)
}

fun doPaint(g: Graphics2D, width: Int, height: Int, arc: Float, bw: Float, symmetric: Boolean) {
var bw = bw
val f = if (UIUtil.isRetina(g)) 0.5f else 1.0f
val lw = if (UIUtil.isUnderDefaultMacTheme()) JBUIScale.scale(f) else DarculaUIUtil.LW.float
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g.setRenderingHint(
RenderingHints.KEY_STROKE_CONTROL,
if (MacUIUtil.USE_QUARTZ) RenderingHints.VALUE_STROKE_PURE else RenderingHints.VALUE_STROKE_NORMALIZE
)
val outerArc = if (arc > 0) arc + bw - JBUIScale.scale(2f) else bw
val rightOuterArc = if (symmetric) outerArc else JBUIScale.scale(6f)
val outerRect: Path2D = Path2D.Float(Path2D.WIND_EVEN_ODD)
outerRect.moveTo((width - rightOuterArc).toDouble(), 0.0)
outerRect.quadTo(width.toDouble(), 0.0, width.toDouble(), rightOuterArc.toDouble())
outerRect.lineTo(width.toDouble(), (height - rightOuterArc).toDouble())
outerRect.quadTo(width.toDouble(), height.toDouble(), (width - rightOuterArc).toDouble(), height.toDouble())
outerRect.lineTo(outerArc.toDouble(), height.toDouble())
outerRect.quadTo(0.0, height.toDouble(), 0.0, (height - outerArc).toDouble())
outerRect.lineTo(0.0, outerArc.toDouble())
outerRect.quadTo(0.0, 0.0, outerArc.toDouble(), 0.0)
outerRect.closePath()
bw += lw
val rightInnerArc = if (symmetric) outerArc else JBUIScale.scale(7f)
val innerRect: Path2D = Path2D.Float(Path2D.WIND_EVEN_ODD)
innerRect.moveTo((width - rightInnerArc).toDouble(), bw.toDouble())
innerRect.quadTo((width - bw).toDouble(), bw.toDouble(), (width - bw).toDouble(), rightInnerArc.toDouble())
innerRect.lineTo((width - bw).toDouble(), (height - rightInnerArc).toDouble())
innerRect.quadTo(
(width - bw).toDouble(),
(height - bw).toDouble(),
(width - rightInnerArc).toDouble(),
(height - bw).toDouble()
)
innerRect.lineTo(outerArc.toDouble(), (height - bw).toDouble())
innerRect.quadTo(bw.toDouble(), (height - bw).toDouble(), bw.toDouble(), (height - outerArc).toDouble())
innerRect.lineTo(bw.toDouble(), outerArc.toDouble())
innerRect.quadTo(bw.toDouble(), bw.toDouble(), outerArc.toDouble(), bw.toDouble())
innerRect.closePath()
val path: Path2D = Path2D.Float(Path2D.WIND_EVEN_ODD)
path.append(outerRect, false)
path.append(innerRect, false)
g.fill(path)
}
1 change: 1 addition & 0 deletions src/main/kotlin/cc/unitmesh/devti/gui/chat/AutoDevInput.kt
Expand Up @@ -152,6 +152,7 @@ class AutoDevInputField(

initializeDocumentListeners(inputDocument)
setDocument(inputDocument)
inputSection.initEditor()
}

private fun initializeDocumentListeners(inputDocument: Document) {
Expand Down
25 changes: 23 additions & 2 deletions src/main/kotlin/cc/unitmesh/devti/gui/chat/AutoDevInputSection.kt
Expand Up @@ -2,13 +2,13 @@ package cc.unitmesh.devti.gui.chat

import cc.unitmesh.devti.AutoDevBundle
import cc.unitmesh.devti.AutoDevIcons
import cc.unitmesh.devti.provider.ContextPrompter
import com.intellij.openapi.Disposable
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.Presentation
import com.intellij.openapi.actionSystem.impl.ActionButton
import com.intellij.openapi.editor.event.DocumentEvent
import com.intellij.openapi.editor.event.DocumentListener
import com.intellij.openapi.editor.ex.EditorEx
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.wm.IdeFocusManager
Expand All @@ -21,7 +21,6 @@ import com.intellij.util.ui.components.BorderLayoutPanel
import java.awt.Color
import java.awt.Component
import java.awt.Dimension
import java.awt.event.ActionEvent
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import javax.swing.Box
Expand Down Expand Up @@ -95,8 +94,30 @@ class AutoDevInputSection(
borderLayoutPanel.addToCenter(horizontalGlue)
borderLayoutPanel.addToRight(button)
addToBottom(borderLayoutPanel)

addListener(object : AutoDevInputListener {
override fun editorAdded(editor: EditorEx) {
this@AutoDevInputSection.initEditor()
}
})

}

fun initEditor() {
val editorEx = when (this.input.editor) {
is EditorEx -> this.input.editor
else -> null
} ?: return

val jComponent = this as JComponent

setBorder(AutoDevCoolBorder(editorEx as EditorEx, jComponent))
UIUtil.forEachComponentInHierarchy(jComponent) { component: Component ->
(component as JComponent).setOpaque(false)
}
}


override fun getPreferredSize(): Dimension {
val result = super.getPreferredSize()
result.height = max(min(result.height, maxHeight), minimumSize.height)
Expand Down
3 changes: 1 addition & 2 deletions src/main/resources/messages/AutoDevBundle.properties
Expand Up @@ -10,8 +10,7 @@ devti.progress.updatingEndpointMethod=Updating endpoint (Controller) method (4/5
devti.progress.creatingServiceAndRepository=Create Service and Repository (5/5)
# Config
autodev.flow=AutoDev Flow
# Chat
devti.chat.clear=Clear Chat

devti.chat.send=Send
devti.chat.replaceSelection=Replace Selection
devti.loading=Loading...
Expand Down

0 comments on commit 7543b15

Please sign in to comment.