Also, bump the version to 0.9 since this change is definitely not binary
compatible: class names and structures have changed. Most clients should
be fine though if they just recompile: the changes are to things that
will generally be used through the implicits system, so most shoudln't
notice the changes.
The custom region doesn't quite work yet, so just expose the underling
bar so we can still get the shared behavior. Maybe the region will get
fixed later on.
JavaFX & ScalaFX already have one of these, but this handles padding
and automatically set up the apply, ok, cancel trilogy (though you can
disable any of these).
This ensures there will be at most one copy of the stage, which will be
created and destroyed as needed. Trying to create a second just brings
the first into focus. This is good for things like preferences windows.
This makes it really convenient to take a data structure like a
`ObservableBuffer`, which normally has special operations to watch for
different CRUD operations on its individual members, and treat the whole
thing as a solid value. This lets you turn it into an `ObservableValue`
where you get a notice of changes and then you can use the normal
operations like `map` and `flatMap` to react to changes.
Because this requires reprocessing the entirety of the contained values,
this may not perform as well as if you subscribe to more granular update
messages.
It is possible to round-trip these collections back to the ScalaFX
native collections using the other utilities available. This will be
required if you want to use the output to back something like a table.
I'm pretty confident that this isn't actually required by the JavaFX
threading model, but it makes the code more obviously correct and
uncontended synchronization has a negligible cost when we're talking
about UI-level changes.
If the new output is equal to the old output, we'll suppress the change
message altogether, so as not to do unnecessary recalculations.
E.g., imagine you have a property `isOdd`. If you go from 27 to 319,
there's no need to trigger all the downstream objects to recalculate.
(Most of the other functional primitives I've created already have this
behavior.)
This is not yet tested, and it requires a lot of testing. A previous
helper that attempted to support `bind` never quite worked correctly,
but I believe that the new approach of implementing `join` and `map`
instead of `bind` makes the code more resilient.
Even though `map` and `ap` can be derived from `point` and `bind`, I'm
keeping both of them, as `bind` requires quite a bit of subscription
manipulation. Those methods have much simpler implementations.
This could prevent it from updating values if you returned to
the original value. E.g., if your values went 1, 2, 1, 2, you'd
get notifications for 1, 2, 2. This would also cause some extra
notifications to go when the logical value didn't actually change.
This commit also includes an `observe2`, which operates directly on a
tuple without explicitly converting to an HList. I'm committing it for
posterity, but the next commit will remove it because it doesn't give a
narrow enough output type.