Two-Way Tools: Designer ↔ Code Sync

HarbourBuilder's Two-Way Tools engine ensures that your visual form design and your source code are always perfectly synchronized. Every change you make in the visual Form Designer is immediately reflected in the generated code, and every structural change you make to the code is instantly visible in the designer.

Your Logic Is Safe

The code regeneration engine only updates UI definition lines (DEFINE, @ POSITION, properties). Your METHOD implementations, event handlers, and custom logic are never touched or overwritten.

How It Works

When you work in the Form Designer, every action — dropping a control, resizing, moving, changing a property — triggers a targeted code regeneration. The engine parses your existing source file, identifies the UI definition sections, updates them, and leaves everything else intact.

sequenceDiagram participant D as Form Designer participant E as Code Engine participant F as Source File participant P as Parser D->>E: Control dropped on form E->>P: Parse existing file P->>P: Find UI definition blocks P->>P: Preserve METHOD bodies E->>F: Regenerate UI lines only E->>D: Refresh designer view Note over D,F: METHOD implementations are never modified

What Gets Regenerated

The code engine identifies and updates only these categories:

CategoryExampleRegenerated?
DEFINE statementsDEFINE FORM, DEFINE BUTTONYes
@ POSITION lines@ 10, 20 BUTTON ...Yes
Property assignments::cTitle := "Hello"Yes
CLASS definitionsCLASS TForm1 FROM TFormYes
Control creation via codeTButton():New()Yes
METHOD implementationsMETHOD OnClick() CLASS TForm1No
Event handler bodiesbAction := { || ... }No
Custom functionsstatic function MyHelper()No
Comments// TODO: ...No

Before and After: Code Regeneration

Before: You drop a button in the designer

CLASS TForm1 FROM TForm

   DATA oBtn1

   METHOD CreateForm()
   METHOD OnBtnClick()

ENDCLASS

METHOD CreateForm() CLASS TForm1
   ::cTitle  := "Form1"
   ::nWidth  := 400
   ::nHeight := 300
return nil

METHOD OnBtnClick() CLASS TForm1
   // Your custom logic - PRESERVED
   MsgInfo( "Button clicked!" )
return nil

After: Code regenerated (button added, method untouched)

CLASS TForm1 FROM TForm

   DATA oBtn1

   METHOD CreateForm()
   METHOD OnBtnClick()

ENDCLASS

METHOD CreateForm() CLASS TForm1
   ::cTitle  := "Form1"
   ::nWidth  := 400
   ::nHeight := 300

   // --- NEW: Button added by designer ---
   @ 120, 140 BUTTON ::oBtn1 PROMPT "Button1" ;
      OF Self SIZE 120, 32 ;
      ACTION ::OnBtnClick()
return nil

METHOD OnBtnClick() CLASS TForm1
   // Your custom logic - PRESERVED
   MsgInfo( "Button clicked!" )
return nil
Notice the preservation

The OnBtnClick method body is completely unchanged. Only the CreateForm method received the new button definition.

Workflow

graph TD A["Start with blank form"] --> B["Drop controls from palette"] B --> C["Set properties in Object Inspector"] C --> D["Code auto-generated"] D --> E{"Need custom logic?"} E -->|"Yes"| F["Switch to Code View"] E -->|"No"| G["Build and run"] F --> H["Write METHOD implementations"] H --> I["Switch back to Designer"] I --> J["Continue visual design"] J --> B G --> K["Done"] style A fill:#d2a8ff,stroke:#bc8cff,color:#0d1117 style F fill:#58a6ff,stroke:#388bfd,color:#0d1117 style H fill:#3fb950,stroke:#2ea043,color:#0d1117 style K fill:#3fb950,stroke:#2ea043,color:#0d1117

Code Parsing Rules

The regeneration engine uses these rules to identify safe-to-modify sections:

  1. CLASS / ENDCCLASS blocks — DATA and METHOD declarations are updated; existing METHOD bodies are skipped.
  2. DEFINE FORM blocks — Properties within DEFINE blocks are regenerated.
  3. @ POSITION statements — Position, size, and property clauses are updated.
  4. ACTIVATE FORM blocks — Activation clauses are regenerated.
  5. Everything else — Static functions, METHOD bodies, comments, and custom code are left untouched.
Best Practice

Keep your custom logic in separate METHOD implementations or static functions rather than inline within DEFINE blocks. This makes it easier for the regeneration engine to identify and preserve your code.

Handling Conflicts

If you manually edit a line that the designer also manages (e.g., changing a button's position in code while it's also on the form canvas), the designer's view takes precedence on the next regeneration. To avoid conflicts:

Two-Way Is Reliable

The regeneration engine has been tested with over 200 edge cases including nested DEFINE blocks, multiple forms in one file, mixed class-based and procedural syntax, and files with extensive comments.

Switching Between Views

Use the toolbar toggle or keyboard shortcut to switch between Designer and Code views:

ShortcutAction
F12Toggle between Designer and Code views
Ctrl+TabCycle through open editor tabs
Ctrl+SSave (both design data and code)

On This Page

Getting Started Component Palette IDE Features Tutorials Reference Platforms How It Works What Gets Regenerated Before and After: Code Regeneration Before: You drop a button in the designer After: Code regenerated (button added, method untouched) Workflow Code Parsing Rules Handling Conflicts Switching Between Views