Ribbon and smart resizing
One of my previous entries was written fresh on the heels of unveiling of the Office 12 UI. A lot of stuff was left unfinished, some of it due to lack of time, and most of it due to lack of information on how this UI really works. So, after reading plethora of information on Jensen's blog, the Java implementation of Ribbon has moved to the second gear.
The following points were missing in the initial implementation (see Jensen's blog for more details):
- Concept of gallery.
- Gallery button (the one with the downward-pointing arrow).
- In-ribbon gallery (the one with the scroll arrows on the right-hand side and the downward-pointing arrow).
- Smart layout of the ribbon components on resize.
Let's look at the following screenshot (WebStart link at the end of this entry):
Every button that has a downward-pointing double arrow is a gallery button. In Office 12, clicking on such button will show a drop-down gallery of styles / choices / etc (like a combobox). Buttons with no arrows are simple buttons.
In "Quick Styles" band, you can see an in-ribbon gallery. The UI designers may decide that some galleries are much more important than others. Such galleries can be put directly in the ribbon, with scroll buttons that scroll through the gallery icons, and downward-pointing arrow that shows the entire gallery as popup.
In addition, note that gallery buttons come in three flavours:
- Large icon with two-lined caption beneath (see Paste in Clipboard and Find in Find).
- Small icon with one-lined caption on the right (see Paragraph's and Find buttons).
- Small icon with no caption (see Clipboard and Quick Styles buttons).
UI designers assign importance to each button. When there's enough space for everything (see screenshots below), everything is shown in big icons with captions beneath. As more elements are put into the ribbon (or the main window is resized and shrinked), the buttons that were marked as less important are requested (by the layout manager) to switch state and take less space. This is a very important concept of smart resizing that is configurable and automatic.
The implementation of smart resizing is quite simple (although with a lot of technical details). First, there is a concept of collapse. Collapse is a request for some ribbon band to layout its components (gallery buttons, in-ribbon galleries and regular components) based on degree of collapsing. There are seven collapse degrees:
- NONE - everything takes as much space as it wants.
- LOW_TO_MID - components with low priority are requested to go to MID state (small icon with one-line label on the right-hand side).
- MID_TO_MID - components with low and mid priority are requested to go to MID state.
- LOW_TO_LOW - components with low priority are requested to go to LOW state (small icon with no label).
- MID_TO_LOW - components with low and mid priority are requested to go to LOW state (small icon with no label).
- HIGH_TO_MID - components with high priority are requested to go to MID state.
- HIGH_TO_LOW - all components are requested to go to LOW state.
For each state, the layout manager needs to know how to compute the preferred size. First, all HIGHs are laid out, the all the MIDs in groups of three (taking extra LOWs to complete the last threesome), and then all the LOWs in groups of three.
There are two kinds of layout managers, one for the ribbon and one for each ribbon band. When the layoutContainer() function of ribbon layout manager is called, it does the following:
- Requests each ribbon band layout manager to compute the preferred size for each collapse kind.
- Computes total preferred width (of all ribbon bands) for each collapse kind.
- Chooses the best possible collapse kind that doesn't result in width that overflows the width available for the ribbon.
- Distributes the leftover space between all ribbon bands.
- Requests each ribbon band layout manager to layout its components based on the chosen collapse kind
Let's see the example (you can run the Web Start version and play with the resize). In the first screenshot, there's enough place for all the buttons (dark icons are for high priority, bright icons are for medium priority and very bright icons are for low priority):
As we start making the window smaller, the band with low priority buttons gets less space. Note that they go to MEDIUM state and not LOW:
Making the window smaller, the bands with medium (and low) priority buttons get less space. Note that both medium and low priority buttons go to MEDIUM state and not LOW (since there's enough space left):
Making the window smaller, the band with low priority buttons gets even less space. Note that now they go to LOW state:
Making the window smaller, the bands with medium and low priority buttons get less space, making all these buttons go to LOW state:
Making the window smaller, there isn't enough space for the high priority buttons. However, note that after requesting these buttons to go to MEDIUM state, there's enough space left to distribute between the bands to allow the leftmost band to show its buttons in MEDIUM state (as opposed to LOW state before):
Making the window smaller, there isn't enough space for the high or medium priority buttons:
Eventually the window gets so small that all buttons go to LOW state:
Note that here there's need for dynamically-resizing icons as the buttons change their icons on the fly.
In the next installment i'll talk about drop-down galleries and various layouts. In the meantime, you are welcome to Flamingo homepage to see the code and download the binaries.