115 lines
2.7 KiB
C++
115 lines
2.7 KiB
C++
#pragma once
|
|
|
|
#include <memory>
|
|
#include <sophia/frame_info.hpp>
|
|
#include <sophia/handles.hpp>
|
|
#include <sophia/ui/dock_layout.hpp>
|
|
#include <sophia/ui/panel.hpp>
|
|
#include <sophia/util/assert.hpp>
|
|
#include <string_view>
|
|
#include <typeinfo>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace sophia {
|
|
|
|
class PanelRegistry {
|
|
public:
|
|
PanelRegistry(const PanelRegistry&) = delete;
|
|
PanelRegistry& operator=(const PanelRegistry&) = delete;
|
|
|
|
PanelRegistry() = default;
|
|
~PanelRegistry() = default;
|
|
|
|
PanelHandle add(std::unique_ptr<Panel> panel);
|
|
|
|
template <typename T, typename... Args>
|
|
PanelHandle emplace(Args&&... args) {
|
|
return add(std::make_unique<T>(std::forward<Args>(args)...));
|
|
}
|
|
|
|
const Panel& get(PanelHandle handle) const;
|
|
Panel& get(PanelHandle handle) {
|
|
return const_cast<Panel&>(std::as_const(*this).get(handle));
|
|
}
|
|
|
|
template <typename T>
|
|
const T& get(PanelHandle handle) const {
|
|
const Panel& panel = get(handle);
|
|
SOPHIA_ASSERT(dynamic_cast<const T*>(&panel) != nullptr,
|
|
"PanelHandle does not refer to a", typeid(T).name());
|
|
return static_cast<const T&>(panel);
|
|
}
|
|
|
|
template <typename T>
|
|
T& get(PanelHandle handle) {
|
|
return const_cast<T&>(std::as_const(*this).template get<T>(handle));
|
|
}
|
|
|
|
void remove(PanelHandle handle);
|
|
bool isValid(PanelHandle handle) const;
|
|
|
|
template <typename T>
|
|
const T* find() const {
|
|
for (const Slot& slot : slots) {
|
|
if (slot.panel) {
|
|
if (const T* panel = dynamic_cast<const T*>(slot.panel.get())) {
|
|
return panel;
|
|
}
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
template <typename T>
|
|
T* find() {
|
|
return const_cast<T*>(std::as_const(*this).template find<T>());
|
|
}
|
|
|
|
const Panel* find(std::string_view name) const {
|
|
for (const Slot& slot : slots) {
|
|
if (slot.panel && slot.panel->getName() == name) {
|
|
return slot.panel.get();
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
Panel* find(std::string_view name) {
|
|
return const_cast<Panel*>(std::as_const(*this).find(name));
|
|
}
|
|
|
|
u32 size() const;
|
|
u32 visibleCount() const;
|
|
|
|
std::vector<std::string_view> names() const {
|
|
std::vector<std::string_view> result;
|
|
result.reserve(slots.size());
|
|
for (const Slot& slot : slots) {
|
|
if (slot.panel) {
|
|
result.push_back(slot.panel->getName());
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void update(const FrameInfo& frameInfo);
|
|
|
|
void setDefaultLayout(DockLayout layout) {
|
|
defaultLayout = std::move(layout);
|
|
}
|
|
const DockLayout& getDefaultLayout() const { return defaultLayout; }
|
|
|
|
private:
|
|
struct Slot {
|
|
std::unique_ptr<Panel> panel;
|
|
u32 generation = 0;
|
|
};
|
|
|
|
std::vector<Slot> slots;
|
|
std::vector<u32> freeList;
|
|
DockLayout defaultLayout;
|
|
};
|
|
|
|
} // namespace sophia
|