refactor(jetbrains): drop Align shorthand helpers, keep only align(h, v)

This commit is contained in:
kirillk
2026-05-22 13:47:24 -04:00
parent dcfa1029c3
commit 20214bbfe9
5 changed files with 41 additions and 66 deletions
+6 -11
View File
@@ -384,23 +384,18 @@ Use `Align` (`ai.kilocode.client.ui.Align`) when a single Swing component must b
"Bounded preferred" means the child's preferred size coerced into the effective `[min, max]` range. If available space is smaller than the effective minimum, the layout shrinks the child to available space to avoid overflow.
**Kotlin-style factory extensions** on `Component`:
**Factory extension** on `Component`:
```kotlin
child.align(HAlign.LEFT, VAlign.TOP) // explicit modes
child.alignCenter() // CENTER / CENTER (replaces CenterShrinkPanel)
child.alignLeft(VAlign.CENTER) // LEFT + custom V
child.alignRight(VAlign.CENTER) // RIGHT + custom V
child.alignTop(HAlign.CENTER) // TOP + custom H
child.alignBottom() // BOTTOM + FIT horizontal
child.track() // TRACK / TRACK — always fills all space
child.trackX(VAlign.TOP) // TRACK horizontal, TOP vertical
child.trackY(HAlign.CENTER) // CENTER horizontal, TRACK vertical
child.align(HAlign.LEFT, VAlign.TOP) // left-aligned, top-pinned
child.align(HAlign.CENTER, VAlign.CENTER) // centered (replaces CenterShrinkPanel)
child.align(HAlign.TRACK, VAlign.CENTER) // fill width, center vertically
child.align(HAlign.TRACK, VAlign.TRACK) // fill all available space
```
**Rules:**
- Prefer the factory extensions over creating one-off `JPanel(FlowLayout(...))` or `BorderLayoutPanel` wrappers just to control alignment.
- Prefer `child.align(h, v)` over creating one-off `JPanel(FlowLayout(...))` or `BorderLayoutPanel` wrappers just to control alignment.
- Use `TRACK` when the child must occupy all available space on an axis and must not reserve any space in the parent's size negotiation on that axis. Use `FIT` when you want to fill available space but still respect child min/max constraints.
- All non-TRACK modes include the child's min, preferred, and max sizes in the wrapper's own min/preferred/max size. This means parent layout managers see the child constraints through the wrapper.
- Do not use `Align` for spacing, padding, borders, colors, or multi-child layout — use `JBUI.Borders.empty(...)`, `UiStyle.Gap`, or an appropriate layout manager for those concerns.
@@ -11,8 +11,10 @@ import ai.kilocode.client.session.ui.style.SessionEditorStyleTarget
import ai.kilocode.client.session.ui.style.SessionUiStyle
import ai.kilocode.client.session.controller.SessionController
import ai.kilocode.client.ui.Align
import ai.kilocode.client.ui.HAlign
import ai.kilocode.client.ui.UiStyle
import ai.kilocode.client.ui.alignCenter
import ai.kilocode.client.ui.VAlign
import ai.kilocode.client.ui.align
import ai.kilocode.rpc.dto.SessionDto
import com.intellij.icons.AllIcons
import com.intellij.openapi.Disposable
@@ -53,7 +55,7 @@ class EmptySessionPanel(
recents: List<SessionDto>,
private val history: () -> Unit = {},
) : BorderLayoutPanel(), Disposable, SessionEditorStyleTarget {
val view: Align = alignCenter()
val view: Align = align(HAlign.CENTER, VAlign.CENTER)
private val model = DefaultListModel<LocalHistoryItem>()
private var hover = -1
@@ -134,7 +136,7 @@ class EmptySessionPanel(
val header = BorderLayoutPanel(0, gap).apply {
isOpaque = false
add(logo, BorderLayout.NORTH)
add(description.alignCenter(), BorderLayout.CENTER)
add(description.align(HAlign.CENTER, VAlign.CENTER), BorderLayout.CENTER)
}
val recent = BorderLayoutPanel().apply {
@@ -10,7 +10,10 @@ import ai.kilocode.client.session.ui.style.SessionEditorStyle
import ai.kilocode.client.session.ui.style.SessionEditorStyleTarget
import ai.kilocode.client.session.ui.style.SessionUiStyle
import ai.kilocode.client.session.ui.style.SessionUiStyle.View.CARD_LAYOUT_GAP
import ai.kilocode.client.ui.HAlign
import ai.kilocode.client.ui.UiStyle
import ai.kilocode.client.ui.VAlign
import ai.kilocode.client.ui.align
import ai.kilocode.rpc.dto.PermissionReplyDto
import com.intellij.icons.AllIcons
import com.intellij.ui.ColorUtil
@@ -25,7 +28,6 @@ import java.awt.BorderLayout
import java.awt.Component
import java.awt.FlowLayout
import javax.swing.BoxLayout
import javax.swing.JComponent
import javax.swing.JPanel
import javax.swing.text.html.StyleSheet
@@ -128,37 +130,30 @@ class PermissionView(
val actionLbl = JBLabel(action).apply {
font = UiStyle.Fonts.bold()
alignmentY = Component.CENTER_ALIGNMENT
}
row.add(actionLbl, BorderLayout.WEST)
row.add(actionLbl.align(HAlign.LEFT, VAlign.CENTER), BorderLayout.WEST)
if (!target.isNullOrBlank()) {
val pane = targetPane(target)
panes.add(pane)
row.add(pane, BorderLayout.CENTER)
row.add(pane.align(HAlign.TRACK, VAlign.CENTER), BorderLayout.CENTER)
}
if (diffs.isNotEmpty()) {
val changes = JPanel(FlowLayout(FlowLayout.CENTER, 0, 0)).apply {
val changes = JPanel(FlowLayout(FlowLayout.LEFT, 0, 0)).apply {
isOpaque = false
alignmentY = Component.CENTER_ALIGNMENT
}
for (diff in diffs) {
val dv = PermissionDiffView(diff)
diffViews.add(dv)
changes.add(dv)
}
row.add(changes, BorderLayout.EAST)
row.add(changes.align(HAlign.RIGHT, VAlign.CENTER), BorderLayout.EAST)
}
body.add(row)
}
private fun JComponent.withGap(left: Int, right: Boolean) = JBUI.Panels.simplePanel(this).apply {
isOpaque = false
border = JBUI.Borders.empty(0, left, 0, if (right) UiStyle.Gap.sm() else 0)
}
private fun targetPane(text: String) = JBHtmlPane(
JBHtmlPaneStyleConfiguration {},
JBHtmlPaneConfiguration {
@@ -23,13 +23,12 @@ enum class VAlign { TRACK, FIT, TOP, CENTER, BOTTOM }
* Wrapper min/preferred/max sizes are computed by combining the per-axis child contribution
* (zero for TRACK axes) with the panel insets.
*
* Use the Kotlin-style factory extensions for concise call sites:
* Use the factory extension for concise call sites:
* ```
* label.alignCenter()
* button.alignRight(VAlign.CENTER)
* label.align(HAlign.CENTER, VAlign.CENTER)
* button.align(HAlign.RIGHT, VAlign.CENTER)
* panel.align(HAlign.LEFT, VAlign.TOP)
* content.track()
* scrollable.trackX(VAlign.TOP)
* scrollable.align(HAlign.TRACK, VAlign.TOP)
* ```
*/
class Align(
@@ -130,23 +129,7 @@ private fun placeAxis(mode: Any, avail: Int, min: Int, pref: Int, max: Int): Pai
private fun bounded(value: Int, min: Int, max: Int) = value.coerceIn(min, maxOf(min, max))
// ---------------------------------------------------------------------------
// Kotlin-style factory extensions
// Factory extension
// ---------------------------------------------------------------------------
fun Component.align(h: HAlign = HAlign.FIT, v: VAlign = VAlign.FIT) = Align(this, h, v)
fun Component.alignCenter() = Align(this, HAlign.CENTER, VAlign.CENTER)
fun Component.alignLeft(v: VAlign = VAlign.FIT) = Align(this, HAlign.LEFT, v)
fun Component.alignRight(v: VAlign = VAlign.FIT) = Align(this, HAlign.RIGHT, v)
fun Component.alignTop(h: HAlign = HAlign.FIT) = Align(this, h, VAlign.TOP)
fun Component.alignBottom(h: HAlign = HAlign.FIT) = Align(this, h, VAlign.BOTTOM)
fun Component.track() = Align(this, HAlign.TRACK, VAlign.TRACK)
fun Component.trackX(v: VAlign = VAlign.FIT) = Align(this, HAlign.TRACK, v)
fun Component.trackY(h: HAlign = HAlign.FIT) = Align(this, h, VAlign.TRACK)
fun Component.align(h: HAlign, v: VAlign) = Align(this, h, v)
@@ -298,56 +298,56 @@ class AlignTest : BasePlatformTestCase() {
assertEquals(30 + ins.top + ins.bottom, ps.height)
}
// ------ factory helpers ------
// ------ align() factory ------
fun `test align extension returns Align wrapping child`() {
val child = JBLabel("x")
assertSame(child, child.align(HAlign.LEFT, VAlign.TOP).getComponent(0))
}
fun `test alignCenter produces CENTER CENTER`() {
fun `test align CENTER CENTER produces centered layout`() {
val child = child(pref = 40 x 20)
val wrap = child.alignCenter()
val wrap = child.align(HAlign.CENTER, VAlign.CENTER)
wrap.setBounds(0, 0, 200, 100)
wrap.doLayout()
assertBounds(80, 40, 40, 20, child)
}
fun `test alignRight produces RIGHT with given VAlign`() {
fun `test align RIGHT TOP positions at top-right`() {
val child = child(pref = 40 x 20)
val wrap = child.alignRight(VAlign.TOP)
val wrap = child.align(HAlign.RIGHT, VAlign.TOP)
wrap.setBounds(0, 0, 200, 100)
wrap.doLayout()
assertBounds(160, 0, 40, 20, child)
}
fun `test alignLeft with default FIT vertical fills height`() {
fun `test align LEFT FIT fills height`() {
val child = child(pref = 40 x 20)
val wrap = child.alignLeft()
val wrap = child.align(HAlign.LEFT, VAlign.FIT)
wrap.setBounds(0, 0, 200, 100)
wrap.doLayout()
assertBounds(0, 0, 40, 100, child)
}
fun `test alignTop with CENTER horizontal centers and pins to top`() {
fun `test align CENTER TOP centers horizontally and pins to top`() {
val child = child(pref = 40 x 20)
val wrap = child.alignTop(HAlign.CENTER)
val wrap = child.align(HAlign.CENTER, VAlign.TOP)
wrap.setBounds(0, 0, 200, 100)
wrap.doLayout()
assertBounds(80, 0, 40, 20, child)
}
fun `test alignBottom with default FIT horizontal fills width and pins to bottom`() {
fun `test align FIT BOTTOM fills width and pins to bottom`() {
val child = child(pref = 40 x 20)
val wrap = child.alignBottom()
val wrap = child.align(HAlign.FIT, VAlign.BOTTOM)
wrap.setBounds(0, 0, 200, 100)
wrap.doLayout()
assertBounds(0, 80, 200, 20, child)
}
fun `test track fills all space and wrapper preferred is inset-only`() {
fun `test align TRACK TRACK fills all space and wrapper preferred is inset-only`() {
val child = child(pref = 40 x 20, max = 60 x 30)
val wrap = child.track()
val wrap = child.align(HAlign.TRACK, VAlign.TRACK)
wrap.setBounds(0, 0, 200, 100)
wrap.doLayout()
assertBounds(0, 0, 200, 100, child)
@@ -356,17 +356,17 @@ class AlignTest : BasePlatformTestCase() {
assertEquals(ins.top + ins.bottom, wrap.preferredSize.height)
}
fun `test trackX fills width only, V respects preferred`() {
fun `test align TRACK TOP fills width only, V respects preferred`() {
val child = child(pref = 40 x 20)
val wrap = child.trackX(VAlign.TOP)
val wrap = child.align(HAlign.TRACK, VAlign.TOP)
wrap.setBounds(0, 0, 200, 100)
wrap.doLayout()
assertBounds(0, 0, 200, 20, child)
}
fun `test trackY fills height only, H respects preferred`() {
fun `test align CENTER TRACK fills height only, H respects preferred`() {
val child = child(pref = 40 x 20)
val wrap = child.trackY(HAlign.CENTER)
val wrap = child.align(HAlign.CENTER, VAlign.TRACK)
wrap.setBounds(0, 0, 200, 100)
wrap.doLayout()
assertBounds(80, 0, 40, 100, child)