14 KiB
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 applicationRE/ToonBoomActionManager.dll.i64- AC_Toolbar and AC_Manager implementationsRE/ToonBoomLayout.dll.i64- TULayoutView and TULayoutFrame implementations
Overview
Toon Boom uses a two-tier toolbar system:
- Global Toolbars - Application-wide toolbars (FileToolbar, EditToolbar, DrawingToolToolbar, etc.)
- 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:
// 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:
<toolbar id="DrawingViewToolbar" trContext="Toolbars">
<item id="DrawingTool.Select" />
<separator />
<item id="DrawingTool.Brush" />
<!-- ... more items ... -->
</toolbar>
2. Global Toolbar Initialization
Global toolbars are shown during session initialization (sub_14002F840):
// 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:
// 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:
// 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:
// 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<QString> m_buttonConfig; // +0x38 - Current button order
QList<QString> 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:
<toolbar id="MyCustomViewToolbar" trContext="MyToolbars">
<item id="MyResponder.Action1" />
<item id="MyResponder.Action2" />
<separator />
<placeholder id="CustomItems" />
</toolbar>
Step 2: Override toolbar() in Your View
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<void(*)(AC_Manager*, QDomElement*, const QString&)>(
(*reinterpret_cast<void***>(manager))[52]
);
QString toolbarName("MyCustomViewToolbar");
getToolbarElement(manager, &element, toolbarName);
return element;
}
};
Step 3: Register Toolbar XML
Ensure your toolbar XML is loaded during initialization:
// 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<void(*)(AC_Manager*, const QDomElement&, const QString&, bool)>(
(*reinterpret_cast<void***>(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 operationsEditToolbar- Edit operationsDrawingToolToolbar- Drawing toolsArtLayerToolbar- Art layer selectionSceneplanningToolToolbar- Scene planning toolsOnionSkinToolbar- Onion skin controlsFlipToolbar- Flip/mirror toolsGameToolbar- Game export toolsAlignmentGuidesToolbar- Alignment guidesMarkDrawingToolBar- Mark drawing tools
View-Specific Toolbars
DrawingViewToolbar- Drawing viewCameraViewToolbar- Camera viewTimelineViewToolbar- Timeline viewXsheetViewToolbar- Xsheet viewNetworkViewToolbar- Network/Node viewFunctionViewToolbar- Function curve viewPlaybackViewToolbar- Playback viewModelViewToolbar- Model viewLibraryViewToolbar- Library viewModuleLibraryViewToolbar- Module library viewFreeViewToolbar- Free-form view