mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-31 23:59:03 +01:00
feat(editor): docked layout: windows of the editor docked around the 3d view (dockspace over the main window, default layout built when there's none or on Mode windows > Reset window layout), menu shown all the time, toolbar with the edit modes, track and road windows, gizmo operations and the top view, status bar with the outcome of the last operation and the selected node; dockspace submitted also when the frame was started by the ui of another mode, so docked windows don't come undocked on the change of mode; stable ids of the editor windows, no auto resize of the dockable ones; hints of the track and road tools placed in the part of the window the 3d view is seen in; Polish translation
This commit is contained in:
@@ -487,6 +487,7 @@ editor_mode::editor_mode() {
|
||||
// the area fill settings live in the node bank window, in the tab of the fill mode
|
||||
ui()->set_fill_options([this]() { render_area_fill(); });
|
||||
ui()->set_gizmo_options([this]() { render_gizmo_options(); });
|
||||
ui()->set_toolbar_options([this]() { render_toolbar(); });
|
||||
ui()->set_array_options([this]() { render_array(); });
|
||||
ui()->set_bend_options([this]() { render_bend(); });
|
||||
ui()->set_file_actions([this]() { save(); }, [this]() { export_scenery(); });
|
||||
@@ -1423,7 +1424,7 @@ bool editor_mode::update()
|
||||
|
||||
void editor_mode::render_settings()
|
||||
{
|
||||
ImGui::Begin(STR_C("Editor Settings"), &m_settings_open, ImGuiWindowFlags_AlwaysAutoResize);
|
||||
ImGui::Begin((std::string(STR_C("Editor Settings")) + "###editorsettings").c_str(), &m_settings_open);
|
||||
|
||||
if (ImGui::BeginTabBar("##editorsettings"))
|
||||
{
|
||||
@@ -2964,7 +2965,7 @@ void editor_mode::render_orthophoto_window()
|
||||
if (false == m_orthophoto_window)
|
||||
return;
|
||||
ImGui::SetNextWindowSize(ImVec2(430.0f, 0.0f), ImGuiCond_FirstUseEver);
|
||||
if (ImGui::Begin(STR_C("Orthophoto##window"), &m_orthophoto_window, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
if (ImGui::Begin((std::string(STR_C("Orthophoto##window")) + "###orthophoto").c_str(), &m_orthophoto_window))
|
||||
render_orthophoto_ui();
|
||||
ImGui::End();
|
||||
}
|
||||
@@ -3623,6 +3624,51 @@ void editor_mode::render_array()
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void editor_mode::render_toolbar()
|
||||
{
|
||||
// edit modes of the node bank, each of them takes the mouse over from the track window
|
||||
std::pair<char const *, nodebank_panel::edit_mode> const modes[] = {
|
||||
{STR_C("Select"), nodebank_panel::MODIFY}, {STR_C("Insert"), nodebank_panel::ADD}, {STR_C("Brush"), nodebank_panel::BRUSH}, {STR_C("Area fill"), nodebank_panel::FILL}, {STR_C("Copy to bank"), nodebank_panel::COPY}};
|
||||
for (auto const &mode : modes)
|
||||
{
|
||||
if (ImGui::MenuItem(mode.first, nullptr, ui()->mode() == mode.second))
|
||||
{
|
||||
m_track_window_open = false;
|
||||
ui()->set_mode(mode.second);
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem(STR_C("Tracks"), nullptr, m_track_window_open))
|
||||
{
|
||||
if (m_track_window_open)
|
||||
m_track_window_open = false;
|
||||
else
|
||||
show_track_tab(m_track_tab);
|
||||
}
|
||||
if (ImGui::MenuItem("Roads", nullptr, m_roadtool.window))
|
||||
{
|
||||
m_roadtool.window = !m_roadtool.window;
|
||||
if (m_roadtool.window)
|
||||
m_track_window_open = false;
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (m_gizmo_enabled)
|
||||
{
|
||||
std::pair<char const *, gizmo_operation> const operations[] = {
|
||||
{STR_C("Translate (Q)"), gizmo_operation::translate}, {STR_C("Rotate (W)"), gizmo_operation::rotate}, {STR_C("Scale (E)"), gizmo_operation::scale}};
|
||||
for (auto const &operation : operations)
|
||||
{
|
||||
if (ImGui::MenuItem(operation.first, nullptr, m_gizmo_op == operation.second))
|
||||
m_gizmo_op = operation.second;
|
||||
}
|
||||
if (m_gizmo_op != gizmo_operation::scale && ImGui::MenuItem(STR_C("Local space (R)"), nullptr, m_gizmo_local))
|
||||
m_gizmo_local = !m_gizmo_local;
|
||||
ImGui::Separator();
|
||||
}
|
||||
if (ImGui::MenuItem(STR_C("Top view, orthographic (O)"), nullptr, Global.EditorOrtho))
|
||||
toggle_ortho();
|
||||
}
|
||||
|
||||
void editor_mode::render_gizmo_options()
|
||||
{
|
||||
if (ImGui::Button(Global.EditorOrtho ? "3D view (O)" : "Top view, orthographic (O)"))
|
||||
@@ -4585,7 +4631,7 @@ void editor_mode::on_mouse_button(int const Button, int const Action, int const
|
||||
void editor_mode::render_change_history(){
|
||||
|
||||
|
||||
ImGui::Begin(STR_C("Editor History"), &m_change_history, ImGuiWindowFlags_AlwaysAutoResize);
|
||||
ImGui::Begin((std::string(STR_C("Editor History")) + "###editorhistory").c_str(), &m_change_history);
|
||||
int maxsize = m_max_history_size;
|
||||
if (ImGui::InputInt(STR_C("Max history size"), &maxsize))
|
||||
{
|
||||
|
||||
@@ -425,6 +425,8 @@ class editor_mode : public application_mode, private editor_track::observer
|
||||
void render_gizmo();
|
||||
// gizmo settings, drawn in the toolset window
|
||||
void render_gizmo_options();
|
||||
// edit modes, editor windows and gizmo settings in the toolbar under the menu
|
||||
void render_toolbar();
|
||||
bool m_gizmo_enabled{true}; // master switch for the in-viewport gizmo
|
||||
bool m_gizmo_using{false}; // tracks an ongoing drag, so a single undo snapshot is taken per drag
|
||||
bool m_gizmo_local{false}; // manipulate in the object's local space instead of world space
|
||||
|
||||
@@ -708,7 +708,7 @@ void editor_mode::render_gauge_window()
|
||||
if (false == m_gauge.open)
|
||||
return;
|
||||
ImGui::SetNextWindowSize(ImVec2(380.0f, 420.0f), ImGuiCond_FirstUseEver);
|
||||
if (false == ImGui::Begin(STR_C("Structure gauge"), &m_gauge.open))
|
||||
if (false == ImGui::Begin((std::string(STR_C("Structure gauge")) + "###structuregauge").c_str(), &m_gauge.open))
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
|
||||
@@ -2834,8 +2834,7 @@ void editor_mode::draw_road_overlay() const
|
||||
"LMB: select a piece, a junction, a point (white dot) or a marker";
|
||||
}
|
||||
// shown above the place the track tools put their hints at
|
||||
ImGuiIO const &io = ImGui::GetIO();
|
||||
ImVec2 const position{12.0f, io.DisplaySize.y - 56.0f};
|
||||
ImVec2 const position{editor_ui::view_min().x + 12.0f, editor_ui::view_max().y - 56.0f};
|
||||
auto const size{ImGui::CalcTextSize(hint.c_str())};
|
||||
drawlist->AddRectFilled(ImVec2(position.x - 6.0f, position.y - 4.0f), ImVec2(position.x + size.x + 6.0f, position.y + size.y + 4.0f), IM_COL32(0, 0, 0, 150), 4.0f);
|
||||
drawlist->AddText(position, IM_COL32(255, 255, 255, 230), hint.c_str());
|
||||
|
||||
@@ -3657,8 +3657,10 @@ void editor_mode::draw_track_hints()
|
||||
auto hints{track_key_hints(false)};
|
||||
if (hints.size() > 4)
|
||||
hints.resize(4);
|
||||
auto const bottom{io.DisplaySize.y};
|
||||
auto const available{io.DisplaySize.x * 0.6f - 2.0f * margin};
|
||||
// in the part of the window the 3d view is seen in, between the docked windows
|
||||
auto const left{editor_ui::view_min().x + margin};
|
||||
auto const bottom{editor_ui::view_max().y};
|
||||
auto const available{(editor_ui::view_max().x - editor_ui::view_min().x) * 0.6f - 2.0f * margin};
|
||||
auto const mode{track_mode_name()};
|
||||
std::vector<std::vector<key_hint const *>> lines(1);
|
||||
float used{ImGui::CalcTextSize(mode.c_str()).x + 2.0f * pad + gap};
|
||||
@@ -3679,13 +3681,13 @@ void editor_mode::draw_track_hints()
|
||||
float width{i == 0 ? ImGui::CalcTextSize(mode.c_str()).x + 2.0f * pad : 0.0f};
|
||||
for (auto const *hint : lines[i])
|
||||
width += (width > 0.0f ? gap : 0.0f) + width_of(*hint);
|
||||
drawlist->AddRectFilled(ImVec2(margin - 6.0f, y - pad - 2.0f), ImVec2(margin + width + 6.0f, y + lineheight - pad - 2.0f), IM_COL32(0, 0, 0, 160), 4.0f);
|
||||
auto x{margin};
|
||||
drawlist->AddRectFilled(ImVec2(left - 6.0f, y - pad - 2.0f), ImVec2(left + width + 6.0f, y + lineheight - pad - 2.0f), IM_COL32(0, 0, 0, 160), 4.0f);
|
||||
auto x{left};
|
||||
if (i == 0)
|
||||
x += chip(ImVec2(x, y), mode.c_str(), IM_COL32(60, 140, 230, 235), IM_COL32(255, 255, 255, 255));
|
||||
for (auto const *hint : lines[i])
|
||||
{
|
||||
if (x > margin)
|
||||
if (x > left)
|
||||
x += gap;
|
||||
x += chip(ImVec2(x, y), hint->key, IM_COL32(255, 210, 60, 220), IM_COL32(20, 20, 20, 255)) + 5.0f;
|
||||
drawlist->AddText(ImVec2(x, y), IM_COL32(255, 255, 255, 230), hint->action.c_str());
|
||||
|
||||
@@ -16,6 +16,10 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "scene/scenelayers.h"
|
||||
#include "rendering/renderer.h"
|
||||
#include "utilities/translation.h"
|
||||
#include "imgui/imgui_internal.h"
|
||||
|
||||
glm::vec2 editor_ui::m_viewmin{0.0f};
|
||||
glm::vec2 editor_ui::m_viewmax{0.0f};
|
||||
|
||||
editor_ui::editor_ui()
|
||||
{
|
||||
@@ -29,6 +33,98 @@ editor_ui::editor_ui()
|
||||
|
||||
m_nodebankpanel.mode_options = [this](nodebank_panel::edit_mode const Mode) { render_mode_options(Mode); };
|
||||
m_nodebankpanel.header_sections = [this]() { render_header_sections(); };
|
||||
// the menu is a part of the layout of the editor, not a pop-up as in the driver mode
|
||||
m_menu_always = true;
|
||||
}
|
||||
|
||||
void editor_ui::render_dockspace()
|
||||
{
|
||||
// windows of the editor are docked around the 3d view, which is left free in the middle
|
||||
auto *viewport{ImGui::GetMainViewport()};
|
||||
auto const dockspace{ImGui::GetID("###editordockspace")};
|
||||
if (m_layoutreset || ImGui::DockBuilderGetNode(dockspace) == nullptr)
|
||||
{
|
||||
m_layoutreset = false;
|
||||
build_default_layout(dockspace);
|
||||
}
|
||||
ImGui::DockSpaceOverViewport(dockspace, viewport, ImGuiDockNodeFlags_PassthruCentralNode);
|
||||
if (auto const *central{ImGui::DockBuilderGetCentralNode(dockspace)}; central != nullptr)
|
||||
{
|
||||
m_viewmin = {central->Pos.x, central->Pos.y};
|
||||
m_viewmax = {central->Pos.x + central->Size.x, central->Pos.y + central->Size.y};
|
||||
}
|
||||
else
|
||||
{
|
||||
m_viewmin = {viewport->WorkPos.x, viewport->WorkPos.y};
|
||||
m_viewmax = {viewport->WorkPos.x + viewport->WorkSize.x, viewport->WorkPos.y + viewport->WorkSize.y};
|
||||
}
|
||||
}
|
||||
|
||||
void editor_ui::build_default_layout(unsigned int const Dockspace)
|
||||
{
|
||||
auto *viewport{ImGui::GetMainViewport()};
|
||||
ImGui::DockBuilderRemoveNode(Dockspace);
|
||||
ImGui::DockBuilderAddNode(Dockspace, ImGuiDockNodeFlags_DockSpace | ImGuiDockNodeFlags_PassthruCentralNode);
|
||||
ImGui::DockBuilderSetNodePos(Dockspace, viewport->WorkPos);
|
||||
ImGui::DockBuilderSetNodeSize(Dockspace, viewport->WorkSize);
|
||||
// widths in pixels the current windows need, as parts of the room there is
|
||||
auto const width{std::max(viewport->WorkSize.x, 1.0f)};
|
||||
auto const height{std::max(viewport->WorkSize.y, 1.0f)};
|
||||
auto const left_width{std::min(440.0f * Global.ui_scale, width * 0.3f)};
|
||||
auto const right_width{std::min(460.0f * Global.ui_scale, width * 0.3f)};
|
||||
auto const bottom_height{std::min(300.0f * Global.ui_scale, height * 0.35f)};
|
||||
ImGuiID center{Dockspace};
|
||||
auto const left{ImGui::DockBuilderSplitNode(center, ImGuiDir_Left, left_width / width, nullptr, ¢er)};
|
||||
auto const right{ImGui::DockBuilderSplitNode(center, ImGuiDir_Right, right_width / (width - left_width), nullptr, ¢er)};
|
||||
auto const bottom{ImGui::DockBuilderSplitNode(center, ImGuiDir_Down, bottom_height / height, nullptr, ¢er)};
|
||||
// windows are found by the stable part of their names, after ###
|
||||
for (auto const *window : {"###Toolset", "###Layers", "###scenehierarchy"})
|
||||
ImGui::DockBuilderDockWindow(window, left);
|
||||
for (auto const *window : {"###trackinspector", "###roadeditor", "###editorsettings", "###Include database", "###orthophoto", "###structuregauge"})
|
||||
ImGui::DockBuilderDockWindow(window, right);
|
||||
for (auto const *window : {"###profilestrip", "###editorhistory", "###modelsets"})
|
||||
ImGui::DockBuilderDockWindow(window, bottom);
|
||||
ImGui::DockBuilderFinish(Dockspace);
|
||||
}
|
||||
|
||||
void editor_ui::render_()
|
||||
{
|
||||
auto *viewport{ImGui::GetMainViewport()};
|
||||
auto const flags{ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar};
|
||||
// toolbar under the menu: the tools of the editor mode
|
||||
if (ImGui::BeginViewportSideBar("##editortoolbar", viewport, ImGuiDir_Up, ImGui::GetFrameHeight(), flags))
|
||||
{
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (m_toolbaroptions)
|
||||
m_toolbaroptions();
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
// status bar: the outcome of the last operation, and the selected node
|
||||
if (ImGui::BeginViewportSideBar("##editorstatusbar", viewport, ImGuiDir_Down, ImGui::GetFrameHeight(), flags))
|
||||
{
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (false == m_layerspanel.status.empty())
|
||||
{
|
||||
if (m_layerspanel.status_error)
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.45f, 0.4f, 1.0f), "%s", m_layerspanel.status.c_str());
|
||||
else
|
||||
ImGui::TextUnformatted(m_layerspanel.status.c_str());
|
||||
}
|
||||
if (m_node != nullptr)
|
||||
{
|
||||
auto const name{m_node->name().empty() ? std::string{"(none)"} : m_node->name()};
|
||||
auto const label{std::string{STR_C("Selected:")} + " " + name};
|
||||
ImGui::SameLine(std::max(ImGui::GetCursorPosX(), ImGui::GetWindowWidth() - ImGui::CalcTextSize(label.c_str()).x - ImGui::GetStyle().ItemSpacing.x * 2.0f));
|
||||
ImGui::TextUnformatted(label.c_str());
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// updates state of UI elements
|
||||
@@ -157,6 +253,9 @@ void editor_ui::render_menu_contents()
|
||||
|
||||
if (ImGui::BeginMenu(STR_C("Mode windows")))
|
||||
{
|
||||
if (ImGui::MenuItem(STR_C("Reset window layout")))
|
||||
m_layoutreset = true;
|
||||
ImGui::Separator();
|
||||
ImGui::MenuItem(STR_C("Toolset"), nullptr, &m_nodebankpanel.is_open);
|
||||
ImGui::MenuItem(STR_C("Layers"), nullptr, &m_layerspanel.is_open);
|
||||
ImGui::MenuItem(STR_C("Include database"), nullptr, &m_includespanel.is_open);
|
||||
|
||||
@@ -61,6 +61,11 @@ class editor_ui : public ui_layer
|
||||
{
|
||||
m_menuoptions = std::move(Renderer);
|
||||
}
|
||||
// draws the tools of the editor mode in the toolbar under the menu
|
||||
void set_toolbar_options(std::function<void()> Renderer)
|
||||
{
|
||||
m_toolbaroptions = std::move(Renderer);
|
||||
}
|
||||
// draws the gizmo settings in the toolset window (the gizmo state lives in the editor mode)
|
||||
void set_gizmo_options(std::function<void()> Renderer)
|
||||
{
|
||||
@@ -83,6 +88,15 @@ class editor_ui : public ui_layer
|
||||
void set_file_actions(std::function<void()> Save, std::function<void()> Export);
|
||||
void set_new_scenery(std::function<void()> New) { m_newscenery = std::move(New); }
|
||||
void set_open_scenery(std::function<void()> Open) { m_openscenery = std::move(Open); }
|
||||
// part of the main window between the docked windows, where the 3d view is seen; for the overlays placed in it
|
||||
static glm::vec2 view_min()
|
||||
{
|
||||
return m_viewmin;
|
||||
}
|
||||
static glm::vec2 view_max()
|
||||
{
|
||||
return m_viewmax;
|
||||
}
|
||||
// shows outcome of an operation in the layers window
|
||||
void set_status(std::string const &Status, bool const Error = false);
|
||||
|
||||
@@ -91,6 +105,10 @@ class editor_ui : public ui_layer
|
||||
void render_mode_options(nodebank_panel::edit_mode const Mode);
|
||||
void render_header_sections();
|
||||
void render_menu_contents() override;
|
||||
void render_dockspace() override;
|
||||
void render_() override;
|
||||
// docks the windows of the editor in their default places
|
||||
void build_default_layout(unsigned int const Dockspace);
|
||||
// members
|
||||
itemproperties_panel m_itempropertiespanel{"Node Properties", true}; // not a window of its own, drawn in the toolset window
|
||||
functions_panel m_functionspanel{"Functions", true}; // not a window of its own, its settings are drawn in the toolset tabs
|
||||
@@ -106,6 +124,10 @@ class editor_ui : public ui_layer
|
||||
model_set_ref m_insertset;
|
||||
std::function<void()> m_filloptions;
|
||||
std::function<void()> m_menuoptions;
|
||||
std::function<void()> m_toolbaroptions;
|
||||
bool m_layoutreset{false}; // the default layout is to be built again on the next frame
|
||||
static glm::vec2 m_viewmin;
|
||||
static glm::vec2 m_viewmax;
|
||||
std::function<void()> m_gizmooptions;
|
||||
std::function<void()> m_arrayoptions;
|
||||
std::function<void()> m_bendoptions;
|
||||
|
||||
@@ -892,7 +892,7 @@ void nodebank_panel::open_sets_window(int const Setid)
|
||||
void nodebank_panel::render_sets_window()
|
||||
{
|
||||
ImGui::SetNextWindowSize(ImVec2S(600, 380), ImGuiCond_FirstUseEver);
|
||||
if (false == ImGui::Begin(STR_C("Model sets"), &m_setsopen, ImGuiWindowFlags_NoCollapse))
|
||||
if (false == ImGui::Begin((std::string(STR_C("Model sets")) + "###modelsets").c_str(), &m_setsopen, ImGuiWindowFlags_NoCollapse))
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
|
||||
@@ -460,6 +460,13 @@ void ui_layer::update()
|
||||
|
||||
void ui_layer::render()
|
||||
{
|
||||
// the frame may have been started by the ui of another mode, when the mode changes; the windows docked in the dockspace
|
||||
// of this one would come undocked if they were drawn in a frame without it
|
||||
if (m_dockspaceframe != ImGui::GetFrameCount())
|
||||
{
|
||||
render_dockspace();
|
||||
m_dockspaceframe = ImGui::GetFrameCount();
|
||||
}
|
||||
render_background();
|
||||
render_panels();
|
||||
render_tooltip();
|
||||
@@ -490,6 +497,8 @@ void ui_layer::render_internal()
|
||||
void ui_layer::begin_ui_frame()
|
||||
{
|
||||
begin_ui_frame_internal();
|
||||
render_dockspace();
|
||||
m_dockspaceframe = ImGui::GetFrameCount();
|
||||
}
|
||||
|
||||
void ui_layer::begin_ui_frame_internal()
|
||||
@@ -520,8 +529,9 @@ void ui_layer::render_hierarchy(){
|
||||
if(!m_editor_hierarchy)
|
||||
return;
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(0, 0));
|
||||
ImGui::Begin(STR_C("Scene Hierarchy"), &m_editor_hierarchy, ImGuiWindowFlags_AlwaysAutoResize);
|
||||
// fitted to the contents when it first appears; no auto resize, which a docked window can't do
|
||||
ImGui::SetNextWindowSize(ImVec2(0, 0), ImGuiCond_FirstUseEver);
|
||||
ImGui::Begin((std::string(STR_C("Scene Hierarchy")) + "###scenehierarchy").c_str(), &m_editor_hierarchy);
|
||||
ImGui::Text("Registered nodes: %zu", scene::Hierarchy.size());
|
||||
ImGui::BeginChild("hierarchy_list", ImVec2(500, 300), true);
|
||||
|
||||
@@ -683,7 +693,7 @@ void ui_layer::render_menu()
|
||||
{
|
||||
glm::dvec2 mousepos = Global.cursor_pos;
|
||||
|
||||
if (!((Global.ControlPicking && mousepos.y < 50.0f) || m_imguiio->WantCaptureMouse) || m_suppress_menu)
|
||||
if (m_suppress_menu || (false == m_menu_always && !((Global.ControlPicking && mousepos.y < 50.0f) || m_imguiio->WantCaptureMouse)))
|
||||
return;
|
||||
|
||||
if (ImGui::BeginMainMenuBar())
|
||||
|
||||
@@ -139,6 +139,8 @@ protected:
|
||||
virtual void render_menu_contents();
|
||||
ui_log_panel m_logpanel { "Log", true };
|
||||
bool m_suppress_menu = false; // if `true`, the menu at the top of the window will not be present
|
||||
bool m_menu_always = false; // if `true`, the menu is shown all the time, not only when the mouse is at the top of the window
|
||||
int m_dockspaceframe{-1}; // frame the dockspace was last submitted in
|
||||
// progress bar config
|
||||
float m_progress { 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
||||
float m_subtaskprogress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
||||
@@ -148,6 +150,8 @@ protected:
|
||||
// methods
|
||||
// render() subclass details
|
||||
virtual void render_() {}
|
||||
// submitted right after the start of the frame, before any window that may be docked in it
|
||||
virtual void render_dockspace() {}
|
||||
// draws background quad with specified earlier texture
|
||||
void render_background();
|
||||
void render_tooltip();
|
||||
|
||||
Reference in New Issue
Block a user