ocornut_imgui.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. /*
  2. * Copyright 2014-2015 Daniel Collin. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  4. */
  5. #include <bgfx/bgfx.h>
  6. #include <bx/allocator.h>
  7. #include <bx/fpumath.h>
  8. #include <bx/timer.h>
  9. #include <ocornut-imgui/imgui.h>
  10. #include <ocornut-imgui/imgui_wm.h>
  11. #include "imgui.h"
  12. #include "ocornut_imgui.h"
  13. #include <stb/stb_image.c>
  14. #ifndef USE_ENTRY
  15. # if defined(SCI_NAMESPACE)
  16. # define USE_ENTRY 1
  17. # else
  18. # define USE_ENTRY 0
  19. # endif // defined(SCI_NAMESPACE)
  20. #endif // USE_ENTRY
  21. #if USE_ENTRY
  22. # include "../entry/entry.h"
  23. #endif // USE_ENTRY
  24. #if defined(SCI_NAMESPACE)
  25. # include "../entry/input.h"
  26. # include "scintilla.h"
  27. #endif // defined(SCI_NAMESPACE)
  28. #include "vs_ocornut_imgui.bin.h"
  29. #include "fs_ocornut_imgui.bin.h"
  30. class PlatformWindow : public ImGuiWM::PlatformWindow
  31. {
  32. typedef ImGuiWM::PlatformWindow Super;
  33. public:
  34. PlatformWindow(bool _mainWindow, bool _isDragWindow)
  35. : ImGuiWM::PlatformWindow(_mainWindow, _isDragWindow)
  36. , m_pos(0.0f, 0.0f)
  37. , m_size(0.0f, 0.0f)
  38. , m_drag(false)
  39. {
  40. #if USE_ENTRY
  41. if (!_mainWindow
  42. && !_isDragWindow)
  43. {
  44. m_window = entry::createWindow(0, 0, 640, 380);
  45. extern void pwToWindow(entry::WindowHandle _handle, class PlatformWindow* _pw);
  46. pwToWindow(m_window, this);
  47. }
  48. else
  49. {
  50. m_window.idx = 0;
  51. }
  52. #endif // USE_ENTRY
  53. }
  54. virtual ~PlatformWindow()
  55. {
  56. #if USE_ENTRY
  57. if (0 != m_window.idx)
  58. {
  59. entry::destroyWindow(m_window);
  60. }
  61. #endif // USE_ENTRY
  62. }
  63. virtual bool Init(ImGuiWM::PlatformWindow* /*_parent*/) BX_OVERRIDE
  64. {
  65. return true;
  66. }
  67. virtual const ImVec2& GetPosition() const BX_OVERRIDE
  68. {
  69. return m_pos;
  70. }
  71. virtual const ImVec2& GetSize() const BX_OVERRIDE
  72. {
  73. return m_size;
  74. }
  75. virtual void Show() BX_OVERRIDE
  76. {
  77. }
  78. virtual void Hide() BX_OVERRIDE
  79. {
  80. }
  81. virtual void SetSize(const ImVec2& _size) BX_OVERRIDE
  82. {
  83. #if USE_ENTRY
  84. if (0 != m_window.idx
  85. && m_size.x != _size.x
  86. && m_size.y != _size.y)
  87. {
  88. entry::setWindowSize(m_window, int32_t(_size.x), int32_t(_size.y) );
  89. }
  90. #endif // USE_ENTRY
  91. m_size = _size;
  92. }
  93. virtual void SetPosition(const ImVec2& _pos) BX_OVERRIDE
  94. {
  95. #if USE_ENTRY
  96. if (0 != m_window.idx
  97. && m_pos.x != _pos.x
  98. && m_pos.y != _pos.y)
  99. {
  100. entry::setWindowPos(m_window, int32_t(_pos.x), int32_t(_pos.y) );
  101. }
  102. #endif // USE_ENTRY
  103. m_pos = _pos;
  104. }
  105. virtual void SetTitle(const char* _title) BX_OVERRIDE
  106. {
  107. #if USE_ENTRY
  108. entry::setWindowTitle(m_window, _title);
  109. #else
  110. BX_UNUSED(_title);
  111. #endif // USE_ENTRY
  112. }
  113. virtual void PreUpdate() BX_OVERRIDE
  114. {
  115. }
  116. virtual void PaintBegin() BX_OVERRIDE;
  117. virtual void Paint() BX_OVERRIDE;
  118. virtual void PaintEnd() BX_OVERRIDE;
  119. virtual void Destroy() BX_OVERRIDE
  120. {
  121. }
  122. virtual void StartDrag() BX_OVERRIDE
  123. {
  124. m_drag = true;
  125. }
  126. virtual void StopDrag() BX_OVERRIDE
  127. {
  128. m_drag = false;
  129. }
  130. virtual bool IsDraging() BX_OVERRIDE
  131. {
  132. return m_drag;
  133. }
  134. private:
  135. ImVec2 m_pos;
  136. ImVec2 m_size;
  137. bool m_drag;
  138. #if USE_ENTRY
  139. entry::WindowHandle m_window;
  140. #endif // USE_ENTRY
  141. };
  142. class WindowManager : public ImGuiWM::WindowManager
  143. {
  144. typedef ImGuiWM::WindowManager Super;
  145. public:
  146. WindowManager()
  147. {
  148. }
  149. virtual ~WindowManager()
  150. {
  151. }
  152. protected:
  153. virtual ImGuiWM::PlatformWindow* CreatePlatformWindow(bool _main, ImGuiWM::PlatformWindow* _parent, bool _isDragWindow) BX_OVERRIDE
  154. {
  155. #if USE_ENTRY
  156. #else
  157. if (!_main
  158. && !_isDragWindow)
  159. {
  160. return NULL;
  161. }
  162. #endif // USE_ENTRY
  163. PlatformWindow* window = new (ImGui::MemAlloc(sizeof(PlatformWindow) ) ) PlatformWindow(_main, _isDragWindow);
  164. window->Init(_parent);
  165. return static_cast<ImGuiWM::PlatformWindow*>(window);
  166. }
  167. virtual void LogFormatted(const char* _str) BX_OVERRIDE
  168. {
  169. BX_TRACE("%s", _str); BX_UNUSED(_str);
  170. }
  171. virtual void InternalRun() BX_OVERRIDE
  172. {
  173. PreUpdate();
  174. Update();
  175. }
  176. };
  177. struct OcornutImguiContext
  178. {
  179. static void* memAlloc(size_t _size);
  180. static void memFree(void* _ptr);
  181. static void renderDrawLists(ImDrawData* _drawData);
  182. void render(ImDrawData* _drawData)
  183. {
  184. const ImGuiIO& io = ImGui::GetIO();
  185. const float width = io.DisplaySize.x;
  186. const float height = io.DisplaySize.y;
  187. {
  188. float ortho[16];
  189. bx::mtxOrtho(ortho, 0.0f, width, height, 0.0f, -1.0f, 1.0f);
  190. bgfx::setViewTransform(m_viewId, NULL, ortho);
  191. }
  192. #if USE_ENTRY
  193. for (uint32_t ii = 1; ii < BX_COUNTOF(m_window); ++ii)
  194. {
  195. Window& window = m_window[ii];
  196. if (bgfx::isValid(window.m_fbh) )
  197. {
  198. const uint8_t viewId = window.m_viewId;
  199. bgfx::setViewClear(viewId
  200. , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
  201. , 0x303030ff
  202. , 1.0f
  203. , 0
  204. );
  205. bgfx::setViewFrameBuffer(viewId, window.m_fbh);
  206. bgfx::setViewRect(viewId
  207. , 0
  208. , 0
  209. , window.m_state.m_width
  210. , window.m_state.m_height
  211. );
  212. float ortho[16];
  213. bx::mtxOrtho(ortho
  214. , 0.0f
  215. , float(window.m_state.m_width)
  216. , float(window.m_state.m_height)
  217. , 0.0f
  218. , -1.0f
  219. , 1.0f
  220. );
  221. bgfx::setViewTransform(viewId
  222. , NULL
  223. , ortho
  224. );
  225. }
  226. }
  227. #endif // USE_ENTRY
  228. // Render command lists
  229. for (int32_t ii = 0, num = _drawData->CmdListsCount; ii < num; ++ii)
  230. {
  231. bgfx::TransientVertexBuffer tvb;
  232. bgfx::TransientIndexBuffer tib;
  233. const ImDrawList* drawList = _drawData->CmdLists[ii];
  234. uint32_t numVertices = (uint32_t)drawList->VtxBuffer.size();
  235. uint32_t numIndices = (uint32_t)drawList->IdxBuffer.size();
  236. if (!bgfx::checkAvailTransientVertexBuffer(numVertices, m_decl)
  237. || !bgfx::checkAvailTransientIndexBuffer(numIndices) )
  238. {
  239. // not enough space in transient buffer just quit drawing the rest...
  240. break;
  241. }
  242. bgfx::allocTransientVertexBuffer(&tvb, numVertices, m_decl);
  243. bgfx::allocTransientIndexBuffer(&tib, numIndices);
  244. ImDrawVert* verts = (ImDrawVert*)tvb.data;
  245. memcpy(verts, drawList->VtxBuffer.begin(), numVertices * sizeof(ImDrawVert) );
  246. ImDrawIdx* indices = (ImDrawIdx*)tib.data;
  247. memcpy(indices, drawList->IdxBuffer.begin(), numIndices * sizeof(ImDrawIdx) );
  248. uint32_t offset = 0;
  249. for (const ImDrawCmd* cmd = drawList->CmdBuffer.begin(), *cmdEnd = drawList->CmdBuffer.end(); cmd != cmdEnd; ++cmd)
  250. {
  251. if (cmd->UserCallback)
  252. {
  253. cmd->UserCallback(drawList, cmd);
  254. }
  255. else if (0 != cmd->ElemCount)
  256. {
  257. uint64_t state = 0
  258. | BGFX_STATE_RGB_WRITE
  259. | BGFX_STATE_ALPHA_WRITE
  260. | BGFX_STATE_MSAA
  261. ;
  262. bgfx::TextureHandle th = m_texture;
  263. bgfx::ProgramHandle program = m_program;
  264. if (NULL != cmd->TextureId)
  265. {
  266. union { ImTextureID ptr; struct { bgfx::TextureHandle handle; uint8_t flags; uint8_t mip; } s; } texture = { cmd->TextureId };
  267. state |= 0 != (IMGUI_FLAGS_ALPHA_BLEND & texture.s.flags)
  268. ? BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
  269. : BGFX_STATE_NONE
  270. ;
  271. th = texture.s.handle;
  272. if (0 != texture.s.mip)
  273. {
  274. extern bgfx::ProgramHandle imguiGetImageProgram(uint8_t _mip);
  275. program = imguiGetImageProgram(texture.s.mip);
  276. }
  277. }
  278. else
  279. {
  280. state |= BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA);
  281. }
  282. const uint16_t xx = uint16_t(bx::fmax(cmd->ClipRect.x, 0.0f) );
  283. const uint16_t yy = uint16_t(bx::fmax(cmd->ClipRect.y, 0.0f) );
  284. bgfx::setScissor(xx, yy
  285. , uint16_t(bx::fmin(cmd->ClipRect.z, 65535.0f)-xx)
  286. , uint16_t(bx::fmin(cmd->ClipRect.w, 65535.0f)-yy)
  287. );
  288. bgfx::setState(state);
  289. bgfx::setTexture(0, s_tex, th);
  290. bgfx::setVertexBuffer(&tvb, 0, numVertices);
  291. bgfx::setIndexBuffer(&tib, offset, cmd->ElemCount);
  292. bgfx::submit(cmd->ViewId, program);
  293. }
  294. offset += cmd->ElemCount;
  295. }
  296. }
  297. }
  298. void create(const void* _data, uint32_t _size, float _fontSize, bx::AllocatorI* _allocator)
  299. {
  300. m_viewId = 255;
  301. m_allocator = _allocator;
  302. m_lastScroll = 0;
  303. m_last = bx::getHPCounter();
  304. ImGuiIO& io = ImGui::GetIO();
  305. io.RenderDrawListsFn = renderDrawLists;
  306. if (NULL != m_allocator)
  307. {
  308. io.MemAllocFn = memAlloc;
  309. io.MemFreeFn = memFree;
  310. }
  311. io.DisplaySize = ImVec2(1280.0f, 720.0f);
  312. io.DeltaTime = 1.0f / 60.0f;
  313. io.IniFilename = NULL;
  314. setupStyle(true);
  315. #if defined(SCI_NAMESPACE)
  316. io.KeyMap[ImGuiKey_Tab] = (int)entry::Key::Tab;
  317. io.KeyMap[ImGuiKey_LeftArrow] = (int)entry::Key::Left;
  318. io.KeyMap[ImGuiKey_RightArrow] = (int)entry::Key::Right;
  319. io.KeyMap[ImGuiKey_UpArrow] = (int)entry::Key::Up;
  320. io.KeyMap[ImGuiKey_DownArrow] = (int)entry::Key::Down;
  321. io.KeyMap[ImGuiKey_Home] = (int)entry::Key::Home;
  322. io.KeyMap[ImGuiKey_End] = (int)entry::Key::End;
  323. io.KeyMap[ImGuiKey_Delete] = (int)entry::Key::Delete;
  324. io.KeyMap[ImGuiKey_Backspace] = (int)entry::Key::Backspace;
  325. io.KeyMap[ImGuiKey_Enter] = (int)entry::Key::Return;
  326. io.KeyMap[ImGuiKey_Escape] = (int)entry::Key::Esc;
  327. io.KeyMap[ImGuiKey_A] = (int)entry::Key::KeyA;
  328. io.KeyMap[ImGuiKey_C] = (int)entry::Key::KeyC;
  329. io.KeyMap[ImGuiKey_V] = (int)entry::Key::KeyV;
  330. io.KeyMap[ImGuiKey_X] = (int)entry::Key::KeyX;
  331. io.KeyMap[ImGuiKey_Y] = (int)entry::Key::KeyY;
  332. io.KeyMap[ImGuiKey_Z] = (int)entry::Key::KeyZ;
  333. #endif // defined(SCI_NAMESPACE)
  334. const bgfx::Memory* vsmem;
  335. const bgfx::Memory* fsmem;
  336. switch (bgfx::getRendererType() )
  337. {
  338. case bgfx::RendererType::Direct3D9:
  339. vsmem = bgfx::makeRef(vs_ocornut_imgui_dx9, sizeof(vs_ocornut_imgui_dx9) );
  340. fsmem = bgfx::makeRef(fs_ocornut_imgui_dx9, sizeof(fs_ocornut_imgui_dx9) );
  341. break;
  342. case bgfx::RendererType::Direct3D11:
  343. case bgfx::RendererType::Direct3D12:
  344. vsmem = bgfx::makeRef(vs_ocornut_imgui_dx11, sizeof(vs_ocornut_imgui_dx11) );
  345. fsmem = bgfx::makeRef(fs_ocornut_imgui_dx11, sizeof(fs_ocornut_imgui_dx11) );
  346. break;
  347. case bgfx::RendererType::Metal:
  348. vsmem = bgfx::makeRef(vs_ocornut_imgui_mtl, sizeof(vs_ocornut_imgui_mtl) );
  349. fsmem = bgfx::makeRef(fs_ocornut_imgui_mtl, sizeof(fs_ocornut_imgui_mtl) );
  350. break;
  351. default:
  352. vsmem = bgfx::makeRef(vs_ocornut_imgui_glsl, sizeof(vs_ocornut_imgui_glsl) );
  353. fsmem = bgfx::makeRef(fs_ocornut_imgui_glsl, sizeof(fs_ocornut_imgui_glsl) );
  354. break;
  355. }
  356. bgfx::ShaderHandle vsh = bgfx::createShader(vsmem);
  357. bgfx::ShaderHandle fsh = bgfx::createShader(fsmem);
  358. m_program = bgfx::createProgram(vsh, fsh, true);
  359. m_decl
  360. .begin()
  361. .add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float)
  362. .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
  363. .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
  364. .end();
  365. s_tex = bgfx::createUniform("s_tex", bgfx::UniformType::Int1);
  366. uint8_t* data;
  367. int32_t width;
  368. int32_t height;
  369. {
  370. void* font = ImGui::MemAlloc(_size);
  371. memcpy(font, _data, _size);
  372. io.Fonts->AddFontFromMemoryTTF(font, _size, _fontSize);
  373. }
  374. io.Fonts->GetTexDataAsRGBA32(&data, &width, &height);
  375. m_texture = bgfx::createTexture2D( (uint16_t)width
  376. , (uint16_t)height
  377. , 1
  378. , bgfx::TextureFormat::BGRA8
  379. , 0
  380. , bgfx::copy(data, width*height*4)
  381. );
  382. ImGuiStyle& style = ImGui::GetStyle();
  383. style.FrameRounding = 4.0f;
  384. m_wm = BX_NEW(m_allocator, WindowManager);
  385. m_wm->Init();
  386. #if 0
  387. {
  388. class Window : public ImGuiWM::Window
  389. {
  390. public:
  391. Window(const char* _title)
  392. : ImGuiWM::Window()
  393. {
  394. SetTitle(_title);
  395. }
  396. virtual void OnGui() BX_OVERRIDE
  397. {
  398. }
  399. };
  400. class WindowX : public ImGuiWM::Window
  401. {
  402. public:
  403. WindowX(const char* _title)
  404. : ImGuiWM::Window()
  405. {
  406. SetTitle(_title);
  407. }
  408. virtual void OnGui() BX_OVERRIDE
  409. {
  410. #if defined(SCI_NAMESPACE) && 0
  411. bool opened = true;
  412. ImGuiScintilla("Scintilla Editor", &opened, ImVec2(640.0f, 480.0f) );
  413. #endif // 0
  414. }
  415. };
  416. Window* w0 = new Window("test");
  417. WindowX* w1 = new WindowX("Scintilla");
  418. Window* w2 = new Window("xyzw");
  419. Window* w3 = new Window("0123");
  420. m_wm->Dock(w0);
  421. m_wm->DockWith(w1, w0, ImGuiWM::E_DOCK_ORIENTATION_RIGHT);
  422. m_wm->DockWith(w2, w1, ImGuiWM::E_DOCK_ORIENTATION_BOTTOM);
  423. m_wm->DockWith(w3, w0, ImGuiWM::E_DOCK_ORIENTATION_BOTTOM);
  424. }
  425. #endif // 0
  426. }
  427. void destroy()
  428. {
  429. m_wm->Exit();
  430. BX_DELETE(m_allocator, m_wm);
  431. ImGui::Shutdown();
  432. bgfx::destroyUniform(s_tex);
  433. bgfx::destroyTexture(m_texture);
  434. bgfx::destroyProgram(m_program);
  435. m_allocator = NULL;
  436. }
  437. void setupStyle(bool _dark)
  438. {
  439. // Doug Binks' darl color scheme
  440. // https://gist.github.com/dougbinks/8089b4bbaccaaf6fa204236978d165a9
  441. ImGuiStyle& style = ImGui::GetStyle();
  442. // light style from Pacome Danhiez (user itamago)
  443. // https://github.com/ocornut/imgui/pull/511#issuecomment-175719267
  444. style.Colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
  445. style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
  446. style.Colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 1.00f);
  447. style.Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
  448. style.Colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.39f);
  449. style.Colors[ImGuiCol_BorderShadow] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f);
  450. style.Colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
  451. style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f);
  452. style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
  453. style.Colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f);
  454. style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f);
  455. style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f);
  456. style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f);
  457. style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f);
  458. style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 0.80f);
  459. style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.49f, 0.49f, 0.80f);
  460. style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f);
  461. style.Colors[ImGuiCol_ComboBg] = ImVec4(0.86f, 0.86f, 0.86f, 0.99f);
  462. style.Colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
  463. style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f);
  464. style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
  465. style.Colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f);
  466. style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
  467. style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f);
  468. style.Colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f);
  469. style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f);
  470. style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
  471. style.Colors[ImGuiCol_Column] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
  472. style.Colors[ImGuiCol_ColumnHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f);
  473. style.Colors[ImGuiCol_ColumnActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
  474. style.Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.50f);
  475. style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
  476. style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
  477. style.Colors[ImGuiCol_CloseButton] = ImVec4(0.59f, 0.59f, 0.59f, 0.50f);
  478. style.Colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f);
  479. style.Colors[ImGuiCol_CloseButtonActive] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f);
  480. style.Colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
  481. style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
  482. style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
  483. style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
  484. style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
  485. style.Colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.94f);
  486. style.Colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
  487. if (_dark)
  488. {
  489. for (int i = 0; i <= ImGuiCol_COUNT; i++)
  490. {
  491. ImVec4& col = style.Colors[i];
  492. float H, S, V;
  493. ImGui::ColorConvertRGBtoHSV( col.x, col.y, col.z, H, S, V );
  494. if( S < 0.1f )
  495. {
  496. V = 1.0f - V;
  497. }
  498. ImGui::ColorConvertHSVtoRGB( H, S, V, col.x, col.y, col.z );
  499. }
  500. }
  501. }
  502. void beginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, int _width, int _height, char _inputChar, uint8_t _viewId)
  503. {
  504. m_viewId = _viewId;
  505. ImGuiIO& io = ImGui::GetIO();
  506. if (_inputChar < 0x7f)
  507. {
  508. io.AddInputCharacter(_inputChar); // ASCII or GTFO! :(
  509. }
  510. io.DisplaySize = ImVec2( (float)_width, (float)_height);
  511. const int64_t now = bx::getHPCounter();
  512. const int64_t frameTime = now - m_last;
  513. m_last = now;
  514. const double freq = double(bx::getHPFrequency() );
  515. io.DeltaTime = float(frameTime/freq);
  516. io.MousePos = ImVec2( (float)_mx, (float)_my);
  517. io.MouseDown[0] = 0 != (_button & IMGUI_MBUT_LEFT);
  518. io.MouseDown[1] = 0 != (_button & IMGUI_MBUT_RIGHT);
  519. io.MouseDown[2] = 0 != (_button & IMGUI_MBUT_MIDDLE);
  520. io.MouseWheel = (float)(_scroll - m_lastScroll);
  521. m_lastScroll = _scroll;
  522. #if defined(SCI_NAMESPACE)
  523. uint8_t modifiers = inputGetModifiersState();
  524. io.KeyShift = 0 != (modifiers & (entry::Modifier::LeftShift | entry::Modifier::RightShift) );
  525. io.KeyCtrl = 0 != (modifiers & (entry::Modifier::LeftCtrl | entry::Modifier::RightCtrl ) );
  526. io.KeyAlt = 0 != (modifiers & (entry::Modifier::LeftAlt | entry::Modifier::RightAlt ) );
  527. for (int32_t ii = 0; ii < (int32_t)entry::Key::Count; ++ii)
  528. {
  529. io.KeysDown[ii] = inputGetKeyState(entry::Key::Enum(ii) );
  530. }
  531. #endif // defined(SCI_NAMESPACE)
  532. ImGui::NewFrame();
  533. ImGui::PushStyleVar(ImGuiStyleVar_ViewId, (float)_viewId);
  534. #if 0
  535. ImGui::ShowTestWindow(); //Debug only.
  536. #endif // 0
  537. #if 0
  538. extern void ShowExampleAppCustomNodeGraph(bool* opened);
  539. bool opened = true;
  540. ShowExampleAppCustomNodeGraph(&opened);
  541. #endif // 0
  542. }
  543. void endFrame()
  544. {
  545. m_wm->Run();
  546. ImGui::PopStyleVar(1);
  547. ImGui::Render();
  548. }
  549. bx::AllocatorI* m_allocator;
  550. bgfx::VertexDecl m_decl;
  551. bgfx::ProgramHandle m_program;
  552. bgfx::TextureHandle m_texture;
  553. bgfx::UniformHandle s_tex;
  554. WindowManager* m_wm;
  555. int64_t m_last;
  556. int32_t m_lastScroll;
  557. uint8_t m_viewId;
  558. #if USE_ENTRY
  559. struct Window
  560. {
  561. Window()
  562. {
  563. m_fbh.idx = bgfx::invalidHandle;
  564. }
  565. entry::WindowState m_state;
  566. PlatformWindow* m_pw;
  567. bgfx::FrameBufferHandle m_fbh;
  568. uint8_t m_viewId;
  569. };
  570. Window m_window[16];
  571. #endif // USE_ENTRY
  572. };
  573. static OcornutImguiContext s_ctx;
  574. void PlatformWindow::PaintBegin()
  575. {
  576. #if USE_ENTRY
  577. if (!m_bIsDragWindow)
  578. {
  579. OcornutImguiContext::Window& win = s_ctx.m_window[m_window.idx];
  580. entry::WindowState& state = win.m_state;
  581. ImGuiIO& io = ImGui::GetIO();
  582. io.MousePos = ImVec2((float)state.m_mouse.m_mx, (float)state.m_mouse.m_my);
  583. io.MouseDown[0] = !!state.m_mouse.m_buttons[entry::MouseButton::Left];
  584. io.MouseDown[1] = !!state.m_mouse.m_buttons[entry::MouseButton::Right];
  585. io.MouseDown[2] = !!state.m_mouse.m_buttons[entry::MouseButton::Middle];
  586. io.MouseWheel = float(state.m_mouse.m_mz);
  587. ImGui::PushStyleVar(ImGuiStyleVar_ViewId, (float)win.m_viewId);
  588. }
  589. #endif // USE_ENTRY
  590. }
  591. void PlatformWindow::Paint()
  592. {
  593. if (!m_bIsDragWindow)
  594. {
  595. Super::Paint();
  596. }
  597. }
  598. void PlatformWindow::PaintEnd()
  599. {
  600. #if USE_ENTRY
  601. if (!m_bIsDragWindow)
  602. {
  603. ImGui::PopStyleVar(1);
  604. entry::WindowState& state = s_ctx.m_window[0].m_state;
  605. ImGuiIO& io = ImGui::GetIO();
  606. io.MousePos = ImVec2((float)state.m_mouse.m_mx, (float)state.m_mouse.m_my);
  607. io.MouseDown[0] = !!state.m_mouse.m_buttons[entry::MouseButton::Left];
  608. io.MouseDown[1] = !!state.m_mouse.m_buttons[entry::MouseButton::Right];
  609. io.MouseDown[2] = !!state.m_mouse.m_buttons[entry::MouseButton::Middle];
  610. io.MouseWheel = float(state.m_mouse.m_mz);
  611. }
  612. #endif // USE_ENTRY
  613. }
  614. #if USE_ENTRY
  615. void pwToWindow(entry::WindowHandle _handle, PlatformWindow* _pw)
  616. {
  617. s_ctx.m_window[_handle.idx].m_pw = _pw;
  618. }
  619. void imguiUpdateWindow(const entry::WindowState& _state)
  620. {
  621. OcornutImguiContext::Window& window = s_ctx.m_window[_state.m_handle.idx];
  622. if (window.m_state.m_nwh != _state.m_nwh
  623. || (window.m_state.m_width != _state.m_width
  624. || window.m_state.m_height != _state.m_height) )
  625. {
  626. // When window changes size or native window handle changed
  627. // frame buffer must be recreated.
  628. if (bgfx::isValid(window.m_fbh) )
  629. {
  630. bgfx::destroyFrameBuffer(window.m_fbh);
  631. window.m_fbh.idx = bgfx::invalidHandle;
  632. }
  633. if (NULL != _state.m_nwh)
  634. {
  635. window.m_fbh = bgfx::createFrameBuffer(_state.m_nwh, _state.m_width, _state.m_height);
  636. window.m_viewId = 200 + _state.m_handle.idx;
  637. }
  638. else
  639. {
  640. window.m_viewId = s_ctx.m_viewId;
  641. }
  642. }
  643. memcpy(&window.m_state, &_state, sizeof(entry::WindowState) );
  644. }
  645. #endif // USE_ENTRY
  646. void* OcornutImguiContext::memAlloc(size_t _size)
  647. {
  648. return BX_ALLOC(s_ctx.m_allocator, _size);
  649. }
  650. void OcornutImguiContext::memFree(void* _ptr)
  651. {
  652. BX_FREE(s_ctx.m_allocator, _ptr);
  653. }
  654. void OcornutImguiContext::renderDrawLists(ImDrawData* _drawData)
  655. {
  656. s_ctx.render(_drawData);
  657. }
  658. void IMGUI_create(const void* _data, uint32_t _size, float _fontSize, bx::AllocatorI* _allocator)
  659. {
  660. s_ctx.create(_data, _size, _fontSize, _allocator);
  661. }
  662. void IMGUI_destroy()
  663. {
  664. s_ctx.destroy();
  665. }
  666. void IMGUI_beginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, int _width, int _height, char _inputChar, uint8_t _viewId)
  667. {
  668. s_ctx.beginFrame(_mx, _my, _button, _scroll, _width, _height, _inputChar, _viewId);
  669. }
  670. void IMGUI_endFrame()
  671. {
  672. s_ctx.endFrame();
  673. }