mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
[glass] Use JSON files for storage instead of imgui ini
Storage is now nested. Separate "roots" can be configured which save to separate files. In particular, this is used to save wpigui and ImGui window position to a -window.json file. ImGui's ini (for window position) is mapped to JSON. You can optionally specify a directory to load from on the command line. If one isn't provided, it uses the global system directory. Any changes made are automatically saved here. Workspace | Open: select directory, the current layout is replaced with that workspace, and future auto-saves also switch to that location. The main window size/location is not changed, only the contents. Workspace | Save As: select directory, the current layout is saved there, and future auto-saves also switch to that location. Workspace | Reset: window locations are preserved, but all other settings are reset to default (including e.g. removing plot windows). This will also end up clearing the current save file. as with load, the main window size/location is not changed. Workspace | Save As Global: "save as" to the global system location Notably, the main window size/location is only loaded at startup, but is auto-saved as part of the current workspace.
This commit is contained in:
@@ -32,6 +32,9 @@
|
||||
#include <wpigui.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
#include "glass/Storage.h"
|
||||
#include "glass/support/ColorSetting.h"
|
||||
#include "glass/support/EnumSetting.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -114,12 +117,14 @@ struct DisplayOptions {
|
||||
|
||||
static constexpr Style kDefaultStyle = kBoxImage;
|
||||
static constexpr float kDefaultWeight = 4.0f;
|
||||
static constexpr float kDefaultColorFloat[] = {255, 0, 0, 255};
|
||||
static constexpr ImU32 kDefaultColor = IM_COL32(255, 0, 0, 255);
|
||||
static constexpr auto kDefaultWidth = 0.6858_m;
|
||||
static constexpr auto kDefaultLength = 0.8204_m;
|
||||
static constexpr bool kDefaultArrows = true;
|
||||
static constexpr int kDefaultArrowSize = 50;
|
||||
static constexpr float kDefaultArrowWeight = 4.0f;
|
||||
static constexpr float kDefaultArrowColorFloat[] = {0, 255, 0, 255};
|
||||
static constexpr ImU32 kDefaultArrowColor = IM_COL32(0, 255, 0, 255);
|
||||
static constexpr bool kDefaultSelectable = true;
|
||||
|
||||
@@ -180,7 +185,7 @@ class PoseFrameData {
|
||||
|
||||
class ObjectInfo {
|
||||
public:
|
||||
ObjectInfo();
|
||||
explicit ObjectInfo(Storage& storage);
|
||||
|
||||
DisplayOptions GetDisplayOptions() const;
|
||||
void DisplaySettings();
|
||||
@@ -191,26 +196,26 @@ class ObjectInfo {
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
bool LoadImageImpl(const char* fn);
|
||||
bool LoadImageImpl(const std::string& fn);
|
||||
|
||||
std::unique_ptr<pfd::open_file> m_fileOpener;
|
||||
|
||||
// in meters
|
||||
float* m_pWidth;
|
||||
float* m_pLength;
|
||||
float& m_width;
|
||||
float& m_length;
|
||||
|
||||
int* m_pStyle; // DisplayOptions::Style
|
||||
float* m_pWeight;
|
||||
int* m_pColor;
|
||||
EnumSetting m_style; // DisplayOptions::Style
|
||||
float& m_weight;
|
||||
ColorSetting m_color;
|
||||
|
||||
bool* m_pArrows;
|
||||
int* m_pArrowSize;
|
||||
float* m_pArrowWeight;
|
||||
int* m_pArrowColor;
|
||||
bool& m_arrows;
|
||||
int& m_arrowSize;
|
||||
float& m_arrowWeight;
|
||||
ColorSetting m_arrowColor;
|
||||
|
||||
bool* m_pSelectable;
|
||||
bool& m_selectable;
|
||||
|
||||
std::string* m_pFilename;
|
||||
std::string& m_filename;
|
||||
gui::Texture m_texture;
|
||||
};
|
||||
|
||||
@@ -219,7 +224,7 @@ class FieldInfo {
|
||||
static constexpr auto kDefaultWidth = 15.98_m;
|
||||
static constexpr auto kDefaultHeight = 8.21_m;
|
||||
|
||||
FieldInfo();
|
||||
explicit FieldInfo(Storage& storage);
|
||||
|
||||
void DisplaySettings();
|
||||
|
||||
@@ -231,25 +236,25 @@ class FieldInfo {
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
bool LoadImageImpl(const char* fn);
|
||||
bool LoadImageImpl(const std::string& fn);
|
||||
void LoadJson(std::string_view jsonfile);
|
||||
|
||||
std::unique_ptr<pfd::open_file> m_fileOpener;
|
||||
|
||||
std::string* m_pFilename;
|
||||
std::string& m_filename;
|
||||
gui::Texture m_texture;
|
||||
|
||||
// in meters
|
||||
float* m_pWidth;
|
||||
float* m_pHeight;
|
||||
float& m_width;
|
||||
float& m_height;
|
||||
|
||||
// in image pixels
|
||||
int m_imageWidth;
|
||||
int m_imageHeight;
|
||||
int* m_pTop;
|
||||
int* m_pLeft;
|
||||
int* m_pBottom;
|
||||
int* m_pRight;
|
||||
int& m_top;
|
||||
int& m_left;
|
||||
int& m_bottom;
|
||||
int& m_right;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -334,16 +339,14 @@ static bool InputPose(frc::Pose2d* pose) {
|
||||
return changed;
|
||||
}
|
||||
|
||||
FieldInfo::FieldInfo() {
|
||||
auto& storage = GetStorage();
|
||||
m_pFilename = storage.GetStringRef("image");
|
||||
m_pTop = storage.GetIntRef("top", 0);
|
||||
m_pLeft = storage.GetIntRef("left", 0);
|
||||
m_pBottom = storage.GetIntRef("bottom", -1);
|
||||
m_pRight = storage.GetIntRef("right", -1);
|
||||
m_pWidth = storage.GetFloatRef("width", kDefaultWidth.to<float>());
|
||||
m_pHeight = storage.GetFloatRef("height", kDefaultHeight.to<float>());
|
||||
}
|
||||
FieldInfo::FieldInfo(Storage& storage)
|
||||
: m_filename{storage.GetString("image")},
|
||||
m_width{storage.GetFloat("width", kDefaultWidth.to<float>())},
|
||||
m_height{storage.GetFloat("height", kDefaultHeight.to<float>())},
|
||||
m_top{storage.GetInt("top", 0)},
|
||||
m_left{storage.GetInt("left", 0)},
|
||||
m_bottom{storage.GetInt("bottom", -1)},
|
||||
m_right{storage.GetInt("right", -1)} {}
|
||||
|
||||
void FieldInfo::DisplaySettings() {
|
||||
if (ImGui::Button("Choose image...")) {
|
||||
@@ -357,23 +360,23 @@ void FieldInfo::DisplaySettings() {
|
||||
if (ImGui::Button("Reset image")) {
|
||||
Reset();
|
||||
}
|
||||
InputFloatLength("Field Width", m_pWidth);
|
||||
InputFloatLength("Field Height", m_pHeight);
|
||||
// ImGui::InputInt("Field Top", m_pTop);
|
||||
// ImGui::InputInt("Field Left", m_pLeft);
|
||||
// ImGui::InputInt("Field Right", m_pRight);
|
||||
// ImGui::InputInt("Field Bottom", m_pBottom);
|
||||
InputFloatLength("Field Width", &m_width);
|
||||
InputFloatLength("Field Height", &m_height);
|
||||
// ImGui::InputInt("Field Top", &m_top);
|
||||
// ImGui::InputInt("Field Left", &m_left);
|
||||
// ImGui::InputInt("Field Right", &m_right);
|
||||
// ImGui::InputInt("Field Bottom", &m_bottom);
|
||||
}
|
||||
|
||||
void FieldInfo::Reset() {
|
||||
m_texture = gui::Texture{};
|
||||
m_pFilename->clear();
|
||||
m_filename.clear();
|
||||
m_imageWidth = 0;
|
||||
m_imageHeight = 0;
|
||||
*m_pTop = 0;
|
||||
*m_pLeft = 0;
|
||||
*m_pBottom = -1;
|
||||
*m_pRight = -1;
|
||||
m_top = 0;
|
||||
m_left = 0;
|
||||
m_bottom = -1;
|
||||
m_right = -1;
|
||||
}
|
||||
|
||||
void FieldInfo::LoadImage() {
|
||||
@@ -384,17 +387,17 @@ void FieldInfo::LoadImage() {
|
||||
LoadJson(result[0]);
|
||||
} else {
|
||||
LoadImageImpl(result[0].c_str());
|
||||
*m_pTop = 0;
|
||||
*m_pLeft = 0;
|
||||
*m_pBottom = -1;
|
||||
*m_pRight = -1;
|
||||
m_top = 0;
|
||||
m_left = 0;
|
||||
m_bottom = -1;
|
||||
m_right = -1;
|
||||
}
|
||||
}
|
||||
m_fileOpener.reset();
|
||||
}
|
||||
if (!m_texture && !m_pFilename->empty()) {
|
||||
if (!LoadImageImpl(m_pFilename->c_str())) {
|
||||
m_pFilename->clear();
|
||||
if (!m_texture && !m_filename.empty()) {
|
||||
if (!LoadImageImpl(m_filename)) {
|
||||
m_filename.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -478,18 +481,18 @@ void FieldInfo::LoadJson(std::string_view jsonfile) {
|
||||
}
|
||||
|
||||
// save to field info
|
||||
*m_pFilename = pathname;
|
||||
*m_pTop = top;
|
||||
*m_pLeft = left;
|
||||
*m_pBottom = bottom;
|
||||
*m_pRight = right;
|
||||
*m_pWidth = width;
|
||||
*m_pHeight = height;
|
||||
m_filename = pathname;
|
||||
m_top = top;
|
||||
m_left = left;
|
||||
m_bottom = bottom;
|
||||
m_right = right;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
bool FieldInfo::LoadImageImpl(const char* fn) {
|
||||
bool FieldInfo::LoadImageImpl(const std::string& fn) {
|
||||
fmt::print("GUI: loading field image '{}'\n", fn);
|
||||
auto texture = gui::Texture::CreateFromFile(fn);
|
||||
auto texture = gui::Texture::CreateFromFile(fn.c_str());
|
||||
if (!texture) {
|
||||
std::puts("GUI: could not read field image");
|
||||
return false;
|
||||
@@ -497,7 +500,7 @@ bool FieldInfo::LoadImageImpl(const char* fn) {
|
||||
m_texture = std::move(texture);
|
||||
m_imageWidth = m_texture.GetWidth();
|
||||
m_imageHeight = m_texture.GetHeight();
|
||||
*m_pFilename = fn;
|
||||
m_filename = fn;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -512,19 +515,19 @@ FieldFrameData FieldInfo::GetFrameData(ImVec2 min, ImVec2 max) const {
|
||||
ffd.imageMax = max;
|
||||
|
||||
// size down the box by the image corners (if any)
|
||||
if (*m_pBottom > 0 && *m_pRight > 0) {
|
||||
min.x += *m_pLeft * (max.x - min.x) / m_imageWidth;
|
||||
min.y += *m_pTop * (max.y - min.y) / m_imageHeight;
|
||||
max.x -= (m_imageWidth - *m_pRight) * (max.x - min.x) / m_imageWidth;
|
||||
max.y -= (m_imageHeight - *m_pBottom) * (max.y - min.y) / m_imageHeight;
|
||||
if (m_bottom > 0 && m_right > 0) {
|
||||
min.x += m_left * (max.x - min.x) / m_imageWidth;
|
||||
min.y += m_top * (max.y - min.y) / m_imageHeight;
|
||||
max.x -= (m_imageWidth - m_right) * (max.x - min.x) / m_imageWidth;
|
||||
max.y -= (m_imageHeight - m_bottom) * (max.y - min.y) / m_imageHeight;
|
||||
}
|
||||
|
||||
// draw the field "active area" as a yellow boundary box
|
||||
gui::MaxFit(&min, &max, *m_pWidth, *m_pHeight);
|
||||
gui::MaxFit(&min, &max, m_width, m_height);
|
||||
|
||||
ffd.min = min;
|
||||
ffd.max = max;
|
||||
ffd.scale = (max.x - min.x) / *m_pWidth;
|
||||
ffd.scale = (max.x - min.x) / m_width;
|
||||
return ffd;
|
||||
}
|
||||
|
||||
@@ -537,48 +540,47 @@ void FieldInfo::Draw(ImDrawList* drawList, const FieldFrameData& ffd) const {
|
||||
drawList->AddRect(ffd.min, ffd.max, IM_COL32(255, 255, 0, 255));
|
||||
}
|
||||
|
||||
ObjectInfo::ObjectInfo() {
|
||||
auto& storage = GetStorage();
|
||||
m_pFilename = storage.GetStringRef("image");
|
||||
m_pWidth =
|
||||
storage.GetFloatRef("width", DisplayOptions::kDefaultWidth.to<float>());
|
||||
m_pLength =
|
||||
storage.GetFloatRef("length", DisplayOptions::kDefaultLength.to<float>());
|
||||
m_pStyle = storage.GetIntRef("style", DisplayOptions::kDefaultStyle);
|
||||
m_pWeight = storage.GetFloatRef("weight", DisplayOptions::kDefaultWeight);
|
||||
m_pColor = storage.GetIntRef("color", DisplayOptions::kDefaultColor);
|
||||
m_pArrows = storage.GetBoolRef("arrows", DisplayOptions::kDefaultArrows);
|
||||
m_pArrowSize =
|
||||
storage.GetIntRef("arrowSize", DisplayOptions::kDefaultArrowSize);
|
||||
m_pArrowWeight =
|
||||
storage.GetFloatRef("arrowWeight", DisplayOptions::kDefaultArrowWeight);
|
||||
m_pArrowColor =
|
||||
storage.GetIntRef("arrowColor", DisplayOptions::kDefaultArrowColor);
|
||||
m_pSelectable =
|
||||
storage.GetBoolRef("selectable", DisplayOptions::kDefaultSelectable);
|
||||
}
|
||||
ObjectInfo::ObjectInfo(Storage& storage)
|
||||
: m_width{storage.GetFloat("width",
|
||||
DisplayOptions::kDefaultWidth.to<float>())},
|
||||
m_length{storage.GetFloat("length",
|
||||
DisplayOptions::kDefaultLength.to<float>())},
|
||||
m_style{storage.GetString("style"),
|
||||
DisplayOptions::kDefaultStyle,
|
||||
{"Box/Image", "Line", "Line (Closed)", "Track"}},
|
||||
m_weight{storage.GetFloat("weight", DisplayOptions::kDefaultWeight)},
|
||||
m_color{
|
||||
storage.GetFloatArray("color", DisplayOptions::kDefaultColorFloat)},
|
||||
m_arrows{storage.GetBool("arrows", DisplayOptions::kDefaultArrows)},
|
||||
m_arrowSize{
|
||||
storage.GetInt("arrowSize", DisplayOptions::kDefaultArrowSize)},
|
||||
m_arrowWeight{
|
||||
storage.GetFloat("arrowWeight", DisplayOptions::kDefaultArrowWeight)},
|
||||
m_arrowColor{storage.GetFloatArray(
|
||||
"arrowColor", DisplayOptions::kDefaultArrowColorFloat)},
|
||||
m_selectable{
|
||||
storage.GetBool("selectable", DisplayOptions::kDefaultSelectable)},
|
||||
m_filename{storage.GetString("image")} {}
|
||||
|
||||
DisplayOptions ObjectInfo::GetDisplayOptions() const {
|
||||
DisplayOptions rv{m_texture};
|
||||
rv.style = static_cast<DisplayOptions::Style>(*m_pStyle);
|
||||
rv.weight = *m_pWeight;
|
||||
rv.color = *m_pColor;
|
||||
rv.width = units::meter_t{*m_pWidth};
|
||||
rv.length = units::meter_t{*m_pLength};
|
||||
rv.arrows = *m_pArrows;
|
||||
rv.arrowSize = *m_pArrowSize;
|
||||
rv.arrowWeight = *m_pArrowWeight;
|
||||
rv.arrowColor = *m_pArrowColor;
|
||||
rv.selectable = *m_pSelectable;
|
||||
rv.style = static_cast<DisplayOptions::Style>(m_style.GetValue());
|
||||
rv.weight = m_weight;
|
||||
rv.color = ImGui::ColorConvertFloat4ToU32(m_color.GetColor());
|
||||
rv.width = units::meter_t{m_width};
|
||||
rv.length = units::meter_t{m_length};
|
||||
rv.arrows = m_arrows;
|
||||
rv.arrowSize = m_arrowSize;
|
||||
rv.arrowWeight = m_arrowWeight;
|
||||
rv.arrowColor = ImGui::ColorConvertFloat4ToU32(m_arrowColor.GetColor());
|
||||
rv.selectable = m_selectable;
|
||||
return rv;
|
||||
}
|
||||
|
||||
void ObjectInfo::DisplaySettings() {
|
||||
static const char* styleChoices[] = {"Box/Image", "Line", "Line (Closed)",
|
||||
"Track"};
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
ImGui::Combo("Style", m_pStyle, styleChoices, IM_ARRAYSIZE(styleChoices));
|
||||
switch (*m_pStyle) {
|
||||
m_style.Combo("Style");
|
||||
switch (m_style.GetValue()) {
|
||||
case DisplayOptions::kBoxImage:
|
||||
if (ImGui::Button("Choose image...")) {
|
||||
m_fileOpener = std::make_unique<pfd::open_file>(
|
||||
@@ -591,35 +593,27 @@ void ObjectInfo::DisplaySettings() {
|
||||
if (ImGui::Button("Reset image")) {
|
||||
Reset();
|
||||
}
|
||||
InputFloatLength("Width", m_pWidth);
|
||||
InputFloatLength("Length", m_pLength);
|
||||
InputFloatLength("Width", &m_width);
|
||||
InputFloatLength("Length", &m_length);
|
||||
break;
|
||||
case DisplayOptions::kTrack:
|
||||
InputFloatLength("Width", m_pWidth);
|
||||
InputFloatLength("Width", &m_width);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ImGui::InputFloat("Line Weight", m_pWeight);
|
||||
ImColor col(*m_pColor);
|
||||
if (ImGui::ColorEdit3("Line Color", &col.Value.x,
|
||||
ImGuiColorEditFlags_NoInputs)) {
|
||||
*m_pColor = col;
|
||||
}
|
||||
ImGui::Checkbox("Arrows", m_pArrows);
|
||||
if (*m_pArrows) {
|
||||
ImGui::SliderInt("Arrow Size", m_pArrowSize, 0, 100, "%d%%",
|
||||
ImGui::InputFloat("Line Weight", &m_weight);
|
||||
m_color.ColorEdit3("Line Color", ImGuiColorEditFlags_NoInputs);
|
||||
ImGui::Checkbox("Arrows", &m_arrows);
|
||||
if (m_arrows) {
|
||||
ImGui::SliderInt("Arrow Size", &m_arrowSize, 0, 100, "%d%%",
|
||||
ImGuiSliderFlags_AlwaysClamp);
|
||||
ImGui::InputFloat("Arrow Weight", m_pArrowWeight);
|
||||
ImColor col(*m_pArrowColor);
|
||||
if (ImGui::ColorEdit3("Arrow Color", &col.Value.x,
|
||||
ImGuiColorEditFlags_NoInputs)) {
|
||||
*m_pArrowColor = col;
|
||||
}
|
||||
ImGui::InputFloat("Arrow Weight", &m_arrowWeight);
|
||||
m_arrowColor.ColorEdit3("Arrow Color", ImGuiColorEditFlags_NoInputs);
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Selectable", m_pSelectable);
|
||||
ImGui::Checkbox("Selectable", &m_selectable);
|
||||
}
|
||||
|
||||
void ObjectInfo::DrawLine(ImDrawList* drawList,
|
||||
@@ -629,10 +623,12 @@ void ObjectInfo::DrawLine(ImDrawList* drawList,
|
||||
}
|
||||
|
||||
if (points.size() == 1) {
|
||||
drawList->AddCircleFilled(points.front(), *m_pWeight, *m_pWeight);
|
||||
drawList->AddCircleFilled(points.front(), m_weight, m_weight);
|
||||
return;
|
||||
}
|
||||
|
||||
ImU32 color = ImGui::ColorConvertFloat4ToU32(m_color.GetColor());
|
||||
|
||||
// PolyLine doesn't handle acute angles well; workaround from
|
||||
// https://github.com/ocornut/imgui/issues/3366
|
||||
size_t i = 0;
|
||||
@@ -651,18 +647,18 @@ void ObjectInfo::DrawLine(ImDrawList* drawList,
|
||||
++nlin;
|
||||
}
|
||||
|
||||
drawList->AddPolyline(&points[i], nlin, *m_pColor, false, *m_pWeight);
|
||||
drawList->AddPolyline(&points[i], nlin, color, false, m_weight);
|
||||
i += nlin - 1;
|
||||
}
|
||||
|
||||
if (points.size() > 2 && *m_pStyle == DisplayOptions::kLineClosed) {
|
||||
drawList->AddLine(points.back(), points.front(), *m_pColor, *m_pWeight);
|
||||
if (points.size() > 2 && m_style.GetValue() == DisplayOptions::kLineClosed) {
|
||||
drawList->AddLine(points.back(), points.front(), color, m_weight);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectInfo::Reset() {
|
||||
m_texture = gui::Texture{};
|
||||
m_pFilename->clear();
|
||||
m_filename.clear();
|
||||
}
|
||||
|
||||
void ObjectInfo::LoadImage() {
|
||||
@@ -673,22 +669,22 @@ void ObjectInfo::LoadImage() {
|
||||
}
|
||||
m_fileOpener.reset();
|
||||
}
|
||||
if (!m_texture && !m_pFilename->empty()) {
|
||||
if (!LoadImageImpl(m_pFilename->c_str())) {
|
||||
m_pFilename->clear();
|
||||
if (!m_texture && !m_filename.empty()) {
|
||||
if (!LoadImageImpl(m_filename)) {
|
||||
m_filename.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ObjectInfo::LoadImageImpl(const char* fn) {
|
||||
bool ObjectInfo::LoadImageImpl(const std::string& fn) {
|
||||
fmt::print("GUI: loading object image '{}'\n", fn);
|
||||
auto texture = gui::Texture::CreateFromFile(fn);
|
||||
auto texture = gui::Texture::CreateFromFile(fn.c_str());
|
||||
if (!texture) {
|
||||
std::fputs("GUI: could not read object image\n", stderr);
|
||||
return false;
|
||||
}
|
||||
m_texture = std::move(texture);
|
||||
*m_pFilename = fn;
|
||||
m_filename = fn;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -857,15 +853,16 @@ void glass::DisplayField2DSettings(Field2DModel* model) {
|
||||
auto& storage = GetStorage();
|
||||
auto field = storage.GetData<FieldInfo>();
|
||||
if (!field) {
|
||||
storage.SetData(std::make_shared<FieldInfo>());
|
||||
storage.SetData(std::make_shared<FieldInfo>(storage));
|
||||
field = storage.GetData<FieldInfo>();
|
||||
}
|
||||
|
||||
static const char* unitNames[] = {"meters", "feet", "inches"};
|
||||
int* pDisplayUnits = GetStorage().GetIntRef("units", kDisplayMeters);
|
||||
EnumSetting displayUnits{GetStorage().GetString("units"),
|
||||
kDisplayMeters,
|
||||
{"meters", "feet", "inches"}};
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
ImGui::Combo("Units", pDisplayUnits, unitNames, IM_ARRAYSIZE(unitNames));
|
||||
gDisplayUnits = static_cast<DisplayUnits>(*pDisplayUnits);
|
||||
displayUnits.Combo("Units");
|
||||
gDisplayUnits = static_cast<DisplayUnits>(displayUnits.GetValue());
|
||||
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 4);
|
||||
if (ImGui::CollapsingHeader("Field")) {
|
||||
@@ -881,7 +878,7 @@ void glass::DisplayField2DSettings(Field2DModel* model) {
|
||||
PushID(name);
|
||||
auto& objRef = field->m_objects[name];
|
||||
if (!objRef) {
|
||||
objRef = std::make_unique<ObjectInfo>();
|
||||
objRef = std::make_unique<ObjectInfo>(GetStorage());
|
||||
}
|
||||
auto obj = objRef.get();
|
||||
|
||||
@@ -1025,7 +1022,7 @@ void FieldDisplay::DisplayObject(FieldObjectModel& model,
|
||||
PushID(name);
|
||||
auto& objRef = m_field->m_objects[name];
|
||||
if (!objRef) {
|
||||
objRef = std::make_unique<ObjectInfo>();
|
||||
objRef = std::make_unique<ObjectInfo>(GetStorage());
|
||||
}
|
||||
auto obj = objRef.get();
|
||||
obj->LoadImage();
|
||||
@@ -1205,7 +1202,7 @@ void glass::DisplayField2D(Field2DModel* model, const ImVec2& contentSize) {
|
||||
auto& storage = GetStorage();
|
||||
auto field = storage.GetData<FieldInfo>();
|
||||
if (!field) {
|
||||
storage.SetData(std::make_shared<FieldInfo>());
|
||||
storage.SetData(std::make_shared<FieldInfo>(storage));
|
||||
field = storage.GetData<FieldInfo>();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user