Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions build/bazel-generated-file-list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,11 @@ platform/find/backend
platform/foldings
platform/forms_rt
platform/icons
platform/icons-api
platform/icons-api/rendering
platform/icons-impl
platform/icons-impl/intellij
platform/icons-impl/intellij/tests
platform/ide-core
platform/ide-core-impl
platform/ide-core/plugins
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ object CoreModuleSets {
embeddedModule("intellij.platform.util.ui")
embeddedModule("intellij.platform.util.coroutines")

embeddedModule("intellij.platform.icons.impl.intellij")

embeddedModule("intellij.platform.locking.impl")

embeddedModule("intellij.platform.core")
Expand Down
2 changes: 2 additions & 0 deletions platform/core-ui/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jvm_library(
"//platform/util:util-ui",
"@lib//:kotlin-stdlib",
"//libraries/hash4j",
"//platform/icons-api",
]
)

Expand All @@ -33,6 +34,7 @@ jvm_library(
"//platform/core-api:core_test_lib",
"//platform/util:util-ui_test_lib",
"//libraries/hash4j:hash4j_test_lib",
"//platform/icons-api:icons-api_test_lib",
]
)
### auto-generated section `build intellij.platform.core.ui` end
1 change: 1 addition & 0 deletions platform/core-ui/intellij.platform.core.ui.iml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
<orderEntry type="module" module-name="intellij.platform.util.ui" />
<orderEntry type="library" name="kotlin-stdlib" level="project" />
<orderEntry type="module" module-name="intellij.libraries.hash4j" />
<orderEntry type="module" module-name="intellij.platform.icons.api" />
</component>
</module>
3 changes: 2 additions & 1 deletion platform/core-ui/module-content.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- name: dist.all/lib/intellij.platform.core.ui.jar
modules:
- name: intellij.platform.core.ui
- name: intellij.platform.core.ui
- name: intellij.platform.icons.api
111 changes: 111 additions & 0 deletions platform/icons-api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
### macOS template
# General
.DS_Store
.AppleDouble
.LSOverride

# Thumbnails
._*

### Gradle template
.gradle
build/

### Terraform template
# Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

*.ipr
*.iws
.idea/*
out/
local.properties

# IDEA/Android Studio project settings ignore exceptions
!.idea/codeStyles/
!.idea/copyright/
!.idea/dataSources.xml
!.idea/detekt.xml
!.idea/encodings.xml
!.idea/externalDependencies.xml
!.idea/fileTemplates/
!.idea/icon.svg
!.idea/icon.png
!.idea/icon_dark.png
!.idea/inspectionProfiles/
!.idea/ktfmt.xml
!.idea/ktlint.xml
!.idea/ktlint-plugin.xml
!.idea/runConfigurations/
!.idea/scopes/
!.idea/vcs.xml

### Kotlin template
# Compiled class file
*.class

# Log file
*.log

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

### Windows template
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db

# Dump file
*.stackdump

# Folder config file
[Dd]esktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp

# Windows shortcuts
*.lnk

### Misc

# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

# Ignore IJP temp folder
/.intellijPlatform

# Ignore release patch generator output
/this-release.txt

# Ignore Kotlin compiler sessions
/.kotlin
/buildSrc/.kotlin
/foundation/bin/*
/samples/showcase/bin/*
/new_release_notes.md
28 changes: 28 additions & 0 deletions platform/icons-api/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
### auto-generated section `build intellij.platform.icons.api` start
load("@rules_jvm//:jvm.bzl", "jvm_library")

jvm_library(
name = "icons-api",
module_name = "intellij.platform.icons.api",
visibility = ["//visibility:public"],
srcs = glob(["src/**/*.kt", "src/**/*.java", "src/**/*.form"], allow_empty = True),
deps = [
"@lib//:kotlin-stdlib",
"//libraries/kotlinx/coroutines/core",
"//libraries/kotlinx/serialization/core",
"@lib//:jetbrains-annotations",
]
)

jvm_library(
name = "icons-api_test_lib",
module_name = "intellij.platform.icons.api",
visibility = ["//visibility:public"],
srcs = glob([], allow_empty = True),
runtime_deps = [
":icons-api",
"//libraries/kotlinx/coroutines/core:core_test_lib",
"//libraries/kotlinx/serialization/core:core_test_lib",
]
)
### auto-generated section `build intellij.platform.icons.api` end
97 changes: 97 additions & 0 deletions platform/icons-api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Cross frontend-api Icons
These Icons support being rendered by multiple frontend-apis (swing, compose, can be extended)

## Data & Rendering split
The API is split to two parts:
- [Data](.)
- [Rendering](./rendering)

This allows declaring icons without depending on the rendering implementation, which is useful on the backend.

## `org.jetbrains.icons.api.Icon`
This is data part, an Icon, which represents how the specific Icon should look like.
This should be serializable (atleast in the IntelliJ implementation) and sendable directly via RPC.
Creating this class should not generate any side-effects or long-loading of resources.

```kotlin
val githubIcon = icon {
image("icons/github.svg", ShowcaseIcons::class.java.classLoader, modifier = IconModifier.fillMaxSize())
}
```

Layouting is also supported, where you can layer more icons into one:
```kotlin
val githubIcon = imageIcon("icons/github.svg", javaClass.classLoader)
val gitIcon = imageIcon("icons/git.svg", javaClass.classLoader)

val layeredIcon = icon {
icon(githubIcon)
icon(gitIcon)
}

val rowLayeredIcon = icon {
column {
row {
icon(githubIcon)
icon(gitIcon)
}
row {
icon(githubIcon)
icon(gitIcon)
}
}
}
```
Row & Column behaves similarly to Compose counterparts.
There is also IconModifiers, that can affect how the resulting Icon will look like,
again, concept from Compose, you can use modifiers to adjust:
- Layouting (margin, size, align
- Color filtering
- Svg replacements

The Icons are going to infer expected size (based on settings, svg data or image data),
however, you can also make the icons scaled to the container component.

To serialize an icon, serializers module can be obtained from the IconManager.

## `org.jetbrains.icons.api.rendering.IconRenderer`
While having data object for Icon is great, we still need a way to render it.
This class is responsible for getting the previously mentioned Icon data object,
it figures out how to load the used images.
Creating this class actually loads resources, so it should be considered a heavy operation.

This normally shouldn't be used directly, but rather via components, like the Jewel `fun Icon(..)` icon, or specific swing components,
that create the renderer themselves.
To create a renderer for an Icon, you should use Icon.createRenderer() function.

The final size of the Icon is inferred from the Icon data object but also affected by the scale factor and the containing component.
In compose, the size is affected by modifiers applied to the `Icon()` composable, the swing conunterpart can be configured via the
toSwingIcon() function. (or will be in the future)

## Legacy/Swing Icon interop
To use Swing icons inside the new icons/with the new api, check [legacy-icon-support](./legacy-icon-support/)

## `org.jetbrains.icons.api.IconManager`
This interface is responsible for generating Icon models.

## Extensibility
All extensions should be registered beforehand, to allow deserialization, where we need to know
all possible layers, loaders, etc. to properly deserialize icons. That is why it is not enough to
just pass your loaders/layers to the IconManager or whatever when creating the icon.

### Custom Layer
Custom layers can be easily added by designer's custom function. However, make sure to also register
the layer in the IconManager, to make sure it is serializable, also, ensure to register corresponding Icon Layer Renderer.

### ImageResourceLoader
Custom image resource loaders can be added.
To do so, you need to implement `org.jetbrains.icons.api.ImageResourceLoader` interface and
then register it via the appropriate IconManager, check individual managers for details.
The registration will tell the IconManager how to serialize this loader and will let
ImageResourceProvider know how to load the resources.
Make sure to implement equals and hashCode functions, as they are used for caching purposes.

Also, introduce an extension function for IconDesigner to allow easy creation of your new loader.

## Implementation details
For implementation details, refer to [implementation modules](../icons-impl/README.md)
53 changes: 53 additions & 0 deletions platform/icons-api/STATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

# Icons API state

* 💻 in progress
* ✅ works everywhere
* ❌ not done
* 🚶 works in compose
* 👫 works in ij-compose
* 🐌 works in swing
* ❔ unsure if planned
* 🔧 partially done

## Layers

* image ✅
* icon ✅
* row ✅
* column ✅
* animation ✅
* swingIcon ✅
* text ❌
* badge 💻

## Modifiers

* align ✅
* alpha 🚶
* color filter 🚶
* size (height/width) ✅
* margin ✅
* svg patcher 👫🐌 – uses legacy api patching
* filters ❌
* stroke 💻

# Deferred Icons

* local ✅
* over network ❌

## Implementation

* caching 🔧 – using legacy api atm.
* loading 🔧 – using legacy api atm.
* skiko svg rendering❔
* intrinsic size calculations 🚶👫
* scaling 🚶👫
* blend modes 🔧 – only some are supported
* update/re-render dispatching 🚶👫

## Loading options
- block ✅
- blank ❌
- placeholder ❌
26 changes: 26 additions & 0 deletions platform/icons-api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// This file is used by Jewel gradle script, check community/platform/jewel

plugins {
jewel
alias(libs.plugins.kotlinx.serialization)
}

sourceSets {
main {
kotlin {
setSrcDirs(listOf("src"))
}
}

test {
kotlin {
setSrcDirs(listOf("test"))
}
}
}

dependencies {
api("org.jetbrains:annotations:26.0.2")
api(libs.kotlinx.serialization.core)
api(libs.kotlinx.coroutines.core)
}
Loading
Loading