TRibbonBar
Office-style ribbon bar with tabs, groups, and buttons
Fuente: source/classes/tribbon.prg | Parent: TControl | Header: include/ribbon.ch
Overview
TRibbonBar implements a Microsoft Office-style ribbon interface. The ribbon docks to the top of a window and organizes commands into tabs, each containing groups of buttons. It supports multiple visual styles (2010, 2013, 2015, 2016), a Quick Access toolbar, keyboard accelerators, backstage view, and fully owner-drawn rendering with gradients.
Architecture
graph TD
WINDOW["TWindow
(Main Window)"] --> RIBBON["TRibbonBar"] RIBBON --> QUICK["Quick Access
Toolbar"] RIBBON --> TAB1["Tab: Home"] RIBBON --> TAB2["Tab: Insert"] RIBBON --> TAB3["Tab: View"] RIBBON --> BACK["BackStage
Panel"] TAB1 --> G1["TRBGroup
Clipboard"] TAB1 --> G2["TRBGroup
Font"] TAB1 --> G3["TRBGroup
Paragraph"] G1 --> B1["TRBButton
Paste"] G1 --> B2["TRBButton
Cut"] G1 --> B3["TRBButton
Copy"] G2 --> B4["TRBButton
Bold"] G2 --> B5["TRBButton
Italic"] style RIBBON fill:#1c2129,stroke:#58a6ff,stroke-width:2px,color:#e6edf3 style G1 fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3 style G2 fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3 style G3 fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3
(Main Window)"] --> RIBBON["TRibbonBar"] RIBBON --> QUICK["Quick Access
Toolbar"] RIBBON --> TAB1["Tab: Home"] RIBBON --> TAB2["Tab: Insert"] RIBBON --> TAB3["Tab: View"] RIBBON --> BACK["BackStage
Panel"] TAB1 --> G1["TRBGroup
Clipboard"] TAB1 --> G2["TRBGroup
Font"] TAB1 --> G3["TRBGroup
Paragraph"] G1 --> B1["TRBButton
Paste"] G1 --> B2["TRBButton
Cut"] G1 --> B3["TRBButton
Copy"] G2 --> B4["TRBButton
Bold"] G2 --> B5["TRBButton
Italic"] style RIBBON fill:#1c2129,stroke:#58a6ff,stroke-width:2px,color:#e6edf3 style G1 fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3 style G2 fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3 style G3 fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3
Component Hierarchy
graph LR
RB["TRibbonBar"] --> RBG["TRBGroup"]
RBG --> RBB["TRBButton"]
RBG --> SEP["Separator"]
RBB --> POPUP["Popup Menu"]
subgraph "Button Types"
NORMAL["NORMAL
Standard button"] POPUPB["POPUP
Menu dropdown"] SPLIT["SPLITPOPUP
Button + dropdown"] SAYB["SAYBUTTON
Label button"] end RBB --> NORMAL RBB --> POPUPB RBB --> SPLIT RBB --> SAYB
Standard button"] POPUPB["POPUP
Menu dropdown"] SPLIT["SPLITPOPUP
Button + dropdown"] SAYB["SAYBUTTON
Label button"] end RBB --> NORMAL RBB --> POPUPB RBB --> SPLIT RBB --> SAYB
TRibbonBar Properties
| Property | Type | Description |
|---|---|---|
aPrompts | Array | Array of tab label strings |
aDialogs | Array | Array of dialog objects (one per tab, holding groups) |
nOption | Numeric | Currently selected tab index (1-based) |
nOldOption | Numeric | Previously selected tab (for change detection) |
bAction | Block | Code block fired on tab change: { |nOption, nOldOption| ... } |
aEnable | Array | Per-tab enable state |
aVisible | Array | Per-tab visibility state |
nTopMargin | Numeric | Height of the tab strip area (default 25) |
nGroupSeparation | Numeric | Pixel gap between groups (default 3) |
nLeftMargin | Numeric | Left margin for the first group |
nRightMargin | Numeric | Right margin |
nRoundBox | Numeric | Corner radius for tab boxes (default 7) |
nClrPaneRB | Numeric | Ribbon background color |
nClrBoxOut / nClrBoxIn | Numeric | Tab box outer/inner colors |
nClrBoxSelOut / nClrBoxSelIn | Numeric | Selected tab box outer/inner colors |
aGrad | Array | Background gradient |
aGradFld | Array | Tab content area gradient |
aGradHigh | Array | Tab highlight gradient (mouse-over) |
aGradOver | Array | Tab hover gradient |
l2010 / l2013 / l2015 / l2016 | Logical | Visual style flags (only one should be .T.) |
oBackStage | Object | Panel used as the backstage view (File tab) |
lUseAcc | Logical | Enable keyboard accelerator hints |
aQuickBmp | Array | Quick Access toolbar bitmaps |
nStart | Numeric | Starting button offset for Quick Access |
Key Methods
| Method | Description |
|---|---|
New( oWnd, aPrompts, bAction, nOption, nWidth, nHeight, nTopMargin, nClrPaneRB, nClrBoxOut, nClrBoxIn, nClrBoxSelOut, nClrBoxSelIn, aGrad, aGradFld, aGradHigh, aGradOver, l2010, nStart, l2013, l2015, l2016 ) | Constructor. Creates the ribbon bar at the top of the window. |
AddTab( cPrompt, nPos, lDefault, bClrTxt ) | Add a new tab at runtime |
DeleteTab( nTab ) | Remove a tab |
AddGroup( nWidth, cCaption, nDialogs, bAction, cBitmap, aGrad ) | Add a group to a tab. Returns the group object. |
SetOption( nOption ) | Programmatically switch to a tab |
GoLeft() / GoRight() | Navigate to previous/next tab |
Enable( nPos, lOnOff ) | Enable or disable a specific tab |
Show( nPos ) / Hide( nPos ) | Show or hide a specific tab |
QuickAccess( nLeft, lQuickGrad ) | Set up the Quick Access toolbar area |
QuickRoundBtn( cBitmap, cBmp, cBmpOver, cBmpPush, bAction, lQuickGrad, bLDblClick ) | Add a Quick Access round button (e.g. the "File" orb) |
SetBackStage( oBackStage ) | Assign a backstage panel |
BackStage() | Show the backstage view |
SetStyles( l2010, l2013, l2015, nTopMargin, ... ) | Change visual style at runtime |
KeybMode() | Enter keyboard accelerator mode (Alt key) |
TRBGroup Methods
Groups are created by TRibbonBar:AddGroup() or the ADD GROUP command. Each group can contain buttons, separators, and other controls.
| Method | Description |
|---|---|
AddButton( nRow, nCol, nHeight, nWidth, cCaption, bAction, cType, bWhen, cBitmap, lBorder, lRound, cLayout, oPopup, ... ) | Add a button to this group |
AddSeparator( nCol ) | Add a vertical separator line |
Command Syntax
#include "ribbon.ch"
// Create the ribbon bar
DEFINE RIBBONBAR [ oRBar ] ;
[ OF oWnd ] ;
[ PROMPTS cTab1, cTab2, cTab3 ] ;
[ ACTION bAction ] ;
[ OPTION nOption ] ;
[ HEIGHT nHeight ] ;
[ TOPMARGIN nTopMargin ] ;
[ COLOR nClrPane ] ;
[ COLORBOX nClrBoxOut, nClrBoxIn ] ;
[ COLORSEL nClrBoxSelOut, nClrBoxSelIn ] ;
[ 2010 | 2013 | 2015 | 2016 ] ;
[ STARTBTN nStart ]
// Add a group to a tab
ADD GROUP [ oGr ] ;
RIBBON oRBar ;
TO nTabIndex ;
[ PROMPT cCaption ] ;
[ WIDTH nWidth ] ;
[ ACTION bAction ] ;
[ BITMAP cBitmap ]
// Add buttons to a group (using @ row, col notation)
@ nRow, nCol ADD BUTTON [ oBtn ] ;
[ PROMPT cCaption ] ;
[ SIZE nWidth, nHeight ] ;
[ BITMAP cBitmap ] ;
[ ACTION bAction ] ;
[ OF oGroup ] ;
[ WHEN bWhen ] ;
[ BORDER ] ;
[ ROUND ] ;
[ TOP | LEFT | BOTTOM | RIGHT | CENTER ] ;
[ NORMAL | POPUP | SPLITPOPUP | SAYBUTTON ] ;
[ MENU oPopup ] ;
[ TOOLTIP cToolTip ]
// Add a separator
ADD SEPARATOR TO GROUP oGr [ COL nCol ]
Ribbon Lifecycle
sequenceDiagram
participant App
participant RB as TRibbonBar
participant GR as TRBGroup
participant BT as TRBButton
App->>RB: DEFINE RIBBONBAR PROMPTS "Home","Insert","View"
RB-->>App: Creates ribbon with 3 tab dialogs
App->>RB: ADD GROUP RIBBON oRBar TO 1 PROMPT "Clipboard" WIDTH 120
RB->>GR: Creates group on tab 1
RB-->>App: Returns oGrClip
App->>GR: @ 2,2 ADD BUTTON PROMPT "Paste" BITMAP "paste.bmp" ACTION ...
GR->>BT: Creates button inside group
GR-->>App: Returns oBtn
App->>RB: ACTIVATE WINDOW oWnd
Note over RB: Tab 1 visible, groups painted
RB-->>App: User clicks "Insert" tab
RB->>RB: SetOption(2)
RB-->>App: Eval(bAction, 2, 1)
Note over RB: Tab 2 groups now visible
Code Examples
Example 1: Basic Ribbon with Groups and Buttons
#include "FiveWin.ch"
#include "Ribbon.ch"
FUNCTION Main()
LOCAL oWnd, oRBar
LOCAL oGrFile, oGrEdit, oGrView
DEFINE WINDOW oWnd TITLE "Ribbon Demo"
DEFINE RIBBONBAR oRBar OF oWnd ;
PROMPTS "Home", "Insert", "View" ;
HEIGHT 160 2015
// ----- HOME TAB (option 1) -----
ADD GROUP oGrFile RIBBON oRBar TO 1 ;
PROMPT "File" WIDTH 140
@ 2, 5 ADD BUTTON PROMPT "New" ;
SIZE 36, 60 BITMAP "new32.bmp" ;
ACTION NewDocument() ;
OF oGrFile TOP
@ 2, 45 ADD BUTTON PROMPT "Open" ;
SIZE 36, 60 BITMAP "open32.bmp" ;
ACTION OpenDocument() ;
OF oGrFile TOP
@ 2, 85 ADD BUTTON PROMPT "Save" ;
SIZE 36, 60 BITMAP "save32.bmp" ;
ACTION SaveDocument() ;
OF oGrFile TOP
ADD GROUP oGrEdit RIBBON oRBar TO 1 ;
PROMPT "Editing" WIDTH 180
@ 2, 5 ADD BUTTON PROMPT "Cut" ;
SIZE 50, 22 BITMAP "cut16.bmp" ;
ACTION Cut() OF oGrEdit
@ 26, 5 ADD BUTTON PROMPT "Copy" ;
SIZE 50, 22 BITMAP "copy16.bmp" ;
ACTION Copy() OF oGrEdit
@ 50, 5 ADD BUTTON PROMPT "Paste" ;
SIZE 50, 22 BITMAP "paste16.bmp" ;
ACTION Paste() OF oGrEdit
ADD SEPARATOR TO GROUP oGrEdit COL 65
@ 2, 70 ADD BUTTON PROMPT "Find" ;
SIZE 50, 22 BITMAP "find16.bmp" ;
ACTION FindText() OF oGrEdit
@ 26, 70 ADD BUTTON PROMPT "Replace" ;
SIZE 60, 22 BITMAP "replace16.bmp" ;
ACTION ReplaceText() OF oGrEdit
// ----- INSERT TAB (option 2) -----
ADD GROUP oGrView RIBBON oRBar TO 2 ;
PROMPT "Objects" WIDTH 200
@ 2, 5 ADD BUTTON PROMPT "Table" ;
SIZE 36, 60 BITMAP "table32.bmp" ;
ACTION InsertTable() OF oGrView TOP
@ 2, 50 ADD BUTTON PROMPT "Image" ;
SIZE 36, 60 BITMAP "image32.bmp" ;
ACTION InsertImage() OF oGrView TOP
@ 2, 95 ADD BUTTON PROMPT "Chart" ;
SIZE 36, 60 BITMAP "chart32.bmp" ;
ACTION InsertChart() OF oGrView TOP
SET MESSAGE OF oWnd TO "Ready" CENTERED
ACTIVATE WINDOW oWnd
RETURN NIL
Example 2: Ribbon with Quick Access and Backstage
#include "FiveWin.ch"
#include "Ribbon.ch"
FUNCTION RibbonAdvanced()
LOCAL oWnd, oRBar, oBackStage
DEFINE WINDOW oWnd TITLE "Advanced Ribbon"
DEFINE RIBBONBAR oRBar OF oWnd ;
PROMPTS "Home", "Data", "Reports" ;
HEIGHT 160 2016 ;
STARTBTN 1
// Quick Access round button (File orb)
oRBar:QuickRoundBtn( "orb.bmp",, , , ;
{ || oRBar:BackStage() } )
// Backstage panel (shown when orb is clicked)
oBackStage := TPanel():New( 0, 0, 600, 300, oWnd )
@ 2, 2 SAY "New" OF oBackStage
@ 4, 2 SAY "Open" OF oBackStage
@ 6, 2 SAY "Save" OF oBackStage
@ 8, 2 SAY "Print" OF oBackStage
oBackStage:Hide()
oRBar:SetBackStage( oBackStage )
// Tab change handling
oRBar:bAction := { |nTab, nOld| ;
MsgInfo( "Switched from tab " + Str(nOld) + ;
" to tab " + Str(nTab) ) }
// Disable a tab at runtime
// oRBar:Enable( 3, .F. )
// Hide a tab at runtime
// oRBar:Hide( 2 )
ACTIVATE WINDOW oWnd
RETURN NIL
Example 3: Popup Buttons and Split Buttons
// Button with a dropdown popup menu
LOCAL oPopup
MENU oPopup POPUP
MENUITEM "Option A" ACTION DoA()
MENUITEM "Option B" ACTION DoB()
SEPARATOR
MENUITEM "More..." ACTION DoMore()
ENDMENU
@ 2, 5 ADD BUTTON PROMPT "Dropdown" ;
SIZE 80, 60 BITMAP "menu32.bmp" ;
ACTION NIL ;
OF oGroup ;
POPUP ;
MENU oPopup TOP
// Split button: click fires action, arrow opens menu
@ 2, 90 ADD BUTTON PROMPT "Print" ;
SIZE 70, 60 BITMAP "print32.bmp" ;
ACTION QuickPrint() ;
OF oGroup ;
SPLITPOPUP ;
MENU oPopup TOP
Visual Styles
| Style | Description |
|---|---|
2010 | Office 2010 style with gradient tabs and rounded orb button. Left margin = 10. |
2013 | Office 2013 flat style with minimal borders |
2015 | Office 2015/2016 style with colored tab strip |
2016 | Office 2016/365 modern flat style |
| (default) | Classic ribbon style with full gradients and 3D boxes |
You can change the style at runtime using SetStyles():
// Switch to 2016 style
oRBar:SetStyles( .F., .F., .F., 25, , , , , , , , , , .T. )
Tips
- Always include
ribbon.chfor the ribbon command preprocessor directives. - The ribbon height should be around 140-160 pixels for comfortable button placement.
- Use
TOPlayout for large icon buttons (icon above text) and default layout for small icon buttons (icon left of text). - Groups are added to specific tabs via the
TO nOptionclause. Tab indices are 1-based. - Use
SPLITPOPUPtype for buttons that have both a direct action and a dropdown menu. - Keyboard accelerators are automatically supported when
lUseAccis.T.-- press Alt to show key hints. - The
WHENclause on buttons supports dynamic enable/disable based on application state. - For responsive layouts, the ribbon automatically resizes with the window width.
Ver También
- TControl -- parent class
- TButton / TBtnBmp -- traditional toolbar buttons
- TMenu -- menus used in popup/split buttons
- More Controls -- TReBar for classic dockable toolbars