Skip to content

Commit

Permalink
Game connection plugin adds a camera sync button to camera toolbar
Browse files Browse the repository at this point in the history
IMainFrame now exposes the camera toolbar via a new Toolbar::CAMERA enum value,
which is used by the GameConnection plugin to add a toolbar button to enable
camera sync. For now the button is just using the sr_icon_communication icon
since it looks somewhat related.
  • Loading branch information
Matthew Mott committed Jan 6, 2021
1 parent 0aefd97 commit eb1b152
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 19 deletions.
31 changes: 18 additions & 13 deletions include/imainframe.h
Expand Up @@ -18,7 +18,7 @@ class IScopedScreenUpdateBlocker
public:
virtual ~IScopedScreenUpdateBlocker() {}

// For operations without calculatable duration, call pulse() regularly to
// For operations without calculatable duration, call pulse() regularly to
// provide some visual feedback
virtual void pulse() = 0;

Expand Down Expand Up @@ -72,7 +72,10 @@ class IMainFrame :
TOP,

/// Left vertical toolbar, containing various edit options
LEFT
LEFT,

/// Toolbar above the 3D camera view
CAMERA
};

/// Obtain a pointer to an application toolbar
Expand Down Expand Up @@ -104,28 +107,30 @@ class IMainFrame :
*
* Pass the title and the message to display in the small modal window.
*/
virtual IScopedScreenUpdateBlockerPtr getScopedScreenUpdateBlocker(const std::string& title,
virtual IScopedScreenUpdateBlockerPtr getScopedScreenUpdateBlocker(const std::string& title,
const std::string& message, bool forceDisplay = false) = 0;

/**
* A signal emitted when the MainFrame window has been set up. Modules can
* subscribe to this to register any UI parts that require a valid main window
* or sub component like the group dialog to be constructed.
* This is a one-time signal, after emission the subscribers will be
* automatically removed by this class.
*/
virtual sigc::signal<void>& signal_MainFrameConstructed() = 0;
/**
* \brief
* A signal emitted when the MainFrame window has been set up.
*
* Modules can subscribe to this to register any UI parts that require a
* valid main window or sub component like the group dialog to be
* constructed. This is a one-time signal, after emission the subscribers
* will be automatically removed by this class.
*/
virtual sigc::signal<void>& signal_MainFrameConstructed() = 0;

/**
* Signal fired after the MainFrame window is shown the first time
* during application start up.
* This is a one-time signal, after emission the subscribers will be
* This is a one-time signal, after emission the subscribers will be
* automatically removed by this class.
*/
virtual sigc::signal<void>& signal_MainFrameReady() = 0;

/**
* Signal fired when the UI is shutting down, right before the MainFrame
* Signal fired when the UI is shutting down, right before the MainFrame
* window will be destroyed. Dependant UI modules can listen to this
* event to get a chance to clean up and save their state.
* This is a one-time signal, after emission the subscribers will be
Expand Down
34 changes: 30 additions & 4 deletions plugins/dm.gameconnection/GameConnection.cpp
Expand Up @@ -12,11 +12,14 @@
#include "iuimanager.h"
#include "ieventmanager.h"
#include "idialogmanager.h"
#include "imainframe.h"

#include "scene/Traverse.h"

#include <sigc++/signal.h>
#include <sigc++/connection.h>
#include <wx/toolbar.h>
#include <wx/artprov.h>

namespace gameconn
{
Expand Down Expand Up @@ -224,16 +227,17 @@ const std::string& GameConnection::getName() const
const StringSet& GameConnection::getDependencies() const
{
static StringSet _dependencies {
MODULE_CAMERA_MANAGER, MODULE_COMMANDSYSTEM, MODULE_MAP, MODULE_SCENEGRAPH,
MODULE_SELECTIONSYSTEM, MODULE_EVENTMANAGER, MODULE_UIMANAGER
MODULE_CAMERA_MANAGER, MODULE_COMMANDSYSTEM, MODULE_MAP,
MODULE_SCENEGRAPH, MODULE_SELECTIONSYSTEM, MODULE_EVENTMANAGER,
MODULE_UIMANAGER, MODULE_MAINFRAME
};
return _dependencies;
}

void GameConnection::initialiseModule(const IApplicationContext& ctx)
{
// Construct toggles
GlobalEventManager().addAdvancedToggle(
_camSyncToggle = GlobalEventManager().addAdvancedToggle(
"GameConnectionToggleCameraSync",
[this](bool v) { return setCameraSyncEnabled(v); }
);
Expand Down Expand Up @@ -284,14 +288,36 @@ void GameConnection::initialiseModule(const IApplicationContext& ctx)
_("Pause game"), "", "GameConnectionPauseGame");
mm.add("main/connection", "respawnSelected", ui::menuItem,
_("Respawn selected entities"), "", "GameConnectionRespawnSelected");

// Toolbar button(s)
GlobalMainFrame().signal_MainFrameConstructed().connect(
sigc::mem_fun(this, &GameConnection::addToolbarItems)
);
}

void GameConnection::shutdownModule()
{
disconnect(true);
}

//-------------------------------------------------------------
void GameConnection::addToolbarItems()
{
wxToolBar* camTB = GlobalMainFrame().getToolbar(IMainFrame::Toolbar::CAMERA);
if (camTB)
{
// Separate GameConnection tools from regular camera tools
camTB->AddSeparator();

// Add a toggle for the camera sync function
auto tool = camTB->AddTool(
wxID_ANY, "L",
wxArtProvider::GetBitmap(GlobalUIManager().ArtIdPrefix() + "sr_icon_communication.png"),
_("Enable game camera sync with DarkRadiant camera")
);
_camSyncToggle->connectToolItem(tool);
camTB->Realize();
}
}

std::string GameConnection::composeConExecRequest(std::string consoleLine) {
//remove trailing spaces/EOLs
Expand Down
9 changes: 9 additions & 0 deletions plugins/dm.gameconnection/GameConnection.h
Expand Up @@ -2,6 +2,8 @@

#include "icommandsystem.h"
#include "iscenegraph.h"
#include "ieventmanager.h"

#include "MapObserver.h"

#include <sigc++/connection.h>
Expand Down Expand Up @@ -86,6 +88,13 @@ class GameConnection :
void shutdownModule() override;

private:

// Add any required items to the application toolbars
void addToolbarItems();

// IEventPtrs corresponding to activatable menu options
IEventPtr _camSyncToggle;

//connection to TDM game (i.e. the socket with custom message framing)
//it can be "dead" in two ways:
// _connection is NULL --- no connection, all modes/observers disabled
Expand Down
4 changes: 3 additions & 1 deletion radiant/camera/CamWnd.h
Expand Up @@ -113,7 +113,9 @@ class CamWnd :
// The unique ID of this camwindow
int getId();

// ICameraView implementation
/// Return the camera toolbar
wxToolBar* getToolbar() { return _camToolbar; }

SelectionTestPtr createSelectionTestForPoint(const Vector2& point) override;
const VolumeTest& getVolumeTest() const override;
int getDeviceWidth() const override;
Expand Down
11 changes: 10 additions & 1 deletion radiant/ui/mainframe/MainFrame.cpp
Expand Up @@ -431,7 +431,16 @@ void MainFrame::restoreWindowPosition()

wxToolBar* MainFrame::getToolbar(IMainFrame::Toolbar type)
{
return _topLevelWindow->getToolbar(type);
// Pass any request for the camera view toolbar to the active CamWnd, if
// any
if (type == Toolbar::CAMERA)
{
CamWndPtr cw = GlobalCamera().getActiveCamWnd();
return cw ? cw->getToolbar() : nullptr;
}

// Main window toolbar
return _topLevelWindow->getToolbar(type);
}

void MainFrame::create()
Expand Down

0 comments on commit eb1b152

Please sign in to comment.