Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 48 additions & 166 deletions src/WeatherEditor/EditorWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(EditorWindow::Settings::PaletteColorEntry, r, g, b, useCount, lastUsedTime, isFavorite)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(EditorWindow::Settings::PaletteFavoriteColor, hasValue, r, g, b)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(EditorWindow::Settings, recordMarkers, markedRecords, autoApplyChanges, useTextButtons, enableInheritFromParent, editorUIScale, favoriteWidgets, recentWidgets, maxRecentWidgets, rememberOpenWidgets, lastOpenWidgets, showViewport, paletteColors, paletteFavorites)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(EditorWindow::Settings, recordMarkers, markedRecords, autoApplyChanges, useTextButtons, enableInheritFromParent, editorUIScale, favoriteWidgets, recentWidgets, maxRecentWidgets, showViewport, widgetTypeSizes, paletteColors, paletteFavorites)
Comment thread
Dlizzio marked this conversation as resolved.

void DrawIconStar(ImVec2 center, float radius, ImU32 color, bool filled)
{
Expand Down Expand Up @@ -178,11 +178,15 @@ void EditorWindow::ShowObjectsWindow()
// Create a table with two columns
if (ImGui::BeginTable("ObjectTable", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner)) {
// Fixed categories column, objects column fills remaining width
ImGui::TableSetupColumn("Categories", ImGuiTableColumnFlags_WidthFixed, 180.0f * Util::GetUIScale());
const float categoriesWidth = 180.0f * Util::GetUIScale();
ImGui::TableSetupColumn("Categories", ImGuiTableColumnFlags_WidthFixed, categoriesWidth);
ImGui::TableSetupColumn("Objects", ImGuiTableColumnFlags_WidthStretch);

ImGui::TableNextRow();

if (resetLayout)
ImGui::TableSetColumnWidth(0, categoriesWidth);

// Left column: Categories
ImGui::TableSetColumnIndex(0);

Expand Down Expand Up @@ -866,13 +870,8 @@ void EditorWindow::ShowWidgetWindow()
}

// Draw all open widgets using WidgetFactory template
WidgetFactory::DrawOpenWidgets(weatherWidgets, lastFocusedWidget);
WidgetFactory::DrawOpenWidgets(lightingTemplateWidgets, lastFocusedWidget);
WidgetFactory::DrawOpenWidgets(imageSpaceWidgets, lastFocusedWidget);
WidgetFactory::DrawOpenWidgets(volumetricLightingWidgets, lastFocusedWidget);
WidgetFactory::DrawOpenWidgets(precipitationWidgets, lastFocusedWidget);
WidgetFactory::DrawOpenWidgets(lensFlareWidgets, lastFocusedWidget);
WidgetFactory::DrawOpenWidgets(referenceEffectWidgets, lastFocusedWidget);
for (auto* collection : GetWidgetCollections())
WidgetFactory::DrawOpenWidgets(*collection, lastFocusedWidget);

// Draw current cell lighting widget if open
if (currentCellLightingWidget && currentCellLightingWidget->IsOpen()) {
Expand Down Expand Up @@ -916,55 +915,25 @@ void EditorWindow::RenderUI()

// Save individual widgets submenu
if (ImGui::BeginMenu("Save")) {
bool hasOpenWidgets = false;

// Weather widgets
for (auto& widget : weatherWidgets) {
if (widget->IsOpen()) {
hasOpenWidgets = true;
if (ImGui::MenuItem(std::format("Save {}", widget->GetEditorID()).c_str())) {
widget->Save();
}
}
}

// Lighting Template widgets
for (auto& widget : lightingTemplateWidgets) {
if (widget->IsOpen()) {
hasOpenWidgets = true;
if (ImGui::MenuItem(std::format("Save {}", widget->GetEditorID()).c_str())) {
widget->Save();
}
}
}

// ImageSpace widgets
for (auto& widget : imageSpaceWidgets) {
if (widget->IsOpen()) {
hasOpenWidgets = true;
if (ImGui::MenuItem(std::format("Save {}", widget->GetEditorID()).c_str())) {
widget->Save();
}
}
bool hasOpen = false;
for (auto* collection : GetWidgetCollections())
hasOpen = WidgetFactory::DrawSaveWidgetMenuItems(*collection, hasOpen);

if (currentCellLightingWidget && currentCellLightingWidget->IsOpen()) {
hasOpen = true;
if (ImGui::MenuItem(currentCellLightingWidget->GetEditorID().c_str()))
currentCellLightingWidget->Save();
}

if (!hasOpenWidgets) {
if (!hasOpen)
ImGui::TextDisabled("No open widgets");
}

ImGui::EndMenu();
}

ImGui::Separator();
if (ImGui::MenuItem("Close All Weather Widgets")) {
for (auto& widget : weatherWidgets) widget->SetOpen(false);
}
if (ImGui::MenuItem("Close All Lighting Widgets")) {
for (auto& widget : lightingTemplateWidgets) widget->SetOpen(false);
}
if (ImGui::MenuItem("Close All ImageSpace Widgets")) {
for (auto& widget : imageSpaceWidgets) widget->SetOpen(false);
}
for (auto* collection : GetWidgetCollections())
WidgetFactory::DrawCloseAllMenuItem(*collection);
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Settings")) {
Expand Down Expand Up @@ -1014,12 +983,7 @@ void EditorWindow::RenderUI()
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Automatically apply weather changes to the game as you edit");
}
if (ImGui::Checkbox("Remember Open Widgets", &settings.rememberOpenWidgets)) {
Save();
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Restore previously open widgets when editor reopens");
}

if (ImGui::Checkbox("Enable Inherit From Parent", &settings.enableInheritFromParent)) {
Save();
}
Expand All @@ -1042,37 +1006,19 @@ void EditorWindow::RenderUI()

ImGui::Separator();
ImGui::Text("Open Widgets:");
ImGui::Separator();

int openCount = 0;
for (auto& widget : weatherWidgets) {
if (widget->IsOpen()) {
openCount++;
if (ImGui::MenuItem(std::format("Weather: {}", widget->GetEditorID()).c_str())) {
// Focus window (ImGui will bring to front when clicked)
}
}
}
for (auto& widget : lightingTemplateWidgets) {
if (widget->IsOpen()) {
openCount++;
if (ImGui::MenuItem(std::format("Lighting: {}", widget->GetEditorID()).c_str())) {
// Focus window
}
}
}
for (auto& widget : imageSpaceWidgets) {
if (widget->IsOpen()) {
openCount++;
if (ImGui::MenuItem(std::format("ImageSpace: {}", widget->GetEditorID()).c_str())) {
// Focus window
}
}
for (auto* collection : GetWidgetCollections())
openCount = WidgetFactory::DrawOpenWidgetMenuItems(*collection, openCount);

if (currentCellLightingWidget && currentCellLightingWidget->IsOpen()) {
++openCount;
if (ImGui::MenuItem(std::format("{}: {}", currentCellLightingWidget->GetWidgetTypeName(), currentCellLightingWidget->GetEditorID()).c_str()))
ImGui::SetWindowFocus(currentCellLightingWidget->GetWindowTitle().c_str());
}

if (openCount == 0) {
if (openCount == 0)
ImGui::TextDisabled("No widgets open");
}

ImGui::EndMenu();
}
Expand Down Expand Up @@ -1375,6 +1321,8 @@ void EditorWindow::RenderUI()
// Show palette window
PaletteWindow::GetSingleton()->Draw();

if (resetLayout)
ResetWidgetTypeSizes();
resetLayout = false;
Comment thread
Dlizzio marked this conversation as resolved.

// Render notifications on top of everything
Expand Down Expand Up @@ -1418,12 +1366,8 @@ EditorWindow::~EditorWindow()
{
ShowGameMenus();
delete tempTexture;
weatherWidgets.clear();
lightingTemplateWidgets.clear();
imageSpaceWidgets.clear();
volumetricLightingWidgets.clear();
precipitationWidgets.clear();
referenceEffectWidgets.clear();
for (auto* collection : GetWidgetCollections())
collection->clear();
artObjectWidgets.clear();
effectShaderWidgets.clear();
currentCellLightingWidget.reset();
Expand Down Expand Up @@ -1457,12 +1401,11 @@ void EditorWindow::UpdateOpenState()
DisableVanityCamera();
HideGameMenus();
BackgroundBlur::SetWeatherEditorActive(settings.showViewport);
RestoreSessionWidgets();

} else if (!open && wasOpen) {
RestoreVanityCamera();
ShowGameMenus();
BackgroundBlur::SetWeatherEditorActive(false);
SaveSessionWidgets();
}

wasOpen = open;
Expand Down Expand Up @@ -1527,33 +1470,30 @@ void EditorWindow::Draw()

void EditorWindow::SaveAll()
{
for (auto& weather : weatherWidgets) {
if (weather->IsOpen())
weather->Save();
}

for (auto& lightingTemplate : lightingTemplateWidgets) {
if (lightingTemplate->IsOpen())
lightingTemplate->Save();
}

for (auto& imageSpace : imageSpaceWidgets) {
if (imageSpace->IsOpen())
imageSpace->Save();
}
auto saveOpen = [](auto& widgets) {
for (auto& w : widgets)
if (w->IsOpen())
w->Save();
};
for (auto* collection : GetWidgetCollections())
saveOpen(*collection);
if (currentCellLightingWidget && currentCellLightingWidget->IsOpen())
currentCellLightingWidget->Save();

Save();
}

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

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

void EditorWindow::ShowSettingsWindow()
Expand Down Expand Up @@ -1606,9 +1546,6 @@ void EditorWindow::ShowSettingsWindow()
ImGui::TextUnformatted("Session & History");
ImGui::Spacing();

ImGui::Checkbox("Remember open widgets", &settings.rememberOpenWidgets);
Util::AddTooltip("Automatically reopen widgets that were open when you last closed the editor");

ImGui::SliderInt("Max recent widgets", &settings.maxRecentWidgets, 5, 20);
Util::AddTooltip("Maximum number of recent widgets to remember");

Expand Down Expand Up @@ -2113,27 +2050,15 @@ void EditorWindow::PerformUndo()
undoStack.pop_back();

if (!state.widget) {
for (auto& w : weatherWidgets) {
if (w->GetEditorID() == state.widgetId) {
state.widget = w.get();
break;
}
}
if (!state.widget) {
for (auto& w : imageSpaceWidgets) {
if (w->GetEditorID() == state.widgetId) {
state.widget = w.get();
break;
}
}
}
if (!state.widget) {
for (auto& w : lightingTemplateWidgets) {
for (auto* collection : GetWidgetCollections()) {
for (auto& w : *collection) {
if (w->GetEditorID() == state.widgetId) {
state.widget = w.get();
break;
}
}
if (state.widget)
break;
}
Comment thread
Dlizzio marked this conversation as resolved.
}

Expand Down Expand Up @@ -2289,46 +2214,3 @@ bool EditorWindow::IsFavorite(const std::string& widgetId) const
{
return std::find(settings.favoriteWidgets.begin(), settings.favoriteWidgets.end(), widgetId) != settings.favoriteWidgets.end();
}

void EditorWindow::SaveSessionWidgets()
{
settings.lastOpenWidgets.clear();

// Save all currently open widgets
for (auto& widget : weatherWidgets) {
if (widget->IsOpen()) {
settings.lastOpenWidgets.push_back(widget->GetEditorID());
}
}
for (auto& widget : lightingTemplateWidgets) {
if (widget->IsOpen()) {
settings.lastOpenWidgets.push_back(widget->GetEditorID());
}
}

Save();
}

void EditorWindow::RestoreSessionWidgets()
{
if (!settings.rememberOpenWidgets || settings.lastOpenWidgets.empty()) {
return;
}

// Open widgets that were open in last session
for (const auto& widgetId : settings.lastOpenWidgets) {
// Search in all widget collections
for (auto& widget : weatherWidgets) {
if (widget->GetEditorID() == widgetId) {
widget->SetOpen(true);
break;
}
}
for (auto& widget : lightingTemplateWidgets) {
if (widget->GetEditorID() == widgetId) {
widget->SetOpen(true);
break;
}
}
}
}
31 changes: 20 additions & 11 deletions src/WeatherEditor/EditorWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,22 @@ class EditorWindow
Texture2D* tempTexture = nullptr;

// Widget collections owned by EditorWindow, created in SetupResources(), released in destructor
std::vector<std::unique_ptr<Widget>> weatherWidgets;
std::vector<std::unique_ptr<Widget>> lightingTemplateWidgets;
std::vector<std::unique_ptr<Widget>> imageSpaceWidgets;
std::vector<std::unique_ptr<Widget>> volumetricLightingWidgets;
std::vector<std::unique_ptr<Widget>> precipitationWidgets;
std::vector<std::unique_ptr<Widget>> lensFlareWidgets;
std::vector<std::unique_ptr<Widget>> referenceEffectWidgets;
using WidgetVec = std::vector<std::unique_ptr<Widget>>;
WidgetVec weatherWidgets;
WidgetVec lightingTemplateWidgets;
WidgetVec imageSpaceWidgets;
WidgetVec volumetricLightingWidgets;
WidgetVec precipitationWidgets;
WidgetVec lensFlareWidgets;
WidgetVec referenceEffectWidgets;

/// Returns references to all editable widget collections for centralized iteration.
std::array<WidgetVec*, 7> GetWidgetCollections()
{
return { &weatherWidgets, &lightingTemplateWidgets, &imageSpaceWidgets,
&volumetricLightingWidgets, &precipitationWidgets, &lensFlareWidgets,
&referenceEffectWidgets };
}
std::vector<std::unique_ptr<Widget>> artObjectWidgets;
std::vector<std::unique_ptr<Widget>> effectShaderWidgets;

Expand Down Expand Up @@ -186,10 +195,12 @@ class EditorWindow
std::vector<std::string> favoriteWidgets;
std::map<std::string, std::vector<std::string>> recentWidgets;
int maxRecentWidgets = 10;
bool rememberOpenWidgets = true;
std::vector<std::string> lastOpenWidgets;

bool showViewport = true;

// Per-widget-type window sizes (serialized as JSON for persistence)
json widgetTypeSizes;

// Palette settings
struct PaletteColorEntry
{
Expand Down Expand Up @@ -222,8 +233,6 @@ class EditorWindow
void AddToRecent(const std::string& widgetId, const std::string& category);
void ToggleFavorite(const std::string& widgetId);
bool IsFavorite(const std::string& widgetId) const;
void SaveSessionWidgets();
void RestoreSessionWidgets();

// Navigation helpers for weather-controlled settings
void OpenWeatherFeatureSetting(RE::TESWeather* weather, const std::string& featureName, const std::string& settingName);
Expand Down
Loading
Loading