Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#5787: Extract the ParticleSelector widget into a separate control th…
…at can be re-used. The dialog part remains in ParticlesChooser.
- Loading branch information
1 parent
c76852f
commit 02ba771
Showing
8 changed files
with
228 additions
and
166 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#include "ParticleSelector.h" | ||
|
||
#include "wxutil/dataview/ResourceTreeViewToolbar.h" | ||
#include "ThreadedParticlesLoader.h" | ||
|
||
namespace ui | ||
{ | ||
|
||
ParticleSelector::ParticleSelector(wxWindow* parent) : | ||
wxPanel(parent, wxID_ANY), | ||
_preview(new wxutil::ParticlePreview(this)) | ||
{ | ||
SetSizer(new wxBoxSizer(wxVERTICAL)); | ||
|
||
// Tree view plus toolbar | ||
auto* treeView = createTreeView(this); | ||
auto* toolbar = new wxutil::ResourceTreeViewToolbar(this, treeView); | ||
|
||
auto treeVbox = new wxBoxSizer(wxVERTICAL); | ||
treeVbox->Add(toolbar, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 6); | ||
treeVbox->Add(treeView, 1, wxEXPAND); | ||
|
||
// Treeview to the left, preview to the right | ||
auto hbox = new wxBoxSizer(wxHORIZONTAL); | ||
|
||
hbox->Add(treeVbox, 1, wxEXPAND); | ||
hbox->Add(_preview->getWidget(), 0, wxEXPAND | wxLEFT, 6); | ||
|
||
GetSizer()->Add(hbox, 1, wxEXPAND | wxALL, 12); | ||
|
||
GlobalParticlesManager().signal_particlesReloaded().connect( | ||
sigc::mem_fun(this, &ParticleSelector::reloadParticles) | ||
); | ||
} | ||
|
||
wxutil::ResourceTreeView* ParticleSelector::createTreeView(wxWindow* parent) | ||
{ | ||
_treeView = new wxutil::ResourceTreeView(parent, _columns, wxDV_NO_HEADER); | ||
_treeView->SetSize(300, -1); | ||
|
||
_treeView->AppendIconTextColumn(_("Particle"), _columns.iconAndName.getColumnIndex(), | ||
wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE, wxALIGN_NOT, wxDATAVIEW_COL_SORTABLE); | ||
|
||
// Apply full-text search to the column | ||
_treeView->AddSearchColumn(_columns.leafName); | ||
_treeView->EnableFavouriteManagement(decl::Type::Particle); | ||
|
||
// Start loading particles into the view | ||
populateParticleList(); | ||
|
||
// Connect up the selection changed callback | ||
_treeView->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &ParticleSelector::_onSelChanged, this); | ||
|
||
return _treeView; | ||
} | ||
|
||
void ParticleSelector::populateParticleList() | ||
{ | ||
_treeView->Populate(std::make_shared<ThreadedParticlesLoader>(_columns)); | ||
} | ||
|
||
void ParticleSelector::reloadParticles() | ||
{ | ||
populateParticleList(); | ||
} | ||
|
||
std::string ParticleSelector::getSelectedParticle() | ||
{ | ||
return _treeView->GetSelectedFullname(); | ||
} | ||
|
||
void ParticleSelector::setSelectedParticle(const std::string& particleName) | ||
{ | ||
_treeView->SetSelectedFullname(particleName); | ||
} | ||
|
||
void ParticleSelector::_onSelChanged(wxDataViewEvent& ev) | ||
{ | ||
// Get the selection and store it | ||
auto item = _treeView->GetSelection(); | ||
|
||
if (item.IsOk()) | ||
{ | ||
wxutil::TreeModel::Row row(item, *_treeView->GetTreeModel()); | ||
_preview->setParticle(row[_columns.leafName]); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#pragma once | ||
|
||
#include <sigc++/trackable.h> | ||
#include <wx/panel.h> | ||
|
||
#include "wxutil/dataview/ResourceTreeView.h" | ||
#include "wxutil/preview/ParticlePreview.h" | ||
|
||
namespace ui | ||
{ | ||
|
||
/** | ||
* \brief | ||
* Chooser widget for selection and preview of particle systems. | ||
* Features a resource tree view on the left and a render preview on the right. | ||
*/ | ||
class ParticleSelector : | ||
public wxPanel, | ||
public sigc::trackable | ||
{ | ||
private: | ||
wxutil::ResourceTreeView::Columns _columns; | ||
|
||
// Tree view listing all the particles | ||
wxutil::ResourceTreeView* _treeView; | ||
|
||
// The preview widget | ||
wxutil::ParticlePreviewPtr _preview; | ||
|
||
public: | ||
ParticleSelector(wxWindow* parent); | ||
|
||
std::string getSelectedParticle(); | ||
void setSelectedParticle(const std::string& particleName); | ||
|
||
private: | ||
wxutil::ResourceTreeView* createTreeView(wxWindow* parent); | ||
|
||
// Populate the list of particles | ||
void populateParticleList(); | ||
void reloadParticles(); | ||
|
||
void _onSelChanged(wxDataViewEvent& ev); | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,178 +1,45 @@ | ||
#include "ParticlesChooser.h" | ||
|
||
#include "i18n.h" | ||
#include "iparticles.h" | ||
#include "iradiant.h" | ||
#include "ifavourites.h" | ||
|
||
#include "debugging/ScopedDebugTimer.h" | ||
|
||
#include "wxutil/dataview/ResourceTreeViewToolbar.h" | ||
#include "wxutil/dataview/ThreadedResourceTreePopulator.h" | ||
#include "wxutil/dataview/TreeViewItemStyle.h" | ||
|
||
#include <wx/sizer.h> | ||
#include <functional> | ||
|
||
namespace ui | ||
{ | ||
|
||
ParticlesChooser::ParticlesChooser() : | ||
DialogBase(_("Choose Particle")), | ||
_selectedParticle(""), | ||
_preview(new wxutil::ParticlePreview(this)) | ||
_selector(new ParticleSelector(this)) | ||
{ | ||
SetSizer(new wxBoxSizer(wxVERTICAL)); | ||
|
||
wxBoxSizer* hbox = new wxBoxSizer(wxHORIZONTAL); | ||
|
||
wxBoxSizer* treeVbox = new wxBoxSizer(wxVERTICAL); | ||
|
||
auto* treeView = createTreeView(this); | ||
auto* toolbar = new wxutil::ResourceTreeViewToolbar(this, treeView); | ||
|
||
treeVbox->Add(toolbar, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 6); | ||
treeVbox->Add(treeView, 1, wxEXPAND); | ||
|
||
hbox->Add(treeVbox, 1, wxEXPAND); | ||
hbox->Add(_preview->getWidget(), 0, wxEXPAND | wxLEFT, 6); | ||
|
||
GetSizer()->Add(hbox, 1, wxEXPAND | wxALL, 12); | ||
GetSizer()->Add(_selector, 1, wxEXPAND | wxALL, 12); | ||
GetSizer()->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_RIGHT | wxBOTTOM | wxLEFT | wxRIGHT, 12); | ||
|
||
FitToScreen(0.5f, 0.6f); | ||
|
||
GlobalParticlesManager().signal_particlesReloaded().connect( | ||
sigc::mem_fun(this, &ParticlesChooser::reloadParticles) | ||
); | ||
|
||
Bind( wxEVT_DATAVIEW_ITEM_ACTIVATED, &ParticlesChooser::_onItemActivated, this ); | ||
} | ||
|
||
// Create the tree view | ||
wxutil::ResourceTreeView* ParticlesChooser::createTreeView(wxWindow* parent) | ||
{ | ||
_treeView = new wxutil::ResourceTreeView(parent, _columns, wxDV_NO_HEADER); | ||
_treeView->SetSize(300, -1); | ||
|
||
_treeView->AppendIconTextColumn(_("Particle"), _columns.iconAndName.getColumnIndex(), | ||
wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE, wxALIGN_NOT, wxDATAVIEW_COL_SORTABLE); | ||
|
||
// Apply full-text search to the column | ||
_treeView->AddSearchColumn(_columns.leafName); | ||
_treeView->EnableFavouriteManagement(decl::Type::Particle); | ||
|
||
// Start loading particles into the view | ||
populateParticleList(); | ||
|
||
// Connect up the selection changed callback | ||
_treeView->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &ParticlesChooser::_onSelChanged, this); | ||
|
||
return _treeView; | ||
} | ||
|
||
void ParticlesChooser::_onItemActivated( wxDataViewEvent& ev ) { | ||
EndModal( wxID_OK ); | ||
} | ||
|
||
/** | ||
* Visitor class to retrieve particle system names and add them to a | ||
* treemodel. | ||
*/ | ||
class ThreadedParticlesLoader final : | ||
public wxutil::ThreadedResourceTreePopulator | ||
{ | ||
private: | ||
const wxutil::ResourceTreeView::Columns& _columns; | ||
|
||
std::set<std::string> _favourites; | ||
|
||
public: | ||
ThreadedParticlesLoader(const wxutil::ResourceTreeView::Columns& columns) : | ||
ThreadedResourceTreePopulator(columns), | ||
_columns(columns) | ||
{ | ||
// Get the list of favourites | ||
_favourites = GlobalFavouritesManager().getFavourites(decl::Type::Particle); | ||
} | ||
|
||
~ThreadedParticlesLoader() | ||
{ | ||
EnsureStopped(); | ||
} | ||
|
||
protected: | ||
void PopulateModel(const wxutil::TreeModel::Ptr& model) override | ||
{ | ||
ScopedDebugTimer timer("ThreadedParticlesLoader::run()"); | ||
|
||
// Create and use a ParticlesVisitor to populate the list | ||
GlobalParticlesManager().forEachParticleDef([&](const particles::IParticleDef& def) | ||
{ | ||
ThrowIfCancellationRequested(); | ||
|
||
// Add the ".prt" extension to the name fo display in the list | ||
std::string prtName = def.getName() + ".prt"; | ||
|
||
// Add the Def name to the list store | ||
wxutil::TreeModel::Row row = model->AddItem(); | ||
|
||
bool isFavourite = _favourites.count(prtName) > 0; | ||
|
||
row[_columns.iconAndName] = wxVariant(wxDataViewIconText(prtName)); | ||
row[_columns.iconAndName] = wxutil::TreeViewItemStyle::Declaration(isFavourite); | ||
row[_columns.fullName] = prtName; | ||
row[_columns.leafName] = prtName; | ||
row[_columns.isFolder] = false; | ||
row[_columns.isFavourite] = isFavourite; | ||
|
||
row.SendItemAdded(); | ||
}); | ||
} | ||
}; | ||
|
||
// Populate the particles list | ||
void ParticlesChooser::populateParticleList() | ||
{ | ||
_treeView->Populate(std::make_shared<ThreadedParticlesLoader>(_columns)); | ||
} | ||
|
||
void ParticlesChooser::reloadParticles() | ||
{ | ||
populateParticleList(); | ||
_selector->Bind(wxEVT_DATAVIEW_ITEM_ACTIVATED, &ParticlesChooser::_onItemActivated, this); | ||
} | ||
|
||
void ParticlesChooser::setSelectedParticle(const std::string& particleName) | ||
void ParticlesChooser::_onItemActivated(wxDataViewEvent& ev) | ||
{ | ||
_treeView->SetSelectedFullname(particleName); | ||
EndModal(wxID_OK); | ||
} | ||
|
||
// Choose a particle system | ||
std::string ParticlesChooser::ChooseParticle(const std::string& current) | ||
{ | ||
auto* dialog = new ParticlesChooser(); | ||
|
||
dialog->setSelectedParticle(current); | ||
dialog->_selector->setSelectedParticle(current); | ||
|
||
auto returnValue = dialog->ShowModal() == wxID_OK ? dialog->_selectedParticle : ""; | ||
auto returnValue = dialog->ShowModal() == wxID_OK ? dialog->_selector->getSelectedParticle() : ""; | ||
|
||
dialog->Destroy(); | ||
|
||
return returnValue; | ||
} | ||
|
||
void ParticlesChooser::_onSelChanged(wxDataViewEvent& ev) | ||
{ | ||
// Get the selection and store it | ||
wxDataViewItem item = _treeView->GetSelection(); | ||
|
||
if (item.IsOk()) | ||
{ | ||
wxutil::TreeModel::Row row(item, *_treeView->GetTreeModel()); | ||
_selectedParticle = row[_columns.leafName]; | ||
|
||
_preview->setParticle(_selectedParticle); | ||
} | ||
} | ||
|
||
} // namespace ui | ||
} // namespace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.