Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enh] Randomization options for new "Metronome w/Tags" Dialog #4858

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 57 additions & 6 deletions xLights/MetronomeLabelDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@
//*)

//(*IdInit(MetronomeLabelDialog)
const long MetronomeLabelDialog::ID_STATICTEXT_DIALOGTEXT = wxNewId();
const long MetronomeLabelDialog::ID_STATICTEXT_TIMING = wxNewId();
const long MetronomeLabelDialog::ID_SPINCTRL_TIMING = wxNewId();
const long MetronomeLabelDialog::ID_STATICTEXT_REPEATING = wxNewId();
const long MetronomeLabelDialog::ID_SPINCTRL_REPEATING = wxNewId();
const wxWindowID MetronomeLabelDialog::ID_STATICTEXT_DIALOGTEXT = wxNewId();
const wxWindowID MetronomeLabelDialog::ID_STATICTEXT_TIMING = wxNewId();
const wxWindowID MetronomeLabelDialog::ID_SPINCTRL_TIMING = wxNewId();
const wxWindowID MetronomeLabelDialog::ID_STATICTEXT_REPEATING = wxNewId();
const wxWindowID MetronomeLabelDialog::ID_SPINCTRL_REPEATING = wxNewId();
const wxWindowID MetronomeLabelDialog::ID_CHECKBOX_RANDOMTIMING = wxNewId();
const wxWindowID MetronomeLabelDialog::ID_STATICTEXT_MINTIMING = wxNewId();
const wxWindowID MetronomeLabelDialog::ID_SPINCTRL1 = wxNewId();
const wxWindowID MetronomeLabelDialog::ID_CHECKBOX_RANDOMTAGS = wxNewId();
//*)

BEGIN_EVENT_TABLE(MetronomeLabelDialog,wxDialog)
Expand All @@ -33,6 +37,7 @@ MetronomeLabelDialog::MetronomeLabelDialog(int base_timing, wxWindow* parent,wxW
{
//(*Initialize(MetronomeLabelDialog)
wxFlexGridSizer* FlexGridSizer1;
wxFlexGridSizer* FlexGridSizer3;
wxGridSizer* GridSizer1;
wxStdDialogButtonSizer* StdDialogButtonSizer1;

Expand All @@ -54,14 +59,34 @@ MetronomeLabelDialog::MetronomeLabelDialog(int base_timing, wxWindow* parent,wxW
SpinCtrlRepeating->SetValue(_T("4"));
GridSizer1->Add(SpinCtrlRepeating, 1, wxALL|wxEXPAND, 5);
FlexGridSizer1->Add(GridSizer1, 1, wxALL|wxEXPAND, 5);
FlexGridSizer3 = new wxFlexGridSizer(0, 4, 0, 0);
FlexGridSizer3->AddGrowableCol(1);
FlexGridSizer3->AddGrowableCol(2);
CheckBox_RandomTiming = new wxCheckBox(this, ID_CHECKBOX_RANDOMTIMING, _("Random Timing"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHECKBOX_RANDOMTIMING"));
CheckBox_RandomTiming->SetValue(false);
CheckBox_RandomTiming->SetMinSize(wxSize(-1,-1));
FlexGridSizer3->Add(CheckBox_RandomTiming, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
StaticText_MinTiming = new wxStaticText(this, ID_STATICTEXT_MINTIMING, _("Min Timing"), wxPoint(-1,-1), wxDefaultSize, 0, _T("ID_STATICTEXT_MINTIMING"));
FlexGridSizer3->Add(StaticText_MinTiming, 1, wxTOP|wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 1);
SpinCtrl_MinTiming = new wxSpinCtrl(this, ID_SPINCTRL1, _T("1"), wxDefaultPosition, wxDefaultSize, 0, 1, 100, 1, _T("ID_SPINCTRL1"));
SpinCtrl_MinTiming->SetValue(_T("1"));
SpinCtrl_MinTiming->Disable();
FlexGridSizer3->Add(SpinCtrl_MinTiming, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
CheckBox_RandomTagsEnabled = new wxCheckBox(this, ID_CHECKBOX_RANDOMTAGS, _("Random Tags"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHECKBOX_RANDOMTAGS"));
CheckBox_RandomTagsEnabled->SetValue(false);
FlexGridSizer3->Add(CheckBox_RandomTagsEnabled, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
FlexGridSizer1->Add(FlexGridSizer3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
StdDialogButtonSizer1 = new wxStdDialogButtonSizer();
StdDialogButtonSizer1->AddButton(new wxButton(this, wxID_OK, wxEmptyString));
StdDialogButtonSizer1->AddButton(new wxButton(this, wxID_CANCEL, wxEmptyString));
StdDialogButtonSizer1->Realize();
FlexGridSizer1->Add(StdDialogButtonSizer1, 1, wxALL|wxEXPAND, 5);
SetSizer(FlexGridSizer1);
FlexGridSizer1->Fit(this);
FlexGridSizer1->SetSizeHints(this);

Connect(ID_SPINCTRL_TIMING, wxEVT_COMMAND_SPINCTRL_UPDATED, (wxObjectEventFunction)&MetronomeLabelDialog::OnSpinCtrlTimingChange);
Connect(ID_CHECKBOX_RANDOMTIMING, wxEVT_COMMAND_CHECKBOX_CLICKED, (wxObjectEventFunction)&MetronomeLabelDialog::OnCheckBox_RandomTimingClick);
Connect(ID_CHECKBOX_RANDOMTAGS, wxEVT_COMMAND_CHECKBOX_CLICKED, (wxObjectEventFunction)&MetronomeLabelDialog::OnCheckBox_RandomTagsEnabledClick);
//*)
SpinCtrlTiming->SetRange(base_timing, SpinCtrlTiming->GetMax());
SpinCtrlTiming->SetValue( 10 * base_timing);
Expand All @@ -75,3 +100,29 @@ MetronomeLabelDialog::~MetronomeLabelDialog()
//*)
}


void MetronomeLabelDialog::OnCheckBox_RandomTimingClick(wxCommandEvent& event)
{
//Set the spinctrl enable disabled based on the checkbox

if( CheckBox_RandomTiming->IsChecked() ) {
SpinCtrl_MinTiming->Enable();
SpinCtrl_MinTiming->SetRange(1, SpinCtrlTiming->GetValue());
}
else
SpinCtrl_MinTiming->Disable();
}

void MetronomeLabelDialog::OnCheckBox_RandomTagsEnabledClick(wxCommandEvent& event)
{
}

void MetronomeLabelDialog::OnSpinCtrlTimingChange(wxSpinEvent& event)
{
if( CheckBox_RandomTiming->IsChecked() ) {
SpinCtrl_MinTiming->SetRange(1, SpinCtrlTiming->GetValue());
if( SpinCtrl_MinTiming->GetValue() > SpinCtrlTiming->GetValue() )
SpinCtrl_MinTiming->SetValue(SpinCtrlTiming->GetValue());

}
}
27 changes: 21 additions & 6 deletions xLights/MetronomeLabelDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
**************************************************************/

//(*Headers(MetronomeLabelDialog)
#include <wx/checkbox.h>
#include <wx/dialog.h>
#include <wx/sizer.h>
#include <wx/spinctrl.h>
Expand All @@ -25,29 +26,43 @@ class MetronomeLabelDialog: public wxDialog
virtual ~MetronomeLabelDialog();

//(*Declarations(MetronomeLabelDialog)
wxCheckBox* CheckBox_RandomTagsEnabled;
wxCheckBox* CheckBox_RandomTiming;
wxSpinCtrl* SpinCtrlRepeating;
wxSpinCtrl* SpinCtrlTiming;
wxSpinCtrl* SpinCtrl_MinTiming;
wxStaticText* StaticTextDialogText;
wxStaticText* StaticTextRepeating;
wxStaticText* StaticTextTiming;
wxStaticText* StaticText_MinTiming;
//*)

[[nodiscard]] int GetTiming() const { return SpinCtrlTiming->GetValue(); }
[[nodiscard]] int GetTagCount() const { return SpinCtrlRepeating->GetValue(); }
[[nodiscard]] int GetTagCount() const { return SpinCtrlRepeating->GetValue(); }
[[nodiscard]] int GetMinRandomTiming() const { return CheckBox_RandomTiming->IsChecked() ? SpinCtrl_MinTiming->GetValue() : -1; }
[[nodiscard]] bool IsRandomTags() const { return CheckBox_RandomTagsEnabled->IsChecked(); }
[[nodiscard]] bool IsRandomTiming() const { return CheckBox_RandomTiming->IsChecked(); }

protected:

//(*Identifiers(MetronomeLabelDialog)
static const long ID_STATICTEXT_DIALOGTEXT;
static const long ID_STATICTEXT_TIMING;
static const long ID_SPINCTRL_TIMING;
static const long ID_STATICTEXT_REPEATING;
static const long ID_SPINCTRL_REPEATING;
static const wxWindowID ID_STATICTEXT_DIALOGTEXT;
static const wxWindowID ID_STATICTEXT_TIMING;
static const wxWindowID ID_SPINCTRL_TIMING;
static const wxWindowID ID_STATICTEXT_REPEATING;
static const wxWindowID ID_SPINCTRL_REPEATING;
static const wxWindowID ID_CHECKBOX_RANDOMTIMING;
static const wxWindowID ID_STATICTEXT_MINTIMING;
static const wxWindowID ID_SPINCTRL1;
static const wxWindowID ID_CHECKBOX_RANDOMTAGS;
//*)

private:

//(*Handlers(MetronomeLabelDialog)
void OnCheckBox_RandomTimingClick(wxCommandEvent& event);
void OnCheckBox_RandomTagsEnabledClick(wxCommandEvent& event);
void OnSpinCtrlTimingChange(wxSpinEvent& event);
//*)

DECLARE_EVENT_TABLE()
Expand Down
15 changes: 13 additions & 2 deletions xLights/SeqSettingsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1079,10 +1079,21 @@ void SeqSettingsDialog::OnButton_Xml_New_TimingClick(wxCommandEvent& event)
wxString msg = wxString::Format("Timing adjusted to match sequence timing %dms -> %dms", dlg.GetTiming(), ms);
wxMessageBox(msg);
}
wxString ttn = wxString::Format("%dms Metronome %d Tag", ms, dlg.GetTagCount());
wxString ttn = wxString::Format("%s%dms Metronome %d Tag", dlg.IsRandomTiming() || dlg.IsRandomTags() ? "Random " : "", ms, dlg.GetTagCount());
//Handle new random tag names
if( (dlg.IsRandomTiming() || dlg.IsRandomTags()) && xml_file->TimingAlreadyExists(ttn.ToStdString(), xLightsParent) ) {
int copyNum = 1;
wxString new_ttn = ttn;
do {
wxString copyString = wxString::Format(" (%d)", copyNum);
new_ttn = ttn + copyString;
copyNum++;
} while (xml_file->TimingAlreadyExists(new_ttn.ToStdString(), xLightsParent));
ttn = new_ttn;
}
if (!xml_file->TimingAlreadyExists(ttn.ToStdString(), xLightsParent))
{
xml_file->AddMetronomeLabelTimingSection(ttn.ToStdString(), ms, dlg.GetTagCount(), xLightsParent);
xml_file->AddMetronomeLabelTimingSection(ttn.ToStdString(), ms, dlg.GetTagCount(), xLightsParent, dlg.GetMinRandomTiming(), dlg.IsRandomTags());
AddTimingCell(ttn);
}
}
Expand Down
16 changes: 14 additions & 2 deletions xLights/sequencer/RowHeading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -787,10 +787,22 @@ void RowHeading::OnLayerPopup(wxCommandEvent& event)
{
DisplayWarning(wxString::Format("Timing adjusted to match sequence timing %dms -> %dms", dlg.GetTiming(), ms).ToStdString());
}
wxString ttn = wxString::Format("%dms Metronome %d Tag", ms, dlg.GetTagCount());
wxString ttn = wxString::Format("%s%dms Metronome %d Tag", dlg.IsRandomTiming() || dlg.IsRandomTags() ? "Random " : "", ms, dlg.GetTagCount());
//Handle new random tag names
if( (dlg.IsRandomTiming() || dlg.IsRandomTags()) && xml_file->TimingAlreadyExists(ttn.ToStdString(), mSequenceElements->GetXLightsFrame()) ) {
int copyNum = 1;
wxString new_ttn = ttn;
do {
wxString copyString = wxString::Format(" (%d)", copyNum);
new_ttn = ttn + copyString;
copyNum++;
} while (xml_file->TimingAlreadyExists(new_ttn.ToStdString(), mSequenceElements->GetXLightsFrame()));
ttn = new_ttn;
}

if (!xml_file->TimingAlreadyExists(ttn.ToStdString(), mSequenceElements->GetXLightsFrame()))
{
xml_file->AddMetronomeLabelTimingSection(ttn.ToStdString(), ms, dlg.GetTagCount(), mSequenceElements->GetXLightsFrame());
xml_file->AddMetronomeLabelTimingSection(ttn.ToStdString(), ms, dlg.GetTagCount(), mSequenceElements->GetXLightsFrame(), dlg.GetMinRandomTiming(), dlg.IsRandomTags());
timing_added = true;
}
}
Expand Down
47 changes: 47 additions & 0 deletions xLights/wxsmith/MetronomeLabelDialog.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<value>50</value>
<min>1</min>
<max>60000</max>
<handler function="OnSpinCtrlTimingChange" entry="EVT_SPINCTRL" />
</object>
<flag>wxALL|wxEXPAND</flag>
<border>5</border>
Expand Down Expand Up @@ -58,6 +59,52 @@
<border>5</border>
<option>1</option>
</object>
<object class="sizeritem">
<object class="wxFlexGridSizer" variable="FlexGridSizer3" member="no">
<cols>4</cols>
<growablecols>1,2</growablecols>
<object class="sizeritem">
<object class="wxCheckBox" name="ID_CHECKBOX_RANDOMTIMING" variable="CheckBox_RandomTiming" member="yes">
<label>Random Timing</label>
<minsize>-1,-1</minsize>
<handler function="OnCheckBox_RandomTimingClick" entry="EVT_CHECKBOX" />
</object>
<flag>wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL</flag>
<border>5</border>
<option>1</option>
</object>
<object class="sizeritem">
<object class="wxStaticText" name="ID_STATICTEXT_MINTIMING" variable="StaticText_MinTiming" member="yes">
<label>Min Timing</label>
<pos>-1,-1</pos>
</object>
<flag>wxTOP|wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL</flag>
<border>1</border>
<option>1</option>
</object>
<object class="sizeritem">
<object class="wxSpinCtrl" name="ID_SPINCTRL1" variable="SpinCtrl_MinTiming" member="yes">
<value>1</value>
<min>1</min>
<enabled>0</enabled>
</object>
<flag>wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL</flag>
<border>5</border>
<option>1</option>
</object>
<object class="sizeritem">
<object class="wxCheckBox" name="ID_CHECKBOX_RANDOMTAGS" variable="CheckBox_RandomTagsEnabled" member="yes">
<label>Random Tags</label>
<handler function="OnCheckBox_RandomTagsEnabledClick" entry="EVT_CHECKBOX" />
</object>
<flag>wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL</flag>
<border>5</border>
<option>1</option>
</object>
</object>
<flag>wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL</flag>
<option>1</option>
</object>
<object class="sizeritem">
<object class="wxStdDialogButtonSizer" variable="StdDialogButtonSizer1" member="no">
<object class="button">
Expand Down
15 changes: 12 additions & 3 deletions xLights/xLightsXmlFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3060,7 +3060,7 @@ void xLightsXmlFile::AddFixedTimingSection(const std::string& interval_name, xLi
AddChildXmlNode(node, "EffectLayer");
}

void xLightsXmlFile::AddMetronomeLabelTimingSection(const std::string& interval_name, int interval, int count, xLightsFrame* xLightsParent)
void xLightsXmlFile::AddMetronomeLabelTimingSection(const std::string& interval_name, int _interval, int count, xLightsFrame* xLightsParent, int minForRandomRange, bool randomLabels)
{
AddTimingDisplayElement(interval_name, "1", "0");
wxXmlNode* node;
Expand All @@ -3072,20 +3072,29 @@ void xLightsXmlFile::AddMetronomeLabelTimingSection(const std::string& interval_
int time {0};
int id {0};
int end_time = GetSequenceDurationMS();
int lastRandomState = -1;
while (time < end_time)
{
int interval = minForRandomRange == -1 ? _interval : intRand(minForRandomRange, _interval);
int next_time = (time + interval <= end_time) ? time + interval : end_time;
int startTime = TimeLine::RoundToMultipleOfPeriod(time, GetFrequency());
int endTime = TimeLine::RoundToMultipleOfPeriod(next_time, GetFrequency());
effectLayer->AddEffect(0, std::to_string(id + 1), "", "", startTime, endTime, EFFECT_NOT_SELECTED, false);
if( randomLabels ) {
do {
id = intRand(1, count);
} while( id == lastRandomState);
lastRandomState = id;
}
effectLayer->AddEffect(0, std::to_string(randomLabels ? id : id + 1), "", "", startTime, endTime, EFFECT_NOT_SELECTED, false);
time += interval;
id++;
if (count != 0) {
id %= count;
}
}
}
node = AddFixedTiming(interval_name, string_format("%d", interval));

node = AddFixedTiming(interval_name, string_format("%d", _interval));


AddChildXmlNode(node, "EffectLayer");
Expand Down
2 changes: 1 addition & 1 deletion xLights/xLightsXmlFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class xLightsXmlFile : public wxFileName
void AddNewTimingSection(const std::string& interval_name, xLightsFrame* xLightsParent, std::vector<int>& starts,
std::vector<int>& ends, std::vector<std::string>& labels);
void AddFixedTimingSection(const std::string& interval_name, xLightsFrame* xLightsParent);
void AddMetronomeLabelTimingSection(const std::string& interval_name, int interval, int count, xLightsFrame* xLightsParent);
void AddMetronomeLabelTimingSection(const std::string& interval_name, int interval, int count, xLightsFrame* xLightsParent, int minForRandomRange = -1, bool randomTags = false);
void DeleteTimingSection(const std::string& section);
void SetTimingSectionName(const std::string& section, const std::string& name);
bool TimingAlreadyExists(const std::string& section, xLightsFrame* xLightsParent);
Expand Down
Loading