
net.peanuuutz.fork.ui.preset.Divider.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fork-ui Show documentation
Show all versions of fork-ui Show documentation
Comprehensive API designed for Minecraft modders
The newest version!
/*
* Copyright 2020 The Android Open Source Project
* Modifications Copyright 2022 Peanuuutz
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.peanuuutz.fork.ui.preset
import androidx.compose.runtime.Composable
import androidx.compose.runtime.NonRestartableComposable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import net.peanuuutz.fork.render.screen.clip.ClipOp
import net.peanuuutz.fork.ui.foundation.draw.background
import net.peanuuutz.fork.ui.foundation.layout.Arrangement
import net.peanuuutz.fork.ui.foundation.layout.Spacer
import net.peanuuutz.fork.ui.foundation.layout.fillMaxWidth
import net.peanuuutz.fork.ui.foundation.layout.height
import net.peanuuutz.fork.ui.foundation.layout.list.Row
import net.peanuuutz.fork.ui.foundation.layout.padding
import net.peanuuutz.fork.ui.foundation.text.LocalTextStyle
import net.peanuuutz.fork.ui.inspection.InspectInfo
import net.peanuuutz.fork.ui.ui.draw.ContentDrawScope
import net.peanuuutz.fork.ui.ui.draw.DrawScope
import net.peanuuutz.fork.ui.ui.draw.canvas.DrawStyle
import net.peanuuutz.fork.ui.ui.draw.shading.Brush
import net.peanuuutz.fork.ui.ui.draw.text.Paragraph
import net.peanuuutz.fork.ui.ui.draw.text.TextAlign
import net.peanuuutz.fork.ui.ui.draw.text.TextStyle
import net.peanuuutz.fork.ui.ui.draw.withClip
import net.peanuuutz.fork.ui.ui.layout.Alignment
import net.peanuuutz.fork.ui.ui.modifier.Modifier
import net.peanuuutz.fork.ui.ui.modifier.ModifierNodeElement
import net.peanuuutz.fork.ui.ui.node.DrawModifierNode
import net.peanuuutz.fork.ui.ui.node.ModifierNode
import net.peanuuutz.fork.ui.ui.unit.FloatOffset
@NonRestartableComposable
@Composable
fun Divider(
modifier: Modifier = Modifier,
brush: Brush = Brush.solid(LocalContentColor.current),
thickness: Int = 1,
padding: Int = 0
) {
Spacer(
modifier = modifier
.fillMaxWidth()
.height(thickness)
.padding(horizontal = padding)
.background(brush)
)
}
@Composable
fun TextDivider(
paragraph: Paragraph,
modifier: Modifier = Modifier,
textStyle: TextStyle = LocalTextStyle.current,
lineBrush: Brush = Brush.solid(LocalContentColor.current),
lineThickness: Int = 1,
innerPadding: Int = 12,
outerPadding: Int = 0
) {
val textWidthState = remember { mutableStateOf(0.0f) }
Row(
modifier = modifier
.fillMaxWidth()
.padding(horizontal = outerPadding)
.textDivider(
textWidthProvider = textWidthState::value,
lineBrush = lineBrush,
lineThickness = lineThickness,
innerPadding = innerPadding
),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Text(
paragraph = paragraph,
textAlign = TextAlign.Center,
textStyle = textStyle,
onTextLayout = { result ->
textWidthState.value = result.measuredParagraph.measuredSize.width
}
)
}
}
// ======== Internal ========
private fun Modifier.textDivider(
textWidthProvider: () -> Float,
lineBrush: Brush,
lineThickness: Int,
innerPadding: Int
): Modifier {
val element = TextDividerModifier(
textWidthProvider = textWidthProvider,
lineBrush = lineBrush,
lineThickness = lineThickness,
innerPadding = innerPadding
)
return this then element
}
private data class TextDividerModifier(
val textWidthProvider: () -> Float,
val lineBrush: Brush,
val lineThickness: Int,
val innerPadding: Int
) : ModifierNodeElement() {
override fun create(): TextDividerModifierNode {
return TextDividerModifierNode(
textWidthProvider = textWidthProvider,
lineBrush = lineBrush,
lineThickness = lineThickness,
innerPadding = innerPadding
)
}
override fun update(node: TextDividerModifierNode) {
node.lineBrush = lineBrush
node.lineThickness = lineThickness
node.innerPadding = innerPadding
}
override fun InspectInfo.inspect() {
set("lineBrush", lineBrush)
set("lineThickness", lineThickness)
set("innerPadding", innerPadding)
}
}
private class TextDividerModifierNode(
val textWidthProvider: () -> Float,
var lineBrush: Brush,
var lineThickness: Int,
var innerPadding: Int
) : ModifierNode(), DrawModifierNode {
override fun ContentDrawScope.draw() {
drawDivider()
drawContent()
}
private fun DrawScope.drawDivider() {
val (width, height) = size
val centerX = width / 2
val centerY = height / 2
val halfClipBoxWidth = innerPadding + textWidthProvider() / 2
withClip(
leftX = centerX - halfClipBoxWidth,
topY = 0.0f,
rightX = centerX + halfClipBoxWidth,
bottomY = height,
op = ClipOp.Xor
) {
drawLine(
brush = lineBrush,
start = FloatOffset(0.0f, centerY),
end = FloatOffset(width, centerY),
stroke = DrawStyle.Stroke(width = lineThickness.toFloat())
)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy