-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scrollbars followup, Textareas, Textfields, and more #457
Conversation
hamen
commented
Jul 18, 2024
•
edited
Loading
edited
- TextAread and TextFields are now based on Compose 1.7 implementation
- Tabstrip scrollbar have a new style
Please add screenshots and videos of the scrollbars in action, and comparable Swing implementations, to help validate they look and behave as expected. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -11,7 +11,6 @@ | |||
<inspection_tool class="LanguageDetectionInspection" enabled="false" level="WARNING" enabled_by_default="false" /> | |||
<inspection_tool class="NoButtonGroup" enabled="false" level="WARNING" enabled_by_default="false" /> | |||
<inspection_tool class="NoScrollPane" enabled="false" level="WARNING" enabled_by_default="false" /> | |||
<inspection_tool class="StructuralWrap" enabled="false" level="INFORMATION" enabled_by_default="false" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this. The StructuralWrap inspection is incredibly unhelpful 🙃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still TODO
decorated-window/src/main/kotlin/org/jetbrains/jewel/window/DecoratedWindow.kt
Outdated
Show resolved
Hide resolved
ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt
Outdated
Show resolved
Hide resolved
ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt
Outdated
Show resolved
Hide resolved
ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt
Outdated
Show resolved
Hide resolved
samples/standalone/src/main/resources/icons/components/scroll.svg
Outdated
Show resolved
Hide resolved
state: TextFieldState, | ||
enabled: Boolean, | ||
readOnly: Boolean, | ||
outline: Outline, | ||
undecorated: Boolean, | ||
keyboardOptions: KeyboardOptions, | ||
singleLine: Boolean, | ||
maxLines: Int, | ||
interactionSource: MutableInteractionSource, | ||
style: InputFieldStyle, | ||
textStyle: TextStyle, | ||
modifier: Modifier = Modifier, | ||
decorationBox: @Composable (innerTextField: @Composable () -> Unit, state: InputFieldState) -> Unit, | ||
showScrollbar: Boolean = true, | ||
) { | ||
var inputState by remember(interactionSource) { | ||
mutableStateOf(InputFieldState.of(enabled = enabled)) | ||
} | ||
remember(enabled) { inputState = inputState.copy(enabled = enabled) } | ||
|
||
LaunchedEffect(interactionSource) { | ||
interactionSource.interactions.collect { interaction -> | ||
when (interaction) { | ||
is FocusInteraction.Focus -> inputState = inputState.copy(focused = true) | ||
is FocusInteraction.Unfocus -> inputState = inputState.copy(focused = false) | ||
} | ||
} | ||
} | ||
|
||
val colors = style.colors | ||
val backgroundColor by colors.backgroundFor(inputState) | ||
val shape = RoundedCornerShape(style.metrics.cornerSize) | ||
|
||
val backgroundModifier = | ||
Modifier.thenIf(!undecorated && backgroundColor.isSpecified) { | ||
background(backgroundColor, shape) | ||
} | ||
|
||
val borderColor by style.colors.borderFor(inputState) | ||
val hasNoOutline = outline == Outline.None | ||
val borderModifier = | ||
Modifier.thenIf(!undecorated && borderColor.isSpecified && hasNoOutline) { | ||
border( | ||
alignment = Stroke.Alignment.Center, | ||
width = style.metrics.borderWidth, | ||
color = borderColor, | ||
shape = shape, | ||
) | ||
} | ||
|
||
val contentColor by colors.contentFor(inputState) | ||
val mergedTextStyle = style.textStyle.merge(textStyle).copy(color = contentColor) | ||
val caretColor by colors.caretFor(inputState) | ||
|
||
val lineLimits = | ||
when { | ||
singleLine -> SingleLine | ||
else -> MultiLine(maxLines) | ||
} | ||
|
||
val scrollState = rememberScrollState() | ||
val canScroll by remember { | ||
derivedStateOf { | ||
scrollState.canScrollBackward || scrollState.canScrollForward | ||
} | ||
} | ||
|
||
Box( | ||
modifier = modifier | ||
.then(backgroundModifier) | ||
.then(borderModifier) | ||
.thenIf(!undecorated && hasNoOutline) { focusOutline(inputState, shape) } | ||
.outline(inputState, outline, shape, Stroke.Alignment.Center), | ||
) { | ||
BasicTextField( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.align(Alignment.CenterStart) | ||
.thenIf(canScroll && showScrollbar) { padding(end = 12.dp) }, | ||
state = state, | ||
enabled = enabled, | ||
readOnly = readOnly, | ||
textStyle = mergedTextStyle, | ||
cursorBrush = SolidColor(caretColor), | ||
keyboardOptions = keyboardOptions, | ||
lineLimits = lineLimits, | ||
interactionSource = interactionSource, | ||
decorator = { innerTextField: @Composable () -> Unit -> decorationBox(innerTextField, inputState) }, | ||
scrollState = scrollState, | ||
) | ||
|
||
if (showScrollbar) | ||
VerticalScrollbar( | ||
scrollState = scrollState, | ||
modifier = Modifier.align(Alignment.CenterEnd), | ||
interactionSource = interactionSource, | ||
) | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To keep this PR more legible, would it be possible to split the text area scrollbars work to a separate PR?
ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InputField.kt
Outdated
Show resolved
Hide resolved
ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InputField.kt
Outdated
Show resolved
Hide resolved
ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt
Outdated
Show resolved
Hide resolved
ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/ScrollbarBridge.kt
Outdated
Show resolved
Hide resolved
scrollbarVisibility = scrollbarVisibility, | ||
) | ||
|
||
public fun ScrollbarStyle.Companion.winOsDark( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
windowsAndLinux*
here and below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in a37a196
) | ||
} | ||
var alwaysVisible by remember { mutableStateOf(false) } | ||
val resolvedStyle = readStyle() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this meant to be done to detect the initial style? I think the issue here is that this will be re-executed on every composition. You should probably call this "baseStyle", and remember(JewelTheme.isDark) it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 9af3d55
...i-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStyling.kt
Outdated
Show resolved
Hide resolved
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
Signed-off-by: Ivan Morgillo <[email protected]>
...dalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiScrollbarStyling.kt
Outdated
Show resolved
Hide resolved
...dalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiScrollbarStyling.kt
Outdated
Show resolved
Hide resolved
...dalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiScrollbarStyling.kt
Outdated
Show resolved
Hide resolved
...dalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiScrollbarStyling.kt
Outdated
Show resolved
Hide resolved
...dalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiScrollbarStyling.kt
Outdated
Show resolved
Hide resolved
...andalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextFields.kt
Outdated
Show resolved
Hide resolved
...andalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextFields.kt
Outdated
Show resolved
Hide resolved
...andalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextFields.kt
Outdated
Show resolved
Hide resolved
reference: #457 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>
if (isHighlighted) { | ||
style.colors.thumbBackgroundHovered | ||
} else { | ||
style.colors.thumbBackgroundHovered |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style.colors.thumbBackgroundHovered | |
style.colors.thumbBackground |
if (isHighlighted) { | ||
style.colors.thumbBackgroundHovered | ||
} else { | ||
style.colors.thumbBackgroundHovered |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style.colors.thumbBackgroundHovered | |
style.colors.thumbBackground |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 70d2cda
state: TextFieldState, | ||
enabled: Boolean, | ||
readOnly: Boolean, | ||
outline: Outline, | ||
undecorated: Boolean, | ||
keyboardOptions: KeyboardOptions, | ||
singleLine: Boolean, | ||
maxLines: Int, | ||
interactionSource: MutableInteractionSource, | ||
style: InputFieldStyle, | ||
textStyle: TextStyle, | ||
modifier: Modifier = Modifier, | ||
decorationBox: @Composable (innerTextField: @Composable () -> Unit, state: InputFieldState) -> Unit, | ||
showScrollbar: Boolean, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
state: TextFieldState, | |
enabled: Boolean, | |
readOnly: Boolean, | |
outline: Outline, | |
undecorated: Boolean, | |
keyboardOptions: KeyboardOptions, | |
singleLine: Boolean, | |
maxLines: Int, | |
interactionSource: MutableInteractionSource, | |
style: InputFieldStyle, | |
textStyle: TextStyle, | |
modifier: Modifier = Modifier, | |
decorationBox: @Composable (innerTextField: @Composable () -> Unit, state: InputFieldState) -> Unit, | |
showScrollbar: Boolean, | |
state: TextFieldState, | |
enabled: Boolean, | |
readOnly: Boolean, | |
outline: Outline, | |
undecorated: Boolean, | |
keyboardOptions: KeyboardOptions, | |
singleLine: Boolean, | |
maxLines: Int, | |
interactionSource: MutableInteractionSource, | |
style: InputFieldStyle, | |
textStyle: TextStyle, | |
showScrollbar: Boolean, | |
modifier: Modifier, | |
decorationBox: @Composable (innerTextField: @Composable () -> Unit, state: InputFieldState) -> Unit, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in e494398
.editorconfig
Outdated
@@ -16,11 +16,14 @@ indent_size = 2 | |||
[*.yml] | |||
indent_size = 2 | |||
|
|||
# noinspection EditorConfigKeyCorrectness |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this file.
Modifier.defaultMinSize(minWidth = minSize.width, minHeight = minSize.height) | ||
.padding(style.metrics.contentPadding), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this.
public value class InputFieldState( | ||
public val state: ULong, | ||
) : FocusableComponentState { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this.
(if (enabled) Enabled else 0UL) or | ||
(if (focused) Focused else 0UL) or | ||
(if (hovered) Hovered else 0UL) or | ||
(if (pressed) Pressed else 0UL) or | ||
(if (active) Active else 0UL), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this.
derivedStateOf { | ||
isHovered || dragInteraction.value is DragInteraction.Start | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this.
thumbColor, | ||
RoundedCornerShape(style.metrics.thumbCornerSize), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this.
measurables | ||
.single { it.layoutId == TEXT_AREA_ID } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this.
reference: #457 (comment) Signed-off-by: Ivan Morgillo <[email protected]>
reference: #457 (comment) Signed-off-by: Ivan Morgillo <[email protected]>