本文同时发布在我的个人博客上:https://dragon_boy.gitee.io/
层的概念在许多软件中都存在,这里以PS中的为例。在PS中的层代表一个可显示的对象,对层可以执行许多不同的操作,窗口中的图像显示的层之间进行混合的结果。
这里我们借鉴这个概念定义层类:
Layer.h
#include "Dragon/Core/Core.h"
#include "Dragon/Core/Timestep.h"
#include "Dragon/Events/Event.h"
namespace Dragon
{
class Layer
{
public:
Layer(const std::string& name = "Layer");
virtual ~Layer() = default;
virtual void OnAttach() {}
virtual void OnDetach() {}
virtual void OnUpdate(Timestep ts) {}
virtual void OnImGuiRender() {}
virtual void OnEvent(Event& event){}
inline const std::string& GetName() const { return m_DebugName; }
private:
std::string m_DebugName;
};
}
该层类上有几个成员方法:绑定和解绑,用于是否显示该层。更新函数用于刷新该层的图像。OnImGuiRender()是该层上可以显示的GUI。接着是事件响应函数。最后是获得该层名的函数。
接着我们定义管理不同层的类,这里使用容器:
LayerStack.h
#include "Dragon/Core/Core.h"
#include "Layer.h"
#include <vector>
namespace Dragon
{
class LayerStack
{
public:
LayerStack();
~LayerStack();
void PushLayer(Layer* layer);
void PushOverlay(Layer* overlay);
void PopLayer(Layer* layer);
void PopOverlay(Layer* overlay);
std::vector<Layer*>::iterator begin() { return m_Layers.begin(); }
std::vector<Layer*>::iterator end() { return m_Layers.end(); }
private:
std::vector<Layer*> m_Layers;
unsigned int m_LayerInsertIndex = 0;
};
}
这里使用vector容器来存储层,并定义两个头尾迭代器方法。PushLayer和PopLayer方法是传统的入栈出栈方法:
void LayerStack::PushLayer(Layer* layer)
{
m_Layers.emplace(m_Layers.begin() + m_LayerInsertIndex, layer);
m_LayerInsertIndex++;
layer->OnAttach();
}
void LayerStack::PopLayer(Layer* layer)
{
auto it = std::find(m_Layers.begin(), m_Layers.begin() + m_LayerInsertIndex, layer);
if (it != m_Layers.end() + m_LayerInsertIndex)
{
layer->OnDetach();
m_Layers.erase(it);
m_LayerInsertIndex--;
}
}
PushLayer将层放到头+索引值的指定位置,然后绑定该层。PopLayer通过find()方法找到要弹出的层,然后解绑,擦除层。
PushOverlay和PopOverlay
void LayerStack::PushOverlay(Layer* overlay)
{
m_Layers.emplace_back(overlay);
overlay->OnAttach();
}
void LayerStack::PopOverlay(Layer* overlay)
{
auto it = std::find(m_Layers.begin() + m_LayerInsertIndex, m_Layers.end(), overlay);
if (it != m_Layers.end())
{
overlay->OnDetach();
m_Layers.erase(it);
}
}
PushOverlay方法在容器末尾添加一个层,PopOverLay方法在当前层索引和容器末尾间删除一个指定层。
简单来说上面的方法区别是正反加减层。
之后要使用层的时候,就是创建层之后插入LayerStack对象中,然后迭代就行。
下一节介绍窗口实现。
项目github地址(未完成):https://github.com/Dragon-Baby/Dragon
网友评论