This is the 5th post about Windows Ribbon Framework features.
On previous posts we have introduced the ribbon framework, seen a complete example, and reviewed how to use buttons-based UI controls and how to control their layout.
In this post we continue our exploration of the Windows Ribbon Framework, this time focusing on Gallery controls.
We will learn what galleries are and what is the difference between an item gallery and a command gallery. We will learn about the different gallery controls: ComboBox, DropDownGallery, SplitButtonGallery and InRibbonGallery.
Of course we will see how to set gallery items and how to respond to a user choice.
What is a gallery?
A gallery is a ribbon UI control which contains a list of elements. The elements in the list are represented by a text caption or an image, and can be organized by categories.
Figure 1: An example of a gallery
The galleries that we will soon review comes in two flavors: item gallery and command gallery.
Item Gallery vs. Command Gallery
In this section we will learn about the differences between an item gallery and a command gallery. There are three differences between the two types of galleries:
The first difference relates to what the gallery elements are.
In the item gallery, every element is a "simple" element and is characterized by a text and an image.
On the other hand, an element in a command gallery is literally a command. This means it has a command ID, which we can handle (as seen in previous posts), and has all the attached resources that a command can have.
You may think of it as a list of images vs. a list of buttons.
The second difference is that an item gallery supports the concept of a "selected item".
Every element in an item gallery has an index and there is a property on the gallery which we can check for getting the selected item index.
On the other hand, the commands in the command gallery are not indexed and thus the gallery doesn't support the concept of a selected item.
Finally, item galleries support "live preview". This means you get a notification when the user is hovering over an item (before actual selection); the notification is received via the IUICommandHandler::Execute method, more on this later. This allows application developers to implement a preview feature where the user can see the result of selecting an item before he actually selects it.
The Styles control in Microsoft Word 2007 / 2010 is a great example for an item gallery with live preview. Hovering over different styles shows immediately what the effect will be.
Figure 2: Styles item gallery in Word 2010
Command galleries doesn't support preview. Every element in a command gallery can only be clicked.
A ribbon ComboBox control is basically the normal ComboBox control that we all know and love, but with the added feature of dividing the items into categories. A category is not an item and cannot be selected from the ComboBox. It is only used to organize the items.
Categories will be discussed further in this post.
Figure 3: A ComboBox with categories
A ribbon ComboBox is considered a gallery, although it has one limitation that the other gallery types don't have: It can only be used as an item gallery. This means that the ComboBox items are always "text / image" items and cannot be, for example, buttons.
Defining ComboBox in markup
Following is an example of defining a ComboBox in ribbon markup:
As you can see, all it takes is a simple ComboBox markup element, attached to a command.
The ComboBox XML attributes are as follows:
- CommandName – The name of the command attached to this ComboBox.
- IsAutoCompleteEnabled – A flag that indicated whether the ComboBox control should automatically complete the word as you write.
- IsEditable – A flag that indicates whether to allow free text in the ComboBox.
- ResizeType – Indicates the allowed type of resizing for the ComboBox. Can be either NoResize or VerticalResize.
Setting ComboBox items
As you may recall from previous posts, every command has an implementation of IUICommandHandler attached to it.
Setting the ComboBox items is done by implementing the IUICommandHandler::UpdateProperty function, specifically, handling the case when the property key is UI_PKEY_ItemsSource. You can find more information on how to implement IUICommandHandler::UpdateProperty in part 3 of this series.
The type of the property ItemsSource is a collection (IUICollection) of IUISimplePropertySet.
The interface IUICollection represents a simple collection and has all the common collection functions, such as: Add, Insert, RemoveAt, GetCount, etc.
The interface IUISimplePropertySet represents, as his name suggests, a set of properties. It has only a single function, GetValue, which should return a property value, given the property identifier.
Both IUICollection and IUISimplePropertySet are defined in the UIRibbon.h, which comes with the Windows 7 SDK.
Every element in the ComboBox or more generally, in an item gallery, has the following properties:
- UI_PKEY_Label – Represents the label of the item.
- UI_PKEY_ItemImage – Represents the item image.
- UI_PKEY_CategoryId – Represents the category id of which this item belongs.
Note that an element in a command gallery has different properties. We will review those properties later in this post.
Following is an example of how to fill the ItemsSource property inside the command handler of a ComboBox. Error handling has been omitted for brevity.
In this example we add three items to the ItemsSource property of the ComboBox. This is done by creating an object that implements IUISimplePropertySet, setting its properties (we set only the label, which is loaded from the resource file), and adding it to the collection.
The CPropertySet class is a helper class that implements IUISimplePropertySet and exposes convenient initialization functions. Its full source is available with the sample application attached to this post.
The end result for this ComboBox looks like this:
Figure 4: The ComboBox created by the previous markup and code
Handling User Selection
In this section we will see how to respond to a selection made by the interactive user.
We will also handle the case where we have an editable ComboBox (IsEditable = "true"), in which case the user might enter a value which is not part of the ComboBox values.
Handling the "Selected Change" event is done by implementing IUICommandHandler::Execute, when the verb parameter has the value UI_EXECUTIONVERB_EXECUTE and the key parameter has the value UI_PKEY_SelectedItem.
In the following example we see code that handles the user selection.
First we check that the correct verb (Execute) and property key (SelectedItem) is handled. Then we use ppropvarValue->uintVal to extract the index of the selected item. According to the index we can know what the selected value is. In case the index is UI_COLLECTION_INVALIDINDEX, which is just a fancy way of saying -1, we can safely assume that the user entered the text manually, in which case we get the label property and parse it.
Figure 5: An editable ComboBox with custom user text
DropDownGallery and SplitButtonGallery
A DropDownGallery is just a button that a click on it displays a list of items. The button itself has no action.
On the other hand, a SplitButtonGallery has two buttons, one that is used as a default action and another one that opens a list of items.
This difference between these two galleries is similar to the difference between the SplitButton control and DropDownButton control, seen on part 3 (Add link to post 3) of this post series.
In the following image, on the right, you can see a SplitButtonGallery which is composed of a split button, on the top part (the image) there is a button and on the lower part (the "Style" text) there is an arrow that opens the list of items.
Figure 6: On the left: a DropDownGallery with categories, On the right: a SplitButtonGallery
Defining SplitButtonGallery in markup
In the following markup code we see how to define a SplitButtonGallery. The code should be placed in the ribbon markup "views" section.
The SplitButtonGallery XML attributes are as follows:
- CommandName – The name of the command attached to this SplitButtonGallery.
- Type – The type of the gallery. It can be either Items or Commands.
- TextPosition – The position where to show the attached text. This can be one the following values: Top, Left, Right, Bottom, Overlap and Hide.
- HasLargeItems – Indicates whether the large or small image resource of the Command is displayed.
The MenuLayout attribute defines how the list of elements will present itself.
VerticalMenuLayout is used to show a vertical layout.
Another option is FlowMenuLayout, which we will review on the next code example.
Setting SplitButtonGallery items with images
Since in this example the SplitButtonGallery is used as an item gallery, adding items is done similarly to how it was done in the previous ComboBox sample. However, we will also see how we can provide image resources to the items. As always, error handling has been omitted.
The important thing to note is the helper function CreateUIImageFromBitmapResource. This function loads a bitmap resource and converts it to an instance of IUIImage, which is the ribbon wrapper for a bitmap. The conversion is done using a COM object provided by the Windows Ribbon Framework, named UIRibbonImageFromBitmapFactory. This object implements the interface IUIImageFromBitmap which has only one function, CreateImage.
The CreateImage function takes an HBITMAP handle as its first parameter and returns a pointer to IUIImage. The second parameter controls the ownership of the created image, and take the value UI_OWNERSHIP_TRANSFER in case you want to transfer the responsibility of releasing the handle to the ribbon framework, or UI_OWNERSHIP_COPY in case you plan to reuse the same HBITMAP from other places in your application, and so need to release it only when you are done.
Defining DropDownGallery in markup
In the following markup code we see how to define a DropDownGallery. The code should be placed in the ribbon markup "views" section.
Note that this time we used "Commands" as the type of the gallery. This means that this particular instance of DropDownGallery will be used as a command gallery.
Most of the DropDownGallery XML attributes are similar to the attributes of SplitButtonGallery, so I'll only explain the FlowMenuLayout.
The FlowMenuLayout XML element is used to define a rich layout for the gallery items. We use the Rows and Columns attributes to control the number of rows and columns in the gallery rectangle. On figure 6, the left control is the result of this definition. Note that the categories seen in the image will be defined later in the code.
Before we continue, I owe you from a previous section the available properties for an element in a command gallery.
Every element in a command gallery has the following properties:
- UI_PKEY_CommandId – Represents the command id of the element.
- UI_PKEY_CommandType – Represents the type the command.
- UI_PKEY_CategoryId – Represents the category id of which this item belongs.
Setting DropDownGallery commands items with categories
In the following code we see how to fill the previously defined DropDownGallery. This time we fill it with commands elements. In addition we will divide the commands into two categories.
In this code we first define Categories property, which contains the list of available categories (in our case, just two items), and then the ItemsSource property.
The items elements are now commands which have a command id and command type. In our case we used UI_COMMANDTYPE_BOOLEAN which makes the commands appear as ToggleButton controls. Note that we didn't define any image resource for the elements. The image comes from the previously define command resources.
Also, check the implementation of the gallery's Execute function:
The implementation is rather empty since the handling of the commands is done by the command handler attached to the elements command id. The gallery's Execute function is never actually called.
An InRibbonGallery is a gallery in which the items are displayed inside the ribbon. Other than its visual representation, it's functionally equivalent to the DropDownGallery.
Figure 7: An example of InRibbonGallery control
Defining InRibbonGallery in markup
In the following markup code we see how to define an InRibbonGallery. As always, view related code should be placed in the ribbon markup "views" section.
All of these XML attributes are already known or self-explanatory.
Handling live preview in an item gallery
One of the benefits of an item gallery is its support for the live preview feature, i.e. it allows the user to see the result of a selection before just by hovering over an item. If the user doesn't select an item and move the mouse cursor away, the selection effect is removed.
In the following code we see how to implement IUICommandHandler::Execute in order to handle the live preview feature:
We handle three different verbs: Preview, CancelPreview and Execute.
The Preview verb is passed when the user hovers over an item, in which case we also get the hovered item index. The CancelPreview verb is passed when a user moves the mouse cursor away from the item gallery. Note that in the CancelPreview case we get the previously selected item so the developer doesn't need to save the previous item.
The last case is when the passed verb is Execute, which means the user has selected an item.
The ShowItem function is in charge of doing the selection effect, for example, drawing a new shape according to the selected one.
The sample application attached to this post is the taken from the Windows 7 SDK "Gallery" ribbon sample. You can find it either here or in your local folder
"\Program Files\Microsoft SDKs\Windows\v7.0\Samples\winui\WindowsRibbon\Gallery\"
Figure 8: Sample application for this post
In this post we have learned how to use the ribbon gallery controls. We learned about the difference between an item gallery and a command gallery. We saw the different gallery controls: ComboBox, SplitButtonGallery, DropDownGallery and InRibbonGallery. And we saw how to add items, categories and images, and how to provide support for live preview.
That's it for now,