ListBox, Combo: Changed signature of "name getter" callback in old one-liner ListBox()/Combo() apis.

This commit is contained in:
ocornut 2023-09-15 18:43:04 +02:00
parent 8a2cd81091
commit b101cf46b6
5 changed files with 59 additions and 24 deletions

View File

@ -42,6 +42,16 @@ HOW TO UPDATE?
Breaking changes: Breaking changes:
- ListBox, Combo: Changed signature of "name getter" callback in old one-liner ListBox()/Combo() apis.
Before:
getter type: bool (*getter)(void* user_data, int idx, const char** out_text)
function: bool Combo(const char* label, int* current_item, bool (*getter)(void* user_data, int idx, const char** out_text), ...);
function: bool ListBox(const char* label, int* current_item, bool (*getting)(void* user_data, int idx, const char** out_text), ...);
After:
getter type: const char* (*getter)(void* user_data, int idx)
function: bool Combo(const char* label, int* current_item, const char* (*getter)(void* user_data, int idx), ...);
function: bool ListBox(const char* label, int* current_item, const char* (*getter)(void* user_data, int idx), ...);
Old type was unnecessarily complex and harder to wrap in e.g. a lambda. Kept inline redirection function (will obsolete).
- Commented out obsolete redirecting enums/functions that were marked obsolete two years ago: - Commented out obsolete redirecting enums/functions that were marked obsolete two years ago:
- GetWindowContentRegionWidth() -> use GetWindowContentRegionMax().x - GetWindowContentRegionMin().x. - GetWindowContentRegionWidth() -> use GetWindowContentRegionMax().x - GetWindowContentRegionMin().x.
Consider that generally 'GetContentRegionAvail().x' is more useful. Consider that generally 'GetContentRegionAvail().x' is more useful.

View File

@ -424,6 +424,11 @@ CODE
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
You can read releases logs https://github.com/ocornut/imgui/releases for more details. You can read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2023/09/15 (1.90.0) - ListBox, Combo: changed signature of "name getter" callback in old one-liner ListBox()/Combo() apis. kept inline redirection function (will obsolete).
- old: bool Combo(const char* label, int* current_item, bool (*getter)(void* user_data, int idx, const char** out_text), ...)
- new: bool Combo(const char* label, int* current_item, const char* (*getter)(void* user_data, int idx), ...);
- old: bool ListBox(const char* label, int* current_item, bool (*getting)(void* user_data, int idx, const char** out_text), ...);
- new: bool ListBox(const char* label, int* current_item, const char* (*getter)(void* user_data, int idx), ...);
- 2023/09/08 (1.90.0) - commented out obsolete redirecting functions: - 2023/09/08 (1.90.0) - commented out obsolete redirecting functions:
- GetWindowContentRegionWidth() -> use GetWindowContentRegionMax().x - GetWindowContentRegionMin().x. Consider that generally 'GetContentRegionAvail().x' is more useful. - GetWindowContentRegionWidth() -> use GetWindowContentRegionMax().x - GetWindowContentRegionMin().x. Consider that generally 'GetContentRegionAvail().x' is more useful.
- ImDrawCornerFlags_XXX -> use ImDrawFlags_RoundCornersXXX flags. Read 1.82 Changelog for details + grep commented names in sources. - ImDrawCornerFlags_XXX -> use ImDrawFlags_RoundCornersXXX flags. Read 1.82 Changelog for details + grep commented names in sources.

View File

@ -527,7 +527,7 @@ namespace ImGui
IMGUI_API void EndCombo(); // only call EndCombo() if BeginCombo() returns true! IMGUI_API void EndCombo(); // only call EndCombo() if BeginCombo() returns true!
IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1); IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1);
IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items = -1); // Separate items with \0 within a string, end item-list with \0\0. e.g. "One\0Two\0Three\0" IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items = -1); // Separate items with \0 within a string, end item-list with \0\0. e.g. "One\0Two\0Three\0"
IMGUI_API bool Combo(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items = -1); IMGUI_API bool Combo(const char* label, int* current_item, const char* (*getter)(void* user_data, int idx), void* user_data, int items_count, int popup_max_height_in_items = -1);
// Widgets: Drag Sliders // Widgets: Drag Sliders
// - CTRL+Click on any drag box to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp. // - CTRL+Click on any drag box to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp.
@ -638,14 +638,14 @@ namespace ImGui
IMGUI_API bool BeginListBox(const char* label, const ImVec2& size = ImVec2(0, 0)); // open a framed scrolling region IMGUI_API bool BeginListBox(const char* label, const ImVec2& size = ImVec2(0, 0)); // open a framed scrolling region
IMGUI_API void EndListBox(); // only call EndListBox() if BeginListBox() returned true! IMGUI_API void EndListBox(); // only call EndListBox() if BeginListBox() returned true!
IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1);
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, const char* (*getter)(void* user_data, int idx), void* user_data, int items_count, int height_in_items = -1);
// Widgets: Data Plotting // Widgets: Data Plotting
// - Consider using ImPlot (https://github.com/epezent/implot) which is much better! // - Consider using ImPlot (https://github.com/epezent/implot) which is much better!
IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float)); IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float));
IMGUI_API void PlotLines(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0)); IMGUI_API void PlotLines(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0));
IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float)); IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float));
IMGUI_API void PlotHistogram(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0)); IMGUI_API void PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0));
// Widgets: Value() Helpers. // Widgets: Value() Helpers.
// - Those are merely shortcut to calling Text() with a format string. Output single value in "name: value" format (tip: freely declare more in your code to handle your types. you can add functions to the ImGui namespace) // - Those are merely shortcut to calling Text() with a format string. Output single value in "name: value" format (tip: freely declare more in your code to handle your types. you can add functions to the ImGui namespace)
@ -3097,6 +3097,9 @@ namespace ImGui
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
namespace ImGui namespace ImGui
{ {
// OBSOLETED in 1.90.0 (from September 2023)
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int height_in_items = -1);
IMGUI_API bool Combo(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int popup_max_height_in_items = -1);
// OBSOLETED in 1.89.7 (from June 2023) // OBSOLETED in 1.89.7 (from June 2023)
IMGUI_API void SetItemAllowOverlap(); // Use SetNextItemAllowOverlap() before item. IMGUI_API void SetItemAllowOverlap(); // Use SetNextItemAllowOverlap() before item.
// OBSOLETED in 1.89.4 (from March 2023) // OBSOLETED in 1.89.4 (from March 2023)

View File

@ -1226,9 +1226,8 @@ static void ShowDemoWindowWidgets()
ImGui::Combo("combo 3 (array)", &item_current_3, items, IM_ARRAYSIZE(items)); ImGui::Combo("combo 3 (array)", &item_current_3, items, IM_ARRAYSIZE(items));
// Simplified one-liner Combo() using an accessor function // Simplified one-liner Combo() using an accessor function
struct Funcs { static bool ItemGetter(void* data, int n, const char** out_str) { *out_str = ((const char**)data)[n]; return true; } };
static int item_current_4 = 0; static int item_current_4 = 0;
ImGui::Combo("combo 4 (function)", &item_current_4, &Funcs::ItemGetter, items, IM_ARRAYSIZE(items)); ImGui::Combo("combo 4 (function)", &item_current_4, [](void* data, int n) { return ((const char**)data)[n]; }, items, IM_ARRAYSIZE(items));
ImGui::TreePop(); ImGui::TreePop();
} }

View File

@ -1870,18 +1870,15 @@ void ImGui::EndComboPreview()
} }
// Getter for the old Combo() API: const char*[] // Getter for the old Combo() API: const char*[]
static bool Items_ArrayGetter(void* data, int idx, const char** out_text) static const char* Items_ArrayGetter(void* data, int idx)
{ {
const char* const* items = (const char* const*)data; const char* const* items = (const char* const*)data;
if (out_text) return items[idx];
*out_text = items[idx];
return true;
} }
// Getter for the old Combo() API: "item1\0item2\0item3\0" // Getter for the old Combo() API: "item1\0item2\0item3\0"
static bool Items_SingleStringGetter(void* data, int idx, const char** out_text) static const char* Items_SingleStringGetter(void* data, int idx)
{ {
// FIXME-OPT: we could pre-compute the indices to fasten this. But only 1 active combo means the waste is limited.
const char* items_separated_by_zeros = (const char*)data; const char* items_separated_by_zeros = (const char*)data;
int items_count = 0; int items_count = 0;
const char* p = items_separated_by_zeros; const char* p = items_separated_by_zeros;
@ -1892,22 +1889,18 @@ static bool Items_SingleStringGetter(void* data, int idx, const char** out_text)
p += strlen(p) + 1; p += strlen(p) + 1;
items_count++; items_count++;
} }
if (!*p) return *p ? p : NULL;
return false;
if (out_text)
*out_text = p;
return true;
} }
// Old API, prefer using BeginCombo() nowadays if you can. // Old API, prefer using BeginCombo() nowadays if you can.
bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int popup_max_height_in_items) bool ImGui::Combo(const char* label, int* current_item, const char* (*getter)(void* user_data, int idx), void* user_data, int items_count, int popup_max_height_in_items)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
// Call the getter to obtain the preview string which is a parameter to BeginCombo() // Call the getter to obtain the preview string which is a parameter to BeginCombo()
const char* preview_value = NULL; const char* preview_value = NULL;
if (*current_item >= 0 && *current_item < items_count) if (*current_item >= 0 && *current_item < items_count)
items_getter(data, *current_item, &preview_value); preview_value = getter(user_data, *current_item);
// The old Combo() API exposed "popup_max_height_in_items". The new more general BeginCombo() API doesn't have/need it, but we emulate it here. // The old Combo() API exposed "popup_max_height_in_items". The new more general BeginCombo() API doesn't have/need it, but we emulate it here.
if (popup_max_height_in_items != -1 && !(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint)) if (popup_max_height_in_items != -1 && !(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint))
@ -1921,11 +1914,12 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
bool value_changed = false; bool value_changed = false;
for (int i = 0; i < items_count; i++) for (int i = 0; i < items_count; i++)
{ {
const char* item_text = getter(user_data, i);
if (item_text == NULL)
item_text = "*Unknown item*";
PushID(i); PushID(i);
const bool item_selected = (i == *current_item); const bool item_selected = (i == *current_item);
const char* item_text;
if (!items_getter(data, i, &item_text))
item_text = "*Unknown item*";
if (Selectable(item_text, item_selected) && *current_item != i) if (Selectable(item_text, item_selected) && *current_item != i)
{ {
value_changed = true; value_changed = true;
@ -1965,6 +1959,30 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa
return value_changed; return value_changed;
} }
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
struct ImGuiGetNameFromIndexOldToNewCallbackData { void* UserData; bool (*OldCallback)(void*, int, const char**); };
static const char* ImGuiGetNameFromIndexOldToNewCallback(void* user_data, int idx)
{
ImGuiGetNameFromIndexOldToNewCallbackData* data = (ImGuiGetNameFromIndexOldToNewCallbackData*)user_data;
const char* s = NULL;
data->OldCallback(data->UserData, idx, &s);
return s;
}
bool ImGui::ListBox(const char* label, int* current_item, bool (*old_getter)(void*, int, const char**), void* user_data, int items_count, int height_in_items)
{
ImGuiGetNameFromIndexOldToNewCallbackData old_to_new_data = { user_data, old_getter };
return ListBox(label, current_item, ImGuiGetNameFromIndexOldToNewCallback, &old_to_new_data, items_count, height_in_items);
}
bool ImGui::Combo(const char* label, int* current_item, bool (*old_getter)(void*, int, const char**), void* user_data, int items_count, int popup_max_height_in_items)
{
ImGuiGetNameFromIndexOldToNewCallbackData old_to_new_data = { user_data, old_getter };
return Combo(label, current_item, ImGuiGetNameFromIndexOldToNewCallback, &old_to_new_data, items_count, popup_max_height_in_items);
}
#endif
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// [SECTION] Data Type and Data Formatting Helpers [Internal] // [SECTION] Data Type and Data Formatting Helpers [Internal]
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -6879,7 +6897,7 @@ bool ImGui::ListBox(const char* label, int* current_item, const char* const item
// This is merely a helper around BeginListBox(), EndListBox(). // This is merely a helper around BeginListBox(), EndListBox().
// Considering using those directly to submit custom data or store selection differently. // Considering using those directly to submit custom data or store selection differently.
bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items) bool ImGui::ListBox(const char* label, int* current_item, const char* (*getter)(void* user_data, int idx), void* user_data, int items_count, int height_in_items)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -6900,8 +6918,8 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
while (clipper.Step()) while (clipper.Step())
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
{ {
const char* item_text; const char* item_text = getter(user_data, i);
if (!items_getter(data, i, &item_text)) if (item_text == NULL)
item_text = "*Unknown item*"; item_text = "*Unknown item*";
PushID(i); PushID(i);