Skip to content

Commit

Permalink
Allow Canvas mode effects to select the model blending layer as a pos…
Browse files Browse the repository at this point in the history
…sible layer.
  • Loading branch information
dkulp committed Apr 13, 2024
1 parent 0faab68 commit d0e3335
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 130 deletions.
225 changes: 105 additions & 120 deletions xLights/LayerSelectDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,178 +27,163 @@ const long LayerSelectDialog::ID_MCU_SELECTALL = wxNewId();
const long LayerSelectDialog::ID_MCU_SELECTNONE = wxNewId();
const long LayerSelectDialog::ID_MCU_SELECTPOPULATED = wxNewId();

BEGIN_EVENT_TABLE(LayerSelectDialog,wxDialog)
//(*EventTable(LayerSelectDialog)
//*)
BEGIN_EVENT_TABLE(LayerSelectDialog, wxDialog)
//(*EventTable(LayerSelectDialog)
//*)
END_EVENT_TABLE()

LayerSelectDialog::LayerSelectDialog(wxWindow* parent, int startLayer, int endLayer, std::string layersSelected, std::vector<int> layerWithEffect, wxWindowID id,const wxPoint& pos,const wxSize& size):
_layerWithEffect(layerWithEffect)
{
//(*Initialize(LayerSelectDialog)
wxFlexGridSizer* FlexGridSizer1;
wxFlexGridSizer* FlexGridSizer2;

Create(parent, id, _("Choose canvas layers ..."), wxDefaultPosition, wxDefaultSize, wxCAPTION|wxRESIZE_BORDER|wxMAXIMIZE_BOX, _T("id"));
SetClientSize(wxDefaultSize);
Move(wxDefaultPosition);
FlexGridSizer1 = new wxFlexGridSizer(0, 1, 0, 0);
FlexGridSizer1->AddGrowableCol(0);
FlexGridSizer1->AddGrowableRow(0);
CheckListBox_Layers = new wxCheckListBox(this, ID_CHECKLISTBOX1, wxDefaultPosition, wxSize(-1,300), 0, 0, 0, wxDefaultValidator, _T("ID_CHECKLISTBOX1"));
FlexGridSizer1->Add(CheckListBox_Layers, 1, wxALL|wxEXPAND, 5);
FlexGridSizer2 = new wxFlexGridSizer(0, 3, 0, 0);
Button_Ok = new wxButton(this, ID_BUTTON1, _("Ok"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
Button_Ok->SetDefault();
FlexGridSizer2->Add(Button_Ok, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
Button_Cancel = new wxButton(this, ID_BUTTON2, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON2"));
FlexGridSizer2->Add(Button_Cancel, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
FlexGridSizer1->Add(FlexGridSizer2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
SetSizer(FlexGridSizer1);
FlexGridSizer1->Fit(this);
FlexGridSizer1->SetSizeHints(this);

Connect(ID_CHECKLISTBOX1,wxEVT_COMMAND_CHECKLISTBOX_TOGGLED,(wxObjectEventFunction)&LayerSelectDialog::OnCheckListBox_LayersToggled);
Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&LayerSelectDialog::OnButton_OkClick);
Connect(ID_BUTTON2,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&LayerSelectDialog::OnButton_CancelClick);
//*)

Connect(ID_CHECKLISTBOX1, wxEVT_CONTEXT_MENU, (wxObjectEventFunction)&LayerSelectDialog::OnListRClick);
LayerSelectDialog::LayerSelectDialog(wxWindow* parent, int startLayer, int endLayer, bool blendLayer, const std::string &layersSelected,
const std::vector<int> &layerWithEffect, wxWindowID id, const wxPoint& pos, const wxSize& size) :
_layerWithEffect(layerWithEffect), _blending(blendLayer) {
//(*Initialize(LayerSelectDialog)
wxFlexGridSizer* FlexGridSizer1;
wxFlexGridSizer* FlexGridSizer2;

Create(parent, id, _("Choose canvas layers ..."), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxRESIZE_BORDER | wxMAXIMIZE_BOX, _T("id"));
SetClientSize(wxDefaultSize);
Move(wxDefaultPosition);
FlexGridSizer1 = new wxFlexGridSizer(0, 1, 0, 0);
FlexGridSizer1->AddGrowableCol(0);
FlexGridSizer1->AddGrowableRow(0);
CheckListBox_Layers = new wxCheckListBox(this, ID_CHECKLISTBOX1, wxDefaultPosition, wxSize(-1, 300), 0, 0, 0, wxDefaultValidator, _T("ID_CHECKLISTBOX1"));
FlexGridSizer1->Add(CheckListBox_Layers, 1, wxALL | wxEXPAND, 5);
FlexGridSizer2 = new wxFlexGridSizer(0, 3, 0, 0);
Button_Ok = new wxButton(this, ID_BUTTON1, _("Ok"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
Button_Ok->SetDefault();
FlexGridSizer2->Add(Button_Ok, 1, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5);
Button_Cancel = new wxButton(this, ID_BUTTON2, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON2"));
FlexGridSizer2->Add(Button_Cancel, 1, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5);
FlexGridSizer1->Add(FlexGridSizer2, 1, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5);
SetSizer(FlexGridSizer1);
FlexGridSizer1->Fit(this);
FlexGridSizer1->SetSizeHints(this);

Connect(ID_CHECKLISTBOX1, wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, (wxObjectEventFunction)&LayerSelectDialog::OnCheckListBox_LayersToggled);
Connect(ID_BUTTON1, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&LayerSelectDialog::OnButton_OkClick);
Connect(ID_BUTTON2, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&LayerSelectDialog::OnButton_CancelClick);
//*)

Connect(ID_CHECKLISTBOX1, wxEVT_CONTEXT_MENU, (wxObjectEventFunction)&LayerSelectDialog::OnListRClick);

_start = startLayer;

for (int i = startLayer; i <= endLayer; i++)
{
for (int i = startLayer; i <= endLayer; i++) {
CheckListBox_Layers->Append(wxString::Format("Layer %d", i));
}

if (layersSelected == "")
{
SelectAllLayers();
if (_blending) {
CheckListBox_Layers->Append("Model Blending");
}
else
{
if (layersSelected == "") {
SelectAllLayers(false);
} else {
wxArrayString layers = wxSplit(layersSelected, '|');
for (const auto& it : layers)
{
int l = wxAtoi(it);
if (l < (int)CheckListBox_Layers->GetCount())
{
for (const auto& it : layers) {
int l = 99999;
if (it == "Blend" && _blending) {
l = CheckListBox_Layers->GetCount() - 1;
} else {
l = wxAtoi(it);
}
if (l < (int)CheckListBox_Layers->GetCount()) {
CheckListBox_Layers->Check(l);
}
}
}

SetEscapeId(Button_Cancel->GetId());

ValidateWindow();
}

LayerSelectDialog::~LayerSelectDialog()
{
//(*Destroy(LayerSelectDialog)
//*)
LayerSelectDialog::~LayerSelectDialog() {
//(*Destroy(LayerSelectDialog)
//*)
}

std::string LayerSelectDialog::GetSelectedLayers() const
{
std::string LayerSelectDialog::GetSelectedLayers() const {
std::string res;
wxArrayInt items;
CheckListBox_Layers->GetCheckedItems(items);
for (auto it = items.begin(); it != items.end(); ++it)
{
if (res != "") res += "|";
res = res + wxString::Format("%d", *it).ToStdString();
for (auto it = items.begin(); it != items.end(); ++it) {
if (res != "")
res += "|";
std::string s = std::to_string(*it);
if (_blending && (*it == CheckListBox_Layers->GetCount() - 1)) {
s = "Blend";
}
res += s;
}

return res;
}

void LayerSelectDialog::SelectAllLayers()
{
for (size_t i = 0; i < CheckListBox_Layers->GetCount(); i++)
{
CheckListBox_Layers->Check(i);
void LayerSelectDialog::SelectAllLayers(bool incBlendingLayer) {
for (size_t i = 0; i < CheckListBox_Layers->GetCount(); i++) {
if (_blending && (i == CheckListBox_Layers->GetCount() - 1)) {
if (incBlendingLayer) {
CheckListBox_Layers->Check(i);
}
} else {
CheckListBox_Layers->Check(i);
}
}
}


void LayerSelectDialog::OnButton_CancelClick(wxCommandEvent& event)
{
void LayerSelectDialog::OnButton_CancelClick(wxCommandEvent& event) {
EndDialog(wxID_CANCEL);
}

void LayerSelectDialog::OnButton_OkClick(wxCommandEvent& event)
{
void LayerSelectDialog::OnButton_OkClick(wxCommandEvent& event) {
EndDialog(wxID_OK);
}

void LayerSelectDialog::OnCheckListBox_LayersToggled(wxCommandEvent& event)
{
void LayerSelectDialog::OnCheckListBox_LayersToggled(wxCommandEvent& event) {
ValidateWindow();
}

void LayerSelectDialog::ValidateWindow()
{
void LayerSelectDialog::ValidateWindow() {
wxArrayInt items;
CheckListBox_Layers->GetCheckedItems(items);
if (items.Count() == 0)
{
if (items.Count() == 0) {
Button_Ok->Enable(false);
}
else
{
} else {
Button_Ok->Enable(true);
}
}

void LayerSelectDialog::OnListRClick(wxContextMenuEvent& event)
{
wxMenu mnu;
mnu.Append(ID_MCU_SELECTALL, "Select All");
mnu.Append(ID_MCU_SELECTNONE, "Deselect All");
mnu.Append(ID_MCU_SELECTPOPULATED, "Select Layers With Effects");
void LayerSelectDialog::OnListRClick(wxContextMenuEvent& event) {
wxMenu mnu;
mnu.Append(ID_MCU_SELECTALL, "Select All");
mnu.Append(ID_MCU_SELECTNONE, "Deselect All");
mnu.Append(ID_MCU_SELECTPOPULATED, "Select Layers With Effects");

mnu.Connect(wxEVT_MENU, (wxObjectEventFunction)&LayerSelectDialog::OnPopup, nullptr, this);
PopupMenu(&mnu);
mnu.Connect(wxEVT_MENU, (wxObjectEventFunction)&LayerSelectDialog::OnPopup, nullptr, this);
PopupMenu(&mnu);
}

void LayerSelectDialog::OnPopup(wxCommandEvent& event)
{
if (event.GetId() == ID_MCU_SELECTALL)
{
SelectAllLayers();
}
else if (event.GetId() == ID_MCU_SELECTNONE)
{
DeselectAllLayers();
}
else if (event.GetId() == ID_MCU_SELECTPOPULATED)
{
SelectLayersWithEffects();
}
void LayerSelectDialog::OnPopup(wxCommandEvent& event) {
if (event.GetId() == ID_MCU_SELECTALL) {
SelectAllLayers();
} else if (event.GetId() == ID_MCU_SELECTNONE) {
DeselectAllLayers();
} else if (event.GetId() == ID_MCU_SELECTPOPULATED) {
SelectLayersWithEffects();
}
}

void LayerSelectDialog::DeselectAllLayers()
{
for (size_t i = 0; i < CheckListBox_Layers->GetCount(); i++)
{
CheckListBox_Layers->Check(i, false);
}
void LayerSelectDialog::DeselectAllLayers() {
for (size_t i = 0; i < CheckListBox_Layers->GetCount(); i++) {
CheckListBox_Layers->Check(i, false);
}
}

void LayerSelectDialog::SelectLayersWithEffects()
{
for (size_t i = 0; i < CheckListBox_Layers->GetCount(); i++)
{
int layer = _start + i - 1;//zero based index
if (std::find(_layerWithEffect.begin(), _layerWithEffect.end(), layer) != _layerWithEffect.end())
{
CheckListBox_Layers->Check(i);
}
else
{
CheckListBox_Layers->Check(i, false);
}
}
void LayerSelectDialog::SelectLayersWithEffects() {
for (size_t i = 0; i < CheckListBox_Layers->GetCount(); i++) {
int layer = _start + i - 1; // zero based index
if (std::find(_layerWithEffect.begin(), _layerWithEffect.end(), layer) != _layerWithEffect.end()) {
CheckListBox_Layers->Check(i);
} else {
CheckListBox_Layers->Check(i, false);
}
}
}
5 changes: 3 additions & 2 deletions xLights/LayerSelectDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@
class LayerSelectDialog: public wxDialog
{
int _start;
bool _blending;
std::vector<int> _layerWithEffect;
void ValidateWindow();

public:

LayerSelectDialog(wxWindow* parent, int startLayer, int endLayer, std::string layersSelected, std::vector<int> layerWithEffect, wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize);
LayerSelectDialog(wxWindow* parent, int startLayer, int endLayer, bool blendLayer, const std::string &layersSelected, const std::vector<int> &layerWithEffect, wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize);
virtual ~LayerSelectDialog();
void SelectLayer(wxString layer);
std::string GetSelectedLayers() const;
void SelectAllLayers();
void SelectAllLayers(bool incBlendingLayer = false);

//(*Declarations(LayerSelectDialog)
wxButton* Button_Cancel;
Expand Down
15 changes: 13 additions & 2 deletions xLights/Render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -655,14 +655,20 @@ class RenderJob: public Job, public NextRenderer {
maybeWaitForFrame(frame);

auto vl = info.validLayers;
bool doBlendLayer = false;
if (info.settingsMaps[layer].Get("LayersSelected", "") != "") {
// remove from valid layers any layers we dont need to include
wxArrayString ls = wxSplit(info.settingsMaps[layer].Get("LayersSelected", ""), '|');
std::vector<std::string> ls;
Split(info.settingsMaps[layer].Get("LayersSelected", ""), '|', ls);
if (!ls.empty() && ls.back() == "Blend") {
doBlendLayer = true;
ls.pop_back();
}
for (int i = layer + 1; i < vl.size(); i++) {
if (vl[i]) {
bool found = false;
for (auto it = ls.begin(); !found && it != ls.end(); ++it) {
if (wxAtoi(*it) + layer + 1 == i) {
if (std::atoi((*it).c_str()) + layer + 1 == i) {
found = true;
}
}
Expand All @@ -671,6 +677,11 @@ class RenderJob: public Job, public NextRenderer {
}
}
}
if (doBlendLayer) {
buffer->SetColors(numLayers, &((*seqData)[frame][0]));
vl[numLayers] = true;
blend = false;
}
}

// preload the buffer with the output from the lower layers
Expand Down
2 changes: 1 addition & 1 deletion xLights/TimingPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ void TimingPanel::OnCheckBox_ResetTimingPanelClick(wxCommandEvent& event)
void TimingPanel::OnButton_LayersClick(wxCommandEvent& event)
{
wxASSERT(_startLayer <= _endLayer);
LayerSelectDialog dlg(this, _startLayer, _endLayer, _layersSelected, _layerWithEffect);
LayerSelectDialog dlg(this, _startLayer, _endLayer, _modelBlending, _layersSelected, _layerWithEffect);
OptimiseDialogPosition(&dlg);

if (dlg.ShowModal() == wxID_OK) {
Expand Down
3 changes: 2 additions & 1 deletion xLights/TimingPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@ class TimingPanel: public xlEffectPanel
std::string _layersSelected;
int _startLayer;
int _endLayer;
bool _modelBlending;
std::vector<int> _layerWithEffect;

public:

TimingPanel(wxWindow* parent,wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize);
virtual ~TimingPanel();

void SetLayersBelow(int start, int end, std::vector<int> effects) { _startLayer = start; _endLayer = end; _layerWithEffect = effects; }
void SetLayersBelow(int start, int end, std::vector<int> effects, bool blending) { _startLayer = start; _endLayer = end; _layerWithEffect = effects; _modelBlending = blending;}
wxString GetTimingString();
void SetDefaultControls(const Model *model, bool optionbased = false);
void ValidateWindow();
Expand Down
7 changes: 3 additions & 4 deletions xLights/sequencer/tabSequencer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1115,14 +1115,13 @@ void xLightsFrame::EffectChanged(wxCommandEvent& event)
// flags something has changed in an effect but does not send the effect
void xLightsFrame::EffectUpdated(wxCommandEvent& event)
{
if (selectedEffect != nullptr)
{
if (selectedEffect != nullptr) {
// For canvas mode the timing panel needs to know how many layers are under this effect
int layers = selectedEffect->GetParentEffectLayer()->GetParentElement()->GetEffectLayerCount();
int start = selectedEffect->GetParentEffectLayer()->GetLayerNumber() + 1;
std::vector<int> effectLayers = selectedEffect->GetParentEffectLayer()->GetParentElement()->GetLayersWithEffectsByTime(selectedEffect->GetStartTimeMS(), selectedEffect->GetEndTimeMS());
if (start > layers) start = -1;
timingPanel->SetLayersBelow(start, layers, effectLayers);
timingPanel->SetLayersBelow(start, layers, effectLayers, _sequenceElements.SupportsModelBlending());
}
}

Expand Down Expand Up @@ -1209,7 +1208,7 @@ void xLightsFrame::SelectedEffectChanged(SelectedEffectChangedEvent& event)
int start = effect->GetParentEffectLayer()->GetLayerNumber() + 1;
std::vector<int> effectLayers = effect->GetParentEffectLayer()->GetParentElement()->GetLayersWithEffectsByTime(effect->GetStartTimeMS(), effect->GetEndTimeMS());
if (start > layers) start = -1;
timingPanel->SetLayersBelow(start, layers, effectLayers);
timingPanel->SetLayersBelow(start, layers, effectLayers, _sequenceElements.SupportsModelBlending());

bool resetStrings = false;
if ("Random" == effect->GetEffectName()) {
Expand Down

0 comments on commit d0e3335

Please sign in to comment.