#pragma once #include <stdint.h> #include <tuple> #include "cocos2d.h" #include "ExtensionMacros.h" #include "imgui/imgui.h" // #define HAVE_IMGUI_MARKDOWN 1 NS_CC_EXT_BEGIN class ImGuiEventTracker; class ImGuiPresenter { friend class ImGuiRenderer; void init(); void cleanup(); public: enum class CHS_GLYPH_RANGE { NONE, GENERAL, FULL }; enum { DEFAULT_FONT_SIZE = 13 // see imgui.cpp }; static ImGuiPresenter* getInstance(); static void destroyInstance(); static void setOnInit(const std::function<void(ImGuiPresenter*)>& callBack); /// <summary> /// Scale ImGui with majorMoniter DPI scaling /// </summary> /// <param name="userScale">Usually is 1.0</param> /// <param name="fontFile">The full path of .ttc/.ttf file</param> /// <returns>The final contentZoomFactor = userScale * dpiScale</returns> float scaleAllByDPI(float userScale); float getContentZoomFactor() const { return _contentZoomFactor; } /// <summary> /// Add ImGui font with contentZoomFactor /// </summary> /// <param name="fontFile"></param> /// <param name="glyphRange"></param> void addFont(std::string_view fontFile, float fontSize = DEFAULT_FONT_SIZE, CHS_GLYPH_RANGE glyphRange = CHS_GLYPH_RANGE::NONE); void removeFont(std::string_view fontFile); void clearFonts(); /// <summary> /// Add a ImGui render loop to specific scene /// </summary> /// <param name="id">The FOURCC id of render loop, starts with '#', such as "#abcd"</id> /// <param name="func">the ImGui render loop</param> /// <param name="target">The target scene to track event, nullptr for global, useful for global GM tools</param> bool addRenderLoop(std::string_view id, std::function<void()> func, Scene* target); /// <summary> /// Remove ImGui render loop /// </summary> /// <param name="id">FOURCC starts with '#', such as "#abcd"</id> void removeRenderLoop(std::string_view id); void end(); // imgui helper void image(Texture2D* tex, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec4& border_col = ImVec4(0, 0, 0, 0)); void image(Sprite* sprite, const ImVec2& size, const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec4& border_col = ImVec4(0, 0, 0, 0)); bool imageButton(Texture2D* tex, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); bool imageButton(Sprite* sprite, const ImVec2& size, int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); void node(Node* node, const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec4& border_col = ImVec4(0, 0, 0, 0)); bool nodeButton(Node* node, int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); std::tuple<ImTextureID, int> useTexture(Texture2D* texture); std::tuple<ImTextureID, ImVec2, ImVec2, int> useSprite(Sprite* sprite); std::tuple<ImTextureID, ImVec2, ImVec2, int> useNode(Node* node, const ImVec2& pos); static void setNodeColor(Node* node, const ImVec4& col); static void setNodeColor(Node* node, ImGuiCol col); static void setLabelColor(Label* label, const ImVec4& col); static void setLabelColor(Label* label, bool disabled = false); static void setLabelColor(Label* label, ImGuiCol col); ImWchar* addGlyphRanges(std::string_view key, const std::vector<ImWchar>& ranges); static void mergeFontGlyphs(ImFont* dst, ImFont* src, ImWchar start, ImWchar end); int getCCRefId(Ref* p); private: static void loadCustomFonts(void*); // perform draw ImGui stubs void beginFrame(); void update(); void endFrame(); static void deactiveImGuiViewports(); private: static std::function<void(ImGuiPresenter*)> _onInit; struct RenderPipline { ImGuiEventTracker* tracker; std::function<void()> frame; }; std::unordered_map<uint32_t, RenderPipline> _renderPiplines; std::unordered_map<Ref*, int> usedCCRefIdMap; // cocos objects should be retained until next frame Vector<Ref*> usedCCRef; hlookup::string_map<std::vector<ImWchar>> glyphRanges; float _contentZoomFactor = 1.0f; int64_t _beginFrames = 0; Texture2D* _fontsTexture = nullptr; struct FontInfo { float fontSize; CHS_GLYPH_RANGE glyphRange; }; hlookup::string_map<FontInfo> _fontsInfoMap; bool _purgeNextLoop = false; }; NS_CC_EXT_END