Merge branch 'master' into docking

This commit is contained in:
ocornut
2024-09-12 23:19:26 +02:00
10 changed files with 309 additions and 209 deletions
+15 -1
View File
@@ -527,6 +527,7 @@ jobs:
emsdk-master/emsdk update
emsdk-master/emsdk install latest
emsdk-master/emsdk activate latest
sudo apt-get install build-essential
- name: Build example_sdl2_opengl3 with Emscripten
run: |
@@ -535,13 +536,26 @@ jobs:
popd
make -C examples/example_sdl2_opengl3 -f Makefile.emscripten
- name: Build example_glfw_wgpu
# This build compiles example_glfw_wgpu using Makefile.emscripten and Emscripten GLFW built-in implementation (-sUSE_GLFW=3)
# This ensures 2 things: the make build works, and the GLFW built-in implementation is tested
- name: Build example_glfw_wgpu with Emscripten/Makefile
run: |
pushd emsdk-master
source ./emsdk_env.sh
popd
make -C examples/example_glfw_wgpu -f Makefile.emscripten
# This build compiles example_glfw_wgpu using CMakeLists.txt and Emscripten GLFW contrib port (--use-port=contrib.glfw3)
# This ensures 2 things: the CMake build works, and the GLFW contrib port is tested
- name: Build example_glfw_wgpu with Emscripten/CMake
run: |
pushd emsdk-master
source ./emsdk_env.sh
popd
emcc -v
emcmake cmake -B build -DCMAKE_BUILD_TYPE=Release examples/example_glfw_wgpu
cmake --build build
Android:
runs-on: ubuntu-24.04
steps:
+23 -1
View File
@@ -21,6 +21,11 @@
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
// About Emscripten support:
// - Emscripten provides its own GLFW (3.2.1) implementation (syntax: "-sUSE_GLFW=3"), but Joystick is broken and several features are not supported (multiple windows, clipboard, timer, etc.)
// - A third-party Emscripten GLFW (3.4.0) implementation (syntax: "--use-port=contrib.glfw3") fixes the Joystick issue and implements all relevant features for the browser.
// See https://github.com/pongasoft/emscripten-glfw/blob/master/docs/Comparison.md for details.
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
@@ -576,7 +581,7 @@ void ImGui_ImplGlfw_SetCallbacksChainForAllWindows(bool chain_for_all_windows)
}
#ifdef __EMSCRIPTEN__
#if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 3'4'0'20240817
#if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
void ImGui_ImplGlfw_EmscriptenOpenURL(const char* url) { if (url) emscripten::glfw3::OpenURL(url); }
#else
EM_JS(void, ImGui_ImplGlfw_EmscriptenOpenURL, (const char* url), { url = url ? UTF8ToString(url) : null; if (url) window.open(url, '_blank'); });
@@ -668,6 +673,23 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
#endif
// Emscripten: the same application can run on various platforms, so we detect the Apple platform at runtime
// to override io.ConfigMacOSXBehaviors from its default (which is always false in Emscripten).
#ifdef __EMSCRIPTEN__
#if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
if (emscripten::glfw3::IsRuntimePlatformApple())
{
ImGui::GetIO().ConfigMacOSXBehaviors = true;
// Due to how the browser (poorly) handles the Meta Key, this line essentially disables repeats when used.
// This means that Meta + V only registers a single key-press, even if the keys are held.
// This is a compromise for dealing with this issue in ImGui since ImGui implements key repeat itself.
// See https://github.com/pongasoft/emscripten-glfw/blob/v3.4.0.20240817/docs/Usage.md#the-problem-of-the-super-key
emscripten::glfw3::SetSuperPlusKeyTimeouts(10, 10);
}
#endif
#endif
bd->ClientApi = client_api;
return true;
}
+9
View File
@@ -63,9 +63,18 @@ Other changes:
#6223, #6364, #6387, #6567, #6692, #6724, #6939, #6984, #7246, #7270, #7375, #7421, #7434,
#7472, #7581, #7724, #7926, #7937 and probably more..)
- Nav: pressing any keyboard key while holding Alt disable toggling nav layer on Alt release. (#4439)
- MultiSelect+Tables: fixed an issue where box-select would skip items while drag-scrolling
in a table with outer borders. (#7970, #7821).
- InputText: internal refactoring to simplify and optimize the code. The ImWchar buffer has been
removed. Simplifications allowed to implement new optimizations for handling very large text buffers
(e.g. in our testing, handling of a 1 MB text buffer is now 3 times faster in VS2022 Debug build).
This is the first step toward more refactorig. (#7925) [@alektron, @ocornut]
- InputText: added CJK double-width punctuation to list of separators considered for CTRL+Arrow.
- Fonts: fixed ellipsis "..." rendering width miscalculation bug introduced in 1.91.0. (#7976) [@DDeimos]
- TextLinkOpenURL(): modified tooltip to display a verb "Open 'xxxx'". (#7885, #7660)
- Backends: SDL2: use SDL_Vulkan_GetDrawableSize() when available. (#7967, #3190) [@scribam]
- Backends: GLFW+Emscripten: use OSX behaviors automatically when using contrib glfw port. (#7965, #7915)
[@ypujante]
Docking+Viewports Branch:
-1
View File
@@ -65,7 +65,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- selectable: generic BeginSelectable()/EndSelectable() mechanism. (work out alongside range-select branch)
- selectable: a way to visualize partial/mixed selection (e.g. parent tree node has children with mixed selection)
- input text: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile. (WIP branch)
- input text: preserve scrolling when unfocused?
- input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541)
- input text: expose CursorPos in char filter event (#816)
@@ -91,7 +91,6 @@ if(EMSCRIPTEN)
if("${IMGUI_EMSCRIPTEN_GLFW3}" STREQUAL "--use-port=contrib.glfw3")
target_compile_options(example_glfw_wgpu PUBLIC
"${IMGUI_EMSCRIPTEN_GLFW3}"
"-DEMSCRIPTEN_USE_PORT_CONTRIB_GLFW3" # unnecessary beyond emscripten 3.1.59
)
endif()
message(STATUS "Using ${IMGUI_EMSCRIPTEN_GLFW3} GLFW implementation")
+3 -3
View File
@@ -2035,7 +2035,7 @@ const char* ImStreolRange(const char* str, const char* str_end)
return p ? p : str_end;
}
const ImWchar* ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin) // find beginning-of-line
const char* ImStrbol(const char* buf_mid_line, const char* buf_begin) // find beginning-of-line
{
while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n')
buf_mid_line--;
@@ -4097,7 +4097,7 @@ static void SetCurrentWindow(ImGuiWindow* window)
if (window)
{
g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
g.FontScale = g.FontSize / g.Font->FontSize;
g.FontScale = g.DrawListSharedData.FontScale = g.FontSize / g.Font->FontSize;
ImGui::NavUpdateCurrentWindowIsScrollPushableX();
}
}
@@ -9663,7 +9663,7 @@ bool ImGui::IsKeyPressed(ImGuiKey key, bool repeat)
return IsKeyPressed(key, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None, ImGuiKeyOwner_Any);
}
// Important: unless legacy IsKeyPressed(ImGuiKey, bool repeat=true) which DEFAULT to repeat, this requires EXPLICIT repeat.
// Important: unlike legacy IsKeyPressed(ImGuiKey, bool repeat=true) which DEFAULT to repeat, this requires EXPLICIT repeat.
bool ImGui::IsKeyPressed(ImGuiKey key, ImGuiInputFlags flags, ImGuiID owner_id)
{
const ImGuiKeyData* key_data = GetKeyData(key);
+1 -1
View File
@@ -29,7 +29,7 @@
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.91.2 WIP"
#define IMGUI_VERSION_NUM 19113
#define IMGUI_VERSION_NUM 19114
#define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
#define IMGUI_HAS_DOCK // Docking WIP branch
+8 -8
View File
@@ -377,7 +377,7 @@ IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end
IMGUI_API void ImStrTrimBlanks(char* str); // Remove leading and trailing blanks from a buffer.
IMGUI_API const char* ImStrSkipBlank(const char* str); // Find first non-blank character.
IMGUI_API int ImStrlenW(const ImWchar* str); // Computer string length (ImWchar string)
IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line (ImWchar string)
IMGUI_API const char* ImStrbol(const char* buf_mid_line, const char* buf_begin); // Find beginning-of-line
IM_MSVC_RUNTIME_CHECKS_OFF
static inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; }
static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
@@ -1108,7 +1108,7 @@ struct IMGUI_API ImGuiInputTextDeactivatedState
#undef IMSTB_TEXTEDIT_STRING
#undef IMSTB_TEXTEDIT_CHARTYPE
#define IMSTB_TEXTEDIT_STRING ImGuiInputTextState
#define IMSTB_TEXTEDIT_CHARTYPE ImWchar
#define IMSTB_TEXTEDIT_CHARTYPE char
#define IMSTB_TEXTEDIT_GETWIDTH_NEWLINE (-1.0f)
#define IMSTB_TEXTEDIT_UNDOSTATECOUNT 99
#define IMSTB_TEXTEDIT_UNDOCHARCOUNT 999
@@ -1122,11 +1122,10 @@ struct IMGUI_API ImGuiInputTextState
ImGuiContext* Ctx; // parent UI context (needs to be set explicitly by parent).
ImStbTexteditState* Stb; // State for stb_textedit.h
ImGuiID ID; // widget id owning the text state
int CurLenW, CurLenA; // we need to maintain our buffer length in both UTF-8 and wchar format. UTF-8 length is valid even if TextA is not.
ImVector<ImWchar> TextW; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer.
ImVector<char> TextA; // temporary UTF8 buffer for callbacks and other operations. this is not updated in every code-path! size=capacity.
int CurLenA; // UTF-8 length of the string in TextA (in bytes)
ImVector<char> TextA; // main UTF8 buffer.
ImVector<char> InitialTextA; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered)
bool TextAIsValid; // temporary UTF8 buffer is not initially valid before we make the widget active (until then we pull the data from user argument)
ImVector<char> CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack
int BufCapacityA; // end-user buffer capacity
ImVec2 Scroll; // horizontal offset (managed manually) + vertical scrolling (pulled from child window's own Scroll.y)
float CursorAnim; // timer for cursor blink, reset on every user action so the cursor reappears immediately
@@ -1140,9 +1139,10 @@ struct IMGUI_API ImGuiInputTextState
ImGuiInputTextState();
~ImGuiInputTextState();
void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); }
void ClearFreeMemory() { TextW.clear(); TextA.clear(); InitialTextA.clear(); }
void ClearText() { CurLenA = 0; TextA[0] = 0; CursorClamp(); }
void ClearFreeMemory() { TextA.clear(); InitialTextA.clear(); }
void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation
void OnCharPressed(unsigned int c);
// Cursor & Selection
void CursorAnimReset();
+189 -159
View File
File diff suppressed because it is too large Load Diff
+61 -34
View File
@@ -4,6 +4,7 @@
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
// - Added name to struct or it may be forward declared in our code.
// - Added UTF-8 support (see https://github.com/nothings/stb/issues/188 + https://github.com/ocornut/imgui/pull/7925)
// Grep for [DEAR IMGUI] to find the changes.
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
@@ -210,6 +211,7 @@
// int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
// int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
// void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXEDIT_KEYTYPE key)
// void stb_textedit_text(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int text_len)
//
// Each of these functions potentially updates the string and updates the
// state.
@@ -244,7 +246,12 @@
// various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit
// set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is
// clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to
// anything other type you wante before including.
// anything other type you want before including.
// if the STB_TEXTEDIT_KEYTOTEXT function is defined, selected keys are
// transformed into text and stb_textedit_text() is automatically called.
//
// text: [DEAR IMGUI] added 2024-09
// call this to text inputs sent to the textfield.
//
//
// When rendering, you can read the cursor position and selection state from
@@ -439,13 +446,13 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
if (x < r.x1) {
// search characters in row for one that straddles 'x'
prev_x = r.x0;
for (k=0; k < r.num_chars; ++k) {
for (k=0; k < r.num_chars; k = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, i + k) - i) {
float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
if (x < prev_x+w) {
if (x < prev_x+w/2)
return k+i;
else
return k+i+1;
return IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, i + k);
}
prev_x += w;
}
@@ -564,7 +571,7 @@ static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING
// now scan to find xpos
find->x = r.x0;
for (i=0; first+i < n; ++i)
for (i=0; first+i < n; i = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, first + i) - first)
find->x += STB_TEXTEDIT_GETWIDTH(str, first, i);
}
@@ -641,6 +648,17 @@ static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditSt
}
}
// [DEAR IMGUI]
// Functions must be implemented for UTF8 support
// Code in this file that uses those functions is modified for [DEAR IMGUI] and deviates from the original stb_textedit.
// There is not necessarily a '[DEAR IMGUI]' at the usage sites.
#ifndef IMSTB_TEXTEDIT_GETPREVCHARINDEX
#define IMSTB_TEXTEDIT_GETPREVCHARINDEX(obj, idx) (idx - 1)
#endif
#ifndef IMSTB_TEXTEDIT_GETNEXTCHARINDEX
#define IMSTB_TEXTEDIT_GETNEXTCHARINDEX(obj, idx) (idx + 1)
#endif
#ifdef STB_TEXTEDIT_IS_SPACE
static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
{
@@ -721,36 +739,44 @@ static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditS
#define STB_TEXTEDIT_KEYTYPE int
#endif
// [DEAR IMGUI] Added stb_textedit_text(), extracted out and called by stb_textedit_key() for backward compatibility.
static void stb_textedit_text(IMSTB_TEXTEDIT_STRING* str, STB_TexteditState* state, const IMSTB_TEXTEDIT_CHARTYPE* text, int text_len)
{
// can't add newline in single-line mode
if (text[0] == '\n' && state->single_line)
return;
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
state->cursor += text_len;
state->has_preferred_x = 0;
}
}
else {
stb_textedit_delete_selection(str, state); // implicitly clamps
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
stb_text_makeundo_insert(state, state->cursor, text_len);
state->cursor += text_len;
state->has_preferred_x = 0;
}
}
}
// API key: process a keyboard input
static void stb_textedit_key(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
{
retry:
switch (key) {
default: {
#ifdef STB_TEXTEDIT_KEYTOTEXT
int c = STB_TEXTEDIT_KEYTOTEXT(key);
if (c > 0) {
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE) c;
// can't add newline in single-line mode
if (c == '\n' && state->single_line)
break;
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
++state->cursor;
state->has_preferred_x = 0;
}
} else {
stb_textedit_delete_selection(str,state); // implicitly clamps
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
stb_text_makeundo_insert(state, state->cursor, 1);
++state->cursor;
state->has_preferred_x = 0;
}
}
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE)c;
stb_textedit_text(str, state, &ch, 1);
}
#endif
break;
}
@@ -776,7 +802,7 @@ retry:
stb_textedit_move_to_first(state);
else
if (state->cursor > 0)
--state->cursor;
state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
state->has_preferred_x = 0;
break;
@@ -785,7 +811,7 @@ retry:
if (STB_TEXT_HAS_SELECTION(state))
stb_textedit_move_to_last(str, state);
else
++state->cursor;
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
stb_textedit_clamp(str, state);
state->has_preferred_x = 0;
break;
@@ -795,7 +821,7 @@ retry:
stb_textedit_prep_selection_at_cursor(state);
// move selection left
if (state->select_end > 0)
--state->select_end;
state->select_end = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->select_end);
state->cursor = state->select_end;
state->has_preferred_x = 0;
break;
@@ -845,7 +871,7 @@ retry:
case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT:
stb_textedit_prep_selection_at_cursor(state);
// move selection right
++state->select_end;
state->select_end = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->select_end);
stb_textedit_clamp(str, state);
state->cursor = state->select_end;
state->has_preferred_x = 0;
@@ -901,7 +927,7 @@ retry:
x += dx;
if (x > goal_x)
break;
++state->cursor;
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
}
stb_textedit_clamp(str, state);
@@ -963,7 +989,7 @@ retry:
x += dx;
if (x > goal_x)
break;
++state->cursor;
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
}
stb_textedit_clamp(str, state);
@@ -991,7 +1017,7 @@ retry:
else {
int n = STB_TEXTEDIT_STRINGLEN(str);
if (state->cursor < n)
stb_textedit_delete(str, state, state->cursor, 1);
stb_textedit_delete(str, state, state->cursor, IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor) - state->cursor);
}
state->has_preferred_x = 0;
break;
@@ -1003,8 +1029,9 @@ retry:
else {
stb_textedit_clamp(str, state);
if (state->cursor > 0) {
stb_textedit_delete(str, state, state->cursor-1, 1);
--state->cursor;
int prev = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
stb_textedit_delete(str, state, prev, state->cursor - prev);
state->cursor = prev;
}
}
state->has_preferred_x = 0;