Skip to content

Commit

Permalink
#6131: Refactor MediaBrowser to be compatible with the IUserControl i…
Browse files Browse the repository at this point in the history
…nterfaces

Separate module implementation from the control. Remove the imediabrowser.h interface
that is no longer needed, it's been replaced by a MessageBus request.
  • Loading branch information
codereader committed Oct 15, 2022
1 parent fc403bc commit 9ed1396
Show file tree
Hide file tree
Showing 13 changed files with 205 additions and 230 deletions.
1 change: 1 addition & 0 deletions include/imessagebus.h
Expand Up @@ -57,6 +57,7 @@ class IMessage
ManipulatorModeToggleRequest,
ComponentSelectionModeToggleRequest,
GridSnapRequest,
FocusMaterialRequest,

UserDefinedMessagesGoHigherThanThis = 999,
};
Expand Down
52 changes: 0 additions & 52 deletions include/ui/imediabrowser.h

This file was deleted.

1 change: 1 addition & 0 deletions include/ui/iusercontrol.h
Expand Up @@ -41,6 +41,7 @@ struct UserControl
constexpr static const char* Camera = "Camera";
constexpr static const char* Console = "Console";
constexpr static const char* EntityInspector = "EntityInspector";
constexpr static const char* MediaBrowser = "MediaBrowser";
constexpr static const char* OrthoView = "OrthoView";
constexpr static const char* TextureBrowser = "TextureBrowser";
};
Expand Down
1 change: 1 addition & 0 deletions radiant/ui/mainframe/MainFrame.cpp
Expand Up @@ -479,6 +479,7 @@ void MainFrame::create()

GlobalGroupDialog().addControl(UserControl::Console);
GlobalGroupDialog().addControl(UserControl::EntityInspector);
GlobalGroupDialog().addControl(UserControl::MediaBrowser);

// Load the previous window settings from the registry
restoreWindowPosition();
Expand Down
40 changes: 40 additions & 0 deletions radiant/ui/mediabrowser/FocusMaterialRequest.h
@@ -0,0 +1,40 @@
#pragma once

#include "imessagebus.h"
#include "iradiant.h"

namespace ui
{

/**
* Request to focus a specific material in the MediaBrowser
*/
class FocusMaterialRequest :
public radiant::IMessage
{
private:
std::string _requestedMaterial;
public:
FocusMaterialRequest(const std::string& material) :
_requestedMaterial(material)
{}

std::size_t getId() const override
{
return Type::FocusMaterialRequest;
}

const std::string& getRequestedMaterial() const
{
return _requestedMaterial;
}

// Convenience method
static void Send(const std::string& material)
{
FocusMaterialRequest msg(material);
GlobalRadiantCore().getMessageBus().sendMessage(msg);
}
};

}
187 changes: 53 additions & 134 deletions radiant/ui/mediabrowser/MediaBrowser.cpp
@@ -1,85 +1,92 @@
#include "MediaBrowser.h"

#include "i18n.h"
#include "ui/imainframe.h"
#include "ideclmanager.h"
#include "imap.h"
#include "ui/igroupdialog.h"
#include "ipreferencesystem.h"
#include "ishaders.h"
#include "ishaderclipboard.h"
#include "ifavourites.h"
#include "ui/iuserinterface.h"

#include "wxutil/MultiMonitor.h"
#include "wxutil/dataview/ResourceTreeViewToolbar.h"

#include <wx/sizer.h>
#include <wx/radiobut.h>
#include <wx/frame.h>

#include <iostream>
#include <map>

#include "registry/registry.h"
#include "string/string.h"
#include "util/ScopedBoolLock.h"
#include "ui/texturebrowser/TextureBrowser.h"
#include "ui/common/TexturePreviewCombo.h"

#include "debugging/ScopedDebugTimer.h"
#include "module/StaticModule.h"

#include <functional>
#include "string/predicate.h"
#include "FocusMaterialRequest.h"
#include "ui/UserInterfaceModule.h"

namespace ui
{

// Constructor
MediaBrowser::MediaBrowser() :
_tempParent(nullptr),
_mainWidget(nullptr),
MediaBrowser::MediaBrowser(wxWindow* parent) :
wxPanel(parent),
_treeView(nullptr),
_preview(nullptr),
_blockShaderClipboardUpdates(false)
{}

void MediaBrowser::construct()
{
if (_mainWidget != nullptr)
{
return;
}
construct();

// Attach to the DeclarationManager to get notified on unrealise/realise
// events, in which case we're reloading the media tree
_materialDefsLoaded = GlobalDeclarationManager().signal_DeclsReloaded(decl::Type::Material)
.connect(sigc::mem_fun(*this, &MediaBrowser::onMaterialDefsLoaded));

_materialDefsUnloaded = GlobalDeclarationManager().signal_DeclsReloading(decl::Type::Material)
.connect(sigc::mem_fun(*this, &MediaBrowser::onMaterialDefsUnloaded));

_shaderClipboardConn = GlobalShaderClipboard().signal_sourceChanged().connect(
sigc::mem_fun(this, &MediaBrowser::onShaderClipboardSourceChanged)
);

// The tree view will be re-populated once the first map loaded signal is fired
_mapLoadedConn = GlobalMapModule().signal_mapEvent().connect(
sigc::mem_fun(this, &MediaBrowser::onMapEvent)
);

_tempParent = new wxFrame(nullptr, wxID_ANY, "");
_tempParent->Hide();
_focusMaterialHandler = GlobalRadiantCore().getMessageBus().addListener(
radiant::IMessage::Type::FocusMaterialRequest,
radiant::TypeListener<ui::FocusMaterialRequest>(
sigc::mem_fun(this, &MediaBrowser::focusMaterial)));

_treeView->Populate();
}

MediaBrowser::~MediaBrowser()
{
GlobalRadiantCore().getMessageBus().removeListener(_focusMaterialHandler);
_mapLoadedConn.disconnect();
_shaderClipboardConn.disconnect();
_materialDefsLoaded.disconnect();
_materialDefsUnloaded.disconnect();
}

_mainWidget = new wxPanel(_tempParent, wxID_ANY);
_mainWidget->SetSizer(new wxBoxSizer(wxVERTICAL));
void MediaBrowser::construct()
{
SetSizer(new wxBoxSizer(wxVERTICAL));

_treeView = new MediaBrowserTreeView(_mainWidget);
auto* toolbar = new wxutil::ResourceTreeViewToolbar(_mainWidget, _treeView);
_treeView = new MediaBrowserTreeView(this);
auto* toolbar = new wxutil::ResourceTreeViewToolbar(this, _treeView);

_mainWidget->GetSizer()->Add(toolbar, 0, wxALIGN_LEFT | wxEXPAND | wxALL, 6);
_mainWidget->GetSizer()->Add(_treeView, 1, wxEXPAND);
GetSizer()->Add(toolbar, 0, wxALIGN_LEFT | wxEXPAND | wxALL, 6);
GetSizer()->Add(_treeView, 1, wxEXPAND);

// Connect up the selection changed callback
_treeView->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &MediaBrowser::_onTreeViewSelectionChanged, this);

// Add the info pane
_preview = new TexturePreviewCombo(_mainWidget);
_mainWidget->GetSizer()->Add(_preview, 0, wxEXPAND);
_preview = new TexturePreviewCombo(this);
GetSizer()->Add(_preview, 0, wxEXPAND);

// When destroying the main widget clear out the held references.
// The dying populator thread might have posted a finished message which
// runs into problems when the _treeView is still valid
_mainWidget->Bind(wxEVT_DESTROY, [&](wxWindowDestroyEvent& ev)
Bind(wxEVT_DESTROY, [&](wxWindowDestroyEvent& ev)
{
// In wxGTK the destroy event might bubble from a child window
// like the search popup, so check the event object
if (ev.GetEventObject() == _mainWidget)
if (ev.GetEventObject() == this)
{
_treeView = nullptr;
_shaderClipboardConn.disconnect();
Expand All @@ -90,27 +97,6 @@ void MediaBrowser::construct()
});
}

void MediaBrowser::onMainFrameConstructed()
{
// Add the Media Browser page
IGroupDialog::PagePtr mediaBrowserPage(new IGroupDialog::Page);

mediaBrowserPage->name = getGroupDialogTabName();
mediaBrowserPage->windowLabel = _("Media");
mediaBrowserPage->page = _mainWidget;
mediaBrowserPage->tabIcon = "folder16.png";
mediaBrowserPage->tabLabel = _("Media");
mediaBrowserPage->position = IGroupDialog::Page::Position::MediaBrowser;

GlobalGroupDialog().addPage(mediaBrowserPage);

if (_tempParent != nullptr)
{
_tempParent->Destroy();
_tempParent = nullptr;
}
}

void MediaBrowser::onMapEvent(IMap::MapEvent ev)
{
// Re-populate the tree after a map has been loaded, this way
Expand All @@ -127,7 +113,6 @@ std::string MediaBrowser::getSelection()
return _treeView->GetSelectedDeclName();
}

// Set the selection in the treeview
void MediaBrowser::setSelection(const std::string& selection)
{
_treeView->SetSelectedDeclName(selection);
Expand Down Expand Up @@ -161,75 +146,6 @@ void MediaBrowser::_onTreeViewSelectionChanged(wxDataViewEvent& ev)
}
}

void MediaBrowser::togglePage(const cmd::ArgumentList& args)
{
GlobalGroupDialog().togglePage(getGroupDialogTabName());
}

const std::string& MediaBrowser::getName() const
{
static std::string _name("MediaBrowser");
return _name;
}

const StringSet& MediaBrowser::getDependencies() const
{
static StringSet _dependencies
{
MODULE_COMMANDSYSTEM,
MODULE_SHADERSYSTEM,
MODULE_GROUPDIALOG,
MODULE_SHADERCLIPBOARD,
MODULE_MAINFRAME,
MODULE_FAVOURITES_MANAGER,
MODULE_MAP,
MODULE_USERINTERFACE,
};

return _dependencies;
}

void MediaBrowser::initialiseModule(const IApplicationContext& ctx)
{
GlobalCommandSystem().addCommand("ToggleMediaBrowser", sigc::mem_fun(this, &MediaBrowser::togglePage));

// We need to create the liststore and widgets before attaching ourselves
// to the material manager as observer, as the attach() call below
// will invoke a realise() callback, which triggers a population
construct();

// The startup event will add this page to the group dialog tab
GlobalMainFrame().signal_MainFrameConstructed().connect(
sigc::mem_fun(*this, &MediaBrowser::onMainFrameConstructed)
);

// Attach to the DeclarationManager to get notified on unrealise/realise
// events, in which case we're reloading the media tree
_materialDefsLoaded = GlobalDeclarationManager().signal_DeclsReloaded(decl::Type::Material)
.connect(sigc::mem_fun(*this, &MediaBrowser::onMaterialDefsLoaded));

_materialDefsUnloaded = GlobalDeclarationManager().signal_DeclsReloading(decl::Type::Material)
.connect(sigc::mem_fun(*this, &MediaBrowser::onMaterialDefsUnloaded));

_shaderClipboardConn = GlobalShaderClipboard().signal_sourceChanged().connect(
sigc::mem_fun(this, &MediaBrowser::onShaderClipboardSourceChanged)
);

_mapLoadedConn = GlobalMapModule().signal_mapEvent().connect(
sigc::mem_fun(this, &MediaBrowser::onMapEvent)
);

// The tree view will be populated once the first map loaded signal is fired
}

void MediaBrowser::shutdownModule()
{
_mapLoadedConn.disconnect();
_shaderClipboardConn.disconnect();
_materialDefsLoaded.disconnect();
_materialDefsUnloaded.disconnect();
}

void MediaBrowser::onShaderClipboardSourceChanged()
{
if (_blockShaderClipboardUpdates)
Expand All @@ -240,7 +156,10 @@ void MediaBrowser::onShaderClipboardSourceChanged()
setSelection(GlobalShaderClipboard().getShaderName());
}

// Static module
module::StaticModuleRegistration<MediaBrowser> mediaBrowserModule;
void MediaBrowser::focusMaterial(FocusMaterialRequest& request)
{
setSelection(request.getRequestedMaterial());
GlobalGroupDialog().setPage(UserControl::MediaBrowser);
}

} // namespace

0 comments on commit 9ed1396

Please sign in to comment.