Skip to content

Commit

Permalink
Added option to save level under a different name (#1881)
Browse files Browse the repository at this point in the history
* Added option to save level under a different name

* Removed needless captures

Co-authored-by: Semphris <semphris@protonmail.com>
  • Loading branch information
Semphriss and Semphris committed Nov 11, 2021
1 parent d4b9be0 commit 7fbeeda
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 10 deletions.
16 changes: 12 additions & 4 deletions src/editor/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ Editor::Editor() :
m_reactivate_request(false),
m_deactivate_request(false),
m_save_request(false),
m_save_request_filename(""),
m_save_request_switch(false),
m_test_request(false),
m_particle_editor_request(false),
m_test_pos(),
Expand Down Expand Up @@ -207,9 +209,11 @@ Editor::update(float dt_sec, const Controller& controller)
}

if (m_save_request) {
save_level();
save_level(m_save_request_filename, m_save_request_switch);
m_enabled = true;
m_save_request = false;
m_save_request_filename = "";
m_save_request_switch = false;
}

if (m_test_request) {
Expand Down Expand Up @@ -272,11 +276,15 @@ Editor::remove_autosave_file()
}

void
Editor::save_level()
Editor::save_level(const std::string& filename, bool switch_file)
{
auto file = !filename.empty() ? filename : m_levelfile;

if (switch_file)
m_levelfile = filename;

m_undo_manager->reset_index();
m_level->save(m_world ? FileSystem::join(m_world->get_basedir(), m_levelfile) :
m_levelfile);
m_level->save(m_world ? FileSystem::join(m_world->get_basedir(), file) : file);
m_time_since_last_save = 0.f;
remove_autosave_file();
}
Expand Down
10 changes: 9 additions & 1 deletion src/editor/editor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,13 @@ class Editor final : public Screen,
void set_level(std::unique_ptr<Level> level, bool reset = true);
void reload_level();
void quit_editor();
void save_level();
/**
* @param filename If non-empty, save to this file instead.
* @param switch_file If true, the level editor will bind itself to the new
* filename; subsequest saves will by default save to the
* new filename.
*/
void save_level(const std::string& filename = "", bool switch_file = false);
void test_level(const boost::optional<std::pair<std::string, Vector>>& test_pos);
void update_keyboard(const Controller& controller);

Expand All @@ -170,6 +176,8 @@ class Editor final : public Screen,
bool m_reactivate_request;
bool m_deactivate_request;
bool m_save_request;
std::string m_save_request_filename;
bool m_save_request_switch;
bool m_test_request;
bool m_particle_editor_request;
boost::optional<std::pair<std::string, Vector>> m_test_pos;
Expand Down
33 changes: 29 additions & 4 deletions src/supertux/menu/editor_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "supertux/level.hpp"
#include "supertux/gameconfig.hpp"
#include "supertux/globals.hpp"
#include "supertux/menu/editor_save_as.hpp"
#include "supertux/menu/menu_storage.hpp"
#include "util/gettext.hpp"
#include "video/compositor.hpp"
Expand All @@ -41,8 +42,14 @@ EditorMenu::EditorMenu()
add_hl();
add_entry(MNID_RETURNTOEDITOR, _("Return to Editor"));
add_entry(MNID_SAVELEVEL, worldmap ? _("Save Worldmap") : _("Save Level"));
if (!worldmap)
{
add_entry(MNID_SAVEASLEVEL, _("Save Level as"));
add_entry(MNID_SAVECOPYLEVEL, _("Save Copy"));
}

if (!worldmap) {
if (!worldmap)
{
add_entry(MNID_TESTLEVEL, _("Test Level"));
}
else
Expand All @@ -54,7 +61,8 @@ EditorMenu::EditorMenu()

add_entry(MNID_OPEN_DIR, _("Open Level Directory"));

if (is_world) {
if (is_world)
{
add_entry(MNID_LEVELSEL, _("Edit Another Level"));
}

Expand Down Expand Up @@ -82,9 +90,10 @@ EditorMenu::EditorMenu()
EditorMenu::~EditorMenu()
{
auto editor = Editor::current();
if (editor == nullptr) {

if (editor == nullptr)
return;
}

editor->m_reactivate_request = true;
}

Expand All @@ -107,6 +116,22 @@ EditorMenu::menu_action(MenuItem& item)
}
break;

case MNID_SAVEASLEVEL:
{
editor->check_save_prerequisites([] {
MenuManager::instance().set_menu(std::make_unique<EditorSaveAs>(true));
});
}
break;

case MNID_SAVECOPYLEVEL:
{
editor->check_save_prerequisites([] {
MenuManager::instance().set_menu(std::make_unique<EditorSaveAs>(false));
});
}
break;

case MNID_OPEN_DIR:
Editor::current()->open_level_directory();
break;
Expand Down
4 changes: 3 additions & 1 deletion src/supertux/menu/editor_menu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ class EditorMenu final : public Menu
enum MenuIDs {
MNID_RETURNTOEDITOR,
MNID_SAVELEVEL,
MNID_SAVEASLEVEL,
MNID_SAVECOPYLEVEL,
MNID_TESTLEVEL,
MNID_OPEN_DIR,
MNID_SHARE,
MNID_LEVELSEL,
MNID_LEVELSETSEL,
MNID_HELP,
MNID_HELP,
MNID_QUITEDITOR
};

Expand Down
77 changes: 77 additions & 0 deletions src/supertux/menu/editor_save_as.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// SuperTux
// Copyright (C) 2020 A. Semphris <semphris@protonmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include "supertux/menu/editor_save_as.hpp"

#include "editor/editor.hpp"
#include "gui/dialog.hpp"
#include "gui/menu_item.hpp"
#include "gui/menu_manager.hpp"
#include "supertux/level.hpp"
#include "supertux/gameconfig.hpp"
#include "supertux/menu/menu_storage.hpp"
#include "util/gettext.hpp"
#include "video/compositor.hpp"

EditorSaveAs::EditorSaveAs(bool do_switch_file) :
m_filename(Editor::current()->get_levelfile()),
m_do_switch_file(do_switch_file)
{
add_label(do_switch_file ? _("Save Level as") : _("Save Copy"));

add_hl();

add_textfield(_("File name"), &m_filename);
add_entry(MNID_SAVE, _("Save"));

add_hl();

add_entry(MNID_CANCEL, _("Cancel"));
}

EditorSaveAs::~EditorSaveAs()
{
auto editor = Editor::current();
if (editor == nullptr) {
return;
}
editor->m_reactivate_request = true;
}

void
EditorSaveAs::menu_action(MenuItem& item)
{
auto editor = Editor::current();

switch (item.get_id())
{
case MNID_SAVE:
editor->m_save_request = true;
editor->m_save_request_filename = m_filename;
editor->m_save_request_switch = m_do_switch_file;
MenuManager::instance().clear_menu_stack();
break;

case MNID_CANCEL:
MenuManager::instance().clear_menu_stack();
break;

default:
break;
}
}

/* EOF */
47 changes: 47 additions & 0 deletions src/supertux/menu/editor_save_as.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SuperTux
// Copyright (C) 2020 A. Semphris <semphris@protonmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#ifndef HEADER_SUPERTUX_SUPERTUX_MENU_EDITOR_SAVE_AS_HPP
#define HEADER_SUPERTUX_SUPERTUX_MENU_EDITOR_SAVE_AS_HPP

#include "gui/menu.hpp"

class EditorSaveAs final : public Menu
{
private:
enum MenuIDs {
MNID_SAVE,
MNID_CANCEL
};

public:
EditorSaveAs(bool do_switch_file);
~EditorSaveAs() override;

void menu_action(MenuItem& item) override;

private:
std::string m_filename;
bool m_do_switch_file;

private:
EditorSaveAs(const EditorSaveAs&) = delete;
EditorSaveAs& operator=(const EditorSaveAs&) = delete;
};

#endif

/* EOF */
6 changes: 6 additions & 0 deletions src/supertux/menu/particle_editor_save_as.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ ParticleEditorSaveAs::menu_action(MenuItem& item)
// In this very case, if you clear the dialog stack before calling the
// callback, the callback will lose its reference to the Particle Editor,
// which will cause a segfault. Somehow. Somebody explain me. ~Semphris
// -----------------------------------------------------------------------
// EDIT: It's because the menu stack is a vector of *unique pointers*, so
// when the stack is cleared, so is the menu (`this`), and so is the
// callback; so the callback becomes a dangling pointer and calling it is
// undefined behavior. Leaving this here for maintainers. ~Semphris

m_callback(true);
MenuManager::instance().clear_menu_stack();
break;
Expand Down

0 comments on commit 7fbeeda

Please sign in to comment.