diff --git a/docs/plans/qt-frontend.md b/docs/plans/qt-frontend.md new file mode 100644 index 0000000..f076fc5 --- /dev/null +++ b/docs/plans/qt-frontend.md @@ -0,0 +1,116 @@ +Based on the project structure and the presence of files like +`imgui.ini`, `GUIFrontend.h`, and `TerminalFrontend.h`, here is an +analysis of the difficulty and challenges involved in adding a GTK or Qt +version of the GUI. + +### **Executive Summary: Difficulty Level - Moderate** + +The project is well-architected for this task. It already supports +multiple frontends (Terminal vs. GUI), meaning the "Core Logic" ( +Buffers, Syntax, Commands) is successfully decoupled from the "View" ( +Rendering/Input). However, the specific move from an **Immediate Mode** +GUI (likely Dear ImGui, implied by `imgui.ini` and standard naming +patterns) to a **Retained Mode** GUI (Qt/GTK) introduces specific +architectural frictions regarding the event loop and state management. + +--- + +### **1. Architectural Analysis** + +The existence of abstract interfaces—likely `Frontend`, `Renderer`, and +`InputHandler`—is the biggest asset here. + +* **Current State:** + * **Abstract Layer:** `Frontend.h`, `Renderer.h`, `InputHandler.h` + likely define the contract. + * **Implementations:** + * `Terminal*` files implement the TUI (likely ncurses or VT100). + * `GUI*` files (currently ImGui) implement the graphical + version. +* **The Path Forward:** + * You would create `QtFrontend`, `QtRenderer`, `QtInputHandler` (or + GTK equivalents). + * Because the core logic (`Editor.cc`, `Buffer.cc`) calls these + interfaces, you theoretically don't need to touch the core text + manipulation code. + +### **2. Key Challenges** + +#### **A. The Event Loop Inversion (Main Challenge)** + +* **Current (ImGui):** Typically, the application owns the loop: + `while (running) { HandleInput(); Update(); Render(); }`. The + application explicitly tells the GUI to draw every frame. +* **Target (Qt/GTK):** The framework owns the loop: `app.exec()` or + `gtk_main()`. The framework calls *you* when events happen. +* **Difficulty:** You will need to refactor `main.cc` or the entry point + to hand over control to the Qt/GTK application object. The Editor's " + tick" function might need to be connected to a timer or an idle event + in the new framework to ensure logic updates happen. + +#### **B. Rendering Paradigm: Canvas vs. Widgets** + +* **The "Easy" Way (Custom Canvas):** + * Implement the `QtRenderer` by subclassing `QWidget` and overriding + `paintEvent`. + * Use `QPainter` (or Cairo in GTK) to draw text, cursors, and + selections exactly where the `Renderer` interface says to. + * **Pros:** Keeps the code similar to the current ImGui/Terminal + renderers. + * **Cons:** You lose native accessibility and some native "feel" ( + scrolling physics, native text context menus). +* **The "Hard" Way (Native Widgets):** + * Trying to map an internal `Buffer` directly to a `QTextEdit` or + `GtkTextView`. + * **Difficulty:** This is usually very hard because the Editor core + likely manages its own cursor, selection, and syntax highlighting. + Syncing that internal state with a complex native widget often + leads to conflicts. + * **Recommendation:** Stick to the "Custom Canvas" approach (drawing + text manually on a surface) to preserve the custom editor + behavior (vim-like modes, specific syntax highlighting). + +#### **C. Input Handling** + +* **Challenge:** Mapping Qt/GTK key events to the internal `Keymap`. +* **Detail:** ImGui and Terminal libraries often provide raw scancodes + or simple chars. Qt/GTK provide complex Event objects. You will need a + translation layer in `QtInputHandler::keyPressEvent` that converts + `Qt::Key_Escape` -> `KKey::Escape` (or your internal equivalent). + +### **3. Portability of Assets** + +#### **Themes (Colors)** + +* **Feasibility:** High. +* **Approach:** `GUITheme.h` likely contains structs with RGB/Hex + values. Qt supports stylesheets (QSS) and GTK uses CSS. You can write + a converter that reads your current theme configuration and generates + a CSS string to apply to your window, or simply use the RGB values + directly in your custom `QPainter`/Cairo drawing logic. + +#### **Fonts** + +* **Feasibility:** Moderate. +* **Approach:** + * **ImGui:** Usually loads a TTF into a texture atlas. + * **Qt/GTK:** Uses the system font engine (Freetype/Pango). + * **Challenge:** You won't use the texture atlas anymore. You will + simply request a font family and size (e.g., + `QFont("JetBrains Mono", 12)`). You may need to ensure your custom + renderer calculates character width/height metrics correctly using + `QFontMetrics` (Qt) or `PangoLayout` (GTK) to align the grid + correctly. + +### **4. Summary Recommendation** + +If you proceed, **Qt** is generally considered easier to integrate with +C++ projects than GTK (which is C-based, though `gtkmm` exists). + +1. **Create a `QtFrontend`** class inheriting from `Frontend`. +2. **Create a `QtWindow`** class inheriting from `QWidget`. +3. **Implement `QtRenderer`** that holds a pointer to the `QtWindow`. + When the core calls `DrawText()`, `QtRenderer` should queue that + command or draw directly to the widget's paint buffer. +4. **Refactor `main.cc`** to instantiate `QApplication` instead of the + current manual loop. \ No newline at end of file