# `imgui_bundle.imgui_kit` imgui_kit: small, standalone additions to Dear ImGui: em units, a fill row, aligned groups, columns, a label column, a flow, a help marker, icon buttons, a segmented switch. The `begin_x()` / `end_x()` pairs are as in C++. The bare names are their context managers: `with imgui_kit.fill_row("slice") as row: ... row.tail() ...`. When C++ has a plain function of the bare name (`help_marker(text)`), the context manager takes the suffix `_ctx` (`help_marker_ctx(str_id)`). Generated from the Python stubs of Dear ImGui Bundle. Each entry gives its Python signature, its C++ declaration ("C++:"), and the first paragraph of its doc. The Python names follow the C++ ones (`ImGui::Button` is `imgui.button`, `ImPlotFlags_` is `implot.Flags_`). The full docs: https://imgui-bundle.pages.dev/doc/api/imgui-kit/ An entry that a demo shows has a "Live demo" link: the ImGui Explorer, a web app, opens at that demo, beside its C++ code (add &lang=python to the link for the Python code). Give it to a user who wants to see the entry in action. Under it, the demo's code that uses the entry, in Python and in C++: an extract ("..." when cut). The explorers: https://imgui-bundle.pages.dev/llms/explorers.txt ### imgui_kit.h ### Demo def show_demo_window(p_open: Optional[bool] = None) -> Optional[bool] C++: IMGUI_API void ShowDemoWindow(bool* p_open = nullptr); The kit's demo window, as ImGui::ShowDemoWindow(). Removed by IMGUI_KIT_DISABLE_DEMO. def show_demo_contents() -> None C++: IMGUI_API void ShowDemoContents(); The demo's content, in the current window (a host that places the window itself) ### Em units def em_size() -> float C++: IMGUI_API float EmSize(); def em_size(lines: float) -> float C++: IMGUI_API float EmSize(float lines); Live demo, section "Em units": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Em%20units C++, in the demo: ImGui::Button("100 x 30 px", ImVec2(100.0f, 30.0f)); ImGui::SameLine(); ImGuiKit::HelpMarker("EmToVec2(8, 2) gives the size in pixels, from the current font size."); ImGui::Text("1 em = %.1f px", ImGuiKit::EmSize()); The current font size, in pixels def em_to_vec2(x: float, y: float) -> ImVec2 C++: IMGUI_API ImVec2 EmToVec2(float x, float y); def em_to_vec2(v: ImVec2Like) -> ImVec2 C++: IMGUI_API ImVec2 EmToVec2(ImVec2 v); Live demo, section "Em units": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Em%20units Python, in the demo: imgui.button("8 x 2 em", imgui_kit.em_to_vec2(8, 2)) C++, in the demo: ImGui::Button("8 x 2 em", ImGuiKit::EmToVec2(8.0f, 2.0f)); A size or a position in em, in pixels def pixels_to_em(pixels: ImVec2Like) -> ImVec2 C++: IMGUI_API ImVec2 PixelsToEm(ImVec2 pixels); Pixels, in em def pixel_size_to_em(pixel_size: float) -> float C++: IMGUI_API float PixelSizeToEm(float pixel_size); ### Layout def begin_fill_row(str_id: str) -> float C++: IMGUI_API float BeginFillRow(const char* str_id); Live demo, section "Layout/Fill row": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FFill%20row C++, in the demo: ImGui::TextWrapped("The slider fills the line; the arrows and the (i) stay on the right. Resize the window."); static int slice = 37; ImGuiKit::BeginFillRow("slice"); Sets the next item's width, and returns it def fill_row_tail() -> None C++: IMGUI_API void FillRowTail(); Live demo, section "Toolbar": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Toolbar C++, in the demo: ImGuiKit::Label("Frame rounding"); ImGuiKit::BeginFillRow("rounding"); ImGui::SliderFloat("##rounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f px"); ImGuiKit::FillRowTail(); def end_fill_row() -> None C++: IMGUI_API void EndFillRow(); Live demo, section "Layout/Fill row": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FFill%20row C++, in the demo: ImGui::SameLine(); ImGuiKit::HelpMarker("BeginFillRow(), the slider, FillRowTail(), the arrows and this marker, EndFillRow()."); ImGuiKit::EndFillRow(); def begin_aligned_group(str_id: str, align_x: float) -> None C++: IMGUI_API void BeginAlignedGroup(const char* str_id, float align_x); Live demo, section "Layout/Aligned group": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FAligned%20group C++, in the demo: ImGuiKit::BeginAlignedGroup("right", 1.0f); def end_aligned_group() -> None C++: IMGUI_API void EndAlignedGroup(); Live demo, section "Layout/Aligned group": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FAligned%20group C++, in the demo: ImGui::Button("Cancel"); ImGui::SameLine(); ImGui::Button("Apply"); ImGuiKit::EndAlignedGroup(); def begin_column(str_id: str) -> None C++: IMGUI_API void BeginColumn(const char* str_id); Live demo, section "Layout/Column": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FColumn C++, in the demo: static float values[] = { 0.3f, 0.6f, 0.45f }; const char* labels[] = { "Bass", "Midrange", "Treble" }; const char* helps[] = { "Bass: below 250 Hz.", "Midrange: from 250 Hz to 4 kHz.", "Treble: above 4 kHz." }; for (int i = 0; i < 3; i++) { ImGui::PushID(i); ImGuiKit::BeginColumn("column"); ImGui::Text("%s", labels[i]); ImGuiKit::BeginAlignedGroup("slider", 0.5f); ImGui::VSliderFloat("##v", ImGuiKit::EmToVec2(1.6f, 6.0f), &values[i], 0.0f, 1.0f, ""); ImGuiKit::EndAlignedGroup(); ImGuiKit::BeginAlignedGroup("help", 0.5f); ImGuiKit::HelpMarker(helps[i]); ImGuiKit::EndAlignedGroup(); ... def end_column() -> None C++: IMGUI_API void EndColumn(); Live demo, section "Layout/Column": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FColumn C++, in the demo: ImGuiKit::BeginAlignedGroup("help", 0.5f); ImGuiKit::HelpMarker(helps[i]); ImGuiKit::EndAlignedGroup(); ImGuiKit::EndColumn(); def begin_label_column(str_id: str, labels_align_x: float = 0.0) -> None C++: IMGUI_API void BeginLabelColumn(const char* str_id, float labels_align_x = 0.0f); Live demo, section "Layout/Label column": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FLabel%20column C++, in the demo: static float volume = 0.5f; static float balance = 0.0f; static bool muted = false; ImGuiKit::BeginLabelColumn("audio", labels_align == 0 ? 0.0f : 1.0f); def label(text: str) -> None C++: IMGUI_API void Label(const char* text); Live demo, section "Layout/Label column": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FLabel%20column Python, in the demo: with imgui_kit.label_column("audio", 0.0 if state.labels_align == 0 else 1.0): imgui_kit.label("Labels") _, state.labels_align = imgui_kit.segmented_switch("##labels_align", state.labels_align, ["Left", "Right"]) imgui_kit.label("Volume") _, state.volume = imgui.slider_float("##volume", state.volume, 0.0, 1.0) imgui_kit.label("Left/right balance") _, state.balance = imgui.slider_float("##balance", state.balance, -1.0, 1.0) imgui_kit.label("Output") _, state.muted = imgui.checkbox("Muted", state.muted) imgui.same_line() imgui.button("Test sound") C++, in the demo: static float balance = 0.0f; static bool muted = false; ImGuiKit::BeginLabelColumn("audio", labels_align == 0 ? 0.0f : 1.0f); ImGuiKit::Label("Labels"); def end_label_column() -> None C++: IMGUI_API void EndLabelColumn(); Live demo, section "Layout/Label column": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FLabel%20column C++, in the demo: ImGui::Checkbox("Muted", &muted); ImGui::SameLine(); ImGui::Button("Test sound"); ImGuiKit::EndLabelColumn(); def begin_group_panel(label: str, size: Optional[ImVec2Like] = None) -> None C++: IMGUI_API void BeginGroupPanel(const char* label, const ImVec2& size = ImVec2(0, 0)); Live demo, section "Layout/Group panel": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FGroup%20panel C++, in the demo: ImGuiKit::BeginGroupPanel("Image info"); def end_group_panel() -> None C++: IMGUI_API void EndGroupPanel(); Live demo, section "Layout/Group panel": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FGroup%20panel C++, in the demo: ImGui::Text("Size: 640 x 480"); ImGui::Text("Channels: 3"); ImGui::Text("Depth: 8 bits"); ImGuiKit::EndGroupPanel(); def begin_flow(str_id: str) -> None C++: IMGUI_API void BeginFlow(const char* str_id); Live demo, section "Layout/Flow": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FFlow C++, in the demo: ImGuiKit::BeginFlow("presets"); def flow_next() -> None C++: IMGUI_API void FlowNext(); Live demo, section "Layout/Flow": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FFlow Python, in the demo: for i, preset in enumerate(presets): imgui_kit.flow_next() selected = i == state.preset if selected: imgui.push_style_color(imgui.Col_.button, imgui.get_style_color_vec4(imgui.Col_.button_active)) if imgui.button(preset): state.preset = i if selected: imgui.pop_style_color() C++, in the demo: ImGuiKit::BeginFlow("presets"); for (int i = 0; i < IM_ARRAYSIZE(presets); i++) { ImGuiKit::FlowNext(); bool is_selected = (i == selected); if (is_selected) ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive)); if (ImGui::Button(presets[i])) selected = i; if (is_selected) ImGui::PopStyleColor(); } def end_flow() -> None C++: IMGUI_API void EndFlow(); Live demo, section "Layout/Flow": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Layout%2FFlow C++, in the demo: ImGuiKit::EndFlow(); ### Widgets def help_marker(text: str, width_em: float = 0.0) -> None C++: IMGUI_API void HelpMarker(const char* text, float width_em = 0.0f); Live demo, section "Widgets/Help marker": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Widgets%2FHelp%20marker Python, in the demo: imgui.bullet_text("On a touch screen: tap to open, tap elsewhere to close.") imgui.text("Try it:") imgui.same_line() imgui_kit.help_marker("With a mouse, hovering shows this text, and a click pins it until a click elsewhere. " "On a touch screen, a tap opens it.") C++, in the demo: ImGui::BulletText("On a touch screen: tap to open, tap elsewhere to close."); ImGui::Text("Try it:"); ImGui::SameLine(); ImGuiKit::HelpMarker("With a mouse, hovering shows this text, and a click pins it until a click elsewhere. " "On a touch screen, a tap opens it."); Help marker: a small drawn (i). It shows its text: - with a mouse: in a tooltip while hovered; a click pins it in a popup, until a click elsewhere or Escape; - on a touch screen (which has no hover): in a popup, opened by a tap. width_em: the window's width, in em (a parameter named _em is in em; ... def begin_help_marker(str_id: str, width_em: float = 0.0) -> bool C++: IMGUI_API bool BeginHelpMarker(const char* str_id, float width_em = 0.0f); Live demo, section "Widgets/Help marker": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Widgets%2FHelp%20marker C++, in the demo: ImGui::Text("Any content, with Begin/End:"); ImGui::SameLine(); if (ImGuiKit::BeginHelpMarker("##custom")) { ImGui::Text("A help with widgets:"); ImGui::BulletText("a list"); ImGui::Button("and a button"); ImGuiKit::EndHelpMarker(); } def end_help_marker() -> None C++: IMGUI_API void EndHelpMarker(); Live demo, section "Widgets/Help marker": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Widgets%2FHelp%20marker C++, in the demo: ImGui::Text("Any content, with Begin/End:"); ImGui::SameLine(); if (ImGuiKit::BeginHelpMarker("##custom")) { ImGui::Text("A help with widgets:"); ImGui::BulletText("a list"); ImGui::Button("and a button"); ImGuiKit::EndHelpMarker(); } def help_marker_width() -> float C++: IMGUI_API float HelpMarkerWidth(); The width a help marker takes at the end of a line, with the spacing before it def icon_button(str_id: str, icon: Icon, size: Optional[ImVec2Like] = None) -> bool C++: IMGUI_API bool IconButton(const char* str_id, ImGuiKitIcon icon, const ImVec2& size = ImVec2(0, 0)); Live demo, section "Widgets/Icon button": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Widgets%2FIcon%20button Python, in the demo: Icon = imgui_kit.Icon_ if imgui_kit.icon_button("##minus", Icon.minus): state.zoom /= 1.25 C++, in the demo: static float zoom = 1.0f; if (ImGuiKit::IconButton("##minus", ImGuiKitIcon_Minus)) zoom /= 1.25f; Icon button: a button with a symbol drawn with the draw list, centered (a font's glyph often sits a little high in a button), in the text's color. size: (0, 0) = a square of the frame's height. def segmented_switch(str_id: str, current: int, labels: List[str]) -> Tuple[bool, int] C++: IMGUI_API bool SegmentedSwitch(const char* str_id, int* current, const char* const labels[], int labels_count); Live demo, section "Widgets/Segmented switch": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Widgets%2FSegmented%20switch Python, in the demo: imgui.text_wrapped("Its corners follow the style's frame_rounding, as a button's do: change it at the top.") views = ["Demo", "Code"] _, state.view = imgui_kit.segmented_switch("##view", state.view, views) C++, in the demo: ImGui::TextWrapped("Its corners follow the style's FrameRounding, as a button's do: change it at the top."); static int view = 0; const char* views[] = { "Demo", "Code" }; ImGuiKit::SegmentedSwitch("##view", &view, views, IM_ARRAYSIZE(views)); Segmented switch: exclusive choices in one frame, the current one filled. Its corners follow the style's FrameRounding, as buttons and sliders do. def segmented_switch_width(labels: List[str]) -> float C++: IMGUI_API float SegmentedSwitchWidth(const char* const labels[], int labels_count); Live demo, section "Toolbar": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Toolbar Python, in the demo: with imgui_kit.label_column("toolbar"): imgui_kit.label("Theme") themes = ["App", "Dark", "Light", "Classic"] next_line_if_too_wide(imgui_kit.segmented_switch_width(themes)) changed, state.theme = imgui_kit.segmented_switch("##theme", state.theme, themes) if changed: if state.theme == 0: for i, c in enumerate(state.app_colors): style.set_color_(i, c) elif state.theme == 1: imgui.style_colors_dark() elif state.theme == 2: imgui.style_colors_light() else: ... C++, in the demo: ImGuiKit::Label("Theme"); static int theme = 0; const char* themes[] = { "App", "Dark", "Light", "Classic" }; NextLineIfTooWide(ImGuiKit::SegmentedSwitchWidth(themes, IM_ARRAYSIZE(themes))); The width a segmented switch takes, to place it: e.g. on the next line when the current one is too short def fit_text(text: str, wrap_width: float, max_lines: int) -> str C++: IMGUI_API const char* FitText(const char* text, float wrap_width, int max_lines); Live demo, section "Widgets/Fit text": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Widgets%2FFit%20text Python, in the demo: width = imgui_kit.em_size(state.fit_width_em) p = imgui.get_cursor_screen_pos() imgui.push_text_wrap_pos(imgui.get_cursor_pos_x() + width) imgui.text_unformatted(imgui_kit.fit_text(text, width, state.fit_lines)) C++, in the demo: float width = ImGuiKit::EmSize(width_em); ImVec2 p = ImGui::GetCursorScreenPos(); ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + width); ImGui::TextUnformatted(ImGuiKit::FitText(text, width, max_lines)); Fit text: the text, cut at a word and ended with an ellipsis, so that it takes at most max_lines once wrapped at wrap_width (in the current font). Returns the text itself when it fits; else a buffer of the kit, valid for this frame (a small cache: the cut is computed once per text and width, not at ... ### Wheel session def setup_wheel_session(enabled: bool = True) -> None C++: IMGUI_API void SetupWheelSession(bool enabled = true); The wheel session: the mouse wheel keeps scrolling the window it started on, as in a browser. A page scrolled with the wheel keeps scrolling when a plot or an image passes under the mouse, and the plot does not zoom; a wheel that starts on the plot zooms it. The page lets go of the wheel when the ... ### Idling def is_animating() -> bool C++: IMGUI_API bool IsAnimating(); Live demo, section "Touch": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Touch Python, in the demo: touch_moves = "yes" if imgui_kit.touch.is_animating() else "no" C++, in the demo: ImGui::Text("Moving on its own: touch %s, kit %s", ImGuiTouch::IsAnimating() ? "yes" : "no", ImGuiKit::IsAnimating() ? "yes" : "no"); True while something of the kit moves on its own: a widget's animation (a segmented switch that slides), or the touch layer's (ImGuiTouch::IsAnimating(): a fling, a bounce, a long press's ring). An app that sleeps when nothing happens keeps drawing frames meanwhile; one that draws every frame can ... def request_animation() -> None C++: IMGUI_API void RequestAnimation(); A widget that animates calls it at each frame of its animation, so that IsAnimating() is True ### Enums enum Icon_ C++: enum ImGuiKitIcon_ The symbols of IconButton() minus = 0 plus = 1 zoom_in = 2 zoom_out = 3 zoom_one_to_one = 4 zoom_fit = 5 ### Touch enum TouchScrollMode_ C++: enum ImGuiTouchScrollMode_ Whether a finger that drags the content of a window scrolls it (the swipe) auto = 0 # only when the input is a touch screen (io.MouseSource) always = 1 # also with the mouse (left button): to try the phone's behavior on a desktop disabled = 2 enum TouchAxis_ C++: enum ImGuiTouchAxis_ The direction in which a widget takes a finger's drags (ImGuiTouch::SetItemTakesDrags); the values of Dear ImGui's internal ImGuiAxis any = -1 # every direction, at once: a canvas, a knob, a plot x = 0 # a slider y = 1 # a vertical slider enum TouchPinchDelivery_ C++: enum ImGuiTouchPinchDelivery_ How a pinch reaches a widget as wheel events (ImGuiTouch::SetItemPinchAsWheel) wheel_continuous = 0 # the exact amount at each frame: a widget that zooms by the wheel's wheel_notches = 1 # whole notches (+1, -1): a widget that reads only the wheel's sign enum TouchPinchKind_ C++: enum ImGuiTouchPinchKind_ What two fingers do, as the layer decides it once per gesture (ImGuiTouchPinch::Kind) undecided = 0 # until their distance changed a little, or their middle moved a little pinch = 1 # they spread or close pan = 2 # they move together class TouchPinch C++: struct ImGuiTouchPinch Two fingers on a widget, at this frame (ImGuiTouch::ItemPinch). A widget applies both the zoom and the pan at each frame: the content stays under the fingers, as on a map. ImGuiTouchPinch p = ImGuiTouch::ItemPinch(); if (p.Active) { offset = p.Center - (p.Center - offset) * p.ScaleDelta; // zoom ... active: bool # two fingers are on this widget's gesture (False: the deltas are neutral) started: bool # the gesture's first frame ended: bool # the fingers lifted (or were cancelled) since the last frame: Active is False then center: ImVec2 # the fingers' middle, in screen coordinates center_delta: ImVec2 # its move since the last frame: the pan scale_delta: float # the fingers' distance over the last frame's: 1 when unchanged scale: float # their distance over the distance at the start: 1 at the start kind: TouchPinchKind # pinch or pan, for a widget that wants one at a time def __init__(self) -> None C++: ImGuiTouchPinch() : Active(false), Started(false), Ended(false), ScaleDelta(1.0f), Scale(1.0f), Kind(ImGuiTouchPinchKind_Undecided); enum TouchPhase_ C++: enum ImGuiTouchPhase_ The phase of a finger, as the platforms report it (ImGuiTouch::AddFingerEvent) began = 0 # the finger landed moved = 1 # it is still down (moved or not) ended = 2 # it lifted cancelled = 3 # the system took the touch over (a system gesture, a call): it lifted, and its press class TouchKeyboardInsets C++: struct ImGuiTouchKeyboardInsets The parts of the screen hidden by a phone's keyboard: see ImGuiTouch::GetKeyboardInsets(). Top and Bottom are distances inward from the display's top and bottom edges, in Dear ImGui's coordinates: the visible part is [Top, io.DisplaySize.y - Bottom]. Zero when no keyboard shows. top: float bottom: float def __init__(self, top: float = 0.0, bottom: float = 0.0) -> None C++: ImGuiTouchKeyboardInsets(float top = 0.0f, float bottom = 0.0f) : Top(top), Bottom(bottom); class TouchConfig C++: struct ImGuiTouchConfig The settings, read at each frame: change them through ImGuiTouch::GetConfig() scroll_mode: TouchScrollMode hold_seconds: float long_press_is_right_click: bool long_press_seconds: float # iOS: about 500 ms thin_scrollbars: bool pinch_scales_font: bool pinch_font_scale_min: float pinch_font_scale_max: float simulate_touch: bool def __init__(self, scroll_mode: Optional[TouchScrollMode] = None, hold_seconds: float = 0.15, long_press_is_right_click: bool = True, long_press_seconds: float = 0.5, thin_scrollbars: bool = True, pinch_scales_font: bool = True, pinch_font_scale_min: float = 0.5, pinch_font_scale_max: float = 5.0, simulate_touch: bool = False) -> None #### Submodule touch class touch @staticmethod def setup(config: Optional[TouchConfig] = None) -> None C++: IMGUI_API void Setup(const ImGuiTouchConfig& config = ImGuiTouchConfig()); @staticmethod def is_installed() -> bool C++: IMGUI_API bool IsInstalled(); True once a setup was called in the current context @staticmethod def get_config() -> TouchConfig C++: IMGUI_API ImGuiTouchConfig& GetConfig(); Live demo, section "Touch": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Touch Python, in the demo: config = imgui_kit.touch.get_config() C++, in the demo: ImGuiTouchConfig& config = ImGuiTouch::GetConfig(); @staticmethod def is_animating() -> bool C++: IMGUI_API bool IsAnimating(); Live demo, section "Touch": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Touch Python, in the demo: touch_moves = "yes" if imgui_kit.touch.is_animating() else "no" C++, in the demo: ImGui::Text("Moving on its own: touch %s, kit %s", ImGuiTouch::IsAnimating() ? "yes" : "no", ImGuiKit::IsAnimating() ? "yes" : "no"); True while the touch layer moves something on its own (a fling's inertia, the bounce, a long press's ring): an app that sleeps when nothing happens keeps drawing frames meanwhile. False without the touch layer. An app uses ImGuiKit::IsAnimating() instead, which adds the kit's widgets. @staticmethod def set_item_takes_drags(axis: Optional[TouchAxis] = None, long_press_is_right_click: bool = True) -> None C++: IMGUI_API void SetItemTakesDrags(ImGuiTouchAxis axis = ImGuiTouchAxis_Any, bool long_press_is_right_click = true); Live demo, section "Touch": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Touch Python, in the demo: card_width = max(imgui_kit.em_size(6), imgui.get_content_region_avail().x * 0.3) # 3 per screen: it scrolls imgui.set_next_item_width(card_width) _, state.row_value = imgui.slider_float("##row_slider", state.row_value, 0.0, 1.0) imgui_kit.touch.set_item_takes_drags(imgui_kit.TouchAxis_.x) C++, in the demo: static float row_value = 0.5f; ImGui::SetNextItemWidth(card_width); ImGui::SliderFloat("##row_slider", &row_value, 0.0f, 1.0f); ImGuiTouch::SetItemTakesDrags(ImGuiTouchAxis_X); Right after a widget that a finger drags: a drag that starts on it goes to it, not to the swipe. - ImGuiTouchAxis_Any (a canvas, a knob, a plot): the widget gets the press at once, in every direction. - ImGuiTouchAxis_X or _Y (a slider, a vertical slider): the layer waits until the finger moved a ... @staticmethod def item_pinch() -> TouchPinch C++: IMGUI_API ImGuiTouchPinch ItemPinch(); Live demo, section "Touch": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Touch Two fingers on a widget: by default they scale the font (a pinch) or are a right drag (moved together). A widget changes that with one of these calls, right after it, at each frame (the claims of the last frame decide where the fingers land). When claims nest, the smallest holding both fingers ... @staticmethod def rect_pinch(id: ImGuiID, min: ImVec2Like, max: ImVec2Like) -> TouchPinch C++: IMGUI_API ImGuiTouchPinch RectPinch(ImGuiID id, const ImVec2& min, const ImVec2& max); The same, for a rectangle in screen coordinates and an id of the caller's: a widget that is not one item @staticmethod def set_item_pinch_as_wheel(wheel_zoom_factor: float, delivery: Optional[TouchPinchDelivery] = None) -> None C++: IMGUI_API void SetItemPinchAsWheel(float wheel_zoom_factor, ImGuiTouchPinchDelivery delivery = ImGuiTouchPinchDelivery_WheelContinuous); @staticmethod def set_rect_pinch_as_wheel(min: ImVec2Like, max: ImVec2Like, wheel_zoom_factor: float, delivery: Optional[TouchPinchDelivery] = None) -> None C++: IMGUI_API void SetRectPinchAsWheel(const ImVec2& min, const ImVec2& max, float wheel_zoom_factor, ImGuiTouchPinchDelivery delivery = ImGuiTouchPinchDelivery_WheelContinuous); @staticmethod def set_item_two_finger_pan_as_mouse_drag(button: ImGuiMouseButton) -> None C++: IMGUI_API void SetItemTwoFingerPanAsMouseDrag(ImGuiMouseButton button); @staticmethod def set_rect_two_finger_pan_as_mouse_drag(min: ImVec2Like, max: ImVec2Like, button: ImGuiMouseButton) -> None C++: IMGUI_API void SetRectTwoFingerPanAsMouseDrag(const ImVec2& min, const ImVec2& max, ImGuiMouseButton button); @staticmethod def add_finger_event(id: int, pos: ImVec2Like, phase: TouchPhase) -> None C++: IMGUI_API void AddFingerEvent(int id, const ImVec2& pos, ImGuiTouchPhase phase); A finger on a touch screen, as the platform reports it: its id (any number the platform gives, stable while the finger is down), its position (in the mouse's coordinates), and its phase. Report every finger, the first one included: Dear ImGui sees only the first finger, as the mouse; these events ... @staticmethod def get_keyboard_insets() -> TouchKeyboardInsets C++: IMGUI_API ImGuiTouchKeyboardInsets GetKeyboardInsets(); Live demo, section "Touch keyboard": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Touch%20keyboard The parts of the screen hidden by a phone's keyboard (in Dear ImGui's coordinates): a full-screen window keeps out of them. Zero when no keyboard shows, and without the touch layer. @staticmethod def set_keyboard_insets(insets: TouchKeyboardInsets) -> None C++: IMGUI_API void SetKeyboardInsets(const ImGuiTouchKeyboardInsets& insets); A native app tells where its keyboard is (iOS: UIKeyboardWillChangeFrameNotification), and zero when it hides: the values stay until the next call. While a keyboard shows, the windows that hold the text field scroll its caret into view, above the keyboard. In a browser, SetupEmscriptenKeyboard() ... @staticmethod def set_item_opens_url(url: str) -> bool C++: IMGUI_API bool SetItemOpensUrl(const char* url); @staticmethod def set_rect_opens_url(min: ImVec2Like, max: ImVec2Like, url: str) -> bool C++: IMGUI_API bool SetRectOpensUrl(const ImVec2& min, const ImVec2& max, const char* url); ### Resize handle def resize_handle(str_id: str, size: ImVec2Like, min_size: Optional[ImVec2Like] = None) -> Tuple[bool, ImVec2] C++: bool ResizeHandle(const char* str_id, ImVec2* size, const ImVec2& min_size = ImVec2(0, 0)); Live demo, section "Widgets/Resize handle": https://pthom.github.io/imgui_explorer/?lib=imguikit&demo=Widgets%2FResize%20handle Python, in the demo: _, state.resizable_text = imgui.input_text_multiline("##text", state.resizable_text, state.text_size) _, state.text_size = imgui_kit.resize_handle("##text_size", state.text_size, imgui_kit.em_to_vec2(6, 2)) C++, in the demo: static char text[512] = "A text field that the reader can make larger.\nDrag its corner."; static ImVec2 text_size = ImGuiKit::EmToVec2(20.0f, 4.0f); ImGui::InputTextMultiline("##text", text, IM_ARRAYSIZE(text), text_size); ImGuiKit::ResizeHandle("##text_size", &text_size, ImGuiKit::EmToVec2(6.0f, 2.0f)); Resize handle: a grip at the bottom-right corner of the last item, which resizes it. Call it right after the item, which takes `size`; dragging the grip changes it (at least `min_size`). Returns (changed, size). ### Context managers, Python only class FillRow `with imgui_kit.fill_row(str_id) as row:` the next item fills the line; call `row.tail()` before the items that stay on its right. `row.width`: the fill width, for a widget that takes a size (a plot). width: float def tail(self) -> None def fill_row(str_id: str) -> FillRow A fill row, as a context manager: `begin_fill_row()`, then `end_fill_row()` at the block's end. def aligned_group(str_id: str, align_x: float) -> _BlockContext An aligned group, as a context manager: `begin_aligned_group()`, then `end_aligned_group()`. def column(str_id: str) -> _BlockContext A column, as a context manager: `begin_column()`, then `end_column()`. The aligned groups inside it align within its width. def label_column(str_id: str, labels_align_x: float = 0.0) -> _BlockContext A label column, as a context manager: `begin_label_column()`, then `end_label_column()`. Call `label(text)` at the start of each row. def group_panel(label: str, size: Optional[ImVec2Like] = None) -> _BlockContext A group panel, as a context manager: `begin_group_panel()`, then `end_group_panel()`. def flow(str_id: str) -> _BlockContext A flow, as a context manager: `begin_flow()`, then `end_flow()`. Call `flow_next()` before each item. class HelpMarkerContext `with imgui_kit.help_marker_ctx(str_id) as shown:` draw the help's content when `shown` is true. shown: bool def help_marker_ctx(str_id: str, width_em: float = 0.0) -> HelpMarkerContext A help marker with any content, as a context manager: `begin_help_marker()`, then `end_help_marker()` when it returned true.