@@ -32,23 +32,10 @@ import com.intellij.openapi.ui.SimpleToolWindowPanel
3232import com.intellij.openapi.vfs.LocalFileSystem
3333import com.intellij.psi.PsiDocumentManager
3434import com.intellij.psi.PsiManager
35- import com.intellij.ui.OnePixelSplitter
3635import com.intellij.ui.ScrollPaneFactory
37- import com.intellij.ui.components.JBLabel
38- import com.intellij.ui.components.JBPanel
39- import com.intellij.ui.components.JBScrollPane
4036import com.intellij.ui.treeStructure.Tree
41- import com.intellij.util.ui.JBUI
42- import com.intellij.util.ui.UIUtil
43- import com.skydoves.compose.stability.idea.settings.StabilitySettingsState
44- import com.skydoves.compose.stability.runtime.ParameterStability
4537import org.jetbrains.kotlin.psi.KtNamedFunction
46- import java.awt.Color
47- import java.awt.Font
48- import java.awt.GridBagConstraints
49- import java.awt.GridBagLayout
5038import javax.swing.JComponent
51- import javax.swing.JPanel
5239import javax.swing.tree.DefaultMutableTreeNode
5340import javax.swing.tree.DefaultTreeModel
5441
@@ -58,13 +45,9 @@ import javax.swing.tree.DefaultTreeModel
5845 */
5946internal class CascadePanel (private val project : Project ) {
6047
61- private val settings: StabilitySettingsState
62- get() = StabilitySettingsState .getInstance()
63-
6448 private val tree: Tree
6549 private val treeModel: DefaultTreeModel
6650 private val rootNode: DefaultMutableTreeNode
67- private val detailsPanel: JPanel
6851 private var currentFunction: KtNamedFunction ? = null
6952
7053 init {
@@ -76,14 +59,6 @@ internal class CascadePanel(private val project: Project) {
7659 tree.isRootVisible = false
7760 tree.showsRootHandles = true
7861
79- detailsPanel = createDetailsPanel()
80-
81- // Selection listener for details
82- tree.addTreeSelectionListener { event ->
83- val node = event.path.lastPathComponent as ? DefaultMutableTreeNode
84- updateDetailsPanel(node)
85- }
86-
8762 // Double-click to navigate to source
8863 tree.addMouseListener(object : java.awt.event.MouseAdapter () {
8964 override fun mouseClicked (e : java.awt.event.MouseEvent ) {
@@ -108,12 +83,7 @@ internal class CascadePanel(private val project: Project) {
10883 val toolbar = createToolbar()
10984 mainPanel.toolbar = toolbar
11085
111- // Create split pane with tree and details
112- val splitter = OnePixelSplitter (false , 0.65f )
113- splitter.firstComponent = ScrollPaneFactory .createScrollPane(tree)
114- splitter.secondComponent = JBScrollPane (detailsPanel)
115-
116- mainPanel.setContent(splitter)
86+ mainPanel.setContent(ScrollPaneFactory .createScrollPane(tree))
11787
11888 return mainPanel
11989 }
@@ -232,200 +202,6 @@ internal class CascadePanel(private val project: Project) {
232202 }
233203 }
234204
235- private fun createDetailsPanel (): JPanel {
236- val panel = JBPanel <JBPanel <* >>(GridBagLayout ())
237- panel.border = JBUI .Borders .empty(10 )
238-
239- val gbc = GridBagConstraints ()
240- gbc.gridx = 0
241- gbc.gridy = 0
242- gbc.anchor = GridBagConstraints .NORTHWEST
243- gbc.fill = GridBagConstraints .HORIZONTAL
244- gbc.weightx = 1.0
245-
246- val label = JBLabel (" Select a composable to view details" )
247- label.foreground = UIUtil .getInactiveTextColor()
248- panel.add(label, gbc)
249-
250- return panel
251- }
252-
253- private fun updateDetailsPanel (node : DefaultMutableTreeNode ? ) {
254- detailsPanel.removeAll()
255- detailsPanel.layout = GridBagLayout ()
256-
257- val gbc = GridBagConstraints ()
258- gbc.gridx = 0
259- gbc.gridy = 0
260- gbc.anchor = GridBagConstraints .NORTHWEST
261- gbc.fill = GridBagConstraints .HORIZONTAL
262- gbc.weightx = 1.0
263- gbc.insets = JBUI .insets(5 )
264-
265- when (val data = node?.userObject) {
266- is CascadeTreeNodeData .Composable -> {
267- val info = data.node.stabilityInfo
268- val hasUnstable = info.parameters.any {
269- it.stability == ParameterStability .UNSTABLE
270- }
271- val hasRuntime = info.parameters.any {
272- it.stability == ParameterStability .RUNTIME
273- }
274- val isRuntimeOnly = ! info.isSkippable && ! hasUnstable && hasRuntime
275-
276- // Title
277- addDetailRow(detailsPanel, gbc, " Composable:" , info.name, bold = true )
278-
279- // Stability status
280- val statusText = when {
281- info.isSkippable -> " STABLE (Skippable)"
282- isRuntimeOnly -> " RUNTIME (Determined at runtime)"
283- else -> " UNSTABLE (Non-skippable)"
284- }
285- val statusColor = when {
286- info.isSkippable -> Color (settings.stableGutterColorRGB)
287- isRuntimeOnly -> Color (settings.runtimeGutterColorRGB)
288- else -> Color (settings.unstableGutterColorRGB)
289- }
290- addDetailRow(detailsPanel, gbc, " Status:" , statusText, color = statusColor)
291-
292- // Restartable
293- addDetailRow(
294- detailsPanel,
295- gbc,
296- " Restartable:" ,
297- if (info.isRestartable) " Yes" else " No" ,
298- )
299-
300- // Depth
301- addDetailRow(detailsPanel, gbc, " Depth:" , " ${data.node.depth} " )
302-
303- // Parameters
304- if (info.parameters.isNotEmpty()) {
305- gbc.gridy++
306- val headerLabel = JBLabel (" Parameters:" )
307- headerLabel.font = headerLabel.font.deriveFont(Font .BOLD )
308- detailsPanel.add(headerLabel, gbc)
309-
310- info.parameters.forEach { param ->
311- gbc.gridy++
312- val paramText = " ${param.name} : ${param.type} "
313- val paramStatus = when (param.stability) {
314- ParameterStability .STABLE -> " Stable"
315- ParameterStability .RUNTIME -> " Runtime"
316- ParameterStability .UNSTABLE -> " Unstable"
317- }
318- val paramColor = when (param.stability) {
319- ParameterStability .STABLE -> Color (settings.stableHintColorRGB)
320- ParameterStability .RUNTIME -> Color (settings.runtimeHintColorRGB)
321- ParameterStability .UNSTABLE -> Color (settings.unstableHintColorRGB)
322- }
323- addDetailRow(detailsPanel, gbc, " $paramText " , paramStatus, color = paramColor)
324-
325- // Show reason if available
326- if (param.reason != null ) {
327- gbc.gridy++
328- val reasonLabel = JBLabel (" Reason: ${param.reason} " )
329- reasonLabel.foreground = UIUtil .getInactiveTextColor()
330- detailsPanel.add(reasonLabel, gbc)
331- }
332- }
333- }
334-
335- // Location
336- gbc.gridy++
337- val fileName = data.node.filePath.substringAfterLast(' /' )
338- addDetailRow(detailsPanel, gbc, " File:" , " $fileName :${data.node.line} " )
339-
340- // Navigation hint
341- gbc.gridy++
342- val navigateLabel = JBLabel (" Double-click to navigate to source" )
343- navigateLabel.foreground = UIUtil .getInactiveTextColor()
344- detailsPanel.add(navigateLabel, gbc)
345- }
346-
347- is CascadeTreeNodeData .Summary -> {
348- addDetailRow(
349- detailsPanel,
350- gbc,
351- " Root Composable:" ,
352- data.composableName,
353- bold = true ,
354- )
355- addDetailRow(
356- detailsPanel,
357- gbc,
358- " Total Downstream:" ,
359- " ${data.summary.totalCount} " ,
360- )
361- addDetailRow(
362- detailsPanel,
363- gbc,
364- " Skippable:" ,
365- " ${data.summary.skippableCount} " ,
366- color = Color (settings.stableGutterColorRGB),
367- )
368- addDetailRow(
369- detailsPanel,
370- gbc,
371- " Unskippable:" ,
372- " ${data.summary.unskippableCount} " ,
373- color = Color (settings.unstableGutterColorRGB),
374- )
375- addDetailRow(
376- detailsPanel,
377- gbc,
378- " Max Depth:" ,
379- " ${data.summary.maxDepth} " ,
380- )
381- if (data.summary.hasTruncatedBranches) {
382- addDetailRow(
383- detailsPanel,
384- gbc,
385- " Note:" ,
386- " Some branches were truncated" ,
387- color = UIUtil .getInactiveTextColor(),
388- )
389- }
390- }
391-
392- else -> {
393- val label = JBLabel (" Select a composable to view details" )
394- label.foreground = UIUtil .getInactiveTextColor()
395- detailsPanel.add(label, gbc)
396- }
397- }
398-
399- // Filler at the bottom
400- gbc.gridy++
401- gbc.weighty = 1.0
402- detailsPanel.add(JPanel (), gbc)
403-
404- detailsPanel.revalidate()
405- detailsPanel.repaint()
406- }
407-
408- private fun addDetailRow (
409- panel : JPanel ,
410- gbc : GridBagConstraints ,
411- label : String ,
412- value : String ,
413- bold : Boolean = false,
414- color : Color ? = null,
415- ) {
416- gbc.gridy++
417-
418- val fullLabel = JBLabel (" $label $value " )
419- if (bold) {
420- fullLabel.font = fullLabel.font.deriveFont(Font .BOLD )
421- }
422- if (color != null ) {
423- fullLabel.foreground = color
424- }
425-
426- panel.add(fullLabel, gbc)
427- }
428-
429205 /* *
430206 * Refresh action - re-analyzes the current function.
431207 */
@@ -457,7 +233,6 @@ internal class CascadePanel(private val project: Project) {
457233 override fun actionPerformed (e : AnActionEvent ) {
458234 currentFunction = null
459235 showEmptyState()
460- updateDetailsPanel(null )
461236 }
462237 }
463238}
0 commit comments