Skip to content

Commit

Permalink
feat: implement marking records in weather editor (#960)
Browse files Browse the repository at this point in the history
* feat: implement marking records in weather editor

* chore: remove unneeded comment
  • Loading branch information
ObsidianGeologist authored Feb 12, 2025
1 parent 93dc0ec commit 4812820
Show file tree
Hide file tree
Showing 3 changed files with 215 additions and 5 deletions.
197 changes: 193 additions & 4 deletions src/Editor/EditorWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

#include "State.h"
#include "features/Weather.h"
#include "imgui_internal.h"

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(EditorWindow::Settings, recordMarkers, markedRecords)

bool ContainsStringIgnoreCase(const std::string_view a_string, const std::string_view a_substring)
{
Expand Down Expand Up @@ -90,10 +93,12 @@ void EditorWindow::ShowObjectsWindow()
HelpMarker("Type a part of an object name to filter the list.");

// Create a table for the right column with "Name" and "ID" headers
if (ImGui::BeginTable("DetailsTable", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
if (ImGui::BeginTable("DetailsTable", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Editor ID", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("Form ID", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("File", ImGuiTableColumnFlags_WidthStretch); // Added File column
ImGui::TableSetupColumn("File", ImGuiTableColumnFlags_WidthStretch); // Added File column
ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthStretch);

ImGui::TableHeadersRow();

// Display objects based on the selected category
Expand All @@ -106,24 +111,62 @@ void EditorWindow::ShowObjectsWindow()
if (!ContainsStringIgnoreCase(widgets[i]->GetEditorID(), filterBuffer))
continue; // Skip widgets that don't match the filter

auto editorLabel = widgets[i]->GetEditorID();
auto markedRecord = settings.markedRecords.find(editorLabel);
ImGui::TableNextRow();

// Set background colour
if (markedRecord != settings.markedRecords.end()) {
auto& color = settings.recordMarkers[markedRecord->second];
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, ImGui::ColorConvertFloat4ToU32(color));
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, ImGui::ColorConvertFloat4ToU32(color));
} else {
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, ImGuiCol_TableRowBg);
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, ImGuiCol_TableRowBgAlt);
}

ImGui::TableSetColumnIndex(0);

// Editor ID column
if (ImGui::Selectable(widgets[i]->GetEditorID().c_str(), widgets[i]->IsOpen(), ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowDoubleClick)) {
if (ImGui::Selectable(editorLabel.c_str(), widgets[i]->IsOpen(), ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowDoubleClick)) {
if (ImGui::IsMouseDoubleClicked(0)) {
widgets[i]->SetOpen(true);
}
}

// Opens a context menu on right click to mark records by color
if (ImGui::BeginPopupContextItem(std::format("widget_context_menu##{}", widgets[i]->GetFormID()).c_str(), ImGuiPopupFlags_MouseButtonRight)) {
auto& markedRecords = settings.markedRecords;

for (auto& recordMarker : settings.recordMarkers) {
if (ImGui::MenuItem(recordMarker.first.c_str())) {
settings.markedRecords[editorLabel] = recordMarker.first;
Save();
}
}

if (ImGui::MenuItem("Remove")) {
markedRecords.erase(editorLabel);
Save();
}

ImGui::EndPopup();
}

// Form ID column
ImGui::TableNextColumn();
ImGui::Text(widgets[i]->GetFormID().c_str());

// File column
ImGui::TableNextColumn();
ImGui::Text(widgets[i]->GetFilename().c_str());

// Status column
ImGui::TableNextColumn();

if (markedRecord != settings.markedRecords.end()) {
ImGui::Text(markedRecord->second.c_str());
}
}

ImGui::EndTable();
Expand Down Expand Up @@ -204,6 +247,8 @@ void EditorWindow::RenderUI()
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Save all"))
SaveAll();
if (ImGui::MenuItem("Settings"))
showSettingsWindow = !showSettingsWindow;
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Edit")) {
Expand All @@ -219,15 +264,23 @@ void EditorWindow::RenderUI()
}

auto width = ImGui::GetIO().DisplaySize.x;
auto height = ImGui::GetIO().DisplaySize.y;
auto viewportWidth = width * 0.5f; // Make the viewport take up 50% of the width
auto sideWidth = (width - viewportWidth) / 2.0f; // Divide the remaining width equally between the side windows

ImGui::SetNextWindowSize(ImVec2(sideWidth, ImGui::GetIO().DisplaySize.y * 0.75f));
ShowObjectsWindow();

ImGui::SetNextWindowSize(ImVec2(viewportWidth, ImGui::GetIO().DisplaySize.y * 0.5f));
ShowViewportWindow();

auto settingsWindowHeight = height * 0.25f;
auto settingsWindowWidth = width * 0.25f;
ImGui::SetNextWindowSizeConstraints(ImVec2(settingsWindowWidth, settingsWindowHeight), ImVec2(FLT_MAX, FLT_MAX));
ImGui::SetNextWindowPos({ (width / 2.0f) - (settingsWindowWidth / 2.0f), (height / 2.0f) - (settingsWindowHeight / 2.0f) });
if (showSettingsWindow) {
ShowSettingsWindow();
}

ShowWidgetWindow();
}

Expand All @@ -236,6 +289,8 @@ void EditorWindow::SetupResources()
auto dataHandler = RE::TESDataHandler::GetSingleton();
auto& weatherArray = dataHandler->GetFormArray<RE::TESWeather>();

Load();

for (auto weather : weatherArray) {
auto widget = new WeatherWidget(weather);
widget->Load();
Expand Down Expand Up @@ -301,4 +356,138 @@ void EditorWindow::SaveAll()
if (lightingTemplate->IsOpen())
lightingTemplate->Save();
}

Save();
}

void EditorWindow::SaveSettings()
{
j = settings;
}

void EditorWindow::LoadSettings()
{
if (!j.empty())
settings = j;
}

void EditorWindow::ShowSettingsWindow()
{
ImGui::Begin("Settings");

// Static variable to track the selected category
static std::string selectedOption = "Preferences";

// Create a table with two columns
if (ImGui::BeginTable("SettingsTable", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner | ImGuiTableFlags_NoHostExtendX)) {
// Set up column widths
ImGui::TableSetupColumn("Options", ImGuiTableColumnFlags_WidthStretch, 0.3f); // 30% width
ImGui::TableSetupColumn("##Settings", ImGuiTableColumnFlags_WidthStretch, 0.7f); // 70% width

ImGui::TableNextRow();

// Left column: Options
ImGui::TableSetColumnIndex(0);
// List of options
const char* options[] = { "Preferences" };
for (int i = 0; i < IM_ARRAYSIZE(options); ++i) {
if (ImGui::Selectable(options[i], selectedOption == options[i])) {
selectedOption = options[i]; // Update selected option
}
}

// Right column: Option settings
ImGui::TableSetColumnIndex(1);

// Create a table for the right column.
if (selectedOption == "Preferences") {
if (ImGui::BeginTable("PreferencesTable", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Label", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("Colour", ImGuiTableColumnFlags_WidthStretch);

auto& recordMarkers = settings.recordMarkers;

for (auto& recordMarker : recordMarkers) {
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text(recordMarker.first.c_str());

ImGui::TableSetColumnIndex(1);
if (ImGui::ColorEdit4(std::format("Color##{}", recordMarker.first).c_str(), (float*)&recordMarker.second)) {
Save();
};
}

ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);

if (recordMarkers.size() < maxRecordMarkers && ImGui::Selectable("Add new marker")) {
recordMarkers.insert({ std::string("New marker##new{}", recordMarkers.size()), { 0, 0, 0, 255 } });
Save();
}

ImGui::EndTable();
}
}
ImGui::EndTable();
}

ImGui::End();
}

void EditorWindow::Save()
{
SaveSettings();
const std::string filePath = State::GetSingleton()->folderPath;
const std::string file = std::format("{}\\{}.json", filePath, settingsFilename);

std::ofstream settingsFile(file);

if (!settingsFile.good() || !settingsFile.is_open()) {
logger::warn("Failed to open settings file: {}", file);
return;
}

if (settingsFile.fail()) {
logger::warn("Unable to create settings file: {}", file);
settingsFile.close();
return;
}

logger::info("Saving settings file: {}", file);

try {
settingsFile << j.dump(1);

settingsFile.close();
} catch (const nlohmann::json::parse_error& e) {
logger::warn("Error parsing settings for settings file ({}) : {}\n", filePath, e.what());
settingsFile.close();
}
}

void EditorWindow::Load()
{
std::string filePath = std::format("{}\\{}.json", State::GetSingleton()->folderPath, settingsFilename);

std::ifstream settingsFile(filePath);

if (!std::filesystem::exists(filePath)) {
// Does not have any settings so just return.
return;
}

if (!settingsFile.good() || !settingsFile.is_open()) {
logger::warn("Failed to load settings file: {}", filePath);
return;
}

try {
j << settingsFile;
settingsFile.close();
} catch (const nlohmann::json::parse_error& e) {
logger::warn("Error parsing settings for file ({}) : {}\n", filePath, e.what());
settingsFile.close();
}
LoadSettings();
}
21 changes: 21 additions & 0 deletions src/Editor/EditorWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class EditorWindow
}

bool open = false;
const static int maxRecordMarkers = 10;

Texture2D* tempTexture;

Expand All @@ -37,6 +38,26 @@ class EditorWindow

void Draw();

struct Settings
{
std::map<std::string, ImVec4> recordMarkers = {
{ "TO-DO", { 0.9f, 0.15, 0.15, 1 } },
{ "In-progress", { 0.5f, 0.8f, 0.0f, 1 } },
{ "Done", { 0.05f, 0.85f, 0.3f, 1 } }
};
std::map<std::string, std::string> markedRecords;
};

Settings settings;

private:
void SaveAll();
void SaveSettings();
void LoadSettings();
void ShowSettingsWindow();
void Save();
void Load();
json j;
std::string settingsFilename = "EditorSettings";
bool showSettingsWindow = false;
};
2 changes: 1 addition & 1 deletion src/Features/Weather.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ uint8_t LerpUint8_t(const uint8_t oldValue, const uint8_t newVal, const float le

void LerpColor(const RE::TESWeather::Data::Color3& oldColor, RE::TESWeather::Data::Color3& newColor, const float changePct)
{
newColor.red = (int8_t)std::lerp(-128, 127, changePct); //LerpInt8_t(oldColor.red, newColor.red, changePct)
newColor.red = (int8_t)std::lerp(-128, 127, changePct);
newColor.green = (int8_t)std::lerp(oldColor.green, newColor.green, changePct);
newColor.blue = LerpInt8_t(oldColor.blue, newColor.blue, changePct);
}
Expand Down

0 comments on commit 4812820

Please sign in to comment.