From f1a7e1696d8194d8f02fa01cba5a5d7d3e2027ac Mon Sep 17 00:00:00 2001 From: Dario Manesku Date: Tue, 5 Aug 2014 20:57:52 +0100 Subject: [PATCH 1/5] Added setWindowTitle(). --- examples/common/entry/entry.h | 5 +++++ examples/common/entry/entry_android.cpp | 5 +++++ examples/common/entry/entry_asmjs.cpp | 5 +++++ examples/common/entry/entry_ios.mm | 5 +++++ examples/common/entry/entry_linux.cpp | 5 +++++ examples/common/entry/entry_nacl.cpp | 5 +++++ examples/common/entry/entry_osx.mm | 5 +++++ examples/common/entry/entry_p.h | 4 ---- examples/common/entry/entry_qnx.cpp | 5 +++++ examples/common/entry/entry_sdl.cpp | 10 ++++++++++ examples/common/entry/entry_windows.cpp | 12 +++++++++++- 11 files changed, 61 insertions(+), 5 deletions(-) diff --git a/examples/common/entry/entry.h b/examples/common/entry/entry.h index 36dbd84e..5b40b7f4 100644 --- a/examples/common/entry/entry.h +++ b/examples/common/entry/entry.h @@ -146,6 +146,11 @@ namespace entry bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse = NULL); + void setWindowSize(uint32_t _width, uint32_t _height); + bool setWindowTitle(const char* _title); + void toggleWindowFrame(); + void setMouseLock(bool _lock); + bx::FileReaderI* getFileReader(); bx::FileWriterI* getFileWriter(); diff --git a/examples/common/entry/entry_android.cpp b/examples/common/entry/entry_android.cpp index 6586be50..16847e4a 100644 --- a/examples/common/entry/entry_android.cpp +++ b/examples/common/entry/entry_android.cpp @@ -207,6 +207,11 @@ namespace entry BX_UNUSED(_width, _height); } + bool setWindowTitle(const char* _title) + { + BX_UNUSED(_title); + } + void toggleWindowFrame() { } diff --git a/examples/common/entry/entry_asmjs.cpp b/examples/common/entry/entry_asmjs.cpp index c6b84cae..1e0c32df 100644 --- a/examples/common/entry/entry_asmjs.cpp +++ b/examples/common/entry/entry_asmjs.cpp @@ -24,6 +24,11 @@ namespace entry { } + bool setWindowTitle(const char* _title) + { + BX_UNUSED(_title); + } + void toggleWindowFrame() { } diff --git a/examples/common/entry/entry_ios.mm b/examples/common/entry/entry_ios.mm index e35c7ef2..ebca9267 100644 --- a/examples/common/entry/entry_ios.mm +++ b/examples/common/entry/entry_ios.mm @@ -86,6 +86,11 @@ namespace entry BX_UNUSED(_width, _height); } + bool setWindowTitle(const char* _title) + { + BX_UNUSED(_title); + } + void toggleWindowFrame() { } diff --git a/examples/common/entry/entry_linux.cpp b/examples/common/entry/entry_linux.cpp index a4361eae..27e80453 100644 --- a/examples/common/entry/entry_linux.cpp +++ b/examples/common/entry/entry_linux.cpp @@ -326,6 +326,11 @@ namespace entry XSendEvent(s_ctx.m_display, s_ctx.m_window, false, ResizeRedirectMask, (XEvent*)&ev); } + bool setWindowTitle(const char* _title) + { + BX_UNUSED(_title); + } + void toggleWindowFrame() { } diff --git a/examples/common/entry/entry_nacl.cpp b/examples/common/entry/entry_nacl.cpp index 72536ac6..d06b3f5e 100644 --- a/examples/common/entry/entry_nacl.cpp +++ b/examples/common/entry/entry_nacl.cpp @@ -61,6 +61,11 @@ namespace entry BX_UNUSED(_width, _height); } + bool setWindowTitle(const char* _title) + { + BX_UNUSED(_title); + } + void toggleWindowFrame() { } diff --git a/examples/common/entry/entry_osx.mm b/examples/common/entry/entry_osx.mm index 5ef7ba46..53cf0a31 100644 --- a/examples/common/entry/entry_osx.mm +++ b/examples/common/entry/entry_osx.mm @@ -281,6 +281,11 @@ namespace entry BX_UNUSED(_width, _height); } + bool setWindowTitle(const char* _title) + { + BX_UNUSED(_title); + } + void toggleWindowFrame() { } diff --git a/examples/common/entry/entry_p.h b/examples/common/entry/entry_p.h index 140e7d15..4125b09a 100644 --- a/examples/common/entry/entry_p.h +++ b/examples/common/entry/entry_p.h @@ -70,10 +70,6 @@ namespace entry const Event* poll(); void release(const Event* _event); - void setWindowSize(uint32_t _width, uint32_t _height); - void toggleWindowFrame(); - void setMouseLock(bool _lock); - class EventQueue { public: diff --git a/examples/common/entry/entry_qnx.cpp b/examples/common/entry/entry_qnx.cpp index df015d0a..1cdd0e22 100644 --- a/examples/common/entry/entry_qnx.cpp +++ b/examples/common/entry/entry_qnx.cpp @@ -25,6 +25,11 @@ namespace entry { } + bool setWindowTitle(const char* _title) + { + BX_UNUSED(_title); + } + void toggleWindowFrame() { } diff --git a/examples/common/entry/entry_sdl.cpp b/examples/common/entry/entry_sdl.cpp index f053a1cf..d7bcc0df 100644 --- a/examples/common/entry/entry_sdl.cpp +++ b/examples/common/entry/entry_sdl.cpp @@ -304,6 +304,11 @@ namespace entry } } + bool setWindowTitle(const char* _title) + { + SDL_WM_SetCaption(_title, NULL); + } + MainThreadEntry m_mte; bx::Thread m_thread; @@ -342,6 +347,11 @@ namespace entry SDL_PushEvent(&event); } + bool setWindowTitle(const char* _title) + { + s_ctx.setWindowTitle(_title); + } + void toggleWindowFrame() { } diff --git a/examples/common/entry/entry_windows.cpp b/examples/common/entry/entry_windows.cpp index 765e5883..22a239a1 100644 --- a/examples/common/entry/entry_windows.cpp +++ b/examples/common/entry/entry_windows.cpp @@ -324,7 +324,7 @@ namespace entry rect.bottom = rect.top + height + m_frameHeight; break; } - + m_eventQueue.postSizeEvent(m_width, m_height); } return 0; @@ -574,6 +574,11 @@ namespace entry } } + bool setWindowTitle(const char* _title) + { + return (1 == SetWindowText(m_hwnd, _title)); + } + static LRESULT CALLBACK wndProc(HWND _hwnd, UINT _id, WPARAM _wparam, LPARAM _lparam); EventQueue m_eventQueue; @@ -621,6 +626,11 @@ namespace entry PostMessage(s_ctx.m_hwnd, WM_USER_SET_WINDOW_SIZE, 0, (_height<<16) | (_width&0xffff) ); } + bool setWindowTitle(const char* _title) + { + return s_ctx.setWindowTitle(_title); + } + void toggleWindowFrame() { PostMessage(s_ctx.m_hwnd, WM_USER_TOGGLE_WINDOW_FRAME, 0, 0); From c143dba942b29869c2f6d8759fd57c01d0fd4c52 Mon Sep 17 00:00:00 2001 From: Dario Manesku Date: Wed, 6 Aug 2014 01:42:46 +0100 Subject: [PATCH 2/5] Added imguiInput(). --- examples/common/imgui/imgui.cpp | 146 ++++++++++++++++++++++++++++++-- examples/common/imgui/imgui.h | 3 +- 2 files changed, 143 insertions(+), 6 deletions(-) diff --git a/examples/common/imgui/imgui.cpp b/examples/common/imgui/imgui.cpp index fd877e7b..add0db11 100644 --- a/examples/common/imgui/imgui.cpp +++ b/examples/common/imgui/imgui.cpp @@ -456,6 +456,11 @@ struct Imgui return m_active == _id; } + bool isActiveInputField(uint32_t _id) const + { + return m_inputField == _id; + } + bool isHot(uint32_t _id) const { return m_hot == _id; @@ -494,10 +499,21 @@ struct Imgui clearInput(); } + void clearActiveInputField() + { + m_inputField = 0; + } + void setActive(uint32_t _id) { m_active = _id; m_wentActive = true; + m_inputField = 0; + } + + void setActiveInputField(uint32_t _id) + { + m_inputField = _id; } void setHot(uint32_t _id) @@ -551,7 +567,41 @@ struct Imgui return res; } - void updateInput(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll) + bool inputLogic(uint32_t _id, bool _over) + { + bool res = false; + + if (!anyActive() ) + { + if (_over) + { + setHot(_id); + } + + if (isHot(_id) + && m_leftPressed) + { + setActiveInputField(_id); + } + } + + if (isHot(_id) ) + { + m_isHot = true; + } + + if (m_leftPressed + && !m_isHot + && m_inputField != 0) + { + clearActiveInputField(); + res = true; + } + + return res; + } + + void updateInput(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, char _inputChar) { bool left = (_button & IMGUI_MBUT_LEFT) != 0; @@ -561,9 +611,16 @@ struct Imgui m_leftReleased = m_left && !left; m_left = left; m_scroll = _scroll; + + if (_inputChar > 0x80) + { + _inputChar = 0; + } + m_lastChar = m_char; + m_char = _inputChar; } - void beginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, uint8_t _view) + void beginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, char _inputChar, uint8_t _view) { nvgBeginFrame(m_nvg, _width, _height, 1.0f, NVG_STRAIGHT_ALPHA); @@ -575,7 +632,7 @@ struct Imgui bx::mtxOrtho(proj, 0.0f, (float)_width, (float)_height, 0.0f, 0.0f, 1000.0f); bgfx::setViewTransform(_view, NULL, proj); - updateInput(_mx, _my, _button, _scroll); + updateInput(_mx, _my, _button, _scroll, _inputChar); m_hot = m_hotToBe; m_hotToBe = 0; @@ -917,6 +974,77 @@ struct Imgui return res; } + void input(const char* _label, char* _str, uint32_t _len, bool _enabled) + { + m_widgetId++; + const uint16_t id = (m_areaId << 8) | m_widgetId; + int32_t xx = m_widgetX; + int32_t yy = m_widgetY; + m_widgetY += BUTTON_HEIGHT + DEFAULT_SPACING; + + const bool drawLabel = (NULL != _label && _label[0] != '\0'); + + if (drawLabel) + { + drawText(xx + , yy + BUTTON_HEIGHT / 2 + TEXT_HEIGHT / 2 + , ImguiTextAlign::Left + , _label + , imguiRGBA(255, 255, 255, 200) + ); + } + + // Handle input. + if (isActiveInputField(id) ) + { + const size_t cursor = size_t(strlen(_str)); + + if (m_char == 0x08) //backspace + { + _str[cursor-1] = '\0'; + } + else if (m_char == 0x0d || m_char == 0x1b) //enter or escape + { + clearActiveInputField(); + } + else if (cursor < _len-1 + && 0 != m_char) + { + _str[cursor] = m_char; + _str[cursor+1] = '\0'; + } + } + + // Draw input area. + int32_t height = BUTTON_HEIGHT; + int32_t width = m_widgetW - 2; + if (drawLabel) + { + uint32_t numVertices = 0; //unused + const int32_t labelWidth = int32_t(getTextLength(m_fonts[m_currentFontIdx].m_cdata, _label, numVertices)); + xx += (labelWidth + 6); + width -= (labelWidth + 6); + } + const bool enabled = _enabled && isEnabled(m_areaId); + const bool over = enabled && inRect(xx, yy, width, height); + const bool res = inputLogic(id, over); + + drawRoundedRect( (float)xx + , (float)yy + , (float)width + , (float)height + , (float)BUTTON_HEIGHT / 5 - 1 + , isActiveInputField(id)?imguiRGBA(255,196,0,255):imguiRGBA(128,128,128,96) + ); + + drawText(xx + 6 + , yy + BUTTON_HEIGHT / 2 + TEXT_HEIGHT / 2 + , ImguiTextAlign::Left + , _str + , isActiveInputField(id)?imguiRGBA(0, 0, 0, 255):imguiRGBA(255,255,255,255) + ); + } + void image(bgfx::TextureHandle _image, float _lod, int32_t _width, int32_t _height, ImguiImageAlign::Enum _align) { int32_t xx; @@ -1936,6 +2064,9 @@ struct Imgui uint32_t m_active; uint32_t m_hot; uint32_t m_hotToBe; + char m_char; + char m_lastChar; + uint32_t m_inputField; int32_t m_dragX; int32_t m_dragY; float m_dragOrig; @@ -2025,9 +2156,9 @@ void imguiDestroy() s_imgui.destroy(); } -void imguiBeginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, uint8_t _view) +void imguiBeginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, char _inputChar, uint8_t _view) { - s_imgui.beginFrame(_mx, _my, _button, _scroll, _width, _height, _view); + s_imgui.beginFrame(_mx, _my, _button, _scroll, _width, _height, _inputChar, _view); } void imguiEndFrame() @@ -2111,6 +2242,11 @@ bool imguiSlider(const char* _text, int32_t& _val, int32_t _vmin, int32_t _vmax, return result; } +void imguiInput(const char* _label, char* _str, uint32_t _len, bool _enabled) +{ + s_imgui.input(_label, _str, _len, _enabled); +} + uint32_t imguiChooseUseMacroInstead(uint32_t _selected, ...) { va_list argList; diff --git a/examples/common/imgui/imgui.h b/examples/common/imgui/imgui.h index 71362f81..d497ec6d 100644 --- a/examples/common/imgui/imgui.h +++ b/examples/common/imgui/imgui.h @@ -71,7 +71,7 @@ void imguiSetFont(ImguiFontHandle _handle); ImguiFontHandle imguiCreate(const void* _data, float _fontSize=15.0f); void imguiDestroy(); -void imguiBeginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, uint8_t _view = 31); +void imguiBeginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, char _inputChar = 0, uint8_t _view = 31); void imguiEndFrame(); bool imguiBeginScrollArea(const char* _name, int _x, int _y, int _width, int _height, int* _scroll, bool _enabled = true); @@ -90,6 +90,7 @@ void imguiLabel(const char* _format, ...); void imguiValue(const char* _text); bool imguiSlider(const char* _text, float& _val, float _vmin, float _vmax, float _vinc, bool _enabled = true); bool imguiSlider(const char* _text, int32_t& _val, int32_t _vmin, int32_t _vmax, bool _enabled = true); +void imguiInput(const char* _label, char* _str, uint32_t _len, bool _enabled = true); uint32_t imguiChooseUseMacroInstead(uint32_t _selected, ...); #define imguiChoose(...) imguiChooseUseMacroInstead(__VA_ARGS__, NULL) From 0baa2d46e6d8cbfa33c32b09eab8526ff6c319ae Mon Sep 17 00:00:00 2001 From: Dario Manesku Date: Wed, 6 Aug 2014 01:44:00 +0100 Subject: [PATCH 3/5] Cleanup. --- examples/common/imgui/imgui.cpp | 1 - examples/common/imgui/imgui.h | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/common/imgui/imgui.cpp b/examples/common/imgui/imgui.cpp index add0db11..c26b011f 100644 --- a/examples/common/imgui/imgui.cpp +++ b/examples/common/imgui/imgui.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include "../entry/dbg.h" #include "imgui.h" diff --git a/examples/common/imgui/imgui.h b/examples/common/imgui/imgui.h index d497ec6d..37407729 100644 --- a/examples/common/imgui/imgui.h +++ b/examples/common/imgui/imgui.h @@ -26,6 +26,8 @@ #ifndef IMGUI_H_HEADER_GUARD #define IMGUI_H_HEADER_GUARD +#include + #define IMGUI_MBUT_LEFT 0x01 #define IMGUI_MBUT_RIGHT 0x02 @@ -105,6 +107,6 @@ void imguiColorWheel(float _rgb[3], bool _respectIndentation = false, bool _enab void imguiColorWheel(const char* _str, float _rgb[3], bool& _activated, bool _enabled = true); void imguiImage(bgfx::TextureHandle _image, float _lod, int32_t _width, int32_t _height, ImguiImageAlign::Enum _align = ImguiImageAlign::LeftIndented); -void imguiImage(bgfx::TextureHandle _image, float _lod, float _width, float _aspect, ImguiImageAlign::Enum _align = ImguiImageAlign::LeftIndented); //_width is in [0.0-1.0] range. +void imguiImage(bgfx::TextureHandle _image, float _lod, float _scale, float _aspect, ImguiImageAlign::Enum _align = ImguiImageAlign::LeftIndented); //_scale is in [0.0-1.0] range. #endif // IMGUI_H_HEADER_GUARD From 78ea520d7dea35aee6fcf05237e52c5f14faa6f3 Mon Sep 17 00:00:00 2001 From: Dario Manesku Date: Wed, 6 Aug 2014 01:49:21 +0100 Subject: [PATCH 4/5] Exposing entry::KeyState to the user. --- examples/common/entry/entry.cpp | 122 +++++++++++++++++++++++++++++++- examples/common/entry/entry.h | 11 ++- 2 files changed, 131 insertions(+), 2 deletions(-) diff --git a/examples/common/entry/entry.cpp b/examples/common/entry/entry.cpp index 02f5fcf8..a24fb35d 100644 --- a/examples/common/entry/entry.cpp +++ b/examples/common/entry/entry.cpp @@ -147,13 +147,123 @@ namespace entry return result; } - bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse) + char keyToAscii(entry::Key::Enum _key, bool _shiftModifier) + { + static const char s_keyToAscii[entry::Key::Count] = + { + '\0', // None + 0x1b, // Esc + 0x0d, // Return + 0x09, // Tab + 0x20, // Space + 0x08, // Backspace + '\0', // Up + '\0', // Down + '\0', // Left + '\0', // Right + '\0', // PageUp + '\0', // PageDown + '\0', // Home + '\0', // End + '\0', // Print + 0x3d, // Equals + 0x2d, // Minus + '\0', // F1 + '\0', // F2 + '\0', // F3 + '\0', // F4 + '\0', // F5 + '\0', // F6 + '\0', // F7 + '\0', // F8 + '\0', // F9 + '\0', // F10 + '\0', // F11 + '\0', // F12 + 0x30, // NumPad0 + 0x31, // NumPad1 + 0x32, // NumPad2 + 0x33, // NumPad3 + 0x34, // NumPad4 + 0x35, // NumPad5 + 0x36, // NumPad6 + 0x37, // NumPad7 + 0x38, // NumPad8 + 0x39, // NumPad9 + 0x30, // Key0 + 0x31, // Key1 + 0x32, // Key2 + 0x33, // Key3 + 0x34, // Key4 + 0x35, // Key5 + 0x36, // Key6 + 0x37, // Key7 + 0x38, // Key8 + 0x39, // Key9 + 0x61, // KeyA + 0x62, // KeyB + 0x63, // KeyC + 0x64, // KeyD + 0x65, // KeyE + 0x66, // KeyF + 0x67, // KeyG + 0x68, // KeyH + 0x69, // KeyI + 0x6a, // KeyJ + 0x6b, // KeyK + 0x6c, // KeyL + 0x6d, // KeyM + 0x6e, // KeyN + 0x6f, // KeyO + 0x70, // KeyP + 0x71, // KeyQ + 0x72, // KeyR + 0x73, // KeyS + 0x74, // KeyT + 0x75, // KeyU + 0x76, // KeyV + 0x77, // KeyW + 0x78, // KeyX + 0x79, // KeyY + 0x7a, // KeyZ + }; + + char ascii = s_keyToAscii[_key]; + + if (_shiftModifier) + { + // Big letters. + if(ascii >= 'a' && ascii <= 'z') + { + ascii += 'A' - 'a'; + } + // Special cases. + else if('-' == ascii) + { + ascii = '_'; + } + else if ('=' == ascii) + { + ascii = '+'; + } + } + + return ascii; + } + + bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse, KeyState* _keyboard) { s_debug = _debug; s_reset = _reset; bool mouseLock = inputIsMouseLocked(); + if (NULL != _keyboard) + { + _keyboard->m_modifiers = 0; + memset(_keyboard->m_keysDown, 0, sizeof(_keyboard->m_keysDown) ); + } + const Event* ev; do { @@ -200,6 +310,16 @@ namespace entry { const KeyEvent* key = static_cast(ev); inputSetKeyState(key->m_key, key->m_modifiers, key->m_down); + + if (NULL != _keyboard) + { + _keyboard->m_modifiers |= key->m_modifiers; + + if (key->m_down) + { + _keyboard->m_keysDown[key->m_key] = true; + } + } } break; diff --git a/examples/common/entry/entry.h b/examples/common/entry/entry.h index 5b40b7f4..0d2fa96b 100644 --- a/examples/common/entry/entry.h +++ b/examples/common/entry/entry.h @@ -124,6 +124,8 @@ namespace entry KeyX, KeyY, KeyZ, + + Count, }; }; @@ -144,7 +146,14 @@ namespace entry uint8_t m_buttons[entry::MouseButton::Count]; }; - bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse = NULL); + struct KeyState + { + uint8_t m_modifiers; + bool m_keysDown[entry::Key::Count]; + }; + + char keyToAscii(entry::Key::Enum _key, bool _shiftModifier); + bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse = NULL, KeyState* _keyboard = NULL); void setWindowSize(uint32_t _width, uint32_t _height); bool setWindowTitle(const char* _title); From 2dd6b60d7e7aaad553b25f0a5e01fb2743076816 Mon Sep 17 00:00:00 2001 From: Dario Manesku Date: Wed, 6 Aug 2014 01:49:34 +0100 Subject: [PATCH 5/5] Cleanup. --- examples/common/entry/entry.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/common/entry/entry.h b/examples/common/entry/entry.h index 0d2fa96b..18f48862 100644 --- a/examples/common/entry/entry.h +++ b/examples/common/entry/entry.h @@ -155,14 +155,14 @@ namespace entry char keyToAscii(entry::Key::Enum _key, bool _shiftModifier); bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse = NULL, KeyState* _keyboard = NULL); + bx::FileReaderI* getFileReader(); + bx::FileWriterI* getFileWriter(); + void setWindowSize(uint32_t _width, uint32_t _height); bool setWindowTitle(const char* _title); void toggleWindowFrame(); void setMouseLock(bool _lock); - bx::FileReaderI* getFileReader(); - bx::FileWriterI* getFileWriter(); - } // namespace entry #endif // ENTRY_H_HEADER_GUARD