Move Style and Layout configuration to shared GUI library.
PiperOrigin-RevId: 840246253 Change-Id: Ic4664b62e86e70fd6780cd9eb885978064c5f585
This commit is contained in:
committed by
Copybara-Service
parent
5f59104877
commit
5ee8b646f7
@@ -22,6 +22,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <implot.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "experimental/platform/helpers.h"
|
||||
@@ -29,12 +30,123 @@
|
||||
|
||||
namespace mujoco::platform {
|
||||
|
||||
static constexpr int kToolsBarHeight = 48;
|
||||
static constexpr int kStatusBarHeight = 32;
|
||||
static constexpr float kOptionsRelWidth = 0.22f;
|
||||
static constexpr float kInspectorRelWidth = 0.18f;
|
||||
static constexpr float kInfoRelHeight = 0.3f;
|
||||
|
||||
static ImVec2 GetFlexElementSize(int num_cols) {
|
||||
const float width = (ImGui::GetContentRegionAvail().x / num_cols) -
|
||||
ImGui::GetStyle().FramePadding.x * 2;
|
||||
return ImVec2(width, 0);
|
||||
}
|
||||
|
||||
void SetupTheme(GuiTheme theme) {
|
||||
ImGuiStyle& s = ImGui::GetStyle();
|
||||
if (theme == GuiTheme::kDark) {
|
||||
ImGui::StyleColorsDark(&s);
|
||||
} else {
|
||||
ImGui::StyleColorsLight(&s);
|
||||
}
|
||||
s.FrameBorderSize = 1;
|
||||
}
|
||||
|
||||
ImVec4 ConfigureDockingLayout() {
|
||||
ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
|
||||
const ImVec2 dockspace_pos{
|
||||
viewport->WorkPos.x,
|
||||
viewport->WorkPos.y + kToolsBarHeight
|
||||
};
|
||||
const ImVec2 dockspace_size{
|
||||
viewport->WorkSize.x,
|
||||
viewport->WorkSize.y - kToolsBarHeight - kStatusBarHeight
|
||||
};
|
||||
|
||||
ImGuiID root = ImGui::GetID("Root");
|
||||
const bool first_time = (ImGui::DockBuilderGetNode(root) == nullptr);
|
||||
|
||||
if (first_time) {
|
||||
ImGui::DockBuilderRemoveNode(root);
|
||||
ImGui::DockBuilderAddNode(root, ImGuiDockNodeFlags_DockSpace);
|
||||
ImGui::DockBuilderSetNodeSize(root, dockspace_size);
|
||||
|
||||
// Slice up the main dock space.
|
||||
ImGuiID main = root;
|
||||
|
||||
ImGuiID options = 0;
|
||||
ImGui::DockBuilderSplitNode(main, ImGuiDir_Left, kOptionsRelWidth,
|
||||
&options, &main);
|
||||
|
||||
ImGuiID inspector = 0;
|
||||
ImGui::DockBuilderSplitNode(main, ImGuiDir_Right, kInspectorRelWidth,
|
||||
&inspector, &main);
|
||||
|
||||
ImGuiID info = 0;
|
||||
ImGui::DockBuilderSplitNode(inspector, ImGuiDir_Down, kInfoRelHeight,
|
||||
&info, &inspector);
|
||||
|
||||
ImGui::DockBuilderDockWindow("Dockspace", main);
|
||||
ImGui::DockBuilderDockWindow("Options", options);
|
||||
ImGui::DockBuilderDockWindow("Inspector", inspector);
|
||||
ImGui::DockBuilderDockWindow("Info", info);
|
||||
ImGui::DockBuilderFinish(root);
|
||||
}
|
||||
|
||||
// Create a dummy window filling the entire workspace in which we can perform
|
||||
// docking.
|
||||
ImGui::SetNextWindowPos(dockspace_pos);
|
||||
ImGui::SetNextWindowSize(dockspace_size);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
|
||||
const ImGuiWindowFlags kWorkspaceFlags =
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoBackground;
|
||||
|
||||
platform::ScopedStyle style;
|
||||
style.Var(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
style.Var(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
style.Var(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::Begin("Dockspace", nullptr, kWorkspaceFlags);
|
||||
style.Reset();
|
||||
|
||||
const ImGuiDockNodeFlags kDockSpaceFlags =
|
||||
ImGuiDockNodeFlags_PassthruCentralNode |
|
||||
ImGuiDockNodeFlags_NoDockingOverCentralNode |
|
||||
ImGuiDockNodeFlags_AutoHideTabBar;
|
||||
ImGui::DockSpace(root, ImVec2(0.0f, 0.0f), kDockSpaceFlags);
|
||||
ImGui::End();
|
||||
|
||||
const ImGuiWindowFlags kFixedFlags = ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoScrollbar |
|
||||
ImGuiWindowFlags_NoDocking;
|
||||
|
||||
// Toolbar is fixed at the top.
|
||||
ImGui::SetNextWindowPos(viewport->WorkPos, ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, kToolsBarHeight), ImGuiCond_Always);
|
||||
ImGui::Begin("ToolBar", nullptr, kFixedFlags);
|
||||
ImGui::End();
|
||||
|
||||
// StatusBar is fixed at the bottom.
|
||||
ImGui::SetNextWindowPos(ImVec2(0, viewport->Size.y - kStatusBarHeight), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, kStatusBarHeight), ImGuiCond_Always);
|
||||
ImGui::Begin("StatusBar", nullptr, kFixedFlags);
|
||||
ImGui::End();
|
||||
|
||||
const int settings_width = dockspace_size.x * kOptionsRelWidth;
|
||||
const int inspector_width = dockspace_size.x * kInspectorRelWidth;
|
||||
const float workspace_x = dockspace_pos.x + settings_width;
|
||||
const float workspace_y = dockspace_pos.y;
|
||||
const float workspace_w = dockspace_size.x - settings_width - inspector_width;
|
||||
const float workspace_h = dockspace_size.y;
|
||||
return ImVec4(workspace_x, workspace_y, workspace_w, workspace_h);
|
||||
}
|
||||
|
||||
void SensorGui(const mjModel* model, const mjData* data) {
|
||||
ImPlot::PushStyleVar(ImPlotStyleVar_FitPadding, ImVec2(0.1f, 0.1f));
|
||||
if (ImPlot::BeginPlot("Sensors", ImVec2(-1, 0),
|
||||
|
||||
@@ -25,10 +25,37 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
|
||||
namespace mujoco::platform {
|
||||
|
||||
// Standard default UX themes for MuJoCo applications.
|
||||
enum class GuiTheme {
|
||||
kLight,
|
||||
kDark,
|
||||
};
|
||||
|
||||
// Updates the ImGui internal style state to match the requested theme.
|
||||
void SetupTheme(GuiTheme theme);
|
||||
|
||||
// Configures the ImGui docking module to the standard layout used by Studio.
|
||||
// This includes the following named sections:
|
||||
// "ToolBar": fixed size bar spanning the top of the window; for placing
|
||||
// buttons and other controls that are always needed.
|
||||
// "StatusBar": fixed size bar spanning the bottom of the window; for
|
||||
// placing information and controls that are always needed.
|
||||
// "Options": resizable section of the left; designed for GUI elements that
|
||||
// are used to configure the simulation (e.g. PhysicsGui).
|
||||
// "Inspector": resizable section of the right; designed for inspecting
|
||||
// or manipulating mjData elements (e.g. ControlsGui).
|
||||
// "Info": resizable section below the inspector; designed for displaying
|
||||
// basic simulation information (e.g. InfoGui); hidden by default.
|
||||
//
|
||||
// Returns the size and position of the remaining workspace area which can then
|
||||
// be used to place additional elements (e.g. floating charts).
|
||||
ImVec4 ConfigureDockingLayout();
|
||||
|
||||
// UX for controlling the physics simulation parameters (e.g. integrator,
|
||||
// solver, etc.) in mjModel.
|
||||
void PhysicsGui(mjModel* model, float min_width);
|
||||
|
||||
Reference in New Issue
Block a user