Skip to content

ofxyz/ofxImGuiStyle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ofxImGuiStyle

preview-example_Basic

ofxImGuiStyle is an umbrella addon for ofxImGui that ships four independent, pure Dear ImGui sub-libraries plus a tiny openFrameworks-aware glue layer:

  • ImTheme (ImTheme.{h,cpp} + ImThemeRegistry.{h,cpp}) Theme system: 17 built-in themes vendored from pthom/hello_imgui (Darcula, DarculaDarker, LightRounded, ImGuiColorsDark, MaterialFlat, ...) plus an open-ended RegisterCustom registry for addons / apps to contribute their own (tb303, tr808, tr909, wasp, ...), plus a ShowSelector / ShowThemeTweakGui UI.
  • ImFonts (ImFonts.{h,cpp}) Font / icon loader: bundled Input Sans Regular TTF (UI font) merged with Font Awesome 5 Solid for icons, JetBrains Mono (Regular / Bold / Italic / BoldItalic) for code editors and markdown, plus IconButton / IconButtonGhost widgets sized from the current row height.
  • ImKnobs (ImKnobs.h + vendored src/imgui-knobs/) Rotary knob widgets from imgui-knobs (MIT). Multiple visual variants; reads colours from the active ImGui style.
  • ImLed (ImLed.{h,cpp}) Small status LED widgets (filled disc + optional label). Caller sets any on/off colour; includes inline layout helpers and a full-screen grid API.
  • ImMidi (ImMidi.h, ImMidiMapper.h, ImMidiRegistry.{h,cpp}) MIDI learn / CC mapping for any ImGui control from ImMidiMapper (MIT). Optional ofxMidi I/O when that addon is linked; otherwise use pushCC() yourself.
  • IconsFontAwesome5.h — vendored constants from juliettef/IconFontCppHeaders.

Fonts and themes are deliberately kept in the same addon: in real apps the two are coupled (different themes presume specific x-height / weight, icon buttons depend on FA glyphs being merged into the active font).

Both APIs are pure Dear ImGui — they don't include any openFrameworks header. The only OF coupling lives in callers that already own an ofxImGui::Gui (passed in by the caller for setDefaultFont / rebuildFontsTexture).

Quick start

Add both addons to addons.make:

ofxImGui
ofxImGuiStyle

Then load fonts + apply a theme after ofxImGui::Gui::setup():

#include "ofxImGui.h"
#include "ImTheme.h>"
#include "ImThemeRegistry.h"
#include "ImFonts.h"

ofxImGui::Gui gui;

void ofApp::setup() {
    gui.setup();

    if (ImFont* f = ImFonts::LoadDefaultFonts(ImGui::GetIO().Fonts, 15.f))
        gui.setDefaultFont(f);
    gui.rebuildFontsTexture();

    // Theme + HiDPI scale in one call (DetectOsScale when uiScale <= 0).
    ImTheme::Setup("DarculaDarker");
}

Selecting + tweaking themes at runtime

static std::string themeId = "DarculaDarker";

if (ImTheme::ShowSelector(themeId)) { }  // applies + re-commits scale

ImTheme::ShowThemeTweakGui(&tweaks);

ShowSelector applies the picked theme and automatically snapshots the unscaled baseline and re-applies the stored UI scale — no extra calls needed.

UI scale

float uiScale = ImTheme::UIScale();

if (ImGui::SliderFloat("Scale", &uiScale, 0.75f, 2.5f))
    ImTheme::SetUIScale(uiScale);

Setup, ApplyByName, and ShowSelector all re-commit scale when the theme changes. SetUIScale only rescales from the existing baseline (fast path for sliders).

Hand-tweaking metrics

If you edit ImGui::GetStyle() after a theme (extra padding, rounding, etc.), call Commit() once to snapshot and re-apply scale:

ImTheme::Setup(ImTheme::Theme_DarculaDarker);
ImGui::GetStyle().WindowPadding = ImVec2(14, 12);
// ...
ImTheme::Commit();

Registering a custom theme from an addon

ImTheme::RegisterCustom({
    "myaddon",
    "My Addon",
    [] {
        ImGui::GetStyle() = ImGuiStyle{};
        ImGui::StyleColorsDark();
        // ...
    }
});

ImTheme::Setup("myaddon");

Guard with __has_include if the addon must build without ofxImGuiStyle (see ofx303 / 808 / 909 / Wasp).

Style snapshot files (.bin)

ImTheme::SaveStyle(ofToDataPath("my_style.bin", true).c_str());

if (ImTheme::LoadStyle(path)) {
    ImTheme::ApplyCompactMetrics();
    ImTheme::Commit();
}

JetBrains Mono (code + markdown)

Four faces are embedded and loaded via LoadJetBrainsMono() or individually via LoadJetBrainsMonoFont(..., JetBrainsMonoVariant::Regular | Bold | Italic | BoldItalic).

#include "ImFonts.h"

ImFont* ui = ImFonts::LoadDefaultFonts(ImGui::GetIO().Fonts, 15.f);
gui.setDefaultFont(ui);

ImFont* code = ImFonts::LoadCodeEditorFont(ImGui::GetIO().Fonts, 14.f);
codeEditor->setFont(code);

// Or load Regular / Bold / Italic / BoldItalic together (e.g. for ofxImGuiMarkdown):
ImFonts::JetBrainsMonoFonts jbm = ImFonts::LoadJetBrainsMono(ImGui::GetIO().Fonts, 15.f);
renderer.regularFont    = jbm.regular;
renderer.boldFont       = jbm.bold;
renderer.italicFont     = jbm.italic;
renderer.boldItalicFont = jbm.boldItalic;
renderer.monoFont       = jbm.regular;

gui.rebuildFontsTexture();

Regenerate embedded headers after updating the TTFs:

python addons/ofxImGuiStyle/src/gen_font_headers.py

Source files are read from addons/JetBrainsMono-2.304/fonts/ttf/.

Icon buttons (ImFonts)

#include "ImFonts.h"
#include "IconsFontAwesome5.h"

if (ImFonts::IconButtonGhost(visible ? ICON_FA_EYE : ICON_FA_EYE_SLASH, "##eye"))
    visible = !visible;

Knobs (ImKnobs)

#include "ImKnobs.h"

float cutoff = 0.5f;
if (ImGuiKnobs::Knob("Cutoff", &cutoff, 0.f, 1.f, 0.f, "%.2f",
                     ImGuiKnobVariant_WiperDot, 42.f))
{
    // value changed
}

Status LEDs (ImLed)

#include "ImLed.h"

// Any colour
ImLed::Draw(ImVec4(0.2f, 0.9f, 0.3f, 1.f), { .label = "Ready" });

// Presets
ImLed::Draw(ImLed::ColorsOk(),   { .label = "Loaded" });
ImLed::Draw(ImLed::ColorsWarn(), { .label = "Pending" });
ImLed::Draw(ImLed::ColorsError());

// Full-screen grid (screen-space rectangle)
ImLed::DrawGrid(rectMin, rectMax, 32, 20, IM_COL32(255, 40, 40, 255));

See example_Led for a full-viewport LED matrix with colour + animation controls.

MIDI mapping (ImMidi)

Requires ofxMidi in addons.make for hardware ports. Wire in your app (e.g. tb303::midiBridge::setup() via tb303::kit::setupMidi()).

#include "ImMidi.h"

ImMidi::Setup(ofToDataPath("midiMapper.json", true));

void ofApp::update() {
    ImMidi::Update();
}

// inside ImGui:
ImGuiKnobs::Knob("Cutoff", &cutoff, 0.f, 1.f);
ImMidi::Mapper().watchLast("cutoff", &cutoff, 0.f, 1.f, "Cutoff");

ImMidi::DrawEditor(&showMidiMapper);

Right-click any registered control → MIDI Learn… → move a hardware knob.

Examples

  • example_Basic — fonts, icons, knobs, theme selector, scale slider, .bin I/O.
  • example_Led — full-screen LED matrix; arbitrary colours, grid size, wave animation.
  • example_LumaStudio — desktop-app mockup with custom padding + Commit().

Attribution

  • ImTheme.{h,cpp} — adapted from pthom/hello_imgui (MIT).
  • IconsFontAwesome5.hjuliettef/IconFontCppHeaders (MIT).
  • src/imgui-knobs/altschuler/imgui-knobs (MIT).
  • ImMidiMapper.h — ImMidiMapper (MIT).
  • Bundled fonts: Input Sans Regular, Font Awesome 5 Free Solid, and JetBrains Mono (Regular / Bold / Italic / BoldItalic, SIL Open Font License).

About

Centralizes shared ImGui styling for openFrameworks apps

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors