Skip to content

Commit

Permalink
#5532: Duplicate layers button
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Mar 20, 2021
1 parent 40317cd commit 6db0dd5
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 0 deletions.
3 changes: 3 additions & 0 deletions include/ishaders.h
Expand Up @@ -325,6 +325,9 @@ class Material
// Removes the indexed layer from this material
virtual void removeLayer(std::size_t index) = 0;

// Duplicates the given layer and returns the index to the copied one
virtual std::size_t duplicateLayer(std::size_t index) = 0;

// Swaps the position of the two layers
virtual void swapLayerPosition(std::size_t first, std::size_t second) = 0;

Expand Down
27 changes: 27 additions & 0 deletions radiant/ui/materials/MaterialEditor.cpp
Expand Up @@ -401,6 +401,7 @@ void MaterialEditor::setupMaterialStageView()
getControl<wxButton>("MaterialEditorToggleStageButton")->Bind(wxEVT_BUTTON, &MaterialEditor::_onToggleStage, this);
getControl<wxButton>("MaterialEditorMoveUpStageButton")->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { moveStagePosition(-1); });
getControl<wxButton>("MaterialEditorMoveDownStageButton")->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { moveStagePosition(+1); });
getControl<wxButton>("MaterialEditorDuplicateStageButton")->Bind(wxEVT_BUTTON, &MaterialEditor::_onDuplicateStage, this);
}

void MaterialEditor::setupStageFlag(const std::string& controlName, int flags)
Expand Down Expand Up @@ -1625,6 +1626,19 @@ void MaterialEditor::_onRemoveStage(wxCommandEvent& ev)

_material->removeLayer(index);
updateStageListFromMaterial();

auto layersCount = _material->getAllLayers().size();

while (index > 0)
{
if (index < layersCount)
{
selectStageByIndex(index);
return;
}

--index;
}
}

void MaterialEditor::_onToggleStage(wxCommandEvent& ev)
Expand All @@ -1644,6 +1658,19 @@ void MaterialEditor::_onToggleStage(wxCommandEvent& ev)
onMaterialChanged();
}

void MaterialEditor::_onDuplicateStage(wxCommandEvent& ev)
{
auto item = _stageView->GetSelection();
if (!_material || !item.IsOk()) return;

auto row = wxutil::TreeModel::Row(item, *_stageList);
auto index = row[STAGE_COLS().index].getInteger();

auto newIndex = _material->duplicateLayer(index);
updateStageListFromMaterial();
selectStageByIndex(newIndex);
}

void MaterialEditor::updateNameOfSelectedStage()
{
auto item = _stageView->GetSelection();
Expand Down
1 change: 1 addition & 0 deletions radiant/ui/materials/MaterialEditor.h
Expand Up @@ -145,6 +145,7 @@ class MaterialEditor :
void _onAddStage(wxCommandEvent& ev);
void _onRemoveStage(wxCommandEvent& ev);
void _onToggleStage(wxCommandEvent& ev);
void _onDuplicateStage(wxCommandEvent& ev);

void onMaterialChanged();

Expand Down
12 changes: 12 additions & 0 deletions radiantcore/shaders/CShader.cpp
Expand Up @@ -340,6 +340,18 @@ void CShader::swapLayerPosition(std::size_t first, std::size_t second)
realiseLighting();
}

std::size_t CShader::duplicateLayer(std::size_t index)
{
ensureTemplateCopy();

auto newIndex = _template->duplicateLayer(index);

unrealiseLighting();
realiseLighting();

return newIndex;
}

IEditableShaderLayer::Ptr CShader::getEditableLayer(std::size_t index)
{
ensureTemplateCopy();
Expand Down
1 change: 1 addition & 0 deletions radiantcore/shaders/CShader.h
Expand Up @@ -96,6 +96,7 @@ class CShader final :
std::size_t addLayer(IShaderLayer::Type type) override;
void removeLayer(std::size_t index) override;
void swapLayerPosition(std::size_t first, std::size_t second) override;
std::size_t duplicateLayer(std::size_t index) override;
IEditableShaderLayer::Ptr getEditableLayer(std::size_t index) override;

IMapExpression::Ptr getLightFalloffExpression() override;
Expand Down
11 changes: 11 additions & 0 deletions radiantcore/shaders/ShaderTemplate.cpp
Expand Up @@ -1436,6 +1436,17 @@ void ShaderTemplate::swapLayerPosition(std::size_t first, std::size_t second)
_layers[first].swap(_layers[second]);
}

std::size_t ShaderTemplate::duplicateLayer(std::size_t index)
{
if (index >= _layers.size())
{
throw std::runtime_error("Cannot duplicate this stage, index invalid");
}

_layers.emplace_back(std::make_shared<Doom3ShaderLayer>(*_layers[index], *this));
return _layers.size() - 1;
}

bool ShaderTemplate::hasDiffusemap()
{
if (!_parsed) parseDefinition();
Expand Down
1 change: 1 addition & 0 deletions radiantcore/shaders/ShaderTemplate.h
Expand Up @@ -326,6 +326,7 @@ class ShaderTemplate final
std::size_t addLayer(IShaderLayer::Type type);
void removeLayer(std::size_t index);
void swapLayerPosition(std::size_t first, std::size_t second);
std::size_t duplicateLayer(std::size_t index);

// Add a specific layer to this template
void addLayer(IShaderLayer::Type type, const MapExpressionPtr& mapExpr);
Expand Down

0 comments on commit 6db0dd5

Please sign in to comment.