ocornut_imgui.cpp 23 KB

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