# TULayoutView Toolbar Integration in Toon Boom
This document explains how toolbars are created, managed, and displayed within TULayoutView instances in Toon Boom Harmony Premium and Storyboard Pro.
**IDA Databases:**
- `RE/HarmonyPremium.exe.i64` - Main application
- `RE/ToonBoomActionManager.dll.i64` - AC_Toolbar and AC_Manager implementations
- `RE/ToonBoomLayout.dll.i64` - TULayoutView and TULayoutFrame implementations
## Overview
Toon Boom uses a two-tier toolbar system:
1. **Global Toolbars** - Application-wide toolbars (FileToolbar, EditToolbar, DrawingToolToolbar, etc.)
2. **View-Specific Toolbars** - Toolbars that appear when a specific view has focus (DrawingViewToolbar, TimelineViewToolbar, CameraViewToolbar, etc.)
## Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ TULayoutManager │
│ - Manages all frames, areas, and global toolbars │
│ - Holds reference to AC_Manager at offset +344 │
│ - showToolbar() at vtable+416 creates/shows toolbars by name │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ TULayoutFrame │
│ - Contains TULayoutMainWindow for toolbar docking │
│ - showViewToolBar() displays view-specific toolbar │
│ - Stores LAY_ToolbarInfo per view for configuration │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ TULayoutViewHolder │
│ - Contains 1-2 TULayoutView instances │
│ - Notifies frame when active view changes │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ TULayoutView │
│ - Abstract base class for all views │
│ - toolbar() virtual method returns QDomElement │
│ - setToolbarInfo() receives LAY_ToolbarInfo │
└─────────────────────────────────────────────────────────────────┘
```
## Toolbar Definition and Creation Flow
### 1. Toolbar XML Loading
During application startup, toolbars are loaded from `toolbars.xml`:
```cpp
// From HarmonyPremium.exe session initialization (0x140034EB0)
// Loads toolbars.xml via AC_Manager::addToolbarFromFile (vtable+376)
UT_String toolbarsPath = RM_GetResourcePath("toolbars.xml");
actionManager->addToolbarFromFile(toolbarsPath.ToQString(), &toolbarList);
```
The `toolbars.xml` file defines toolbar content using XML elements like:
```xml
```
### 2. Global Toolbar Initialization
Global toolbars are shown during session initialization (`sub_14002F840`):
```cpp
// Show global toolbars via TULayoutManager::showToolbar (vtable+416)
layoutManager->showToolbar("FileToolbar", true);
layoutManager->showToolbar("EditToolbar", true);
layoutManager->showToolbar("DrawingToolToolbar", true);
layoutManager->showToolbar("ArtLayerToolbar", true);
// Conditional toolbars based on features
if (WHO_Features::hasOnionSkinToolbar()) {
layoutManager->showToolbar("OnionSkinToolbar", false, true, nullptr);
}
```
**Key Function Addresses (HarmonyPremium.exe):**
- Session toolbar init: `0x14002F840`
- TULayoutManager::showToolbar import: `0x1409c8ea0`
### 3. View-Specific Toolbar Definition
Each view class overrides `TULayoutView::toolbar()` to return its toolbar definition:
```cpp
// Example: CameraView::toolbar() at 0x1403BC450
QDomElement CameraView::toolbar() {
// Get AC_Manager from embedded context (offset -56 from TULayoutView*)
AC_Manager* manager = *(AC_Manager**)(this - 56);
if (manager) {
// Call AC_Manager::getToolbarElement (vtable+416 / offset 52*8)
QDomElement element;
manager->getToolbarElement(&element, "CameraViewToolbar");
return element;
}
return QDomElement(); // Empty if no manager
}
```
**Known View Toolbar Implementations:**
| View Class | Toolbar Name | Address |
|------------|--------------|---------|
| DrawingView | "DrawingViewToolbar" | `0x1403B9880` |
| CameraView | "CameraViewToolbar" | `0x1403BC450` |
| TimelineView | "TimelineViewToolbar" | `0x14011C5F0` |
| SGV_Graph3DView | (custom impl) | `0x1409e1866` |
### 4. Toolbar Display Flow
When a view gains focus, the toolbar is displayed through this flow:
```
1. User clicks on a view widget
│
▼
2. Application event handler detects focus change
(sub_140059DE0 checks for TULayoutFrame inheritance)
│
▼
3. TULayoutManager::setCurrentLayoutFrame(frame)
│
▼
4. TULayoutFrame::showViewToolBar()
- Gets current view from view holder
- Calls view->toolbar() to get QDomElement
- Creates AC_ToolbarImpl from element
- Adds toolbar to TULayoutMainWindow
│
▼
5. Toolbar becomes visible in frame's toolbar area
```
## AC_Toolbar Integration
### AC_Manager Methods Used
The AC_Manager provides these key toolbar methods:
| Method | Vtable Offset | Description |
|--------|---------------|-------------|
| `getToolbarElement` | +416 (52*8) | Returns QDomElement for toolbar by name |
| `addToolbarFromFile` | +376 (47*8) | Loads toolbar definitions from XML file |
| `createToolbar` | +368 (46*8) | Creates AC_ToolbarImpl from element |
### AC_ToolbarImpl Creation
When `TULayoutFrame::showViewToolBar()` needs to display a toolbar:
```cpp
// Pseudocode for toolbar creation
void TULayoutFrame::showViewToolBar() {
TULayoutView* view = getCurrentView();
if (!view) return;
// Get toolbar XML element from view
QDomElement toolbarElement = view->toolbar();
if (toolbarElement.isNull()) return;
// Create AC_ToolbarImpl via AC_Manager
AC_Toolbar* toolbar = m_actionManager->createToolbar(
this, // owner
toolbarElement.attribute("text"),
m_mainWindow, // parent QMainWindow
toolbarElement.attribute("id").toUtf8().constData(),
toolbarElement,
nullptr // default config
);
// Add to frame's main window
m_mainWindow->addToolBar(Qt::TopToolBarArea, toolbar->toQToolBar());
// Store for later removal
m_viewToolbar = toolbar;
}
```
### LAY_ToolbarInfo Configuration
Each view can have stored toolbar configuration via `LAY_ToolbarInfo`:
```cpp
// Structure of LAY_ToolbarInfo (104 bytes)
class LAY_ToolbarInfo {
int m_x; // +0x00 - X position
int m_y; // +0x04 - Y position
int m_index; // +0x08 - Toolbar index
int m_width; // +0x0C - Width
int m_height; // +0x10 - Height
bool m_newline; // +0x14 - Break to new line
bool m_visible; // +0x15 - Visibility
bool m_isDefault; // +0x16 - Using default config
QString m_name; // +0x18 - Toolbar name
Qt::Orientation m_orientation; // +0x30 - Horizontal/Vertical
Qt::ToolBarArea m_toolBarArea; // +0x34 - Docking area
QList m_buttonConfig; // +0x38 - Current button order
QList m_buttonDefaultConfig; // +0x50 - Default button order
};
```
The view receives its toolbar info via `TULayoutView::setToolbarInfo()`:
- Import: `0x1409c8f4e` (thunk to ToonBoomLayout.dll)
- Called by TULayoutFrame when loading saved layout preferences
## Implementing Custom View Toolbars
### Step 1: Define Toolbar in XML
Create a toolbar definition that will be loaded by AC_Manager:
```xml
```
### Step 2: Override toolbar() in Your View
```cpp
class MyCustomView : public TULayoutView {
public:
QDomElement toolbar() override {
// Get AC_Manager - depends on your view's structure
// For TUWidgetLayoutView subclasses, manager is at offset -56
AC_Manager* manager = getActionManager();
if (!manager) {
return QDomElement();
}
// Use AC_Manager to get toolbar element by name
QDomElement element;
// Call via vtable[52] - getToolbarElement
auto getToolbarElement = reinterpret_cast(
(*reinterpret_cast(manager))[52]
);
QString toolbarName("MyCustomViewToolbar");
getToolbarElement(manager, &element, toolbarName);
return element;
}
};
```
### Step 3: Register Toolbar XML
Ensure your toolbar XML is loaded during initialization:
```cpp
// Option 1: Add to existing toolbars.xml (if modifying installation)
// Option 2: Load programmatically
AC_Manager* manager = PLUG_Services::getActionManager();
if (manager) {
// Use addToolbarFromElement (vtable+376)
QDomDocument doc;
doc.setContent(myToolbarXml);
QDomElement element = doc.documentElement();
// Call via vtable
auto addToolbarFromElement = reinterpret_cast(
(*reinterpret_cast(manager))[47]
);
addToolbarFromElement(manager, element, "MyCustomViewToolbar", false);
}
```
## Key Memory Offsets
### TULayoutView (from TULayoutView*)
- `+0x00`: vptr
- `+0x08`: QString m_internalName
- `+0x20`: LAY_ToolbarInfo m_toolbarInfo (104 bytes)
- `+0x88`: AC_Menu* m_menuByType[2]
- `+0xA0`: QString m_caption
### TULayoutFrame (from TULayoutFrame*)
- `+0x28`: TULayoutManager* m_layoutManager
- `+0x48`: TULayoutMainWindow* m_mainWindow (toolbar host)
- `+0x90`: AC_Toolbar* m_toolbar
- `+0xC0`: AC_Toolbar* m_viewToolbar
### AC_ToolbarImpl (from QToolBar base)
- `+0x28`: AC_ContainerImpl m_container (88 bytes)
- `+0x80`: AC_Toolbar vptr
- `+0x98`: QString m_responderIdentity
- `+0xC8`: bool m_isCustomizable
- `+0xE0`: QObject* m_owner
## Database Reference
### HarmonyPremium.exe
| Symbol | Address | Description |
|--------|---------|-------------|
| Session toolbar init | `0x14002F840` | Initializes all global toolbars |
| DrawingView::toolbar | `0x1403B9880` | Returns DrawingViewToolbar element |
| CameraView::toolbar | `0x1403BC450` | Returns CameraViewToolbar element |
| TimelineView::toolbar | `0x14011C5F0` | Returns TimelineViewToolbar element |
| TULayoutView::setToolbarInfo import | `0x1409c8f4e` | Sets toolbar configuration |
| TULayoutView::toolbar import | `0x1409c8fc0` | Returns toolbar QDomElement |
| TULayoutManager::showToolbar import | `0x1409c8ea0` | Shows/creates toolbar by name |
| TULayoutManager::addToolbar import | `0x1409c8e4c` | Adds toolbar to manager |
### ToonBoomActionManager.dll
| Symbol | Address | Description |
|--------|---------|-------------|
| AC_ToolbarImpl::AC_ToolbarImpl | `0x180032df0` | Constructor |
| AC_ToolbarImpl::~AC_ToolbarImpl | `0x180033080` | Destructor |
| AC_ToolbarImpl::create | `0x180033910` | Creates toolbar from XML |
| AC_ToolbarImpl::insert | `0x1800345e0` | Inserts item at position |
| AC_ToolbarImpl vtable | `0x180054eb0` | Main vtable |
## Toolbar Names Reference
### Global Toolbars
- `FileToolbar` - File operations
- `EditToolbar` - Edit operations
- `DrawingToolToolbar` - Drawing tools
- `ArtLayerToolbar` - Art layer selection
- `SceneplanningToolToolbar` - Scene planning tools
- `OnionSkinToolbar` - Onion skin controls
- `FlipToolbar` - Flip/mirror tools
- `GameToolbar` - Game export tools
- `AlignmentGuidesToolbar` - Alignment guides
- `MarkDrawingToolBar` - Mark drawing tools
### View-Specific Toolbars
- `DrawingViewToolbar` - Drawing view
- `CameraViewToolbar` - Camera view
- `TimelineViewToolbar` - Timeline view
- `XsheetViewToolbar` - Xsheet view
- `NetworkViewToolbar` - Network/Node view
- `FunctionViewToolbar` - Function curve view
- `PlaybackViewToolbar` - Playback view
- `ModelViewToolbar` - Model view
- `LibraryViewToolbar` - Library view
- `ModuleLibraryViewToolbar` - Module library view
- `FreeViewToolbar` - Free-form view