ocornut_imgui.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  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( (uint16_t)width
  405. , (uint16_t)height
  406. , 1
  407. , bgfx::TextureFormat::BGRA8
  408. , 0
  409. , bgfx::copy(data, width*height*4)
  410. );
  411. m_wm = BX_NEW(m_allocator, WindowManager);
  412. m_wm->Init();
  413. #if 0
  414. {
  415. class Window : public ImGuiWM::Window
  416. {
  417. public:
  418. Window(const char* _title)
  419. : ImGuiWM::Window()
  420. {
  421. SetTitle(_title);
  422. }
  423. virtual void OnGui() BX_OVERRIDE
  424. {
  425. }
  426. };
  427. class WindowX : public ImGuiWM::Window
  428. {
  429. public:
  430. WindowX(const char* _title)
  431. : ImGuiWM::Window()
  432. {
  433. SetTitle(_title);
  434. }
  435. virtual void OnGui() BX_OVERRIDE
  436. {
  437. #if defined(SCI_NAMESPACE) && 0
  438. bool opened = true;
  439. ImGuiScintilla("Scintilla Editor", &opened, ImVec2(640.0f, 480.0f) );
  440. #endif // 0
  441. }
  442. };
  443. Window* w0 = new Window("test");
  444. WindowX* w1 = new WindowX("Scintilla");
  445. Window* w2 = new Window("xyzw");
  446. Window* w3 = new Window("0123");
  447. m_wm->Dock(w0);
  448. m_wm->DockWith(w1, w0, ImGuiWM::E_DOCK_ORIENTATION_RIGHT);
  449. m_wm->DockWith(w2, w1, ImGuiWM::E_DOCK_ORIENTATION_BOTTOM);
  450. m_wm->DockWith(w3, w0, ImGuiWM::E_DOCK_ORIENTATION_BOTTOM);
  451. }
  452. #endif // 0
  453. }
  454. void destroy()
  455. {
  456. m_wm->Exit();
  457. BX_DELETE(m_allocator, m_wm);
  458. ImGui::Shutdown();
  459. bgfx::destroyUniform(s_tex);
  460. bgfx::destroyTexture(m_texture);
  461. bgfx::destroyProgram(m_program);
  462. m_allocator = NULL;
  463. }
  464. void setupStyle(bool _dark)
  465. {
  466. // Doug Binks' darl color scheme
  467. // https://gist.github.com/dougbinks/8089b4bbaccaaf6fa204236978d165a9
  468. ImGuiStyle& style = ImGui::GetStyle();
  469. style.FrameRounding = 4.0f;
  470. // light style from Pacome Danhiez (user itamago)
  471. // https://github.com/ocornut/imgui/pull/511#issuecomment-175719267
  472. style.Colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
  473. style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
  474. style.Colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 1.00f);
  475. style.Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
  476. style.Colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.39f);
  477. style.Colors[ImGuiCol_BorderShadow] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f);
  478. style.Colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
  479. style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f);
  480. style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
  481. style.Colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f);
  482. style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f);
  483. style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f);
  484. style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f);
  485. style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f);
  486. style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 0.80f);
  487. style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.49f, 0.49f, 0.80f);
  488. style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f);
  489. style.Colors[ImGuiCol_ComboBg] = ImVec4(0.86f, 0.86f, 0.86f, 0.99f);
  490. style.Colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
  491. style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f);
  492. style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
  493. style.Colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f);
  494. style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
  495. style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f);
  496. style.Colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f);
  497. style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f);
  498. style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
  499. style.Colors[ImGuiCol_Column] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
  500. style.Colors[ImGuiCol_ColumnHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f);
  501. style.Colors[ImGuiCol_ColumnActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
  502. style.Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.50f);
  503. style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
  504. style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
  505. style.Colors[ImGuiCol_CloseButton] = ImVec4(0.59f, 0.59f, 0.59f, 0.50f);
  506. style.Colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f);
  507. style.Colors[ImGuiCol_CloseButtonActive] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f);
  508. style.Colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
  509. style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
  510. style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
  511. style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
  512. style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
  513. style.Colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.94f);
  514. style.Colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
  515. if (_dark)
  516. {
  517. for (int i = 0; i <= ImGuiCol_COUNT; i++)
  518. {
  519. ImVec4& col = style.Colors[i];
  520. float H, S, V;
  521. ImGui::ColorConvertRGBtoHSV( col.x, col.y, col.z, H, S, V );
  522. if( S < 0.1f )
  523. {
  524. V = 1.0f - V;
  525. }
  526. ImGui::ColorConvertHSVtoRGB( H, S, V, col.x, col.y, col.z );
  527. }
  528. }
  529. }
  530. void beginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, int _width, int _height, char _inputChar, uint8_t _viewId)
  531. {
  532. m_viewId = _viewId;
  533. ImGuiIO& io = ImGui::GetIO();
  534. if (_inputChar < 0x7f)
  535. {
  536. io.AddInputCharacter(_inputChar); // ASCII or GTFO! :(
  537. }
  538. io.DisplaySize = ImVec2( (float)_width, (float)_height);
  539. const int64_t now = bx::getHPCounter();
  540. const int64_t frameTime = now - m_last;
  541. m_last = now;
  542. const double freq = double(bx::getHPFrequency() );
  543. io.DeltaTime = float(frameTime/freq);
  544. io.MousePos = ImVec2( (float)_mx, (float)_my);
  545. io.MouseDown[0] = 0 != (_button & IMGUI_MBUT_LEFT);
  546. io.MouseDown[1] = 0 != (_button & IMGUI_MBUT_RIGHT);
  547. io.MouseDown[2] = 0 != (_button & IMGUI_MBUT_MIDDLE);
  548. io.MouseWheel = (float)(_scroll - m_lastScroll);
  549. m_lastScroll = _scroll;
  550. #if defined(SCI_NAMESPACE)
  551. uint8_t modifiers = inputGetModifiersState();
  552. io.KeyShift = 0 != (modifiers & (entry::Modifier::LeftShift | entry::Modifier::RightShift) );
  553. io.KeyCtrl = 0 != (modifiers & (entry::Modifier::LeftCtrl | entry::Modifier::RightCtrl ) );
  554. io.KeyAlt = 0 != (modifiers & (entry::Modifier::LeftAlt | entry::Modifier::RightAlt ) );
  555. for (int32_t ii = 0; ii < (int32_t)entry::Key::Count; ++ii)
  556. {
  557. io.KeysDown[ii] = inputGetKeyState(entry::Key::Enum(ii) );
  558. }
  559. #endif // defined(SCI_NAMESPACE)
  560. ImGui::NewFrame();
  561. ImGui::PushStyleVar(ImGuiStyleVar_ViewId, (float)_viewId);
  562. #if 0
  563. ImGui::ShowTestWindow(); //Debug only.
  564. #endif // 0
  565. #if 0
  566. {
  567. static ImGui::MemoryEditor me;
  568. bool open = true;
  569. if (ImGui::Begin("HexII", &open))
  570. {
  571. me.Draw(s_iconsKenneyTtf, sizeof(s_iconsKenneyTtf) );
  572. ImGui::End();
  573. }
  574. }
  575. #endif // 0
  576. #if 0
  577. {
  578. extern void ShowExampleAppCustomNodeGraph(bool* opened);
  579. bool opened = true;
  580. ShowExampleAppCustomNodeGraph(&opened);
  581. }
  582. #endif // 0
  583. }
  584. void endFrame()
  585. {
  586. m_wm->Run();
  587. ImGui::PopStyleVar(1);
  588. ImGui::Render();
  589. }
  590. bx::AllocatorI* m_allocator;
  591. bgfx::VertexDecl m_decl;
  592. bgfx::ProgramHandle m_program;
  593. bgfx::TextureHandle m_texture;
  594. bgfx::UniformHandle s_tex;
  595. ImFont* m_font[ImGui::Font::Count];
  596. WindowManager* m_wm;
  597. int64_t m_last;
  598. int32_t m_lastScroll;
  599. uint8_t m_viewId;
  600. #if USE_ENTRY
  601. struct Window
  602. {
  603. Window()
  604. {
  605. m_fbh.idx = bgfx::invalidHandle;
  606. }
  607. entry::WindowState m_state;
  608. PlatformWindow* m_pw;
  609. bgfx::FrameBufferHandle m_fbh;
  610. uint8_t m_viewId;
  611. };
  612. Window m_window[16];
  613. #endif // USE_ENTRY
  614. };
  615. static OcornutImguiContext s_ctx;
  616. void PlatformWindow::PaintBegin()
  617. {
  618. #if USE_ENTRY
  619. if (!m_bIsDragWindow)
  620. {
  621. OcornutImguiContext::Window& win = s_ctx.m_window[m_window.idx];
  622. entry::WindowState& state = win.m_state;
  623. ImGuiIO& io = ImGui::GetIO();
  624. io.MousePos = ImVec2((float)state.m_mouse.m_mx, (float)state.m_mouse.m_my);
  625. io.MouseDown[0] = !!state.m_mouse.m_buttons[entry::MouseButton::Left];
  626. io.MouseDown[1] = !!state.m_mouse.m_buttons[entry::MouseButton::Right];
  627. io.MouseDown[2] = !!state.m_mouse.m_buttons[entry::MouseButton::Middle];
  628. io.MouseWheel = float(state.m_mouse.m_mz);
  629. ImGui::PushStyleVar(ImGuiStyleVar_ViewId, (float)win.m_viewId);
  630. }
  631. #endif // USE_ENTRY
  632. }
  633. void PlatformWindow::Paint()
  634. {
  635. if (!m_bIsDragWindow)
  636. {
  637. Super::Paint();
  638. }
  639. }
  640. void PlatformWindow::PaintEnd()
  641. {
  642. #if USE_ENTRY
  643. if (!m_bIsDragWindow)
  644. {
  645. ImGui::PopStyleVar(1);
  646. entry::WindowState& state = s_ctx.m_window[0].m_state;
  647. ImGuiIO& io = ImGui::GetIO();
  648. io.MousePos = ImVec2((float)state.m_mouse.m_mx, (float)state.m_mouse.m_my);
  649. io.MouseDown[0] = !!state.m_mouse.m_buttons[entry::MouseButton::Left];
  650. io.MouseDown[1] = !!state.m_mouse.m_buttons[entry::MouseButton::Right];
  651. io.MouseDown[2] = !!state.m_mouse.m_buttons[entry::MouseButton::Middle];
  652. io.MouseWheel = float(state.m_mouse.m_mz);
  653. }
  654. #endif // USE_ENTRY
  655. }
  656. #if USE_ENTRY
  657. void pwToWindow(entry::WindowHandle _handle, PlatformWindow* _pw)
  658. {
  659. s_ctx.m_window[_handle.idx].m_pw = _pw;
  660. }
  661. void imguiUpdateWindow(const entry::WindowState& _state)
  662. {
  663. OcornutImguiContext::Window& window = s_ctx.m_window[_state.m_handle.idx];
  664. if (window.m_state.m_nwh != _state.m_nwh
  665. || (window.m_state.m_width != _state.m_width
  666. || window.m_state.m_height != _state.m_height) )
  667. {
  668. // When window changes size or native window handle changed
  669. // frame buffer must be recreated.
  670. if (bgfx::isValid(window.m_fbh) )
  671. {
  672. bgfx::destroyFrameBuffer(window.m_fbh);
  673. window.m_fbh.idx = bgfx::invalidHandle;
  674. }
  675. if (NULL != _state.m_nwh)
  676. {
  677. window.m_fbh = bgfx::createFrameBuffer(_state.m_nwh, _state.m_width, _state.m_height);
  678. window.m_viewId = 200 + _state.m_handle.idx;
  679. }
  680. else
  681. {
  682. window.m_viewId = s_ctx.m_viewId;
  683. }
  684. }
  685. memcpy(&window.m_state, &_state, sizeof(entry::WindowState) );
  686. }
  687. #endif // USE_ENTRY
  688. void* OcornutImguiContext::memAlloc(size_t _size)
  689. {
  690. return BX_ALLOC(s_ctx.m_allocator, _size);
  691. }
  692. void OcornutImguiContext::memFree(void* _ptr)
  693. {
  694. BX_FREE(s_ctx.m_allocator, _ptr);
  695. }
  696. void OcornutImguiContext::renderDrawLists(ImDrawData* _drawData)
  697. {
  698. s_ctx.render(_drawData);
  699. }
  700. void IMGUI_create(float _fontSize, bx::AllocatorI* _allocator)
  701. {
  702. s_ctx.create(_fontSize, _allocator);
  703. }
  704. void IMGUI_destroy()
  705. {
  706. s_ctx.destroy();
  707. }
  708. void IMGUI_beginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, int _width, int _height, char _inputChar, uint8_t _viewId)
  709. {
  710. s_ctx.beginFrame(_mx, _my, _button, _scroll, _width, _height, _inputChar, _viewId);
  711. }
  712. void IMGUI_endFrame()
  713. {
  714. s_ctx.endFrame();
  715. }
  716. namespace ImGui
  717. {
  718. void PushFont(Font::Enum _font)
  719. {
  720. PushFont(s_ctx.m_font[_font]);
  721. }
  722. } // namespace ImGui