mirror of https://github.com/axmolengine/axmol.git
ImGUIEXT addRenderLoop support global without any target scene
This commit is contained in:
parent
cde039b34b
commit
500e913517
|
@ -4,63 +4,122 @@
|
||||||
NS_CC_EXT_BEGIN
|
NS_CC_EXT_BEGIN
|
||||||
|
|
||||||
static uint32_t fourccValue(const std::string& str) {
|
static uint32_t fourccValue(const std::string& str) {
|
||||||
if (str.empty() || str[0] != '#') return (uint32_t)-1;
|
if (str.empty() || str[0] != '#') return (uint32_t)-1;
|
||||||
uint32_t value = 0;
|
uint32_t value = 0;
|
||||||
memcpy(&value, str.c_str() + 1, std::min(sizeof(value), str.size() - 1));
|
memcpy(&value, str.c_str() + 1, std::min(sizeof(value), str.size() - 1));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Rename to ImGuiEXTLayerBlock
|
class ImGuiEXTEventTracker {
|
||||||
// Because it's only used for block event when ImGui::IsAnyWindowHovered() == 'true'
|
public:
|
||||||
class ImGuiEXTRenderer : public Layer
|
virtual ~ImGuiEXTEventTracker() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Track scene event and check whether routed to the scene graph
|
||||||
|
class ImGuiEXTSceneEventTracker : public ImGuiEXTEventTracker
|
||||||
{
|
{
|
||||||
CC_CONSTRUCTOR_ACCESS:
|
public:
|
||||||
bool initWithImGuiEXT()
|
bool initWithScene(Scene* scene)
|
||||||
{
|
{
|
||||||
if (!Layer::init())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef CC_PLATFORM_PC
|
#ifdef CC_PLATFORM_PC
|
||||||
// note: when at the first click to focus the window, this will not take effect
|
_trackLayer = utils::newInstance<Layer>();
|
||||||
auto listener = EventListenerTouchOneByOne::create();
|
|
||||||
listener->setSwallowTouches(true);
|
|
||||||
listener->onTouchBegan = [this](Touch* touch, Event*) -> bool {
|
|
||||||
if (!_visible)
|
|
||||||
return false;
|
|
||||||
return ImGui::IsAnyWindowHovered();
|
|
||||||
};
|
|
||||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
|
||||||
|
|
||||||
// add by halx99
|
// note: when at the first click to focus the window, this will not take effect
|
||||||
auto stopAnyMouse = [=](EventMouse* event) {
|
auto listener = EventListenerTouchOneByOne::create();
|
||||||
if (ImGui::IsAnyWindowHovered()) {
|
listener->setSwallowTouches(true);
|
||||||
event->stopPropagation();
|
listener->onTouchBegan = [this](Touch* touch, Event*) -> bool {
|
||||||
}
|
return ImGui::IsAnyWindowHovered();
|
||||||
};
|
};
|
||||||
auto mouseListener = EventListenerMouse::create();
|
_trackLayer->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, _trackLayer);
|
||||||
mouseListener->onMouseDown = mouseListener->onMouseUp = stopAnyMouse;
|
|
||||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(mouseListener, this);
|
// add by halx99
|
||||||
|
auto stopAnyMouse = [=](EventMouse* event) {
|
||||||
|
if (ImGui::IsAnyWindowHovered()) {
|
||||||
|
event->stopPropagation();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto mouseListener = EventListenerMouse::create();
|
||||||
|
mouseListener->onMouseDown = mouseListener->onMouseUp = stopAnyMouse;
|
||||||
|
_trackLayer->getEventDispatcher()->addEventListenerWithSceneGraphPriority(mouseListener, _trackLayer);
|
||||||
|
scene->addChild(_trackLayer, INT_MAX);
|
||||||
#endif
|
#endif
|
||||||
// add an empty sprite to avoid render problem
|
// add an empty sprite to avoid render problem
|
||||||
// const auto sp = Sprite::create();
|
// const auto sp = Sprite::create();
|
||||||
// sp->setGlobalZOrder(1);
|
// sp->setGlobalZOrder(1);
|
||||||
// sp->setOpacity(0);
|
// sp->setOpacity(0);
|
||||||
// addChild(sp, 1);
|
// addChild(sp, 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There a 3 choice for schedule frame for ImGui render loop
|
* There a 3 choice for schedule frame for ImGui render loop
|
||||||
* a. at visit/draw to call beginFrame/endFrame, but at ImGui loop, we can't game object and add to Scene directly, will cause damage iterator
|
* a. at visit/draw to call beginFrame/endFrame, but at ImGui loop, we can't game object and add to Scene directly, will cause damage iterator
|
||||||
* b. scheduleUpdate at onEnter to call beginFrame, at visit/draw to call endFrame, it's solve iterator damage problem, but when director is paused
|
* b. scheduleUpdate at onEnter to call beginFrame, at visit/draw to call endFrame, it's solve iterator damage problem, but when director is paused
|
||||||
* the director will stop call 'update' function of Scheduler
|
* the director will stop call 'update' function of Scheduler
|
||||||
* And need modify engine code to call _scheduler->update(_deltaTime) even director is paused, pass 0 for update
|
* And need modify engine code to call _scheduler->update(_deltaTime) even director is paused, pass 0 for update
|
||||||
* c. Director::EVENT_BEFORE_DRAW call beginFrame, EVENT_AFTER_VISIT call endFrame
|
* c. Director::EVENT_BEFORE_DRAW call beginFrame, EVENT_AFTER_VISIT call endFrame
|
||||||
*/
|
*/
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
~ImGuiEXTRenderer()
|
return true;
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
~ImGuiEXTSceneEventTracker()
|
||||||
|
{
|
||||||
|
#ifdef CC_PLATFORM_PC
|
||||||
|
if (_trackLayer) {
|
||||||
|
if (_trackLayer->getParent())
|
||||||
|
_trackLayer->removeFromParent();
|
||||||
|
_trackLayer->release();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Layer* _trackLayer = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImGuiEXTGlobalEventTracker : public ImGuiEXTEventTracker
|
||||||
|
{
|
||||||
|
static const int highestPriority = (std::numeric_limits<int>::min)();
|
||||||
|
public:
|
||||||
|
bool init()
|
||||||
|
{
|
||||||
|
#ifdef CC_PLATFORM_PC
|
||||||
|
// note: when at the first click to focus the window, this will not take effect
|
||||||
|
|
||||||
|
auto eventDispatcher = Director::getInstance()->getEventDispatcher();
|
||||||
|
|
||||||
|
_touchListener = utils::newInstance<EventListenerTouchOneByOne>();
|
||||||
|
_touchListener->setSwallowTouches(true);
|
||||||
|
_touchListener->onTouchBegan = [this](Touch* touch, Event*) -> bool {
|
||||||
|
return ImGui::IsAnyWindowHovered();
|
||||||
|
};
|
||||||
|
eventDispatcher->addEventListenerWithFixedPriority(_touchListener, highestPriority);
|
||||||
|
|
||||||
|
// add by halx99
|
||||||
|
auto stopAnyMouse = [=](EventMouse* event) {
|
||||||
|
if (ImGui::IsAnyWindowHovered()) {
|
||||||
|
event->stopPropagation();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
_mouseListener = utils::newInstance<EventListenerMouse>();
|
||||||
|
_mouseListener->onMouseDown = _mouseListener->onMouseUp = stopAnyMouse;
|
||||||
|
eventDispatcher->addEventListenerWithFixedPriority(_mouseListener, highestPriority);
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ImGuiEXTGlobalEventTracker() {
|
||||||
|
#ifdef CC_PLATFORM_PC
|
||||||
|
auto eventDispatcher = Director::getInstance()->getEventDispatcher();
|
||||||
|
eventDispatcher->removeEventListener(_mouseListener);
|
||||||
|
eventDispatcher->removeEventListener(_touchListener);
|
||||||
|
|
||||||
|
_mouseListener->release();
|
||||||
|
_touchListener->release();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
EventListenerTouchOneByOne* _touchListener = nullptr;
|
||||||
|
EventListenerMouse* _mouseListener = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ImGuiEXT* _instance = nullptr;
|
static ImGuiEXT* _instance = nullptr;
|
||||||
|
@ -68,400 +127,404 @@ std::function<void(ImGuiEXT*)> ImGuiEXT::_onInit;
|
||||||
|
|
||||||
void ImGuiEXT::init()
|
void ImGuiEXT::init()
|
||||||
{
|
{
|
||||||
ImGui_ImplCocos2dx_Init(true);
|
ImGui_ImplCocos2dx_Init(true);
|
||||||
|
|
||||||
ImGui::StyleColorsClassic();
|
ImGui::StyleColorsClassic();
|
||||||
|
|
||||||
auto eventDispatcher = Director::getInstance()->getEventDispatcher();
|
auto eventDispatcher = Director::getInstance()->getEventDispatcher();
|
||||||
eventDispatcher->addCustomEventListener(Director::EVENT_BEFORE_DRAW, [=](EventCustom*) { beginFrame(); });
|
eventDispatcher->addCustomEventListener(Director::EVENT_BEFORE_DRAW, [=](EventCustom*) { beginFrame(); });
|
||||||
eventDispatcher->addCustomEventListener(Director::EVENT_AFTER_VISIT, [=](EventCustom*) { endFrame(); });
|
eventDispatcher->addCustomEventListener(Director::EVENT_AFTER_VISIT, [=](EventCustom*) { endFrame(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiEXT* ImGuiEXT::getInstance()
|
ImGuiEXT* ImGuiEXT::getInstance()
|
||||||
{
|
{
|
||||||
if(_instance == nullptr)
|
if (_instance == nullptr)
|
||||||
{
|
{
|
||||||
_instance = new ImGuiEXT();
|
_instance = new ImGuiEXT();
|
||||||
_instance->init();
|
_instance->init();
|
||||||
if (_onInit)
|
if (_onInit)
|
||||||
_onInit(_instance);
|
_onInit(_instance);
|
||||||
}
|
}
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::destroyInstance()
|
void ImGuiEXT::destroyInstance()
|
||||||
{
|
{
|
||||||
if (_instance)
|
if (_instance)
|
||||||
{
|
{
|
||||||
auto eventDispatcher = Director::getInstance()->getEventDispatcher();
|
auto eventDispatcher = Director::getInstance()->getEventDispatcher();
|
||||||
eventDispatcher->removeCustomEventListeners(Director::EVENT_AFTER_VISIT);
|
eventDispatcher->removeCustomEventListeners(Director::EVENT_AFTER_VISIT);
|
||||||
eventDispatcher->removeCustomEventListeners(Director::EVENT_BEFORE_DRAW);
|
eventDispatcher->removeCustomEventListeners(Director::EVENT_BEFORE_DRAW);
|
||||||
|
|
||||||
ImGui_ImplCocos2dx_Shutdown();
|
ImGui_ImplCocos2dx_Shutdown();
|
||||||
delete _instance;
|
delete _instance;
|
||||||
_instance = nullptr;
|
_instance = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::setOnInit(const std::function<void(ImGuiEXT*)>& callBack)
|
void ImGuiEXT::setOnInit(const std::function<void(ImGuiEXT*)>& callBack)
|
||||||
{
|
{
|
||||||
_onInit = callBack;
|
_onInit = callBack;
|
||||||
}
|
}
|
||||||
|
|
||||||
float ImGuiEXT::scaleAllByDPI(float userScale)
|
float ImGuiEXT::scaleAllByDPI(float userScale)
|
||||||
{
|
{
|
||||||
// Gets scale
|
// Gets scale
|
||||||
float xscale = 1.0f;
|
float xscale = 1.0f;
|
||||||
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, nullptr);
|
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, nullptr);
|
||||||
auto zoomFactor = userScale * xscale;
|
auto zoomFactor = userScale * xscale;
|
||||||
|
|
||||||
auto imFonts = ImGui::GetIO().Fonts;
|
auto imFonts = ImGui::GetIO().Fonts;
|
||||||
|
|
||||||
// clear before add new font
|
// clear before add new font
|
||||||
auto fontConf = imFonts->ConfigData; // copy font config data
|
auto fontConf = imFonts->ConfigData; // copy font config data
|
||||||
|
|
||||||
if (zoomFactor != _contentZoomFactor) {
|
if (zoomFactor != _contentZoomFactor) {
|
||||||
for (auto& fontConf : imFonts->ConfigData)
|
for (auto& fontConf : imFonts->ConfigData)
|
||||||
{
|
{
|
||||||
fontConf.SizePixels = (fontConf.SizePixels / _contentZoomFactor) * zoomFactor;
|
fontConf.SizePixels = (fontConf.SizePixels / _contentZoomFactor) * zoomFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destory font informations, let implcocos2dx recreate at newFrame
|
// Destory font informations, let implcocos2dx recreate at newFrame
|
||||||
ImGui_ImplCocos2dx_DestroyDeviceObjects();
|
ImGui_ImplCocos2dx_DestroyDeviceObjects();
|
||||||
|
|
||||||
ImGui::GetStyle().ScaleAllSizes(zoomFactor);
|
ImGui::GetStyle().ScaleAllSizes(zoomFactor);
|
||||||
|
|
||||||
_contentZoomFactor = zoomFactor;
|
_contentZoomFactor = zoomFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
return zoomFactor;
|
return zoomFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::addFont(const std::string& fontFile, float fontSize, CHS_GLYPH_RANGE glyphRange)
|
void ImGuiEXT::addFont(const std::string& fontFile, float fontSize, CHS_GLYPH_RANGE glyphRange)
|
||||||
{
|
{
|
||||||
auto imFonts = ImGui::GetIO().Fonts;
|
auto imFonts = ImGui::GetIO().Fonts;
|
||||||
const ImWchar* imChars = nullptr;
|
const ImWchar* imChars = nullptr;
|
||||||
switch (glyphRange) {
|
switch (glyphRange) {
|
||||||
case CHS_GLYPH_RANGE::GENERAL:
|
case CHS_GLYPH_RANGE::GENERAL:
|
||||||
imChars = imFonts->GetGlyphRangesChineseSimplifiedCommon();
|
imChars = imFonts->GetGlyphRangesChineseSimplifiedCommon();
|
||||||
break;
|
break;
|
||||||
case CHS_GLYPH_RANGE::FULL:
|
case CHS_GLYPH_RANGE::FULL:
|
||||||
imChars = imFonts->GetGlyphRangesChineseFull();
|
imChars = imFonts->GetGlyphRangesChineseFull();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
imFonts->AddFontFromFileTTF(fontFile.c_str(), fontSize * _contentZoomFactor, nullptr, imChars);
|
imFonts->AddFontFromFileTTF(fontFile.c_str(), fontSize * _contentZoomFactor, nullptr, imChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::clearFonts()
|
void ImGuiEXT::clearFonts()
|
||||||
{
|
{
|
||||||
ImGui::GetIO().Fonts->Clear();
|
ImGui::GetIO().Fonts->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* begin ImGui frame and draw ImGui stubs
|
* begin ImGui frame and draw ImGui stubs
|
||||||
*/
|
*/
|
||||||
void ImGuiEXT::beginFrame()
|
void ImGuiEXT::beginFrame()
|
||||||
{
|
{
|
||||||
// create frame
|
// create frame
|
||||||
ImGui_ImplCocos2dx_NewFrame();
|
ImGui_ImplCocos2dx_NewFrame();
|
||||||
|
|
||||||
// draw all gui
|
// draw all gui
|
||||||
this->update();
|
this->update();
|
||||||
|
|
||||||
// render
|
// render
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* flush ImGui draw data to engine
|
* flush ImGui draw data to engine
|
||||||
*/
|
*/
|
||||||
void ImGuiEXT::endFrame() {
|
void ImGuiEXT::endFrame() {
|
||||||
ImGui_ImplCocos2dx_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplCocos2dx_RenderDrawData(ImGui::GetDrawData());
|
||||||
ImGui_ImplCocos2dx_RenderPlatform();
|
ImGui_ImplCocos2dx_RenderPlatform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::update()
|
void ImGuiEXT::update()
|
||||||
{ // drived by ImGuiEXTRenderer
|
{ // drived by ImGuiEXTRenderer
|
||||||
|
|
||||||
// clear things from last frame
|
// clear things from last frame
|
||||||
usedCCRefIdMap.clear();
|
usedCCRefIdMap.clear();
|
||||||
usedCCRef.clear();
|
usedCCRef.clear();
|
||||||
// drawing commands
|
// drawing commands
|
||||||
for (auto& pipline : _renderPiplines)
|
for (auto& pipline : _renderPiplines)
|
||||||
pipline.second.frame();
|
pipline.second.frame();
|
||||||
|
|
||||||
// commands will be processed after update
|
// commands will be processed after update
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGuiEXT::addRenderLoop(const std::string& id, Scene* scene, std::function<void()> onFrame)
|
bool ImGuiEXT::addRenderLoop(const std::string& id, std::function<void()> func, Scene* target)
|
||||||
{
|
{
|
||||||
// TODO: check whether exist
|
// TODO: check whether exist
|
||||||
auto fourccId = fourccValue(id);
|
auto fourccId = fourccValue(id);
|
||||||
if (_renderPiplines.find(fourccId) != _renderPiplines.end())
|
if (_renderPiplines.find(fourccId) != _renderPiplines.end())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto renderer = utils::newInstance<ImGuiEXTRenderer>(&ImGuiEXTRenderer::initWithImGuiEXT);
|
ImGuiEXTEventTracker* tracker;
|
||||||
scene->addChild(renderer, INT_MAX, fourccId);
|
if (target)
|
||||||
_renderPiplines.emplace(fourccId, RenderPipline{ renderer, std::move(onFrame) });
|
tracker = utils::newInstance<ImGuiEXTSceneEventTracker>(&ImGuiEXTSceneEventTracker::initWithScene, target);
|
||||||
|
else
|
||||||
|
tracker = utils::newInstance<ImGuiEXTGlobalEventTracker>();
|
||||||
|
|
||||||
return true;
|
if (tracker) {
|
||||||
|
_renderPiplines.emplace(fourccId, RenderPipline{ tracker, std::move(func) });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::removeRenderLoop(const std::string& id)
|
void ImGuiEXT::removeRenderLoop(const std::string& id)
|
||||||
{
|
{
|
||||||
auto fourccId = fourccValue(id);
|
auto fourccId = fourccValue(id);
|
||||||
const auto iter = _renderPiplines.find(fourccId);
|
const auto iter = _renderPiplines.find(fourccId);
|
||||||
if (iter != _renderPiplines.end()) {
|
if (iter != _renderPiplines.end()) {
|
||||||
auto renderer = iter->second.renderer;
|
auto tracker = iter->second.tracker;
|
||||||
if (renderer->getParent())
|
delete tracker;
|
||||||
renderer->removeFromParent();
|
_renderPiplines.erase(iter);
|
||||||
renderer->release();
|
}
|
||||||
_renderPiplines.erase(iter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::tuple<ImVec2, ImVec2> getTextureUV(Sprite* sp)
|
static std::tuple<ImVec2, ImVec2> getTextureUV(Sprite* sp)
|
||||||
{
|
{
|
||||||
ImVec2 uv0, uv1;
|
ImVec2 uv0, uv1;
|
||||||
if (!sp || !sp->getTexture())
|
if (!sp || !sp->getTexture())
|
||||||
return { uv0,uv1 };
|
return { uv0,uv1 };
|
||||||
const auto rect = sp->getTextureRect();
|
const auto rect = sp->getTextureRect();
|
||||||
const auto tex = sp->getTexture();
|
const auto tex = sp->getTexture();
|
||||||
const float atlasWidth = (float)tex->getPixelsWide();
|
const float atlasWidth = (float)tex->getPixelsWide();
|
||||||
const float atlasHeight = (float)tex->getPixelsHigh();
|
const float atlasHeight = (float)tex->getPixelsHigh();
|
||||||
uv0.x = rect.origin.x / atlasWidth;
|
uv0.x = rect.origin.x / atlasWidth;
|
||||||
uv0.y = rect.origin.y / atlasHeight;
|
uv0.y = rect.origin.y / atlasHeight;
|
||||||
uv1.x = (rect.origin.x + rect.size.width) / atlasWidth;
|
uv1.x = (rect.origin.x + rect.size.width) / atlasWidth;
|
||||||
uv1.y = (rect.origin.y + rect.size.height) / atlasHeight;
|
uv1.y = (rect.origin.y + rect.size.height) / atlasHeight;
|
||||||
return { uv0,uv1 };
|
return { uv0,uv1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::image(Texture2D* tex, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1,
|
void ImGuiEXT::image(Texture2D* tex, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1,
|
||||||
const ImVec4& tint_col, const ImVec4& border_col)
|
const ImVec4& tint_col, const ImVec4& border_col)
|
||||||
{
|
{
|
||||||
if (!tex)
|
if (!tex)
|
||||||
return;
|
return;
|
||||||
auto size_ = size;
|
auto size_ = size;
|
||||||
if (size_.x <= 0.f) size_.x = tex->getPixelsWide();
|
if (size_.x <= 0.f) size_.x = tex->getPixelsWide();
|
||||||
if (size_.y <= 0.f) size_.y = tex->getPixelsHigh();
|
if (size_.y <= 0.f) size_.y = tex->getPixelsHigh();
|
||||||
ImGui::PushID(getCCRefId(tex));
|
ImGui::PushID(getCCRefId(tex));
|
||||||
ImGui::Image((ImTextureID)tex, size_, uv0, uv1, tint_col, border_col);
|
ImGui::Image((ImTextureID)tex, size_, uv0, uv1, tint_col, border_col);
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::image(Sprite* sprite, const ImVec2& size, const ImVec4& tint_col, const ImVec4& border_col)
|
void ImGuiEXT::image(Sprite* sprite, const ImVec2& size, const ImVec4& tint_col, const ImVec4& border_col)
|
||||||
{
|
{
|
||||||
if (!sprite || !sprite->getTexture())
|
if (!sprite || !sprite->getTexture())
|
||||||
return;
|
return;
|
||||||
auto size_ = size;
|
auto size_ = size;
|
||||||
const auto rect = sprite->getTextureRect();
|
const auto rect = sprite->getTextureRect();
|
||||||
if (size_.x <= 0.f) size_.x = rect.size.width;
|
if (size_.x <= 0.f) size_.x = rect.size.width;
|
||||||
if (size_.y <= 0.f) size_.y = rect.size.height;
|
if (size_.y <= 0.f) size_.y = rect.size.height;
|
||||||
ImVec2 uv0, uv1;
|
ImVec2 uv0, uv1;
|
||||||
std::tie(uv0, uv1) = getTextureUV(sprite);
|
std::tie(uv0, uv1) = getTextureUV(sprite);
|
||||||
ImGui::PushID(getCCRefId(sprite));
|
ImGui::PushID(getCCRefId(sprite));
|
||||||
ImGui::Image((ImTextureID)sprite->getTexture(), size_, uv0, uv1, tint_col, border_col);
|
ImGui::Image((ImTextureID)sprite->getTexture(), size_, uv0, uv1, tint_col, border_col);
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGuiEXT::imageButton(Texture2D* tex, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1,
|
bool ImGuiEXT::imageButton(Texture2D* tex, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1,
|
||||||
int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col)
|
int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col)
|
||||||
{
|
{
|
||||||
if (!tex)
|
if (!tex)
|
||||||
return false;
|
return false;
|
||||||
auto size_ = size;
|
auto size_ = size;
|
||||||
if (size_.x <= 0.f) size_.x = tex->getPixelsWide();
|
if (size_.x <= 0.f) size_.x = tex->getPixelsWide();
|
||||||
if (size_.y <= 0.f) size_.y = tex->getPixelsHigh();
|
if (size_.y <= 0.f) size_.y = tex->getPixelsHigh();
|
||||||
ImGui::PushID(getCCRefId(tex));
|
ImGui::PushID(getCCRefId(tex));
|
||||||
const auto ret = ImGui::ImageButton((ImTextureID)tex,
|
const auto ret = ImGui::ImageButton((ImTextureID)tex,
|
||||||
size_, uv0, uv1, frame_padding, bg_col, tint_col);
|
size_, uv0, uv1, frame_padding, bg_col, tint_col);
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGuiEXT::imageButton(Sprite* sprite, const ImVec2& size, int frame_padding, const ImVec4& bg_col,
|
bool ImGuiEXT::imageButton(Sprite* sprite, const ImVec2& size, int frame_padding, const ImVec4& bg_col,
|
||||||
const ImVec4& tint_col)
|
const ImVec4& tint_col)
|
||||||
{
|
{
|
||||||
if (!sprite || !sprite->getTexture())
|
if (!sprite || !sprite->getTexture())
|
||||||
return false;
|
return false;
|
||||||
auto size_ = size;
|
auto size_ = size;
|
||||||
const auto rect = sprite->getTextureRect();
|
const auto rect = sprite->getTextureRect();
|
||||||
if (size_.x <= 0.f) size_.x = rect.size.width;
|
if (size_.x <= 0.f) size_.x = rect.size.width;
|
||||||
if (size_.y <= 0.f) size_.y = rect.size.height;
|
if (size_.y <= 0.f) size_.y = rect.size.height;
|
||||||
ImVec2 uv0, uv1;
|
ImVec2 uv0, uv1;
|
||||||
std::tie(uv0, uv1) = getTextureUV(sprite);
|
std::tie(uv0, uv1) = getTextureUV(sprite);
|
||||||
ImGui::PushID(getCCRefId(sprite));
|
ImGui::PushID(getCCRefId(sprite));
|
||||||
const auto ret = ImGui::ImageButton((ImTextureID)sprite->getTexture(),
|
const auto ret = ImGui::ImageButton((ImTextureID)sprite->getTexture(),
|
||||||
size_, uv0, uv1, frame_padding, bg_col, tint_col);
|
size_, uv0, uv1, frame_padding, bg_col, tint_col);
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::node(Node* node, const ImVec4& tint_col, const ImVec4& border_col)
|
void ImGuiEXT::node(Node* node, const ImVec4& tint_col, const ImVec4& border_col)
|
||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
const auto size = node->getContentSize();
|
const auto size = node->getContentSize();
|
||||||
const auto pos = ImGui::GetCursorScreenPos();
|
const auto pos = ImGui::GetCursorScreenPos();
|
||||||
Mat4 tr;
|
Mat4 tr;
|
||||||
tr.m[5] = -1;
|
tr.m[5] = -1;
|
||||||
tr.m[12] = pos.x;
|
tr.m[12] = pos.x;
|
||||||
tr.m[13] = pos.y + size.height;
|
tr.m[13] = pos.y + size.height;
|
||||||
if (border_col.w > 0.f)
|
if (border_col.w > 0.f)
|
||||||
{
|
{
|
||||||
tr.m[12] += 1;
|
tr.m[12] += 1;
|
||||||
tr.m[13] += 1;
|
tr.m[13] += 1;
|
||||||
}
|
}
|
||||||
node->setNodeToParentTransform(tr);
|
node->setNodeToParentTransform(tr);
|
||||||
ImGui::PushID(getCCRefId(node));
|
ImGui::PushID(getCCRefId(node));
|
||||||
ImGui::Image((ImTextureID)node,
|
ImGui::Image((ImTextureID)node,
|
||||||
ImVec2(size.width, size.height), ImVec2(0, 0), ImVec2(1, 1), tint_col, border_col);
|
ImVec2(size.width, size.height), ImVec2(0, 0), ImVec2(1, 1), tint_col, border_col);
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGuiEXT::nodeButton(Node* node, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col)
|
bool ImGuiEXT::nodeButton(Node* node, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col)
|
||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
return false;
|
return false;
|
||||||
const auto size = node->getContentSize();
|
const auto size = node->getContentSize();
|
||||||
const auto pos = ImGui::GetCursorScreenPos();
|
const auto pos = ImGui::GetCursorScreenPos();
|
||||||
Mat4 tr;
|
Mat4 tr;
|
||||||
tr.m[5] = -1;
|
tr.m[5] = -1;
|
||||||
tr.m[12] = pos.x;
|
tr.m[12] = pos.x;
|
||||||
tr.m[13] = pos.y + size.height;
|
tr.m[13] = pos.y + size.height;
|
||||||
if (frame_padding >= 0)
|
if (frame_padding >= 0)
|
||||||
{
|
{
|
||||||
tr.m[12] += (float)frame_padding;
|
tr.m[12] += (float)frame_padding;
|
||||||
tr.m[13] += (float)frame_padding;
|
tr.m[13] += (float)frame_padding;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tr.m[12] += ImGui::GetStyle().FramePadding.x;
|
tr.m[12] += ImGui::GetStyle().FramePadding.x;
|
||||||
tr.m[13] += ImGui::GetStyle().FramePadding.y;
|
tr.m[13] += ImGui::GetStyle().FramePadding.y;
|
||||||
}
|
}
|
||||||
node->setNodeToParentTransform(tr);
|
node->setNodeToParentTransform(tr);
|
||||||
ImGui::PushID(getCCRefId(node));
|
ImGui::PushID(getCCRefId(node));
|
||||||
const auto ret = ImGui::ImageButton((ImTextureID)node,
|
const auto ret = ImGui::ImageButton((ImTextureID)node,
|
||||||
ImVec2(size.width, size.height), ImVec2(0, 0), ImVec2(1, 1), frame_padding, bg_col, tint_col);
|
ImVec2(size.width, size.height), ImVec2(0, 0), ImVec2(1, 1), frame_padding, bg_col, tint_col);
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<ImTextureID, int> ImGuiEXT::useTexture(Texture2D* texture)
|
std::tuple<ImTextureID, int> ImGuiEXT::useTexture(Texture2D* texture)
|
||||||
{
|
{
|
||||||
if (!texture)
|
if (!texture)
|
||||||
return { nullptr,0 };
|
return { nullptr,0 };
|
||||||
return { (ImTextureID)texture,getCCRefId(texture) };
|
return { (ImTextureID)texture,getCCRefId(texture) };
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<ImTextureID, ImVec2, ImVec2, int> ImGuiEXT::useSprite(Sprite* sprite)
|
std::tuple<ImTextureID, ImVec2, ImVec2, int> ImGuiEXT::useSprite(Sprite* sprite)
|
||||||
{
|
{
|
||||||
if (!sprite || !sprite->getTexture())
|
if (!sprite || !sprite->getTexture())
|
||||||
return { nullptr,{},{},0 };
|
return { nullptr,{},{},0 };
|
||||||
ImVec2 uv0, uv1;
|
ImVec2 uv0, uv1;
|
||||||
std::tie(uv0, uv1) = getTextureUV(sprite);
|
std::tie(uv0, uv1) = getTextureUV(sprite);
|
||||||
return { (ImTextureID)sprite->getTexture(),uv0,uv1,getCCRefId(sprite) };
|
return { (ImTextureID)sprite->getTexture(),uv0,uv1,getCCRefId(sprite) };
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<ImTextureID, ImVec2, ImVec2, int> ImGuiEXT::useNode(Node* node, const ImVec2& pos)
|
std::tuple<ImTextureID, ImVec2, ImVec2, int> ImGuiEXT::useNode(Node* node, const ImVec2& pos)
|
||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
return { nullptr,{},{},0 };
|
return { nullptr,{},{},0 };
|
||||||
const auto size = node->getContentSize();
|
const auto size = node->getContentSize();
|
||||||
Mat4 tr;
|
Mat4 tr;
|
||||||
tr.m[5] = -1;
|
tr.m[5] = -1;
|
||||||
tr.m[12] = pos.x;
|
tr.m[12] = pos.x;
|
||||||
tr.m[13] = pos.y + size.height;
|
tr.m[13] = pos.y + size.height;
|
||||||
node->setNodeToParentTransform(tr);
|
node->setNodeToParentTransform(tr);
|
||||||
return { (ImTextureID)node,pos,ImVec2(pos.x + size.width,pos.y + size.height),getCCRefId(node) };
|
return { (ImTextureID)node,pos,ImVec2(pos.x + size.width,pos.y + size.height),getCCRefId(node) };
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::setNodeColor(Node* node, const ImVec4& col)
|
void ImGuiEXT::setNodeColor(Node* node, const ImVec4& col)
|
||||||
{
|
{
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
node->setColor({ uint8_t(col.x * 255),uint8_t(col.y * 255),uint8_t(col.z * 255) });
|
node->setColor({ uint8_t(col.x * 255),uint8_t(col.y * 255),uint8_t(col.z * 255) });
|
||||||
node->setOpacity(uint8_t(col.w * 255));
|
node->setOpacity(uint8_t(col.w * 255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::setNodeColor(Node* node, ImGuiCol col)
|
void ImGuiEXT::setNodeColor(Node* node, ImGuiCol col)
|
||||||
{
|
{
|
||||||
if (node && 0 <= col && col < ImGuiCol_COUNT)
|
if (node && 0 <= col && col < ImGuiCol_COUNT)
|
||||||
setNodeColor(node, ImGui::GetStyleColorVec4(col));
|
setNodeColor(node, ImGui::GetStyleColorVec4(col));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::setLabelColor(Label* label, const ImVec4& col)
|
void ImGuiEXT::setLabelColor(Label* label, const ImVec4& col)
|
||||||
{
|
{
|
||||||
if (label)
|
if (label)
|
||||||
{
|
{
|
||||||
label->setTextColor(
|
label->setTextColor(
|
||||||
{ uint8_t(col.x * 255),uint8_t(col.y * 255),uint8_t(col.z * 255),uint8_t(col.w * 255) });
|
{ uint8_t(col.x * 255),uint8_t(col.y * 255),uint8_t(col.z * 255),uint8_t(col.w * 255) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::setLabelColor(Label* label, bool disabled)
|
void ImGuiEXT::setLabelColor(Label* label, bool disabled)
|
||||||
{
|
{
|
||||||
if (label)
|
if (label)
|
||||||
setLabelColor(label, ImGui::GetStyleColorVec4(disabled ? ImGuiCol_TextDisabled : ImGuiCol_Text));
|
setLabelColor(label, ImGui::GetStyleColorVec4(disabled ? ImGuiCol_TextDisabled : ImGuiCol_Text));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::setLabelColor(Label* label, ImGuiCol col)
|
void ImGuiEXT::setLabelColor(Label* label, ImGuiCol col)
|
||||||
{
|
{
|
||||||
if (label && 0 <= col && col < ImGuiCol_COUNT)
|
if (label && 0 <= col && col < ImGuiCol_COUNT)
|
||||||
setLabelColor(label, ImGui::GetStyleColorVec4(col));
|
setLabelColor(label, ImGui::GetStyleColorVec4(col));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImWchar* ImGuiEXT::addGlyphRanges(const std::string& key, const std::vector<ImWchar>& ranges)
|
ImWchar* ImGuiEXT::addGlyphRanges(const std::string& key, const std::vector<ImWchar>& ranges)
|
||||||
{
|
{
|
||||||
auto it = glyphRanges.find(key);
|
auto it = glyphRanges.find(key);
|
||||||
// the pointer must be persistant, do not replace
|
// the pointer must be persistant, do not replace
|
||||||
if (it != glyphRanges.end())
|
if (it != glyphRanges.end())
|
||||||
return it->second.data();
|
return it->second.data();
|
||||||
glyphRanges[key] = ranges;
|
glyphRanges[key] = ranges;
|
||||||
if (ranges.empty())
|
if (ranges.empty())
|
||||||
glyphRanges[key].push_back(0);
|
glyphRanges[key].push_back(0);
|
||||||
return glyphRanges[key].data();
|
return glyphRanges[key].data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::mergeFontGlyphs(ImFont* dst, ImFont* src, ImWchar start, ImWchar end)
|
void ImGuiEXT::mergeFontGlyphs(ImFont* dst, ImFont* src, ImWchar start, ImWchar end)
|
||||||
{
|
{
|
||||||
if (!dst || !src || start > end)
|
if (!dst || !src || start > end)
|
||||||
return;
|
return;
|
||||||
for (auto i = start; i <= end; ++i)
|
for (auto i = start; i <= end; ++i)
|
||||||
{
|
{
|
||||||
const auto g = src->FindGlyphNoFallback(i);
|
const auto g = src->FindGlyphNoFallback(i);
|
||||||
if (g)
|
if (g)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
// dst->AddGlyph(g->Codepoint, g->X0, g->Y0, g->X1, g->Y1, g->U0, g->V0, g->U1, g->V1, g->AdvanceX);
|
// dst->AddGlyph(g->Codepoint, g->X0, g->Y0, g->X1, g->Y1, g->U0, g->V0, g->U1, g->V1, g->AdvanceX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dst->BuildLookupTable();
|
dst->BuildLookupTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImGuiEXT::getCCRefId(Ref* p)
|
int ImGuiEXT::getCCRefId(Ref* p)
|
||||||
{
|
{
|
||||||
int id = 0;
|
int id = 0;
|
||||||
const auto it = usedCCRefIdMap.find(p);
|
const auto it = usedCCRefIdMap.find(p);
|
||||||
if (it == usedCCRefIdMap.end())
|
if (it == usedCCRefIdMap.end())
|
||||||
{
|
{
|
||||||
usedCCRefIdMap[p] = 0;
|
usedCCRefIdMap[p] = 0;
|
||||||
usedCCRef.pushBack(p);
|
usedCCRef.pushBack(p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
id = ++it->second;
|
id = ++it->second;
|
||||||
// BKDR hash
|
// BKDR hash
|
||||||
constexpr unsigned int seed = 131;
|
constexpr unsigned int seed = 131;
|
||||||
unsigned int hash = 0;
|
unsigned int hash = 0;
|
||||||
for (auto i = 0u; i < sizeof(void*); ++i)
|
for (auto i = 0u; i < sizeof(void*); ++i)
|
||||||
hash = hash * seed + ((const char*)&p)[i];
|
hash = hash * seed + ((const char*)&p)[i];
|
||||||
for (auto i = 0u; i < sizeof(int); ++i)
|
for (auto i = 0u; i < sizeof(int); ++i)
|
||||||
hash = hash * seed + ((const char*)&id)[i];
|
hash = hash * seed + ((const char*)&id)[i];
|
||||||
return (int)hash;
|
return (int)hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_IMGUI_MARKDOWN)
|
#if defined(HAVE_IMGUI_MARKDOWN)
|
||||||
|
@ -473,64 +536,64 @@ static ImGui::MarkdownImageData ImGuiMarkdownInvalidImageData = { false, false,
|
||||||
|
|
||||||
void MarkdownLinkCallback(ImGui::MarkdownLinkCallbackData data)
|
void MarkdownLinkCallback(ImGui::MarkdownLinkCallbackData data)
|
||||||
{
|
{
|
||||||
if (ImGuiMarkdownLinkCallback)
|
if (ImGuiMarkdownLinkCallback)
|
||||||
{
|
{
|
||||||
ImGuiMarkdownLinkCallback(
|
ImGuiMarkdownLinkCallback(
|
||||||
{ data.text, (size_t)data.textLength }, { data.link, (size_t)data.linkLength }, data.isImage);
|
{ data.text, (size_t)data.textLength }, { data.link, (size_t)data.linkLength }, data.isImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::MarkdownImageData MarkdownImageCallback(ImGui::MarkdownLinkCallbackData data)
|
ImGui::MarkdownImageData MarkdownImageCallback(ImGui::MarkdownLinkCallbackData data)
|
||||||
{
|
{
|
||||||
if (!data.isImage || !ImGuiMarkdownImageCallback)
|
if (!data.isImage || !ImGuiMarkdownImageCallback)
|
||||||
return ImGuiMarkdownInvalidImageData;
|
return ImGuiMarkdownInvalidImageData;
|
||||||
Sprite* sp; ImVec2 size; ImVec4 tint_col; ImVec4 border_col;
|
Sprite* sp; ImVec2 size; ImVec4 tint_col; ImVec4 border_col;
|
||||||
std::tie(sp, size, tint_col, border_col) = ImGuiMarkdownImageCallback(
|
std::tie(sp, size, tint_col, border_col) = ImGuiMarkdownImageCallback(
|
||||||
{ data.text, (size_t)data.textLength },
|
{ data.text, (size_t)data.textLength },
|
||||||
{ data.link, (size_t)data.linkLength });
|
{ data.link, (size_t)data.linkLength });
|
||||||
if(!sp || !sp->getTexture())
|
if (!sp || !sp->getTexture())
|
||||||
return ImGuiMarkdownInvalidImageData;
|
return ImGuiMarkdownInvalidImageData;
|
||||||
auto size_ = size;
|
auto size_ = size;
|
||||||
const auto rect = sp->getTextureRect();
|
const auto rect = sp->getTextureRect();
|
||||||
if (size_.x <= 0.f) size_.x = rect.size.width;
|
if (size_.x <= 0.f) size_.x = rect.size.width;
|
||||||
if (size_.y <= 0.f) size_.y = rect.size.height;
|
if (size_.y <= 0.f) size_.y = rect.size.height;
|
||||||
ImVec2 uv0, uv1;
|
ImVec2 uv0, uv1;
|
||||||
std::tie(uv0, uv1) = getTextureUV(sp);
|
std::tie(uv0, uv1) = getTextureUV(sp);
|
||||||
ImGuiEXT::getInstance()->getCCRefId(sp);
|
ImGuiEXT::getInstance()->getCCRefId(sp);
|
||||||
return { true, true, (ImTextureID)sp->getTexture(), size_,uv0, uv1, tint_col, border_col };
|
return { true, true, (ImTextureID)sp->getTexture(), size_,uv0, uv1, tint_col, border_col };
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string ImGuiMarkdownLinkIcon;
|
static std::string ImGuiMarkdownLinkIcon;
|
||||||
static ImGui::MarkdownConfig ImGuiMarkdownConfig = {
|
static ImGui::MarkdownConfig ImGuiMarkdownConfig = {
|
||||||
MarkdownLinkCallback, MarkdownImageCallback, "" };
|
MarkdownLinkCallback, MarkdownImageCallback, "" };
|
||||||
|
|
||||||
void ImGuiEXT::setMarkdownLinkCallback(const MdLinkCallback& f)
|
void ImGuiEXT::setMarkdownLinkCallback(const MdLinkCallback& f)
|
||||||
{
|
{
|
||||||
ImGuiMarkdownLinkCallback = f;
|
ImGuiMarkdownLinkCallback = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::setMarkdownImageCallback(const MdImageCallback& f)
|
void ImGuiEXT::setMarkdownImageCallback(const MdImageCallback& f)
|
||||||
{
|
{
|
||||||
ImGuiMarkdownImageCallback = f;
|
ImGuiMarkdownImageCallback = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::setMarkdownFont(int index, ImFont* font, bool seperator, float scale)
|
void ImGuiEXT::setMarkdownFont(int index, ImFont* font, bool seperator, float scale)
|
||||||
{
|
{
|
||||||
if (index < 0 || index >= ImGui::MarkdownConfig::NUMHEADINGS)
|
if (index < 0 || index >= ImGui::MarkdownConfig::NUMHEADINGS)
|
||||||
return;
|
return;
|
||||||
ImGuiMarkdownConfig.headingFormats[index] = { font,seperator };
|
ImGuiMarkdownConfig.headingFormats[index] = { font,seperator };
|
||||||
ImGuiMarkdownConfig.headingScales[index] = scale;
|
ImGuiMarkdownConfig.headingScales[index] = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::setMarkdownLinkIcon(const std::string& icon)
|
void ImGuiEXT::setMarkdownLinkIcon(const std::string& icon)
|
||||||
{
|
{
|
||||||
ImGuiMarkdownLinkIcon = icon;
|
ImGuiMarkdownLinkIcon = icon;
|
||||||
ImGuiMarkdownConfig.linkIcon = ImGuiMarkdownLinkIcon.c_str();
|
ImGuiMarkdownConfig.linkIcon = ImGuiMarkdownLinkIcon.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::markdown(const std::string& content)
|
void ImGuiEXT::markdown(const std::string& content)
|
||||||
{
|
{
|
||||||
ImGui::Markdown(content.c_str(), content.size(), ImGuiMarkdownConfig);
|
ImGui::Markdown(content.c_str(), content.size(), ImGuiMarkdownConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,145 +10,145 @@
|
||||||
|
|
||||||
NS_CC_EXT_BEGIN
|
NS_CC_EXT_BEGIN
|
||||||
|
|
||||||
class ImGuiEXTRenderer;
|
class ImGuiEXTEventTracker;
|
||||||
class ImGuiEXT
|
class ImGuiEXT
|
||||||
{
|
{
|
||||||
friend class ImGuiEXTRenderer;
|
friend class ImGuiEXTRenderer;
|
||||||
void init();
|
void init();
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum class CHS_GLYPH_RANGE {
|
enum class CHS_GLYPH_RANGE {
|
||||||
NONE,
|
NONE,
|
||||||
GENERAL,
|
GENERAL,
|
||||||
FULL
|
FULL
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
DEFAULT_FONT_SIZE = 13 // see imgui.cpp
|
DEFAULT_FONT_SIZE = 13 // see imgui.cpp
|
||||||
};
|
};
|
||||||
|
|
||||||
static ImGuiEXT* getInstance();
|
static ImGuiEXT* getInstance();
|
||||||
static void destroyInstance();
|
static void destroyInstance();
|
||||||
static void setOnInit(const std::function<void(ImGuiEXT*)>& callBack);
|
static void setOnInit(const std::function<void(ImGuiEXT*)>& callBack);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scale ImGui with majorMoniter DPI scaling
|
/// Scale ImGui with majorMoniter DPI scaling
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userScale">Usually is 1.0</param>
|
/// <param name="userScale">Usually is 1.0</param>
|
||||||
/// <param name="fontFile">The full path of .ttc/.ttf file</param>
|
/// <param name="fontFile">The full path of .ttc/.ttf file</param>
|
||||||
/// <returns>The final contentZoomFactor = userScale * dpiScale</returns>
|
/// <returns>The final contentZoomFactor = userScale * dpiScale</returns>
|
||||||
float scaleAllByDPI(float userScale);
|
float scaleAllByDPI(float userScale);
|
||||||
float getContentZoomFactor() const { return _contentZoomFactor; }
|
float getContentZoomFactor() const { return _contentZoomFactor; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add ImGui font with contentZoomFactor
|
/// Add ImGui font with contentZoomFactor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fontFile"></param>
|
/// <param name="fontFile"></param>
|
||||||
/// <param name="glyphRange"></param>
|
/// <param name="glyphRange"></param>
|
||||||
void addFont(const std::string& fontFile, float fontSize = DEFAULT_FONT_SIZE, CHS_GLYPH_RANGE glyphRange = CHS_GLYPH_RANGE::NONE);
|
void addFont(const std::string& fontFile, float fontSize = DEFAULT_FONT_SIZE, CHS_GLYPH_RANGE glyphRange = CHS_GLYPH_RANGE::NONE);
|
||||||
void clearFonts();
|
void clearFonts();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a ImGui render loop to specific scene
|
/// Add a ImGui render loop to specific scene
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">The FOURCC id of render loop, starts with '#', such as "#abcd"</id>
|
/// <param name="id">The FOURCC id of render loop, starts with '#', such as "#abcd"</id>
|
||||||
/// <param name="target">the target scene to render ImGui</param>
|
/// <param name="func">the ImGui render loop</param>
|
||||||
/// <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(const std::string& id, Scene* target, std::function<void()> func);
|
bool addRenderLoop(const std::string& id, std::function<void()> func, Scene* target);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove ImGui render loop
|
/// Remove ImGui render loop
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">FOURCC starts with '#', such as "#abcd"</id>
|
/// <param name="id">FOURCC starts with '#', such as "#abcd"</id>
|
||||||
void removeRenderLoop(const std::string& id);
|
void removeRenderLoop(const std::string& id);
|
||||||
|
|
||||||
// imgui helper
|
// imgui helper
|
||||||
void image(
|
void image(
|
||||||
Texture2D* tex,
|
Texture2D* tex,
|
||||||
const ImVec2& size,
|
const ImVec2& size,
|
||||||
const ImVec2& uv0 = ImVec2(0, 0),
|
const ImVec2& uv0 = ImVec2(0, 0),
|
||||||
const ImVec2& uv1 = ImVec2(1, 1),
|
const ImVec2& uv1 = ImVec2(1, 1),
|
||||||
const ImVec4& tint_col = ImVec4(1, 1, 1, 1),
|
const ImVec4& tint_col = ImVec4(1, 1, 1, 1),
|
||||||
const ImVec4& border_col = ImVec4(0, 0, 0, 0));
|
const ImVec4& border_col = ImVec4(0, 0, 0, 0));
|
||||||
void image(
|
void image(
|
||||||
Sprite* sprite,
|
Sprite* sprite,
|
||||||
const ImVec2& size,
|
const ImVec2& size,
|
||||||
const ImVec4& tint_col = ImVec4(1, 1, 1, 1),
|
const ImVec4& tint_col = ImVec4(1, 1, 1, 1),
|
||||||
const ImVec4& border_col = ImVec4(0, 0, 0, 0));
|
const ImVec4& border_col = ImVec4(0, 0, 0, 0));
|
||||||
bool imageButton(
|
bool imageButton(
|
||||||
Texture2D* tex,
|
Texture2D* tex,
|
||||||
const ImVec2& size,
|
const ImVec2& size,
|
||||||
const ImVec2& uv0 = ImVec2(0, 0),
|
const ImVec2& uv0 = ImVec2(0, 0),
|
||||||
const ImVec2& uv1 = ImVec2(1, 1),
|
const ImVec2& uv1 = ImVec2(1, 1),
|
||||||
int frame_padding = -1,
|
int frame_padding = -1,
|
||||||
const ImVec4& bg_col = ImVec4(0, 0, 0, 0),
|
const ImVec4& bg_col = ImVec4(0, 0, 0, 0),
|
||||||
const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
|
const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
|
||||||
bool imageButton(
|
bool imageButton(
|
||||||
Sprite* sprite,
|
Sprite* sprite,
|
||||||
const ImVec2& size,
|
const ImVec2& size,
|
||||||
int frame_padding = -1,
|
int frame_padding = -1,
|
||||||
const ImVec4& bg_col = ImVec4(0, 0, 0, 0),
|
const ImVec4& bg_col = ImVec4(0, 0, 0, 0),
|
||||||
const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
|
const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
|
||||||
|
|
||||||
void node(
|
void node(
|
||||||
Node* node,
|
Node* node,
|
||||||
const ImVec4& tint_col = ImVec4(1, 1, 1, 1),
|
const ImVec4& tint_col = ImVec4(1, 1, 1, 1),
|
||||||
const ImVec4& border_col = ImVec4(0, 0, 0, 0));
|
const ImVec4& border_col = ImVec4(0, 0, 0, 0));
|
||||||
bool nodeButton(
|
bool nodeButton(
|
||||||
Node* node,
|
Node* node,
|
||||||
int frame_padding = -1,
|
int frame_padding = -1,
|
||||||
const ImVec4& bg_col = ImVec4(0, 0, 0, 0),
|
const ImVec4& bg_col = ImVec4(0, 0, 0, 0),
|
||||||
const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
|
const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
|
||||||
|
|
||||||
std::tuple<ImTextureID, int> useTexture(Texture2D* texture);
|
std::tuple<ImTextureID, int> useTexture(Texture2D* texture);
|
||||||
std::tuple<ImTextureID, ImVec2, ImVec2, int> useSprite(Sprite* sprite);
|
std::tuple<ImTextureID, ImVec2, ImVec2, int> useSprite(Sprite* sprite);
|
||||||
std::tuple<ImTextureID, ImVec2, ImVec2, int> useNode(Node* node, const ImVec2& pos);
|
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, const ImVec4& col);
|
||||||
static void setNodeColor(Node* node, ImGuiCol col);
|
static void setNodeColor(Node* node, ImGuiCol col);
|
||||||
static void setLabelColor(Label* label, const ImVec4& col);
|
static void setLabelColor(Label* label, const ImVec4& col);
|
||||||
static void setLabelColor(Label* label, bool disabled = false);
|
static void setLabelColor(Label* label, bool disabled = false);
|
||||||
static void setLabelColor(Label* label, ImGuiCol col);
|
static void setLabelColor(Label* label, ImGuiCol col);
|
||||||
|
|
||||||
ImWchar* addGlyphRanges(const std::string& key, const std::vector<ImWchar>& ranges);
|
ImWchar* addGlyphRanges(const std::string& key, const std::vector<ImWchar>& ranges);
|
||||||
static void mergeFontGlyphs(ImFont* dst, ImFont* src, ImWchar start, ImWchar end);
|
static void mergeFontGlyphs(ImFont* dst, ImFont* src, ImWchar start, ImWchar end);
|
||||||
int getCCRefId(Ref* p);
|
int getCCRefId(Ref* p);
|
||||||
|
|
||||||
#if defined(HAVE_IMGUI_MARKDOWN)
|
#if defined(HAVE_IMGUI_MARKDOWN)
|
||||||
// markdown
|
// markdown
|
||||||
|
|
||||||
using MdLinkCallback = std::function<void(const std::string&, const std::string&, bool)>;
|
using MdLinkCallback = std::function<void(const std::string&, const std::string&, bool)>;
|
||||||
using MdImageCallback = std::function<std::tuple<Sprite*, ImVec2, ImVec4, ImVec4>(const std::string&, const std::string&)>;
|
using MdImageCallback = std::function<std::tuple<Sprite*, ImVec2, ImVec4, ImVec4>(const std::string&, const std::string&)>;
|
||||||
|
|
||||||
void setMarkdownLinkCallback(const MdLinkCallback& f);
|
void setMarkdownLinkCallback(const MdLinkCallback& f);
|
||||||
void setMarkdownImageCallback(const MdImageCallback& f);
|
void setMarkdownImageCallback(const MdImageCallback& f);
|
||||||
void setMarkdownFont(int index, ImFont* font, bool seperator, float scale = 1.f);
|
void setMarkdownFont(int index, ImFont* font, bool seperator, float scale = 1.f);
|
||||||
void setMarkdownLinkIcon(const std::string& icon);
|
void setMarkdownLinkIcon(const std::string& icon);
|
||||||
void markdown(const std::string& content);
|
void markdown(const std::string& content);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// perform draw ImGui stubs
|
// perform draw ImGui stubs
|
||||||
void beginFrame();
|
void beginFrame();
|
||||||
void update();
|
void update();
|
||||||
void endFrame();
|
void endFrame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::function<void(ImGuiEXT*)> _onInit;
|
static std::function<void(ImGuiEXT*)> _onInit;
|
||||||
|
|
||||||
struct RenderPipline {
|
|
||||||
ImGuiEXTRenderer* renderer;
|
|
||||||
std::function<void()> frame;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unordered_map<uint32_t, RenderPipline> _renderPiplines;
|
struct RenderPipline {
|
||||||
|
ImGuiEXTEventTracker* tracker;
|
||||||
|
std::function<void()> frame;
|
||||||
|
};
|
||||||
|
|
||||||
std::unordered_map<Ref*, int> usedCCRefIdMap;
|
std::unordered_map<uint32_t, RenderPipline> _renderPiplines;
|
||||||
// cocos objects should be retained until next frame
|
|
||||||
Vector<Ref*> usedCCRef;
|
|
||||||
std::unordered_map<std::string, std::vector<ImWchar>> glyphRanges;
|
|
||||||
|
|
||||||
float _contentZoomFactor = 1.0f;
|
std::unordered_map<Ref*, int> usedCCRefIdMap;
|
||||||
|
// cocos objects should be retained until next frame
|
||||||
|
Vector<Ref*> usedCCRef;
|
||||||
|
std::unordered_map<std::string, std::vector<ImWchar>> glyphRanges;
|
||||||
|
|
||||||
|
float _contentZoomFactor = 1.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_CC_EXT_END
|
NS_CC_EXT_END
|
||||||
|
|
Loading…
Reference in New Issue