Color button hover

color_button is a click trigger — its ClickState records click counts and the clicked per-frame flag. Some call sites want the swatch’s geometry only, with no click bookkeeping; the hover variant covers that:

let hovered = color_button_hover(SWATCH,
    (desc_id = "##red", col = float4(0.85f, 0.20f, 0.20f, 1.0f),
     size = float2(96.0f, 64.0f), flags = ImGuiColorEditFlags.NoTooltip))
if (hovered) {
    // per-frame side-effect, e.g. SetNextFrameWantCaptureMouse(...)
}

EmptyMarkerState backs the widget; the return value is the per-frame hover bool (ImGui::IsItemHovered() of the just-drawn swatch).

Source: examples/tutorial/color_button_hover.das.

Walkthrough

  1options gen2
  2
  3require imgui
  4require imgui_app
  5require opengl/opengl_boost
  6require live/glfw_live
  7require live/live_api
  8require live/live_commands
  9require live/live_vars
 10require live_host
 11require imgui/imgui_live
 12require imgui/imgui_boost_runtime
 13require imgui/imgui_boost_v2
 14require imgui/imgui_widgets_builtin
 15require imgui/imgui_containers_builtin
 16require imgui/imgui_visual_aids
 17
 18// =============================================================================
 19// TUTORIAL: color_button_hover — hover-target variant of color_button.
 20//
 21//   color_button(IDENT, (col = ...))        — click trigger (ClickState).
 22//   color_button_hover(IDENT, (col = ...))  — hover only (EmptyMarkerState);
 23//                                              returns true while ImGui
 24//                                              considers the swatch hovered.
 25//
 26// Use the hover variant when the swatch is the surface on which a
 27// hover-driven side-effect is mounted (e.g. "while hovering this swatch,
 28// override io.WantCaptureMouse"); the click form would force the caller to
 29// distinguish click vs hover at every site.
 30//
 31// STANDALONE: daslang.exe modules/dasImgui/examples/tutorial/color_button_hover.das
 32// LIVE:       daslang-live modules/dasImgui/examples/tutorial/color_button_hover.das
 33// =============================================================================
 34
 35var private STATE_MESSAGE = "Hover any swatch."
 36
 37[export]
 38def init() {
 39    live_create_window("dasImgui color_button_hover tutorial", 640, 380)
 40    live_imgui_init(live_window)
 41    let io & = unsafe(GetIO())
 42    GetStyle().FontScaleMain = 1.4
 43}
 44
 45[export]
 46def update() {
 47    if (!live_begin_frame()) return
 48    begin_frame()
 49
 50    ImGui_ImplGlfw_NewFrame()
 51    apply_synth_io_override()
 52    NewFrame()
 53
 54    SetNextWindowPos(ImVec2(40.0f, 40.0f), ImGuiCond.Always)
 55    SetNextWindowSize(ImVec2(560.0f, 300.0f), ImGuiCond.Always)
 56    window(CBH_WIN, (text = "color_button_hover", closable = false,
 57                     flags = ImGuiWindowFlags.None)) {
 58        text("color_button_hover returns true while ImGui considers the")
 59        text("just-drawn swatch hovered. No click state, no toggle.")
 60        separator()
 61
 62        let swatch_flags = (ImGuiColorEditFlags.NoTooltip | ImGuiColorEditFlags.NoDragDrop)
 63        let red = color_button_hover(CBH_RED,
 64            (desc_id = "##red", col = float4(0.85f, 0.20f, 0.20f, 1.0f),
 65             size = float2(96.0f, 64.0f), flags = swatch_flags))
 66        same_line(CBH_SL_1)
 67        let green = color_button_hover(CBH_GREEN,
 68            (desc_id = "##green", col = float4(0.20f, 0.85f, 0.30f, 1.0f),
 69             size = float2(96.0f, 64.0f), flags = swatch_flags))
 70        same_line(CBH_SL_2)
 71        let blue = color_button_hover(CBH_BLUE,
 72            (desc_id = "##blue", col = float4(0.20f, 0.40f, 0.85f, 1.0f),
 73             size = float2(96.0f, 64.0f), flags = swatch_flags))
 74
 75        if (red) {
 76            STATE_MESSAGE = "Hovering: red"
 77        } elif (green) {
 78            STATE_MESSAGE = "Hovering: green"
 79        } elif (blue) {
 80            STATE_MESSAGE = "Hovering: blue"
 81        }
 82
 83        text(CBH_STATUS, (text = STATE_MESSAGE))
 84    }
 85
 86    end_of_frame()
 87    Render()
 88    var w, h : int
 89    live_get_framebuffer_size(w, h)
 90    glViewport(0, 0, w, h)
 91    glClearColor(0.10f, 0.10f, 0.12f, 1.0f)
 92    glClear(GL_COLOR_BUFFER_BIT)
 93    live_imgui_render()
 94
 95    live_end_frame()
 96}
 97
 98[export]
 99def shutdown() {
100    live_imgui_shutdown()
101    live_destroy_window()
102}
103
104[export]
105def main() {
106    init()
107    while (!exit_requested()) {
108        update()
109    }
110    shutdown()
111}

Requires

Same baseline as color_button — already in imgui/imgui_widgets_builtin (re-exported by imgui/imgui_boost_v2).

When to reach for it

When the swatch is a surface, not a trigger:

  • examples/imgui_demo/inputs.das — the WantCapture-override panel uses a hover-target swatch to override io.WantCaptureMouse / io.WantCaptureKeyboard while the swatch is hovered. The ClickState of the regular color_button would force the caller to distinguish click vs hover.

  • Style previews where moving the mouse over the swatch shows a tooltip or status line — the hover bool is the natural drive signal.

Click vs hover

The two variants share the same call shape but pick the right state shape for the call site:

  • color_button(IDENT, (col, size, flags)) — returns bool clicked, records state.click_count and state.clicked.

  • color_button_hover(IDENT, (col, size, flags)) — returns bool hovered, no click bookkeeping.

A site that needs both (click triggers an action, hover updates a preview) should use the regular color_button and read IsItemHovered() after the call — the post-item hover query is allowed by the lint as a pure read.

Standalone vs live

Same convention as the other widget tutorials.

See also

Full source: examples/tutorial/color_button_hover.das

Integration test: tests/integration/test_color_button_hover.das.

Boost macros — the macro layer.