forked from scottmudge/imgui_tabs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
imgui_tabs.h
232 lines (186 loc) · 9.88 KB
/
imgui_tabs.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/* **************************************************************************************
* Author: Scott Mudge
* MAIL@SCOTTMUDGE.COM
*
* MIT License
* -----------
* MAIL@SCOTTMUDGE.COM
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* **************************************************************************************/
// File Name: imgui_tabs.cpp
// File Description: Custom ImGui tab system module added by me (Scott)
/*
* Usage:
* * To start a tab bar, use: ImGui::BeginTabBar(const char* label)
* -> The label can be blank if you want, but you MUST!! pass a string of some length. Use the '#' character to
* give it an ID without a label.
*
* * Add tabs by using:
* if (ImGui::AddTab("Tab Name")){
* < Insert other draw commands here >
* }
* -> This is much like collapsing header. If the tab is active, then AddTab will return true, allowing drawing
* to occur.
*
* * End the tab bar by using ImGui::EndTabBar()
*
* And that's it! You can dynamically add or remove tabs, the bar will reset the ID and tab label vectors appropriately,
* but it DOESN'T continuously allocate/deallocate them in memory every time (unless the CRC32 hashes of the tab or tab bar change,
* computed from their respective labels).
*
* Notes:
* * You can change the rounding by altering:
* "static constexpr const float rounding = 6.0f;"
* in the _drawTabBarTop function. Alternatively, you can add it as a parameter, but to save on memory being passed
* around, and since I will be using 6 as a constant, I didn't include this.
*
* * The constexpr:
* "static constexpr const float shrink = 1.0f;"
* in the _drawTabBarTop function needs to be set to the width of your borders.
*
* * I added custom colors and a new prototype for GetColorU32() to acquire these colors. You can change them here.
*
* * I added extra operator functions for ImVec2 and ImVec4, _YOU MUST_ define IMGUI_DEFINE_MATH_OPERATORS in
* imgui_internal.h for this to work.
*
* * Please attribute my work if used or added, along with the original ImGui license/attribution.
*/
#ifndef IMGUI_TABS_HPP
#define IMGUI_TABS_HPP
#include <vector>
#include "imgui.h"
#include "imgui_internal.h"
// Extra Math Helpers (Set the proper define below in imgui_internal.h)
#ifdef IMGUI_DEFINE_MATH_OPERATORS
static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x+rhs.x, lhs.y+rhs.y, lhs.z+rhs.z, lhs.w+rhs.w); }
static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x*rhs.x, lhs.y*rhs.y, lhs.z*rhs.z, lhs.w*rhs.w); }
static inline ImVec4 operator/(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x/rhs.x, lhs.y/rhs.y, lhs.z/rhs.z, lhs.w/rhs.w); }
static inline ImVec4& operator+=(ImVec4& lhs, const ImVec4& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; lhs.z += rhs.z; lhs.w += rhs.w; return lhs;}
static inline ImVec4& operator-=(ImVec4& lhs, const ImVec4& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; lhs.z -= rhs.z; lhs.w -= rhs.w; return lhs;}
static inline ImVec4& operator*=(ImVec4& lhs, const ImVec4& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; lhs.z *= rhs.z; lhs.w *= rhs.w; return lhs;}
static inline ImVec4& operator/=(ImVec4& lhs, const ImVec4& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; lhs.z /= rhs.z; lhs.w /= rhs.w; return lhs;}
#endif
namespace ImGui
{
/// User Colors & Style Extensions
enum ImGuiUserCol_ {
ImGuiUserCol_TabBorder = 0,
ImGuiUserCol_TabBorderShadow,
ImGuiUserCol_TabNormal,
ImGuiUserCol_TabHover,
ImGuiUserCol_TabTitleTextNormal,
ImGuiUserCol_TabTitleTextSelected,
ImGuiUserCol_COUNT
};
/// Defines our user style attributes that don't fit within the standard ImGui stack
IMGUI_API struct ImGuiUserStyle
{
ImVec4 Colors[ImGuiUserCol_COUNT];
ImGuiUserStyle();
};
IMGUI_API static ImGuiUserStyle UserStyle;
/// Additional prototype to retrieve user-defined colors in this header (to prevent foward compatilibity conflicts)
IMGUI_API const ImU32 GetColorU32(ImGuiUserCol_ idx, float alpha_mul = 0.0f);
///Bitmask flags for telling _drawPartialRect() what edges to draw
enum _EdgeType : char {
EDGE_NONE = 0,
EDGE_LEFT = 1 << 0,
EDGE_TOP = 1 << 1,
EDGE_RIGHT = 1 << 2,
EDGE_BOTTOM = 1 << 3
};
/// Used internally to draw a rounded rect with the different borders disabled
static void _drawPartialRect(const ImVec2 a, const ImVec2 b, const float rounding, const int rounding_corners,
ImDrawList* dl, const _EdgeType edges, const ImU32 color, const bool shadow = false,
const _EdgeType shadow_edges = EDGE_NONE, const float shadow_offset = 4.0f,
const float shadow_alpha = 0.075f);
/// Struct containing TabBar data
IMGUI_API struct TabBar{
/// Constructor
TabBar(const char* label, const ImVec2 tab_bar_size);
/// Stores the titles of the tabs
std::vector<const char*> tabTitles;
/// Stores hash IDs of the tabs
std::vector<ImGuiID> tabHashes;
/// Keeps a tally of how many tabs have been added
int tabCount = 0; // Set to 0 in StartTab
/// Index defining the active tab
int activeTab = 0;
/// Title of the bar. Use #<ID> to omit the title but pass in an ID
std::string barTitle;
/// Size
ImVec2 size = ImVec2(0,0);
/// Hash of the TabBar
ImU32 hash = 0x0;
/// Index counter, cleared every call to "BeginTabBar"
int idxCounter = 0;
/// This holds the upper left corner for the final draw sequence
ImVec2 upperLeft = ImVec2(0,0);
/// Set to true once the tab bar has been initialized
bool hasBeenInitialized = false;
/// Holds the rounding value for padding reasons
float corner_rounding = 0;
/// Holds the value of the new selected tab
int newSelected = -1;
/// Sets the active tab
void setActiveTab(const unsigned idx);
/// Returns the currently active tab
const int getActiveTab();
/// Useful enums
enum _TabType : char {LEFTMOST_TAB, MIDDLE_TAB, RIGHTMOST_TAB};
/// Used internally
void _drawTabBarTop(const char* label);
void _drawTabBarBottom();
/// Used internally
void _setTabCount();
};
/// Struct containing global TabBar status
IMGUI_API struct TabBarStack{
/// Vector containing all of our tab bars
std::vector <TabBar> TabBars;
/// The running count of our tab bar. Useful as it's only written to when a new tab bar is generated. Helps prevent useless calls to std::vector<>::size()
unsigned TabBarCount = 0;
/// Index pointing to the current tab
unsigned CurrentTabBar = 0;
/// Returns a pointer to the current tab bar
TabBar* getCurrentTabBar();
/// Clears the counting index for the current tab bar
void clearIdxCountCurrentTabBar();
/// Returns true if the tab bar already exists, pass idx if you want a return index value
const bool doesTabBarExist(const ImU32 hash, unsigned* const idx = NULL);
/// Returns true if the tab bar already exists (computes hash), pass idx if you want a return index value
const bool doesTabBarExist(const char* id, unsigned* const idx = NULL);
};
/// Static instantiation of the TabBarStack
IMGUI_API static TabBarStack TabStack;
// FIXME : unused ?
/// Outwardly accessible way to set the active tab of the current stack.
// IMGUI_API static void SetActiveTabOfCurrentTabBar(const unsigned idx);
/// Star the Tab Bar with this function. It creates a tab bar based on the computed CRC32 hash and pushes it into the internal stack if so.
IMGUI_API void BeginTabBar(const char *label, const ImVec2 size = ImVec2(0, 0));
/// Returns true when the tab is active. To use, implement with if(ImGui::AddTab(...)){}
IMGUI_API const bool AddTab(const char* title);
/// To use, implement with if(ImGui::DrawTabsBackground(...)){} just after ImGui::BeginTabBar();
IMGUI_API void DrawTabsBackground();
/// Call this after you are done adding tabs
IMGUI_API void EndTabBar();
} // namespace ImGui
#endif //IMGUI_TABS_HPP