DigiSlate: Interactive Whiteboard Application
A full-featured interactive whiteboard supporting 10+ shape types with color picker, undo/redo, select/drag, and save/load persistence, built in C++17 with Qt5/Qt6.
Overview
DigiSlate is a full-featured desktop interactive whiteboard application built with C++17 and Qt5/Qt6. It supports freehand drawing, 10+ geometric shape types, real-time color selection, adjustable pen width, shape grouping, undo/redo, and file persistence, all running at >60 FPS with 100+ simultaneously drawn elements.
The project demonstrates how to apply OOP, design patterns, and event-driven architecture in a real-time interactive GUI application.
Supported Shape Types
Freehand · Line · Circle · Ellipse · Arc · Polygon · Polyline · Rectangle · Point · Text
Key Technical Contributions
Polymorphic Shape Hierarchy (Open/Closed Principle)
Designed a polymorphic shape hierarchy with an abstract Shape base class and virtual dispatch. Adding a new shape type requires zero modifications to the rendering layer or event-handling code: only a new concrete class. This is the Open/Closed Principle applied in a practical, non-trivial context.
Shape Grouping & Undo/Redo System
Implemented a GroupShape class that treats multiple shapes as a single movable/resizable unit. The Undo/Redo system uses a Command-pattern-inspired stack, recording state diffs rather than full snapshots.
Dirty-Region Repaint Optimization
Optimized incremental repaint using dirty-region tracking: only the regions of the canvas that changed between frames are redrawn, rather than repainting the entire canvas. This maintains >60 FPS with 100+ elements on screen simultaneously.
Qt Signal-Slot for Decoupled State Transitions
Used Qt’s signal-slot mechanism to decouple tool state transitions (switching between draw, select, erase modes) from the rendering and model layers, keeping each layer’s responsibility clean.
MVC-Inspired Module Separation
Separated the application into three distinct modules:
model.cpp: shape state and business rulesmainwindow.cpp: UI and event handling- Rendering: pure drawing logic
What I Learned
- How to design extensible class hierarchies using the Open/Closed Principle in a real system
- The performance difference between full-canvas repaints vs. dirty-region tracking in interactive applications
- How Qt’s signal-slot mechanism enables decoupled, event-driven architecture in GUI applications
- How to manage complex application state (selection, grouping, undo history) cleanly
Stack
| Layer | Technology |
|---|---|
| Language | C++17 |
| GUI Framework | Qt5 / Qt6 |
| Build System | CMake |
| Design Patterns | Polymorphism, OCP, Command, MVC |
| Performance | Dirty-region repaint, >60 FPS |