/** * @file toon_boom_layout.hpp * @brief Reconstructed header files for ToonBoomLayout.dll classes * * These class definitions are reverse-engineered from ToonBoomLayout.dll * used in Toon Boom Harmony Premium and Storyboard Pro. * * WARNING: This is a reconstruction based on binary analysis. Member offsets * and sizes have been verified but exact types may differ from the original. * * @see RE/ToonBoomLayout_Classes.md for detailed analysis */ #ifndef TOON_BOOM_LAYOUT_HPP #define TOON_BOOM_LAYOUT_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Forward declarations class TULayoutView; class TULayoutViewHolder; class TULayoutFrame; class TULayoutManager; class TULayoutManager_Private; class TULayoutArea; class TULayoutSplitter; class TULayoutMainWindow; class TULayoutDisplayTools; class TULayout; class AC_Manager; class AC_Menu; class AC_Toolbar; class AC_ActionInfo; class AC_ToolbarItemGenerator; class AC_Responder; class AC_ResponderTemplate; class TUWidgetLayoutView; class GUT_TabBar; class GUT_Tab; class LAY_ToolbarInfo; class UI_Splitter; class WID_VBoxLayout; class WID_HBoxLayout; /** * @brief Result code for action command handling */ enum class AC_Result { NotHandled = 0, Handled = 1, Error = 2 }; // ============================================================================= // AC_Responder, AC_ResponderTemplate, AC_ResponderTemplateWidget // ============================================================================= // // These classes are implemented in Toon Boom DLLs (ToonBoomActionManager.dll // or similar). Since we don't have access to those libraries for linking, // we provide forward declarations only. // // For reference, the full interface is documented in RE/ToonBoomLayout_Classes.md // // Key vtable addresses (in ToonBoomLayout.dll): // - AC_Responder vtable: 0x18004cd28 // - AC_ResponderTemplate vtable: 0x18004cdc8 // - AC_ResponderTemplateWidget vtable: 0x18004ce68 // // AC_Responder is a pure abstract interface with the following virtual methods: // - perform(AC_ActionInfo*) -> AC_Result // - performDownToChildren(AC_ActionInfo*) -> AC_Result // - parentResponder() -> AC_Responder* // - proxyResponder() -> AC_Responder* // - acceptsFirstResponder() -> bool // - acceptsSelectionResponder() -> bool // - becomeFirstResponder() -> bool // - becomeSelectionResponder() -> bool // - resignFirstResponder() -> bool // - handleShortcuts() const -> bool // - shouldReceiveMessages() const -> bool // - responderIdentity() const -> const QString& // - responderDescription() const -> const QString& // - setResponderDescription(const QString&) -> void // - actionManager() const -> AC_Manager* // // AC_ResponderTemplate (sizeof 0x38): // - Inherits AC_Responder // - +0x08: QString m_identity // - +0x20: QString m_description // - +0x30: AC_Manager* m_manager // // AC_ResponderTemplateWidget (sizeof ~0x68 for T=QWidget): // - Inherits T (QWidget, QFrame, etc.) and AC_ResponderTemplate // - Combines a Qt widget with action responder capabilities // ============================================================================= // Forward declarations only - implemented in Toon Boom DLLs class AC_Responder; class AC_ResponderTemplate; // Template class - forward declaration for common instantiations // The actual template is implemented in Toon Boom DLLs template class AC_ResponderTemplateWidget; /** * @brief Toolbar configuration and state for a view * * Stores position, visibility, and button configuration for a toolbar * associated with a TULayoutView. * * sizeof(LAY_ToolbarInfo) = 0x68 (104 bytes) on x64 */ class LAY_ToolbarInfo { public: LAY_ToolbarInfo(); LAY_ToolbarInfo(const LAY_ToolbarInfo &other); LAY_ToolbarInfo(QString name, int x, int y, int width, int height, int index, bool visible, bool isDefault); ~LAY_ToolbarInfo(); LAY_ToolbarInfo &operator=(const LAY_ToolbarInfo &other); // Getters int getHeight() const; // +0x10 const QString &getName() const; // +0x18 int getNewline() const; // +0x14 (bool as int) Qt::Orientation getOrientation() const; // +0x30 const Qt::ToolBarArea &getToolBarArea() const; // +0x34 bool isDefault() const; // +0x16 bool isVisible() const; // +0x15 // Setters void setHeight(int height); // +0x10 void setIndex(int index); // +0x08 void setName(const QString &name); // +0x18 void setNewline(int newline); // +0x14 void setOrientation(Qt::Orientation orientation); // +0x30 void setToolBarArea(Qt::ToolBarArea area); // +0x34 void setVisible(bool visible); // +0x15 void setWidth(int width); // +0x0C void setX(int x); // +0x00 void setY(int y); // +0x04 // Serialization void fromXml(const QDomElement &element); void toXml(QDomElement &element) const; // Button configuration const QList *getButtonConfig() const; // +0x38 void setButtonConfig(const QList *config); // +0x38 void setButtonDefaultConfig(const QList *config); // +0x50 private: // Member layout (x64): int m_x; // +0x00 int m_y; // +0x04 int m_index; // +0x08 int m_width; // +0x0C int m_height; // +0x10 bool m_newline; // +0x14 bool m_visible; // +0x15 bool m_isDefault; // +0x16 char _padding1; // +0x17 QString m_name; // +0x18 (24 bytes) Qt::Orientation m_orientation; // +0x30 Qt::ToolBarArea m_toolBarArea; // +0x34 QList m_buttonConfig; // +0x38 (24 bytes) QList m_buttonDefaultConfig; // +0x50 (24 bytes) }; /** * @brief Abstract base class for all layout views in Toon Boom * * Represents a dockable/tabbable view panel that can be displayed in a * TULayoutFrame. This is an abstract class - subclasses must implement * the pure virtual methods to provide actual functionality. * * LINKING: Requires ToonBoomLayout.lib - constructor/destructor are exported. * * sizeof(TULayoutView) = 0xB8 (184 bytes) on x64 * * VTABLE ORDER (32 slots total): * 0: ~TULayoutView() * 1: widget() = 0 * 2: initiate() * 3: getWidget() const = 0 * 4: getWidget() = 0 * 5: getParentHolderWidget() const * 6: getParentHolderWidget() * 7: hasMenu() * 8: setMenu(AC_Manager*, ...) * 9: setMenu(AC_Menu*, ...) * 10: menu() * 11: toolbar() * 12: setToolbarInfo() * 13: connectView() * 14: disconnectView() * 15: initializedFromCopy() * 16: getCaption() * 17: getDynamicTextForCaption() * 18: wantEditionStack() * 19: displayName() * 20: compositeChanged() * 21: dropOverComposite() * 22: wantComposites() * 23: initActionManager() * 24: wantDisplaySelector() * 25: isUsingDefaultDisplay() * 26: storeViewPreferences() * 27: loadViewPreferences() * 28: cshHelpId() * 29: triggerMenuChanged() = 0 * 30: copy() * 31: isTULayoutView() = 0 */ class TULayoutView { public: /** * @brief Menu type enumeration for TULayoutView */ enum class MenuType : int { Primary = 0, // Main context menu Secondary = 1 // Secondary/overflow menu }; // Constructors - implemented in ToonBoomLayout.dll TULayoutView(); TULayoutView(const TULayoutView &other); virtual ~TULayoutView(); // slot 0 TULayoutView &operator=(const TULayoutView &other); // ===== PURE VIRTUAL METHODS (MUST override all 5) ===== virtual QWidget *widget() = 0; // slot 1 virtual TULayoutView *initiate(QWidget *parent); // slot 2 virtual const QWidget *getWidget() const = 0; // slot 3 virtual QWidget *getWidget() = 0; // slot 4 // ===== Virtual methods with default implementations ===== virtual const TULayoutViewHolder *getParentHolderWidget() const; // slot 5 virtual TULayoutViewHolder *getParentHolderWidget(); // slot 6 virtual bool hasMenu(); // slot 7 virtual void setMenu(AC_Manager *manager, const char *menuName, MenuType type); // slot 8 virtual void setMenu(AC_Menu *menu, MenuType type); // slot 9 virtual AC_Menu *menu(MenuType type); // slot 10 virtual QDomElement toolbar(); // slot 11 virtual void setToolbarInfo(const LAY_ToolbarInfo &info); // slot 12 virtual void connectView() {} // slot 13 (empty impl) virtual void disconnectView() {} // slot 14 (empty impl) virtual bool initializedFromCopy(); // slot 15 virtual QString getCaption(bool includeAdvanced) const; // slot 16 virtual QString getDynamicTextForCaption() const; // slot 17 virtual bool wantEditionStack() const { return false; } // slot 18 (returns false) virtual QString displayName() const; // slot 19 virtual void compositeChanged(const QString &) {} // slot 20 (empty impl) virtual void dropOverComposite(QDropEvent *, const QString &) {} // slot 21 (empty) virtual bool wantComposites() const { return false; } // slot 22 (returns false) virtual void initActionManager(AC_Manager *) {} // slot 23 (empty impl) virtual bool wantDisplaySelector() const { return false; } // slot 24 (returns false) virtual bool isUsingDefaultDisplay() const { return false; } // slot 25 (returns false) virtual bool storeViewPreferences(QDomElement &) const { return false; } // slot 26 virtual void loadViewPreferences(const QDomElement &) {} // slot 27 (empty impl) virtual QString cshHelpId(); // slot 28 // ===== MORE PURE VIRTUALS ===== virtual void triggerMenuChanged() = 0; // slot 29 - MUST override! // Non-virtual methods void setCaption(const QString &caption); const LAY_ToolbarInfo &getToolbarInfo(); TULayoutFrame *getLayoutFrame(const QWidget *widget) const; // Static static bool inClosingState(); protected: virtual void copy(const TULayoutView &other); // slot 30 virtual void isTULayoutView() = 0; // slot 31 - MUST override! private: // Member layout (x64): // vptr at +0x00 (8 bytes) QString m_internalName; // +0x08 (24 bytes) - "View{N}" by default LAY_ToolbarInfo m_toolbarInfo; // +0x20 (104 bytes) AC_Menu *m_menuByType[2]; // +0x88 (16 bytes) - indexed by MenuType bool m_initializedFromCopy; // +0x98 (1 byte) char _padding[7]; // +0x99 QString m_caption; // +0xA0 (24 bytes) static int _uniqueId; // Static counter for unique names }; // Note: AC_ResponderTemplateWidget is a template class defined in Toon Boom DLLs // that combines a QWidget subclass with AC_Responder capabilities. // Memory layout for AC_ResponderTemplateWidget: // - +0x00: vptr (QObject) // - +0x10: vptr (QPaintDevice) // - +0x18-0x27: QWidget members // - +0x28: vptr (AC_ResponderTemplateWidget) // - +0x30: AC_Manager* m_actionManager // - +0x38: QString m_responderIdentity // - +0x50: QString m_responderDescription // sizeof(AC_ResponderTemplateWidget) ≈ 0x68 (104 bytes) on x64 // ============================================================================= // TUWidgetLayoutView // ============================================================================= // // TUWidgetLayoutView is implemented in ToonBoomLayout.dll. It inherits from // AC_ResponderTemplateWidget and embeds a TULayoutView at offset +0x68. // // Since the base classes are implemented in Toon Boom DLLs, we cannot define // a compilable C++ class here. Use this as a reference for the memory layout // when working with TUWidgetLayoutView pointers obtained from the application. // // Memory layout (x64 MSVC): // - +0x00: vptr (QObject) - from AC_ResponderTemplateWidget // - +0x10: vptr (QPaintDevice) // - +0x18-0x27: QWidget members // - +0x28: vptr (AC_ResponderTemplateWidget) // - +0x30: AC_Manager* m_actionManager // - +0x38: QString m_responderIdentity // - +0x50: QString m_responderDescription // - +0x68: vptr (TULayoutView) - TULayoutView base starts here // - +0x70: QString m_internalName (from TULayoutView) // - +0x88: LAY_ToolbarInfo m_toolbarInfo (from TULayoutView) // - +0xF0: AC_Menu* m_menuByType[2] (from TULayoutView) // - +0x100: bool m_initializedFromCopy (from TULayoutView) // - +0x108: QString m_caption (from TULayoutView) // // sizeof(TUWidgetLayoutView) ≈ 0x120 (288 bytes) on x64 // // Key methods (in ToonBoomLayout.dll): // - Constructor at 0x1800300A0 // - Destructor at 0x180030480 // - getWidget() at 0x180030E90 - returns (this - 104) from TULayoutView* // // To get TULayoutView* from TUWidgetLayoutView*: // TULayoutView* layoutView = reinterpret_cast( // reinterpret_cast(widgetLayoutView) + 104); // // To get TUWidgetLayoutView* from TULayoutView*: // TUWidgetLayoutView* widget = reinterpret_cast( // reinterpret_cast(layoutView) - 104); // ============================================================================= // Forward declaration - implemented in ToonBoomLayout.dll // Use the helper functions below for pointer conversion class TUWidgetLayoutView; /** * @brief Convert TUWidgetLayoutView* to its embedded TULayoutView* * @param widget Pointer to TUWidgetLayoutView * @return Pointer to embedded TULayoutView at offset +104 */ inline TULayoutView *TUWidgetLayoutView_getLayoutView(TUWidgetLayoutView *widget) { return reinterpret_cast(reinterpret_cast(widget) + 104); } /** * @brief Convert TULayoutView* back to containing TUWidgetLayoutView* * @param view Pointer to TULayoutView (must be embedded in TUWidgetLayoutView) * @return Pointer to containing TUWidgetLayoutView at offset -104 */ inline TUWidgetLayoutView *TULayoutView_getWidgetLayoutView(TULayoutView *view) { return reinterpret_cast(reinterpret_cast(view) - 104); } /** * @brief Get the QWidget* from a TUWidgetLayoutView* * @param widget Pointer to TUWidgetLayoutView * @return The QWidget* (same address, different type) */ inline QWidget *TUWidgetLayoutView_getWidget(TUWidgetLayoutView *widget) { return reinterpret_cast(widget); } /** * @brief Container widget that holds 1-2 TULayoutView instances * * When holding 2 views, they are displayed in a vertical splitter. * Single views are displayed directly in the layout. * * sizeof(TULayoutViewHolder) = 0x70 (112 bytes) on x64 */ class TULayoutViewHolder : public QWidget { Q_OBJECT public: explicit TULayoutViewHolder(QWidget *parent = nullptr); virtual ~TULayoutViewHolder(); /** * @brief Add a view to this holder * @param view The view to add * @param splitterRatio Initial splitter ratio (only used when adding 2nd * view) * @return true if added successfully, false if holder is full (max 2) */ bool addView(TULayoutView *view, double splitterRatio = 0.5); /** * @brief Remove a view from this holder * @param view The view to remove * @return true if removed successfully */ bool removeView(TULayoutView *view); /** * @brief Get the number of views in this holder * @return 0, 1, or 2 */ int nbViews() const; /** * @brief Get the current splitter ratio * @return Ratio between 0.0 and 1.0 (left/total) */ double splitterRatio(); /** * @brief Set focus to the first view's widget */ void setFocusToChild(); /** * @brief Update widget visibility and layout */ void updateWidgets(); // Static translation helper private: bool removeWidgetFromLayout(QWidget *widget, QLayout *layout); // Member layout (x64): // QWidget members at +0x00 to +0x27 std::vector m_views; // +0x28 (24 bytes) double m_savedSplitterRatio; // +0x40 (8 bytes) - default 0.5 UI_Splitter *m_splitter; // +0x48 (8 bytes) - vertical splitter WID_VBoxLayout *m_leftLayout; // +0x50 (8 bytes) WID_VBoxLayout *m_rightLayout; // +0x58 (8 bytes) QFrame *m_leftFrame; // +0x60 (8 bytes) QFrame *m_rightFrame; // +0x68 (8 bytes) }; /** * @brief Top-level dockable/floatable frame with tabbed view holders * * Contains a tab bar for switching between view holders, toolbar area, * and various control buttons. * * Inherits from QFrame for border painting and styling. */ class TULayoutFrame : public QFrame { Q_OBJECT public: /** * @brief Construct a TULayoutFrame * @param manager Action/menu manager for creating menus * @param parent Parent widget * @param name Object name for this frame * @param layoutManager The TULayoutManager managing this frame * @param floating True if this is a floating window (false = docked) * @param unknown Unknown parameter * @param singleViewMode True for single view mode */ TULayoutFrame(AC_Manager *manager, QWidget *parent, const QString &name, TULayoutManager *layoutManager, bool floating, bool unknown, bool singleViewMode); virtual ~TULayoutFrame(); // Accessors TULayoutManager *getLayoutManager(); QStackedWidget *getStack() const; GUT_TabBar *getTab(); AC_Toolbar *getToolbar() const; bool isDocked() const; bool isInSingleViewMode() const; bool isVisibleFullScreen() const; // Tab management int currentTab() const; QString currentTabName() const; TULayoutViewHolder *currentTabViewHolder(); const GUT_Tab *addTab(TULayoutViewHolder *holder, const QString &name); void delTab(TULayoutViewHolder *holder); void setCurrentTab(int index); void setCurrentTab(TULayoutViewHolder *holder); bool updateTabName(TULayoutViewHolder *holder); void setTabVisible(bool visible); // View management void delView(QWidget *widget); void delViewHolder(TULayoutViewHolder *holder); TULayoutView *newTab(int areaIndex); void newView(int areaIndex); QWidget *getViewWidget(int index); void setCurrentViewByIndex(unsigned int index); // State management void setCurrent(bool current); void setFocusToChild() const; void updateCaption(); void updateFocus(); void updateVisibilityStatus(); void updateTabHolderSplitters(); void emitViewAdded(); void postCustomRaiseEvent(); // Toolbar management const LAY_ToolbarInfo *getToolbarInfoForView(const QString &viewName) const; void setToolbarInfoForView(const QString &viewName, const LAY_ToolbarInfo &info); void showViewToolBar(); void removeViewToolBar(); void showToolBarMenu(); void loadToolbars(QDomElement &element); void saveToolbars(QDomElement &element); void saveLayoutToolbar(QDomElement &element, QToolBar *toolbar); void createEmptyToolBar(const QString &name); // Composite/display management void enableComposite(bool enable); void enableEditionStack(bool enable); void compositeAdded(const QString &name); void compositeDeleted(const QString &name); void compositeOrGroupRenamed(); void resetDisplayList(); void resetDisplayList(const QString &name, const std::vector &items); // Static signals: void viewAdded(); public slots: void handleCloseViewButton(); void onActionCloseAllTabs(); void onActionCloseCurrentTab(); void onActionCloseTab(QString name); void onActionRaiseArea(QString name); void onActionRenameTab(); void renameTab(int index); void syncCurrentTab(); virtual void contextMenuEvent(QContextMenuEvent *event) override; virtual void enterEvent(QEnterEvent *event) override; virtual bool eventFilter(QObject *watched, QEvent *event) override; virtual void mousePressEvent(QMouseEvent *event) override; protected: // Qt event overrides virtual void closeEvent(QCloseEvent *event) override; virtual void paintEvent(QPaintEvent *event) override; // Internal methods void borderPaintEvent(QWidget *widget); void filterComposite(const QString &name); int findCompositeName(const QString &name); int findName(const QString &name); bool getCurToolbarState(LAY_ToolbarInfo &info); QString getFrameCaption() const; bool isLastDockFrame() const; void updateDisplaySelectorStatus(); void updateEditionStackStatus(); void updateMenuStatus(); private slots: void onDisplayChanged(int index); void onShowLayoutFrameMenu(AC_Menu *menu); void compositeChanged(const QString &name) const; void toolbarWasCustomized(); private: // Member layout (x64): // QFrame members at +0x00 to +0x27 TULayoutManager *m_layoutManager; // +0x28 WID_VBoxLayout *m_mainLayout; // +0x30 WID_HBoxLayout *m_topHBoxLayout; // +0x38 QToolButton *m_menuButton; // +0x40 - "View Menu" button TULayoutMainWindow *m_mainWindow; // +0x48 - contains toolbar area TULayoutDisplayTools *m_displayTools; // +0x50 - display selector QComboBox *m_compositeCombo; // +0x58 - composite selector GUT_TabBar *m_tabBar; // +0x60 - tab bar QStackedWidget *m_stack; // +0x68 - stacked widget for tab content QWidget *m_editionStackWidget; // +0x70 - symbol/edition stack QToolButton *m_closeButton; // +0x78 - close button QToolButton *m_createViewMenuButton; // +0x80 - "Create View Menu" button bool m_isCurrent; // +0x88 - is focused frame bool m_isDocked; // +0x89 - true if docked (not floating) bool m_isInSingleViewMode; // +0x8A - single view mode char _padding1; // +0x8B int _reserved1; // +0x8C AC_Toolbar *m_toolbar; // +0x90 - view-specific toolbar int m_unknown; // +0x98 - initialized to -1 int _reserved2; // +0x9C // Map/list structure at +0xA0-0xAF for toolbar info per view QWidget *m_parentWidget; // +0xB0 AC_Menu *m_layoutFrameMenu; // +0xB8 - context menu AC_Toolbar *m_viewToolbar; // +0xC0 - currently active toolbar }; /** * @brief Lightweight QMainWindow for toolbar hosting inside TULayoutFrame * * Used inside TULayoutFrame to provide toolbar docking areas for * view-specific toolbars. The QStackedWidget is set as its central widget. * * sizeof(TULayoutMainWindow) = 0x30 (48 bytes) on x64 */ class TULayoutMainWindow : public QMainWindow { Q_OBJECT public: explicit TULayoutMainWindow(AC_Manager *manager, QWidget *parent = nullptr); virtual ~TULayoutMainWindow(); AC_Manager *getManager() const { return m_manager; } private: // Member layout (x64): // QMainWindow members at +0x00 to +0x27 AC_Manager *m_manager; // +0x28 - Action manager reference }; /** * @brief Base class for layout persistence and configuration * * Provides layout loading, saving, and toolbar configuration management. * TULayoutManager inherits from this class. * * sizeof(TULayoutStorage) = 0x88 (136 bytes) on x64 */ class TULayoutStorage { public: /** * @brief Toolbar button configuration */ struct ToolbarButtonConfig { QList buttons; bool isDefault; }; TULayoutStorage(const QString &layoutPath); TULayoutStorage(const TULayoutStorage &other); TULayoutStorage &operator=(const TULayoutStorage &other); virtual ~TULayoutStorage(); // Layout management TULayout *addLayout(const QString &name, int index = -1); virtual void delLayout(const QString &name, int index, bool notify); virtual void delLayout(TULayout *layout, bool notify); void delLayouts(); TULayout *duplicateLayout(TULayout *layout); TULayout *findLayout(const QString &name, int index = -1); int findLayoutIndex(const QString &name, int index = -1); int findLayoutIndex(TULayout *layout); TULayout *loadLayout(const QString &name, int index); virtual void loadLayouts(bool reloadFromDisk); void loadLayouts(const QDir &dir, int index); void renameLayout(TULayout *layout, const QString &newName); bool resetLayouts(const QDir &sourceDir); void saveLayout(const QString &name, int index); void saveLayout(TULayout *layout, bool notify); void saveLayoutToolbar(); // Layout toolbar (workspace bar) void addToLayoutToolbar(TULayout *layout); void clearLayoutToolbar(); std::vector &getToolbarLayouts(); void setLayoutToolbarIndex(TULayout *layout, int index); // Accessors TULayout *getCurrentLayout(); TULayout *getPreviousLayout(); size_t getLayoutCount(); void setCurrentLayout(TULayout *layout); QString getFileNameForLayout(TULayout *layout, TULayout *parent = nullptr); bool isLayoutsModified() const; bool isLocked(); // Toolbar configuration const QList *getGlobalToolbarConfig(const QString &name, bool defaultConfig) const; const QList *getViewToolbarConfig(const QString &name, bool defaultConfig) const; void setGlobalToolbarConfig(const QString &name, const QList &config, bool isDefault); void setViewToolbarConfig(const QString &name, const QList &config, bool isDefault); protected: void loadLayoutInfo(const QString &path, bool initial); void selectDefaultLayout(); void setUniqueLayout(QString &name); static void setUniqueLayout(const QList &existing, QString &name); void addToolbarConfig( std::map &configMap, const QString &name, const QList &config, bool isDefault); void clearToolbarConfig(std::map &configMap, bool defaultOnly); private: // Member layout (x64): // vptr at +0x00 TULayout *m_currentLayout; // +0x08 TULayout *m_previousLayout; // +0x10 std::vector m_layouts; // +0x18 (24 bytes) std::vector m_toolbarLayouts; // +0x30 (24 bytes) QString m_layoutPath; // +0x50 (24 bytes) std::map *m_globalToolbarConfig; // +0x68 void *_reserved; // +0x70 std::map *m_viewToolbarConfig; // +0x78 int m_flags; // +0x80 }; /** * @brief Service interface for toolbar management * * Empty interface class for toolbar-related plugin services. */ class PLUG_ToolbarService { public: PLUG_ToolbarService() = default; virtual ~PLUG_ToolbarService() = default; }; /** * @brief Service interface for menu management * * Empty interface class for menu-related plugin services. */ class PLUG_MenuService { public: PLUG_MenuService() = default; virtual ~PLUG_MenuService() = default; }; /** * @brief Private implementation data for TULayoutManager * * Holds the internal state including frame, area, and splitter vectors. * * sizeof(TULayoutManager_Private) = 0x110 (272 bytes) on x64 */ class TULayoutManager_Private : public QObject { Q_OBJECT public: explicit TULayoutManager_Private(TULayoutManager *owner); virtual ~TULayoutManager_Private(); // Accessors QFrame *getMainFrame() const { return m_mainFrame; } WID_VBoxLayout *getMainLayout() const { return m_mainLayout; } const std::vector &getSplitters() const { return m_splitters; } const std::vector &getFrames() const { return m_frames; } const std::vector &getAreas() const { return m_areas; } const std::vector &getPluginAreas() const { return m_pluginAreas; } TULayoutFrame *getCurrentLayoutFrame() const { return m_currentLayoutFrame; } AC_Manager *getActionManager() const { return m_actionManager; } QPoint getSavedPos() const { return m_savedPos; } QSize getSavedSize() const { return m_savedSize; } // Mutators void setMainFrame(QFrame *frame) { m_mainFrame = frame; } void setMainLayout(WID_VBoxLayout *layout) { m_mainLayout = layout; } void setCurrentLayoutFrame(TULayoutFrame *frame) { m_currentLayoutFrame = frame; } void setActionManager(AC_Manager *manager) { m_actionManager = manager; } void setSavedPos(const QPoint &pos) { m_savedPos = pos; } void setSavedSize(const QSize &size) { m_savedSize = size; } private: // Member layout (x64): // QObject members at +0x00 to +0x0F QFrame *m_mainFrame; // +0x10 WID_VBoxLayout *m_mainLayout; // +0x18 char _reserved[0x48]; // +0x20-0x5F (padding) std::vector m_splitters; // +0x60 std::vector m_frames; // +0x78 std::vector m_areas; // +0x90 std::vector m_pluginAreas; // +0xA8 QPoint m_savedPos; // +0xC0 QSize m_savedSize; // +0xC8 int m_stateFlags; // +0xD0 int _padding; // +0xD4 TULayoutFrame *m_currentLayoutFrame; // +0xD8 char _reserved2[0x10]; // +0xE0-0xEF (padding) TULayoutManager *m_owner; // +0xF0 AC_Manager *m_actionManager; // +0xF8 }; /** * @brief Central manager for the entire layout system * * Manages all frames, areas, splitters, toolbars, and layout persistence. * Inherits from QMainWindow, TULayoutStorage, PLUG_ToolbarService, and * PLUG_MenuService to provide comprehensive layout management functionality. * * This is the main entry point for the Toon Boom layout system. */ class TULayoutManager : public QMainWindow, public TULayoutStorage, public PLUG_ToolbarService, public PLUG_MenuService { Q_OBJECT public: explicit TULayoutManager(const QString &layoutPath); virtual ~TULayoutManager(); // Frame management TULayoutFrame *addFrame(const QString &name, bool floating, bool unknown, bool singleViewMode); TULayoutFrame *addFrame(QWidget *parent, const double &ratio, bool floating, bool unknown, bool singleViewMode); void delFrame(TULayoutFrame *frame); bool closeFrame(TULayoutFrame *frame); TULayoutFrame *findFrame(int index) const; TULayoutFrame *findFrame(QWidget *widget) const; TULayoutFrame *findFrame(TULayoutView *view) const; TULayoutFrame *findFirstChildFrame(QWidget *widget); int findNoFrame(TULayoutFrame *frame); int getNbFrame() const; int getNbFrameDocked(); const std::vector &getFrames() const; TULayoutFrame *getCurrentLayoutFrame() const; void setCurrentLayoutFrame(TULayoutFrame *frame); // Area management bool addArea(const char *type, const QString &name, TULayoutView *view, bool visible, bool createFrame, bool docked, const QSize &minSize, bool useMinSize, bool isPlugin, bool defaultVisible, bool unknown); bool addPluginArea(const char *type, const QString &name, TULayoutView *view, bool visible, bool createFrame, bool docked, const QSize &minSize, bool useMinSize, bool defaultVisible); void delAreas(TULayoutFrame *frame = nullptr); TULayoutArea *findArea(const QString &name); TULayoutArea *findArea(QWidget *widget); TULayoutArea *findArea(TULayoutFrame *frame); TULayoutArea *findArea(TULayoutView *view) const; int findNoArea(QWidget *widget); int findNoArea(TULayoutFrame *frame); int findNoArea(const char *name); int getNbArea() const; bool isValidAreaID(int id); int isValidAreaName(const QString &name); const std::vector &getAreas() const; void getAvailableWindows(std::vector &windows); void commitPluginAreas(); // View management bool addView(const char *type, const QString &name, TULayoutView *&view, TULayoutFrame *&frame, bool visible, double ratio); bool addView(const char *type, const QString &name, TULayoutFrame *frame, double ratio, Qt::Orientation orientation, TULayoutView *&view, TULayoutFrame *&newFrame, bool visible, double splitRatio); bool addViewHorizontal(const char *type, const QString &name, TULayoutFrame *frame, double ratio, TULayoutView *&view, TULayoutFrame *&newFrame, bool visible, double splitRatio); bool addViewVertical(const char *type, const QString &name, TULayoutFrame *frame, double ratio, TULayoutView *&view, TULayoutFrame *&newFrame, bool visible, double splitRatio); bool addDetached(const QString &name, const QString &type, TULayoutView *&view, TULayoutFrame *&frame); void deleteAllViews(); TULayoutView *findInstance(const QString &name); TULayoutView *findInstance(const QWidget *widget); TULayoutView *findInstance(const TULayoutFrame *frame, bool current); TULayoutView *findInstance(const TULayoutViewHolder *holder, bool current); TULayoutView *findInstanceOfType(const QString &typeName); TULayoutView *findFirstInstance(); void findAllInstances(const QString &typeName, std::vector &results); QString findInstanceName(TULayoutFrame *frame); void getViews(const TULayoutFrame *frame, std::vector *views) const; bool hasView(const char *name); TULayoutView *currentView(); bool validateView(const QString &name, TULayoutView *view); // Splitter management TULayoutSplitter *getRootSplitter(); void delSplitter(TULayoutSplitter *splitter); int getNbSplitter() const; const std::vector &getSplitters() const; void sortFramesRecursive(TULayoutSplitter *splitter, int &index); int isFrame(QWidget *widget); int isSplitter(QWidget *widget); // Layout operations virtual bool changeLayout(const QString &name, int index); void deleteLayout(); void updateLayout(); void expandMainWindow(); void showFrames(); // Toolbar management virtual AC_Toolbar *addToolbar(const char *name); virtual void addToolbarFromFile(const QString &path, const QString &name, bool global); virtual void addToolbarFromElement(const QDomElement &element, const QString &name, bool global); virtual AC_Toolbar *showToolbar(const char *name, bool show, bool global, AC_ToolbarItemGenerator *generator); virtual bool setToolbarVisibility(const QString &name, bool visible); virtual bool removeToolbar(const char *name); virtual AC_Toolbar *toolbar(const char *name); void addGlobalToolbar(QToolBar *toolbar); void registerGlobalToolbar(const QToolBar *toolbar); void clearGlobalToolBarList(); void getAllToolbars(std::list &viewToolbars, std::list &globalToolbars, bool includeHidden); bool isGlobalToolbar(const QString &name) const; bool isGlobalToolbar(const QToolBar *toolbar) const; virtual bool getMainToolbarDefaultVisibility(const QToolBar &toolbar) const; void showViewToolBars(); void removeViewToolBar(); void showDisplayToolBar(bool show); void showPortNameToolBar(bool show); void hideLayoutToolBar(); void createWorkspaceToolbar(); void destroyWorkspaceToolbar(); void customizeToolBar(); // Menu management virtual bool addMenuFromFile(const QString &path, const QString &name); virtual bool addMenuFromElement(const QString &name, const QDomElement &element); // Fullscreen void fullScreenFrame(TULayoutFrame *frame); void fullScreenMainFrame(TULayoutFrame *frame); void restoreNormalScreen(); // Accessors void setActionManager(AC_Manager *manager); QFrame *getMainFrame() const; QString getDefaultLayoutsPath() const; virtual const unsigned int &getCurrentViewBorderColor(); QString unconnectedDisplayNodeName() const; QString unconnectedDisplayNodeNameTranslated() const; QString noPortFilterNameTranslated() const; // Event handlers virtual void closeEvent(QCloseEvent *event) override; virtual void moveEvent(QMoveEvent *event) override; virtual void resizeEvent(QResizeEvent *event) override; virtual QMenu *createPopupMenu() override; // Layout operations virtual void loadLayouts(bool reloadFromDisk) override; virtual void updateLayoutBar(); virtual void updateLayoutBarSelection(); virtual void onPreferenceChanged(); virtual void onActionFullscreen(); virtual void onActionFullscreenValidate(AC_ActionInfo *info); // Composite management void compositeAdded(const QString &name); void compositeDeleted(const QString &name); void raiseWindow(); TULayoutView *raiseArea(const QString &name, TULayoutFrame *frame, bool createNew, const QPoint &pos); TULayoutView *raiseArea(int areaIndex, TULayoutFrame *frame, bool createNew, const QPoint &pos); TULayoutView *raiseArea(TULayoutArea *area, TULayoutFrame *frame, bool createNew, const QPoint &pos); TULayoutView *newDetached(TULayoutArea *area, QPoint pos); void saveCurrentLayout(); signals: void backgroundImageChanged(); void fullScreenStateChanged(); void layoutChanged(TULayout *layout); void preferencesChange(); void sceneSaved(); public slots: void onActionRaiseArea(QString name, bool createNew); void onActionSaveLayouts(); void onActionSaveWorkspaceAs(); void onActionShowLayoutManager(); void onLayoutMenu(int index); void onPortNamesChanged(int index); void onPortNamesChanged(QString name); void onDefaultDisplayChanged(int index); protected slots: void closeLayoutCheck(); void refresh(); void resetDisplayLists(); void resetPortNamesLists(); void compositeOrGroupRenamed(); void updateAutoSaveLayoutVisibilityStatus(); protected: void layoutFrameBeingDeleted(TULayoutFrame *frame); private: void sortToolbarList(QList list, std::list &viewToolbars, std::list &globalToolbars, bool includeHidden); QToolBar *getToolbarUnderMouse(); void moveGlobalToolbar(); void toolbarWasCustomized(QString name); void updateToolBarScriptIcons(const QString &oldName, const QString &newName, const QString &path); // Member layout (x64): // QMainWindow members at +0x00 to +0x27 // TULayoutStorage members at +0x28 to +0xAF // PLUG_ToolbarService at +0xB0 // PLUG_MenuService at +0xB8 bool m_unknown; // +0xC0 char _padding[7]; // +0xC1-0xC7 TULayoutManager_Private *m_private; // +0xC8 }; #endif // TOON_BOOM_LAYOUT_HPP