github nacular/doodle v0.9.0
0.9.0

latest releases: v0.11.5, v0.11.4, v0.11.3...
2 years ago

Features

New Constraint Layout Fully Adopted

The new layout system was introduced in 0.8.2 alongside the former approach is now fully adopted and the old system has been removed. You can get more details on how the new system works in the previous release notes. This release does bring a few additional changes as well. The main difference is that parent constraints are now "constant" by default. This means constraints like the following will NOT modify the parent bounds:

constraint(view) {
    it.width eq parent.width - 10 // parent.width is treated like a simple number and is not updated to meet the constraints
}

However, you can still make parent properties writable by being explicit as follows:

constraint(view) {
    it.width eq parent.width.writable - 10 // now parent.width could be modified if needed to meet the constraints
}

There were also some improvements to this new layout engine. Constraints now default all parent properties to read-only. This means it is no longer possible to use the readOnly field on parent properties. Instead, each can be turned into a "writable" value using the new writable field on each.

Revamped Animation APIs

The Animation APIs have been updated to make them more powerful and easier to use. You can now animate a lot more data types, with built-in support for common ones like (Int, Float, Double, Size, Position, Rectangle, Color, and Measure). It is also easy to add new types when they can be converted to a numeric representation. The animation APIs also let you create animatable properties, and provides a few different types of animations, including tweens, key-frames, and repetition.

New Diff API for ObservableList

A new list diff algorithm (based on Google's diff-match-patch) was introduced internally in 0.8.2 to support the new constraint system. It has now been adopted as the mechanism for notifying about changes to ObservableList and related types (i.e. FilteredList). This algorithm scales better and more intuitive than what was in place before. But the APIs are very different.

Old

observableList.changed += { list, removed: Map<Int, T>, added: Map<Int, T>, moved: Map<Int, Pair<Int, T>> ->
    
}

New

observableList.changed += { list, changes: Differences<T> ->
    
}

The new API indicates changes via the Differences interface. This interface lets you iterate over a series of Difference<T> instances that indicate what change was applied to the list at a given index.

observableList.changed += { list, changes: Differences<T> ->
    changes.forEach { difference ->
        when (difference) {
            is Delete -> {}
            is Insert -> {}
            else      -> {} // Equal
        }
    }  
}

Differences also let you compute moves optionally in case they matter to your handling of changes.

diffs.computeMoves().forEach {
    when (it) {
        is Insert -> {
            it.items.forEach { item ->
                if (it.origin(of = item) == null) {
                    // not a move
                }
            }
        }
        is Delete -> {
            it.items.forEach { item ->
                when (val destination = it.destination(of = item)) {
                    null -> {
                        // not a move
                    }
                    else -> {
                       // move
                   }
                }
            }
        }
        else -> {}
    }
}

Improved Tables and TreeTables

  • Table/TreeTable now support footers
  • Table/TreeTable now allow changing the visibility of their header (and footer)
  • Tables and their related types now handle being added to a ScrollPanel. In this case they will
  • BasicMutableTableBehavior now shows sort order via an icon
  • New EqualSizePolicy and ProportionalSizePolicy types to support different table header sizing strategies
  • New way to specify the stickiness of headers and footers within tables and their derivatives
  • New KeyValueTable to simplify showing Maps in tabular form
  • Table and its derivatives no longer prevent their first column from resizing
  • BasicTreeTableBehavior now takes an iconFactory instead of an icon color
  • TreeTable now scales the contents of its internal ScrollPanel like Table does
  • TableHeaderCell (used for basic table behaviors) now repaints when disabled/enabled to update colors correctly.
  • TableHeaderCell no longer changes color on pointer pressed if its column is not movable
  • TableHeaderCell no longer uses the Grabbing icon when dragging
  • BasicMutableTableBehavior now reflects initial sorting of its table.
  • Ideal size for Table (and derivatives)
  • TableBehavior moveColumn now provides the distance it will move. This allows for constant velocity animations

New FileSelector Control

Form Controls

  • New slider, rangeSlider, circularSlider and circularRangeSlider controls
  • New file and files controls

APIs

  • Replaced constrain(videw: View, within: Rectangle) method with faster <T: Positionable> Iterable<T>.constrain(using: ConstraintDslContext.(Bounds) -> Unit, within: (Int, T) -> Rectangle)
  • new ifNull utility function
  • ScrollPanel now exposes scrollbar dimensions and notifies listeners when they change.
  • CheckBoxRadioButtonBehavior now takes an iconInset which indicates the padding around the icon (does not apply to icon-text spacing gap).
  • BasicMutableTableBehavior now takes a footerColor
  • New simpleTableCellEditor function for creating TableEditors that modify a single cell at a time.
  • New ConvexPolygon.map function to create a new polygon by transforming another
  • New DSL to use an ItemVisualizer of a different time after mapping its inputs: ItemVisualizer<R, C>.after(mapper: (T) -> R): ItemVisualizer<T, C>
  • New ExpandableItem interface for use with Tree and related views.
  • [API] MutableTreeNode's children is now a MutableList
  • Updated path(data: String) function, so it can return null
  • New cancelable delegate

Performance

  • General
    • Minor change to AffineTransformImpl to support single Point invocations without converting to array/list
    • RenderManagerImpl now uses View.generationNumber instead of an ancestor comparison for layout order
    • ConstraintLayoutImpl handles changes in constant parts of constraints more efficiently. This makes readOnly usage faster.
  • Browser
    • Now using native JS Set/Map in some performance critical areas
    • TreeSetJs no longer uses recursion

Fixes | Improvements

  • General
    • Bug in HorizontalFlowLayout when container is empty
    • typo in ScrollPanelConstraintDslContext property
    • optionalRadioList now allows deselection of its items
    • Layout of some Form list items
    • SplitPanel constraints no longer modify parent
    • ScrollPanel how ignores layout when its content scrolls
    • ListItem no longer replaces layout if children remain the same
    • Bug in Table that could lead to an incorrect index being used when generating a row
    • Bug in TreeTable that could lead to an incorrect index being used when generating a row
    • Bug in basic list positioning for cases when the list has now width or height
    • Bug in FilteredList when filter is null
    • Improved how Table and TreeTable handle visible scrollbars. They both now avoid showing horizontal bars and adjust their headers accordingly if the vertical bar is visible.
    • Bug in TreeColumns where items weren't being recycled
    • Bug in View.generationNumber updating
    • Issue in CheckBoxRadioButtonBehavior where icon inset was not being included in the button's idealSize.
    • MutableTable keeps itself sorted when its model changes.
    • Bug in ListItem that caused default cellAlignment to be ignored
    • No longer doing layout in TreeTable when columnSizePolicy changed before it has a behavior
    • View.scrollTo now handles nested ScrollPanels
    • List now checks the point that is 1 pixel up and left from its display rect bottom-right corner when updating visible cells. This avoids accidentally including cells that are hidden.
    • Bug in Tree that rendered rows incorrectly in some cases
    • ScrollPanel now matches content ideal size right away
  • Browser
    • Minor icon alignment issue in native button behavior
    • Native button behavior now properly updates button idealSize
    • Bug in native Slider snapping Behavior for some values of ticks
    • Default Key event behavior now prevented when event consumed.
  • Desktop
    • Bug in desktop DragManagerImpl where unsupported MimeTypes were not properly handled

Dependencies

  • Kotlin -> 1.7.21
  • Kodein -> 7.16.0
  • Skiko -> 0.7.40
  • Kover -> 0.6.1
  • Dokka -> 1.7.20
  • Measured -> 0.3.2

Don't miss a new doodle release

NewReleases is sending notifications on new releases.