1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
#include "AIHeadChooserDialog.h"
#include "i18n.h"
#include "ieclass.h"
#include "eclass.h"
#include <wx/splitter.h>
#include "wxutil/Bitmap.h"
#include "wxutil/dataview/TreeViewItemStyle.h"
#include "wxutil/dataview/ResourceTreeViewToolbar.h"
#include "ThreadedEntityDefPopulator.h"
namespace ui
{
namespace
{
const char* const WINDOW_TITLE = N_("Choose AI Head");
}
class ThreadedAIHeadLoader :
public ThreadedEntityDefPopulator
{
public:
ThreadedAIHeadLoader(const wxutil::DeclarationTreeView::Columns& columns) :
ThreadedEntityDefPopulator(columns, "icon_classname.png")
{}
protected:
bool ClassShouldBeListed(const IEntityClassPtr& eclass) override
{
return eclass->getAttributeValue("editor_head") == "1";
}
};
AIHeadChooserDialog::AIHeadChooserDialog() :
DialogBase(_(WINDOW_TITLE)),
_headsView(nullptr),
_description(nullptr)
{
SetSizer(new wxBoxSizer(wxVERTICAL));
auto splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition,
wxDefaultSize, wxSP_3D | wxSP_LIVE_UPDATE);
splitter->SetMinimumPaneSize(10); // disallow unsplitting
GetSizer()->Add(splitter, 1, wxEXPAND | wxALL, 12);
GetSizer()->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_RIGHT | wxBOTTOM | wxRIGHT, 12);
auto treeViewPanel = new wxPanel(splitter);
treeViewPanel->SetSizer(new wxBoxSizer(wxVERTICAL));
_headsView = new wxutil::DeclarationTreeView(treeViewPanel, decl::Type::EntityDef, _columns, wxDV_NO_HEADER);
_headsView->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &AIHeadChooserDialog::onHeadSelectionChanged, this);
// Head Name column
_headsView->AppendIconTextColumn("", _columns.iconAndName.getColumnIndex(),
wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE, wxALIGN_NOT, wxDATAVIEW_COL_SORTABLE);
// Allow searching for the name
_headsView->AddSearchColumn(_columns.leafName);
auto treeViewToolbar = new wxutil::ResourceTreeViewToolbar(treeViewPanel, _headsView);
treeViewPanel->GetSizer()->Add(treeViewToolbar, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 6);
treeViewPanel->GetSizer()->Add(_headsView, 1, wxEXPAND);
FitToScreen(0.7f, 0.6f);
auto previewPanel = new wxPanel(splitter, wxID_ANY);
// Set the default rotation to something better suitable for the head models
_preview.reset(new wxutil::ModelPreview(previewPanel));
_preview->setDefaultCamDistanceFactor(5.0f);
_description = new wxTextCtrl(previewPanel, wxID_ANY, "",
wxDefaultPosition, wxDefaultSize, wxTE_LEFT | wxTE_MULTILINE | wxTE_READONLY | wxTE_WORDWRAP);
_description->SetMinClientSize(wxSize(-1, 60));
previewPanel->SetSizer(new wxBoxSizer(wxVERTICAL));
previewPanel->GetSizer()->Add(_description, 0, wxEXPAND | wxBOTTOM, 6);
previewPanel->GetSizer()->Add(_preview->getWidget(), 1, wxEXPAND);
splitter->SplitVertically(treeViewPanel, previewPanel);
// Set the default size of the window
splitter->SetSashPosition(static_cast<int>(GetSize().GetWidth() * 0.3f));
populateHeadStore();
Bind(wxEVT_DATAVIEW_ITEM_ACTIVATED, &AIHeadChooserDialog::_onItemActivated, this);
}
void AIHeadChooserDialog::populateHeadStore()
{
_headsView->Populate(std::make_shared<ThreadedAIHeadLoader>(_columns));
}
void AIHeadChooserDialog::_onItemActivated(wxDataViewEvent& ev)
{
EndModal(wxID_OK);
}
void AIHeadChooserDialog::setSelectedHead(const std::string& headDef)
{
_headsView->SetSelectedDeclName(headDef);
}
std::string AIHeadChooserDialog::getSelectedHead()
{
return _headsView->GetSelectedDeclName();
}
void AIHeadChooserDialog::handleSelectionChanged()
{
_selectedHead = _headsView->GetSelectedDeclName();
// Update sensitivity
FindWindowById(wxID_OK, this)->Enable(!_selectedHead.empty());
_description->Enable(!_selectedHead.empty());
if (!_selectedHead.empty())
{
// Lookup the IEntityClass instance
if (auto ecls = GlobalEntityClassManager().findClass(_selectedHead); ecls)
{
_preview->setModel(ecls->getAttributeValue("model"));
_preview->setSkin(ecls->getAttributeValue("skin"));
// Update the usage panel
_description->SetValue(eclass::getUsage(ecls));
}
}
else
{
_preview->setModel("");
}
}
void AIHeadChooserDialog::onHeadSelectionChanged(wxDataViewEvent& ev)
{
handleSelectionChanged();
}
} // namespace
|