Skip to content

Commit

Permalink
Fix scaling in the IDE once again
Browse files Browse the repository at this point in the history
Turns out the previous change was wrong — the issue was mostly due to us
taking some JBDimensions and not un-scaling them before using their
values.

To better match the line width in Swing, I also tweaked the border
modifier logic to not round up line widths, as that was causing lines
to be drawn thicker than they should. This is not a full fix, since
Swing does some tweaks in DarculaNewUIUtils#paintRectangle, and it
probably just draws things slightly differently.

However, this does considerably improve things at most IDE zoom levels,
at the cost of some minor fuzziness at 110% zoom.
  • Loading branch information
rock3r committed May 10, 2024
1 parent a939da7 commit 60583a1
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ private fun Modifier.drawBorderWithAlignment(
drawContent()

val strokeWidthPx =
min(if (width == Dp.Hairline) 1f else ceil(width.toPx()), ceil(size.minDimension / 2))
min(if (width == Dp.Hairline) 1f else width.toPx(), size.minDimension / 2)
.coerceAtLeast(1f)

val expandWidthPx = expand.takeOrElse { 0.dp }.toPx()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import androidx.compose.ui.graphics.Color
import com.intellij.ide.ui.UITheme
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.ui.NewUI
import org.jetbrains.jewel.bridge.theme.isNewUiTheme
import org.jetbrains.jewel.foundation.InternalJewelApi
import org.jetbrains.jewel.foundation.theme.JewelTheme
import org.jetbrains.jewel.foundation.util.inDebugMode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.isUnspecified
import androidx.compose.ui.unit.sp
import androidx.compose.ui.unit.takeOrElse
import com.intellij.ide.ui.LafManager
import com.intellij.ide.ui.UISettingsUtils
import com.intellij.openapi.diagnostic.Logger
import com.intellij.ui.JBColor
import com.intellij.ui.JBColor.marker
import com.intellij.ui.NewUI
import com.intellij.ui.scale.JBUIScale.scale
import com.intellij.util.ui.JBDimension
import com.intellij.util.ui.JBFont
Expand Down Expand Up @@ -118,7 +120,8 @@ public fun JBInsets.toPaddingValues(): PaddingValues =
* instance, this function delegates to the specific [toDpSize] for it,
* which is scaling-aware.
*/
public fun Dimension.toDpSize(): DpSize = DpSize(width.dp, height.dp)
public fun Dimension.toDpSize(): DpSize =
if (this is JBDimension) toDpSize() else DpSize(width.dp, height.dp)

/**
* Converts a [JBDimension] to [DpSize], in a scaling-aware way. This means
Expand Down Expand Up @@ -195,9 +198,22 @@ internal operator fun TextUnit.plus(delta: Float): TextUnit =
else -> this
}

internal fun retrieveIdeaDensity(sourceDensity: Density): Density {
internal fun scaleDensityWithIdeScale(sourceDensity: Density): Density {
val ideaScale = UISettingsUtils.getInstance().currentIdeScale
val fontScale = sourceDensity.fontScale * ideaScale
val density = sourceDensity.density * ideaScale

return Density(sourceDensity.density, fontScale)
return Density(density, sourceDensity.fontScale)
}

internal fun isNewUiTheme(): Boolean {
if (!NewUI.isEnabled()) return false

val lafName = lafName()
return lafName == "Light" || lafName == "Dark" || lafName == "Light with Light Header"
}

@Suppress("UnstableApiUsage")
internal fun lafName(): String {
val lafInfo = LafManager.getInstance().currentUIThemeLookAndFeel
return lafInfo.name
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package org.jetbrains.jewel.bridge

import androidx.compose.runtime.Composable
import com.intellij.openapi.util.NlsContexts.TabTitle
import com.intellij.openapi.wm.ToolWindow
import org.jetbrains.jewel.foundation.enableNewSwingCompositing

public fun ToolWindow.addComposeTab(
tabDisplayName: String,
@TabTitle tabDisplayName: String,
isLockable: Boolean = true,
isCloseable: Boolean = false,
content: @Composable ToolWindowScope.() -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.isSpecified
import androidx.compose.ui.unit.takeOrElse
import com.intellij.ide.ui.LafManager
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil
import com.intellij.ide.ui.laf.intellij.IdeaPopupMenuUI
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.util.registry.Registry
import com.intellij.ui.JBColor
import com.intellij.ui.NewUI
import com.intellij.util.ui.DirProvider
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.NamedColorUtil
import org.jetbrains.jewel.bridge.bridgePainterProvider
import org.jetbrains.jewel.bridge.createVerticalBrush
import org.jetbrains.jewel.bridge.dp
import org.jetbrains.jewel.bridge.isNewUiTheme
import org.jetbrains.jewel.bridge.lafName
import org.jetbrains.jewel.bridge.readFromLaF
import org.jetbrains.jewel.bridge.retrieveArcAsCornerSizeOrDefault
import org.jetbrains.jewel.bridge.retrieveArcAsCornerSizeWithFallbacks
Expand All @@ -36,6 +36,7 @@ import org.jetbrains.jewel.bridge.retrieveIntAsDpOrUnspecified
import org.jetbrains.jewel.bridge.retrieveTextStyle
import org.jetbrains.jewel.bridge.toComposeColor
import org.jetbrains.jewel.bridge.toComposeColorOrUnspecified
import org.jetbrains.jewel.bridge.toDpSize
import org.jetbrains.jewel.bridge.toPaddingValues
import org.jetbrains.jewel.foundation.GlobalColors
import org.jetbrains.jewel.foundation.GlobalMetrics
Expand Down Expand Up @@ -227,13 +228,13 @@ private fun readDefaultButtonStyle(): ButtonStyle {
borderHovered = normalBorder,
)

val minimumSize = JBUI.CurrentTheme.Button.minimumSize()
val minimumSize = JBUI.CurrentTheme.Button.minimumSize().toDpSize()
return ButtonStyle(
colors = colors,
metrics = ButtonMetrics(
cornerSize = retrieveArcAsCornerSizeWithFallbacks("Button.default.arc", "Button.arc"),
padding = PaddingValues(horizontal = 14.dp), // see DarculaButtonUI.HORIZONTAL_PADDING
minSize = DpSize(minimumSize.width.dp, minimumSize.height.dp),
minSize = DpSize(minimumSize.width, minimumSize.height),
borderWidth = DarculaUIUtil.LW.dp,
),
)
Expand Down Expand Up @@ -270,14 +271,14 @@ private fun readOutlinedButtonStyle(): ButtonStyle {
borderHovered = normalBorder,
)

val minimumSize = JBUI.CurrentTheme.Button.minimumSize()
val minimumSize = JBUI.CurrentTheme.Button.minimumSize().toDpSize()
return ButtonStyle(
colors = colors,
metrics =
ButtonMetrics(
cornerSize = CornerSize(DarculaUIUtil.BUTTON_ARC.dp / 2),
padding = PaddingValues(horizontal = 14.dp), // see DarculaButtonUI.HORIZONTAL_PADDING
minSize = DpSize(minimumSize.width.dp, minimumSize.height.dp),
minSize = DpSize(minimumSize.width, minimumSize.height),
borderWidth = DarculaUIUtil.LW.dp,
),
)
Expand Down Expand Up @@ -468,13 +469,13 @@ private fun readDefaultDropdownStyle(
iconTintHovered = Color.Unspecified,
)

val minimumSize = JBUI.CurrentTheme.ComboBox.minimumSize()
val minimumSize = JBUI.CurrentTheme.ComboBox.minimumSize().toDpSize()
val arrowWidth = JBUI.CurrentTheme.Component.ARROW_AREA_WIDTH.dp
return DropdownStyle(
colors = colors,
metrics = DropdownMetrics(
arrowMinSize = DpSize(arrowWidth, minimumSize.height.dp),
minSize = DpSize(minimumSize.width.dp + arrowWidth, minimumSize.height.dp),
arrowMinSize = DpSize(arrowWidth, minimumSize.height),
minSize = DpSize(minimumSize.width + arrowWidth, minimumSize.height),
cornerSize = CornerSize(DarculaUIUtil.COMPONENT_ARC.dp / 2),
contentPadding = retrieveInsetsAsPaddingValues("ComboBox.padding"),
borderWidth = DarculaUIUtil.LW.dp,
Expand Down Expand Up @@ -517,15 +518,15 @@ private fun readUndecoratedDropdownStyle(
)

val arrowWidth = JBUI.CurrentTheme.Component.ARROW_AREA_WIDTH.dp
val minimumSize = JBUI.CurrentTheme.Button.minimumSize()
val minimumSize = JBUI.CurrentTheme.Button.minimumSize().toDpSize()

return DropdownStyle(
colors = colors,
metrics = DropdownMetrics(
arrowMinSize = DpSize(arrowWidth, minimumSize.height.dp),
minSize = DpSize(minimumSize.width.dp + arrowWidth, minimumSize.height.dp),
arrowMinSize = DpSize(arrowWidth, minimumSize.height),
minSize = DpSize(minimumSize.width + arrowWidth, minimumSize.height),
cornerSize = CornerSize(JBUI.CurrentTheme.MainToolbar.Dropdown.hoverArc().dp),
contentPadding = JBUI.CurrentTheme.MainToolbar.Dropdown.borderInsets().toPaddingValues(),
contentPadding = PaddingValues(3.dp), // from com.intellij.ide.ui.laf.darcula.ui.DarculaComboBoxUI.getDefaultComboBoxInsets
borderWidth = 0.dp,
),
icons = DropdownIcons(chevronDown = bridgePainterProvider("general/chevron-down.svg")),
Expand Down Expand Up @@ -852,13 +853,13 @@ private fun readTextFieldStyle(textFieldStyle: TextStyle): TextFieldStyle {
placeholder = NamedColorUtil.getInactiveTextColor().toComposeColor(),
)

val minimumSize = JBUI.CurrentTheme.TextField.minimumSize()
val minimumSize = JBUI.CurrentTheme.TextField.minimumSize().toDpSize()
return TextFieldStyle(
colors = colors,
metrics = TextFieldMetrics(
cornerSize = CornerSize(DarculaUIUtil.COMPONENT_ARC.dp / 2),
contentPadding = PaddingValues(horizontal = 9.dp, vertical = 2.dp),
minSize = DpSize(minimumSize.width.dp, minimumSize.height.dp),
minSize = DpSize(minimumSize.width, minimumSize.height),
borderWidth = DarculaUIUtil.LW.dp,
),
textStyle = textFieldStyle,
Expand Down Expand Up @@ -1056,16 +1057,3 @@ private fun readIconButtonStyle(): IconButtonStyle =
borderHovered = retrieveColorOrUnspecified("ActionButton.hoverBorderColor"),
),
)

internal fun isNewUiTheme(): Boolean {
if (!NewUI.isEnabled()) return false

val lafName = lafName()
return lafName == "Light" || lafName == "Dark" || lafName == "Light with Light Header"
}

@Suppress("UnstableApiUsage")
private fun lafName(): String {
val lafInfo = LafManager.getInstance().currentUIThemeLookAndFeel
return lafInfo.name
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import androidx.compose.ui.platform.LocalDensity
import com.intellij.openapi.components.service
import org.jetbrains.jewel.bridge.BridgePainterHintsProvider
import org.jetbrains.jewel.bridge.SwingBridgeService
import org.jetbrains.jewel.bridge.retrieveIdeaDensity
import org.jetbrains.jewel.bridge.scaleDensityWithIdeScale
import org.jetbrains.jewel.foundation.ExperimentalJewelApi
import org.jetbrains.jewel.ui.ComponentStyling
import org.jetbrains.jewel.ui.painter.LocalPainterHintsProvider
Expand All @@ -29,7 +29,7 @@ public fun SwingBridgeTheme(content: @Composable () -> Unit) {
) {
CompositionLocalProvider(
LocalPainterHintsProvider provides BridgePainterHintsProvider(themeData.themeDefinition.isDark),
LocalDensity provides retrieveIdeaDensity(LocalDensity.current),
LocalDensity provides scaleDensityWithIdeScale(LocalDensity.current),
) {
content()
}
Expand Down

0 comments on commit 60583a1

Please sign in to comment.