Skip to content

Commit

Permalink
#6021: Remove a ton of redundant code from ShaderSelector. Remove the…
Browse files Browse the repository at this point in the history
… ShaderSelector::Client interface in favour of a callback.
  • Loading branch information
codereader committed Jul 30, 2022
1 parent ec80000 commit 77c8573
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 366 deletions.
18 changes: 6 additions & 12 deletions radiant/ui/common/ShaderChooser.cpp
@@ -1,7 +1,6 @@
#include "ShaderChooser.h"

#include "i18n.h"
#include "iregistry.h"
#include "ishaders.h"
#include "texturelib.h"

Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);

Expand All @@ -124,7 +118,7 @@ void ShaderChooser::callbackCancel(wxCommandEvent& ev)

void ShaderChooser::callbackOK(wxCommandEvent& ev)
{
if (_targetEntry != NULL)
if (_targetEntry)
{
_targetEntry->SetValue(_selector->getSelection());
}
Expand Down
12 changes: 4 additions & 8 deletions radiant/ui/common/ShaderChooser.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand Down
239 changes: 14 additions & 225 deletions 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 <vector>
#include <string>

#include "texturelib.h"
#include "i18n.h"
#include "ishaders.h"

#include <wx/dataview.h>
#include <wx/sizer.h>

#include <GL/glew.h>

#include <vector>
#include <string>

#include "texturelib.h"
#include "string/split.h"
#include "string/predicate.h"
#include <functional>

#include "wxutil/dataview/VFSTreePopulator.h"
#include "wxutil/dataview/ThreadedDeclarationTreePopulator.h"

namespace ui
Expand Down Expand Up @@ -48,7 +40,7 @@ class ThreadedMaterialLoader final :
_prefixes(prefixes)
{}

~ThreadedMaterialLoader()
~ThreadedMaterialLoader() override
{
EnsureStopped();
}
Expand Down Expand Up @@ -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<void()>& 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));

Expand All @@ -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);
Expand Down Expand Up @@ -141,209 +118,21 @@ 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()
{
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

0 comments on commit 77c8573

Please sign in to comment.