Skip to content

Commit

Permalink
#5623: Add IMap::signal_editModeChanged to get notified on edit mode …
Browse files Browse the repository at this point in the history
…changes. The MergeControlDialog needs to monitor that mode and adjust its UI state.
  • Loading branch information
codereader committed Jun 6, 2021
1 parent 521f972 commit f1e1b30
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 34 deletions.
7 changes: 7 additions & 0 deletions include/imap.h
Expand Up @@ -125,6 +125,9 @@ class IMap :
// Change the edit mode to the specified value
virtual void setEditMode(EditMode mode) = 0;

// Signal fired when the map edit mode has been changed
virtual sigc::signal<void, EditMode>& signal_editModeChanged() = 0;

/**
* Returns the worldspawn node of this map. The worldspawn
* node is NOT created if it doesn't exist yet, so this
Expand Down Expand Up @@ -185,6 +188,10 @@ class IMap :
// Exports the current selection to the given output stream, using the given map format
virtual void exportSelected(std::ostream& out, const map::MapFormatPtr& format) = 0;

// Starts a merge operation which imports differences from the given sourceMap into this one
// Will throw exceptions when the given map cannot be found, or this map doesn't have a root
virtual void startMergeOperation(const std::string& sourceMap) = 0;

// When called in EditMode::Merge, this will apply the currently active set of actions
virtual void finishMergeOperation() = 0;

Expand Down
15 changes: 15 additions & 0 deletions radiant/ui/merge/MergeControlDialog.cpp
Expand Up @@ -127,13 +127,16 @@ void MergeControlDialog::onMergeSourceChanged(wxCommandEvent& ev)
void MergeControlDialog::onLoadAndCompare(wxCommandEvent& ev)
{
auto sourceMapPath = findNamedObject<wxutil::PathEntry>(this, "MergeMapFilename")->getValue();
#if false
auto baseMapPath = findNamedObject<wxutil::PathEntry>(this, "BaseMapFilename")->getValue();
#endif

if (sourceMapPath.empty())
{
return;
}

#if false
if (!baseMapPath.empty())
{
GlobalCommandSystem().executeCommand("StartMergeOperation", sourceMapPath, baseMapPath);
Expand All @@ -142,6 +145,8 @@ void MergeControlDialog::onLoadAndCompare(wxCommandEvent& ev)
{
GlobalCommandSystem().executeCommand("StartMergeOperation", sourceMapPath);
}
#endif
GlobalMapModule().startMergeOperation(sourceMapPath);

updateSummary();
updateControlSensitivity();
Expand Down Expand Up @@ -234,6 +239,7 @@ void MergeControlDialog::_preHide()
_undoHandler.disconnect();
_redoHandler.disconnect();
_mapEventHandler.disconnect();
_mapEditModeHandler.disconnect();

GlobalSelectionSystem().removeObserver(this);
}
Expand All @@ -251,6 +257,9 @@ void MergeControlDialog::_preShow()
_mapEventHandler = GlobalMapModule().signal_mapEvent().connect(
sigc::mem_fun(this, &MergeControlDialog::onMapEvent)
);
_mapEditModeHandler = GlobalMapModule().signal_editModeChanged().connect(
sigc::mem_fun(this, &MergeControlDialog::onMapEditModeChanged)
);

_undoHandler = GlobalUndoSystem().signal_postUndo().connect(
sigc::mem_fun(this, &MergeControlDialog::queueUpdate));
Expand Down Expand Up @@ -294,6 +303,12 @@ void MergeControlDialog::onMapEvent(IMap::MapEvent ev)
}
}

void MergeControlDialog::onMapEditModeChanged(IMap::EditMode newMode)
{
updateSummary();
updateControlSensitivity();
}

void MergeControlDialog::updateSummary()
{
auto operation = GlobalMapModule().getActiveMergeOperation();
Expand Down
2 changes: 2 additions & 0 deletions radiant/ui/merge/MergeControlDialog.h
Expand Up @@ -21,6 +21,7 @@ class MergeControlDialog :
sigc::connection _undoHandler;
sigc::connection _redoHandler;
sigc::connection _mapEventHandler;
sigc::connection _mapEditModeHandler;

bool _updateNeeded;

Expand Down Expand Up @@ -56,6 +57,7 @@ class MergeControlDialog :
void queueUpdate();
void onIdle(wxIdleEvent& ev);
void onMapEvent(IMap::MapEvent ev);
void onMapEditModeChanged(IMap::EditMode newMode);
void updateSummary();

std::size_t getNumSelectedMergeNodes();
Expand Down
101 changes: 68 additions & 33 deletions radiantcore/map/Map.cpp
Expand Up @@ -359,9 +359,15 @@ void Map::setEditMode(EditMode mode)
GlobalSelectionSystem().SetMode(SelectionSystem::ePrimitive);
}

signal_editModeChanged().emit(_editMode);
SceneChangeNotify();
}

sigc::signal<void, IMap::EditMode>& Map::signal_editModeChanged()
{
return _mapEditModeChangedSignal;
}

const scene::INodePtr& Map::getWorldspawn()
{
return _worldSpawnNode;
Expand Down Expand Up @@ -864,8 +870,10 @@ void Map::registerCommands()
GlobalCommandSystem().addCommand("OpenMap", Map::openMap, { cmd::ARGTYPE_STRING | cmd::ARGTYPE_OPTIONAL });
GlobalCommandSystem().addCommand("OpenMapFromArchive", Map::openMapFromArchive, { cmd::ARGTYPE_STRING, cmd::ARGTYPE_STRING });
GlobalCommandSystem().addCommand("ImportMap", Map::importMap);
GlobalCommandSystem().addCommand("StartMergeOperation", std::bind(&Map::startMergeOperation, this, std::placeholders::_1),
GlobalCommandSystem().addCommand("StartMergeOperation", std::bind(&Map::startMergeOperationCmd, this, std::placeholders::_1),
{ cmd::ARGTYPE_STRING | cmd::ARGTYPE_OPTIONAL, cmd::ARGTYPE_STRING | cmd::ARGTYPE_OPTIONAL });
GlobalCommandSystem().addCommand("AbortMergeOperation", std::bind(&Map::abortMergeOperationCmd, this, std::placeholders::_1));
GlobalCommandSystem().addCommand("FinishMergeOperation", std::bind(&Map::finishMergeOperationCmd, this, std::placeholders::_1));
GlobalCommandSystem().addCommand(LOAD_PREFAB_AT_CMD, std::bind(&Map::loadPrefabAt, this, std::placeholders::_1),
{ cmd::ARGTYPE_STRING, cmd::ARGTYPE_VECTOR3, cmd::ARGTYPE_INT|cmd::ARGTYPE_OPTIONAL, cmd::ARGTYPE_INT | cmd::ARGTYPE_OPTIONAL });
GlobalCommandSystem().addCommand("SaveSelectedAsPrefab", Map::saveSelectedAsPrefab);
Expand Down Expand Up @@ -1121,7 +1129,55 @@ void Map::createMergeOperation(const scene::merge::ComparisonResult& result)
}
}

void Map::startMergeOperation(const cmd::ArgumentList& args)
void Map::startMergeOperation(const std::string& sourceMap)
{
if (!getRoot())
{
throw cmd::ExecutionNotPossible(_("No map loaded, cannot merge"));
}

if (!os::fileOrDirExists(sourceMap))
{
throw cmd::ExecutionFailure(fmt::format(_("File doesn't exist: {0}"), sourceMap));
}

{
// Make sure we have a worldspawn in this map
UndoableCommand cmd("ensureWorldSpawn");
findOrInsertWorldspawn();
}

// Stop any pending merge operation
abortMergeOperation();

auto sourceMapResource = GlobalMapResourceManager().createFromPath(sourceMap);

try
{
if (sourceMapResource->load())
{
const auto& otherRoot = sourceMapResource->getRootNode();

// Compare the scenes and get the report
auto result = scene::merge::GraphComparer::Compare(otherRoot, getRoot());

// Create renderable merge actions
createMergeOperation(*result);

// Switch to merge mode
setEditMode(EditMode::Merge);

// Dispose of the resource, we don't need it anymore
sourceMapResource->clear();
}
}
catch (const IMapResource::OperationException& ex)
{
radiant::NotificationMessage::SendError(ex.what());
}
}

void Map::startMergeOperationCmd(const cmd::ArgumentList& args)
{
if (!getRoot())
{
Expand Down Expand Up @@ -1153,6 +1209,7 @@ void Map::startMergeOperation(const cmd::ArgumentList& args)
throw cmd::ExecutionFailure(fmt::format(_("File doesn't exist: {0}"), sourceCandidate));
}

#if false // base map handling not yet implemented
// Do we have a second argument (base map)
if (args.size() > 1)
{
Expand All @@ -1163,41 +1220,19 @@ void Map::startMergeOperation(const cmd::ArgumentList& args)
throw cmd::ExecutionFailure(fmt::format(_("File doesn't exist: {0}"), baseCandidate));
}
}
#endif

{
// Make sure we have a worldspawn in this map
UndoableCommand cmd("ensureWorldSpawn");
findOrInsertWorldspawn();
}
startMergeOperation(sourceCandidate);
}

// Stop any pending merge operation
void Map::abortMergeOperationCmd(const cmd::ArgumentList& args)
{
abortMergeOperation();
}

auto sourceMapResource = GlobalMapResourceManager().createFromPath(sourceCandidate);

try
{
if (sourceMapResource->load())
{
const auto& otherRoot = sourceMapResource->getRootNode();

// Compare the scenes and get the report
auto result = scene::merge::GraphComparer::Compare(otherRoot, getRoot());

// Create renderable merge actions
createMergeOperation(*result);

// Switch to merge mode
setEditMode(EditMode::Merge);

// Dispose of the resource, we don't need it anymore
sourceMapResource->clear();
}
}
catch (const IMapResource::OperationException& ex)
{
radiant::NotificationMessage::SendError(ex.what());
}
void Map::finishMergeOperationCmd(const cmd::ArgumentList& args)
{
finishMergeOperation();
}

void Map::emitMapEvent(MapEvent ev)
Expand Down
8 changes: 7 additions & 1 deletion radiantcore/map/Map.h
Expand Up @@ -45,6 +45,7 @@ class Map :

sigc::signal<void> _mapNameChangedSignal;
sigc::signal<void> _mapModifiedChangedSignal;
sigc::signal<void, EditMode> _mapEditModeChangedSignal;

// Pointer to the resource for this map
IMapResourcePtr _resource;
Expand Down Expand Up @@ -84,6 +85,8 @@ class Map :
EditMode getEditMode() override;
void setEditMode(EditMode mode) override;

sigc::signal<void, EditMode>& signal_editModeChanged() override;

const scene::INodePtr& getWorldspawn() override;
const scene::INodePtr& findOrInsertWorldspawn() override;
scene::IMapRootNodePtr getRoot() override;
Expand Down Expand Up @@ -166,6 +169,7 @@ class Map :
void exportSelected(std::ostream& out) override;
void exportSelected(std::ostream& out, const MapFormatPtr& format) override;

void startMergeOperation(const std::string& sourceMap) override;
void finishMergeOperation() override;
void abortMergeOperation() override;
scene::merge::IMergeOperation::Ptr getActiveMergeOperation() override;
Expand Down Expand Up @@ -259,7 +263,9 @@ class Map :
void loadMapResourceFromPath(const std::string& path);
void loadMapResourceFromArchive(const std::string& archive, const std::string& archiveRelativePath);

void startMergeOperation(const cmd::ArgumentList& args);
void startMergeOperationCmd(const cmd::ArgumentList& args);
void abortMergeOperationCmd(const cmd::ArgumentList& args);
void finishMergeOperationCmd(const cmd::ArgumentList& args);
void createMergeOperation(const scene::merge::ComparisonResult& result);

void emitMapEvent(MapEvent ev);
Expand Down

0 comments on commit f1e1b30

Please sign in to comment.