Implement a dialog for unsaved changes (#1241)
* Track unsaved scene changes * Implement a dialog for unsaved changes * Exclude all selection actions from scene change tracking
This commit is contained in:
committed by
GitHub
parent
7318056235
commit
a00fb8efc2
+85
-6
@@ -1294,7 +1294,15 @@ void EditorComponent::Load()
|
||||
exitButton.SetTooltip("Exit");
|
||||
exitButton.SetColor(wi::Color(160, 50, 50, 180), wi::gui::WIDGETSTATE::IDLE);
|
||||
exitButton.SetColor(wi::Color(200, 50, 50, 255), wi::gui::WIDGETSTATE::FOCUS);
|
||||
exitButton.OnClick([](wi::gui::EventArgs args) {
|
||||
exitButton.OnClick([this](wi::gui::EventArgs args) {
|
||||
// Check all scenes for unsaved changes
|
||||
for (int i = 0; i < (int)scenes.size(); ++i)
|
||||
{
|
||||
if (!CheckUnsavedChanges(i))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
wi::platform::Exit();
|
||||
});
|
||||
topmenuWnd.AddWidget(&exitButton);
|
||||
@@ -2350,7 +2358,7 @@ void EditorComponent::Update(float dt)
|
||||
// Select...
|
||||
if (leftmouse_select || selectAll || clear_selected)
|
||||
{
|
||||
wi::Archive& archive = AdvanceHistory();
|
||||
wi::Archive& archive = AdvanceHistory(true);
|
||||
archive << HISTORYOP_SELECTION;
|
||||
// record PREVIOUS selection state...
|
||||
RecordSelection(archive);
|
||||
@@ -4735,8 +4743,9 @@ void EditorComponent::ResetHistory()
|
||||
EditorScene& editorscene = GetCurrentEditorScene();
|
||||
editorscene.historyPos = -1;
|
||||
editorscene.history.clear();
|
||||
editorscene.has_unsaved_changes = false;
|
||||
}
|
||||
wi::Archive& EditorComponent::AdvanceHistory()
|
||||
wi::Archive& EditorComponent::AdvanceHistory(const bool scene_unchanged)
|
||||
{
|
||||
EditorScene& editorscene = GetCurrentEditorScene();
|
||||
editorscene.historyPos++;
|
||||
@@ -4749,6 +4758,12 @@ wi::Archive& EditorComponent::AdvanceHistory()
|
||||
editorscene.history.emplace_back();
|
||||
editorscene.history.back().SetReadModeAndResetPos(false);
|
||||
|
||||
if (!scene_unchanged)
|
||||
{
|
||||
editorscene.has_unsaved_changes = true;
|
||||
RefreshSceneList();
|
||||
}
|
||||
|
||||
return editorscene.history.back();
|
||||
}
|
||||
void EditorComponent::ConsumeHistoryOperation(bool undo)
|
||||
@@ -5218,6 +5233,10 @@ void EditorComponent::Open(std::string filename)
|
||||
|
||||
componentsWnd.weatherWnd.UpdateData();
|
||||
componentsWnd.RefreshEntityTree();
|
||||
|
||||
GetCurrentEditorScene().has_unsaved_changes = false;
|
||||
RefreshSceneList();
|
||||
|
||||
wi::backlog::post("[Editor] finished loading model: " + filename);
|
||||
});
|
||||
});
|
||||
@@ -5282,6 +5301,7 @@ void EditorComponent::Save(const std::string& filename)
|
||||
}
|
||||
|
||||
GetCurrentEditorScene().path = filename;
|
||||
GetCurrentEditorScene().has_unsaved_changes = false;
|
||||
RefreshSceneList();
|
||||
|
||||
RegisterRecentlyUsed(filename);
|
||||
@@ -5994,28 +6014,42 @@ void EditorComponent::RefreshSceneList()
|
||||
for (int i = 0; i < int(scenes.size()); ++i)
|
||||
{
|
||||
auto& editorscene = scenes[i];
|
||||
std::string tabText;
|
||||
if (editorscene->path.empty())
|
||||
{
|
||||
if (current_localization.Get((size_t)EditorLocalization::UntitledScene))
|
||||
{
|
||||
editorscene->tabSelectButton.SetText(current_localization.Get((size_t)EditorLocalization::UntitledScene));
|
||||
tabText = current_localization.Get((size_t)EditorLocalization::UntitledScene);
|
||||
}
|
||||
else
|
||||
{
|
||||
editorscene->tabSelectButton.SetText("Untitled scene");
|
||||
tabText = "Untitled scene";
|
||||
}
|
||||
editorscene->tabSelectButton.SetTooltip("");
|
||||
}
|
||||
else
|
||||
{
|
||||
editorscene->tabSelectButton.SetText(wi::helper::GetFileNameFromPath(editorscene->path));
|
||||
tabText = wi::helper::GetFileNameFromPath(editorscene->path);
|
||||
editorscene->tabSelectButton.SetTooltip(editorscene->path);
|
||||
}
|
||||
|
||||
if (editorscene->has_unsaved_changes)
|
||||
{
|
||||
tabText = tabText + " *";
|
||||
}
|
||||
|
||||
editorscene->tabSelectButton.SetText(tabText);
|
||||
|
||||
editorscene->tabSelectButton.OnClick([this, i](wi::gui::EventArgs args) {
|
||||
SetCurrentScene(i);
|
||||
});
|
||||
editorscene->tabCloseButton.OnClick([this, i](wi::gui::EventArgs args) {
|
||||
// Check for unsaved changes before closing
|
||||
if (!CheckUnsavedChanges(i))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wi::lua::KillProcesses();
|
||||
|
||||
translator.selected.clear();
|
||||
@@ -6090,6 +6124,51 @@ void EditorComponent::NewScene()
|
||||
cameraWnd.ResetCam();
|
||||
}
|
||||
|
||||
bool EditorComponent::CheckUnsavedChanges(int scene_index)
|
||||
{
|
||||
if (scene_index < 0)
|
||||
scene_index = current_scene;
|
||||
|
||||
if (scene_index < 0 || scene_index >= (int)scenes.size())
|
||||
return true;
|
||||
|
||||
EditorScene& editorscene = *scenes[scene_index];
|
||||
if (!editorscene.has_unsaved_changes)
|
||||
return true;
|
||||
|
||||
std::string sceneName = editorscene.path.empty() ? "" : wi::helper::GetFileNameFromPath(editorscene.path);
|
||||
std::string message = sceneName.empty() ? "Do you want to save the untitled scene?" : "Do you want to save changes to \"" + sceneName + "\"?";
|
||||
wi::helper::MessageBoxResult result = wi::helper::messageBoxCustom(message, "Unsaved changes", "YesNoCancel");
|
||||
|
||||
if (result == wi::helper::MessageBoxResult::Yes)
|
||||
{
|
||||
// User wants to save
|
||||
if (editorscene.path.empty())
|
||||
{
|
||||
// Need to prompt for save location
|
||||
SaveAs();
|
||||
// After SaveAs, check if the scene was actually saved
|
||||
return !editorscene.has_unsaved_changes;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Save to existing path
|
||||
Save(editorscene.path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (result == wi::helper::MessageBoxResult::No)
|
||||
{
|
||||
// User doesn't want to save, proceed
|
||||
return true;
|
||||
}
|
||||
else // Cancel or closed dialog
|
||||
{
|
||||
// User cancelled, don't proceed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorComponent::FocusCameraOnSelected()
|
||||
{
|
||||
Scene& scene = GetCurrentScene();
|
||||
|
||||
Reference in New Issue
Block a user