ktsu.ImGui.Widgets
3.8.1
Prefix Reserved
dotnet add package ktsu.ImGui.Widgets --version 3.8.1
NuGet\Install-Package ktsu.ImGui.Widgets -Version 3.8.1
<PackageReference Include="ktsu.ImGui.Widgets" Version="3.8.1" />
<PackageVersion Include="ktsu.ImGui.Widgets" Version="3.8.1" />
<PackageReference Include="ktsu.ImGui.Widgets" />
paket add ktsu.ImGui.Widgets --version 3.8.1
#r "nuget: ktsu.ImGui.Widgets, 3.8.1"
#:package ktsu.ImGui.Widgets@3.8.1
#addin nuget:?package=ktsu.ImGui.Widgets&version=3.8.1
#tool nuget:?package=ktsu.ImGui.Widgets&version=3.8.1
ktsu.ImGui.Widgets
ImGuiWidgets is a library of custom widgets using ImGui.NET. This library provides a variety of widgets and utilities to enhance your ImGui-based applications.
Features
- Knobs: Ported to .NET from ImGui-works/ImGui-knobs-dial-gauge-meter
- Radial Progress Bar: Circular progress indicators for visualizing loading and progress with countdown/count-up timers
- Resizable Layout Dividers: Draggable layout dividers for resizable layouts (DividerContainer)
- TabPanel: Tabbed interface with closable, reorderable tabs and dirty indicator support
- Combo: Type-safe combo boxes for enums, strings, and strong strings
- Icons: Customizable icons with various alignment options and event delegates
- Grid: Flexible grid layout for displaying items
- Color Indicator: An indicator that displays a color when enabled
- Image: An image widget with alignment options
- Text: A text widget with alignment options
- Tree: A tree widget for displaying hierarchical data
- Scoped Id: A utility class for creating scoped IDs
- Scoped Disable: Temporarily disable UI elements within a scope
- SearchBox: A powerful search box with support for various filter types (Glob, Regex, Fuzzy) and matching options
- Hexa-backed widgets: Thin adapters over
Hexa.NET.ImGui.Widgets— spinners, buffering bars, splitters, toggle/transparent/inline buttons, an icon tree node, an enum combo, text/image alignment helpers, tooltips, breadcrumbs, a date/year picker, a flame graph, a file tree view, stateful file/rename/message dialogs, and a docked-window base class. See Hexa-backed Widgets below. - Callback-driven editors:
Sequencer(an editable clip timeline),CurveEditor(a multi-curve graph, or a singleCurveDatacurve), andBezierEditor(a cubic easing curve) — driven by aSequenceSource/CurveSourceyou subclass, or by aCurveData/BezierControlPointsvalue. See Callback-driven Editors below.
Installation
To install ImGuiWidgets, you can add the library to your .NET project using the following command:
dotnet add package ktsu.ImGui.Widgets
Usage
To use ImGuiWidgets, you need to include the ktsu.ImGui.Widgets namespace in your code:
using ktsu.ImGui.Widgets;
Then, you can start using the widgets provided by ImGuiWidgets in your ImGui-based applications.
Examples
Here are some examples of using ImGuiWidgets:
Knobs
Knobs are useful for creating dial-like controls:
float value = 0.5f;
float minValue = 0.0f;
float maxValue = 1.0f;
ImGuiWidgets.Knob("Knob", ref value, minValue, maxValue);
Radial Progress Bar
The RadialProgressBar widget displays circular progress indicators perfect for loading states, progress tracking, countdowns, and timers:
float progress = 0.65f; // Progress from 0.0 to 1.0
// Basic usage - displays with default size and settings (clockwise from top, percentage text)
ImGuiWidgets.RadialProgressBar(progress);
// Custom size (radius in pixels)
ImGuiWidgets.RadialProgressBar(progress, radius: 50);
// Custom thickness
ImGuiWidgets.RadialProgressBar(progress, radius: 50, thickness: 10);
// Without text in center
ImGuiWidgets.RadialProgressBar(progress, 50, 0, 32, ImGuiRadialProgressBarOptions.NoText);
// Counter-clockwise direction (default is clockwise)
ImGuiWidgets.RadialProgressBar(progress, 50, 0, 32, ImGuiRadialProgressBarOptions.CounterClockwise);
// Start at bottom instead of top
ImGuiWidgets.RadialProgressBar(progress, 50, 0, 32, ImGuiRadialProgressBarOptions.StartAtBottom);
// Combine options: counter-clockwise starting at bottom
ImGuiWidgets.RadialProgressBar(progress, 50, 0, 32,
ImGuiRadialProgressBarOptions.CounterClockwise | ImGuiRadialProgressBarOptions.StartAtBottom);
// Animated progress example
float animatedProgress = 0.0f;
void UpdateProgress(float deltaTime)
{
animatedProgress += deltaTime * 0.2f;
if (animatedProgress > 1.0f) animatedProgress = 0.0f;
ImGuiWidgets.RadialProgressBar(animatedProgress);
}
Text Display Modes
The RadialProgressBar supports three text display modes:
// Percentage mode (default) - displays "65%"
ImGuiWidgets.RadialProgressBar(0.65f);
// Time mode - displays time in MM:SS or HH:MM:SS format
ImGuiWidgets.RadialProgressBar(
progress: 0.5f,
textMode: ImGuiRadialProgressBarTextMode.Time,
timeValue: 150.0f // Displays "02:30"
);
// Time mode with hours - displays "01:05:30"
ImGuiWidgets.RadialProgressBar(
progress: 0.7f,
textMode: ImGuiRadialProgressBarTextMode.Time,
timeValue: 3930.0f // 1 hour, 5 minutes, 30 seconds
);
// Custom text mode - displays any string you provide
ImGuiWidgets.RadialProgressBar(
progress: 0.3f,
textMode: ImGuiRadialProgressBarTextMode.Custom,
customText: "Loading..."
);
Countdown Timer
Use RadialCountdown for countdown timers showing time remaining:
float countdownTime = 300.0f; // 5 minutes in seconds
const float CountdownTotal = 300.0f;
bool isRunning = false;
// Update countdown
if (isRunning && countdownTime > 0.0f)
{
countdownTime -= deltaTime;
if (countdownTime < 0.0f)
{
countdownTime = 0.0f;
isRunning = false;
}
}
// Display countdown - shows time remaining (e.g., "05:00", "04:30", etc.)
ImGuiWidgets.RadialCountdown(countdownTime, CountdownTotal);
// With custom options
ImGuiWidgets.RadialCountdown(
countdownTime,
CountdownTotal,
radius: 60,
thickness: 12,
segments: 64,
options: ImGuiRadialProgressBarOptions.CounterClockwise
);
// Reset button
if (ImGui.Button("Reset"))
{
countdownTime = CountdownTotal;
isRunning = false;
}
Count-Up Timer
Use RadialCountUp for timers showing elapsed time:
float elapsedTime = 0.0f;
const float TotalTime = 180.0f; // 3 minutes
bool isRunning = false;
// Update timer
if (isRunning && elapsedTime < TotalTime)
{
elapsedTime += deltaTime;
if (elapsedTime > TotalTime)
{
elapsedTime = TotalTime;
isRunning = false;
}
}
// Display count-up timer - shows elapsed time (e.g., "00:00", "00:15", etc.)
ImGuiWidgets.RadialCountUp(elapsedTime, TotalTime);
// With custom size and options
ImGuiWidgets.RadialCountUp(
elapsedTime,
TotalTime,
radius: 70,
options: ImGuiRadialProgressBarOptions.StartAtBottom
);
// Start/stop controls
if (ImGui.Button(isRunning ? "Stop" : "Start"))
{
isRunning = !isRunning;
}
if (ImGui.Button("Reset"))
{
elapsedTime = 0.0f;
isRunning = false;
}
Advanced Timer Examples
// Pomodoro timer (25 minutes work, 5 minutes break)
const float WorkDuration = 1500.0f; // 25 minutes
const float BreakDuration = 300.0f; // 5 minutes
float currentTime = WorkDuration;
bool isWorkSession = true;
if (isWorkSession)
{
ImGuiWidgets.RadialCountdown(currentTime, WorkDuration, radius: 80);
}
else
{
ImGuiWidgets.RadialCountdown(currentTime, BreakDuration, radius: 80);
}
// Stopwatch with custom display
float stopwatchTime = 0.0f;
ImGuiWidgets.RadialProgressBar(
progress: 0.0f, // No progress bar fill
radius: 60,
textMode: ImGuiRadialProgressBarTextMode.Time,
timeValue: stopwatchTime,
options: ImGuiRadialProgressBarOptions.NoText // Hide text if desired
);
ImGui.Text($"Elapsed: {stopwatchTime:F2}s");
// Combined progress and time display
float taskProgress = 0.35f;
float taskTimeRemaining = 120.0f; // 2 minutes remaining
ImGui.Columns(2);
ImGuiWidgets.RadialProgressBar(taskProgress);
ImGui.TextUnformatted("Progress");
ImGui.NextColumn();
ImGuiWidgets.RadialProgressBar(
taskProgress,
textMode: ImGuiRadialProgressBarTextMode.Time,
timeValue: taskTimeRemaining
);
ImGui.TextUnformatted("Time Remaining");
ImGui.Columns(1);
SearchBox
The SearchBox widget provides a powerful search interface with multiple filter type options:
// Static fields to maintain filter state between renders.
// The options record carries the label, filter type, match options,
// and hint/tooltip/context-menu toggles. Right-click updates it in place.
private static string searchTerm = string.Empty;
private static SearchBoxOptions searchOptions = new(Label: "##BasicSearch", FilterType: TextFilterType.Glob);
private static SearchBoxRankedOptions rankedOptions = new(Label: "##RankedSearch");
// List of items to search
var items = new List<string> { "Apple", "Banana", "Cherry", "Date", "Elderberry" };
// Basic search box with right-click context menu for filter options
ImGuiWidgets.SearchBox(ref searchOptions, ref searchTerm);
// Display results
if (!string.IsNullOrEmpty(searchTerm))
{
ImGui.TextUnformatted($"Search results for: {searchTerm}");
}
// Search box that returns filtered results directly
var filteredResults = ImGuiWidgets.SearchBox(
ref searchOptions,
ref searchTerm,
items, // Collection to filter
item => item).ToList(); // Selector function to extract string from each item
// Ranked search box for fuzzy matching and ranked results
var rankedResults = ImGuiWidgets.SearchBoxRanked(
ref rankedOptions,
ref searchTerm,
items,
item => item).ToList();
TabPanel
TabPanel creates a tabbed interface with support for closable tabs, reordering, and dirty state indication:
// Create a tab panel with closable and reorderable tabs
var tabPanel = new ImGuiWidgets.TabPanel("MyTabPanel", true, true);
// Add tabs with explicit IDs (recommended for stability when tabs are reordered)
string tab1Id = tabPanel.AddTab("tab1", "First Tab", RenderTab1Content);
string tab2Id = tabPanel.AddTab("tab2", "Second Tab", RenderTab2Content);
string tab3Id = tabPanel.AddTab("tab3", "Third Tab", RenderTab3Content);
// Draw the tab panel in your render loop
tabPanel.Draw();
// Methods to render tab content
void RenderTab1Content()
{
ImGui.Text("Tab 1 Content");
// Mark tab as dirty when content changes
if (ImGui.Button("Edit"))
{
tabPanel.MarkTabDirty(tab1Id);
}
// Mark tab as clean when content is saved
if (ImGui.Button("Save"))
{
tabPanel.MarkTabClean(tab1Id);
}
}
void RenderTab2Content()
{
ImGui.Text("Tab 2 Content");
}
void RenderTab3Content()
{
ImGui.Text("Tab 3 Content");
}
Icons
Icons can be used to display images with various alignment options and event delegates:
float iconWidthEms = 7.5f;
float iconWidthPx = ImGuiApp.EmsToPx(iconWidthEms);
// GetOrLoadTexture returns an ImGuiAppTextureInfo; use its TextureId
ImGuiAppTextureInfo texture = ImGuiApp.GetOrLoadTexture("icon.png");
ImGuiWidgets.Icon("Click Me", texture.TextureId, iconWidthPx, ImGuiWidgets.IconAlignment.Vertical, new ImGuiWidgets.IconOptions()
{
OnClick = () => Console.WriteLine("You clicked")
});
ImGui.SameLine();
ImGuiWidgets.Icon("Double Click Me", texture.TextureId, iconWidthPx, ImGuiWidgets.IconAlignment.Vertical, new ImGuiWidgets.IconOptions()
{
OnDoubleClick = () => Console.WriteLine("You clicked twice")
});
ImGui.SameLine();
ImGuiWidgets.Icon("Right Click Me", texture.TextureId, iconWidthPx, ImGuiWidgets.IconAlignment.Vertical, new ImGuiWidgets.IconOptions()
{
OnContextMenu = () =>
{
ImGui.MenuItem("Context Menu Item 1");
ImGui.MenuItem("Context Menu Item 2");
ImGui.MenuItem("Context Menu Item 3");
},
});
Grid
The grid layout allows you to display items in a flexible grid:
float iconSizeEms = 7.5f;
float iconSizePx = ImGuiApp.EmsToPx(iconSizeEms);
ImGuiAppTextureInfo texture = ImGuiApp.GetOrLoadTexture("icon.png");
// RowMajorGrid (or ColumnMajorGrid) takes an id, the items, a measure delegate, and a draw delegate
ImGuiWidgets.RowMajorGrid(
"MyGrid",
items,
item => ImGuiWidgets.CalcIconSize(item, iconSizePx, ImGuiWidgets.IconAlignment.Vertical),
(item, cellSize, itemSize) =>
{
ImGuiWidgets.Icon(item, texture.TextureId, iconSizePx, ImGuiWidgets.IconAlignment.Vertical);
});
Color Indicator
The color indicator widget displays a color when enabled:
// color is a Hexa.NET.ImGui.ImColor (for example, from ktsu.ImGui.Styler's Color helpers)
ImColor color = Color.FromHex("#ff0000");
bool enabled = true;
ImGuiWidgets.ColorIndicator(color, enabled);
Image
The image widget allows you to display images with alignment options:
ImGuiAppTextureInfo texture = ImGuiApp.GetOrLoadTexture("image.png");
ImGuiWidgets.Image(texture.TextureId, new Vector2(100, 100));
Text
The text widget allows you to display text with alignment options:
ImGuiWidgets.Text("Hello, ImGuiWidgets!");
ImGuiWidgets.TextCentered("Hello, ImGuiWidgets!");
ImGuiWidgets.TextCenteredWithin("Hello, ImGuiWidgets!", new Vector2(100, 100));
Tree
The tree widget allows you to display hierarchical data:
using (var tree = new ImGuiWidgets.Tree())
{
for (int i = 0; i < 5; i++)
{
using (tree.Child)
{
ImGui.Button($"Hello, Child {i}!");
using (var subtree = new ImGuiWidgets.Tree())
{
using (subtree.Child)
{
ImGui.Button($"Hello, Grandchild!");
}
}
}
}
}
Scoped Id
The scoped ID utility class helps in creating scoped IDs for ImGui elements and ensuring they get popped appropriately:
using (new ImGuiWidgets.ScopedId())
{
ImGui.Button("Hello, Scoped ID!");
}
Scoped Disable
Temporarily disable UI elements within a scope. Disabled elements are visually grayed out and non-interactive:
bool shouldDisable = true;
// Disable buttons within this scope
using (new ScopedDisable(shouldDisable))
{
ImGui.Button("I'm disabled!");
ImGui.InputText("Disabled Input", ref someText, 256);
}
// Elements outside the scope are enabled normally
ImGui.Button("I'm enabled!");
// Nested disables work as expected (per Dear ImGui rules)
using (new ScopedDisable(false))
{
ImGui.Text("Enabled section");
using (new ScopedDisable(true))
{
ImGui.Button("Disabled button");
}
}
Note: As per Dear ImGui documentation, nested BeginDisabled calls cannot re-enable an already disabled section - a single BeginDisabled(true) in the stack is enough to keep everything disabled.
Combo
Type-safe combo box widgets for enums, strings, and strong strings:
// Enum combo box
enum Season { Spring, Summer, Fall, Winter }
Season selectedSeason = Season.Summer;
if (ImGuiWidgets.Combo("Season", ref selectedSeason))
{
Console.WriteLine($"Selected: {selectedSeason}");
}
// String combo box
string selectedFruit = "Apple";
var fruits = new Collection<string> { "Apple", "Banana", "Cherry", "Date" };
if (ImGuiWidgets.Combo("Fruit", ref selectedFruit, fruits))
{
Console.WriteLine($"Selected: {selectedFruit}");
}
// Strong string combo box (using ktsu.Semantics.Strings)
using ktsu.Semantics.Strings;
MyStrongString selected = new("Value1");
var options = new Collection<MyStrongString>
{
new("Value1"),
new("Value2"),
new("Value3")
};
if (ImGuiWidgets.Combo("Option", ref selected, options))
{
Console.WriteLine($"Selected: {selected}");
}
DividerContainer
Create resizable layouts with draggable dividers between content regions:
// Create a column-based divider container (side-by-side zones)
var dividerContainer = new ImGuiWidgets.DividerContainer(
"MyContainer",
ImGuiWidgets.DividerLayout.Columns
);
// Add zones with: id, initial size (relative weight), resizable, and a tick delegate (receives delta time)
dividerContainer.Add("Left Panel", 0.33f, true, dt =>
{
ImGui.Text("Left side content");
ImGui.Button("Left Button");
});
dividerContainer.Add("Right Panel", 0.67f, true, dt =>
{
ImGui.Text("Right side content");
ImGui.Button("Right Button");
});
// Tick the container each frame in your render loop
dividerContainer.Tick(deltaTime);
// For a stacked (top/bottom) layout, use DividerLayout.Rows:
var stackedContainer = new ImGuiWidgets.DividerContainer(
"StackedContainer",
ImGuiWidgets.DividerLayout.Rows
);
stackedContainer.Add("Top Panel", 0.5f, true, dt =>
{
ImGui.Text("Top content");
});
stackedContainer.Add("Bottom Panel", 0.5f, true, dt =>
{
ImGui.Text("Bottom content");
});
stackedContainer.Tick(deltaTime);
The dividers can be dragged by the user to resize the content regions dynamically.
Hexa-backed Widgets
These widgets are thin adapters that delegate to Hexa.NET.ImGui.Widgets rather than reimplementing rendering logic:
Spinner: Indeterminate loading spinner animated from the ImGui frame timeBufferingBar: Horizontal bar filled left-to-right in proportion to a valueHorizontalSplitter/VerticalSplitter: Draggable splitters that adjust a bound height/width within min/max limitsToggleSwitch: Sliding on/off switchToggleButton: Button that shows a highlight ring while selectedTransparentButton: Button with no background until hoveredInlineButton: Compact button anchored inside an existing rectangle, for rows and headersIconTreeNode: Tree node with a coloured icon glyph before its labelEnumCombo<T>: Combo box listing every member of an enum typeTextCenteredV/TextCenteredH/TextCenteredVH: Text centred vertically, horizontally, or bothImageCenteredV/ImageCenteredH/ImageCenteredVH: Image centred vertically, horizontally, or bothImageScaleTo: Image scaled to fit inside a destination box while preserving aspect ratioTooltip: Shows a tooltip for the preceding item while it is hoveredBreadcrumb: Clickable breadcrumb trail from a separator-delimited pathDatePicker: Calendar control for picking a dateYearPicker: Grid control for picking a yearFlameGraph: Flame graph of hierarchical timing samplesFileTreeView: Navigable tree of the filesystem rooted at the machine's drivesOpenFileDialog/SaveFileDialog/OpenFolderDialog: Stateful dialogs for choosing existing files, a save destination, or a folderRenameDialog: Renames or moves a file, reporting success or failure without throwingDialogMessageBox/ShowMessageBox: A movable-window-style and a popup-style message box, respectivelyDockedWindow: Abstract base for a floating window the user can drag into the dockspaceDrawDeferredDocked()creates — subclass it, overrideTitleandDrawContent(), then callShow()/Close(). It is dockable, not auto-docked: it opens floating and stays there until the user drags it in
Material Icons font: DatePicker (Material CalendarToday, U+E935) and FileTreeView (Home U+E9B2, Computer U+E31E) render placeholder boxes unless a Material Icons font is registered in the atlas. OpenFileDialog, SaveFileDialog and OpenFolderDialog need the same font for their toolbar, breadcrumb and file-tree glyphs. Register it via FontHelper.AddCustomFont(io, fontData, size, FontHelper.GetMaterialIconRanges(), mergeWithPrevious: true) — not via ImGuiAppConfig.Fonts, which applies the Nerd Font mapping and leaves the glyphs unmapped. See examples/ImGuiAppDemo for a worked example. YearPicker, RenameDialog, DialogMessageBox and ShowMessageBox require no icon font.
Duplicate widgets: Several Hexa-backed widgets deliberately coexist with an existing ktsu widget that covers similar ground: HorizontalSplitter/VerticalSplitter vs DividerContainer, IconTreeNode vs Tree, ToggleSwitch vs Switch, BufferingBar/Spinner vs RadialProgressBar/SkeletonLoader, EnumCombo vs Combo, TextCenteredV/H/VH vs TextCentered, and ImageCenteredV/H/VH vs ImageCentered. Both sides of each pair remain until the "Hexa vs ktsu" comparison tab in examples/ImGuiWidgetsDemo settles which one to keep — that decision is a separate, breaking change.
Deferred drawing: The dialogs above and DockedWindow only draw when a per-frame pump runs. Call ImGuiWidgets.DrawDeferred() once per frame (at the end of OnRender) to draw every open dialog, message box and popup and advance Hexa's animation clock; call ImGuiWidgets.DrawDeferredDocked() instead if you use DockedWindow — it additionally enables ImGuiConfigFlags.DockingEnable (idempotently, since Hexa's dockspace is a no-op without it) and creates a dockspace over the main viewport, and it already does everything DrawDeferred() does, so call only one of the two per frame (calling both draws every dialog twice). Showing a dialog before either pump has ever run throws InvalidOperationException, as does calling Show() on a dialog instance that is already shown (Hexa would register the same instance twice and permanently block input) — wait for the close callback, or create a new instance per showing. A pump is not needed just to keep animated widgets like ToggleSwitch correct — it self-ticks when unpumped — only to show dialogs or docked windows.
Callback-driven Editors
Sequencer and the multi-curve CurveEditor overload take a source object they interrogate while drawing, instead of a value:
- Subclass
SequenceSourcefor a timeline:FrameMin,FrameMax,ItemCount,GetItem(int), andSetItemRange(int index, int start, int endFrame), which receives drag edits. - Subclass
CurveSourcefor a multi-curve graph:CurveCount,ViewMin,ViewMax,GetPointCount(int),GetPoints(int),GetCurveColor(int),EditPoint(int, int, Vector2),AddPoint(int, Vector2).
Neither needs a deferred-drawing pump — both are immediate-mode calls that happen to take a callback object, and neither Sequencer nor CurveEditor calls DrawDeferred()/DrawDeferredDocked().
public static bool ImGuiWidgets.Sequencer(SequenceSource source, ref int currentFrame, ref bool expanded,
ref int selectedEntry, ref int firstFrame, SequencerFeatures features = SequencerFeatures.EditAll);
public static bool ImGuiWidgets.CurveEditor(CurveSource source, Vector2 size, string id);
CurveEditor also has a single-curve overload taking a CurveData value instead of a CurveSource:
public static bool ImGuiWidgets.CurveEditor(CurveData curve, Vector2 size, Vector2 rangeMin,
Vector2 rangeMax, ref int selection, string label);
CurveData wraps the curve representation the widget expects — points are CurveKnot (Position plus a CurvePointKind of .Smooth or .Corner), shaped by CurveShape.Smooth/.Freehand — and tracks a dirty flag so Sample(float t) recomputes its cache automatically after AddPoint/SetPoint/RemovePoint/Clear, a Shape change, or an edit made through the widget.
BezierEditor edits a BezierControlPoints pair (First/Second) directly, with no source object:
public static bool ImGuiWidgets.BezierEditor(string label, ref BezierControlPoints points, float size = 128f);
Contributing
Contributions are welcome! For feature requests, bug reports, or questions, please open an issue on the GitHub repository. If you would like to contribute code, please open a pull request with your changes.
Acknowledgements
ImGuiWidgets is inspired by the following projects:
License
ImGuiWidgets is licensed under the MIT License. See LICENSE for more information.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Hexa.NET.ImGui (>= 2.2.9)
- Hexa.NET.ImGui.Widgets (>= 1.2.18)
- Hexa.NET.ImGui.Widgets.Extras (>= 1.0.9)
- Hexa.NET.Math (>= 2.0.8)
- ktsu.Extensions (>= 1.6.2)
- ktsu.ImGui.Color (>= 3.8.1)
- ktsu.ImGui.Probes (>= 3.8.1)
- ktsu.ImGui.Styler (>= 3.8.1)
- ktsu.ScopedAction (>= 1.1.30)
- ktsu.Semantics.Color (>= 3.0.0)
- ktsu.Semantics.Paths (>= 3.0.0)
- ktsu.Semantics.Strings (>= 3.0.0)
- ktsu.TextFilter (>= 1.5.34)
-
net8.0
- Hexa.NET.ImGui (>= 2.2.9)
- Hexa.NET.ImGui.Widgets (>= 1.2.18)
- Hexa.NET.ImGui.Widgets.Extras (>= 1.0.9)
- Hexa.NET.Math (>= 2.0.8)
- ktsu.Extensions (>= 1.6.2)
- ktsu.ImGui.Color (>= 3.8.1)
- ktsu.ImGui.Probes (>= 3.8.1)
- ktsu.ImGui.Styler (>= 3.8.1)
- ktsu.ScopedAction (>= 1.1.30)
- ktsu.Semantics.Color (>= 3.0.0)
- ktsu.Semantics.Paths (>= 3.0.0)
- ktsu.Semantics.Strings (>= 3.0.0)
- ktsu.TextFilter (>= 1.5.34)
-
net9.0
- Hexa.NET.ImGui (>= 2.2.9)
- Hexa.NET.ImGui.Widgets (>= 1.2.18)
- Hexa.NET.ImGui.Widgets.Extras (>= 1.0.9)
- Hexa.NET.Math (>= 2.0.8)
- ktsu.Extensions (>= 1.6.2)
- ktsu.ImGui.Color (>= 3.8.1)
- ktsu.ImGui.Probes (>= 3.8.1)
- ktsu.ImGui.Styler (>= 3.8.1)
- ktsu.ScopedAction (>= 1.1.30)
- ktsu.Semantics.Color (>= 3.0.0)
- ktsu.Semantics.Paths (>= 3.0.0)
- ktsu.Semantics.Strings (>= 3.0.0)
- ktsu.TextFilter (>= 1.5.34)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.8.1 | 0 | 8/19/2026 |
| 3.8.0 | 0 | 8/19/2026 |
| 3.7.3 | 0 | 8/19/2026 |
| 3.7.2 | 0 | 8/18/2026 |
| 3.7.1 | 67 | 8/17/2026 |
| 3.7.0 | 81 | 8/17/2026 |
| 3.6.1 | 81 | 8/16/2026 |
| 3.6.0 | 54 | 8/16/2026 |
| 3.5.2 | 57 | 8/16/2026 |
| 3.5.1 | 60 | 8/16/2026 |
| 3.5.0 | 66 | 8/15/2026 |
| 3.4.3 | 56 | 8/15/2026 |
| 3.4.2 | 48 | 8/15/2026 |
| 3.4.1 | 60 | 8/15/2026 |
| 3.4.0 | 59 | 8/15/2026 |
| 3.3.12 | 141 | 8/12/2026 |
| 3.3.11 | 95 | 8/11/2026 |
| 3.3.10 | 95 | 8/11/2026 |
| 3.3.9 | 119 | 8/6/2026 |
## v3.8.1 (patch)
Changes since v3.8.0:
- chore: refresh the API compatibility suppressions [patch] ([@matt-edmondson](https://github.com/matt-edmondson))