Skip to content

Commit

Permalink
update hello_imgui (+ Add/RemoveDockableWindow)
Browse files Browse the repository at this point in the history
  • Loading branch information
pthom committed Sep 19, 2024
1 parent 416d885 commit 7aae505
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 74 deletions.
53 changes: 26 additions & 27 deletions bindings/imgui_bundle/demos_cpp/demos_immapp/demo_docking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,28 +183,38 @@ void DemoHideWindow(AppState& appState)
}
}

// Display a button that will show an additional window
// Display a button that will add another dockable window during execution
void DemoShowAdditionalWindow(AppState& appState)
{
// Notes:
// - it is *not* possible to modify the content of the vector runnerParams.dockingParams.dockableWindows
// from the code inside a window's `GuiFunction` (since this GuiFunction will be called while iterating on this vector!)
// - there are two ways to dynamically add windows:
// * either make them initially invisible, and exclude them from the view menu (such as shown here)
// * or modify runnerParams.dockingParams.dockableWindows inside the callback RunnerCallbacks.PreNewFrame
const char* windowName = "Additional Window";
// In order to add a dockable window during execution, you should use
// HelloImGui::AddDockableWindow()
// Note: you should not modify manually the content of runnerParams.dockingParams.dockableWindows
// (since HelloImGui is constantly looping on it)

ImGui::PushFont(appState.TitleFont); ImGui::Text("Dynamically add window"); ImGui::PopFont();

auto currentWindow = ImGui::GetCurrentWindow();

const char* windowName = "Additional Window";
if (ImGui::Button("Show additional window"))
{
auto additionalWindowPtr = HelloImGui::GetRunnerParams()->dockingParams.dockableWindowOfName(windowName);
if (additionalWindowPtr)
{
// additionalWindowPtr->includeInViewMenu = true;
additionalWindowPtr->isVisible = true;
}
HelloImGui::DockableWindow additionalWindow;
additionalWindow.label = windowName;
additionalWindow.includeInViewMenu = false; // this window is not shown in the view menu,
additionalWindow.rememberIsVisible = true; // its visibility is not saved in the settings file,
additionalWindow.dockSpaceName = "MiscSpace"; // when shown, it will appear in MiscSpace.
additionalWindow.GuiFunction = [] { ImGui::Text("This is the additional window"); };
HelloImGui::AddDockableWindow(
additionalWindow,
false // forceDockspace=false: means that the window will be docked to the last space it was docked to
// i.e. dockSpaceName is ignored if the user previously moved the window to another space
);
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("By clicking this button, you can show an additional window");
ImGui::SetItemTooltip("By clicking this button, you can show an additional window");

if (ImGui::Button("Remove additional window"))
HelloImGui::RemoveDockableWindow(windowName);
ImGui::SetItemTooltip("By clicking this button, you can remove the additional window");
}

void DemoLogs(AppState& appState)
Expand Down Expand Up @@ -723,16 +733,6 @@ std::vector<HelloImGui::DockableWindow> CreateDockableWindows(AppState& appState
dearImGuiDemoWindow.imGuiWindowFlags = ImGuiWindowFlags_MenuBar;
dearImGuiDemoWindow.GuiFunction = [] { ImGui::ShowDemoWindow(); };

// additionalWindow is initially not visible (and not mentioned in the view menu).
// it will be opened only if the user chooses to display it
HelloImGui::DockableWindow additionalWindow;
additionalWindow.label = "Additional Window";
additionalWindow.isVisible = false; // this window is initially hidden,
additionalWindow.includeInViewMenu = false; // it is not shown in the view menu,
additionalWindow.rememberIsVisible = false; // its visibility is not saved in the settings file,
additionalWindow.dockSpaceName = "MiscSpace"; // when shown, it will appear in MiscSpace.
additionalWindow.GuiFunction = [] { ImGui::Text("This is the additional window"); };

// alternativeThemeWindow
HelloImGui::DockableWindow alternativeThemeWindow;
// Since this window applies a theme, We need to call "ImGui::Begin" ourselves so
Expand All @@ -747,7 +747,6 @@ std::vector<HelloImGui::DockableWindow> CreateDockableWindows(AppState& appState
layoutCustomizationWindow,
logsWindow,
dearImGuiDemoWindow,
additionalWindow,
alternativeThemeWindow
};
return dockableWindows;
Expand Down
53 changes: 21 additions & 32 deletions bindings/imgui_bundle/demos_python/demos_immapp/demo_docking.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,31 +161,35 @@ def demo_hide_window(app_state: AppState):
hello_imgui.get_runner_params().app_window_params.hidden = False


# Display a button that will show an additional window
# Display a button that will add another dockable window during execution
def demo_show_additional_window(app_state: AppState):
# Notes:
# - it is *not* possible to modify the content of the vector runnerParams.dockingParams.dockableWindows
# from the code inside a window's `GuiFunction` (since this GuiFunction will be called while iterating
# on this vector!)
# - there are two ways to dynamically add windows:
# * either make them initially invisible, and exclude them from the view menu (such as shown here)
# * or modify runnerParams.dockingParams.dockableWindows inside the callback RunnerCallbacks.PreNewFrame
window_name = "Additional Window"
# In order to add a dockable window during execution, you should use
# hello_imgui.add_dockable_window()
# Note: you should not modify manually the content of runnerParams.docking_params.dockable_windows
# (since HelloImGui is constantly looping on it)

imgui.push_font(app_state.title_font)
imgui.text("Dynamically add window")
imgui.pop_font()

window_name = "Additional Window"
if imgui.button("Show additional window"):
runner_params = hello_imgui.get_runner_params()
additional_window_ptr = runner_params.docking_params.dockable_window_of_name(
window_name
additional_window = hello_imgui.DockableWindow()
additional_window.label = window_name
additional_window.include_in_view_menu = False # this window is not shown in the view menu,
additional_window.remember_is_visible = False # its visibility is not saved in the settings file,
additional_window.dock_space_name = "MiscSpace" # when shown, it will appear in MiscSpace.
additional_window.gui_function = lambda: imgui.text("This is the additional window")
hello_imgui.add_dockable_window(
additional_window,
force_dockspace=False # means that the window will be docked to the last space it was docked to
# i.e. dock_space_name is ignored if the user previously moved the window to another space
)
if additional_window_ptr:
# additional_window_ptr.include_in_view_menu = True
additional_window_ptr.is_visible = True
if imgui.is_item_hovered():
imgui.set_tooltip("By clicking this button, you can show an additional window")
imgui.set_item_tooltip("By clicking this button, you can show an additional window")

if imgui.button("Remove additional window"):
hello_imgui.remove_dockable_window(window_name)
imgui.set_item_tooltip("By clicking this button, you can remove the additional window")


def demo_basic_widgets(app_state: AppState):
Expand Down Expand Up @@ -725,20 +729,6 @@ def create_dockable_windows(app_state: AppState) -> List[hello_imgui.DockableWin
dear_imgui_demo_window.imgui_window_flags = imgui.WindowFlags_.menu_bar
dear_imgui_demo_window.gui_function = imgui.show_demo_window # type: ignore

# additional_window is initially not visible (and not mentioned in the view menu).
# it will be opened only if the user chooses to display it
additional_window = hello_imgui.DockableWindow()
additional_window.label = "Additional Window"
additional_window.is_visible = False # this window is initially hidden,
additional_window.include_in_view_menu = False # it is not shown in the view menu,
additional_window.remember_is_visible = (
False # its visibility is not saved in the settings file,
)
additional_window.dock_space_name = (
"MiscSpace" # when shown, it will appear in MiscSpace.
)
additional_window.gui_function = lambda: imgui.text("This is the additional window")

# alternativeThemeWindow
alternative_theme_window = hello_imgui.DockableWindow()
# Since this window applies a theme, We need to call "imgui.begin" ourselves so
Expand All @@ -753,7 +743,6 @@ def create_dockable_windows(app_state: AppState) -> List[hello_imgui.DockableWin
layout_customization_window,
logs_window,
dear_imgui_demo_window,
additional_window,
alternative_theme_window,
]
return dockable_windows
Expand Down
25 changes: 19 additions & 6 deletions bindings/imgui_bundle/hello_imgui.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2122,7 +2122,7 @@ class DockableWindow:
# --------------- Main params -------------------

# std::string label; /* original C++ signature */
# `label`: _string_. Title of the window.
# `label`: _string_. Title of the window. It should be unique! Use "##" to add a unique suffix if needed.
label: str

# DockSpaceName dockSpaceName; /* original C++ signature */
Expand Down Expand Up @@ -2306,11 +2306,7 @@ class DockingParams:
# std::optional<ImGuiID> dockSpaceIdFromName(const std::string& dockSpaceName); /* original C++ signature */
def dock_space_id_from_name(self, dock_space_name: str) -> Optional[ImGuiID]:
"""`optional<ImGuiID> dockSpaceIdFromName(const std::string& dockSpaceName)`:
may return the ImGuiID corresponding to the dockspace with this name.
**Warning**: this will work reliably only if
layoutCondition = DockingLayoutCondition::ApplicationStart.
In other cases, the ID may be cached by ImGui himself at the first run,
and HelloImGui will *not* know it on subsequent runs!
returns the ImGuiID corresponding to the dockspace with this name
"""
pass
# DockingParams(std::vector<DockingSplit> dockingSplits = std::vector<DockingSplit>(), std::vector<DockableWindow> dockableWindows = std::vector<DockableWindow>(), std::string layoutName = "Default", ImGuiDockNodeFlags mainDockSpaceNodeFlags = ImGuiDockNodeFlags_PassthruCentralNode, DockingLayoutCondition layoutCondition = DockingLayoutCondition::FirstUseEver, bool layoutReset = false); /* original C++ signature */
Expand Down Expand Up @@ -3292,6 +3288,23 @@ def current_layout_name() -> str:
"""`CurrentLayoutName()`: returns the name of the current layout"""
pass

# void AddDockableWindow(const DockableWindow& dockableWindow, bool forceDockspace = false); /* original C++ signature */
def add_dockable_window(
dockable_window: DockableWindow, force_dockspace: bool = False
) -> None:
"""`AddDockableWindow()`: will add a dockable window to the current layout.
Will dock the window to the dockspace it belongs to if forceDockspace is True,
otherwise will dock it to the last space it was docked to (using saved settings)
"""
pass

# void RemoveDockableWindow(const std::string& dockableWindowName); /* original C++ signature */
def remove_dockable_window(dockable_window_name: str) -> None:
"""`RemoveDockableWindow()`: will remove a dockable window from the current layout.
(dockableWindowName is the label of the window, as provided in the DockableWindow struct)
"""
pass

# @@md

# ============================== User prefs Utils =============================
Expand Down
18 changes: 12 additions & 6 deletions external/hello_imgui/bindings/hello_imgui_amalgamation.h
Original file line number Diff line number Diff line change
Expand Up @@ -1692,7 +1692,7 @@ struct DockableWindow
{
// --------------- Main params -------------------

// `label`: _string_. Title of the window.
// `label`: _string_. Title of the window. It should be unique! Use "##" to add a unique suffix if needed.
std::string label;

// `dockSpaceName`: _DockSpaceName (aka string)_.
Expand Down Expand Up @@ -1846,11 +1846,7 @@ struct DockingParams
bool focusDockableWindow(const std::string& windowName);

// `optional<ImGuiID> dockSpaceIdFromName(const std::string& dockSpaceName)`:
// may return the ImGuiID corresponding to the dockspace with this name.
// **Warning**: this will work reliably only if
// layoutCondition = DockingLayoutCondition::ApplicationStart.
// In other cases, the ID may be cached by ImGui himself at the first run,
// and HelloImGui will *not* know it on subsequent runs!
// returns the ImGuiID corresponding to the dockspace with this name
std::optional<ImGuiID> dockSpaceIdFromName(const std::string& dockSpaceName);
};
// @@md
Expand Down Expand Up @@ -2626,6 +2622,16 @@ void SwitchLayout(const std::string& layoutName);

// `CurrentLayoutName()`: returns the name of the current layout
std::string CurrentLayoutName();

// `AddDockableWindow()`: will add a dockable window to the current layout.
// Will dock the window to the dockspace it belongs to if forceDockspace is true,
// otherwise will dock it to the last space it was docked to (using saved settings)
void AddDockableWindow(const DockableWindow& dockableWindow, bool forceDockspace = false);

// `RemoveDockableWindow()`: will remove a dockable window from the current layout.
// (dockableWindowName is the label of the window, as provided in the DockableWindow struct)
void RemoveDockableWindow(const std::string& dockableWindowName);

// @@md


Expand Down
14 changes: 12 additions & 2 deletions external/hello_imgui/bindings/pybind_hello_imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ void py_init_module_hello_imgui(py::module& m)
auto pyClassDockableWindow =
py::class_<HelloImGui::DockableWindow>
(m, "DockableWindow", "DockableWindow is a struct that represents a window that can be docked.")
.def_readwrite("label", &HelloImGui::DockableWindow::label, "`label`: _string_. Title of the window.")
.def_readwrite("label", &HelloImGui::DockableWindow::label, "`label`: _string_. Title of the window. It should be unique! Use \"##\" to add a unique suffix if needed.")
.def_readwrite("dock_space_name", &HelloImGui::DockableWindow::dockSpaceName, " `dockSpaceName`: _DockSpaceName (aka string)_.\n Id of the dock space where this window should initially be placed")
.def_readwrite("gui_function", &HelloImGui::DockableWindow::GuiFunction, " `GuiFunction`: _VoidFunction_.\n Any function that will render this window's Gui")
.def_readwrite("is_visible", &HelloImGui::DockableWindow::isVisible, " `isVisible`: _bool, default=true_.\n Flag that indicates whether this window is visible or not.")
Expand Down Expand Up @@ -910,7 +910,7 @@ void py_init_module_hello_imgui(py::module& m)
.def("dock_space_id_from_name",
&HelloImGui::DockingParams::dockSpaceIdFromName,
py::arg("dock_space_name"),
" `optional<ImGuiID> dockSpaceIdFromName(const std::string& dockSpaceName)`:\n may return the ImGuiID corresponding to the dockspace with this name.\n **Warning**: this will work reliably only if\n layoutCondition = DockingLayoutCondition::ApplicationStart.\n In other cases, the ID may be cached by ImGui himself at the first run,\n and HelloImGui will *not* know it on subsequent runs!")
" `optional<ImGuiID> dockSpaceIdFromName(const std::string& dockSpaceName)`:\n returns the ImGuiID corresponding to the dockspace with this name")
;


Expand Down Expand Up @@ -1273,6 +1273,16 @@ void py_init_module_hello_imgui(py::module& m)
m.def("current_layout_name",
HelloImGui::CurrentLayoutName, "`CurrentLayoutName()`: returns the name of the current layout");

m.def("add_dockable_window",
HelloImGui::AddDockableWindow,
py::arg("dockable_window"), py::arg("force_dockspace") = false,
" `AddDockableWindow()`: will add a dockable window to the current layout.\n Will dock the window to the dockspace it belongs to if forceDockspace is True,\n otherwise will dock it to the last space it was docked to (using saved settings)");

m.def("remove_dockable_window",
HelloImGui::RemoveDockableWindow,
py::arg("dockable_window_name"),
" `RemoveDockableWindow()`: will remove a dockable window from the current layout.\n (dockableWindowName is the label of the window, as provided in the DockableWindow struct)");

m.def("save_user_pref",
HelloImGui::SaveUserPref,
py::arg("user_pref_name"), py::arg("user_pref_content"),
Expand Down

0 comments on commit 7aae505

Please sign in to comment.