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
|
@ -10,26 +10,27 @@ static uint32_t fourccValue(const std::string& str) {
|
||||||
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() {}
|
||||||
{
|
};
|
||||||
CC_CONSTRUCTOR_ACCESS:
|
|
||||||
bool initWithImGuiEXT()
|
|
||||||
{
|
|
||||||
if (!Layer::init())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
// Track scene event and check whether routed to the scene graph
|
||||||
|
class ImGuiEXTSceneEventTracker : public ImGuiEXTEventTracker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool initWithScene(Scene* scene)
|
||||||
|
{
|
||||||
#ifdef CC_PLATFORM_PC
|
#ifdef CC_PLATFORM_PC
|
||||||
|
_trackLayer = utils::newInstance<Layer>();
|
||||||
|
|
||||||
// note: when at the first click to focus the window, this will not take effect
|
// note: when at the first click to focus the window, this will not take effect
|
||||||
auto listener = EventListenerTouchOneByOne::create();
|
auto listener = EventListenerTouchOneByOne::create();
|
||||||
listener->setSwallowTouches(true);
|
listener->setSwallowTouches(true);
|
||||||
listener->onTouchBegan = [this](Touch* touch, Event*) -> bool {
|
listener->onTouchBegan = [this](Touch* touch, Event*) -> bool {
|
||||||
if (!_visible)
|
|
||||||
return false;
|
|
||||||
return ImGui::IsAnyWindowHovered();
|
return ImGui::IsAnyWindowHovered();
|
||||||
};
|
};
|
||||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
_trackLayer->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, _trackLayer);
|
||||||
|
|
||||||
// add by halx99
|
// add by halx99
|
||||||
auto stopAnyMouse = [=](EventMouse* event) {
|
auto stopAnyMouse = [=](EventMouse* event) {
|
||||||
|
@ -39,7 +40,8 @@ CC_CONSTRUCTOR_ACCESS:
|
||||||
};
|
};
|
||||||
auto mouseListener = EventListenerMouse::create();
|
auto mouseListener = EventListenerMouse::create();
|
||||||
mouseListener->onMouseDown = mouseListener->onMouseUp = stopAnyMouse;
|
mouseListener->onMouseDown = mouseListener->onMouseUp = stopAnyMouse;
|
||||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(mouseListener, this);
|
_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();
|
||||||
|
@ -55,12 +57,69 @@ CC_CONSTRUCTOR_ACCESS:
|
||||||
* 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ImGuiEXTRenderer()
|
~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;
|
||||||
|
@ -79,7 +138,7 @@ void ImGuiEXT::init()
|
||||||
|
|
||||||
ImGuiEXT* ImGuiEXT::getInstance()
|
ImGuiEXT* ImGuiEXT::getInstance()
|
||||||
{
|
{
|
||||||
if(_instance == nullptr)
|
if (_instance == nullptr)
|
||||||
{
|
{
|
||||||
_instance = new ImGuiEXT();
|
_instance = new ImGuiEXT();
|
||||||
_instance->init();
|
_instance->init();
|
||||||
|
@ -194,7 +253,7 @@ void ImGuiEXT::update()
|
||||||
// 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);
|
||||||
|
@ -203,11 +262,17 @@ bool ImGuiEXT::addRenderLoop(const std::string& id, Scene* scene, std::function<
|
||||||
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>();
|
||||||
|
|
||||||
|
if (tracker) {
|
||||||
|
_renderPiplines.emplace(fourccId, RenderPipline{ tracker, std::move(func) });
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::removeRenderLoop(const std::string& id)
|
void ImGuiEXT::removeRenderLoop(const std::string& id)
|
||||||
|
@ -215,10 +280,8 @@ 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();
|
|
||||||
renderer->release();
|
|
||||||
_renderPiplines.erase(iter);
|
_renderPiplines.erase(iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -488,7 +551,7 @@ ImGui::MarkdownImageData MarkdownImageCallback(ImGui::MarkdownLinkCallbackData d
|
||||||
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();
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
NS_CC_EXT_BEGIN
|
NS_CC_EXT_BEGIN
|
||||||
|
|
||||||
class ImGuiEXTRenderer;
|
class ImGuiEXTEventTracker;
|
||||||
class ImGuiEXT
|
class ImGuiEXT
|
||||||
{
|
{
|
||||||
friend class ImGuiEXTRenderer;
|
friend class ImGuiEXTRenderer;
|
||||||
|
@ -52,9 +52,9 @@ public:
|
||||||
/// 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>
|
||||||
bool addRenderLoop(const std::string& id, Scene* target, std::function<void()> func);
|
/// <param name="target">The target scene to track event, nullptr for global, useful for global GM tools</param>
|
||||||
|
bool addRenderLoop(const std::string& id, std::function<void()> func, Scene* target);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove ImGui render loop
|
/// Remove ImGui render loop
|
||||||
|
@ -137,7 +137,7 @@ private:
|
||||||
static std::function<void(ImGuiEXT*)> _onInit;
|
static std::function<void(ImGuiEXT*)> _onInit;
|
||||||
|
|
||||||
struct RenderPipline {
|
struct RenderPipline {
|
||||||
ImGuiEXTRenderer* renderer;
|
ImGuiEXTEventTracker* tracker;
|
||||||
std::function<void()> frame;
|
std::function<void()> frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue