Sunday, July 10, 2011

Experimenting with ribbons in LiveCode (part 1)

In the previous post, we kicked off a series on the construction of a ribbon using pure LiveCode. For now, we'll concentrate on the Windows 7 Wordpad look-and-feel, but future posts will refine it for cross-platform consistency. Let's get started by creating a new stack "qrtRibbonExperiment" in LiveCode, with two substacks "qrtRexBehaviors" and "qrtRexTemplate" - the mainstack will be a launchpad whereas the substacks will each provide support for the experiment.

The stack qrtRexBehaviors will contain all the behavior scripts as a series of buttons. The stack qrtRexTemplate will be used to as a template to 'clone' isntance stacks from. This way, you have a skeleton of a document editor to learn from as well.

Peeking ahead at the actual ribbon custom control itself, we note that we'll need 5 areas, which we'll implement as subgroups, each with their own behavior script:
- the application menu in the topleft
- the tab items in the topright (minimize and/or help/customize)
- the ribbon tabs between these two blocks at the top
- the ribbon groups in the center
- the quick access toolbar at the bottom

First things first - the main stack:



It contains three simple buttons and some information about this experiment. Nothing spectacular there, so we'll move along to the behaviors stack:



As you can see, it contains seven buttons right now, aptly named after the different items they provide the behavior for. The number of buttons will expand as we add moire features, but this will do for now. Open each of the button scripts for editing and move on to the template stack.

We'll start by creating the menubar for the stack - even though it's only for Mac, it pays off to put it in straight away. Just go to the 'Tools' menu, and select the option 'Menu Builder' ; then click on the 'New...' button to create a menubar called 'qrtRexMenubar' ; not feeling particularly adventurous, we'll use the prefab set for now.
To make the next step easier, uncheck the 'Set as stack Menu bar' box. Now close the menu builder, and you'll see the menubar as part of your stack. When you set the menubar property of the stack, the stack content moves upward, and that's why I want to help you visualize where the controls end up. The menubar group should have its margins set to 4 and thus have a bottom of 22 - which wiill be our anchor point for the ribbon custom control group.

So now we'll add a rectangle graphic as background for our ribbon - just draw one, and set its rectangle using the property inspector to: -1, 21, 401, 161. Set its name to 'Ribbon_Background', make it opaque and set its fill color to a light gray (I picked 'Silver' from the Mac crayons color set).

Next we'll add the background rectangle graphics for each of the ribbon areas:
- ApplicationMenu_Background -> rect: -1, 21, 70, 46 | color: salmon
- TabHeaderItems_Background -> rect: 350, 21, 401, 46 | color: banana
- RibbonTabs_Background -> rect: 70, 21, 350, 46 | color: honeydew
- RibbonGroups_Background -> rect: -1, 46, 401, 137 | color: lavender
- QuickAccessToolbar_Background -> rect: -1, 137, 401, 163 | color: melon

In case you're wondering about the colors: of course they don't match the ribbon color scheme - but they'll help visualize errors in our resizing scripts. But before we start scripting, let's create the necessary custom control groups out of these background graphics.
Once you've grouped the graphic, set the containing group's lockLocation property to true and change its rectangle to clip to the edges of the window
- ApplicationMenu_Background -> group: ApplicationMenu | rect: 0, 21, 70, 46
- TabHeaderItems_Background -> group: TabHeaderItems | rect: 350, 21, 400, 46
- RibbonTabs_Background -> group: RibbonTabs | rect: 70, 21, 350, 46
- RibbonGroups_Background -> group: RibbonTabs | rect: 0, 46, 400, 137
- QuickAccessToolbar_Background -> group: QuickAccessToolbar | rect: 0, 137, 400, 163

Then take those five groups, and the rectangle graphic 'Ribbon_Background', and group everything once more; name that outer group 'Ribbon' and set its margins to 0 as well, before settings its lockLocation to true and its rectangle to 0, 21, 400, 163.
We end up with something like this:



Now we can start setting the behaviors and do some scripting at last. Open the message box, and execute the following seven lines one by one:
set the behavior of this stack to the long id of button "qrtRexStackBehavior" of stack "qrtRexBehaviors"
set the behavior of group "Ribbon" to the long id of button "qrtRexRibbonBehavior" of stack "qrtRexBehaviors"
set the behavior of group "ApplicationMenu" to the long id of button "qrtRexApplicationMenuBehavior" of stack "qrtRexBehaviors"
set the behavior of group "TabHeaderItems" to the long id of button "qrtRexTabHeaderItemsBehavior" of stack "qrtRexBehaviors"
set the behavior of group "RibbonTabs" to the long id of button "qrtRexRibbonTabsBehavior" of stack "qrtRexBehaviors"
set the behavior of group "RibbonGroups" to the long id of button "qrtRexRibbonGroupsBehavior" of stack "qrtRexBehaviors"
set the behavior of group "QuickAccessToolbar" to the long name of button "qrtRexQuickAccessToolbarBehavior" of stack "qrtRexBehaviors"


On to the script of the 'qrtRexStackBehavior' button:
##
on resizeStack pNewWidth, pNewHeight
local tRectangle
lock screen
--> resize the ribbon group
put the rectangle of group "Ribbon" into tRectangle
put pNewWidth into item 3 of tRectangle
set the rectangle of group "Ribbon" to tRectangle
--> pass the message
unlock screen
pass resizeStack
end resizeStack
##


Next comes the script of the 'qrtRexRibbonBehavior' button:
##
on resizeControl
local tRectangle
lock screen
--> resize the background graphic
put the rectangle of graphic "Ribbon_Background" of me into tRectangle
put (the width of me) + 1 into item 3 of tRectangle
set the rectangle of graphic "Ribbon_Background" of me to tRectangle
--> move the tab header items group
set the right of group "TabHeaderItems" of me to the right of me
--> resize the ribbon tabs group
put the rectangle of group "RibbonTabs" of me into tRectangle
put the left of group "TabHeaderItems" of me into item 3 of tRectangle
set the rectangle of group "RibbonTabs" of me to tRectangle
--> resize the ribbon groups group
put the rectangle of group "RibbonGroups" of me into tRectangle
put the width of me into item 3 of tRectangle
set the rectangle of group "RibbonGroups" of me to tRectangle
--> resize the quick access toolbar group
put the rectangle of group "QuickAccessToolbar" of me into tRectangle
put the width of me into item 3 of tRectangle
set the rectangle of group "QuickAccessToolbar" of me to tRectangle
--> pass the message
unlock screen
pass resizeControl
end resizeControl
##


Next comes the script of the 'qrtRexApplicationMenuBehavior' button:
##
--> TODO
##


Next comes the script of the 'qrtRexTabHeaderItemsBehavior' button:
##
--> TODO
##


Next comes the script of the 'qrtRexRibbonTabsBehavior' button:
##
on resizeControl
local tRectangle
--> resize the background graphic
put the rectangle of graphic "RibbonTabs_Background" of me into tRectangle
put (the width of me) + 1 into item 3 of tRectangle
set the rectangle of graphic "RibbonTabs_Background" of me to tRectangle
--> TODO: whatever needs to happen to the group content
--> do not pass the message
end resizeControl
##


Next comes the script of the 'qrtRexRibbonTabsBehavior' button:
##
on resizeControl
local tRectangle
--> resize the background graphic
put the rectangle of graphic "RibbonTabs_Background" of me into tRectangle
put the right of me into item 3 of tRectangle
set the rectangle of graphic "RibbonTabs_Background" of me to tRectangle
--> TODO: whatever needs to happen to the group content
--> do not pass the message
end resizeControl
##


Next comes the script of the 'qrtRexRibbonGroupsBehavior' button:
##
on resizeControl
local tRectangle
--> resize the background graphic
put the rectangle of graphic "RibbonGroups_Background" of me into tRectangle
put (the width of me) + 1 into item 3 of tRectangle
set the rectangle of graphic "RibbonGroups_Background" of me to tRectangle
--> TODO: whatever needs to happen to the group content
--> do not pass the message
end resizeControl
##


Finally comes the script of the 'qrtRexQuickAccessToolbar' button
##
on resizeControl
local tRectangle
--> resize the background graphic
put the rectangle of graphic "QuickAccessToolbar_Background" of me into tRectangle
put (the width of me) + 1 into item 3 of tRectangle
set the rectangle of graphic "QuickAccessToolbar_Background" of me to tRectangle
--> TODO: whatever needs to happen to the group content
--> do not pass the message
end resizeControl
##


Don't worry, there will be more to those scripts soon - bot for now this gives us a set of groups that resize correctly as the stack is resized. You have to start somewhere :-)

In the next installment, we'll build on this foundation by introducing the 'ribbonText' property - an XML structure that describes the content of the ribbon. In the meantime, you can download the first draft of our ribbon experiment here.

No comments: