From 7b8ffddd872e4380769cd98ad2cebda51afcb54f Mon Sep 17 00:00:00 2001 From: sanlorng Date: Thu, 13 Jun 2024 19:53:06 +0800 Subject: [PATCH 1/5] [gallery] copy `FontIcon` from fluent. --- .../gallery/component/FontIcon.android.kt | 8 +++ .../konyaco/fluent/gallery/GalleryTheme.kt | 29 ++++---- .../fluent/gallery/component/FontIcon.kt | 72 +++++++++++++++++++ .../gallery/component/FontIcon.desktop.kt | 38 ++++++++++ 4 files changed, 134 insertions(+), 13 deletions(-) create mode 100644 gallery/src/androidMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.android.kt create mode 100644 gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.kt create mode 100644 gallery/src/desktopMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.desktop.kt diff --git a/gallery/src/androidMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.android.kt b/gallery/src/androidMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.android.kt new file mode 100644 index 00000000..21f3543b --- /dev/null +++ b/gallery/src/androidMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.android.kt @@ -0,0 +1,8 @@ +package com.konyaco.fluent.gallery.component + +import androidx.compose.runtime.Composable + +@Composable +internal actual fun ProvideFontIcon(content: @Composable () -> Unit) { + content() +} \ No newline at end of file diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/GalleryTheme.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/GalleryTheme.kt index f5c5bf90..d6c37a7e 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/GalleryTheme.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/GalleryTheme.kt @@ -6,6 +6,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import com.konyaco.fluent.* import com.konyaco.fluent.background.Mica +import com.konyaco.fluent.gallery.component.ProvideFontIcon val LocalStore = compositionLocalOf { error("Not provided") } @@ -43,20 +44,22 @@ fun GalleryTheme( CompositionLocalProvider( LocalStore provides store ) { - FluentTheme( - colors = if (store.darkMode) darkColors() else lightColors(), - useAcrylicPopup = store.enabledAcrylicPopup, - compactMode = store.compactMode - ) { - if (displayMicaLayer) { - Mica(modifier = Modifier.fillMaxSize()) { - content() + ProvideFontIcon { + FluentTheme( + colors = if (store.darkMode) darkColors() else lightColors(), + useAcrylicPopup = store.enabledAcrylicPopup, + compactMode = store.compactMode + ) { + if (displayMicaLayer) { + Mica(modifier = Modifier.fillMaxSize()) { + content() + } + } else { + CompositionLocalProvider( + LocalContentColor provides FluentTheme.colors.text.text.primary, + content = content + ) } - } else { - CompositionLocalProvider( - LocalContentColor provides FluentTheme.colors.text.text.primary, - content = content - ) } } } diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.kt new file mode 100644 index 00000000..58f90665 --- /dev/null +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.kt @@ -0,0 +1,72 @@ +package com.konyaco.fluent.gallery.component + +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.sp +import com.konyaco.fluent.component.Icon +import com.konyaco.fluent.component.Text + +//TODO Remove when FontIcon is public +@Composable +internal fun FontIcon( + glyph: Char, + modifier: Modifier = Modifier, + iconSize: TextUnit = FontIconDefaults.fontSizeStandard, + fallback: (@Composable () -> Unit)? = null, +) { + if (LocalFontIconFontFamily.current != null || fallback == null) { + Text( + text = glyph.toString(), + fontFamily = LocalFontIconFontFamily.current, + fontSize = iconSize, + modifier = Modifier.then(modifier) + .height(with(LocalDensity.current) { iconSize.toDp() }), + onTextLayout = { + } + ) + } else { + fallback() + } +} + +@Composable +internal fun FontIcon( + glyph: Char, + vector: ImageVector?, + contentDescription: String?, + modifier: Modifier = Modifier, + iconSize: TextUnit = FontIconDefaults.fontSizeStandard, + vectorSize: Dp = with(LocalDensity.current) { iconSize.toDp() } +) { + FontIcon( + glyph = glyph, + modifier = modifier, + iconSize = iconSize, + fallback = if (vector == null) { + null + } else { + { Icon(vector, contentDescription, modifier = Modifier.size(vectorSize)) } + } + ) +} + +internal object FontIconDefaults { + val fontSizeStandard = 16.sp + val fontSizeSmall = 12.sp +} + +@Composable +internal expect fun ProvideFontIcon( + content: @Composable () -> Unit +) + +internal val LocalFontIconFontFamily = + staticCompositionLocalOf { error("No Font provide for load font icon") } \ No newline at end of file diff --git a/gallery/src/desktopMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.desktop.kt b/gallery/src/desktopMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.desktop.kt new file mode 100644 index 00000000..a58d45f1 --- /dev/null +++ b/gallery/src/desktopMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.desktop.kt @@ -0,0 +1,38 @@ +package com.konyaco.fluent.gallery.component + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.LocalFontFamilyResolver +import androidx.compose.ui.text.ExperimentalTextApi +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.platform.FontLoadResult + +@OptIn(ExperimentalTextApi::class) +@Composable +internal actual fun ProvideFontIcon(content: @Composable () -> Unit) { + val fontFamilyResolver = LocalFontFamilyResolver.current + var fontIconFamily by remember { + mutableStateOf(null) + } + LaunchedEffect(fontFamilyResolver) { + val fontName = "Segoe Fluent Icons" + val fontFamily = FontFamily(fontName) + fontIconFamily = kotlin.runCatching { + val result = fontFamilyResolver.resolve(fontFamily).value as FontLoadResult + if (result.typeface == null || result.typeface?.familyName != fontName) { + null + } else { + fontFamily + } + }.getOrNull() + } + CompositionLocalProvider( + LocalFontIconFontFamily provides fontIconFamily, + content = content + ) +} \ No newline at end of file From a72570e8969b17173360d8215594192df429af0c Mon Sep 17 00:00:00 2001 From: sanlorng Date: Fri, 14 Jun 2024 00:52:45 +0800 Subject: [PATCH 2/5] [gallery] use `FontIcon` in Gallery. --- .../gallery/processor/ComponentProcessor.kt | 11 +- .../kotlin/com/konyaco/fluent/gallery/App.kt | 11 +- .../fluent/gallery/annotation/Component.kt | 1 + .../gallery/annotation/ComponentGroup.kt | 1 + .../gallery/component/ComponentGroupInfo.kt | 34 ++-- .../fluent/gallery/component/ComponentItem.kt | 1 + .../fluent/gallery/component/CopyButton.kt | 5 +- .../fluent/gallery/component/GalleryHeader.kt | 21 +- .../fluent/gallery/screen/AllSamplesScreen.kt | 2 +- .../fluent/gallery/screen/HomeScreen.kt | 180 +++++++----------- .../gallery/screen/design/IconsScreen.kt | 2 +- .../gallery/screen/design/TypographyScreen.kt | 1 + 12 files changed, 127 insertions(+), 143 deletions(-) diff --git a/gallery-processor/src/jvmMain/kotlin/com/konyaco/fluent/gallery/processor/ComponentProcessor.kt b/gallery-processor/src/jvmMain/kotlin/com/konyaco/fluent/gallery/processor/ComponentProcessor.kt index f716b2b7..547a1bf1 100644 --- a/gallery-processor/src/jvmMain/kotlin/com/konyaco/fluent/gallery/processor/ComponentProcessor.kt +++ b/gallery-processor/src/jvmMain/kotlin/com/konyaco/fluent/gallery/processor/ComponentProcessor.kt @@ -162,6 +162,7 @@ class ComponentProcessor(private val logger: KSPLogger, private val codeGenerato fileSpecBuilder.addImport(iconImportPrefix, this) "$iconPrefix.$this" }, + iconGlyph = componentGroupConfig.iconGlyph, content = componentGroupConfig.contentData, items = createItemsString( itemName, @@ -259,11 +260,13 @@ class ComponentProcessor(private val logger: KSPLogger, private val codeGenerato var nameArg: KSValueArgument? = null var descriptionArg: KSValueArgument? = null var icon: String? = null + var iconGlyph: Char? = null annotation.arguments.forEach { when (it.name?.asString()) { "name" -> nameArg = it "description" -> descriptionArg = it "icon" -> icon = (it.value as? String)?.ifBlank { null } + "iconGlyph" -> iconGlyph = (it.value as? Char)?.takeIf { char -> char != 'A' } } } val description = descriptionArg?.value as? String ?: "" @@ -312,6 +315,7 @@ class ComponentProcessor(private val logger: KSPLogger, private val codeGenerato fileSpec.addImport(iconImportPrefix, this) "$iconPrefix.$this" }, + iconGlyph = iconGlyph, items = null, getItem = { it } ) @@ -327,6 +331,7 @@ class ComponentProcessor(private val logger: KSPLogger, private val codeGenerato description: String, content: String?, icon: String?, + iconGlyph: Char?, items: List?, getItem: (T) -> String, ) = CodeBlock.builder() @@ -337,6 +342,7 @@ class ComponentProcessor(private val logger: KSPLogger, private val codeGenerato addStatement("description = %S,", description) addStatement("content = $content,") addStatement("icon = $icon,") + addStatement("iconGlyph = ${iconGlyph?.let { "'$it'" }},") if (items != null) { createList("items = ", items, getItem) } else { @@ -348,11 +354,13 @@ class ComponentProcessor(private val logger: KSPLogger, private val codeGenerato private fun generateComponentGroupConfig(group: String): ComponentGroupConfig { var icon: String? = null + var iconGlyph: Char? = null var contentData: String? = null componentGroups[group]?.let { (annotation) -> annotation.arguments.forEach { when (it.name?.asString()) { "icon" -> icon = (it.value as? String)?.ifBlank { null } + "iconGlyph" -> iconGlyph = (it.value as? Char).takeIf { char -> char != 'A' } "generateScreen" -> if (it.value as? Boolean == true) { contentData = """ { ComponentIndexScreen(it) } @@ -361,7 +369,7 @@ class ComponentProcessor(private val logger: KSPLogger, private val codeGenerato } } } - return ComponentGroupConfig(icon, contentData) + return ComponentGroupConfig(icon, iconGlyph, contentData) } private fun PropertySpec.Builder.lazy(buildAction: CodeBlock.Builder.() -> Unit) = delegate( @@ -395,6 +403,7 @@ class ComponentProcessor(private val logger: KSPLogger, private val codeGenerato data class ComponentGroupConfig( val icon: String?, + val iconGlyph: Char?, val contentData: String? ) } \ No newline at end of file diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/App.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/App.kt index 286ac0a5..a907c31d 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/App.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/App.kt @@ -43,6 +43,7 @@ import com.konyaco.fluent.component.TextBoxButtonDefaults import com.konyaco.fluent.component.TextField import com.konyaco.fluent.gallery.component.ComponentItem import com.konyaco.fluent.gallery.component.ComponentNavigator +import com.konyaco.fluent.gallery.component.FontIcon import com.konyaco.fluent.gallery.component.components import com.konyaco.fluent.gallery.component.rememberComponentNavigator import com.konyaco.fluent.gallery.component.flatMapComponents @@ -214,7 +215,13 @@ private fun NavigationItem( onSelectedItemChanged(navItem) expandedItems.value = !expandedItems.value }, - icon = navItem.icon?.let { { Icon(it, navItem.name) } }, + icon = navItem.icon?.let { { + if (navItem.iconGlyph != null) { + FontIcon(navItem.iconGlyph, navItem.icon, navItem.name) + } else { + Icon(it, navItem.name) + } + } }, content = { Text(navItem.name) }, expandItems = expandedItems.value, items = navItem.items?.let { @@ -235,4 +242,4 @@ private fun NavigationItem( ) } -private val settingItem = ComponentItem("Settings", group = "", description = "", icon = Icons.Default.Settings) { SettingsScreen() } \ No newline at end of file +private val settingItem = ComponentItem("Settings", group = "", description = "", icon = Icons.Default.Settings, iconGlyph = '\uE713') { SettingsScreen() } \ No newline at end of file diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/annotation/Component.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/annotation/Component.kt index 84a8e8ea..a06f363e 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/annotation/Component.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/annotation/Component.kt @@ -4,6 +4,7 @@ package com.konyaco.fluent.gallery.annotation annotation class Component( val name: String = "", val icon: String = "", + val iconGlyph: Char = 'A', val description: String = "", val group: String = "_Auto", val index: Int = -1, diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/annotation/ComponentGroup.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/annotation/ComponentGroup.kt index 4f845549..1753f8df 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/annotation/ComponentGroup.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/annotation/ComponentGroup.kt @@ -3,6 +3,7 @@ package com.konyaco.fluent.gallery.annotation @Target(AnnotationTarget.PROPERTY) annotation class ComponentGroup( val icon: String, + val iconGlyph: Char = 'A', val index: Int = Int.MAX_VALUE, val generateScreen: Boolean = true, val packageMap: String = "" diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/ComponentGroupInfo.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/ComponentGroupInfo.kt index a95859f3..61810d5d 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/ComponentGroupInfo.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/ComponentGroupInfo.kt @@ -8,54 +8,54 @@ object ComponentGroupInfo { private const val screenPackage: String = "com.konyaco.fluent.gallery.screen" - @ComponentGroup("Ruler", index = 0, generateScreen = false, packageMap = "$screenPackage.design") + @ComponentGroup("Ruler", iconGlyph = '\uEB3C', index = 0, generateScreen = false, packageMap = "$screenPackage.design") const val DesignGuidance = "Design guidance" - @ComponentGroup("Accessibility", generateScreen = false, index = 3) + @ComponentGroup("Accessibility", iconGlyph = '\uE776', generateScreen = false, index = 3) const val Accessibility = "Design guidance/Accessibility" - @ComponentGroup("CheckboxChecked", index = 2, packageMap = "$screenPackage.basicinput") + @ComponentGroup("CheckboxChecked", iconGlyph = '\uE73A', index = 2, packageMap = "$screenPackage.basicinput") const val BasicInput = "Basic input" - @ComponentGroup("Table", index = 3, packageMap = "$screenPackage.collections") + @ComponentGroup("Table", iconGlyph = '\uE80A', index = 3, packageMap = "$screenPackage.collections") const val Collections = "Collections" - @ComponentGroup("CalendarClock", index = 4, packageMap = "$screenPackage.datetime") + @ComponentGroup("CalendarClock", iconGlyph = '\uEC92', index = 4, packageMap = "$screenPackage.datetime") const val DateAndTime = "Date & time" - @ComponentGroup("Chat", index = 5, packageMap = "$screenPackage.dialogs") + @ComponentGroup("Chat", iconGlyph = '\uE8BD', index = 5, packageMap = "$screenPackage.dialogs") const val DialogAndFlyout = "Dialog & flyouts" - @ComponentGroup("SlideLayout", index = 6) + @ComponentGroup("SlideLayout", iconGlyph = '\uE8A1', index = 6) const val Layout = "Layout" - @ComponentGroup("VideoClip", index = 7) + @ComponentGroup("VideoClip", iconGlyph = '\uE786', index = 7) const val Media = "Media" - @ComponentGroup("Save", index = 8) + @ComponentGroup("Save", iconGlyph = '\uE74E', index = 8) const val MenusAndToolbars = "Menus & toolbars" - @ComponentGroup("Flash", index = 9) + @ComponentGroup("Flash", iconGlyph = '\uE945', index = 9) const val Motion = "Motion" - @ComponentGroup("Navigation", index = 10, packageMap = "$screenPackage.navigation") + @ComponentGroup("Navigation", iconGlyph = '\uE700', index = 10, packageMap = "$screenPackage.navigation") const val Navigation = "Navigation" - @ComponentGroup("ArrowSort", index = 11) + @ComponentGroup("ArrowSort", iconGlyph = '\uE174', index = 11) const val Scrolling = "Scrolling" - @ComponentGroup("ChatMultiple", index = 12, packageMap = "$screenPackage.status") + @ComponentGroup("ChatMultiple", iconGlyph = '\uE8F2', index = 12, packageMap = "$screenPackage.status") const val StatusAndInfo = "Status & info" - @ComponentGroup("Color", index = 13, packageMap = "$screenPackage.styles") + @ComponentGroup("Color", iconGlyph = '\uE2B1', index = 13, packageMap = "$screenPackage.styles") const val Styles = "Styles" - @ComponentGroup("System", index = 14) + @ComponentGroup("System", iconGlyph = '\uE770', index = 14) const val System = "System" - @ComponentGroup("TextFont", index = 15, packageMap = "$screenPackage.text") + @ComponentGroup("TextFont", iconGlyph = '\uE8D2', index = 15, packageMap = "$screenPackage.text") const val Text = "Text" - @ComponentGroup("Window", index = 16) + @ComponentGroup("Window", iconGlyph = '\uE7C4', index = 16) const val Windowing = "Windowing" } \ No newline at end of file diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/ComponentItem.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/ComponentItem.kt index 36e652d5..1a22e401 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/ComponentItem.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/ComponentItem.kt @@ -9,5 +9,6 @@ class ComponentItem( val description: String, val items: List? = null, val icon: ImageVector? = null, + val iconGlyph: Char? = null, val content: (@Composable ComponentItem.(navigator: ComponentNavigator) -> Unit)? ) diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/CopyButton.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/CopyButton.kt index b76d693f..08517b54 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/CopyButton.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/CopyButton.kt @@ -11,7 +11,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.text.AnnotatedString import com.konyaco.fluent.component.Button -import com.konyaco.fluent.component.Icon import com.konyaco.fluent.icons.Icons import com.konyaco.fluent.icons.regular.Checkmark import com.konyaco.fluent.icons.regular.Copy @@ -39,9 +38,9 @@ fun CopyButton( content = { AnimatedContent(isCopy) { target -> if (target) { - Icon(Icons.Default.Checkmark, contentDescription = null) + FontIcon('\uE73E', Icons.Default.Checkmark, contentDescription = null) } else { - Icon(Icons.Default.Copy, contentDescription = null) + FontIcon('\uE8C8', Icons.Default.Copy, contentDescription = null) } } }, diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/GalleryHeader.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/GalleryHeader.kt index 00936785..aacdce2d 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/GalleryHeader.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/GalleryHeader.kt @@ -97,10 +97,11 @@ fun GalleryHeader( uriHandler.openUri(ProjectUrl.documentationOf(documentPath)) }, content = { - Icon( - Icons.Default.Document, + FontIcon( + glyph = '\uE8A5', + vector = Icons.Default.Document, contentDescription = null, - modifier = Modifier.size(18.dp) + vectorSize = 18.dp ) Text("Documentation") } @@ -153,10 +154,11 @@ fun GalleryHeader( checked = themeButtonChecked, onCheckedChanged = onThemeButtonChanged, content = { - Icon( - Icons.Filled.BrightnessHigh, + FontIcon( + glyph = '\uE793', + vector = Icons.Filled.BrightnessHigh, contentDescription = null, - modifier = Modifier.size(18.dp) + vectorSize = 18.dp ) }, iconOnly = true, @@ -169,10 +171,11 @@ fun GalleryHeader( Button( onClick = { uriHandler.openUri(ProjectUrl.FEED_BACK) }, content = { - Icon( - Icons.Default.PersonFeedback, + FontIcon( + glyph = '\uED15', + vector = Icons.Default.PersonFeedback, contentDescription = null, - modifier = Modifier.size(18.dp) + vectorSize = 18.dp ) }, iconOnly = true, diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/AllSamplesScreen.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/AllSamplesScreen.kt index 144774e7..a9b56cf1 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/AllSamplesScreen.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/AllSamplesScreen.kt @@ -6,7 +6,7 @@ import com.konyaco.fluent.gallery.component.* import com.konyaco.fluent.gallery.component._AllSamplesScreenComponent import com.konyaco.fluent.gallery.component._HomeScreenComponent -@Component(icon = "AppsList", index = 1, name = "All samples") +@Component(icon = "AppsList", iconGlyph = '\uE71D', index = 1, name = "All samples") @Composable fun AllSamplesScreen(navigator: ComponentNavigator) { var allComponents by remember { diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/HomeScreen.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/HomeScreen.kt index e0fd9d90..70b9e360 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/HomeScreen.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/HomeScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -22,15 +23,18 @@ import androidx.compose.ui.draw.scale import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.konyaco.fluent.FluentTheme -import com.konyaco.fluent.component.Icon +import com.konyaco.fluent.LocalContentAlpha +import com.konyaco.fluent.LocalContentColor import com.konyaco.fluent.component.Text import com.konyaco.fluent.gallery.LocalStore import com.konyaco.fluent.gallery.ProjectUrl import com.konyaco.fluent.gallery.annotation.Component +import com.konyaco.fluent.gallery.component.FontIcon import com.konyaco.fluent.icons.Icons import com.konyaco.fluent.icons.regular.Open import com.konyaco.fluent.surface.Card @@ -39,14 +43,12 @@ import fluentdesign.gallery.generated.resources.banner import fluentdesign.gallery.generated.resources.fluent_logo import fluentdesign.gallery.generated.resources.github_logo import fluentdesign.gallery.generated.resources.jetpack_compose_logo -import org.jetbrains.compose.resources.ExperimentalResourceApi +import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.painterResource -@OptIn(ExperimentalResourceApi::class) -@Component(icon = "Home") +@Component(icon = "Home", iconGlyph = '\uE80F') @Composable fun HomeScreen() { - val uriHandler = LocalUriHandler.current Column( Modifier .verticalScroll(rememberScrollState()) @@ -95,119 +97,79 @@ fun HomeScreen() { ) } - Card( - onClick = { - uriHandler.openUri(ProjectUrl.FRAMEWORK) - }, - modifier = Modifier.fillMaxWidth() - ) { - Row( - Modifier.fillMaxWidth().padding(12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Image( - painter = painterResource(Res.drawable.jetpack_compose_logo), - contentDescription = null, - modifier = Modifier.size(64.dp) - ) - Column( - modifier = Modifier.weight(1f).padding(start = 16.dp) - ) { - Text( - text = "Jetpack Compose", - style = FluentTheme.typography.bodyLarge - ) - Spacer(modifier = Modifier.height(4.dp)) - Text( - text = "A powerful toolkit to build beautiful UI on multiple platforms.", - style = FluentTheme.typography.body, - color = FluentTheme.colors.text.text.secondary - ) - } - Icon( - Icons.Default.Open, - contentDescription = "Open Link", - Modifier.padding(end = 16.dp), - tint = FluentTheme.colors.text.text.secondary - ) - } - } + HomeCardItem( + url = ProjectUrl.FRAMEWORK, + icon = Res.drawable.jetpack_compose_logo, + title = "Jetpack Compose", + caption = "A powerful toolkit to build beautiful UI on multiple platforms." + ) - Card( - onClick = { - uriHandler.openUri(ProjectUrl.UI_DESIGN) - }, - modifier = Modifier.fillMaxWidth() + HomeCardItem( + url = ProjectUrl.UI_DESIGN, + icon = Res.drawable.fluent_logo, + title = "Fluent Design", + caption = "A modern design system face to desktop and other platforms.", + iconColorFilter = ColorFilter.tint(FluentTheme.colors.text.text.primary) + ) + HomeCardItem( + url = ProjectUrl.ROOT, + icon = Res.drawable.github_logo, + title = "compose-fluent-ui", + caption = "View our source code on GitHub.", + iconColorFilter = ColorFilter.tint(FluentTheme.colors.text.text.primary) + ) + } +} + +@Composable +private fun HomeCardItem( + url: String, + icon: DrawableResource, + title: String, + caption: String, + iconColorFilter: ColorFilter? = null +) { + val uriHandler = LocalUriHandler.current + Card( + onClick = { + uriHandler.openUri(url) + }, + modifier = Modifier.fillMaxWidth() + ) { + Row( + Modifier.fillMaxWidth().padding(12.dp), + verticalAlignment = Alignment.CenterVertically ) { - Row( - Modifier.fillMaxWidth().padding(12.dp), - verticalAlignment = Alignment.CenterVertically + Image( + painter = painterResource(icon), + contentDescription = null, + modifier = Modifier.size(64.dp).padding(12.dp), + colorFilter = iconColorFilter, + ) + Column( + modifier = Modifier.weight(1f).padding(start = 16.dp) ) { - Icon( - painter = painterResource(Res.drawable.fluent_logo), - contentDescription = null, - modifier = Modifier.size(64.dp).padding(8.dp), - tint = FluentTheme.colors.text.text.primary + Text( + text = title, + style = FluentTheme.typography.bodyLarge ) - Column( - modifier = Modifier.weight(1f).padding(start = 16.dp) - ) { - Text( - text = "Fluent Design", - style = FluentTheme.typography.bodyLarge - ) - Spacer(modifier = Modifier.height(4.dp)) - Text( - text = "A modern design system face to desktop and other platforms.", - style = FluentTheme.typography.body, - color = FluentTheme.colors.text.text.secondary - ) - } - Icon( - Icons.Default.Open, - contentDescription = "Open Link", - Modifier.padding(end = 16.dp), - tint = FluentTheme.colors.text.text.secondary + Spacer(modifier = Modifier.height(4.dp)) + Text( + text = caption, + style = FluentTheme.typography.body, + color = FluentTheme.colors.text.text.secondary ) } - } - - Card( - onClick = { - uriHandler.openUri(ProjectUrl.ROOT) - }, - modifier = Modifier.fillMaxWidth() - ) { - Row( - Modifier.fillMaxWidth().padding(12.dp), - verticalAlignment = Alignment.CenterVertically + CompositionLocalProvider( + LocalContentColor provides FluentTheme.colors.text.text.secondary, + LocalContentAlpha provides FluentTheme.colors.text.text.secondary.alpha ) { - Icon( - painter = painterResource(Res.drawable.github_logo), - contentDescription = null, - modifier = Modifier.size(64.dp).padding(12.dp), - tint = FluentTheme.colors.text.text.primary - ) - Column( - modifier = Modifier.weight(1f).padding(start = 16.dp) - ) { - Text( - text = "compose-fluent-ui", - style = FluentTheme.typography.bodyLarge - ) - Spacer(modifier = Modifier.height(4.dp)) - Text( - text = "View our source code on GitHub.", - style = FluentTheme.typography.body, - color = FluentTheme.colors.text.text.secondary - ) - } - Icon( - Icons.Default.Open, + FontIcon( + glyph = '\uE8A7', + vector = Icons.Default.Open, contentDescription = "Open Link", - Modifier.padding(end = 16.dp), - tint = FluentTheme.colors.text.text.secondary + modifier = Modifier.padding(end = 16.dp) ) } } diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/IconsScreen.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/IconsScreen.kt index 370c1a0a..8a270847 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/IconsScreen.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/IconsScreen.kt @@ -66,7 +66,7 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce @OptIn(FlowPreview::class, ExperimentalFluentApi::class, ExperimentalFoundationApi::class) -@Component(index = 1, name = "Icons", icon = "Diversity") +@Component(index = 1, name = "Icons", icon = "Diversity", iconGlyph = '\uED58') @Composable fun IconsScreen() { GalleryPage( diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/TypographyScreen.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/TypographyScreen.kt index 48ee14d8..ef3bfac9 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/TypographyScreen.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/TypographyScreen.kt @@ -30,6 +30,7 @@ import com.konyaco.fluent.gallery.component.HeaderItemRow import com.konyaco.fluent.gallery.component.ItemRow import com.konyaco.fluent.source.generated.FluentSourceFile +@Component(index = 1, icon = "TextFont", iconGlyph = '\uE8D2') @OptIn(ExperimentalTextApi::class) @Component(index = 1, icon = "TextFont") @Composable From 1ebcd763f3dc6ba031abe890133b913ddfc1feac Mon Sep 17 00:00:00 2001 From: sanlorng Date: Fri, 14 Jun 2024 01:06:56 +0800 Subject: [PATCH 3/5] [gallery] support disable font icon for testing gallery vector icon. --- .../konyaco/fluent/gallery/GalleryTheme.kt | 21 ++++++++++++++++--- .../fluent/gallery/component/FontIcon.kt | 3 +-- .../gallery/screen/settings/SettingsScreen.kt | 9 ++++++-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/GalleryTheme.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/GalleryTheme.kt index d6c37a7e..f3efd1d6 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/GalleryTheme.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/GalleryTheme.kt @@ -6,6 +6,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import com.konyaco.fluent.* import com.konyaco.fluent.background.Mica +import com.konyaco.fluent.gallery.component.LocalFontIconFontFamily import com.konyaco.fluent.gallery.component.ProvideFontIcon val LocalStore = compositionLocalOf { error("Not provided") } @@ -13,13 +14,16 @@ val LocalStore = compositionLocalOf { error("Not provided") } class Store( systemDarkMode: Boolean, enabledAcrylicPopup: Boolean, - compactMode: Boolean + compactMode: Boolean, + fontIconEnabled: Boolean ) { var darkMode by mutableStateOf(systemDarkMode) var enabledAcrylicPopup by mutableStateOf(enabledAcrylicPopup) var compactMode by mutableStateOf(compactMode) + + var fontIconEnabled by mutableStateOf(fontIconEnabled) } @OptIn(ExperimentalFluentApi::class) @@ -34,7 +38,8 @@ fun GalleryTheme( Store( systemDarkMode = systemDarkMode, enabledAcrylicPopup = true, - compactMode = true + compactMode = true, + fontIconEnabled = true ) } @@ -44,7 +49,7 @@ fun GalleryTheme( CompositionLocalProvider( LocalStore provides store ) { - ProvideFontIcon { + ProvideFontIcon(store.fontIconEnabled) { FluentTheme( colors = if (store.darkMode) darkColors() else lightColors(), useAcrylicPopup = store.enabledAcrylicPopup, @@ -63,4 +68,14 @@ fun GalleryTheme( } } } +} + +@Composable +private fun ProvideFontIcon(enabled: Boolean, content: @Composable () -> Unit) { + ProvideFontIcon { + CompositionLocalProvider( + LocalFontIconFontFamily provides if (enabled) LocalFontIconFontFamily.current else null, + content = content + ) + } } \ No newline at end of file diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.kt index 58f90665..ca101f81 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/component/FontIcon.kt @@ -68,5 +68,4 @@ internal expect fun ProvideFontIcon( content: @Composable () -> Unit ) -internal val LocalFontIconFontFamily = - staticCompositionLocalOf { error("No Font provide for load font icon") } \ No newline at end of file +internal val LocalFontIconFontFamily = staticCompositionLocalOf { null } \ No newline at end of file diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/settings/SettingsScreen.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/settings/SettingsScreen.kt index d76ed6ab..8c03f59f 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/settings/SettingsScreen.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/settings/SettingsScreen.kt @@ -89,7 +89,9 @@ fun SettingsScreen() { acrylicPopupEnabled = store.enabledAcrylicPopup, onAcrylicPopupChange = { store.enabledAcrylicPopup = it }, compactModeEnabled = store.compactMode, - onCompactModeChange = { store.compactMode = it } + onCompactModeChange = { store.compactMode = it }, + fontIconEnabled = store.fontIconEnabled, + onFontIconEnabledChanged = { store.fontIconEnabled = it } ) CompositionLocalProvider(LocalDensity provides Density(scale)) { @@ -259,7 +261,9 @@ private fun Controller( acrylicPopupEnabled: Boolean, onAcrylicPopupChange: (Boolean) -> Unit, compactModeEnabled: Boolean, - onCompactModeChange: (Boolean) -> Unit + onCompactModeChange: (Boolean) -> Unit, + fontIconEnabled: Boolean, + onFontIconEnabledChanged: (Boolean) -> Unit, ) { Row( verticalAlignment = Alignment.CenterVertically, @@ -271,6 +275,7 @@ private fun Controller( Switcher(darkMode, text = "Dark Mode", onCheckStateChange = { onDarkModeChange(it) }) Switcher(acrylicPopupEnabled, text = "Acrylic Popup", onCheckStateChange = { onAcrylicPopupChange(it) }) Switcher(compactModeEnabled, text = "Compact Mode", onCheckStateChange = { onCompactModeChange(it) }) + Switcher(fontIconEnabled, text = "Font Icon", onCheckStateChange = { onFontIconEnabledChanged(it) }) } Slider( modifier = Modifier.width(200.dp), From 275ee57036a188e7b7873b53eee888c4f9d133cc Mon Sep 17 00:00:00 2001 From: sanlorng Date: Mon, 23 Sep 2024 22:02:46 +0800 Subject: [PATCH 4/5] [fluent] Fixed TypographyScreen compile error. --- .../konyaco/fluent/gallery/screen/design/TypographyScreen.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/TypographyScreen.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/TypographyScreen.kt index ef3bfac9..7053a6e7 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/TypographyScreen.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/TypographyScreen.kt @@ -30,9 +30,8 @@ import com.konyaco.fluent.gallery.component.HeaderItemRow import com.konyaco.fluent.gallery.component.ItemRow import com.konyaco.fluent.source.generated.FluentSourceFile -@Component(index = 1, icon = "TextFont", iconGlyph = '\uE8D2') @OptIn(ExperimentalTextApi::class) -@Component(index = 1, icon = "TextFont") +@Component(index = 1, icon = "TextFont", iconGlyph = '\uE8D2') @Composable fun TypographyScreen() { val linkTextColor = FluentTheme.colors.text.accent.primary From b580b07fcc212415ca76501b5219ebde630f9447 Mon Sep 17 00:00:00 2001 From: sanlorng Date: Fri, 18 Oct 2024 18:48:29 +0800 Subject: [PATCH 5/5] [gallery] Add icon glyph for `Elevation` and `Geometry` --- .../com/konyaco/fluent/gallery/screen/design/ElevationScreen.kt | 2 +- .../com/konyaco/fluent/gallery/screen/design/GeometryScreen.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/ElevationScreen.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/ElevationScreen.kt index cac0696c..6126e802 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/ElevationScreen.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/ElevationScreen.kt @@ -37,7 +37,7 @@ import com.konyaco.fluent.gallery.component.GalleryPage import com.konyaco.fluent.source.generated.FluentSourceFile @OptIn(ExperimentalFluentApi::class) -@Component(index = 0, icon = "Layer") +@Component(index = 0, icon = "Layer", iconGlyph = '\uE81E') @Composable fun ElevationScreen() { GalleryPage( diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/GeometryScreen.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/GeometryScreen.kt index efb216e5..7d764b52 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/GeometryScreen.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/screen/design/GeometryScreen.kt @@ -26,7 +26,7 @@ import com.konyaco.fluent.gallery.component.HeaderItemRow import com.konyaco.fluent.gallery.component.ItemRow import com.konyaco.fluent.source.generated.FluentSourceFile -@Component(index = 1, icon = "Shapes") +@Component(index = 1, icon = "Shapes", iconGlyph = '\uE743') @Composable fun GeometryScreen() { GalleryPage(