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;
|
||||
}
|
||||
|
||||
// TODO: Rename to ImGuiEXTLayerBlock
|
||||
// Because it's only used for block event when ImGui::IsAnyWindowHovered() == 'true'
|
||||
class ImGuiEXTRenderer : public Layer
|
||||
{
|
||||
CC_CONSTRUCTOR_ACCESS:
|
||||
bool initWithImGuiEXT()
|
||||
{
|
||||
if (!Layer::init())
|
||||
return false;
|
||||
class ImGuiEXTEventTracker {
|
||||
public:
|
||||
virtual ~ImGuiEXTEventTracker() {}
|
||||
};
|
||||
|
||||
// Track scene event and check whether routed to the scene graph
|
||||
class ImGuiEXTSceneEventTracker : public ImGuiEXTEventTracker
|
||||
{
|
||||
public:
|
||||
bool initWithScene(Scene* scene)
|
||||
{
|
||||
#ifdef CC_PLATFORM_PC
|
||||
_trackLayer = utils::newInstance<Layer>();
|
||||
|
||||
// note: when at the first click to focus the window, this will not take effect
|
||||
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);
|
||||
_trackLayer->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, _trackLayer);
|
||||
|
||||
// add by halx99
|
||||
auto stopAnyMouse = [=](EventMouse* event) {
|
||||
|
@ -39,7 +40,8 @@ CC_CONSTRUCTOR_ACCESS:
|
|||
};
|
||||
auto mouseListener = EventListenerMouse::create();
|
||||
mouseListener->onMouseDown = mouseListener->onMouseUp = stopAnyMouse;
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(mouseListener, this);
|
||||
_trackLayer->getEventDispatcher()->addEventListenerWithSceneGraphPriority(mouseListener, _trackLayer);
|
||||
scene->addChild(_trackLayer, INT_MAX);
|
||||
#endif
|
||||
// add an empty sprite to avoid render problem
|
||||
// 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
|
||||
* c. Director::EVENT_BEFORE_DRAW call beginFrame, EVENT_AFTER_VISIT call endFrame
|
||||
*/
|
||||
|
||||
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;
|
||||
|
@ -194,7 +253,7 @@ void ImGuiEXT::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
|
||||
auto fourccId = fourccValue(id);
|
||||
|
@ -203,22 +262,26 @@ bool ImGuiEXT::addRenderLoop(const std::string& id, Scene* scene, std::function<
|
|||
return false;
|
||||
}
|
||||
|
||||
auto renderer = utils::newInstance<ImGuiEXTRenderer>(&ImGuiEXTRenderer::initWithImGuiEXT);
|
||||
scene->addChild(renderer, INT_MAX, fourccId);
|
||||
_renderPiplines.emplace(fourccId, RenderPipline{ renderer, std::move(onFrame) });
|
||||
ImGuiEXTEventTracker* tracker;
|
||||
if (target)
|
||||
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 false;
|
||||
}
|
||||
|
||||
void ImGuiEXT::removeRenderLoop(const std::string& id)
|
||||
{
|
||||
auto fourccId = fourccValue(id);
|
||||
const auto iter = _renderPiplines.find(fourccId);
|
||||
if (iter != _renderPiplines.end()) {
|
||||
auto renderer = iter->second.renderer;
|
||||
if (renderer->getParent())
|
||||
renderer->removeFromParent();
|
||||
renderer->release();
|
||||
auto tracker = iter->second.tracker;
|
||||
delete tracker;
|
||||
_renderPiplines.erase(iter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
NS_CC_EXT_BEGIN
|
||||
|
||||
class ImGuiEXTRenderer;
|
||||
class ImGuiEXTEventTracker;
|
||||
class ImGuiEXT
|
||||
{
|
||||
friend class ImGuiEXTRenderer;
|
||||
|
@ -52,9 +52,9 @@ public:
|
|||
/// 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="target">the target scene to render ImGui</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>
|
||||
/// Remove ImGui render loop
|
||||
|
@ -137,7 +137,7 @@ private:
|
|||
static std::function<void(ImGuiEXT*)> _onInit;
|
||||
|
||||
struct RenderPipline {
|
||||
ImGuiEXTRenderer* renderer;
|
||||
ImGuiEXTEventTracker* tracker;
|
||||
std::function<void()> frame;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue