# Adding a New Control

## Overview

Adding a new control to GacUI requires coordinated changes across multiple files to integrate the control into the class hierarchy, template system, theme management, reflection system, and XML compiler. This document provides a comprehensive guide covering control classes, templates, inheritance patterns, registration, and a minimal working example.

## Control Class Definition

### Header File Structure (`Source/Controls/*.h`)

The control class must:

- **Inherit from base class**: `GuiControl` (or another control) and `Description<YourControl>` for reflection
- **Specify template type**: Use `GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(TemplateName, BaseControlType)` macro
- **Declare state variables**: Member variables to track control state
- **Implement the generated template hooks in the `.cpp` file**:
  - `BeforeControlTemplateUninstalled_()` - cleanup before template removal
  - `AfterControlTemplateInstalled_(bool initialize)` - setup after template installation
  - Do not redeclare these underscore functions in the class: `GUI_SPECIFY_CONTROL_TEMPLATE_TYPE` declares them and generates the actual `BeforeControlTemplateUninstalled()` and `AfterControlTemplateInstalled(bool)` overrides
- **Override feature-specific virtual methods only when needed**, such as `OnParentLineChanged()`, `OnActiveAlt()`, or `IsTabAvailable()`
- **Attach event handlers**: In constructor to `boundsComposition->GetEventReceiver()` for mouse/keyboard events
- **Define public events**: Using `compositions::GuiNotifyEvent`
- **Define properties**: With getters/setters
- **Accept theme parameter**: Constructor takes `theme::ThemeName` parameter and passes to base class

**Example pattern from `GuiButton`:**

```cpp
class GuiButton : public GuiControl, public Description<GuiButton>
{
    GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(ButtonTemplate, GuiControl)
protected:
    ButtonState controlState;
    void OnMouseDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments);
    void UpdateControlState();
public:
    GuiButton(theme::ThemeName themeName);
    ~GuiButton();
    
    compositions::GuiNotifyEvent BeforeClicked;
    compositions::GuiNotifyEvent Clicked;
    compositions::GuiNotifyEvent AfterClicked;
    
    bool GetAutoFocus();
    void SetAutoFocus(bool value);
};
```

## Control Implementation

### Implementation File (`Source/Controls/*.cpp`)

Implement:

- **Constructor**: Initialize state, set up event handlers on `boundsComposition`
  - Pattern: `GuiYourControl(theme::ThemeName themeName) : GuiControl(themeName)`
  - Set up events: `eventName.SetAssociatedComposition(boundsComposition)`
  - Attach handlers: `boundsComposition->GetEventReceiver()->eventName.AttachMethod(this, &GuiYourControl::Handler)`
- **Destructor**: Cleanup (usually minimal, automatic cleanup happens)
- **Generated hook definition `BeforeControlTemplateUninstalled_()`**: Clear template-specific state; the definition may be empty
- **Generated hook definition `AfterControlTemplateInstalled_(bool initialize)`**: Sync state to template; the definition may be empty when no synchronization is needed
  - Call template methods: `TypedControlTemplateObject(true)->SetState(controlState)`
- **Event handlers**: Mouse events (`leftButtonDown`, `leftButtonUp`, `mouseEnter`, `mouseLeave`), keyboard events (`keyDown`, `keyUp`)
- **Property getters/setters**: Update state and notify template
- **Template access**: Use `TypedControlTemplateObject(true)` to get typed template with existence check, or `TypedControlTemplateObject(false)` without check

**Key patterns from `GuiButton`:**

- State machine pattern: `controlState` variable tracks visual state (Normal, Active, Pressed)
- Event chaining: `BeforeClicked` → `Clicked` → `AfterClicked`
- Mouse tracking: Separate flags for `mousePressingDirect`, `mousePressingIndirect`, `mouseHoving`
- Keyboard support: SPACE and ENTER keys trigger click
- Focus integration: `SetFocusableComposition(boundsComposition)` and `autoFocus` property
- Template communication: Call template setters in `AfterControlTemplateInstalled_`

## Control Template System

### Template Declaration (`Source/Controls/Templates/GuiControlTemplates.h`)

Three required entries:

**1. Add to `GUI_CONTROL_TEMPLATE_DECL` macro:**

```cpp
F(GuiYourTemplate, GuiBaseTemplate)
```

**2. Define template properties macro:**

```cpp
#define GuiYourTemplate_PROPERTIES(F)\
    F(GuiYourTemplate, PropertyType, PropertyName, DefaultValue)
```

Properties are defined using the `F` macro with: template class name, property type, property name, default value.

**3. Forward declaration and class declaration:**

The macros `GUI_TEMPLATE_CLASS_FORWARD_DECL` and `GUI_TEMPLATE_CLASS_DECL` are applied to `GUI_CONTROL_TEMPLATE_DECL` to generate these automatically.

### Template Implementation (`Source/Controls/Templates/GuiControlTemplates.cpp`)

The template implementation is auto-generated by:

```cpp
GUI_CONTROL_TEMPLATE_DECL(GUI_TEMPLATE_CLASS_IMPL)
```

This macro expands to create:
- Property getter/setter implementations with change events
- Constructor that initializes event handlers
- Destructor that calls `FinalizeAggregation()`

## Theme Integration

### Theme Name Registration (`Source/Application/Controls/GuiThemeManager.h`)

Add the control to `GUI_CONTROL_TEMPLATE_TYPES` macro:

```cpp
#define GUI_CONTROL_TEMPLATE_TYPES(F) \
    ... existing entries ...\
    F(YourTemplate, YourControl)
```

This generates the corresponding `theme::ThemeName::YourControl` enum value used in control constructors.

## Reflection Registration

### Three-Step Registration Process

**Step 1: Add to type list** (`Source/Reflection/TypeDescriptors/GuiReflectionPlugin.h`):

Add to `GUIREFLECTIONCONTROLS_CLASS_TYPELIST` macro:

```cpp
F(presentation::controls::GuiYourControl)
```

**Step 2: Register control class** (`Source/Reflection/TypeDescriptors/GuiReflectionControls.cpp`):

```cpp
BEGIN_CLASS_MEMBER(GuiYourControl)
    CLASS_MEMBER_BASE(GuiBaseControl)
    CONTROL_CONSTRUCTOR_CONTROLT_TEMPLATE(GuiYourControl)
    
    CLASS_MEMBER_GUIEVENT(EventName)
    CLASS_MEMBER_PROPERTY_FAST(PropertyName)
    CLASS_MEMBER_PROPERTY_GUIEVENT_FAST(PropertyWithEvent)
    CLASS_MEMBER_METHOD(MethodName, {L"param1" _ L"param2"})
END_CLASS_MEMBER(GuiYourControl)
```

**Step 3: Template registration** (`Source/Reflection/TypeDescriptors/GuiReflectionTemplates.cpp`):

Templates are auto-registered via the `GUI_CONTROL_TEMPLATE` macro expansion applied to all templates declared in `GUI_CONTROL_TEMPLATE_DECL`.

## XML Compiler Integration

### Instance Loader Registration (`Source/Compiler/InstanceLoaders/GuiInstanceLoader_Plugin.cpp`)

Add to loader registration in `IGuiPlugin::Load()`:

**For a normal control:**

```cpp
ADD_TEMPLATE_CONTROL(GuiYourControl, YourControl);
```

**For a virtual control** (uses another control's implementation with different theme):

```cpp
ADD_VIRTUAL_CONTROL(VirtualName, GuiActualControl, ThemeName);
```

This uses `GuiTemplateControlInstanceLoader<T>` to register the control with the instance loader manager, making it available in GacUI XML files.

## Header File Organization

### Include Files

Add includes to:
- `Source/Controls/IncludeForward.h` - forward declaration
- `Source/Controls/IncludeAll.h` - full header inclusion

This ensures proper compilation order and accessibility throughout the framework.

## Creating a Control that Inherits from Another Control

When creating a control that inherits from another control (e.g., `GuiSelectableButton` inherits from `GuiButton`):

### Class Definition Differences

- **Inherit from parent control**: `class GuiDerivedControl : public GuiParentControl, public Description<GuiDerivedControl>`
- **Specify parent in template macro**: `GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(DerivedTemplate, GuiParentControl)`
- **Do NOT re-attach parent event handlers**: Don't re-attach `leftButtonDown` if parent already handles it
- **Attach to parent's events instead**: Example - `GuiSelectableButton` attaches to `GuiButton::AfterClicked`

### Constructor Pattern

- **Call parent constructor**: `GuiDerivedControl(theme::ThemeName themeName) : GuiParentControl(themeName)`
- **Initialize additional events**: On `boundsComposition` (inherited from parent)
- **Attach handlers to parent's events**: If extending behavior

### Template Inheritance

- **Template inherits from parent template**: In `GuiControlTemplates.h`, add:
  ```cpp
  F(GuiDerivedTemplate, GuiParentTemplate)
  ```
- **Define additional properties**: Separate `GuiDerivedTemplate_PROPERTIES(F)` macro with new properties

### Reflection Registration

- **Use parent as base**: `CLASS_MEMBER_BASE(GuiParentControl)` instead of `CLASS_MEMBER_BASE(GuiControl)`
- **Still use standard constructor macro**: `CONTROL_CONSTRUCTOR_CONTROLT_TEMPLATE(GuiDerivedControl)`
- **Only register new members**: Properties/events/methods introduced by derived class

### Minimal Changes Approach

- **Define both generated hooks**: `GUI_SPECIFY_CONTROL_TEMPLATE_TYPE` declares `BeforeControlTemplateUninstalled_()` and `AfterControlTemplateInstalled_(bool)`, so provide definitions even when they are empty
- **Parent handles the actual lifecycle overrides**: The macro-generated overrides invoke the derived hook and chain to the parent control in the required order
- **Parent's event handlers inherited**: No need to re-implement
- **Focus on new functionality**: Don't repeat parent's work

### Example Pattern from `GuiSelectableButton`

- **Extends `GuiButton`** with selection state
- **Attaches to parent's `AfterClicked`** event to toggle selection
- **Adds new properties**: `GroupController`, `AutoSelection`, `Selected`
- **Adds new template property**: `Selected` in `SelectableButtonTemplate`
- **Template calls both**: `SetState()` (from parent) and `SetSelected()` (new)

## Template Property Access Pattern

Controls access template properties via:

- `TypedControlTemplateObject(true)` - gets the typed template with existence check
- `TypedControlTemplateObject(false)` - gets the typed template without check
- Template properties have auto-generated `Get/Set` methods and `Changed` events

## Control Template Macro System

The macro system provides:

- `GUI_TEMPLATE_CLASS_DECL`: Generates class declaration with properties
- `GUI_TEMPLATE_CLASS_IMPL`: Generates implementation (constructor, destructor, property accessors)
- `GUI_SPECIFY_CONTROL_TEMPLATE_TYPE`: Links a control to its template type, declares the two underscore hook functions, generates the lifecycle overrides, and provides typed template access
- Property macros: Generate private field, getter, setter, and change event

## Minimal Working Example

This example demonstrates the essential code structure for creating a custom control:

### Step 1: Header File (`Source/Controls/GuiMyControls.h`)

```cpp
class GuiMyControl : public GuiControl, public Description<GuiMyControl>
{
    GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(MyControlTemplate, GuiControl)
protected:
    // State variables
    bool myState = false;

    // Event handlers
    void OnMouseClick(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments);
    
public:
    GuiMyControl(theme::ThemeName themeName);
    ~GuiMyControl();
    
    // Events
    compositions::GuiNotifyEvent StateChanged;
    
    // Properties
    bool GetMyState();
    void SetMyState(bool value);
};
```

### Step 2: Implementation File (`Source/Controls/GuiMyControls.cpp`)

```cpp
void GuiMyControl::BeforeControlTemplateUninstalled_()
{
    // Cleanup before template removal
}

void GuiMyControl::AfterControlTemplateInstalled_(bool initialize)
{
    // Sync state to template
    TypedControlTemplateObject(true)->SetMyState(myState);
}

void GuiMyControl::OnMouseClick(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments)
{
    SetMyState(!myState);
}

GuiMyControl::GuiMyControl(theme::ThemeName themeName)
    : GuiControl(themeName)
{
    StateChanged.SetAssociatedComposition(boundsComposition);
    boundsComposition->GetEventReceiver()->leftButtonUp.AttachMethod(this, &GuiMyControl::OnMouseClick);
}

GuiMyControl::~GuiMyControl()
{
}

bool GuiMyControl::GetMyState()
{
    return myState;
}

void GuiMyControl::SetMyState(bool value)
{
    if (myState != value)
    {
        myState = value;
        TypedControlTemplateObject(false)->SetMyState(myState);
        StateChanged.Execute(compositions::GuiEventArgs(boundsComposition));
    }
}
```

### Step 3: Template Declaration (`Source/Controls/Templates/GuiControlTemplates.h`)

```cpp
// Add to GUI_CONTROL_TEMPLATE_DECL macro:
F(GuiMyControlTemplate, GuiControlTemplate)

// Define template properties:
#define GuiMyControlTemplate_PROPERTIES(F)\
    F(GuiMyControlTemplate, bool, MyState, false)
```

### Step 4: Theme Registration (`Source/Application/Controls/GuiThemeManager.h`)

```cpp
// Add to GUI_CONTROL_TEMPLATE_TYPES macro:
F(MyControlTemplate, MyControl)
```

### Step 5: Reflection (`Source/Reflection/TypeDescriptors/GuiReflectionControls.cpp`)

```cpp
BEGIN_CLASS_MEMBER(GuiMyControl)
    CLASS_MEMBER_BASE(GuiControl)
    CONTROL_CONSTRUCTOR_CONTROLT_TEMPLATE(GuiMyControl)
    
    CLASS_MEMBER_GUIEVENT(StateChanged)
    CLASS_MEMBER_PROPERTY_GUIEVENT_FAST(MyState)
END_CLASS_MEMBER(GuiMyControl)
```

### Step 6: XML Loader (`Source/Compiler/InstanceLoaders/GuiInstanceLoader_Plugin.cpp`)

```cpp
// Add in IGuiPlugin::Load():
ADD_TEMPLATE_CONTROL(GuiMyControl, MyControl);
```

### Core Pattern Summary

Each control has:

- **A C++ class** managing state and events
- **A template** defining visual properties
- **Reflection** for runtime access
- **XML loader** for declarative usage
- **Theme integration** for consistent styling
