Update themes to differentiate from default dear_imgui themes and add a classic theme that's similar to simulate.
PiperOrigin-RevId: 843313013 Change-Id: Id01841097f32a5b01acd8fcf59392a73acad8f27
This commit is contained in:
committed by
Copybara-Service
parent
3c19b63ed3
commit
e07adc387a
+169
-97
@@ -88,38 +88,22 @@ static void SelectParentPerturb(const mjModel* model, mjvPerturb& perturb) {
|
||||
}
|
||||
}
|
||||
|
||||
// FontAwesome icon codes.
|
||||
static constexpr const char* ICON_FA_PLAY = "\xef\x81\x8b";
|
||||
static constexpr const char* ICON_FA_PAUSE = "\xef\x81\x8c";
|
||||
static constexpr const char* ICON_FA_COPY = "\xef\x83\x85";
|
||||
static constexpr const char* ICON_FA_EJECT = "\xef\x81\x92";
|
||||
static constexpr const char* ICON_FA_REFRESH = "\xef\x80\xa1";
|
||||
static constexpr const char* ICON_FA_COMMENT = "\xef\x83\xa5";
|
||||
static constexpr const char* ICON_FA_UNDO = "\xef\x83\xa2";
|
||||
static constexpr const char* ICON_FA_ARROWS = "\xef\x81\x87";
|
||||
static constexpr const char* ICON_FA_CAMERA = "\xef\x80\xbd";
|
||||
static constexpr const char* ICON_FA_MOON = "\xef\x86\x86";
|
||||
static constexpr const char* ICON_FA_SUN = "\xef\x86\x85";
|
||||
static constexpr const char* ICON_FA_CARET_LEFT = "\xef\x83\x99";
|
||||
static constexpr const char* ICON_FA_CARET_RIGHT = "\xef\x83\x9a";
|
||||
static constexpr const char* ICON_FA_FAST_FORWARD = "\xef\x81\x90";
|
||||
static constexpr const char* ICON_FA_TACHOMETER = "\xef\x83\xa4";
|
||||
|
||||
static constexpr const char* ICON_PLAY = ICON_FA_PLAY;
|
||||
static constexpr const char* ICON_PAUSE = ICON_FA_PAUSE;
|
||||
static constexpr const char* ICON_COPY_CAMERA = ICON_FA_COPY;
|
||||
static constexpr const char* ICON_UNLOAD_MODEL = ICON_FA_EJECT;
|
||||
static constexpr const char* ICON_RELOAD_MODEL = ICON_FA_REFRESH;
|
||||
static constexpr const char* ICON_LABEL = ICON_FA_COMMENT;
|
||||
static constexpr const char* ICON_RESET_MODEL = ICON_FA_UNDO;
|
||||
static constexpr const char* ICON_FRAME = ICON_FA_ARROWS;
|
||||
static constexpr const char* ICON_CAMERA = ICON_FA_CAMERA;
|
||||
static constexpr const char* ICON_DARKMODE = ICON_FA_MOON;
|
||||
static constexpr const char* ICON_LIGHTMODE = ICON_FA_SUN;
|
||||
static constexpr const char* ICON_PREV_FRAME = ICON_FA_CARET_LEFT;
|
||||
static constexpr const char* ICON_NEXT_FRAME = ICON_FA_CARET_RIGHT;
|
||||
static constexpr const char* ICON_CURR_FRAME = ICON_FA_FAST_FORWARD;
|
||||
static constexpr const char* ICON_SPEED = ICON_FA_TACHOMETER;
|
||||
static constexpr const char* ICON_PLAY = platform::ICON_FA_PLAY;
|
||||
static constexpr const char* ICON_PAUSE = platform::ICON_FA_PAUSE;
|
||||
static constexpr const char* ICON_COPY_CAMERA = platform::ICON_FA_COPY;
|
||||
static constexpr const char* ICON_UNLOAD_MODEL = platform::ICON_FA_EJECT;
|
||||
static constexpr const char* ICON_RELOAD_MODEL = platform::ICON_FA_REFRESH;
|
||||
static constexpr const char* ICON_LABEL = platform::ICON_FA_COMMENT;
|
||||
static constexpr const char* ICON_RESET_MODEL = platform::ICON_FA_UNDO;
|
||||
static constexpr const char* ICON_FRAME = platform::ICON_FA_ARROWS;
|
||||
static constexpr const char* ICON_CAMERA = platform::ICON_FA_CAMERA;
|
||||
static constexpr const char* ICON_DARKMODE = platform::ICON_FA_MOON;
|
||||
static constexpr const char* ICON_LIGHTMODE = platform::ICON_FA_SUN;
|
||||
static constexpr const char* ICON_CLASSICMODE = platform::ICON_FA_DIAMOND;
|
||||
static constexpr const char* ICON_PREV_FRAME = platform::ICON_FA_CARET_LEFT;
|
||||
static constexpr const char* ICON_NEXT_FRAME = platform::ICON_FA_CARET_RIGHT;
|
||||
static constexpr const char* ICON_CURR_FRAME = platform::ICON_FA_FAST_FORWARD;
|
||||
static constexpr const char* ICON_SPEED = platform::ICON_FA_TACHOMETER;
|
||||
|
||||
// UI labels for mjtLabel.
|
||||
static constexpr const char* kLabelNames[] = {
|
||||
@@ -145,7 +129,7 @@ App::App(int width, int height, std::string ini_path,
|
||||
const platform::LoadAssetFn& load_asset_fn)
|
||||
: ini_path_(std::move(ini_path)), load_asset_fn_(load_asset_fn) {
|
||||
window_ = std::make_unique<platform::Window>("MuJoCo Studio", width, height,
|
||||
kWindowConfig, load_asset_fn);
|
||||
kWindowConfig, load_asset_fn);
|
||||
ImPlot::CreateContext();
|
||||
|
||||
auto make_context_fn = [&](const mjModel* m, mjrContext* con) {
|
||||
@@ -480,7 +464,7 @@ void App::HandleMouseEvents() {
|
||||
platform::InitPerturb(model_, data_, &camera_, &perturb_, active);
|
||||
}
|
||||
platform::MovePerturb(model_, data_, &camera_, &perturb_, action,
|
||||
mouse_dx, mouse_dy);
|
||||
mouse_dx, mouse_dy);
|
||||
}
|
||||
}
|
||||
// Handle camera movement actions.
|
||||
@@ -515,7 +499,7 @@ void App::HandleMouseEvents() {
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
platform::PickResult picked =
|
||||
platform::Pick(model_, data_, &camera_, mouse_x, mouse_y,
|
||||
window_->GetAspectRatio(), &vis_options_);
|
||||
window_->GetAspectRatio(), &vis_options_);
|
||||
if (picked.body >= 0) {
|
||||
perturb_.select = picked.body;
|
||||
perturb_.flexselect = picked.flex;
|
||||
@@ -537,7 +521,7 @@ void App::HandleMouseEvents() {
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Right)) {
|
||||
platform::PickResult picked =
|
||||
platform::Pick(model_, data_, &camera_, mouse_x, mouse_y,
|
||||
window_->GetAspectRatio(), &vis_options_);
|
||||
window_->GetAspectRatio(), &vis_options_);
|
||||
mju_copy3(camera_.lookat, picked.point);
|
||||
if (picked.body > 0 && io.KeyCtrl) {
|
||||
// Switch camera to tracking mode and track the selected body.
|
||||
@@ -697,11 +681,14 @@ void App::HandleKeyboardEvents() {
|
||||
ToggleFlag(vis_options_.geomgroup[5]);
|
||||
} else if (model_) {
|
||||
if (ImGui_IsChordJustPressed(ImGuiKey_Escape)) {
|
||||
ui_.camera_idx = platform::SetCamera(model_, &camera_, platform::kTumbleCameraIdx);
|
||||
ui_.camera_idx =
|
||||
platform::SetCamera(model_, &camera_, platform::kTumbleCameraIdx);
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_LeftBracket)) {
|
||||
ui_.camera_idx = platform::SetCamera(model_, &camera_, ui_.camera_idx - 1);
|
||||
ui_.camera_idx =
|
||||
platform::SetCamera(model_, &camera_, ui_.camera_idx - 1);
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_RightBracket)) {
|
||||
ui_.camera_idx = platform::SetCamera(model_, &camera_, ui_.camera_idx + 1);
|
||||
ui_.camera_idx =
|
||||
platform::SetCamera(model_, &camera_, ui_.camera_idx + 1);
|
||||
}
|
||||
|
||||
// WASD camera controls for free camera.
|
||||
@@ -777,7 +764,8 @@ void App::SetSpeedIndex(int idx) {
|
||||
step_control_.SetSpeed(speed);
|
||||
}
|
||||
|
||||
void App::MoveCamera(platform::CameraMotion motion, mjtNum reldx, mjtNum reldy) {
|
||||
void App::MoveCamera(platform::CameraMotion motion, mjtNum reldx,
|
||||
mjtNum reldy) {
|
||||
platform::MoveCamera(model_, data_, &camera_, motion, reldx, reldy);
|
||||
}
|
||||
|
||||
@@ -937,25 +925,39 @@ void App::SetupTheme(platform::GuiTheme theme) {
|
||||
|
||||
void App::ModelOptionsGui() {
|
||||
const float min_width = GetExpectedLabelWidth();
|
||||
const ImGuiTreeNodeFlags flags =
|
||||
const ImGuiChildFlags child_flags =
|
||||
ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysAutoResize;
|
||||
const ImGuiTreeNodeFlags node_flags =
|
||||
ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_Framed;
|
||||
|
||||
if (ImGui::TreeNodeEx("Physics Settings", flags)) {
|
||||
ImGui::BeginChild("PhysicsGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Physics Settings", node_flags)) {
|
||||
platform::PhysicsGui(model_, min_width);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNodeEx("Rendering Settings", flags)) {
|
||||
platform::RenderingGui(model_, &vis_options_, renderer_->GetRenderFlags(), min_width);
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("RenderingGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Rendering Settings", node_flags)) {
|
||||
platform::RenderingGui(model_, &vis_options_, renderer_->GetRenderFlags(),
|
||||
min_width);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNodeEx("Visibility Groups", flags)) {
|
||||
platform::GroupsGui(model_, &vis_options_, min_width);
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("GroupsGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Visibility Groups", node_flags)) {
|
||||
platform::GroupsGui(model_, &vis_options_, min_width);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNodeEx("Visualization", flags)) {
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("VisualizationGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Visualization", node_flags)) {
|
||||
platform::VisualizationGui(model_, &vis_options_, &camera_, min_width);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void App::DataInspectorGui() {
|
||||
@@ -965,10 +967,13 @@ void App::DataInspectorGui() {
|
||||
}
|
||||
|
||||
const float min_width = GetExpectedLabelWidth();
|
||||
const ImGuiTreeNodeFlags flags =
|
||||
const ImGuiChildFlags child_flags =
|
||||
ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysAutoResize;
|
||||
const ImGuiTreeNodeFlags node_flags =
|
||||
ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_Framed;
|
||||
|
||||
if (ImGui::TreeNodeEx("Noise", flags)) {
|
||||
ImGui::BeginChild("NoiseGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Noise", node_flags)) {
|
||||
float noise_scale = 0;
|
||||
float noise_rate = 0;
|
||||
step_control_.GetNoiseParameters(noise_scale, noise_rate);
|
||||
@@ -976,27 +981,43 @@ void App::DataInspectorGui() {
|
||||
step_control_.SetNoiseParameters(noise_scale, noise_rate);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNodeEx("Joints", flags)) {
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("JointsGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Joints", node_flags)) {
|
||||
platform::JointsGui(model_, data_, &vis_options_);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNodeEx("Controls", flags)) {
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("ControlsGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Controls", node_flags)) {
|
||||
platform::ControlsGui(model_, data_, &vis_options_);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNodeEx("Sensor", flags)) {
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("SensorGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Sensor", node_flags)) {
|
||||
platform::SensorGui(model_, data_);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNodeEx("Watch", flags)) {
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("WatchGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Watch", node_flags)) {
|
||||
platform::WatchGui(model_, data_, ui_.watch_field, sizeof(ui_.watch_field),
|
||||
ui_.watch_index);
|
||||
ui_.watch_index);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNodeEx("State", flags)) {
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("StateGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("State", node_flags)) {
|
||||
platform::StateGui(model_, data_, tmp_.state, tmp_.state_sig, min_width);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void DisplayElementTree(mjsElement* element) {
|
||||
@@ -1014,7 +1035,8 @@ void App::SpecExplorerGui() {
|
||||
return;
|
||||
}
|
||||
|
||||
const ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||
const ImGuiTreeNodeFlags flags =
|
||||
ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_Framed;
|
||||
|
||||
auto display_group = [this](mjtObj type, const std::string& prefix) {
|
||||
mjsElement* element = mjs_firstElement(spec_, type);
|
||||
@@ -1036,7 +1058,6 @@ void App::SpecExplorerGui() {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (ImGui::TreeNodeEx("Bodies", flags)) {
|
||||
// We don't use `display_group` here because we do additional selection
|
||||
// logic tied to the `perturb_` field.
|
||||
@@ -1055,7 +1076,8 @@ void App::SpecExplorerGui() {
|
||||
tmp_.element = element;
|
||||
tmp_.element_id = id;
|
||||
}
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
if (ImGui::IsItemHovered() &&
|
||||
ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
perturb_.select = id;
|
||||
}
|
||||
|
||||
@@ -1096,8 +1118,7 @@ void App::PropertiesGui() {
|
||||
case mjOBJ_SITE:
|
||||
ImGui::Text("Site");
|
||||
ImGui::Separator();
|
||||
platform::SitePropertiesGui(model_, data_, tmp_.element,
|
||||
tmp_.element_id);
|
||||
platform::SitePropertiesGui(model_, data_, tmp_.element, tmp_.element_id);
|
||||
break;
|
||||
default:
|
||||
// ignore other types
|
||||
@@ -1211,26 +1232,34 @@ void App::HelpGui() {
|
||||
void App::ToolBarGui() {
|
||||
if (ImGui::BeginTable("##ToolBarTable", 2)) {
|
||||
platform::ScopedStyle style;
|
||||
const ImColor red(220, 40, 40, 255);
|
||||
const ImColor green(40, 180, 40, 255);
|
||||
const ImColor yellow(250, 230, 10, 255);
|
||||
const int combo_flags = ImGuiComboFlags_NoArrowButton;
|
||||
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 560);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 520);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", " ");
|
||||
|
||||
// Reset/Reload/Unload.
|
||||
style.Color(ImGuiCol_ButtonHovered, ImColor(220, 40, 40, 255));
|
||||
// Unload button.
|
||||
ImGui::SameLine();
|
||||
style.Color(ImGuiCol_ButtonHovered, red);
|
||||
if (ImGui::Button(ICON_UNLOAD_MODEL, ImVec2(48, 32))) {
|
||||
RequestModelLoad("");
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Unload");
|
||||
style.Reset();
|
||||
|
||||
// Reload button.
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_RELOAD_MODEL, ImVec2(48, 32))) {
|
||||
RequestModelLoad(model_name_);
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Reload");
|
||||
|
||||
// Reset button.
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_RESET_MODEL, ImVec2(48, 32))) {
|
||||
ResetPhysics();
|
||||
@@ -1240,8 +1269,7 @@ void App::ToolBarGui() {
|
||||
// Play/pause button.
|
||||
ImGui::SameLine();
|
||||
const bool paused = step_control_.IsPaused();
|
||||
style.Color(ImGuiCol_Button,
|
||||
paused ? ImColor(250, 230, 10, 255) : ImColor(40, 180, 40, 255));
|
||||
style.Color(ImGuiCol_Button, paused ? yellow : green);
|
||||
if (ImGui::Button(paused ? ICON_PLAY : ICON_PAUSE, ImVec2(120, 32))) {
|
||||
step_control_.TogglePause();
|
||||
}
|
||||
@@ -1257,25 +1285,36 @@ void App::ToolBarGui() {
|
||||
ImGui::SetItemTooltip("%s", "Playback Speed");
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(80);
|
||||
int speed_index = tmp_.speed_index;
|
||||
if (ImGui::Combo("##Speed", &speed_index, kPercentRealTime.data(),
|
||||
kPercentRealTime.size())) {
|
||||
SetSpeedIndex(speed_index);
|
||||
ImGui::SetNextItemWidth(50);
|
||||
if (ImGui::BeginCombo("##Speed", kPercentRealTime[tmp_.speed_index],
|
||||
combo_flags)) {
|
||||
for (int n = 0; n < kPercentRealTime.size(); n++) {
|
||||
if (ImGui::Selectable(kPercentRealTime[n], (tmp_.speed_index == n))) {
|
||||
SetSpeedIndex(n);
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Playback Speed");
|
||||
|
||||
// Camera selection.
|
||||
std::vector<const char*> cameras = GetCameraNames();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", ICON_CAMERA);
|
||||
ImGui::SetItemTooltip("%s", "Camera");
|
||||
ImGui::SameLine();
|
||||
std::vector<const char*> cameras = GetCameraNames();
|
||||
ImGui::SetNextItemWidth(GetExpectedLabelWidth());
|
||||
int camera_idx = ui_.camera_idx - platform::kTumbleCameraIdx;
|
||||
if (ImGui::Combo("##Camera", &camera_idx, cameras.data(), cameras.size())) {
|
||||
ui_.camera_idx = ::mujoco::platform::SetCamera(
|
||||
model_, &camera_, camera_idx + platform::kTumbleCameraIdx);
|
||||
if (ImGui::BeginCombo("##Camera", cameras[camera_idx], combo_flags)) {
|
||||
for (int n = 0; n < cameras.size(); n++) {
|
||||
if (ImGui::Selectable(cameras[n], (camera_idx == n))) {
|
||||
ui_.camera_idx = ::mujoco::platform::SetCamera(
|
||||
model_, &camera_, camera_idx + platform::kTumbleCameraIdx);
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Camera");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_COPY_CAMERA)) {
|
||||
std::string camera_string = platform::CameraToString(data_, &camera_);
|
||||
@@ -1293,8 +1332,16 @@ void App::ToolBarGui() {
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(GetExpectedLabelWidth());
|
||||
ImGui::Combo("##Label", &vis_options_.label, kLabelNames,
|
||||
IM_ARRAYSIZE(kLabelNames));
|
||||
if (ImGui::BeginCombo("##Label", kLabelNames[vis_options_.label],
|
||||
combo_flags)) {
|
||||
for (int n = 0; n < IM_ARRAYSIZE(kLabelNames); n++) {
|
||||
if (ImGui::Selectable(kLabelNames[n], (vis_options_.label == n))) {
|
||||
vis_options_.label = n;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Label");
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", " |");
|
||||
@@ -1306,24 +1353,42 @@ void App::ToolBarGui() {
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(GetExpectedLabelWidth());
|
||||
ImGui::Combo("##Frame", &vis_options_.frame, kFrameNames,
|
||||
IM_ARRAYSIZE(kFrameNames));
|
||||
if (ImGui::BeginCombo("##Frame", kFrameNames[vis_options_.frame],
|
||||
combo_flags)) {
|
||||
for (int n = 0; n < IM_ARRAYSIZE(kFrameNames); n++) {
|
||||
if (ImGui::Selectable(kFrameNames[n], (vis_options_.frame == n))) {
|
||||
vis_options_.frame = n;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Frame");
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", " |");
|
||||
|
||||
// Style selection.
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ui_.theme == platform::GuiTheme::kDark
|
||||
? ICON_DARKMODE
|
||||
: ICON_LIGHTMODE)) {
|
||||
if (ui_.theme == platform::GuiTheme::kDark) {
|
||||
SetupTheme(platform::GuiTheme::kLight);
|
||||
} else {
|
||||
SetupTheme(platform::GuiTheme::kDark);
|
||||
}
|
||||
switch (ui_.theme) {
|
||||
case platform::GuiTheme::kLight:
|
||||
if (ImGui::Button(ICON_LIGHTMODE)) {
|
||||
SetupTheme(platform::GuiTheme::kDark);
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Switch to Dark Mode");
|
||||
break;
|
||||
case platform::GuiTheme::kDark:
|
||||
if (ImGui::Button(ICON_DARKMODE)) {
|
||||
SetupTheme(platform::GuiTheme::kClassic);
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Switch to Classic Mode");
|
||||
break;
|
||||
case platform::GuiTheme::kClassic:
|
||||
if (ImGui::Button(ICON_CLASSICMODE)) {
|
||||
SetupTheme(platform::GuiTheme::kLight);
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Switch to Light Mode");
|
||||
break;
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Switch Style");
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
@@ -1345,10 +1410,12 @@ void App::StatusBarGui() {
|
||||
} else {
|
||||
const float desired_realtime = step_control_.GetSpeed();
|
||||
const float measured_realtime = step_control_.GetSpeedMeasured();
|
||||
const float realtime_offset = mju_abs(measured_realtime - desired_realtime);
|
||||
const float realtime_offset =
|
||||
mju_abs(measured_realtime - desired_realtime);
|
||||
const bool misaligned = realtime_offset > 0.1 * desired_realtime;
|
||||
if (misaligned) {
|
||||
ImGui::Text("Running: %g%% (%-4.1f%%)", desired_realtime, measured_realtime);
|
||||
ImGui::Text("Running: %g%% (%-4.1f%%)", desired_realtime,
|
||||
measured_realtime);
|
||||
} else {
|
||||
ImGui::Text("Running: %g%%", desired_realtime);
|
||||
}
|
||||
@@ -1476,8 +1543,8 @@ void App::MainMenuGui() {
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem(
|
||||
tmp_.options_panel ? "Hide Options" : "Show Left UI", "Tab")) {
|
||||
if (ImGui::MenuItem(tmp_.options_panel ? "Hide Options" : "Show Left UI",
|
||||
"Tab")) {
|
||||
tmp_.options_panel = !tmp_.options_panel;
|
||||
}
|
||||
if (ImGui::MenuItem(
|
||||
@@ -1530,19 +1597,22 @@ void App::FileDialogGui() {
|
||||
if (tmp_.load_popup) {
|
||||
ImGui::OpenPopup("LoadModel");
|
||||
tmp_.load_popup = false;
|
||||
strncpy(tmp_.filename, tmp_.last_load_file.c_str(), tmp_.last_load_file.size());
|
||||
strncpy(tmp_.filename, tmp_.last_load_file.c_str(),
|
||||
tmp_.last_load_file.size());
|
||||
tmp_.filename[tmp_.last_load_file.size()] = 0;
|
||||
}
|
||||
if (tmp_.save_xml_popup) {
|
||||
ImGui::OpenPopup("SaveXML");
|
||||
tmp_.save_xml_popup = false;
|
||||
strncpy(tmp_.filename, tmp_.last_save_xml_file.c_str(), tmp_.last_save_xml_file.size());
|
||||
strncpy(tmp_.filename, tmp_.last_save_xml_file.c_str(),
|
||||
tmp_.last_save_xml_file.size());
|
||||
tmp_.filename[tmp_.last_save_xml_file.size()] = 0;
|
||||
}
|
||||
if (tmp_.save_mjb_popup) {
|
||||
ImGui::OpenPopup("SaveMJB");
|
||||
tmp_.save_mjb_popup = false;
|
||||
strncpy(tmp_.filename, tmp_.last_save_mjb_file.c_str(), tmp_.last_save_mjb_file.size());
|
||||
strncpy(tmp_.filename, tmp_.last_save_mjb_file.c_str(),
|
||||
tmp_.last_save_mjb_file.size());
|
||||
tmp_.filename[tmp_.last_save_mjb_file.size()] = 0;
|
||||
}
|
||||
if (tmp_.save_screenshot_popup) {
|
||||
@@ -1555,13 +1625,15 @@ void App::FileDialogGui() {
|
||||
if (tmp_.print_model_popup) {
|
||||
ImGui::OpenPopup("PrintModel");
|
||||
tmp_.print_model_popup = false;
|
||||
strncpy(tmp_.filename, tmp_.last_print_model_file.c_str(), tmp_.last_print_model_file.size());
|
||||
strncpy(tmp_.filename, tmp_.last_print_model_file.c_str(),
|
||||
tmp_.last_print_model_file.size());
|
||||
tmp_.filename[tmp_.last_print_model_file.size()] = 0;
|
||||
}
|
||||
if (tmp_.print_data_popup) {
|
||||
ImGui::OpenPopup("PrintData");
|
||||
tmp_.print_data_popup = false;
|
||||
strncpy(tmp_.filename, tmp_.last_print_data_file.c_str(), tmp_.last_print_data_file.size());
|
||||
strncpy(tmp_.filename, tmp_.last_print_data_file.c_str(),
|
||||
tmp_.last_print_data_file.size());
|
||||
tmp_.filename[tmp_.last_print_data_file.size()] = 0;
|
||||
}
|
||||
|
||||
@@ -1571,7 +1643,7 @@ void App::FileDialogGui() {
|
||||
ImGui::IsPopupOpen("PrintModel") || ImGui::IsPopupOpen("PrintData");
|
||||
|
||||
if (ImGui::BeginPopupModal("LoadModel", NULL,
|
||||
ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
if (platform::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
|
||||
RequestModelLoad(tmp_.filename);
|
||||
tmp_.last_load_file = tmp_.filename;
|
||||
|
||||
Reference in New Issue
Block a user