diff --git a/radiant/ui/common/ShaderChooser.cpp b/radiant/ui/common/ShaderChooser.cpp index 41d61fed63..a0f90a2024 100644 --- a/radiant/ui/common/ShaderChooser.cpp +++ b/radiant/ui/common/ShaderChooser.cpp @@ -1,7 +1,6 @@ #include "ShaderChooser.h" #include "i18n.h" -#include "iregistry.h" #include "ishaders.h" #include "texturelib.h" @@ -30,7 +29,8 @@ ShaderChooser::ShaderChooser(wxWindow* parent, wxTextCtrl* targetEntry) : wxBoxSizer* dialogVBox = new wxBoxSizer(wxVERTICAL); mainPanel->GetSizer()->Add(dialogVBox, 1, wxEXPAND | wxALL, 12); - _selector = new ShaderSelector(mainPanel, this, SHADER_PREFIXES); + _selector = new ShaderSelector(mainPanel, + std::bind(&ShaderChooser::shaderSelectionChanged, this), SHADER_PREFIXES); if (_targetEntry != nullptr) { @@ -84,27 +84,21 @@ void ShaderChooser::createButtons(wxPanel* mainPanel, wxBoxSizer* dialogVBox) dialogVBox->Add(buttons, 0, wxALIGN_RIGHT | wxTOP, 6); } -void ShaderChooser::shaderSelectionChanged(const std::string& shaderName, - wxutil::TreeModel& listStore) +void ShaderChooser::shaderSelectionChanged() { - if (_targetEntry != NULL) + if (_targetEntry) { _targetEntry->SetValue(_selector->getSelection()); } // Propagate the call up to the client (e.g. SurfaceInspector) _shaderChangedSignal.emit(); - - // Get the shader, and its image map if possible - MaterialPtr shader = _selector->getSelectedShader(); - // Pass the call to the static member - ShaderSelector::displayShaderInfo(shader, listStore); } void ShaderChooser::revertShader() { // Revert the shadername to the value it had at dialog startup - if (_targetEntry != NULL) + if (_targetEntry) { _targetEntry->SetValue(_initialShader); @@ -124,7 +118,7 @@ void ShaderChooser::callbackCancel(wxCommandEvent& ev) void ShaderChooser::callbackOK(wxCommandEvent& ev) { - if (_targetEntry != NULL) + if (_targetEntry) { _targetEntry->SetValue(_selector->getSelection()); } diff --git a/radiant/ui/common/ShaderChooser.h b/radiant/ui/common/ShaderChooser.h index 02b7906214..f871c391d8 100644 --- a/radiant/ui/common/ShaderChooser.h +++ b/radiant/ui/common/ShaderChooser.h @@ -17,8 +17,7 @@ namespace ui * all shaders matching the "texture/" prefix. */ class ShaderChooser : - public wxutil::DialogBase, - public ShaderSelector::Client + public wxutil::DialogBase { // The text entry the chosen texture is written into (can be NULL) wxTextCtrl* _targetEntry; @@ -51,13 +50,10 @@ class ShaderChooser : return _shaderChangedSignal; } - /** - * greebo: ShaderSelector::Client implementation - * Gets called upon shader selection change. - */ - void shaderSelectionChanged(const std::string& shader, wxutil::TreeModel& listStore); - private: + // greebo: Gets called upon shader selection change. + void shaderSelectionChanged(); + // Saves the window position void shutdown(); diff --git a/radiant/ui/common/ShaderSelector.cpp b/radiant/ui/common/ShaderSelector.cpp index 92ea0a2165..9cd3d7d034 100644 --- a/radiant/ui/common/ShaderSelector.cpp +++ b/radiant/ui/common/ShaderSelector.cpp @@ -1,26 +1,18 @@ #include "ShaderSelector.h" -#include "i18n.h" - -#include "wxutil/dataview/TreeView.h" -#include "wxutil/dataview/VFSTreePopulator.h" -#include "wxutil/DeclarationSourceView.h" +#include +#include -#include "texturelib.h" +#include "i18n.h" #include "ishaders.h" -#include #include -#include - -#include -#include - +#include "texturelib.h" #include "string/split.h" #include "string/predicate.h" -#include +#include "wxutil/dataview/VFSTreePopulator.h" #include "wxutil/dataview/ThreadedDeclarationTreePopulator.h" namespace ui @@ -48,7 +40,7 @@ class ThreadedMaterialLoader final : _prefixes(prefixes) {} - ~ThreadedMaterialLoader() + ~ThreadedMaterialLoader() override { EnsureStopped(); } @@ -76,14 +68,11 @@ class ThreadedMaterialLoader final : } }; -// Constructor creates elements -ShaderSelector::ShaderSelector(wxWindow* parent, Client* client, const std::string& prefixes, bool isLightTexture) : +ShaderSelector::ShaderSelector(wxWindow* parent, const std::function& selectionChanged, + const std::string& prefixes) : wxPanel(parent, wxID_ANY), _treeView(nullptr), - _glWidget(nullptr), - _client(client), - _isLightTexture(isLightTexture), - _infoStore(new wxutil::TreeModel(_infoStoreColumns, true)) // is a listmodel + _selectionChanged(selectionChanged) { SetSizer(new wxBoxSizer(wxVERTICAL)); @@ -95,23 +84,11 @@ ShaderSelector::ShaderSelector(wxWindow* parent, Client* client, const std::stri createPreview(); } -void ShaderSelector::_onShowShaderDefinition() -{ - // Construct a definition view and pass the material name - auto view = new wxutil::DeclarationSourceView(this); - view->setDeclaration(decl::Type::Material, getSelection()); - - view->ShowModal(); - view->Destroy(); -} - -// Return the selection to the calling code std::string ShaderSelector::getSelection() { return _treeView->GetSelectedDeclName(); } -// Set the selection in the treeview void ShaderSelector::setSelection(const std::string& sel) { _treeView->SetSelectedDeclName(sel); @@ -141,30 +118,6 @@ void ShaderSelector::createPreview() { _previewCombo = new TexturePreviewCombo(this); GetSizer()->Add(_previewCombo, 0, wxEXPAND | wxTOP, 3); -#if 0 - // HBox contains the preview GL widget along with a texture attributes pane. - wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); - - // Cast the GLWidget object to GtkWidget - _glWidget = new wxutil::GLWidget(this, std::bind(&ShaderSelector::onPreviewRender, this), "ShaderSelector"); - _glWidget->SetMinClientSize(wxSize(128, 128)); - - // Attributes table - wxDataViewCtrl* tree = new wxDataViewCtrl(this, wxID_ANY, - wxDefaultPosition, wxDefaultSize, wxDV_NO_HEADER | wxDV_SINGLE); - - tree->AssociateModel(_infoStore.get()); - - tree->AppendTextColumn(_("Attribute"), _infoStoreColumns.attribute.getColumnIndex(), - wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE); - tree->AppendTextColumn(_("Value"), _infoStoreColumns.value.getColumnIndex(), - wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE); - - sizer->Add(_glWidget, 0, wxEXPAND); - sizer->Add(tree, 1, wxEXPAND); - - GetSizer()->Add(sizer, 0, wxEXPAND | wxTOP, 3); -#endif } MaterialPtr ShaderSelector::getSelectedShader() @@ -172,178 +125,14 @@ MaterialPtr ShaderSelector::getSelectedShader() return GlobalMaterialManager().getMaterial(getSelection()); } -// Update the attributes table -void ShaderSelector::updateInfoTable() -{ - return; - _infoStore->Clear(); - - // Get the selected texture name. If nothing is selected, we just leave the - // infotable empty. - std::string selName = getSelection(); - - // Notify the client of the change to give it a chance to update the infostore - if (_client != NULL && !selName.empty()) - { - _client->shaderSelectionChanged(selName, *_infoStore); - } -} - -// Callback to redraw the GL widget -bool ShaderSelector::onPreviewRender() -{ - return true; - - // Get the viewport size from the GL widget - wxSize req = _glWidget->GetClientSize(); - - if (req.GetWidth() == 0 || req.GetHeight() == 0) return false; - - glViewport(0, 0, req.GetWidth(), req.GetHeight()); - - // Initialise - glClearColor(0.3f, 0.3f, 0.3f, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_DEPTH_TEST); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glOrtho(0, req.GetWidth(), 0, req.GetHeight(), -100, 100); - glEnable (GL_TEXTURE_2D); - - // Get the selected texture, and set up OpenGL to render it on - // the quad. - MaterialPtr shader = getSelectedShader(); - - bool drawQuad = false; - TexturePtr tex; - - // Check what part of the shader we should display in the preview - if (_isLightTexture) { - // This is a light, take the first layer texture - const IShaderLayer* first = shader->firstLayer(); - if (first != NULL) { - tex = shader->firstLayer()->getTexture(); - glBindTexture (GL_TEXTURE_2D, tex->getGLTexNum()); - drawQuad = true; - } - } - else { - // This is an "ordinary" texture, take the editor image - tex = shader->getEditorImage(); - if (tex != NULL) { - glBindTexture (GL_TEXTURE_2D, tex->getGLTexNum()); - drawQuad = true; - } - } - - if (drawQuad) - { - // Calculate the correct aspect ratio for preview. - float aspect = float(tex->getWidth()) / float(tex->getHeight()); - - float hfWidth, hfHeight; - if (aspect > 1.0) { - hfWidth = 0.5*req.GetWidth(); - hfHeight = 0.5*req.GetHeight() / aspect; - } - else { - hfHeight = 0.5*req.GetWidth(); - hfWidth = 0.5*req.GetHeight() * aspect; - } - - // Draw a quad to put the texture on - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - glColor3f(1, 1, 1); - glBegin(GL_QUADS); - glTexCoord2i(0, 1); - glVertex2f(0.5*req.GetWidth() - hfWidth, 0.5*req.GetHeight() - hfHeight); - glTexCoord2i(1, 1); - glVertex2f(0.5*req.GetWidth() + hfWidth, 0.5*req.GetHeight() - hfHeight); - glTexCoord2i(1, 0); - glVertex2f(0.5*req.GetWidth() + hfWidth, 0.5*req.GetHeight() + hfHeight); - glTexCoord2i(0, 0); - glVertex2f(0.5*req.GetWidth() - hfWidth, 0.5*req.GetHeight() + hfHeight); - glEnd(); - } - - return true; -} - -namespace -{ - -// Helper function -void addInfoItem(wxutil::TreeModel& listStore, const std::string& attr, const std::string& value, - int attrCol, int valueCol) -{ - wxDataViewItemAttr bold; - bold.SetBold(true); - - wxDataViewItem item = listStore.AddItem().getItem(); - - listStore.SetValue(attr, item, attrCol); - listStore.SetAttr(item, attrCol, bold); - listStore.SetValue(value, item, valueCol); - - listStore.ItemAdded(listStore.GetRoot(), item); -} - -} - -void ShaderSelector::displayShaderInfo(const MaterialPtr& shader, - wxutil::TreeModel& listStore, - int attrCol, int valueCol) -{ - // Update the infostore in the ShaderSelector - addInfoItem(listStore, _("Shader"), shader->getName(), attrCol, valueCol); - addInfoItem(listStore, _("Defined in"), shader->getShaderFileName(), attrCol, valueCol); - addInfoItem(listStore, _("Description"), shader->getDescription(), attrCol, valueCol); -} - -void ShaderSelector::displayLightShaderInfo(const MaterialPtr& shader, - wxutil::TreeModel& listStore, - int attrCol, int valueCol) -{ - const IShaderLayer* first = shader->firstLayer(); - std::string texName = _("None"); - - if (first != NULL) - { - TexturePtr tex = shader->firstLayer()->getTexture(); - texName = tex->getName(); - } - - addInfoItem(listStore, _("Image map"), texName, attrCol, valueCol); - addInfoItem(listStore, _("Defined in"), shader->getShaderFileName(), attrCol, valueCol); - - // Light types, from the Material - std::string lightType; - if (shader->isAmbientLight()) - lightType.append("ambient "); - if (shader->isBlendLight()) - lightType.append("blend "); - if (shader->isFogLight()) - lightType.append("fog"); - if (lightType.size() == 0) - lightType.append("-"); - - addInfoItem(listStore, _("Light flags"), lightType, attrCol, valueCol); - - std::string descr = shader->getDescription(); - addInfoItem(listStore, _("Description"), descr.empty() ? "-" : descr, attrCol, valueCol); -} - -// Callback for selection changed void ShaderSelector::_onSelChange(wxDataViewEvent& ev) { _previewCombo->SetTexture(getSelection()); -#if 0 - updateInfoTable(); - _glWidget->Refresh(); -#endif + if (_selectionChanged) + { + _selectionChanged(); + } } -} // namespace ui +} // namespace diff --git a/radiant/ui/common/ShaderSelector.h b/radiant/ui/common/ShaderSelector.h index 105bfe543f..da0cab21f6 100644 --- a/radiant/ui/common/ShaderSelector.h +++ b/radiant/ui/common/ShaderSelector.h @@ -3,10 +3,7 @@ #include #include #include -#include "wxutil/GLWidget.h" -#include "wxutil/dataview/TreeView.h" #include "wxutil/dataview/DeclarationTreeView.h" -#include "wxutil/menu/PopupMenu.h" #include @@ -21,10 +18,11 @@ class wxDataViewCtrl; namespace ui { -/** A widget that allows the selection of a shader. The widget contains +/** + * A widget that allows the selection of a shader. The widget contains * three elements - a tree view displaying available shaders as - * identified by the specified prefixes, an OpenGL widget displaying a - * preview of the currently-selected shader, and a table containing certain + * identified by the specified prefixes, a TexturePreviewComob displaying a + * preview of the currently-selected shader and a table containing certain * information about the shader. * * Use the wxWindow* operator to incorporate this class into a dialog window. @@ -33,76 +31,18 @@ namespace ui * that allows calling code to retrieve the user's selection. The set of * displayed textures can be defined by passing a list of texture prefixes to * the constructor (comma-separated, e.g. "fog,light"). - * - * The client class has to derive from the abstract ShaderSelector::Client class - * providing an interface to allow the update of the info liststore. - * - * For convenience purposes, this class provides two static members that - * allow populating the infostore widget with common lightshader/shader information. - * */ class ShaderSelector : public wxPanel { -public: - - // Derive from this class to update the info widget - class Client - { - public: - /// destructor - virtual ~Client() {} - - /** greebo: This gets invoked upon selection changed to allow the client - * class to display custom information in the selector's liststore. - */ - virtual void shaderSelectionChanged(const std::string& shader, wxutil::TreeModel& listStore) = 0; - }; - - struct ShaderTreeColumns : - public wxutil::TreeModel::ColumnRecord - { - ShaderTreeColumns() : - iconAndName(add(wxutil::TreeModel::Column::IconText)), - shaderName(add(wxutil::TreeModel::Column::String)) - {} - - wxutil::TreeModel::Column iconAndName; - wxutil::TreeModel::Column shaderName; - }; - private: wxutil::DeclarationTreeView::Columns _shaderTreeColumns; wxutil::DeclarationTreeView* _treeView; - // GL preview widget - wxutil::GLWidget* _glWidget; - - // The client of this class. - Client* _client; - - // TRUE, if the first light layers are to be rendered instead of the editorimages - bool _isLightTexture; - - struct InfoStoreColumns : - public wxutil::TreeModel::ColumnRecord - { - InfoStoreColumns() : - attribute(add(wxutil::TreeModel::Column::String)), - value(add(wxutil::TreeModel::Column::String)) - {} - - wxutil::TreeModel::Column attribute; - wxutil::TreeModel::Column value; - }; - - InfoStoreColumns _infoStoreColumns; + std::function _selectionChanged; TexturePreviewCombo* _previewCombo; - // List store for info table - wxutil::TreeModel::Ptr _infoStore; - public: // This is where the prefixes are stored (needed to filter the possible shaders) typedef std::vector PrefixList; @@ -110,12 +50,11 @@ class ShaderSelector : /** Constructor. * - * @client: The client class that gets notified on selection change + * @selectionChanged: Functor invoked when the tree view selection changes. * @prefixes: A comma-separated list of shader prefixes. - * @isLightTexture: set this to TRUE to render the light textures instead of the editor images */ - ShaderSelector(wxWindow* parent, Client* client, - const std::string& prefixes, bool isLightTexture = false); + ShaderSelector(wxWindow* parent, const std::function& selectionChanged, + const std::string& prefixes); /** Return the shader selected by the user, or an empty string if there * was no selection. @@ -134,35 +73,12 @@ class ShaderSelector : // Get the selected Material MaterialPtr getSelectedShader(); - /** greebo: Static info display function (can be used by other UI classes as well - * to allow code reuse). - */ - static void displayShaderInfo(const MaterialPtr& shader, - wxutil::TreeModel& listStore, - int attrCol = 0, // attribute column number - int valueCol = 1); // value column number - - /** greebo: Populates the given listStore with the light shader information. - */ - static void displayLightShaderInfo(const MaterialPtr& shader, - wxutil::TreeModel& listStore, - int attrCol = 0, // attribute column number - int valueCol = 1); // value column number - private: - // Create GUI elements void createTreeView(); void createPreview(); - // Update the info in the table (passes the call to the client class) - void updateInfoTable(); - - // callbacks - bool onPreviewRender(); void _onSelChange(wxDataViewEvent& ev); - - void _onShowShaderDefinition(); }; } // namespace ui diff --git a/radiant/ui/einspector/LightTextureChooser.cpp b/radiant/ui/einspector/LightTextureChooser.cpp index 9c90778073..4a2c199796 100644 --- a/radiant/ui/einspector/LightTextureChooser.cpp +++ b/radiant/ui/einspector/LightTextureChooser.cpp @@ -52,7 +52,7 @@ LightTextureChooser::LightTextureChooser() : wxBoxSizer* dialogVBox = new wxBoxSizer(wxVERTICAL); mainPanel->GetSizer()->Add(dialogVBox, 1, wxEXPAND | wxALL, 12); - _selector = new ShaderSelector(mainPanel, this, getPrefixList(), true); // true >> render a light texture + _selector = new ShaderSelector(mainPanel, {}, getPrefixList()); // Pack in the ShaderSelector and buttons panel dialogVBox->Add(_selector, 1, wxEXPAND); @@ -88,13 +88,4 @@ void LightTextureChooser::setSelectedTexture(const std::string& textureName) _selector->setSelection(textureName); } -void LightTextureChooser::shaderSelectionChanged(const std::string& shaderName, - wxutil::TreeModel& listStore) -{ - // Get the shader, and its image map if possible - MaterialPtr shader = _selector->getSelectedShader(); - // Pass the call to the static member light shader info - ShaderSelector::displayLightShaderInfo(shader, listStore); -} - } // namespace ui diff --git a/radiant/ui/einspector/LightTextureChooser.h b/radiant/ui/einspector/LightTextureChooser.h index 151accc7c3..5aab218aff 100644 --- a/radiant/ui/einspector/LightTextureChooser.h +++ b/radiant/ui/einspector/LightTextureChooser.h @@ -16,8 +16,7 @@ namespace ui * buttons. */ class LightTextureChooser : - public wxutil::DialogBase, - public ShaderSelector::Client + public wxutil::DialogBase { private: // The ShaderSelector widget group, that contains the actual selection @@ -51,11 +50,8 @@ class LightTextureChooser : */ void setSelectedTexture(const std::string& textureName); - /** greebo: Gets called upon selection change, updates the infostore - * of the contained ShaderSelector helper class accordingly. - */ - void shaderSelectionChanged(const std::string& shaderName, - wxutil::TreeModel& listStore); + // greebo: Gets called upon selection change + void shaderSelectionChanged(); }; diff --git a/radiant/ui/lightinspector/LightInspector.cpp b/radiant/ui/lightinspector/LightInspector.cpp index d09cc18c39..2df5a20fca 100644 --- a/radiant/ui/lightinspector/LightInspector.cpp +++ b/radiant/ui/lightinspector/LightInspector.cpp @@ -100,14 +100,10 @@ void LightInspector::onMainFrameShuttingDown() InstancePtr().reset(); } -void LightInspector::shaderSelectionChanged( - const std::string& shader, - wxutil::TreeModel& listStore) +void LightInspector::shaderSelectionChanged() { - // Get the shader, and its image map if possible + // Get the selected shader MaterialPtr ishader = _texSelector->getSelectedShader(); - // Pass the call to the static member of ShaderSelector - ShaderSelector::displayLightShaderInfo(ishader, listStore); // greebo: Do not write to the entities if this call resulted from an update() if (_updateActive) return; @@ -201,7 +197,7 @@ void LightInspector::setupTextureWidgets() { wxPanel* parent = findNamedObject(this, "LightInspectorChooserPanel"); - _texSelector = new ShaderSelector(parent, this, getPrefixList(), true); + _texSelector = new ShaderSelector(parent, std::bind(&LightInspector::shaderSelectionChanged, this), getPrefixList()); parent->GetSizer()->Add(_texSelector, 1, wxEXPAND); } diff --git a/radiant/ui/lightinspector/LightInspector.h b/radiant/ui/lightinspector/LightInspector.h index cdc6b02fd8..76f47b53bd 100644 --- a/radiant/ui/lightinspector/LightInspector.h +++ b/radiant/ui/lightinspector/LightInspector.h @@ -28,7 +28,6 @@ typedef std::shared_ptr LightInspectorPtr; */ class LightInspector : public wxutil::TransientWindow, - public ShaderSelector::Client, public sigc::trackable, private wxutil::XmlResourceBasedWidget { @@ -106,10 +105,8 @@ class LightInspector : // Set the given key/value pair on ALL entities in the list of lights void setKeyValueAllLights(const std::string& k, const std::string& v); - /** greebo: Gets called when the shader selection gets changed, so that - * the displayed texture info can be updated. - */ - void shaderSelectionChanged(const std::string& shader, wxutil::TreeModel& listStore); + // greebo: Gets called when the light texture selection has changed + void shaderSelectionChanged(); // Safely disconnects this dialog from all the systems // and saves the window size/position to the registry