toon-boom-extension-framework/docs/TULayoutView_Toolbar_Integration.md

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 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:

// 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 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