|
@@ -1,4 +1,4 @@
|
1
|
|
-// ImGui library v1.38 WIP
|
|
1
|
+// ImGui library v1.39 WIP
|
2
|
2
|
// See ImGui::ShowTestWindow() for sample code.
|
3
|
3
|
// Read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
|
4
|
4
|
// Get latest version at https://github.com/ocornut/imgui
|
|
@@ -13,6 +13,7 @@
|
13
|
13
|
- API BREAKING CHANGES (read me when you update!)
|
14
|
14
|
- FREQUENTLY ASKED QUESTIONS (FAQ), TIPS
|
15
|
15
|
- Can I have multiple widgets with the same label? (Yes)
|
|
16
|
+ - How do I update to a newer version of ImGui?
|
16
|
17
|
- Why is my text output blurry?
|
17
|
18
|
- How can I load a different font than the default?
|
18
|
19
|
- How can I load multiple fonts?
|
|
@@ -268,6 +269,15 @@
|
268
|
269
|
e.g. when displaying a single object that may change over time (1-1 relationship), using a static string as ID will preserve your node open/closed state when the targeted object change.
|
269
|
270
|
e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense!
|
270
|
271
|
|
|
272
|
+ Q: How do I update to a newer version of ImGui?
|
|
273
|
+ A: Overwrite the following files:
|
|
274
|
+ imgui.cpp
|
|
275
|
+ imgui.h
|
|
276
|
+ stb_rect_pack.h
|
|
277
|
+ stb_textedit.h
|
|
278
|
+ stb_truetype.h
|
|
279
|
+ Check the "API BREAKING CHANGES" sections for a list of occasional API breaking changes.
|
|
280
|
+
|
271
|
281
|
Q: Why is my text output blurry?
|
272
|
282
|
A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
|
273
|
283
|
|
|
@@ -492,7 +502,7 @@ static bool ItemAdd(const ImRect& bb, const ImGuiID* id);
|
492
|
502
|
static void ItemSize(ImVec2 size, float text_offset_y = 0.0f);
|
493
|
503
|
static void ItemSize(const ImRect& bb, float text_offset_y = 0.0f);
|
494
|
504
|
static void PushColumnClipRect(int column_index = -1);
|
495
|
|
-static bool IsClippedEx(const ImRect& bb, bool clip_even_when_logged);
|
|
505
|
+static bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged);
|
496
|
506
|
|
497
|
507
|
static bool IsMouseHoveringRect(const ImRect& bb);
|
498
|
508
|
static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true);
|
|
@@ -1146,6 +1156,7 @@ struct ImGuiState
|
1146
|
1156
|
ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc.
|
1147
|
1157
|
ImGuiStorage ColorEditModeStorage; // for user selection
|
1148
|
1158
|
ImGuiID ActiveComboID;
|
|
1159
|
+ ImVec2 ActiveClickDeltaToCenter;
|
1149
|
1160
|
float DragCurrentValue; // current dragged value, always float, not rounded by end-user precision settings
|
1150
|
1161
|
ImVec2 DragLastMouseDelta;
|
1151
|
1162
|
float DragSpeedDefaultRatio; // if speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
|
|
@@ -1204,6 +1215,7 @@ struct ImGuiState
|
1204
|
1215
|
|
1205
|
1216
|
ScalarAsInputTextId = 0;
|
1206
|
1217
|
ActiveComboID = 0;
|
|
1218
|
+ ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f);
|
1207
|
1219
|
DragCurrentValue = 0.0f;
|
1208
|
1220
|
DragLastMouseDelta = ImVec2(0.0f, 0.0f);
|
1209
|
1221
|
DragSpeedDefaultRatio = 0.01f;
|
|
@@ -1403,6 +1415,14 @@ float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val)
|
1403
|
1415
|
return &it->val_f;
|
1404
|
1416
|
}
|
1405
|
1417
|
|
|
1418
|
+void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val)
|
|
1419
|
+{
|
|
1420
|
+ ImVector<Pair>::iterator it = LowerBound(Data, key);
|
|
1421
|
+ if (it == Data.end() || it->key != key)
|
|
1422
|
+ it = Data.insert(it, Pair(key, default_val));
|
|
1423
|
+ return &it->val_p;
|
|
1424
|
+}
|
|
1425
|
+
|
1406
|
1426
|
// FIXME-OPT: Wasting CPU because all SetInt() are preceeded by GetInt() calls so we should have the result from lower_bound already in place.
|
1407
|
1427
|
// However we only use SetInt() on explicit user action (so that's maximum once a frame) so the optimisation isn't much needed.
|
1408
|
1428
|
void ImGuiStorage::SetInt(ImU32 key, int val)
|
|
@@ -4255,7 +4275,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end)
|
4255
|
4275
|
while (line < text_end)
|
4256
|
4276
|
{
|
4257
|
4277
|
const char* line_end = strchr(line, '\n');
|
4258
|
|
- if (IsClippedEx(line_rect, false))
|
|
4278
|
+ if (IsClippedEx(line_rect, NULL, false))
|
4259
|
4279
|
break;
|
4260
|
4280
|
|
4261
|
4281
|
const ImVec2 line_size = CalcTextSize(line, line_end, false);
|
|
@@ -5126,7 +5146,7 @@ static inline float RoundScalar(float value, int decimal_precision)
|
5126
|
5146
|
return value;
|
5127
|
5147
|
}
|
5128
|
5148
|
|
5129
|
|
-static bool SliderBehavior(const ImRect& frame_bb, const ImRect& slider_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, bool horizontal)
|
|
5149
|
+static bool SliderScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, bool horizontal)
|
5130
|
5150
|
{
|
5131
|
5151
|
ImGuiState& g = *GImGui;
|
5132
|
5152
|
ImGuiWindow* window = GetCurrentWindow();
|
|
@@ -5137,15 +5157,16 @@ static bool SliderBehavior(const ImRect& frame_bb, const ImRect& slider_bb, ImGu
|
5137
|
5157
|
|
5138
|
5158
|
const bool is_non_linear = fabsf(power - 1.0f) > 0.0001f;
|
5139
|
5159
|
|
5140
|
|
- const float slider_sz = horizontal ? slider_bb.GetWidth() : slider_bb.GetHeight();
|
|
5160
|
+ const float padding = horizontal ? style.FramePadding.x : style.FramePadding.y;
|
|
5161
|
+ const float slider_sz = horizontal ? (frame_bb.GetWidth() - padding * 2.0f) : (frame_bb.GetHeight() - padding * 2.0f);
|
5141
|
5162
|
float grab_sz;
|
5142
|
5163
|
if (decimal_precision > 0)
|
5143
|
5164
|
grab_sz = ImMin(style.GrabMinSize, slider_sz);
|
5144
|
5165
|
else
|
5145
|
5166
|
grab_sz = ImMin(ImMax(1.0f * (slider_sz / (v_max-v_min+1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit
|
5146
|
5167
|
const float slider_usable_sz = slider_sz - grab_sz;
|
5147
|
|
- const float slider_usable_pos_min = (horizontal ? slider_bb.Min.x : slider_bb.Min.y) + grab_sz*0.5f;
|
5148
|
|
- const float slider_usable_pos_max = (horizontal ? slider_bb.Max.x : slider_bb.Max.y) - grab_sz*0.5f;
|
|
5168
|
+ const float slider_usable_pos_min = (horizontal ? frame_bb.Min.x : frame_bb.Min.y) + padding + grab_sz*0.5f;
|
|
5169
|
+ const float slider_usable_pos_max = (horizontal ? frame_bb.Max.x : frame_bb.Max.y) - padding - grab_sz*0.5f;
|
5149
|
5170
|
|
5150
|
5171
|
bool value_changed = false;
|
5151
|
5172
|
|
|
@@ -5183,7 +5204,7 @@ static bool SliderBehavior(const ImRect& frame_bb, const ImRect& slider_bb, ImGu
|
5183
|
5204
|
// Negative: rescale to the negative range before powering
|
5184
|
5205
|
float a = 1.0f - (normalized_pos / linear_zero_pos);
|
5185
|
5206
|
a = powf(a, power);
|
5186
|
|
- new_value = ImLerp(ImMin(v_max,0.f), v_min, a);
|
|
5207
|
+ new_value = ImLerp(ImMin(v_max,0.0f), v_min, a);
|
5187
|
5208
|
}
|
5188
|
5209
|
else
|
5189
|
5210
|
{
|
|
@@ -5272,7 +5293,6 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
|
5272
|
5293
|
|
5273
|
5294
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
5274
|
5295
|
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f);
|
5275
|
|
- const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding);
|
5276
|
5296
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
5277
|
5297
|
|
5278
|
5298
|
// NB- we don't call ItemSize() yet because we may turn into a text edit box below
|
|
@@ -5312,16 +5332,16 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
|
5312
|
5332
|
ItemSize(total_bb, style.FramePadding.y);
|
5313
|
5333
|
|
5314
|
5334
|
// Actual slider behavior + render grab
|
5315
|
|
- const bool value_changed = SliderBehavior(frame_bb, inner_bb, id, v, v_min, v_max, power, decimal_precision, true);
|
|
5335
|
+ const bool value_changed = SliderScalarBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, true);
|
5316
|
5336
|
|
5317
|
5337
|
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
5318
|
5338
|
char value_buf[64];
|
5319
|
5339
|
const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v);
|
5320
|
5340
|
const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true);
|
5321
|
|
- RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x + style.FramePadding.x, inner_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max);
|
|
5341
|
+ RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x + style.FramePadding.x, frame_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max);
|
5322
|
5342
|
|
5323
|
5343
|
if (label_size.x > 0.0f)
|
5324
|
|
- RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label);
|
|
5344
|
+ RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
5325
|
5345
|
|
5326
|
5346
|
return value_changed;
|
5327
|
5347
|
}
|
|
@@ -5338,7 +5358,6 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float
|
5338
|
5358
|
|
5339
|
5359
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
5340
|
5360
|
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
5341
|
|
- const ImRect slider_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding);
|
5342
|
5361
|
const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
5343
|
5362
|
|
5344
|
5363
|
ItemSize(bb, style.FramePadding.y);
|
|
@@ -5361,17 +5380,17 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float
|
5361
|
5380
|
}
|
5362
|
5381
|
|
5363
|
5382
|
// Actual slider behavior + render grab
|
5364
|
|
- bool value_changed = SliderBehavior(frame_bb, slider_bb, id, v, v_min, v_max, power, decimal_precision, false);
|
|
5383
|
+ bool value_changed = SliderScalarBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, false);
|
5365
|
5384
|
|
5366
|
5385
|
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
5367
|
5386
|
// For the vertical slider we allow centered text to overlap the frame padding
|
5368
|
5387
|
char value_buf[64];
|
5369
|
5388
|
char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v);
|
5370
|
5389
|
const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true);
|
5371
|
|
- RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x, slider_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max);
|
|
5390
|
+ RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x, frame_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max);
|
5372
|
5391
|
|
5373
|
5392
|
if (label_size.x > 0.0f)
|
5374
|
|
- RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, slider_bb.Min.y), label);
|
|
5393
|
+ RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
5375
|
5394
|
|
5376
|
5395
|
return value_changed;
|
5377
|
5396
|
}
|
|
@@ -5405,7 +5424,7 @@ bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min,
|
5405
|
5424
|
}
|
5406
|
5425
|
|
5407
|
5426
|
// Add multiple sliders on 1 line for compact edition of multiple components
|
5408
|
|
-static bool SliderFloatN(const char* label, float v[3], int components, float v_min, float v_max, const char* display_format, float power)
|
|
5427
|
+static bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power)
|
5409
|
5428
|
{
|
5410
|
5429
|
ImGuiState& g = *GImGui;
|
5411
|
5430
|
ImGuiWindow* window = GetCurrentWindow();
|
|
@@ -5457,7 +5476,7 @@ bool ImGui::SliderFloat4(const char* label, float v[4], float v_min, float v_max
|
5457
|
5476
|
return SliderFloatN(label, v, 4, v_min, v_max, display_format, power);
|
5458
|
5477
|
}
|
5459
|
5478
|
|
5460
|
|
-static bool SliderIntN(const char* label, int v[3], int components, int v_min, int v_max, const char* display_format)
|
|
5479
|
+static bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format)
|
5461
|
5480
|
{
|
5462
|
5481
|
ImGuiState& g = *GImGui;
|
5463
|
5482
|
ImGuiWindow* window = GetCurrentWindow();
|
|
@@ -5522,7 +5541,7 @@ static bool DragScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, flo
|
5522
|
5541
|
|
5523
|
5542
|
bool value_changed = false;
|
5524
|
5543
|
|
5525
|
|
- // Process clicking on the slider
|
|
5544
|
+ // Process clicking on the drag
|
5526
|
5545
|
if (g.ActiveId == id)
|
5527
|
5546
|
{
|
5528
|
5547
|
if (g.IO.MouseDown[0])
|
|
@@ -5652,6 +5671,58 @@ bool ImGui::DragFloat(const char* label, float *v, float v_speed, float v_min, f
|
5652
|
5671
|
return value_changed;
|
5653
|
5672
|
}
|
5654
|
5673
|
|
|
5674
|
+static bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power)
|
|
5675
|
+{
|
|
5676
|
+ ImGuiState& g = *GImGui;
|
|
5677
|
+ ImGuiWindow* window = GetCurrentWindow();
|
|
5678
|
+ if (window->SkipItems)
|
|
5679
|
+ return false;
|
|
5680
|
+
|
|
5681
|
+ const ImGuiStyle& style = g.Style;
|
|
5682
|
+ const float w_full = ImGui::CalcItemWidth();
|
|
5683
|
+ const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components));
|
|
5684
|
+ const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)));
|
|
5685
|
+
|
|
5686
|
+ bool value_changed = false;
|
|
5687
|
+ ImGui::BeginGroup();
|
|
5688
|
+ ImGui::PushID(label);
|
|
5689
|
+ ImGui::PushItemWidth(w_item_one);
|
|
5690
|
+ for (int i = 0; i < components; i++)
|
|
5691
|
+ {
|
|
5692
|
+ ImGui::PushID(i);
|
|
5693
|
+ if (i + 1 == components)
|
|
5694
|
+ {
|
|
5695
|
+ ImGui::PopItemWidth();
|
|
5696
|
+ ImGui::PushItemWidth(w_item_last);
|
|
5697
|
+ }
|
|
5698
|
+ value_changed |= ImGui::DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power);
|
|
5699
|
+ ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
|
|
5700
|
+ ImGui::PopID();
|
|
5701
|
+ }
|
|
5702
|
+ ImGui::PopItemWidth();
|
|
5703
|
+ ImGui::PopID();
|
|
5704
|
+
|
|
5705
|
+ ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
|
|
5706
|
+ ImGui::EndGroup();
|
|
5707
|
+
|
|
5708
|
+ return value_changed;
|
|
5709
|
+}
|
|
5710
|
+
|
|
5711
|
+bool ImGui::DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power)
|
|
5712
|
+{
|
|
5713
|
+ return DragFloatN(label, v, 2, v_speed, v_min, v_max, display_format, power);
|
|
5714
|
+}
|
|
5715
|
+
|
|
5716
|
+bool ImGui::DragFloat3(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power)
|
|
5717
|
+{
|
|
5718
|
+ return DragFloatN(label, v, 3, v_speed, v_min, v_max, display_format, power);
|
|
5719
|
+}
|
|
5720
|
+
|
|
5721
|
+bool ImGui::DragFloat4(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power)
|
|
5722
|
+{
|
|
5723
|
+ return DragFloatN(label, v, 4, v_speed, v_min, v_max, display_format, power);
|
|
5724
|
+}
|
|
5725
|
+
|
5655
|
5726
|
// NB: v_speed is float to allow adjusting the drag speed with more precision
|
5656
|
5727
|
bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* display_format)
|
5657
|
5728
|
{
|
|
@@ -5663,6 +5734,58 @@ bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_m
|
5663
|
5734
|
return value_changed;
|
5664
|
5735
|
}
|
5665
|
5736
|
|
|
5737
|
+static bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format)
|
|
5738
|
+{
|
|
5739
|
+ ImGuiState& g = *GImGui;
|
|
5740
|
+ ImGuiWindow* window = GetCurrentWindow();
|
|
5741
|
+ if (window->SkipItems)
|
|
5742
|
+ return false;
|
|
5743
|
+
|
|
5744
|
+ const ImGuiStyle& style = g.Style;
|
|
5745
|
+ const float w_full = ImGui::CalcItemWidth();
|
|
5746
|
+ const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)) / (float)components));
|
|
5747
|
+ const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1)));
|
|
5748
|
+
|
|
5749
|
+ bool value_changed = false;
|
|
5750
|
+ ImGui::BeginGroup();
|
|
5751
|
+ ImGui::PushID(label);
|
|
5752
|
+ ImGui::PushItemWidth(w_item_one);
|
|
5753
|
+ for (int i = 0; i < components; i++)
|
|
5754
|
+ {
|
|
5755
|
+ ImGui::PushID(i);
|
|
5756
|
+ if (i + 1 == components)
|
|
5757
|
+ {
|
|
5758
|
+ ImGui::PopItemWidth();
|
|
5759
|
+ ImGui::PushItemWidth(w_item_last);
|
|
5760
|
+ }
|
|
5761
|
+ value_changed |= ImGui::DragInt("##v", &v[i], v_speed, v_min, v_max, display_format);
|
|
5762
|
+ ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
|
|
5763
|
+ ImGui::PopID();
|
|
5764
|
+ }
|
|
5765
|
+ ImGui::PopItemWidth();
|
|
5766
|
+ ImGui::PopID();
|
|
5767
|
+
|
|
5768
|
+ ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
|
|
5769
|
+ ImGui::EndGroup();
|
|
5770
|
+
|
|
5771
|
+ return value_changed;
|
|
5772
|
+}
|
|
5773
|
+
|
|
5774
|
+bool ImGui::DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* display_format)
|
|
5775
|
+{
|
|
5776
|
+ return DragIntN(label, v, 2, v_speed, v_min, v_max, display_format);
|
|
5777
|
+}
|
|
5778
|
+
|
|
5779
|
+bool ImGui::DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* display_format)
|
|
5780
|
+{
|
|
5781
|
+ return DragIntN(label, v, 3, v_speed, v_min, v_max, display_format);
|
|
5782
|
+}
|
|
5783
|
+
|
|
5784
|
+bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* display_format)
|
|
5785
|
+{
|
|
5786
|
+ return DragIntN(label, v, 4, v_speed, v_min, v_max, display_format);
|
|
5787
|
+}
|
|
5788
|
+
|
5666
|
5789
|
enum ImGuiPlotType
|
5667
|
5790
|
{
|
5668
|
5791
|
ImGuiPlotType_Lines,
|
|
@@ -6865,7 +6988,8 @@ bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg)
|
6865
|
6988
|
const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : w, size_arg.y != 0.0f ? size_arg.y : label_size.y);
|
6866
|
6989
|
ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
6867
|
6990
|
ItemSize(bb);
|
6868
|
|
- bb.Max.x += style.AutoFitPadding.x;
|
|
6991
|
+ if (size_arg.x == 0.0f)
|
|
6992
|
+ bb.Max.x += style.AutoFitPadding.x;
|
6869
|
6993
|
|
6870
|
6994
|
// Selectables are meant to be tightly packed together. So for both rendering and collision we extend to compensate for spacing.
|
6871
|
6995
|
ImRect bb_with_spacing = bb;
|
|
@@ -7256,15 +7380,16 @@ static inline void ItemSize(const ImRect& bb, float text_offset_y)
|
7256
|
7380
|
ItemSize(bb.GetSize(), text_offset_y);
|
7257
|
7381
|
}
|
7258
|
7382
|
|
7259
|
|
-static bool IsClippedEx(const ImRect& bb, bool clip_even_when_logged)
|
|
7383
|
+static bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged)
|
7260
|
7384
|
{
|
7261
|
7385
|
ImGuiState& g = *GImGui;
|
7262
|
7386
|
ImGuiWindow* window = GetCurrentWindow();
|
7263
|
7387
|
|
7264
|
7388
|
if (!bb.Overlaps(ImRect(window->ClipRectStack.back())))
|
7265
|
7389
|
{
|
7266
|
|
- if (clip_even_when_logged || !g.LogEnabled)
|
7267
|
|
- return true;
|
|
7390
|
+ if (!id || *id != GImGui->ActiveId)
|
|
7391
|
+ if (clip_even_when_logged || !g.LogEnabled)
|
|
7392
|
+ return true;
|
7268
|
7393
|
}
|
7269
|
7394
|
return false;
|
7270
|
7395
|
}
|
|
@@ -7272,7 +7397,7 @@ static bool IsClippedEx(const ImRect& bb, bool clip_even_when_logged)
|
7272
|
7397
|
bool ImGui::IsRectClipped(const ImVec2& size)
|
7273
|
7398
|
{
|
7274
|
7399
|
ImGuiWindow* window = GetCurrentWindow();
|
7275
|
|
- return IsClippedEx(ImRect(window->DC.CursorPos, window->DC.CursorPos + size), true);
|
|
7400
|
+ return IsClippedEx(ImRect(window->DC.CursorPos, window->DC.CursorPos + size), NULL, true);
|
7276
|
7401
|
}
|
7277
|
7402
|
|
7278
|
7403
|
static bool ItemAdd(const ImRect& bb, const ImGuiID* id)
|
|
@@ -7280,13 +7405,10 @@ static bool ItemAdd(const ImRect& bb, const ImGuiID* id)
|
7280
|
7405
|
ImGuiWindow* window = GetCurrentWindow();
|
7281
|
7406
|
window->DC.LastItemID = id ? *id : 0;
|
7282
|
7407
|
window->DC.LastItemRect = bb;
|
7283
|
|
- if (IsClippedEx(bb, false))
|
|
7408
|
+ if (IsClippedEx(bb, id, false))
|
7284
|
7409
|
{
|
7285
|
|
- if (!id || *id != GImGui->ActiveId)
|
7286
|
|
- {
|
7287
|
|
- window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false;
|
7288
|
|
- return false;
|
7289
|
|
- }
|
|
7410
|
+ window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false;
|
|
7411
|
+ return false;
|
7290
|
7412
|
}
|
7291
|
7413
|
|
7292
|
7414
|
// This is a sensible default, but widgets are free to override it after calling ItemAdd()
|
|
@@ -7416,7 +7538,7 @@ void ImGui::NextColumn()
|
7416
|
7538
|
window->DC.CurrentLineTextBaseOffset = 0.0f;
|
7417
|
7539
|
|
7418
|
7540
|
PushColumnClipRect();
|
7419
|
|
- ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f);
|
|
7541
|
+ ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f); // FIXME
|
7420
|
7542
|
}
|
7421
|
7543
|
}
|
7422
|
7544
|
|
|
@@ -7432,6 +7554,21 @@ int ImGui::GetColumnsCount()
|
7432
|
7554
|
return window->DC.ColumnsCount;
|
7433
|
7555
|
}
|
7434
|
7556
|
|
|
7557
|
+static float GetDraggedColumnOffset(int column_index)
|
|
7558
|
+{
|
|
7559
|
+ // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing
|
|
7560
|
+ // window creates a feedback loop because we store normalized positions/ So while dragging we enforce absolute positioning
|
|
7561
|
+ ImGuiState& g = *GImGui;
|
|
7562
|
+ ImGuiWindow* window = GetCurrentWindow();
|
|
7563
|
+ IM_ASSERT(g.ActiveId == window->DC.ColumnsSetID + ImGuiID(column_index));
|
|
7564
|
+
|
|
7565
|
+ float x = g.IO.MousePos.x + g.ActiveClickDeltaToCenter.x;
|
|
7566
|
+ x -= window->Pos.x;
|
|
7567
|
+ x = ImClamp(x, ImGui::GetColumnOffset(column_index-1)+g.Style.ColumnsMinSpacing, ImGui::GetColumnOffset(column_index+1)-g.Style.ColumnsMinSpacing);
|
|
7568
|
+
|
|
7569
|
+ return x;
|
|
7570
|
+}
|
|
7571
|
+
|
7435
|
7572
|
float ImGui::GetColumnOffset(int column_index)
|
7436
|
7573
|
{
|
7437
|
7574
|
ImGuiState& g = *GImGui;
|
|
@@ -7439,6 +7576,13 @@ float ImGui::GetColumnOffset(int column_index)
|
7439
|
7576
|
if (column_index < 0)
|
7440
|
7577
|
column_index = window->DC.ColumnsCurrent;
|
7441
|
7578
|
|
|
7579
|
+ if (g.ActiveId)
|
|
7580
|
+ {
|
|
7581
|
+ const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index);
|
|
7582
|
+ if (g.ActiveId == column_id)
|
|
7583
|
+ return GetDraggedColumnOffset(column_index);
|
|
7584
|
+ }
|
|
7585
|
+
|
7442
|
7586
|
// Read from cache
|
7443
|
7587
|
IM_ASSERT(column_index < (int)window->DC.ColumnsOffsetsT.size());
|
7444
|
7588
|
const float t = window->DC.ColumnsOffsetsT[column_index];
|
|
@@ -7515,7 +7659,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
|
7515
|
7659
|
const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(i);
|
7516
|
7660
|
const ImRect column_rect(ImVec2(x-4,y1),ImVec2(x+4,y2));
|
7517
|
7661
|
|
7518
|
|
- if (IsClippedEx(column_rect, false))
|
|
7662
|
+ if (IsClippedEx(column_rect, &column_id, false))
|
7519
|
7663
|
continue;
|
7520
|
7664
|
|
7521
|
7665
|
bool hovered, held;
|
|
@@ -7530,10 +7674,11 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
|
7530
|
7674
|
|
7531
|
7675
|
if (held)
|
7532
|
7676
|
{
|
7533
|
|
- x -= window->Pos.x;
|
7534
|
|
- x = ImClamp(x + g.IO.MouseDelta.x, ImGui::GetColumnOffset(i-1)+g.Style.ColumnsMinSpacing, ImGui::GetColumnOffset(i+1)-g.Style.ColumnsMinSpacing);
|
|
7677
|
+ if (g.ActiveIdIsJustActivated)
|
|
7678
|
+ g.ActiveClickDeltaToCenter.x = x - g.IO.MousePos.x;
|
|
7679
|
+
|
|
7680
|
+ x = GetDraggedColumnOffset(i);
|
7535
|
7681
|
SetColumnOffset(i, x);
|
7536
|
|
- x += window->Pos.x;
|
7537
|
7682
|
}
|
7538
|
7683
|
}
|
7539
|
7684
|
}
|
|
@@ -9868,29 +10013,32 @@ void ImGui::ShowTestWindow(bool* opened)
|
9868
|
10013
|
ImGui::InputFloat3("input float3", vec4a);
|
9869
|
10014
|
}
|
9870
|
10015
|
|
9871
|
|
- /*
|
9872
|
10016
|
{
|
9873
|
10017
|
static int i1=50;
|
9874
|
10018
|
static int i2=42;
|
9875
|
10019
|
ImGui::DragInt("drag int", &i1, 1);
|
9876
|
|
- ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100);
|
|
10020
|
+ ImGui::SameLine();
|
|
10021
|
+ ImGui::TextColored(ImColor(170,170,170,255), "(?)");
|
|
10022
|
+ if (ImGui::IsItemHovered())
|
|
10023
|
+ ImGui::SetTooltip("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input text");
|
|
10024
|
+
|
|
10025
|
+ ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%");
|
9877
|
10026
|
|
9878
|
10027
|
static float f1=1.00f;
|
9879
|
10028
|
static float f2=0.0067f;
|
9880
|
10029
|
ImGui::DragFloat("drag float", &f1, 1.0f);
|
9881
|
|
- ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f");
|
|
10030
|
+ ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns");
|
9882
|
10031
|
}
|
9883
|
|
- */
|
9884
|
10032
|
|
9885
|
10033
|
{
|
9886
|
10034
|
static int i1=0;
|
9887
|
|
- static int i2=42;
|
|
10035
|
+ //static int i2=42;
|
9888
|
10036
|
ImGui::SliderInt("slider int 0..3", &i1, 0, 3);
|
9889
|
|
- ImGui::SliderInt("slider int -100..100", &i2, -100, 100);
|
|
10037
|
+ //ImGui::SliderInt("slider int -100..100", &i2, -100, 100);
|
9890
|
10038
|
|
9891
|
|
- static float f1=1.123f;
|
9892
|
|
- static float f2=0;
|
9893
|
|
- ImGui::SliderFloat("slider float", &f1, 0.0f, 2.0f);
|
|
10039
|
+ static float f1=0.123f;
|
|
10040
|
+ static float f2=0.0f;
|
|
10041
|
+ ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f");
|
9894
|
10042
|
ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f);
|
9895
|
10043
|
static float angle = 0.0f;
|
9896
|
10044
|
ImGui::SliderAngle("slider angle", &angle);
|
|
@@ -9918,18 +10066,24 @@ void ImGui::ShowTestWindow(bool* opened)
|
9918
|
10066
|
static int vec4i[4] = { 1, 5, 100, 255 };
|
9919
|
10067
|
|
9920
|
10068
|
ImGui::InputFloat2("input float2", vec4f);
|
|
10069
|
+ ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f);
|
9921
|
10070
|
ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f);
|
|
10071
|
+ ImGui::DragInt2("drag int2", vec4i, 1, 0, 255);
|
9922
|
10072
|
ImGui::InputInt2("input int2", vec4i);
|
9923
|
10073
|
ImGui::SliderInt2("slider int2", vec4i, 0, 255);
|
9924
|
10074
|
|
9925
|
10075
|
ImGui::InputFloat3("input float3", vec4f);
|
|
10076
|
+ ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f);
|
9926
|
10077
|
ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f);
|
|
10078
|
+ ImGui::DragInt3("drag int3", vec4i, 1, 0, 255);
|
9927
|
10079
|
ImGui::InputInt3("input int3", vec4i);
|
9928
|
10080
|
ImGui::SliderInt3("slider int3", vec4i, 0, 255);
|
9929
|
10081
|
|
9930
|
10082
|
ImGui::InputFloat4("input float4", vec4f);
|
|
10083
|
+ ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f);
|
9931
|
10084
|
ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f);
|
9932
|
10085
|
ImGui::InputInt4("input int4", vec4i);
|
|
10086
|
+ ImGui::DragInt4("drag int4", vec4i, 1, 0, 255);
|
9933
|
10087
|
ImGui::SliderInt4("slider int4", vec4i, 0, 255);
|
9934
|
10088
|
|
9935
|
10089
|
ImGui::Indent();
|