Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
ImGuiExtensions.cpp
Go to the documentation of this file.
1
2
5
6#include <imgui_internal.h>
7
8namespace ImGui {
9 bool ToggleButton(const char* str_id, bool* v)
10 {
11 bool ret = false;
12 const ImVec4* colours = ImGui::GetStyle().Colors;
13 const ImVec2 p = GetCursorScreenPos();
14 ImDrawList* draw_list = GetWindowDrawList();
15
16 const float height = GetFrameHeight();
17 const float width = height * 1.55f;
18 const float radius = height * 0.50f;
19
20 if (InvisibleButton(str_id, ImVec2(width, height))) {
21 ret = true;
22 *v = !*v;
23 }
24
25 if (ImGui::IsItemHovered()) {
26 draw_list->AddRectFilled(p, ImVec2(p.x + width, p.y + height), ImGui::GetColorU32(*v ? Divide::Util::ColoursHovered[1] : Divide::Util::ColoursHovered[0]), height * 0.5f);
27 draw_list->AddCircleFilled(ImVec2(p.x + radius + (*v ? 1 : 0) * (width - radius * 2.0f), p.y + radius), radius - 1.5f, ImGui::GetColorU32(colours[ImGuiCol_ButtonHovered]));
28 } else {
29 draw_list->AddRectFilled(p, ImVec2(p.x + width, p.y + height), ImGui::GetColorU32(*v ? Divide::Util::Colours[1] : Divide::Util::Colours[0]), height * 0.50f);
30 draw_list->AddCircleFilled(ImVec2(p.x + radius + (*v ? 1 : 0) * (width - radius * 2.0f), p.y + radius), radius - 1.5f, ImGui::GetColorU32(colours[ImGuiCol_ButtonActive]));
31 }
32
33 return ret;
34 }
35
36 // ref:https://github.com/Flix01/imgui
37
38 // This software is provided 'as-is', without any express or implied
39 // warranty. In no event will the authors be held liable for any damages
40 // arising from the use of this software.
41 // Permission is granted to anyone to use this software for any purpose,
42 // including commercial applications, and to alter it and redistribute it
43 // freely, subject to the following restrictions:
44 // 1. The origin of this software must not be misrepresented; you must not
45 // claim that you wrote the original software. If you use this software
46 // in a product, an acknowledgment in the product documentation would be
47 // appreciated but is not required.
48 // 2. Altered source versions must be plainly marked as such, and must not be
49 // misrepresented as being the original software.
50 // 3. This notice may not be removed or altered from any source distribution.
51
52 /*
53 inline ImVec2 mouseToPdfRelativeCoords(const ImVec2 &mp) const {
54 return ImVec2((mp.x+cursorPosAtStart.x-startPos.x)*(uv1.x-uv0.x)/zoomedImageSize.x+uv0.x,
55 (mp.y+cursorPosAtStart.y-startPos.y)*(uv1.y-uv0.y)/zoomedImageSize.y+uv0.y);
56 }
57 inline ImVec2 pdfRelativeToMouseCoords(const ImVec2 &mp) const {
58 return ImVec2((mp.x-uv0.x)*(zoomedImageSize.x)/(uv1.x-uv0.x)+startPos.x-cursorPosAtStart.x,(mp.y-uv0.y)*(zoomedImageSize.y)/(uv1.y-uv0.y)+startPos.y-cursorPosAtStart.y);
59 }
60 */
61 bool ImageZoomAndPan(ImTextureID user_texture_id, const ImVec2& size, float aspectRatio, float& zoom, ImVec2& zoomCenter, int panMouseButtonDrag, int resetZoomAndPanMouseButton, const ImVec2& zoomMaxAndZoomStep)
62 {
63 bool rv = false;
64 ImGuiWindow* window = GetCurrentWindow();
65 if (!window || window->SkipItems) return rv;
66 ImVec2 curPos = ImGui::GetCursorPos();
67 const ImVec2 wndSz(size.x > 0 ? size.x : ImGui::GetWindowSize().x - curPos.x, size.y > 0 ? size.y : ImGui::GetWindowSize().y - curPos.y);
68
69 IM_ASSERT(wndSz.x != 0 && wndSz.y != 0 && zoom != 0);
70
71 // Here we use the whole size (although it can be partially empty)
72 ImRect bb(window->DC.CursorPos, ImVec2(window->DC.CursorPos.x + wndSz.x, window->DC.CursorPos.y + wndSz.y));
73 ItemSize(bb);
74 if (!ItemAdd(bb, 0)) return rv;
75
76 ImVec2 imageSz = wndSz;
77 ImVec2 remainingWndSize(0, 0);
78 if (aspectRatio != 0) {
79 const float wndAspectRatio = wndSz.x / wndSz.y;
80 if (aspectRatio >= wndAspectRatio) { imageSz.y = imageSz.x / aspectRatio; remainingWndSize.y = wndSz.y - imageSz.y; }
81 else { imageSz.x = imageSz.y * aspectRatio; remainingWndSize.x = wndSz.x - imageSz.x; }
82 }
83
84 if (ImGui::IsItemHovered()) {
85 const ImGuiIO& io = ImGui::GetIO();
86 if (io.MouseWheel != 0) {
87 if (io.KeyCtrl) {
88 const float zoomStep = zoomMaxAndZoomStep.y;
89 const float zoomMin = 1.f;
90 const float zoomMax = zoomMaxAndZoomStep.x;
91 if (io.MouseWheel < 0) { zoom /= zoomStep; if (zoom < zoomMin) zoom = zoomMin; }
92 else { zoom *= zoomStep; if (zoom > zoomMax) zoom = zoomMax; }
93 rv = true;
94 /*if (io.FontAllowUserScaling) {
95 // invert effect:
96 // Zoom / Scale window
97 ImGuiContext& g = *GImGui;
98 ImGuiWindow* window = g.HoveredWindow;
99 float new_font_scale = ImClamp(window->FontWindowScale - g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
100 float scale = new_font_scale / window->FontWindowScale;
101 window->FontWindowScale = new_font_scale;
102
103 const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
104 window->Pos += offset;
105 window->PosFloat += offset;
106 window->Size *= scale;
107 window->SizeFull *= scale;
108 }*/
109 }
110 else {
111 const bool scrollDown = io.MouseWheel <= 0;
112 const float zoomFactor = .5f / zoom;
113 if ((!scrollDown && zoomCenter.y > zoomFactor) || (scrollDown && zoomCenter.y < 1.f - zoomFactor)) {
114 const float slideFactor = zoomMaxAndZoomStep.y * 0.1f * zoomFactor;
115 if (scrollDown) {
116 zoomCenter.y += slideFactor;
117 if (zoomCenter.y > 1.f - zoomFactor) zoomCenter.y = 1.f - zoomFactor;
118 }
119 else {
120 zoomCenter.y -= slideFactor;
121 if (zoomCenter.y < zoomFactor) zoomCenter.y = zoomFactor;
122 }
123 rv = true;
124 }
125 }
126 }
127 if (io.MouseClicked[resetZoomAndPanMouseButton]) { zoom = 1.f; zoomCenter.x = zoomCenter.y = .5f; rv = true; }
128 if (ImGui::IsMouseDragging(panMouseButtonDrag, 1.f)) {
129 zoomCenter.x -= io.MouseDelta.x / (imageSz.x * zoom);
130 zoomCenter.y -= io.MouseDelta.y / (imageSz.y * zoom);
131 rv = true;
132 ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
133 }
134 }
135
136 const float zoomFactor = .5f / zoom;
137 if (rv) {
138 if (zoomCenter.x < zoomFactor) zoomCenter.x = zoomFactor;
139 else if (zoomCenter.x > 1.f - zoomFactor) zoomCenter.x = 1.f - zoomFactor;
140 if (zoomCenter.y < zoomFactor) zoomCenter.y = zoomFactor;
141 else if (zoomCenter.y > 1.f - zoomFactor) zoomCenter.y = 1.f - zoomFactor;
142 }
143
144 ImVec2 uvExtension(2.f * zoomFactor, 2.f * zoomFactor);
145 if (remainingWndSize.x > 0) {
146 const float remainingSizeInUVSpace = 2.f * zoomFactor * (remainingWndSize.x / imageSz.x);
147 const float deltaUV = uvExtension.x;
148 const float remainingUV = 1.f - deltaUV;
149 if (deltaUV < 1) {
150 float adder = (remainingUV < remainingSizeInUVSpace ? remainingUV : remainingSizeInUVSpace);
151 uvExtension.x += adder;
152 remainingWndSize.x -= adder * zoom * imageSz.x;
153 imageSz.x += adder * zoom * imageSz.x;
154
155 if (zoomCenter.x < uvExtension.x * .5f) zoomCenter.x = uvExtension.x * .5f;
156 else if (zoomCenter.x > 1.f - uvExtension.x * .5f) zoomCenter.x = 1.f - uvExtension.x * .5f;
157 }
158 }
159 if (remainingWndSize.y > 0) {
160 const float remainingSizeInUVSpace = 2.f * zoomFactor * (remainingWndSize.y / imageSz.y);
161 const float deltaUV = uvExtension.y;
162 const float remainingUV = 1.f - deltaUV;
163 if (deltaUV < 1) {
164 float adder = (remainingUV < remainingSizeInUVSpace ? remainingUV : remainingSizeInUVSpace);
165 uvExtension.y += adder;
166 remainingWndSize.y -= adder * zoom * imageSz.y;
167 imageSz.y += adder * zoom * imageSz.y;
168
169 if (zoomCenter.y < uvExtension.y * .5f) zoomCenter.y = uvExtension.y * .5f;
170 else if (zoomCenter.y > 1.f - uvExtension.y * .5f) zoomCenter.y = 1.f - uvExtension.y * .5f;
171 }
172 }
173
174 ImVec2 uv0((zoomCenter.x - uvExtension.x * .5f), (zoomCenter.y - uvExtension.y * .5f));
175 ImVec2 uv1((zoomCenter.x + uvExtension.x * .5f), (zoomCenter.y + uvExtension.y * .5f));
176
177 /* // Here we use just the window size, but then ImGui::IsItemHovered() should be moved below this block. How to do it?
178 ImVec2 startPos=window->DC.CursorPos;
179 startPos.x+= remainingWndSize.x*.5f;
180 startPos.y+= remainingWndSize.y*.5f;
181 ImVec2 endPos(startPos.x+imageSz.x,startPos.y+imageSz.y);
182 ImRect bb(startPos, endPos);
183 ItemSize(bb);
184 if (!ItemAdd(bb, NULL)) return rv;*/
185
186 ImVec2 startPos = bb.Min, endPos = bb.Max;
187 startPos.x += remainingWndSize.x * .5f;
188 startPos.y += remainingWndSize.y * .5f;
189 endPos.x = startPos.x + imageSz.x;
190 endPos.y = startPos.y + imageSz.y;
191
192 window->DrawList->AddImage(user_texture_id, startPos, endPos, uv0, uv1);
193
194 return rv;
195 }
196} //namespace ImGui
#define IM_ASSERT(_EXPR)
static const ImVec4 Colours[]
Definition: Utils.h:58
static const ImVec4 ColoursHovered[]
Definition: Utils.h:63
bool ImageZoomAndPan(ImTextureID user_texture_id, const ImVec2 &size, float aspectRatio, float &zoom, ImVec2 &zoomCenter, int panMouseButtonDrag, int resetZoomAndPanMouseButton, const ImVec2 &zoomMaxAndZoomStep)
bool ToggleButton(const char *str_id, bool *v)
void * ImTextureID