Menu

Spark ScrollBar

SourceForge Editorial Staff
There is a newer version of this page. You can find it here.
# Spark ScrollBar - Mini Functional and Design Specification ---- ## Recent Modifications ScrollBar has now been re-factored to subclass [TrackBase](Spark%20TrackBase) with the following major changes: * Many properties (`trackSize`, `thumbSize`, etc…) and methods (value to position conversion methods, etc…) have been pushed into [TrackBase](Spark%20TrackBase). * The `pageSize` property is now part of ScrollBar instead of [Range](Spark%20Range). * ScrollBar now dispatches the appropriate events. The `change` event for user interaction, and the `valueCommit` event for a change in value. * The up/downButton's are now called `decrement`/`incrementButton`. Also, ScrollBar continues to use its own timer…it may be possible to use the Button's `autoRepeat` property of the button later on? ---- ## Major unfinished areas There are minor elements not yet ported that we need to decide upon and then implement. See the "To do" section below for details on these. ## Differences in functionality from the Halo version Several things didn't make it to the new component, either because they didn't fit with the Gumbo architecture (all of the Halo styles were about skinning the component, and don't apply to the Gumbo architecture), they seemed superfluous (disabling double-click events), or there are better or different ways of accomplishing the same things in the Gumbo component (`valueChanged` event vs. the old scroll event). In general, the approach is to only port those items that make sense, and not to drag things forward without a clear reason; we want these components to be as lightweight as possible. * double-click disablement: The Halo ScrollBar disabled double-click events on the component. There doesn't seem to be any particular reason to do this. We process click events on the scrollbar sensibly either way. * `lineScrollSize`, etc: Various properties in the Halo scrollbar have been replaced by properties with different, mostly more generically named, properties in the Gumbo scrollbar (and in [Range](Spark%20Range) in particular). This is what we want, since these properties can be re-used by other non-scrolling components. So without a mandate to keep the Halo API as-is, it makes sense for these Halo property names to go away. * `pageSize` vs `pageScrollSize`: There used to be 2 separate page sizes to control the amount that would be scrolled on a paging event. Without a clear reason for this extra flexibility, we will leave this behavior behind and just replace it by the new `pageSize` property. * bitmap caching: There were some places in the Halo code where we would force bitmap caching on for the thumb button. We want to avoid this as much as possible, so without a clear reason why we need to do this, we're leaving this code. * `setScrollProperties`: We used to have a single method where a developer could set the main properties of scrollbar. But even this convenience method didn't allow setting all of the properties (such as the step size). Rather than having duplicate API (this method plus the individual properties), we're leaving this method behind and now just have the properties themselves as the way of setting the scrollbar behavior. * `isScrollBarKey()`: This was an mx_internals function in the Halo version. Since the key events should happen at the scrolled-container level (not the scrollbar component itself), it's not clear what purpose this function serves, so it's staying behind. * `minHeight` vs `explicitMinHeight` (and width): The Halo code used the explicit version, but it seems better/simpler to use just the `minHeight` property instead (which by default uses the explicit property if set). * styles: All of the styles in the Halo ScrollBar component related to skins and other appearance items, which don't apply in the Gumbo architecture. Thus, none of the previous styles are being ported. * Excludes: The Halo ScrollBar had excludes that applied to properties that are not being carried over. We have no current need for excludes in the new version. * `virtualHeight/Width`: These mx_internals properties were linked to the old scrollbar's constraint of horizontally or vertically aligned scrollbars. In the Gumbo architecture, the Gumbo HScrollBar and Gumbo VScrollBar subclasses take care of this functionality, and there is no longer any need for these Halo properties. * ScrollBarDirection, direction property: The Halo ScrollBar was very tuned to scrollbars that were either horizontally or vertically oriented. The Gumbo ScrollBar allows arbitrary orientation (and skinning). These Halo constants and property do not make sense in the Gumbo component. * ScrollEvent: The Halo code sent out a ScrollEvent when things changed. The Gumbo component sends out a simpler `valueChanged` event. The new approach means that anyone that wants to know the details that used to be in the ScrollEvent would have to query the [Range](Spark%20Range), but this seems simpler than creating a whole event with details that the user can figure out if they really need it. ## Code _What parts of the code were ported?_ The event handlers were ported very similarly, including the Timer-related code for repetition. _What parts of the code were re-written?_ The code responsible for positioning the scroll thumb was mostly re-written, to make it more general and less constrained to a vertical-or-horizontal world. Halo methods or properties that were mx_internal were rewritten to be either protected (if possible to override) or private (if there were other mechanisms to get the same behavior). _ _ _What parts of the code are new?_ * The [Range](Spark%20Range) class is new. * The handling of skins is new * HScrollBar and VScrollBar now perform calculations specific to their size and orientation. Previously, this functionality was embedded in the scrollbar, but the new code makes positioning/sizing more generalized and needs the subclasses to calculate position and size appropriately. * There is slightly new repeat behavior, where the initial delay of the Timer is set every time there is a new repeat cycle. Previously, the Timer only performed a repeat delay the first time it was created. ## Issues Encountered _What issues did you encounter during the port?_ * I needed to generalize the positioning/sizing functionality. With our more general skinning mechanism, it seems more possible for people to implement arbitrarily shaped, sized, and oriented components. For example, what about a circular scroll bar? Our Halo ScrollBar, as well as the prototype, were very focused on supporting one-dimension X or Y-based calculations. I had to generalize this to allow the subclasses to determine how to calculate the sizes and positions and how to interpret the mouse input appropriately. * The prototype code pushed the event handlers into the subclasses. This meant that boilerplate code for handling the events was duplicated in the subclasses. I hoisted these methods into the superclass and had the subclasses override simpler methods that just returned values based on their orientation/sizing constraints. * I found a bit of repeating behavior that seemed wrong in Halo, so I changed the new component to handle it correctly. Once we set up the timer the first time, we never went back and changed the `repeatDelay`. This meant that if you held the track down a second time, it would start repeating immediately. That's not generally how native scrolling works - there's always an initial delay on a new repeat cycle. * The prototype had a simple Graphic element for the track, but it's really more like a Button, with similar mouse events and enablement. So I made it a Button (just like it was in Halo). * The `enabled` property functionality is split between stuff that's handled automatically for the sub-components (so when we tell the sub-buttons that they're disabled, they do the right thing for themselves) and stuff that has to be handled manually for ScrollBar. * The prototype relied on the propagation of a `changed` event from [Range](Spark%20Range). I changed this to directly set up sizes and positions in the setter for `value`. This avoided the problem where thumb dragging circumvented the indirect mechanism and just positioned the button directly; now everyone goes through the same direct mechanism. \\ _Did this component implementation lead to any architectural changes in the framework?_ No. I added a minor amount of functionality to [Range](Spark%20Range) and changed that class slightly. ## To Do _What items are incomplete?_ See below
[[ include ref='flexsdk_rightnav' ]]
[[ include ref='site:open_commentlogin' ]]

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.