Updated imgui.

This commit is contained in:
Branimir Karadžić 2015-07-11 07:38:11 -07:00
parent c4a94843fa
commit 77bb76e83b
3 changed files with 260 additions and 36 deletions

View file

@ -136,6 +136,7 @@
Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix.
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
- 2015/07/10 (1.43) - changed SameLine() parameters from int to float.
- 2015/07/02 (1.42) - renamed SetScrollPosHere() to SetScrollFromCursorPos(). Kept inline redirection function (will obsolete).
- 2015/07/02 (1.42) - renamed GetScrollPosY() to GetScrollY(). Necessary to reduce confusion along with other scrolling functions, because positions (e.g. cursor position) are not equivalent to scrolling amount.
- 2015/06/14 (1.41) - changed ImageButton() default bg_col parameter from (0,0,0,1) (black) to (0,0,0,0) (transparent) - makes a difference when texture have transparence
@ -1289,7 +1290,7 @@ struct ImGuiState
bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
bool ActiveIdIsFocusedOnly; // Set only by active widget. Denote focus but no active interaction
ImGuiWindow* ActiveIdWindow;
ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. Only valid if ActiveID is the "#MOVE" identifier of a window.
ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. Pointer is only valid if ActiveID is the "#MOVE" identifier of a window.
float SettingsDirtyTimer;
ImVector<ImGuiIniData> Settings;
int DisableHideTextAfterDoubleHash;
@ -2400,13 +2401,14 @@ void ImGui::Render()
ImGui::End();
// Click to focus window and start moving (after we're done with all our widgets)
if (!g.ActiveId)
g.MovedWindow = NULL;
if (g.ActiveId == 0 && g.HoveredId == 0 && g.IO.MouseClicked[0])
{
if (!(g.FocusedWindow && !g.FocusedWindow->WasActive && g.FocusedWindow->Active)) // Unless we just made a popup appear
{
if (g.HoveredRootWindow != NULL)
{
IM_ASSERT(g.MovedWindow == NULL);
g.MovedWindow = g.HoveredWindow;
SetActiveId(g.HoveredRootWindow->MoveID, g.HoveredRootWindow);
}
@ -6161,7 +6163,7 @@ static bool SliderFloatN(const char* label, float* v, int components, float v_mi
{
ImGui::PushID(i);
value_changed |= ImGui::SliderFloat("##v", &v[i], v_min, v_max, display_format, power);
ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
ImGui::PopID();
ImGui::PopItemWidth();
}
@ -6203,7 +6205,7 @@ static bool SliderIntN(const char* label, int* v, int components, int v_min, int
{
ImGui::PushID(i);
value_changed |= ImGui::SliderInt("##v", &v[i], v_min, v_max, display_format);
ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
ImGui::PopID();
ImGui::PopItemWidth();
}
@ -6387,7 +6389,7 @@ static bool DragFloatN(const char* label, float* v, int components, float v_spee
{
ImGui::PushID(i);
value_changed |= ImGui::DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power);
ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
ImGui::PopID();
ImGui::PopItemWidth();
}
@ -6427,10 +6429,10 @@ bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_cu
bool value_changed = ImGui::DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format, power);
ImGui::PopItemWidth();
ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
value_changed |= ImGui::DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, display_format_max ? display_format_max : display_format, power);
ImGui::PopItemWidth();
ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
ImGui::EndGroup();
@ -6465,7 +6467,7 @@ static bool DragIntN(const char* label, int* v, int components, float v_speed, i
{
ImGui::PushID(i);
value_changed |= ImGui::DragInt("##v", &v[i], v_speed, v_min, v_max, display_format);
ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
ImGui::PopID();
ImGui::PopItemWidth();
}
@ -6505,10 +6507,10 @@ bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_
bool value_changed = ImGui::DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? IM_INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format);
ImGui::PopItemWidth();
ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
value_changed |= ImGui::DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? IM_INT_MAX : v_max, display_format_max ? display_format_max : display_format);
ImGui::PopItemWidth();
ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
ImGui::EndGroup();
@ -6672,7 +6674,7 @@ bool ImGui::Checkbox(const char* label, bool* v)
ImRect total_bb = check_bb;
if (label_size.x > 0)
SameLine(0, (int)style.ItemInnerSpacing.x);
SameLine(0, style.ItemInnerSpacing.x);
const ImRect text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + label_size);
if (label_size.x > 0)
{
@ -6730,7 +6732,7 @@ bool ImGui::RadioButton(const char* label, bool active)
ImRect total_bb = check_bb;
if (label_size.x > 0)
SameLine(0, (int)style.ItemInnerSpacing.x);
SameLine(0, style.ItemInnerSpacing.x);
const ImRect text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size);
if (label_size.x > 0)
{
@ -7121,6 +7123,8 @@ static bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
edit_state.StbState.select_start = ImMin(edit_state.StbState.select_start, edit_state.CurLenW);
edit_state.StbState.select_end = ImMin(edit_state.StbState.select_end, edit_state.CurLenW);
}
if (flags & ImGuiInputTextFlags_AlwaysInsertMode)
edit_state.StbState.insert_mode = true;
if (!is_multiline && (focus_requested_by_tab || (user_clicked && is_ctrl_down)))
select_all = true;
}
@ -7420,11 +7424,18 @@ static bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
if (edit_state.CursorFollow)
{
// Horizontal scroll in chunks of quarter width
const float scroll_increment_x = size.x * 0.25f;
if (cursor_offset.x < edit_state.ScrollX)
edit_state.ScrollX = ImMax(0.0f, cursor_offset.x - scroll_increment_x);
else if (cursor_offset.x - size.x >= edit_state.ScrollX)
edit_state.ScrollX = cursor_offset.x - size.x + scroll_increment_x;
if (!(flags & ImGuiInputTextFlags_NoHorizontalScroll))
{
const float scroll_increment_x = size.x * 0.25f;
if (cursor_offset.x < edit_state.ScrollX)
edit_state.ScrollX = ImMax(0.0f, cursor_offset.x - scroll_increment_x);
else if (cursor_offset.x - size.x >= edit_state.ScrollX)
edit_state.ScrollX = cursor_offset.x - size.x + scroll_increment_x;
}
else
{
edit_state.ScrollX = 0.0f;
}
// Vertical scroll
if (is_multiline)
@ -7566,13 +7577,13 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast,
if (step > 0.0f)
{
ImGui::PopItemWidth();
ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
ImGui::SameLine(0, style.ItemInnerSpacing.x);
if (ButtonEx("-", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups))
{
*v -= g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step;
value_changed = true;
}
ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
ImGui::SameLine(0, style.ItemInnerSpacing.x);
if (ButtonEx("+", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups))
{
*v += g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step;
@ -7583,7 +7594,7 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast,
if (label_size.x > 0)
{
ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
ImGui::SameLine(0, style.ItemInnerSpacing.x);
RenderText(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), label);
ItemSize(label_size, style.FramePadding.y);
}
@ -7616,7 +7627,7 @@ static bool InputFloatN(const char* label, float* v, int components, int decimal
{
ImGui::PushID(i);
value_changed |= ImGui::InputFloat("##v", &v[i], 0, 0, decimal_precision, extra_flags);
ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
ImGui::PopID();
ImGui::PopItemWidth();
}
@ -7659,7 +7670,7 @@ static bool InputIntN(const char* label, int* v, int components, ImGuiInputTextF
{
ImGui::PushID(i);
value_changed |= ImGui::InputInt("##v", &v[i], 0, 0, extra_flags);
ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
ImGui::PopID();
ImGui::PopItemWidth();
}
@ -8333,7 +8344,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
for (int n = 0; n < components; n++)
{
if (n > 0)
ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
ImGui::SameLine(0, style.ItemInnerSpacing.x);
if (n + 1 == components)
ImGui::PushItemWidth(w_item_last);
value_changed |= ImGui::DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt[n]);
@ -8368,7 +8379,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
break;
}
ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
ImGui::SameLine(0, style.ItemInnerSpacing.x);
const ImVec4 col_display(col[0], col[1], col[2], 1.0f);
if (ImGui::ColorButton(col_display))
@ -8376,7 +8387,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton)
{
ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
ImGui::SameLine(0, style.ItemInnerSpacing.x);
const char* button_titles[3] = { "RGB", "HSV", "HEX" };
if (ButtonEx(button_titles[edit_mode], ImVec2(0,0), ImGuiButtonFlags_DontClosePopups))
g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away!
@ -8384,7 +8395,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
}
else
{
ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
ImGui::SameLine(0, style.ItemInnerSpacing.x);
}
ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
@ -8606,11 +8617,11 @@ void ImGui::EndGroup()
}
// Gets back to previous line and continue with horizontal layout
// column_x == 0 : follow on previous item
// columm_x != 0 : align to specified column
// pos_x == 0 : follow on previous item
// pos_x != 0 : align to specified column
// spacing_w < 0 : use default spacing if column_x==0, no spacing if column_x!=0
// spacing_w >= 0 : enforce spacing
void ImGui::SameLine(int column_x, int spacing_w)
void ImGui::SameLine(float pos_x, float spacing_w)
{
ImGuiState& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
@ -8618,16 +8629,16 @@ void ImGui::SameLine(int column_x, int spacing_w)
return;
float x, y;
if (column_x != 0)
if (pos_x != 0.0f)
{
if (spacing_w < 0) spacing_w = 0;
x = window->Pos.x + (float)column_x + (float)spacing_w;
if (spacing_w < 0.0f) spacing_w = 0.0f;
x = window->Pos.x + pos_x + spacing_w;
y = window->DC.CursorPosPrevLine.y;
}
else
{
if (spacing_w < 0) spacing_w = (int)g.Style.ItemSpacing.x;
x = window->DC.CursorPosPrevLine.x + (float)spacing_w;
if (spacing_w < 0.0f) spacing_w = g.Style.ItemSpacing.x;
x = window->DC.CursorPosPrevLine.x + spacing_w;
y = window->DC.CursorPosPrevLine.y;
}
window->DC.CurrentLineHeight = window->DC.PrevLineHeight;
@ -11368,7 +11379,7 @@ void ImGui::ShowTestWindow(bool* opened)
}
}
ImGui::PlotLines("##Graph", &values.front(), (int)values.Size, values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80));
ImGui::SameLine(0, (int)ImGui::GetStyle().ItemInnerSpacing.x);
ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
ImGui::BeginGroup();
ImGui::Text("Graph");
ImGui::Checkbox("pause", &pause);

View file

@ -170,7 +170,7 @@ namespace ImGui
IMGUI_API void BeginGroup(); // once closing a group it is seen as a single item (so you can use IsItemHovered() on a group, SameLine() between groups, etc.
IMGUI_API void EndGroup();
IMGUI_API void Separator(); // horizontal line
IMGUI_API void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets or groups to layout them horizontally
IMGUI_API void SameLine(float pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally
IMGUI_API void Spacing(); // add spacing
IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size
IMGUI_API void Indent(); // move content position toward the right by style.IndentSpacing pixels
@ -461,6 +461,8 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character.
ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field
ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, allow exiting edition by pressing Enter. Ctrl+Enter to add new line (by default adds new lines with Enter).
ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally
ImGuiInputTextFlags_AlwaysInsertMode = 1 << 13, // Insert mode
// [Internal]
ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline()
};
@ -920,6 +922,7 @@ struct ImGuiTextEditCallbackData
// NB: calling those function loses selection.
void DeleteChars(int pos, int bytes_count);
void InsertChars(int pos, const char* text, const char* text_end = NULL);
bool HasSelection() const { return SelectionStart != SelectionEnd; }
};
// ImColor() is just a helper that implicity converts to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float)

210
3rdparty/ocornut-imgui/memory_editor.h vendored Normal file
View file

@ -0,0 +1,210 @@
// Mini memory editor for ImGui (to embed in your game/tools)
// v0.10
//
// You can adjust the keyboard repeat delay/rate in ImGuiIO.
// The code assume a mono-space font for simplicity! If you don't use the default font, use ImGui::PushFont()/PopFont() to switch to a mono-space font before caling this.
//
// Usage:
// static MemoryEditor memory_editor; // save your state somewhere
// memory_editor.Draw("Memory Editor", mem_block, mem_block_size, (size_t)mem_block); // run
//
// TODO: better resizing policy (ImGui doesn't have flexible window resizing constraints yet)
struct MemoryEditor
{
bool Open;
bool AllowEdits;
int Rows;
int DataEditingAddr;
bool DataEditingTakeFocus;
char DataInput[32];
char AddrInput[32];
MemoryEditor()
{
Open = true;
Rows = 16;
DataEditingAddr = -1;
DataEditingTakeFocus = false;
strcpy(DataInput, "");
strcpy(AddrInput, "");
AllowEdits = true;
}
void Draw(const char* title, unsigned char* mem_data, int mem_size, size_t base_display_addr = 0)
{
if (ImGui::Begin(title, &Open))
{
ImGui::BeginChild("##scrolling", ImVec2(0, -ImGui::GetItemsLineHeightWithSpacing()));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));
int addr_digits_count = 0;
for (int n = base_display_addr + mem_size - 1; n > 0; n >>= 4)
addr_digits_count++;
float glyph_width = ImGui::CalcTextSize("F").x;
float cell_width = glyph_width * 3; // "FF " we include trailing space in the width to easily catch clicks everywhere
float line_height = ImGui::GetTextLineHeight();
int line_total_count = (int)((mem_size + Rows-1) / Rows);
ImGuiListClipper clipper(line_total_count, line_height);
int visible_start_addr = clipper.DisplayStart * Rows;
int visible_end_addr = clipper.DisplayEnd * Rows;
bool data_next = false;
if (!AllowEdits || DataEditingAddr >= mem_size)
DataEditingAddr = -1;
int data_editing_addr_backup = DataEditingAddr;
if (DataEditingAddr != -1)
{
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)) && DataEditingAddr >= Rows) { DataEditingAddr -= Rows; DataEditingTakeFocus = true; }
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)) && DataEditingAddr < mem_size - Rows) { DataEditingAddr += Rows; DataEditingTakeFocus = true; }
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow)) && DataEditingAddr > 0) { DataEditingAddr -= 1; DataEditingTakeFocus = true; }
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow)) && DataEditingAddr < mem_size - 1) { DataEditingAddr += 1; DataEditingTakeFocus = true; }
}
if ((DataEditingAddr / Rows) != (data_editing_addr_backup / Rows))
{
// Track cursor movements
float scroll_offset = ((DataEditingAddr / Rows) - (data_editing_addr_backup / Rows)) * line_height;
bool scroll_desired = (scroll_offset < 0.0f && DataEditingAddr < visible_start_addr + Rows*2) || (scroll_offset > 0.0f && DataEditingAddr > visible_end_addr - Rows*2);
if (scroll_desired)
ImGui::SetScrollY(ImGui::GetScrollY() + scroll_offset);
}
bool draw_separator = true;
for (int line_i = clipper.DisplayStart; line_i < clipper.DisplayEnd; line_i++) // display only visible items
{
int addr = line_i * Rows;
ImGui::Text("%0*X: ", addr_digits_count, base_display_addr+addr);
ImGui::SameLine();
// Draw Hexadecimal
float line_start_x = ImGui::GetCursorPosX();
for (int n = 0; n < Rows && addr < mem_size; n++, addr++)
{
ImGui::SameLine(line_start_x + cell_width * n);
if (DataEditingAddr == addr)
{
// Display text input on current byte
ImGui::PushID(addr);
struct FuncHolder
{
// FIXME: We should have a way to retrieve the text edit cursor position more easily in the API, this is rather tedious.
static int Callback(ImGuiTextEditCallbackData* data)
{
int* p_cursor_pos = (int*)data->UserData;
if (!data->HasSelection())
*p_cursor_pos = data->CursorPos;
return 0;
}
};
int cursor_pos = -1;
bool data_write = false;
if (DataEditingTakeFocus)
{
ImGui::SetKeyboardFocusHere();
sprintf(AddrInput, "%0*X", addr_digits_count, base_display_addr+addr);
sprintf(DataInput, "%02X", mem_data[addr]);
}
ImGui::PushItemWidth(ImGui::CalcTextSize("FF").x);
ImGuiInputTextFlags flags = ImGuiInputTextFlags_CharsHexadecimal|ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_AutoSelectAll|ImGuiInputTextFlags_NoHorizontalScroll|ImGuiInputTextFlags_AlwaysInsertMode|ImGuiInputTextFlags_CallbackAlways;
if (ImGui::InputText("##data", DataInput, 32, flags, FuncHolder::Callback, &cursor_pos))
data_write = data_next = true;
else if (!DataEditingTakeFocus && !ImGui::IsItemActive())
DataEditingAddr = -1;
DataEditingTakeFocus = false;
ImGui::PopItemWidth();
if (cursor_pos >= 2)
data_write = data_next = true;
if (data_write)
{
int data;
if (sscanf(DataInput, "%X", &data) == 1)
mem_data[addr] = (unsigned char)data;
}
ImGui::PopID();
}
else
{
ImGui::Text("%02X ", mem_data[addr]);
if (AllowEdits && ImGui::IsItemHovered() && ImGui::IsMouseClicked(0))
{
DataEditingTakeFocus = true;
DataEditingAddr = addr;
}
}
}
ImGui::SameLine(line_start_x + cell_width * Rows + glyph_width * 2);
if (draw_separator)
{
ImVec2 screen_pos = ImGui::GetCursorScreenPos();
ImGui::GetWindowDrawList()->AddLine(ImVec2(screen_pos.x - glyph_width, screen_pos.y - 9999), ImVec2(screen_pos.x - glyph_width, screen_pos.y + 9999), ImColor(ImGui::GetStyle().Colors[ImGuiCol_Border]));
draw_separator = false;
}
// Draw ASCII values
addr = line_i * Rows;
for (int n = 0; n < Rows && addr < mem_size; n++, addr++)
{
if (n > 0) ImGui::SameLine();
int c = mem_data[addr];
ImGui::Text("%c", (c >= 32 && c < 128) ? c : '.');
}
}
clipper.End();
ImGui::PopStyleVar(2);
ImGui::EndChild();
if (data_next && DataEditingAddr < mem_size)
{
DataEditingAddr = DataEditingAddr + 1;
DataEditingTakeFocus = true;
}
ImGui::Separator();
ImGui::AlignFirstTextHeightToWidgets();
ImGui::PushItemWidth(50);
ImGui::PushAllowKeyboardFocus(false);
int rows_backup = Rows;
if (ImGui::DragInt("##rows", &Rows, 0.2f, 4, 32, "%.0f rows"))
{
ImVec2 new_window_size = ImGui::GetWindowSize();
new_window_size.x += (Rows - rows_backup) * (cell_width + glyph_width);
ImGui::SetWindowSize(new_window_size);
}
ImGui::PopAllowKeyboardFocus();
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::Text("Range %0*X..%0*X", addr_digits_count, (int)base_display_addr, addr_digits_count, (int)base_display_addr+mem_size-1);
ImGui::SameLine();
ImGui::PushItemWidth(70);
if (ImGui::InputText("##addr", AddrInput, 32, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_EnterReturnsTrue))
{
int goto_addr;
if (sscanf(AddrInput, "%X", &goto_addr) == 1)
{
goto_addr -= base_display_addr;
if (goto_addr >= 0 && goto_addr < mem_size)
{
ImGui::BeginChild("##scrolling");
ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + (goto_addr / Rows) * ImGui::GetTextLineHeight());
ImGui::EndChild();
DataEditingAddr = goto_addr;
DataEditingTakeFocus = true;
}
}
}
ImGui::PopItemWidth();
}
ImGui::End();
}
};