Recent big changes (1.60 WIP): CreateContext() required + Navigation Beta available
ocornut opened this issue · 9 comments
Two things have made it into master today:
- Context creation is now explicit + refactored context/allocators related functions (#1565)
- The gamepad/keyboard navigation branch has been merged as Beta. (#787)
The first change is relatively small but will break your code until you call CreateContext()
. This motivated me to bump the version number from 1.54 WIP to 1.60 WIP.
Context Creation
If you are not using multiple contexts or reassigning allocators, you still need to make 2 small changes:
- You will need to call ImGui::CreateContext()
once before using ImGui.
Similarly you probably want to call ImGui::DestroyContext()
at the end of your application.
- There was a function ImGui::Shutdown()
that the sample code in imgui_impl_xxx.cpp were calling. This function doesn't exist any more. You need to remove this line from your old copy of imgui_imgul_xxx.cpp, or update your copy of it. This is being replaced by DestroyContext
and it isn't the job of imgui_impl_xxx to make that call.
If you are using multiple contexts, see #1565 for more details.
Memory Allocators
If you are reassigning memory allocators. The allocators are now global and not stored on a per-context basis, which was causing too much trouble. You can call ImGui::SetAllocatorFunctions()
if you need to override them (they default to malloc/free).
Keyboard Navigation
You can enable Beta keyboard navigation by setting:
io.NavFlags |= ImGuiNavFlags_EnableKeyboard
.
Note that a new ImGuiKey enum ImGuiKey_Space
was added that didn't exist before and you need to map it to use keyboard navigation. e.g.
// Win32 bindings
io.KeyMap[ImGuiKey_Space] = VK_SPACE;
// GLFW bindings
io.KeyMap[ImGuiKey_Space] = GLFW_KEY_SPACE;
// SDL bindings
io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE;
etc.
If you enable keyboard navigation but haven't set up this new key, NewFrame() will assert as a reminder.
If your code used a copy of the imgui_impl_xxx bindings it will be a good occasion to update them.
If your code used its own input binding you'll need to update that if you want to use keyboard navigation. Keyboard navigation is still in beta, you may post feedback/issue in #787.
With keyboard navigation you can use/activate most of dear imgui features from the keyboard:
- ALT to access menus.
- Arrow keys to move.
- Space to activate buttons, sliders, tree node, enter into child nodes, etc.
- Escape to close popups, exit a child window, clear selection.
- Enter to input text.
- CTRL-Tab (CTRL-Shift-Tab) to focus windows, etc.
It took a crazy amount of work to get this working nicely with the imgui paradigm and with the fact that dear imgui has little restriction on e.g the contents of menus, or the ability of lay out multiple items on one line, not mentioning that we don't have a fully retained understand of the UI. This is not a standard OS keyboard navigation scheme because the application you build with imgui are not following standard scheme. So it may be odd, incomplete and will definitively have issues, but we'll work through them over time.
Gamepad Navigation
You can enable Beta gamepad navigation by setting:
io.NavFlags |= ImGuiNavFlags_EnableGamepad
.
And fill the io.NavInputs[]
array.
enum ImGuiNavInput_
{
// Gamepad Mapping
ImGuiNavInput_Activate, // activate / open / toggle / tweak value // e.g. Circle (PS4), A (Xbox), B (Switch), Space (Keyboard)
ImGuiNavInput_Cancel, // cancel / close / exit // e.g. Cross (PS4), B (Xbox), A (Switch), Escape (Keyboard)
ImGuiNavInput_Input, // text input / on-screen keyboard // e.g. Triang.(PS4), Y (Xbox), X (Switch), Return (Keyboard)
ImGuiNavInput_Menu, // tap: toggle menu / hold: focus, move, resize // e.g. Square (PS4), X (Xbox), Y (Switch), Alt (Keyboard)
ImGuiNavInput_DpadLeft, // move / tweak / resize window (w/ PadMenu) // e.g. D-pad Left/Right/Up/Down (Gamepads), Arrow keys (Keyboard)
ImGuiNavInput_DpadRight, //
ImGuiNavInput_DpadUp, //
ImGuiNavInput_DpadDown, //
ImGuiNavInput_LStickLeft, // scroll / move window (w/ PadMenu) // e.g. Left Analog Stick Left/Right/Up/Down
ImGuiNavInput_LStickRight, //
ImGuiNavInput_LStickUp, //
ImGuiNavInput_LStickDown, //
ImGuiNavInput_FocusPrev, // next window (w/ PadMenu) // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch)
ImGuiNavInput_FocusNext, // prev window (w/ PadMenu) // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch)
ImGuiNavInput_TweakSlow, // slower tweaks // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch)
ImGuiNavInput_TweakFast, // faster tweaks // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch)
Here's some handy pictures depicting the controls for common controllers:
Edit Added images + PSD link
https://drive.google.com/drive/folders/1k4328OV-w20pWZfNcfpH0UoxHHQRkbQi
Gamepad navigation is still in beta, you may post feedback/issue in #787.
Rendering
This is not a new change but I feel the need to reiterate that you don't need to set a render function in io.RenderDrawListsFn
any more (that function was then automatically called by ImGui::Render()
). Instead you can call ImDrawData* ImGui::GetDrawData()
to obtain a pointer to the stuff to content and pass that around as you wish. So there's no more callback involved which is more flexible.
ImGui::Render()
MyDrawFunction(ImGui::GetDrawData());
So technically io.RenderDrawListsFn
is going to eventually be obsoleted (maybe in imgui 2.0) because it's less flexible. I'll update the example applications to use GetDrawData()
soon.
Styles
Still will be revamped. In the meanwhile I have added 3 helpers functions to call in default styles: StyleColorsClassic()
, StyleColorsDark()
, StyleColorsLight()
. I also changed the examples application to call it StyleColorsDark()
by default to make the default 1.60 experience better.
What next?
- Need to make the examples application to be hi-dpi aware, because the current experience with them is very poor especially using the default pixelly font. I normally leave it to people to figure out DPI on their side but the example application needs to provide a better first impression.
- Will keep improving/fixing keyboard and gamepad navigation based on your feedback.
- Upcoming big feature will be the virtual viewports #1542 and docking #351. I have no ETA for those yet, sorry.
- Need to add a proper auto-testing suite.
EDIT
When you update always check out the API BREAKING CHANGES section at the top of imgui.cpp. Changes that may affect codebases/behavior should be listed here.
Do you have any vision or direction for the auto-testing suite? That's something I would like to help out with, as I could kill two birds with one stone (learn APIs while also contributing to the project).
@gerryhernandez The only things are the rough ideas written down in the old thread #435 (which was left abandoned, my bad). I think at the time I was mostly focusing on visual/documentation, whereas today I would put more focus on the testing aspect of it. Let's move over that topic.
Thank you for the update! <3
Congratulations for your big work :-)
Now, reading (e.g.) the last Windowmaker changes, I'm a little confused : does ImGui slowly become sort of window manager OpenGL / DirectX based , but more powerfull (several backends, and so on) ?
e.g., reading http://repo.or.cz/wmaker-crm.git/blob/HEAD:/NEWS I see a lot of similarities (I previously read Sawfish code too, and I had this feeling). But maybe there is something important I did not understand.
Complementary link (in french) : https://fr.wikipedia.org/wiki/Window_Maker
Now, reading (e.g.) the last Windowmaker changes, I'm a little confused : does ImGui slowly become sort of window manager OpenGL / DirectX based , but more powerfull (several backends, and so on) ?
Not sure I understand nor how to answer the question. Dear ImGui wants to empower developers to create tools, and it'll improve toward that goal. It's a very different goal than WindowMaker, even though there is a small amount of overlap in sort the things they need to do. There was always a little bit of "window management" inside imgui since you can move windows around, in essence imgui is its own window manager within your app.
Closing this informational topic now (it is being linked from 1.60 release notes)
Thanks for making all this stuff!
By the way, currently you have this in comments (in imgui.h):
ImGuiNavInput_Activate, // activate / open / toggle / tweak value // e.g. Circle (PS4), A (Xbox), A (Switch), Space (Keyboard)
ImGuiNavInput_Cancel, // cancel / close / exit // e.g. Cross (PS4), B (Xbox), B (Switch), Escape (Keyboard)
Shouldn't Circle and Cross be switched?
Shouldn't Circle and Cross be switched?
Correct, I'll fix the comment note.
That that A/B are on different side on the Xbox and Switch controller.
The fact that Enter uses "A" and Cancel uses "B" for both is actually intentional, since the Nintendo usage convention is to use A (on the right) for validation, B (on the left) for back, whereas Xbox usage convention is to use A (on the left) for validation, B (on the left) for back. PS4 usage convention is actually different in Asia vs the rest of the world. People who are affected and care will map the button however they want, this is merely a suggestion.
Yes, I fully agree with "A" and "B" differences on Switch and Xbox. :)