├── .github └── FUNDING.yml ├── LICENSE ├── CMakeLists.txt ├── README.md ├── ImCoolBar.h └── ImCoolBar.cpp /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: aiekick 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Aiekick 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Option to control installation (disabled by default if used as subproject) 2 | if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) 3 | set(IM_COOLBAR_INSTALL_DEFAULT ON) 4 | else() 5 | set(IM_COOLBAR_INSTALL_DEFAULT OFF) 6 | endif() 7 | 8 | option(IM_COOLBAR_INSTALL "Install ImCoolBar library and headers" ${IM_COOLBAR_INSTALL_DEFAULT}) 9 | 10 | find_package(imgui QUIET) # fails quietly if not found (imgui is the target name for vcpkg and nixpkgs). 11 | 12 | add_library(ImCoolBar 13 | ImCoolBar.cpp 14 | ImCoolBar.h 15 | ) 16 | 17 | if(imgui_FOUND) 18 | target_link_libraries(ImCoolBar PUBLIC imgui::imgui) 19 | message(STATUS "ImCoolBar: Found imgui package, linking automatically") 20 | else() 21 | message(STATUS "ImCoolBar: imgui package not found - ensure ImGui is available in your project") 22 | endif() 23 | 24 | # Use generator expressions for proper include directory handling 25 | target_include_directories(ImCoolBar 26 | PUBLIC 27 | $ 28 | $ 29 | ) 30 | 31 | if(UNIX) 32 | target_compile_options(ImCoolBar PUBLIC -Wno-unknown-pragmas) 33 | endif() 34 | 35 | # Installation configuration 36 | if(IM_COOLBAR_INSTALL) 37 | include(GNUInstallDirs) 38 | 39 | # Install the library 40 | install(TARGETS ImCoolBar 41 | EXPORT ImCoolBarTargets 42 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 43 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 44 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 45 | ) 46 | 47 | # Install headers 48 | install(FILES 49 | ImCoolBar.h 50 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 51 | ) 52 | 53 | # Install export targets 54 | install(EXPORT ImCoolBarTargets 55 | FILE ImCoolBarConfig.cmake 56 | NAMESPACE ImCoolBar:: 57 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ImCoolBar 58 | ) 59 | endif() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Win](https://github.com/aiekick/ImCoolBar/actions/workflows/win.yml/badge.svg)](https://github.com/aiekick/ImCoolBar/actions/workflows/win.yml) 2 | [![Linux](https://github.com/aiekick/ImCoolBar/actions/workflows/linux.yml/badge.svg)](https://github.com/aiekick/ImCoolBar/actions/workflows/linux.yml) 3 | [![Osx](https://github.com/aiekick/ImCoolBar/actions/workflows/osx.yml/badge.svg)](https://github.com/aiekick/ImCoolBar/actions/workflows/osx.yml) 4 | 5 | # ImCoolbar 6 | 7 | # Minimal Sample 8 | 9 | ```cpp 10 | ImGuiContext& g = *GImGui; 11 | const float& ref_font_scale = g.FontSizeBase; 12 | 13 | static bool show_imgui_demo{false}; 14 | static bool show_implot_demo{false}; 15 | static bool show_imgui_metrics{false}; 16 | static bool show_imcoolbar_metrics{false}; 17 | static std::array arr = {"ImGui\nDemo", "ImPlot\nDemo", "ImGui\nMetrics", "ImCoolBar\nMetrics"}; 18 | static ImGui::ImCoolBarConfig _config; 19 | _config.normal_size = 35.0f; 20 | _config.hovered_size = 100.0f; 21 | _config.anchor = ImVec2(0.5f, 1.0f); 22 | 23 | if (ImGui::BeginCoolBar("CoolBarMainWin", ImCoolBarFlags_Horizontal, _config)) { 24 | for (size_t idx = 0U; idx < arr.size(); ++idx) { 25 | if (ImGui::CoolBarItem()) { 26 | const char* label = arr.at(idx); 27 | const float w = ImGui::GetCoolBarItemWidth(); 28 | const float s = ImGui::GetCoolBarItemScale(); 29 | ImGui::PushFont(nullptr, ref_font_scale * s); 30 | const auto ret = ImGui::Button(label, ImVec2(w * 2.0f, w)); 31 | ImGui::PopFont(); 32 | if (ret) { 33 | switch (idx) { 34 | case 0: show_imgui_demo = !show_imgui_demo; break; 35 | case 1: show_implot_demo = !show_implot_demo; break; 36 | case 2: show_imgui_metrics = !show_imgui_metrics; break; 37 | case 3: show_imcoolbar_metrics = !show_imcoolbar_metrics; break; 38 | } 39 | } 40 | } 41 | } 42 | ImGui::EndCoolBar(); 43 | } 44 | 45 | if (show_imgui_demo) { 46 | ImGui::ShowDemoWindow(&show_imgui_demo); 47 | } 48 | if (show_implot_demo) { 49 | ImPlot::ShowDemoWindow(&show_implot_demo); 50 | } 51 | if (show_imgui_metrics) { 52 | ImGui::ShowMetricsWindow(&show_imgui_metrics); 53 | } 54 | if (show_imcoolbar_metrics) { 55 | ImGui::ShowCoolBarMetrics(&show_imcoolbar_metrics); 56 | } 57 | ``` 58 | 59 | Result : 60 | 61 | ![alt text](https://github.com/aiekick/ImCoolBar/blob/DemoApp/doc/sample.gif) 62 | 63 | # Demo App 64 | 65 | ![alt text](https://github.com/aiekick/ImCoolBar/blob/DemoApp/doc/DemoApp.gif) 66 | -------------------------------------------------------------------------------- /ImCoolBar.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2024 Stephane Cuillerdier (aka Aiekick) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "imgui.h" 28 | 29 | //#define ENABLE_IMCOOLBAR_DEBUG 30 | 31 | typedef int ImCoolBarFlags; // 32 | enum ImCoolBarFlags_ { // 33 | ImCoolBarFlags_None = 0, // 34 | ImCoolBarFlags_Vertical = (1 << 0), // 35 | ImCoolBarFlags_Horizontal = (1 << 1), // 36 | }; 37 | 38 | namespace ImGui { 39 | 40 | struct ImCoolBarConfig { 41 | ImVec2 anchor = ImVec2(-1.0f, -1.0f); // 42 | float normal_size = 40.0f; // 43 | float hovered_size = 60.0f; // 44 | float anim_step = 0.15f; // 45 | float effect_strength = 0.5f; // 46 | ImCoolBarConfig( // 47 | const ImVec2 vAnchor = ImVec2(-1.0f, -1.0f), // 48 | const float& vNormalSize = 40.0f, // 49 | const float& vHoveredSize = 60.0f, // 50 | const float& vAnimStep = 0.15f, // 51 | const float& vEffectStrength = 0.5f) // 52 | : // 53 | anchor(vAnchor), // 54 | normal_size(vNormalSize), // 55 | hovered_size(vHoveredSize), // 56 | anim_step(vAnimStep), // 57 | effect_strength(vEffectStrength) // 58 | { 59 | } 60 | }; 61 | IMGUI_API bool BeginCoolBar(const char* vLabel, ImCoolBarFlags vCBFlags = ImCoolBarFlags_Vertical, const ImCoolBarConfig& vConfig = {}, ImGuiWindowFlags vFlags = ImGuiWindowFlags_None); 62 | IMGUI_API void EndCoolBar(); 63 | IMGUI_API bool CoolBarItem(); 64 | IMGUI_API float GetCoolBarItemWidth(); 65 | IMGUI_API float GetCoolBarItemScale(); 66 | IMGUI_API void ShowCoolBarMetrics(bool* vOpened); 67 | 68 | } // namespace ImGui 69 | -------------------------------------------------------------------------------- /ImCoolBar.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2023 Stephane Cuillerdier (aka Aiekick) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef IMGUI_DEFINE_MATH_OPERATORS 26 | #define IMGUI_DEFINE_MATH_OPERATORS 27 | #endif 28 | #include "ImCoolBar.h" 29 | #include "imgui_internal.h" 30 | #include 31 | #include 32 | #include 33 | 34 | #define ICB_PREFIX "ICB" 35 | 36 | #ifdef _MSC_VER 37 | #include 38 | #define ICB_DEBUG_BREAK \ 39 | if (IsDebuggerPresent()) \ 40 | __debugbreak() 41 | #else 42 | #define ICB_DEBUG_BREAK 43 | #endif 44 | 45 | #define BREAK_ON_KEY(KEY) \ 46 | if (ImGui::IsKeyPressed(KEY)) \ 47 | ICB_DEBUG_BREAK 48 | 49 | static float bubbleEffect(const float vValue, const float vStrength) { 50 | return pow(cos(vValue * IM_PI * vStrength), 8.0f); 51 | } 52 | 53 | static float getBarSize(const float vNormalSize, const float vHoveredSize, const float vScale) { 54 | return ImClamp(vNormalSize + (vHoveredSize - vNormalSize) * vScale, vNormalSize, vHoveredSize); 55 | } 56 | 57 | // https://codesandbox.io/s/motion-dock-forked-hs4p8d?file=/src/Dock.tsx 58 | static float getHoverSize(const float vValue, const float vNormalSize, const float vHoveredSize, const float vStength, const float vScale) { 59 | return getBarSize(vNormalSize, vHoveredSize, bubbleEffect(vValue, vStength) * vScale); 60 | } 61 | 62 | static bool isWindowHovered(ImGuiWindow* vWindow) { 63 | return ImGui::IsMouseHoveringRect(vWindow->Rect().Min, vWindow->Rect().Max); 64 | } 65 | 66 | static float getChannel(const ImVec2& vVec, const ImCoolBarFlags vCBFlags) { 67 | if (vCBFlags & ImCoolBarFlags_Horizontal) { 68 | return vVec.x; 69 | } 70 | return vVec.y; 71 | } 72 | 73 | static float getChannelInv(const ImVec2& vVec, const ImCoolBarFlags vCBFlags) { 74 | if (vCBFlags & ImCoolBarFlags_Horizontal) { 75 | return vVec.y; 76 | } 77 | return vVec.x; 78 | } 79 | 80 | IMGUI_API bool ImGui::BeginCoolBar(const char* vLabel, ImCoolBarFlags vCBFlags, const ImCoolBarConfig& vConfig, ImGuiWindowFlags vFlags) { 81 | ImGuiWindowFlags flags = // 82 | vFlags // 83 | | ImGuiWindowFlags_NoTitleBar // 84 | | ImGuiWindowFlags_NoScrollbar // 85 | | ImGuiWindowFlags_AlwaysAutoResize // 86 | | ImGuiWindowFlags_NoCollapse // 87 | | ImGuiWindowFlags_NoMove // 88 | | ImGuiWindowFlags_NoSavedSettings // 89 | | ImGuiWindowFlags_NoFocusOnAppearing // 90 | #ifndef ENABLE_IMCOOLBAR_DEBUG 91 | | ImGuiWindowFlags_NoBackground // 92 | #endif // 93 | #ifdef IMGUI_HAS_DOCK 94 | | ImGuiWindowFlags_DockNodeHost // 95 | | ImGuiWindowFlags_NoDocking // 96 | #endif 97 | ; 98 | bool res = ImGui::Begin(vLabel, nullptr, flags); 99 | if (!res) { 100 | ImGui::End(); 101 | } else { 102 | // Can be Horizontal or Vertical, not both 103 | const bool isVertical = (vCBFlags & ImCoolBarFlags_Vertical); 104 | const bool isHorizontal = (vCBFlags & ImCoolBarFlags_Horizontal); 105 | IM_ASSERT((isHorizontal && !isVertical) || (!isHorizontal && isVertical)); 106 | 107 | ImGuiWindow* pWindow = GetCurrentWindow(); 108 | pWindow->StateStorage.SetVoidPtr(pWindow->GetID(ICB_PREFIX "Type"), (void*)"ImCoolBar"); 109 | pWindow->StateStorage.SetInt(pWindow->GetID(ICB_PREFIX "ItemIdx"), 0); 110 | pWindow->StateStorage.SetInt(pWindow->GetID(ICB_PREFIX "Flags"), vCBFlags); 111 | const float anchor = ImClamp(getChannelInv(vConfig.anchor, vCBFlags), 0.0f, 1.0f); 112 | pWindow->StateStorage.SetFloat(pWindow->GetID(ICB_PREFIX "Anchor"), anchor); 113 | const auto normal_size_id = pWindow->GetID(ICB_PREFIX "NormalSize"); 114 | const auto hovered_size_id = pWindow->GetID(ICB_PREFIX "HoveredSize"); 115 | pWindow->StateStorage.SetFloat(normal_size_id, vConfig.normal_size); 116 | pWindow->StateStorage.SetFloat(hovered_size_id, vConfig.hovered_size); 117 | pWindow->StateStorage.SetFloat(pWindow->GetID(ICB_PREFIX "EffectStrength"), vConfig.effect_strength); 118 | 119 | const auto anim_scale_id = pWindow->GetID(ICB_PREFIX "AnimScale"); 120 | float anim_scale = pWindow->StateStorage.GetFloat(anim_scale_id); 121 | if (isWindowHovered(pWindow)) { 122 | if (anim_scale < 1.0f) { 123 | anim_scale += vConfig.anim_step; 124 | } 125 | } else { 126 | if (anim_scale > 0.0f) { 127 | anim_scale -= vConfig.anim_step; 128 | } 129 | } 130 | 131 | anim_scale = ImClamp(anim_scale, 0.0f, 1.0f); 132 | pWindow->StateStorage.SetFloat(anim_scale_id, anim_scale); 133 | 134 | // --- Position with predicted cross-axis size for THIS frame --- 135 | ImVec2 pad = ImGui::GetStyle().WindowPadding * 2.0f; 136 | ImVec2 bar_size = pWindow->ContentSize + pad; // along main axis ok 137 | const float normal_size = pWindow->StateStorage.GetFloat(normal_size_id); 138 | const float hovered_size = pWindow->StateStorage.GetFloat(hovered_size_id); 139 | const float cross = getBarSize(normal_size, hovered_size, anim_scale); 140 | if (isHorizontal) { 141 | bar_size.y = cross + pad.y; 142 | } else { 143 | bar_size.x = cross + pad.x; 144 | } 145 | 146 | const ImGuiViewport* pViewport = pWindow->Viewport; 147 | ImVec2 new_pos = ImFloor(pViewport->Pos + (pViewport->Size - bar_size) * vConfig.anchor); 148 | ImGui::SetWindowPos(new_pos); 149 | } 150 | 151 | return res; 152 | } 153 | 154 | IMGUI_API void ImGui::EndCoolBar() { 155 | ImGui::End(); 156 | } 157 | 158 | IMGUI_API bool ImGui::CoolBarItem() { 159 | ImGuiWindow* pWindow = GetCurrentWindow(); 160 | if (pWindow->SkipItems) { 161 | return false; 162 | } 163 | 164 | const auto item_index_id = pWindow->GetID(ICB_PREFIX "ItemIdx"); 165 | const auto idx = pWindow->StateStorage.GetInt(item_index_id); 166 | const auto coolbar_item_id = pWindow->GetID(pWindow->ID + idx + 1); 167 | float current_item_size = pWindow->StateStorage.GetFloat(coolbar_item_id); 168 | const auto flags = pWindow->StateStorage.GetInt(pWindow->GetID(ICB_PREFIX "Flags")); 169 | const auto anim_scale = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "AnimScale")); 170 | const auto normal_size = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "NormalSize")); 171 | const auto hovered_size = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "HoveredSize")); 172 | const auto effect_strength = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "EffectStrength")); 173 | const auto last_mouse_pos_id = pWindow->GetID(ICB_PREFIX "LastMousePos"); 174 | auto last_mouse_pos = pWindow->StateStorage.GetFloat(last_mouse_pos_id); 175 | 176 | assert(normal_size > 0.0f); 177 | 178 | if (flags & ImCoolBarFlags_Horizontal) { 179 | if (idx) { 180 | ImGui::SameLine(); 181 | } 182 | } 183 | ImGuiContext& g = *GImGui; 184 | 185 | if (isWindowHovered(pWindow)) { 186 | last_mouse_pos = getChannel(g.IO.MousePos, flags); 187 | } 188 | 189 | if (current_item_size <= 0.0f) { 190 | current_item_size = normal_size; 191 | } 192 | 193 | float current_size = normal_size; 194 | if (anim_scale > 0.0f) { 195 | const auto csp = getChannel(pWindow->DC.CursorPos, flags); 196 | const auto ws = getChannel(pWindow->Size, flags); 197 | const auto wp = getChannel(g.Style.WindowPadding, flags); 198 | const float btn_center = csp + current_item_size * 0.5f; 199 | const float diff_pos = (last_mouse_pos - btn_center) / ws; 200 | current_size = getHoverSize(diff_pos, normal_size, hovered_size, effect_strength, anim_scale); 201 | const float anchor = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "Anchor")); 202 | const float bar_height = getBarSize(normal_size, hovered_size, anim_scale); 203 | const float btn_offset = ImFloor((bar_height - current_size) * anchor + wp); 204 | if (flags & ImCoolBarFlags_Horizontal) { 205 | ImGui::SetCursorPosY(btn_offset); 206 | } else if (flags & ImCoolBarFlags_Vertical) { 207 | ImGui::SetCursorPosX(btn_offset); 208 | } 209 | } 210 | 211 | pWindow->StateStorage.SetInt(item_index_id, idx + 1); 212 | pWindow->StateStorage.SetFloat(coolbar_item_id, current_size); 213 | pWindow->StateStorage.SetFloat(last_mouse_pos_id, last_mouse_pos); 214 | pWindow->StateStorage.SetFloat(pWindow->GetID(ICB_PREFIX "ItemCurrentSize"), current_size); 215 | pWindow->StateStorage.SetFloat(pWindow->GetID(ICB_PREFIX "ItemCurrentScale"), current_size / normal_size); 216 | 217 | return true; 218 | } 219 | 220 | IMGUI_API float ImGui::GetCoolBarItemWidth() { 221 | ImGuiWindow* pWindow = GetCurrentWindow(); 222 | if (pWindow->SkipItems) { 223 | return 0.0f; 224 | } 225 | return pWindow->StateStorage.GetFloat( // 226 | pWindow->GetID(ICB_PREFIX "ItemCurrentSize")); 227 | } 228 | 229 | IMGUI_API float ImGui::GetCoolBarItemScale() { 230 | ImGuiWindow* pWindow = GetCurrentWindow(); 231 | if (pWindow->SkipItems) { 232 | return 0.0f; 233 | } 234 | return pWindow->StateStorage.GetFloat( // 235 | pWindow->GetID(ICB_PREFIX "ItemCurrentScale")); 236 | } 237 | 238 | IMGUI_API void ImGui::ShowCoolBarMetrics(bool* vOpened) { 239 | if (ImGui::Begin("ImCoolBar Metrics", vOpened)) { 240 | ImGuiContext& g = *GImGui; 241 | for (auto* pWindow : g.Windows) { 242 | const char* type = (const char*)pWindow->StateStorage.GetVoidPtr(pWindow->GetID(ICB_PREFIX "Type")); 243 | if (type != nullptr && strcmp(type, "ImCoolBar") == 0) { 244 | if (!TreeNode(pWindow, "ImCoolBar %s", pWindow->Name)) { 245 | continue; 246 | } 247 | 248 | const auto flags = pWindow->StateStorage.GetInt(pWindow->GetID(ICB_PREFIX "Flags")); 249 | const auto anchor = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "Anchor")); 250 | const auto max_idx = pWindow->StateStorage.GetInt(pWindow->GetID(ICB_PREFIX "ItemIdx")); 251 | const auto anim_scale = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "AnimScale")); 252 | const auto normal_size = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "NormalSize")); 253 | const auto hovered_size = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "HoveredSize")); 254 | const auto effect_strength = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "EffectStrength")); 255 | const auto item_last_size = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "ItemCurrentSize")); 256 | const auto item_last_scale = pWindow->StateStorage.GetFloat(pWindow->GetID(ICB_PREFIX "ItemCurrentScale")); 257 | 258 | #define SetColumnLabel(a, fmt, v) \ 259 | ImGui::TableNextColumn(); \ 260 | ImGui::Text("%s", a); \ 261 | ImGui::TableNextColumn(); \ 262 | ImGui::Text(fmt, v); \ 263 | ImGui::TableNextRow() 264 | 265 | if (ImGui::BeginTable("CoolbarDebugDatas", 2)) { 266 | ImGui::TableSetupScrollFreeze(0, 1); 267 | ImGui::TableSetupColumn("Label", ImGuiTableColumnFlags_WidthFixed); 268 | ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch); 269 | ImGui::TableHeadersRow(); 270 | 271 | SetColumnLabel("MaxIdx ", "%i", max_idx); 272 | SetColumnLabel("Anchor ", "%f", anchor); 273 | SetColumnLabel("AnimScale ", "%f", anim_scale); 274 | SetColumnLabel("NormalSize ", "%f", normal_size); 275 | SetColumnLabel("HoveredSize ", "%f", hovered_size); 276 | SetColumnLabel("EffectStrength ", "%f", effect_strength); 277 | SetColumnLabel("ItemLastSize ", "%f", item_last_size); 278 | SetColumnLabel("ItemLastScale ", "%f", item_last_scale); 279 | 280 | ImGui::TableNextColumn(); 281 | ImGui::Text("%s", "Flags "); 282 | ImGui::TableNextColumn(); 283 | if (flags & ImCoolBarFlags_None) { 284 | ImGui::Text("None"); 285 | } 286 | if (flags & ImCoolBarFlags_Vertical) { 287 | ImGui::Text("Vertical"); 288 | } 289 | if (flags & ImCoolBarFlags_Horizontal) { 290 | ImGui::Text("Horizontal"); 291 | } 292 | ImGui::TableNextRow(); 293 | 294 | for (int idx = 0; idx < max_idx; ++idx) { 295 | const auto coolbar_item_id = pWindow->GetID(pWindow->ID + idx + 1); 296 | const auto current_item_size = pWindow->StateStorage.GetFloat(coolbar_item_id); 297 | ImGui::TableNextColumn(); 298 | ImGui::Text("Item %i Size ", idx); 299 | ImGui::TableNextColumn(); 300 | ImGui::Text("%f", current_item_size); 301 | ImGui::TableNextRow(); 302 | } 303 | 304 | ImGui::EndTable(); 305 | } 306 | 307 | #undef SetColumnLabel 308 | TreePop(); 309 | } 310 | } 311 | } 312 | ImGui::End(); 313 | } 314 | --------------------------------------------------------------------------------