Skip to content

Commit

Permalink
Apply the icon override for standalone
Browse files Browse the repository at this point in the history
  • Loading branch information
devkanro committed Oct 13, 2023
1 parent f57da0d commit 70e79ee
Show file tree
Hide file tree
Showing 16 changed files with 119 additions and 53 deletions.
30 changes: 30 additions & 0 deletions core/src/main/kotlin/org/jetbrains/jewel/IconMapper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.jetbrains.jewel

import androidx.compose.ui.res.ResourceLoader
import java.util.logging.Level
import java.util.logging.Logger

interface IconMapper {

fun mapPath(originalPath: String, iconData: IntelliJThemeIconData, resourceLoader: ResourceLoader): String
}

object IntelliJIconMapper : IconMapper {

private val verbose = true

override fun mapPath(
originalPath: String,
iconData: IntelliJThemeIconData,
resourceLoader: ResourceLoader,
): String {
val normalized = "/${originalPath.trimStart('/')}"
val overriddenPath = iconData.iconOverrides[normalized] ?: normalized

if (overriddenPath != normalized) {
if (verbose) println("Found theme icon override: '$originalPath' -> '$overriddenPath'")
}

return overriddenPath
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,24 @@ package org.jetbrains.jewel.styling

import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.ResourceLoader
import org.jetbrains.jewel.IconMapper
import org.jetbrains.jewel.IntelliJIconMapper
import org.jetbrains.jewel.IntelliJThemeIconData
import org.jetbrains.jewel.InteractiveComponentState
import org.jetbrains.jewel.InternalJewelApi
import org.jetbrains.jewel.LocalIconData
import org.jetbrains.jewel.SvgLoader
import org.jetbrains.jewel.painterResource

open class ResourcePainterProvider<T> @InternalJewelApi constructor(
private val basePath: String,
private val svgLoader: SvgLoader,
private val iconMapper: IconMapper,
private val iconData: IntelliJThemeIconData,
private val pathPatcher: ResourcePathPatcher<T>,
) : PainterProvider<T> {

Expand All @@ -38,7 +45,8 @@ open class ResourcePainterProvider<T> @InternalJewelApi constructor(
extraData: T?,
): String {
val patched = pathPatcher.patchVariant(basePath, resourceLoader, extraData)
return pathPatcher.patchTheme(patched, resourceLoader)
val override = iconMapper.mapPath(patched, iconData, resourceLoader)
return pathPatcher.patchTheme(override, resourceLoader)
}

override fun equals(other: Any?): Boolean {
Expand All @@ -49,32 +57,63 @@ open class ResourcePainterProvider<T> @InternalJewelApi constructor(

if (basePath != other.basePath) return false
if (svgLoader != other.svgLoader) return false
if (iconMapper != other.iconMapper) return false
if (iconData != other.iconData) return false
if (pathPatcher != other.pathPatcher) return false


return true
}

override fun hashCode(): Int {
var result = basePath.hashCode()
result = 31 * result + svgLoader.hashCode()
result = 31 * result + iconMapper.hashCode()
result = 31 * result + iconData.hashCode()
result = 31 * result + pathPatcher.hashCode()
return result
}

override fun toString(): String =
"ResourcePainterProvider(basePath='$basePath', svgLoader=$svgLoader, pathPatcher=$pathPatcher)"
"ResourcePainterProvider(basePath='$basePath', svgLoader=$svgLoader, iconMapper=$iconMapper, iconData=$iconData, pathPatcher=$pathPatcher)"

@OptIn(InternalJewelApi::class) // These are the public constructors
companion object Factory {

fun stateless(basePath: String, svgLoader: SvgLoader) =
ResourcePainterProvider<Unit>(basePath, svgLoader, SimpleResourcePathPatcher())
fun stateless(basePath: String, svgLoader: SvgLoader, iconData: IntelliJThemeIconData) =
ResourcePainterProvider<Unit>(
basePath,
svgLoader,
IntelliJIconMapper,
iconData,
SimpleResourcePathPatcher()
)

fun <T : InteractiveComponentState> stateful(
basePath: String,
svgLoader: SvgLoader,
pathPatcher: ResourcePathPatcher<T> = StatefulResourcePathPatcher(),
iconData: IntelliJThemeIconData,
pathPatcher: ResourcePathPatcher<T> = StatefulResourcePathPatcher()
) =
ResourcePainterProvider(basePath, svgLoader, pathPatcher)
ResourcePainterProvider(basePath, svgLoader, IntelliJIconMapper, iconData, pathPatcher)
}
}

@Composable
fun rememberStatelessPainterProvider(
basePath: String,
svgLoader: SvgLoader,
iconData: IntelliJThemeIconData = LocalIconData.current
): ResourcePainterProvider<Unit> = remember(basePath, iconData) {
ResourcePainterProvider.stateless(basePath, svgLoader, iconData)
}

@Composable
fun <T : InteractiveComponentState> rememberStatefulPainterProvider(
basePath: String,
svgLoader: SvgLoader,
pathPatcher: ResourcePathPatcher<T> = StatefulResourcePathPatcher(),
iconData: IntelliJThemeIconData = LocalIconData.current
): ResourcePainterProvider<T> = remember(basePath, iconData, pathPatcher) {
ResourcePainterProvider.stateful(basePath, svgLoader, iconData, pathPatcher)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.compose.ui.res.ResourceLoader
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.util.ui.DirProvider
import org.jetbrains.jewel.ClassLoaderProvider
import org.jetbrains.jewel.IconMapper
import org.jetbrains.jewel.IntelliJThemeIconData
import org.jetbrains.jewel.InternalJewelApi

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.jetbrains.jewel.bridge

import androidx.compose.runtime.Composable
import androidx.compose.ui.res.ResourceLoader
import org.jetbrains.jewel.IconMapper
import org.jetbrains.jewel.IntelliJThemeIconData
import org.jetbrains.jewel.InteractiveComponentState
import org.jetbrains.jewel.InternalJewelApi
Expand All @@ -15,21 +14,10 @@ import org.jetbrains.jewel.styling.StatefulResourcePathPatcher
internal class BridgeResourcePainterProvider<T> @InternalJewelApi constructor(
basePath: String,
svgLoader: SvgLoader,
private val pathPatcher: ResourcePathPatcher<T>,
private val iconMapper: IconMapper,
private val iconData: IntelliJThemeIconData,
) : ResourcePainterProvider<T>(basePath, svgLoader, pathPatcher) {

@Composable
override fun patchPath(
basePath: String,
resourceLoader: ResourceLoader,
extraData: T?,
): String {
val patched = pathPatcher.patchVariant(basePath, resourceLoader, extraData)
val override = iconMapper.mapPath(patched, iconData, resourceLoader)
return pathPatcher.patchTheme(override, resourceLoader)
}
pathPatcher: ResourcePathPatcher<T>,
iconMapper: IconMapper,
iconData: IntelliJThemeIconData,
) : ResourcePainterProvider<T>(basePath, svgLoader, iconMapper, iconData, pathPatcher) {

companion object Factory {

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import org.jetbrains.jewel.CheckboxState
import org.jetbrains.jewel.LocalIconData
import org.jetbrains.jewel.SvgLoader
import org.jetbrains.jewel.intui.core.theme.IntUiDarkTheme
import org.jetbrains.jewel.intui.core.theme.IntUiLightTheme
Expand Down Expand Up @@ -104,19 +105,22 @@ import org.jetbrains.jewel.styling.StatefulResourcePathPatcher

companion object {

@Composable
fun checkbox(
svgLoader: SvgLoader,
basePath: String = "com/intellij/ide/ui/laf/icons/intellij/checkBox.svg",
): PainterProvider<CheckboxState> = ResourcePainterProvider.stateful(
basePath,
svgLoader,
LocalIconData.current,
pathPatcher = StatefulResourcePathPatcher(
prefixTokensProvider = { state: CheckboxState ->
if (state.toggleableState == ToggleableState.Indeterminate) "Indeterminate" else ""
},
),
)
)

@Composable
fun light(
svgLoader: SvgLoader,
checkbox: PainterProvider<CheckboxState> = checkbox(
Expand All @@ -125,6 +129,7 @@ import org.jetbrains.jewel.styling.StatefulResourcePathPatcher
),
) = IntUiCheckboxIcons(checkbox)

@Composable
fun dark(
svgLoader: SvgLoader,
checkbox: PainterProvider<CheckboxState> = checkbox(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import org.jetbrains.jewel.DropdownState
import org.jetbrains.jewel.LocalIconData
import org.jetbrains.jewel.SvgLoader
import org.jetbrains.jewel.intui.core.theme.IntUiDarkTheme
import org.jetbrains.jewel.intui.core.theme.IntUiLightTheme
Expand Down Expand Up @@ -195,7 +196,7 @@ data class IntUiDropdownIcons(
svgLoader: SvgLoader,
basePath: String = "expui/general/chevronDown.svg",
): PainterProvider<DropdownState> =
ResourcePainterProvider.stateful(basePath, svgLoader)
ResourcePainterProvider.stateful(basePath, svgLoader, LocalIconData.current)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import org.jetbrains.jewel.LocalIconData
import org.jetbrains.jewel.SvgLoader
import org.jetbrains.jewel.intui.core.theme.IntUiDarkTheme
import org.jetbrains.jewel.intui.core.theme.IntUiLightTheme
Expand Down Expand Up @@ -123,14 +124,14 @@ data class IntUiLazyTreeIcons(
svgLoader: SvgLoader,
basePath: String = "expui/general/chevronRight.svg",
): PainterProvider<Unit> =
ResourcePainterProvider.stateless(basePath, svgLoader)
ResourcePainterProvider.stateless(basePath, svgLoader, LocalIconData.current)

@Composable
fun chevronExpanded(
svgLoader: SvgLoader,
basePath: String = "expui/general/chevronDown.svg",
): PainterProvider<Unit> =
ResourcePainterProvider.stateless(basePath, svgLoader)
ResourcePainterProvider.stateless(basePath, svgLoader, LocalIconData.current)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import org.jetbrains.jewel.LinkState
import org.jetbrains.jewel.LocalIconData
import org.jetbrains.jewel.SvgLoader
import org.jetbrains.jewel.intui.core.theme.IntUiDarkTheme
import org.jetbrains.jewel.intui.core.theme.IntUiLightTheme
Expand Down Expand Up @@ -120,14 +121,14 @@ data class IntUiLinkIcons(
svgLoader: SvgLoader,
basePath: String = "expui/general/chevronDown.svg",
): PainterProvider<LinkState> =
ResourcePainterProvider.stateful(basePath, svgLoader)
ResourcePainterProvider.stateful(basePath, svgLoader, LocalIconData.current)

@Composable
fun externalLink(
svgLoader: SvgLoader,
basePath: String = "expui/ide/externalLink.svg",
): PainterProvider<LinkState> =
ResourcePainterProvider.stateful(basePath, svgLoader)
ResourcePainterProvider.stateful(basePath, svgLoader, LocalIconData.current)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import org.jetbrains.jewel.LocalIconData
import org.jetbrains.jewel.MenuItemState
import org.jetbrains.jewel.SvgLoader
import org.jetbrains.jewel.intui.core.theme.IntUiDarkTheme
Expand Down Expand Up @@ -214,7 +215,7 @@ data class IntUiMenuIcons(
svgLoader: SvgLoader,
basePath: String = "expui/general/chevronRight.svg",
): PainterProvider<MenuItemState> =
ResourcePainterProvider.stateful(basePath, svgLoader)
ResourcePainterProvider.stateful(basePath, svgLoader, LocalIconData.current)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import org.jetbrains.jewel.LocalIconData
import org.jetbrains.jewel.RadioButtonState
import org.jetbrains.jewel.SvgLoader
import org.jetbrains.jewel.intui.core.theme.IntUiDarkTheme
Expand Down Expand Up @@ -105,12 +106,14 @@ data class IntUiRadioButtonIcons(

companion object {

@Composable
fun radioButton(
svgLoader: SvgLoader,
basePath: String = "com/intellij/ide/ui/laf/icons/intellij/radio.svg",
): PainterProvider<RadioButtonState> =
ResourcePainterProvider.stateful(basePath, svgLoader)
ResourcePainterProvider.stateful(basePath, svgLoader, LocalIconData.current)

@Composable
fun light(
svgLoader: SvgLoader,
radioButton: PainterProvider<RadioButtonState> = radioButton(
Expand All @@ -119,6 +122,7 @@ data class IntUiRadioButtonIcons(
),
) = IntUiRadioButtonIcons(radioButton)

@Composable
fun dark(
svgLoader: SvgLoader,
radioButton: PainterProvider<RadioButtonState> = radioButton(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import org.jetbrains.jewel.ButtonState
import org.jetbrains.jewel.LocalIconData
import org.jetbrains.jewel.SvgLoader
import org.jetbrains.jewel.intui.core.theme.IntUiDarkTheme
import org.jetbrains.jewel.intui.core.theme.IntUiLightTheme
Expand Down Expand Up @@ -355,7 +356,7 @@ data class IntUiTabIcons(
svgLoader: SvgLoader,
basePath: String = "expui/general/closeSmall.svg",
): PainterProvider<ButtonState> =
ResourcePainterProvider.stateful(basePath, svgLoader)
ResourcePainterProvider.stateful(basePath, svgLoader, LocalIconData.current)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.ResourceLoader
Expand All @@ -15,9 +14,10 @@ import org.jetbrains.jewel.GroupHeader
import org.jetbrains.jewel.Icon
import org.jetbrains.jewel.IconButton
import org.jetbrains.jewel.JewelSvgLoader
import org.jetbrains.jewel.LocalIconData
import org.jetbrains.jewel.OutlinedButton
import org.jetbrains.jewel.Text
import org.jetbrains.jewel.styling.ResourcePainterProvider
import org.jetbrains.jewel.styling.rememberStatelessPainterProvider

@Composable
fun Buttons(svgLoader: JewelSvgLoader, resourceLoader: ResourceLoader) {
Expand All @@ -44,7 +44,7 @@ fun Buttons(svgLoader: JewelSvgLoader, resourceLoader: ResourceLoader) {
}

IconButton(onClick = {}) {
val iconProvider = remember { ResourcePainterProvider.stateless("icons/close.svg", svgLoader) }
val iconProvider = rememberStatelessPainterProvider("icons/close.svg", svgLoader)
val iconPainter by iconProvider.getPainter(resourceLoader)
Icon(
painter = iconPainter,
Expand Down
Loading

0 comments on commit 70e79ee

Please sign in to comment.