Skip to content

Implement LVGL-backed WinForms control rendering with designer support#1

Merged
maikebing merged 3 commits intomasterfrom
copilot/implement-winform-controls-lvgl
Mar 14, 2026
Merged

Implement LVGL-backed WinForms control rendering with designer support#1
maikebing merged 3 commits intomasterfrom
copilot/implement-winform-controls-lvgl

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 14, 2026

Connects the existing WinForms-compatible stub controls to actual LVGL widgets so the control tree renders correctly at runtime. All controls are usable in the Visual Studio WinForms designer and render via LVGL on Linux/embedded targets.

Core architecture

  • Control base class — adds CreateLvglObject(nint parent) (virtual), ApplyLvglProperties(), CreateChildrenLvglObjects(), and helpers ToUtf8 / LvPct
  • Form.Init() — after LVGL display init, sets _lvglObjectHandle = root and calls CreateChildrenLvglObjects() to instantiate the full control tree; removes hardcoded flex-column root layout; raises Load event
// Controls are added in InitializeComponent() as before; Init() wires them to LVGL
form.Init();
form.StartLoop(() => { /* tick */ });

LVGL widget mapping

Control LVGL widget
Button lv_button_create + inner lv_label_create
Label lv_label_create
TextBox lv_textarea_create (one-line / multiline, placeholder)
CheckBox lv_checkbox_create (checked state)
ComboBox lv_dropdown_create
FlowLayoutPanel lv_obj_create + LV_FLEX_FLOW_ROW_WRAP
TableLayoutPanel lv_obj_create container
RadioButton (new) lv_checkbox_create
ProgressBar (new) lv_bar_create
TrackBar (new) lv_slider_create + orientation
ListBox (new) lv_list_create
Panel (new) transparent lv_obj_create
GroupBox (new) lv_obj_create + title label
PictureBox (new) lv_image_create
NumericUpDown (new) lv_spinbox_create
RichTextBox (new) lv_textarea_create

Bug fixes

  • TableLayoutPanel was in the global namespace; moved into LVGLSharp.Forms
  • RowStyles was typed as a single RowStyle (with a throwing Add()); changed to List<RowStyle>; ColumnStyles now auto-initialized
  • RowStyle now extends TableLayoutStyle and drops the redundant private field
  • Form.Load made nullable

Enums

ContentAlignment, AnchorStyles ([Flags]), DockStyle, and several others expanded to full WinForms value sets. New enums: BorderStyle, HorizontalAlignment, Orientation, TickStyle, DrawMode, SelectionMode, PictureBoxSizeMode, FormWindowState, FormBorderStyle, FormStartPosition, ScrollBars.

Project file

All control classes registered with <SubType>Component</SubType> for designer toolbox visibility.


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copilot AI and others added 2 commits March 14, 2026 16:02
Co-authored-by: maikebing <3445167+maikebing@users.noreply.github.com>
…, fix size check, fix enum ordering, apply TrackBar orientation

Co-authored-by: maikebing <3445167+maikebing@users.noreply.github.com>
Copilot AI changed the title [WIP] Add WinForm controls implementation using lvgl Implement LVGL-backed WinForms control rendering with designer support Mar 14, 2026
Copilot AI requested a review from maikebing March 14, 2026 16:09
@maikebing maikebing marked this pull request as ready for review March 14, 2026 17:11
Copilot AI review requested due to automatic review settings March 14, 2026 17:11
@maikebing maikebing merged commit 5babad6 into master Mar 14, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR wires the WinForms-compatible LVGLSharp.Forms control tree to actual LVGL widgets so controls created via InitializeComponent() can be instantiated and rendered at runtime (and be usable in the VS designer metadata-wise).

Changes:

  • Adds LVGL object creation + basic property application to Control, and initializes the full control tree from Form.Init().
  • Implements LVGL-backed widget creation for a set of common controls (and adds several new control stubs).
  • Expands/introduces WinForms-like enums and updates the project file to improve designer/toolbox support.

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/LVGLSharp.WinForms/enums.cs Expands WinForms-like enums (alignment, docking/anchoring, etc.).
src/LVGLSharp.WinForms/LVGLSharp.Forms.csproj Marks controls as SubType=Component for designer/toolbox visibility.
src/LVGLSharp.WinForms/Forms/Control.cs Introduces LVGL object creation + layout/visibility application + recursive child creation.
src/LVGLSharp.WinForms/Forms/Form.cs Initializes root LVGL handle and builds child control LVGL objects; raises Load.
src/LVGLSharp.WinForms/Forms/Button.cs Maps Button to lv_button_create + inner label.
src/LVGLSharp.WinForms/Forms/CheckBox.cs Maps CheckBox to lv_checkbox_create with checked state.
src/LVGLSharp.WinForms/Forms/ComboBox.cs Maps ComboBox to lv_dropdown_create.
src/LVGLSharp.WinForms/Forms/FlowLayoutPanel.cs Maps FlowLayoutPanel to an LVGL flex container (ROW_WRAP).
src/LVGLSharp.WinForms/Forms/GroupBox.cs Adds GroupBox backed by container + title label.
src/LVGLSharp.WinForms/Forms/Label.cs Maps Label to lv_label_create.
src/LVGLSharp.WinForms/Forms/ListBox.cs Adds ListBox backed by lv_list_create.
src/LVGLSharp.WinForms/Forms/NumericUpDown.cs Adds NumericUpDown backed by lv_spinbox_create.
src/LVGLSharp.WinForms/Forms/Panel.cs Adds Panel as a transparent LVGL container.
src/LVGLSharp.WinForms/Forms/PictureBox.cs Adds PictureBox backed by lv_image_create.
src/LVGLSharp.WinForms/Forms/ProgressBar.cs Adds ProgressBar backed by lv_bar_create.
src/LVGLSharp.WinForms/Forms/RadioButton.cs Adds RadioButton simulated via lv_checkbox_create.
src/LVGLSharp.WinForms/Forms/RichTextBox.cs Adds RichTextBox backed by lv_textarea_create.
src/LVGLSharp.WinForms/Forms/RowStyle.cs Refactors RowStyle to inherit TableLayoutStyle.
src/LVGLSharp.WinForms/Forms/TableLayoutPanel.cs Moves into LVGLSharp.Forms, fixes styles collection types, maps to LVGL container.
src/LVGLSharp.WinForms/Forms/TextBox.cs Maps TextBox to lv_textarea_create with one-line/multiline + placeholder.
src/LVGLSharp.WinForms/Forms/TrackBar.cs Adds TrackBar backed by lv_slider_create + orientation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +3626 to +3627
if (!Visible)
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
Comment on lines +52 to +55
Font,
Dpi,
Inherit,
None
public bool FormattingEnabled { get; set; }
public int DropDownHeight { get; set; }
public object FlatStyle { get; set; }
public object? FlatStyle { get; set; }
Comment on lines +41 to +57
public Orientation Orientation { get; set; } = Orientation.Horizontal;

private unsafe void UpdateLvglValue()
{
if (_lvglObjectHandle == 0) return;
var obj = (lv_obj_t*)_lvglObjectHandle;
lv_bar_set_range(obj, _minimum, _maximum);
lv_bar_set_value(obj, _value, LV_ANIM_OFF);
}

internal override unsafe void CreateLvglObject(nint parentHandle)
{
_lvglObjectHandle = (nint)lv_bar_create((lv_obj_t*)parentHandle);
var obj = (lv_obj_t*)_lvglObjectHandle;
lv_bar_set_range(obj, _minimum, _maximum);
lv_bar_set_value(obj, _value, LV_ANIM_OFF);
ApplyLvglProperties();
}
}

public Orientation Orientation { get; set; } = Orientation.Horizontal;
Comment on lines +12 to +17
// Stores the column/row position for each child added via Add(control, col, row)
private readonly Dictionary<Control, (int col, int row)> _cellPositions = new();

public void SetColumnSpan(FlowLayoutPanel recv_container, int v)
{
public void SetColumnSpan(Control control, int span)
{
}
Comment on lines +3599 to +3602
var parent = (Interop.lv_obj_t*)parentHandle;
_lvglObjectHandle = (nint)lv_obj_create(parent);
// Remove default padding so child positioning is exact
lv_obj_set_style_pad_all((Interop.lv_obj_t*)_lvglObjectHandle, 0, 0);
Comment on lines +3619 to +3621
// Use explicit size when set (non-negative); fall back to LV_SIZE_CONTENT.
int w = Size.Width >= 0 ? Size.Width : LV_SIZE_CONTENT;
int h = Size.Height >= 0 ? Size.Height : LV_SIZE_CONTENT;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants