Features
New Date controls
MonthPanel is a customizable control that shows the days of a given month in a year. The panel allows full customization of the rendering for each day as well as selection handling via an ItemVisualizer. This control is a building block that can be used to create calendars and date selectors.
Days in the month are rendered using the ItemVisualizer. This can be set directly when creating the panel, or it can be provided via an installed MonthPanelBehavior. Selection of days within the panel is controlled by the SelectionModel installed when the panel is created.
val today = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date
val panel = MonthPanel(today, /*itemVisualizer, selectionModel*/)This release also contains BasicMonthPanelBehavior, which provides a simple day visualizer. You can also install it into a Theme
using basicMonthPanelBehavior(...).
There is also a new DaysOfTheWeekPanel control for displaying days of the week intended for use along with MonthPanel.
It allows fully customizable display for each day (via an ItemVisualizer) as well as control over how the days are sorted.
New behaviors in BasicTheme for MonthPanel via basicMonthPanelBehavior(...) and DaysOfTheWeekPanel via basicDaysOfTheWeekPanelBehavior(...)
Range Sliders
New RangeSlider and CircularRangeSlider controls that allow the selection of a range of strongly-typed values. These are analogs to Slider and CiruclarSlider. Both also have new behaviors in Basic Theme.
You can create these sliders in a similar fashion to the value sliders.
val slider = RangeSlider (range = 0 .. 100, value = 4 .. 10)
val circularSlider = CircularRangeSlider(range = 0 .. 100, value = 4 .. 10)Tick Marks For (BasicSliderBehavior and BasicRangeSliderBehavior)
The basic behaviors can now display tick marks when a Slider or RangeSlider has ticks set to a value larger than 1. This is done via their showTicks parameter. Ticks can be shown either on the slider's groove, or on both the groove and range.
More Flexible Lists
List and its variants now have better support for items positioned in an arbitrary way. Previously, the List class itself assumed a vertical
layout and only used the y-component of its viewport to determine which items to render. This has been updated so both the top-left and bottom-right points on the List are now used.
There are now two new ItemPositioners to make laying out vertical hand horizontal lists easier. VerticalListPositioner allows you to specify the number of columns for the list, while HorizontalListPositioner lets you give a number of rows. These can be used directly with custom ListBehaviors or, they can be used with BasicListBehavior directly, or via the basicListBehavior and basicHorizontalListBehavior modules when using a Theme.
Vertical + Horizontal List Variants
List contents can be positioned using an ItemPositioner, which the List gets from its ListBehavior. But specifying the layout for a single list means installing a behavior on it directly, since any theme used will provide the same behavior to all lists.
The new variants allow themes to identify lists that should be explicitly vertical or horizontal for cases when it is less convenient to use explicit behaviors.
// ...
import io.nacular.doodle.theme.basic.list.basicHorizontalListBehavior
import io.nacular.doodle.theme.basic.BasicTheme.Companion.basicHorizontalListBehavior
val manualHorizontalList = List(0..10).apply {
acceptsThemes = false // prevent behavior from being swapped if theme present
behavior = basicHorizontalListBehavior(itemWidth = 300.0, numRows = 2) // or some other custom behavior
}
// Will be same as above when using BasicTheme.basicHorizontalListBehavior() module
val autoHorizontalList = HorizontalList(0..10, numRows = 2)New Platform-specific Desktop Artifacts
Previously apps would depend on the desktop-jvm library when targeting desktop. The problem with this approach is skiko is inherently platform-specific and the published library would depend on the build machine. Therefore, apps would only run on the same OS as the library build machine.
This release introduces new platform library artifacts to fix this issue. Apps will now depend on the new desktop-jvm-{platform} library instead.
dependencies {
implementation("io.nacular.doodle:desktop-jvm:$doodleVersion") // <----- Incorrect
}dependencies {
val osName = System.getProperty("os.name")
val targetOs = when {
osName == "Mac OS X" -> "macos"
osName.startsWith("Win") -> "windows"
osName.startsWith("Linux") -> "linux"
else -> error("Unsupported OS: $osName")
}
val osArch = System.getProperty("os.arch")
val targetArch = when (osArch) {
"x86_64", "amd64" -> "x64"
"aarch64" -> "arm64"
else -> error("Unsupported arch: $osArch")
}
val target = "$targetOs-$targetArch"
implementation("io.nacular.doodle:desktop-jvm-$target:$doodleVersion") // <----- CORRECT: use platform-specific version of desktop-jvm artifact
}This approach is a bit messy, so there might be some future work on a Gradle plugin to make this simpler.
APIs
- Various models now return
Result<T>instead ofT?, which allows them to hold null and continue representing the concept of a missing or invalid value request. ItemEditor<T>now returnsResult<T>.- Various bounds properties in
Vieware nowfinal. - View's children can now be clipped by a
Path. - Canvas now supports clipping using a
Path. - List and its variants now take a set for
fitContentthat allow control over whether the list fits the width, height or both. TextFithas been replaced with the more generalDimension.- Basic slider behaviors can now be constructed with lambdas that allow more dynamic Painting based on the state of the slider.
BasicCircularSliderBehaviormoved to packageio.nacular.doodle.theme.basic.range.- Basic range slider behaviors now take start and end knob paint configs.
- New View extension
scrollTo(Rectangle)that handles scrolling the most recentScrollPanelancestor to show a rectangle within the View. - Changed
DragOperation.visualOffsetso positive values of x and y move the drag image in the positive x and y direction relative to the cursor, instead of the negative. - Renamed
GridPanel.verticalSpacingandGridPanel.horizontalSpacingtoGridPanel.rowSpacingandGridPanel.columnSpacing. - Renamed
io.nacular.doodle.controls.spinner.Modeltoio.nacular.doodle.controls.spinner.SpinnerModel. Also renamed many descendants.
Fixes | Improvements
- General
- Fixed bug in form control check/switch lists where they did not properly update the form.
- Fixed pointer event bug for disabled
ScrollPanelwith native behavior. - ValueSlider now rounds when converting floating-point values to integers.
- Improved slider snapping behavior for basic behaviors.
- GridPanel now updates whenever relevant properties change
- GridPanel now supports
inset - GridPanel now has behavior support
- Fixed several basic behaviors so they rerender their view when installed to avoid stale styling on theme change.
- Fixed slider support for negative range values.
- Sliders now update their value when
snapToTicksis set. - Improved key handling for sliders with tick snapping.
- Layout constraints are now comparable, making comparisons like
constrain(view) { it.left < parent.right - 10 }possible.
- Browser
- Fixed bug with corner radius of re-used element.
- Improved handling of
element.dirproperty so changes to it better connect to `Display.contentDirection. - Fixed font loading bug
- Fixed bug that caused ScrollPanel sorting order when
scrollTocalled before panel with NativeScrollPanelBehavior is rendered. - Fixed bug where
ScrollPanel.scrollTowould be ignored if called before native behavior is installed. - Fixed drag-drop bug on iOS where visual not rendered
- Fixed drag-drop on iOS Safari that failed drag operations that do not contain plain text or uri-lists
- Fixed bug where clip-path not cleared correctly for reused elements.
- Fixed shadow rendering bug in Safari
- NativeSliderBehavior supports
Verticalorientation - NativeSliderBehavior supports snapping to ticks
- Desktop
- New platform specific desktop-jvm publications that depend on corresponding Skiko libs. This addresses the underlying issue in #28.
- Fix native font handling that led to exceptions on some platforms.
Dependencies
- Dokka -> 1.6.0
- Kotlin -> 1.6.10
- Kotlinx Coroutines -> 1.6.0
- Kodein -> 7.11.0
- Measured -> 0.3.1
- Mockk -> 1.12.2
- Skiko -> 0.7.12