Another approach to UI composition (IDEA-219212)
authorIvan Migalev <ivan.migalev@jetbrains.com>
Mon, 10 Aug 2020 13:40:04 +0000 (20:40 +0700)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Mon, 10 Aug 2020 15:25:40 +0000 (15:25 +0000)
GitOrigin-RevId: 9f189f476a3a9d9a3751496cc1cdf3db582fe0e9

platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.kt

index 92cc0a8647e2f772efad69c3a8ac22d9902f5fc1..853858475878d9e98beca19412c9706b3a7689a1 100644 (file)
@@ -191,42 +191,46 @@ internal class AppearanceConfigurable : BoundSearchableConfigurable(message("tit
           }
         }
       }
+      @Suppress("MoveLambdaOutsideParentheses") // this suggestion is wrong, see KT-40969
       titledRow(message("group.ui.options")) {
-        val hasMergeMainMenuWithWindowTitleOption = IdeFrameDecorator.isCustomDecorationAvailable()
-        twoPanelRow(
-          {
-            fullRow { checkBox(cdShowTreeIndents) }
-            fullRow { checkBox(cdUseCompactTreeIndents) }
-            fullRow { checkBox(cdEnableMenuMnemonics) }
-            fullRow { checkBox(cdEnableControlsMnemonics) }
-            // The last item migrates here from the right column if the right column has the additional item:
-            if (hasMergeMainMenuWithWindowTitleOption)
-              fullRow { checkBox(cdShowMenuIcons) }
-          },
-          {
-            fullRow {
-              checkBox(cdSmoothScrolling)
-              ContextHelpLabel.create(message("checkbox.smooth.scrolling.description"))()
-            }
-            fullRow { checkBox(cdDnDWithAlt) }
+        val leftColumnControls = sequence<InnerCell.() -> Unit> {
+          yield({ checkBox(cdShowTreeIndents) })
+          yield({ checkBox(cdUseCompactTreeIndents) })
+          yield({ checkBox(cdEnableMenuMnemonics) })
+          yield({ checkBox(cdEnableControlsMnemonics) })
+        }
+        val rightColumnControls = sequence<InnerCell.() -> Unit> {
+          yield({
+                  checkBox(cdSmoothScrolling)
+                  ContextHelpLabel.create(message("checkbox.smooth.scrolling.description"))()
+                })
+          yield({ checkBox(cdDnDWithAlt) })
+          if (IdeFrameDecorator.isCustomDecorationAvailable()) {
+            yield({
+                    val overridden = UISettings.isMergeMainMenuWithWindowTitleOverridden
+                    checkBox(cdMergeMainMenuWithWindowTitle).enabled(!overridden)
+                    if (overridden) {
+                      ContextHelpLabel.create(
+                        message("option.is.overridden.by.jvm.property", UISettings.MERGE_MAIN_MENU_WITH_WINDOW_TITLE_PROPERTY))()
+                    }
+                    commentNoWrap(message("checkbox.merge.main.menu.with.window.title.comment")).withLargeLeftGap()
+                  })
+          }
+          yield({ checkBox(cdFullPathsInTitleBar) })
+          yield({ checkBox(cdShowMenuIcons) })
+        }
 
-            if (hasMergeMainMenuWithWindowTitleOption) {
-              fullRow {
-                val overridden = UISettings.isMergeMainMenuWithWindowTitleOverridden
-                checkBox(cdMergeMainMenuWithWindowTitle).enabled(!overridden)
-                if (overridden) {
-                  ContextHelpLabel.create(
-                    message("option.is.overridden.by.jvm.property", UISettings.MERGE_MAIN_MENU_WITH_WINDOW_TITLE_PROPERTY))()
-                }
-                commentNoWrap(message("checkbox.merge.main.menu.with.window.title.comment")).withLargeLeftGap()
-              }
-            }
-            fullRow { checkBox(cdFullPathsInTitleBar) }
-            // The last item migrates to the left column if the right column has the additional item:
-            if (!hasMergeMainMenuWithWindowTitleOption)
-              fullRow { checkBox(cdShowMenuIcons) }
+        // Since some of the columns have variable number of items, enumerate them in a loop, while moving orphaned items from the right
+        // column to the left one:
+        val leftIt = leftColumnControls.iterator()
+        val rightIt = rightColumnControls.iterator()
+        while (leftIt.hasNext() || rightIt.hasNext()) {
+          when {
+            leftIt.hasNext() && rightIt.hasNext() -> twoColumnRow(leftIt.next(), rightIt.next())
+            leftIt.hasNext() -> twoColumnRow(leftIt.next()) { placeholder() }
+            rightIt.hasNext() -> twoColumnRow(rightIt.next()) { placeholder() } // move from right to left
           }
-        )
+        }
         val backgroundImageAction = ActionManager.getInstance().getAction("Images.SetBackgroundImage")
         if (backgroundImageAction != null) {
           fullRow {
@@ -352,16 +356,6 @@ private fun RowBuilder.twoColumnRow(column1: InnerCell.() -> Unit, column2: Inne
   placeholder().constraints(growX, pushX)
 }
 
-private fun RowBuilder.twoPanelRow(initPanel1: LayoutBuilder.() -> Unit, initPanel2: LayoutBuilder.() -> Unit): Row {
-  val panel1 = panel {
-    initPanel1()
-  }
-  val panel2 = panel {
-    initPanel2()
-  }
-  return twoColumnRow({ component(panel1) }, { component(panel2) })
-}
-
 private fun getIntValue(text: String?, defaultValue: Int): Int {
   if (text != null && text.isNotBlank()) {
     val value = text.toIntOrNull()