├── CMakeLists.txt ├── ImCoolBar.cpp ├── ImCoolBar.h ├── LICENSE └── README.md /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(ImCoolBar CXX) 4 | 5 | file(GLOB PROJECT_MAIN 6 | ${CMAKE_CURRENT_SOURCE_DIR}/*.h 7 | ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) 8 | source_group(src FILES ${PROJECT_MAIN}) 9 | 10 | add_library(ImCoolBar ${PROJECT_MAIN}) 11 | 12 | set(IMCOOLBAR_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE) 13 | set(IMCOOLBAR_LIBRARIES ImCoolBar PARENT_SCOPE) 14 | set(IMCOOLBAR_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) 15 | -------------------------------------------------------------------------------- /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 | //#define ENABLE_IMCOOLBAR_DEBUG 36 | 37 | #ifdef _MSC_VER 38 | #include 39 | #define ICB_DEBUG_BREAK \ 40 | if (IsDebuggerPresent()) \ 41 | __debugbreak() 42 | #else 43 | #define ICB_DEBUG_BREAK 44 | #endif 45 | 46 | #define BREAK_ON_KEY(KEY) \ 47 | if (ImGui::IsKeyPressed(KEY)) \ 48 | ICB_DEBUG_BREAK 49 | 50 | static float bubbleEffect(const float vValue, const float vStength) { 51 | return pow(cos(vValue * IM_PI * vStength), 12.0f); 52 | } 53 | 54 | // https://codesandbox.io/s/motion-dock-forked-hs4p8d?file=/src/Dock.tsx 55 | static float getHoverSize(const float vValue, const float vNormalSize, const float vHoveredSize, const float vStength, const float vScale) { 56 | return ImClamp(vNormalSize + (vHoveredSize - vNormalSize) * bubbleEffect(vValue, vStength) * vScale, vNormalSize, vHoveredSize); 57 | } 58 | 59 | static bool isWindowHovered(ImGuiWindow* vWindow) { 60 | return ImGui::IsMouseHoveringRect(vWindow->Rect().Min, vWindow->Rect().Max); 61 | } 62 | 63 | static float getBarSize(ImGuiWindow* vWindow, const float vNormalSize, const float vHoveredSize, const float vScale) { 64 | ImGuiContext& g = *GImGui; 65 | return vNormalSize + vHoveredSize * vScale; 66 | } 67 | 68 | static float getChannel(const ImVec2& vVec, const ImCoolBarFlags vCBFlags) { 69 | if (vCBFlags & ImCoolBarFlags_Horizontal) { 70 | return vVec.x; 71 | } 72 | return vVec.y; 73 | } 74 | 75 | static float getChannelInv(const ImVec2& vVec, const ImCoolBarFlags vCBFlags) { 76 | if (vCBFlags & ImCoolBarFlags_Horizontal) { 77 | return vVec.y; 78 | } 79 | return vVec.x; 80 | } 81 | 82 | IMGUI_API bool ImGui::BeginCoolBar(const char* vLabel, ImCoolBarFlags vCBFlags, const ImCoolBarConfig& vConfig, ImGuiWindowFlags vFlags) { 83 | ImGuiWindowFlags flags = // 84 | vFlags | // 85 | ImGuiWindowFlags_NoTitleBar | // 86 | ImGuiWindowFlags_NoScrollbar | // 87 | ImGuiWindowFlags_AlwaysAutoResize | // 88 | ImGuiWindowFlags_NoCollapse | // 89 | ImGuiWindowFlags_NoMove | // 90 | ImGuiWindowFlags_NoSavedSettings | // 91 | #ifndef ENABLE_IMCOOLBAR_DEBUG // 92 | ImGuiWindowFlags_NoBackground | // 93 | #endif // 94 | ImGuiWindowFlags_NoFocusOnAppearing | // 95 | ImGuiWindowFlags_DockNodeHost | // 96 | ImGuiWindowFlags_NoDocking; // 97 | bool res = ImGui::Begin(vLabel, nullptr, flags); 98 | if (!res) { 99 | ImGui::End(); 100 | } else { 101 | // Can be Horizontal or Vertical, not both 102 | // this working atm, just because we have only H or V flags 103 | IM_ASSERT( // 104 | ((vCBFlags & ImCoolBarFlags_Horizontal) == ImCoolBarFlags_Horizontal) || // 105 | ((vCBFlags & ImCoolBarFlags_Vertical) == ImCoolBarFlags_Vertical) // 106 | ); 107 | 108 | ImGuiContext& g = *GImGui; 109 | ImGuiWindow* window_ptr = GetCurrentWindow(); 110 | window_ptr->StateStorage.SetVoidPtr(window_ptr->GetID(ICB_PREFIX "Type"), (void*)"ImCoolBar"); 111 | window_ptr->StateStorage.SetInt(window_ptr->GetID(ICB_PREFIX "ItemIdx"), 0); 112 | window_ptr->StateStorage.SetInt(window_ptr->GetID(ICB_PREFIX "Flags"), vCBFlags); 113 | window_ptr->StateStorage.SetFloat(window_ptr->GetID(ICB_PREFIX "Anchor"), getChannelInv(vConfig.anchor, vCBFlags)); 114 | window_ptr->StateStorage.SetFloat(window_ptr->GetID(ICB_PREFIX "NormalSize"), vConfig.normal_size); 115 | window_ptr->StateStorage.SetFloat(window_ptr->GetID(ICB_PREFIX "HoveredSize"), vConfig.hovered_size); 116 | window_ptr->StateStorage.SetFloat(window_ptr->GetID(ICB_PREFIX "EffectStrength"), vConfig.effect_strength); 117 | 118 | const auto bar_size = window_ptr->ContentSize + ImGui::GetStyle().WindowPadding * 2.0f; 119 | const auto viewport_ptr = window_ptr->Viewport; 120 | const auto new_pos = viewport_ptr->Pos + (viewport_ptr->Size - bar_size) * vConfig.anchor; 121 | ImGui::SetWindowPos(new_pos); 122 | 123 | const auto anim_scale_id = window_ptr->GetID(ICB_PREFIX "AnimScale"); 124 | float anim_scale = window_ptr->StateStorage.GetFloat(anim_scale_id); 125 | if (isWindowHovered(window_ptr)) { 126 | if (anim_scale < 1.0f) { 127 | anim_scale += vConfig.anim_step; 128 | } 129 | } else { 130 | if (anim_scale > 0.0f) { 131 | anim_scale -= vConfig.anim_step; 132 | } 133 | } 134 | window_ptr->StateStorage.SetFloat(anim_scale_id, ImClamp(anim_scale, 0.0f, 1.0f)); 135 | } 136 | 137 | return res; 138 | } 139 | 140 | IMGUI_API void ImGui::EndCoolBar() { 141 | ImGui::End(); 142 | } 143 | 144 | IMGUI_API bool ImGui::CoolBarItem() { 145 | ImGuiWindow* window_ptr = GetCurrentWindow(); 146 | if (window_ptr->SkipItems) 147 | return false; 148 | 149 | const auto item_index_id = window_ptr->GetID(ICB_PREFIX "ItemIdx"); 150 | const auto idx = window_ptr->StateStorage.GetInt(item_index_id); 151 | const auto coolbar_item_id = window_ptr->GetID(window_ptr->ID + idx + 1); 152 | const auto current_item_size = window_ptr->StateStorage.GetFloat(coolbar_item_id); 153 | const auto flags = window_ptr->StateStorage.GetInt(window_ptr->GetID(ICB_PREFIX "Flags")); 154 | const auto anim_scale = window_ptr->StateStorage.GetFloat(window_ptr->GetID(ICB_PREFIX "AnimScale")); 155 | const auto normal_size = window_ptr->StateStorage.GetFloat(window_ptr->GetID(ICB_PREFIX "NormalSize")); 156 | const auto hovered_size = window_ptr->StateStorage.GetFloat(window_ptr->GetID(ICB_PREFIX "HoveredSize")); 157 | const auto effect_strength = window_ptr->StateStorage.GetFloat(window_ptr->GetID(ICB_PREFIX "EffectStrength")); 158 | const auto last_mouse_pos_id = window_ptr->GetID(ICB_PREFIX "LastMousePos"); 159 | auto last_mouse_pos = window_ptr->StateStorage.GetFloat(last_mouse_pos_id); 160 | 161 | assert(normal_size > 0.0f); 162 | 163 | if (flags & ImCoolBarFlags_Horizontal) { 164 | if (idx) { 165 | ImGui::SameLine(); 166 | } 167 | } 168 | 169 | float current_size = normal_size; 170 | ImGuiContext& g = *GImGui; 171 | 172 | if (isWindowHovered(window_ptr)) { 173 | last_mouse_pos = getChannel(ImGui::GetMousePos(), flags); 174 | } 175 | 176 | if (anim_scale > 0.0f) { 177 | const auto csp = getChannel(ImGui::GetCursorScreenPos(), flags); 178 | const auto ws = getChannel(window_ptr->Size, flags); 179 | const auto wp = getChannel(g.Style.WindowPadding, flags); 180 | const float btn_center = csp + current_item_size * 0.5f; 181 | const float diff_pos = (last_mouse_pos - btn_center) / ws; 182 | current_size = getHoverSize(diff_pos, normal_size, hovered_size, effect_strength, anim_scale); 183 | const float anchor = window_ptr->StateStorage.GetFloat(window_ptr->GetID(ICB_PREFIX "Anchor")); 184 | const float bar_height = getBarSize(window_ptr, normal_size, hovered_size, anim_scale); 185 | float btn_offset = (bar_height - current_size) * anchor + wp; 186 | if (flags & ImCoolBarFlags_Horizontal) { 187 | ImGui::SetCursorPosY(btn_offset); 188 | } else if (flags & ImCoolBarFlags_Vertical) { 189 | ImGui::SetCursorPosX(btn_offset); 190 | } 191 | } 192 | 193 | BREAK_ON_KEY(ImGuiKey_D); 194 | window_ptr->StateStorage.SetInt(item_index_id, idx + 1); 195 | window_ptr->StateStorage.SetFloat(coolbar_item_id, current_size); 196 | window_ptr->StateStorage.SetFloat(last_mouse_pos_id, last_mouse_pos); 197 | window_ptr->StateStorage.SetFloat(window_ptr->GetID(ICB_PREFIX "ItemCurrentSize"), current_size); 198 | window_ptr->StateStorage.SetFloat(window_ptr->GetID(ICB_PREFIX "ItemCurrentScale"), current_size / normal_size); 199 | 200 | return true; 201 | } 202 | 203 | IMGUI_API float ImGui::GetCoolBarItemWidth() { 204 | ImGuiWindow* window_ptr = GetCurrentWindow(); 205 | if (window_ptr->SkipItems) { 206 | return 0.0f; 207 | } 208 | return window_ptr->StateStorage.GetFloat( // 209 | window_ptr->GetID(ICB_PREFIX "ItemCurrentSize")); 210 | } 211 | 212 | IMGUI_API float ImGui::GetCoolBarItemScale() { 213 | ImGuiWindow* window_ptr = GetCurrentWindow(); 214 | if (window_ptr->SkipItems) { 215 | return 0.0f; 216 | } 217 | 218 | return window_ptr->StateStorage.GetFloat( // 219 | window_ptr->GetID(ICB_PREFIX "ItemCurrentScale")); 220 | } 221 | 222 | IMGUI_API void ImGui::ShowCoolBarMetrics(bool* vOpened) { 223 | if (ImGui::Begin("ImCoolBar Metrics", vOpened)) { 224 | ImGuiContext& g = *GImGui; 225 | for (auto* window_ptr : g.Windows) { 226 | const char* type = (const char*)window_ptr->StateStorage.GetVoidPtr(window_ptr->GetID(ICB_PREFIX "Type")); 227 | if (type != nullptr && strcmp(type, "ImCoolBar") == 0) { 228 | if (!TreeNode(window_ptr, "ImCoolBar %s", window_ptr->Name)) { 229 | continue; 230 | } 231 | 232 | const auto flags_id = window_ptr->GetID(ICB_PREFIX "Flags"); 233 | const auto anchor_id = window_ptr->GetID(ICB_PREFIX "Anchor"); 234 | const auto anim_scale_id = window_ptr->GetID(ICB_PREFIX "AnimScale"); 235 | const auto item_index_id = window_ptr->GetID(ICB_PREFIX "ItemIdx"); 236 | const auto normal_size_id = window_ptr->GetID(ICB_PREFIX "NormalSize"); 237 | const auto hovered_size_id = window_ptr->GetID(ICB_PREFIX "HoveredSize"); 238 | const auto effect_strength_id = window_ptr->GetID(ICB_PREFIX "EffectStrength"); 239 | const auto item_current_size_id = window_ptr->GetID(ICB_PREFIX "ItemCurrentSize"); 240 | const auto item_current_scale_id = window_ptr->GetID(ICB_PREFIX "ItemCurrentScale"); 241 | 242 | const auto flags = window_ptr->StateStorage.GetInt(flags_id); 243 | const auto anchor = window_ptr->StateStorage.GetFloat(anchor_id); 244 | const auto max_idx = window_ptr->StateStorage.GetInt(item_index_id); 245 | const auto anim_scale = window_ptr->StateStorage.GetFloat(anim_scale_id); 246 | const auto normal_size = window_ptr->StateStorage.GetFloat(normal_size_id); 247 | const auto hovered_size = window_ptr->StateStorage.GetFloat(hovered_size_id); 248 | const auto effect_strength = window_ptr->StateStorage.GetFloat(effect_strength_id); 249 | const auto item_current_size = window_ptr->StateStorage.GetFloat(item_current_size_id); 250 | const auto item_current_scale = window_ptr->StateStorage.GetFloat(item_current_scale_id); 251 | 252 | #define SetColumnLabel(a, fmt, v) \ 253 | ImGui::TableNextColumn(); \ 254 | ImGui::Text("%s", a); \ 255 | ImGui::TableNextColumn(); \ 256 | ImGui::Text(fmt, v); \ 257 | ImGui::TableNextRow() 258 | 259 | if (ImGui::BeginTable("CoolbarDebugDatas", 2)) { 260 | ImGui::TableSetupScrollFreeze(0, 1); 261 | ImGui::TableSetupColumn("Label", ImGuiTableColumnFlags_WidthFixed); 262 | ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch); 263 | ImGui::TableHeadersRow(); 264 | 265 | SetColumnLabel("MaxIdx ", "%i", max_idx); 266 | SetColumnLabel("Anchor ", "%f", anchor); 267 | SetColumnLabel("AnimScale ", "%f", anim_scale); 268 | SetColumnLabel("NormalSize ", "%f", normal_size); 269 | SetColumnLabel("HoveredSize ", "%f", hovered_size); 270 | SetColumnLabel("EffectStrength ", "%f", effect_strength); 271 | SetColumnLabel("ItemCurrentSize ", "%f", item_current_size); 272 | SetColumnLabel("ItemCurrentScale ", "%f", item_current_scale); 273 | 274 | ImGui::TableNextColumn(); 275 | ImGui::Text("%s", "Flags "); 276 | ImGui::TableNextColumn(); 277 | if (flags & ImCoolBarFlags_None) { 278 | ImGui::Text("None"); 279 | } 280 | if (flags & ImCoolBarFlags_Vertical) { 281 | ImGui::Text("Vertical"); 282 | } 283 | if (flags & ImCoolBarFlags_Horizontal) { 284 | ImGui::Text("Horizontal"); 285 | } 286 | ImGui::TableNextRow(); 287 | 288 | for (int idx = 0; idx < max_idx; ++idx) { 289 | const auto coolbar_item_id = window_ptr->GetID(window_ptr->ID + idx + 1); 290 | const auto current_item_size = window_ptr->StateStorage.GetFloat(coolbar_item_id); 291 | ImGui::TableNextColumn(); 292 | ImGui::Text("Item %i Size ", idx); 293 | ImGui::TableNextColumn(); 294 | ImGui::Text("%f", current_item_size); 295 | ImGui::TableNextRow(); 296 | } 297 | 298 | ImGui::EndTable(); 299 | } 300 | 301 | #undef SetColumnLabel 302 | TreePop(); 303 | } 304 | } 305 | } 306 | ImGui::End(); 307 | } 308 | -------------------------------------------------------------------------------- /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 | typedef int ImCoolBarFlags; // 30 | enum ImCoolBarFlags_ { // 31 | ImCoolBarFlags_None = 0, // 32 | ImCoolBarFlags_Vertical = (1 << 0), // 33 | ImCoolBarFlags_Horizontal = (1 << 1), // 34 | }; 35 | 36 | namespace ImGui { 37 | 38 | struct ImCoolBarConfig { 39 | ImVec2 anchor = ImVec2(-1.0f, -1.0f); // 40 | float normal_size = 40.0f; // 41 | float hovered_size = 60.0f; // 42 | float anim_step = 0.15f; // 43 | float effect_strength = 0.5f; // 44 | ImCoolBarConfig( // 45 | const ImVec2 vAnchor = ImVec2(-1.0f, -1.0f), // 46 | const float& vNormalSize = 40.0f, // 47 | const float& vHoveredSize = 60.0f, // 48 | const float& vAnimStep = 0.15f, // 49 | const float& vEffectStrength = 0.5f) // 50 | : // 51 | anchor(vAnchor), // 52 | normal_size(vNormalSize), // 53 | hovered_size(vHoveredSize), // 54 | anim_step(vAnimStep), // 55 | effect_strength(vEffectStrength) // 56 | { 57 | } 58 | }; 59 | IMGUI_API bool BeginCoolBar(const char* vLabel, ImCoolBarFlags vCBFlags = ImCoolBarFlags_Vertical, const ImCoolBarConfig& vConfig = {}, ImGuiWindowFlags vFlags = ImGuiWindowFlags_None); 60 | IMGUI_API void EndCoolBar(); 61 | IMGUI_API bool CoolBarItem(); 62 | IMGUI_API float GetCoolBarItemWidth(); 63 | IMGUI_API float GetCoolBarItemScale(); 64 | IMGUI_API void ShowCoolBarMetrics(bool* vOpened); 65 | 66 | } // namespace ImGui 67 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | auto coolbar_button = [](const char* label) -> bool { 11 | float w = ImGui::GetCoolBarItemWidth(); 12 | auto font_ptr = ImGui::GetIO().Fonts->Fonts[0]; 13 | font_ptr->Scale = ImGui::GetCoolBarItemScale(); 14 | ImGui::PushFont(font_ptr); 15 | bool res = ImGui::Button(label, ImVec2(w, w)); 16 | ImGui::PopFont(); 17 | return res; 18 | }; 19 | 20 | if (ImGui::BeginCoolBar("##CoolBarMain", ImCoolBar_Horizontal, ImVec2(0.5f, 1.0f))) { 21 | if (ImGui::CoolBarItem()) { 22 | if (coolbar_button("A")) { 23 | 24 | } 25 | } 26 | if (ImGui::CoolBarItem()) { 27 | if (coolbar_button("B")) { 28 | 29 | } 30 | } 31 | if (ImGui::CoolBarItem()) { 32 | if (coolbar_button("C")) { 33 | 34 | } 35 | } 36 | if (ImGui::CoolBarItem()) { 37 | if (coolbar_button("D")) { 38 | 39 | } 40 | } 41 | if (ImGui::CoolBarItem()) { 42 | if (coolbar_button("E")) { 43 | 44 | } 45 | } 46 | if (ImGui::CoolBarItem()) { 47 | if (coolbar_button("F")) { 48 | 49 | } 50 | } 51 | if (ImGui::CoolBarItem()) { 52 | if (coolbar_button("G")) { 53 | 54 | } 55 | } 56 | if (ImGui::CoolBarItem()) { 57 | if (coolbar_button("H")) { 58 | 59 | } 60 | } 61 | if (ImGui::CoolBarItem()) { 62 | if (coolbar_button("I")) { 63 | 64 | } 65 | } 66 | if (ImGui::CoolBarItem()) { 67 | if (coolbar_button("J")) { 68 | 69 | } 70 | } 71 | if (ImGui::CoolBarItem()) { 72 | if (coolbar_button("K")) { 73 | 74 | } 75 | } 76 | if (ImGui::CoolBarItem()) { 77 | if (coolbar_button("L")) { 78 | 79 | } 80 | } 81 | if (ImGui::CoolBarItem()) { 82 | if (coolbar_button("M")) { 83 | 84 | } 85 | } 86 | ImGui::EndCoolBar(); 87 | } 88 | ``` 89 | 90 | Result : 91 | 92 | ![alt text](https://github.com/aiekick/ImCoolBar/blob/DemoApp/doc/minimal_code.gif) 93 | 94 | # Demo App 95 | 96 | ![alt text](https://github.com/aiekick/ImCoolBar/blob/DemoApp/doc/DemoApp.gif) 97 | --------------------------------------------------------------------------------