diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_Add_Slaves_Dialog.cpp b/xLights/controllers/EasyLights_Utils/EasyLights_Add_Slaves_Dialog.cpp new file mode 100644 index 0000000000..6b72f03318 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_Add_Slaves_Dialog.cpp @@ -0,0 +1,641 @@ + + +#include +#include +#include +#include + +#include +#include + + +#include "../../models/Model.h" +#include "../../outputs/OutputManager.h" +#include "../../outputs/Output.h" +#include "../../models/ModelManager.h" + + +#include +#include "UtilFunctions.h" +#include + +#include + +#include "../../models/Model.h" +#include "../../outputs/OutputManager.h" +#include "../../outputs/Output.h" +#include "../../models/ModelManager.h" + +#include "EasyLights_Add_Slaves_Dialog.h" +#include "EasyLights_Identify_Dialog.h" +#include "../EasyLights.h" +#include "EasyLights_Data.h" +#include + + + +//(*IdInit(EasyLights_Add_Slaves_Dialog) +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT1 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_LISTCTRL1 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT2 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT3 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL1 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT4 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL2 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT5 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL3 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT6 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL4 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT7 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL5 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT16 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL12 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT8 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT9 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL6 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT12 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL8 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT14 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL10 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_BUTTON1 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_BUTTON2 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT10 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT11 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL7 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT13 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL9 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_STATICTEXT15 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_TEXTCTRL11 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_BUTTON3 = wxNewId(); +const long EasyLights_Add_Slaves_Dialog::ID_BUTTON4 = wxNewId(); +//*) + +BEGIN_EVENT_TABLE(EasyLights_Add_Slaves_Dialog,wxDialog) + //(*EventTable(EasyLights_Add_Slaves_Dialog) + EVT_INIT_DIALOG(EasyLights_Add_Slaves_Dialog::InitDialog) + //*) +END_EVENT_TABLE() + +EasyLights_Add_Slaves_Dialog::EasyLights_Add_Slaves_Dialog(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) +{ + Selected_EndPoint = 0; + Dirty = 0; + EL_EndPoint = 0; + Channels_Avail_To_Slave = 0; + S1_EndPoint = 0; + S2_EndPoint = 0; + S1_Selected_EndPoint_Index = 0; + S2_Selected_EndPoint_Index = 0; + + + + + BuildContent(parent,id,pos,size); + + + wxListItem itemCol; + + itemCol.SetText(wxT("Name")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(0, itemCol); + ListCtrl1->SetColumnWidth(0, 200); + + itemCol.SetText(wxT("IP")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(1, itemCol); + ListCtrl1->SetColumnWidth(1, 100); + + itemCol.SetText(wxT("Pixels")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(2, itemCol); + ListCtrl1->SetColumnWidth(2, 100); + + + Connect(ID_BUTTON1, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Add_Slaves_Dialog::OnButton_S1_Add); + Connect(ID_BUTTON2, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Add_Slaves_Dialog::OnButton_S1_Remove); + Connect(ID_BUTTON3, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Add_Slaves_Dialog::OnButton_S2_Add); + Connect(ID_BUTTON4, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Add_Slaves_Dialog::OnButton_S2_Remove); + + Connect(wxID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Add_Slaves_Dialog::OnButtonCloseClick); + Connect(wxID_ANY, wxEVT_CLOSE_WINDOW, (wxObjectEventFunction)&EasyLights_Add_Slaves_Dialog::OnButtonCloseClick); + + +} + +void EasyLights_Add_Slaves_Dialog::BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) +{ + //(*Initialize(EasyLights_Add_Slaves_Dialog) + wxFlexGridSizer* FlexGridSizer10; + wxFlexGridSizer* FlexGridSizer1; + wxFlexGridSizer* FlexGridSizer2; + wxFlexGridSizer* FlexGridSizer3; + wxFlexGridSizer* FlexGridSizer4; + wxFlexGridSizer* FlexGridSizer5; + wxFlexGridSizer* FlexGridSizer6; + wxFlexGridSizer* FlexGridSizer7; + wxFlexGridSizer* FlexGridSizer8; + wxFlexGridSizer* FlexGridSizer9; + + Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("wxID_ANY")); + FlexGridSizer1 = new wxFlexGridSizer(0, 1, 0, 0); + StaticText1 = new wxStaticText(this, ID_STATICTEXT1, _("E131 Controllers that May be Set as Slaves to the Selected EasyLights Controller"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1")); + FlexGridSizer1->Add(StaticText1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + ListCtrl1 = new wxListCtrl(this, ID_LISTCTRL1, wxDefaultPosition, wxSize(400,250), wxLC_REPORT|wxLC_SINGLE_SEL|wxVSCROLL, wxDefaultValidator, _T("ID_LISTCTRL1")); + FlexGridSizer1->Add(ListCtrl1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer2 = new wxFlexGridSizer(0, 3, 0, 0); + FlexGridSizer3 = new wxFlexGridSizer(0, 1, 0, 0); + StaticText2 = new wxStaticText(this, ID_STATICTEXT2, _("Selected EasyLights Controller"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2")); + FlexGridSizer3->Add(StaticText2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer5 = new wxFlexGridSizer(0, 2, 0, 0); + StaticText3 = new wxStaticText(this, ID_STATICTEXT3, _("IP Address"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT3")); + FlexGridSizer5->Add(StaticText3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl1 = new wxTextCtrl(this, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxSize(100,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL1")); + FlexGridSizer5->Add(TextCtrl1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText4 = new wxStaticText(this, ID_STATICTEXT4, _("Name"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT4")); + FlexGridSizer5->Add(StaticText4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl2 = new wxTextCtrl(this, ID_TEXTCTRL2, wxEmptyString, wxDefaultPosition, wxSize(200,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL2")); + FlexGridSizer5->Add(TextCtrl2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText5 = new wxStaticText(this, ID_STATICTEXT5, _("Model"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT5")); + FlexGridSizer5->Add(StaticText5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl3 = new wxTextCtrl(this, ID_TEXTCTRL3, wxEmptyString, wxDefaultPosition, wxSize(150,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL3")); + FlexGridSizer5->Add(TextCtrl3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText6 = new wxStaticText(this, ID_STATICTEXT6, _("Number of Pixels Used"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT6")); + FlexGridSizer5->Add(StaticText6, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl4 = new wxTextCtrl(this, ID_TEXTCTRL4, wxEmptyString, wxDefaultPosition, wxSize(100,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL4")); + FlexGridSizer5->Add(TextCtrl4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText7 = new wxStaticText(this, ID_STATICTEXT7, _("Pixels Available to Slaves"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT7")); + FlexGridSizer5->Add(StaticText7, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl5 = new wxTextCtrl(this, ID_TEXTCTRL5, wxEmptyString, wxDefaultPosition, wxSize(100,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL5")); + FlexGridSizer5->Add(TextCtrl5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText16 = new wxStaticText(this, ID_STATICTEXT16, _("Status"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT16")); + FlexGridSizer5->Add(StaticText16, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl12 = new wxTextCtrl(this, ID_TEXTCTRL12, wxEmptyString, wxDefaultPosition, wxSize(200,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL12")); + FlexGridSizer5->Add(TextCtrl12, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer3->Add(FlexGridSizer5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer2->Add(FlexGridSizer3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer4 = new wxFlexGridSizer(0, 1, 0, 0); + FlexGridSizer6 = new wxFlexGridSizer(0, 1, 0, 0); + StaticText8 = new wxStaticText(this, ID_STATICTEXT8, _("Attachment 1"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT8")); + FlexGridSizer6->Add(StaticText8, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer7 = new wxFlexGridSizer(0, 2, 0, 0); + StaticText9 = new wxStaticText(this, ID_STATICTEXT9, _("IP Address"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT9")); + FlexGridSizer7->Add(StaticText9, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl6 = new wxTextCtrl(this, ID_TEXTCTRL6, wxEmptyString, wxDefaultPosition, wxSize(100,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL6")); + FlexGridSizer7->Add(TextCtrl6, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText12 = new wxStaticText(this, ID_STATICTEXT12, _("Name"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT12")); + FlexGridSizer7->Add(StaticText12, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl8 = new wxTextCtrl(this, ID_TEXTCTRL8, wxEmptyString, wxDefaultPosition, wxSize(100,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL8")); + FlexGridSizer7->Add(TextCtrl8, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText14 = new wxStaticText(this, ID_STATICTEXT14, _("Pixels"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT14")); + FlexGridSizer7->Add(StaticText14, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl10 = new wxTextCtrl(this, ID_TEXTCTRL10, wxEmptyString, wxDefaultPosition, wxSize(100,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL10")); + FlexGridSizer7->Add(TextCtrl10, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer7->Add(-1,-1,1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer7->Add(-1,-1,1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button1 = new wxButton(this, ID_BUTTON1, _("Add Selected"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1")); + FlexGridSizer7->Add(Button1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button2 = new wxButton(this, ID_BUTTON2, _("Remove"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON2")); + FlexGridSizer7->Add(Button2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer6->Add(FlexGridSizer7, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer4->Add(FlexGridSizer6, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer2->Add(FlexGridSizer4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer8 = new wxFlexGridSizer(0, 3, 0, 0); + FlexGridSizer9 = new wxFlexGridSizer(0, 1, 0, 0); + StaticText10 = new wxStaticText(this, ID_STATICTEXT10, _("Attachment 2"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT10")); + FlexGridSizer9->Add(StaticText10, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer10 = new wxFlexGridSizer(0, 2, 0, 0); + StaticText11 = new wxStaticText(this, ID_STATICTEXT11, _("IP Address"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT11")); + FlexGridSizer10->Add(StaticText11, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl7 = new wxTextCtrl(this, ID_TEXTCTRL7, wxEmptyString, wxDefaultPosition, wxSize(100,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL7")); + FlexGridSizer10->Add(TextCtrl7, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText13 = new wxStaticText(this, ID_STATICTEXT13, _("Name"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT13")); + FlexGridSizer10->Add(StaticText13, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl9 = new wxTextCtrl(this, ID_TEXTCTRL9, wxEmptyString, wxDefaultPosition, wxSize(100,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL9")); + FlexGridSizer10->Add(TextCtrl9, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText15 = new wxStaticText(this, ID_STATICTEXT15, _("Pixels"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT15")); + FlexGridSizer10->Add(StaticText15, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl11 = new wxTextCtrl(this, ID_TEXTCTRL11, wxEmptyString, wxDefaultPosition, wxSize(100,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL11")); + FlexGridSizer10->Add(TextCtrl11, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer10->Add(-1,-1,1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer10->Add(-1,-1,1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button3 = new wxButton(this, ID_BUTTON3, _("Add Selected"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON3")); + FlexGridSizer10->Add(Button3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button4 = new wxButton(this, ID_BUTTON4, _("Remove"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON4")); + FlexGridSizer10->Add(Button4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer9->Add(FlexGridSizer10, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer8->Add(FlexGridSizer9, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer2->Add(FlexGridSizer8, 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); + //*) +} + +EasyLights_Add_Slaves_Dialog::~EasyLights_Add_Slaves_Dialog() +{ + //(*Destroy(EasyLights_Add_Slaves_Dialog) + //*) +} + +void EasyLights_Add_Slaves_Dialog::InitDialog(wxInitDialogEvent &WXUNUSED(event)) +{ + Load_S_List(0); + + TransferDataToWindow(); +} + + +void EasyLights_Add_Slaves_Dialog::Load_S_List(int Ignore_Slaves_Attached) +{ + wxString T; + int i = 0; + int ListIndex = 0; + + + + for(auto it = EL_Ptr->EL_EndPoints.begin(); it != EL_Ptr->EL_EndPoints.end(); ++it, i++) + { + if(((*it)->Model.size() == 0 || (*it)->Model == "Undefined") && (*it)->DDP_Network == 0) // no slave DDP + { + if(Ignore_Slaves_Attached || (*it)->Slave_Attached == 0) + { + T.Printf("%s", (*it)->Name); + ListCtrl1->InsertItem(ListIndex, T, -1); + ListCtrl1->SetItemData(ListIndex, i); + + T.Printf("%s", (*it)->IP); + ListCtrl1->SetItem(ListIndex, 1, T); + + T.Printf("%d", (*it)->Channels_Used / 3); + ListCtrl1->SetItem(ListIndex, 2, T); + + ListIndex++; + } + } + } +} + + + +bool EasyLights_Add_Slaves_Dialog::TransferDataToWindow() +{ + wxString T; + + wxColour CR(255, 150, 150); + wxColour CG(150, 255, 150); + + int V; + + Button1->Enable(true); + Button3->Enable(true); + + V = ELC_Status_To_Support_Slaves(EL_EndPoint); + if(V == ELC_Support_NO_Slaves) + { + Channels_Avail_To_Slave = 0; + Button1->Enable(false); + Button3->Enable(false); + } + else if(V == ELC_Support_One_Slave) + { + Channels_Avail_To_Slave = (510 * 16) / 3; + //if(EL_EndPoint->S1_IP.size() > 3) + // Button3->Enable(false); + //else if(EL_EndPoint->S2_IP.size() > 3) + // Button1->Enable(false); + } + else + Channels_Avail_To_Slave = (510 * 32) / 3; + + + + + + + T = EL_EndPoint->IP; + TextCtrl1->SetValue(T); + + T = EL_EndPoint->Name; + TextCtrl2->SetValue(T); + + T = EL_EndPoint->Model; + TextCtrl3->SetValue(T); + + + T = wxString::Format("%d", EL_EndPoint->Channels_Used / 3); + TextCtrl4->SetValue(T); + +// now check for any slaves + + if(EL_EndPoint->S1_IP.size() > 1) + { + S1_EndPoint = Find_EndPoint_By_IP(EL_EndPoint->S1_IP); + if(S1_EndPoint) + { + T = S1_EndPoint->IP; + TextCtrl6->SetValue(T); + + T = S1_EndPoint->Name; + TextCtrl8->SetValue(T); + + T = wxString::Format("%d", S1_EndPoint->Channels_Used / 3); + TextCtrl10->SetValue(T); + + } + } + + if(S1_EndPoint == 0) + { + T = ""; + TextCtrl6->SetValue(T); + TextCtrl8->SetValue(T); + TextCtrl10->SetValue(T); + } + + + if(EL_EndPoint->S2_IP.size() > 1) + { + S2_EndPoint = Find_EndPoint_By_IP(EL_EndPoint->S2_IP); + if(S2_EndPoint) + { + T = S2_EndPoint->IP; + TextCtrl7->SetValue(T); + + T = S2_EndPoint->Name; + TextCtrl9->SetValue(T); + + T = wxString::Format("%d", S2_EndPoint->Channels_Used / 3); + TextCtrl11->SetValue(T); + + } + } + + if(S2_EndPoint == 0) + { + T = ""; + TextCtrl7->SetValue(T); + TextCtrl9->SetValue(T); + TextCtrl11->SetValue(T); + } + + + + if(Channels_Avail_To_Slave == 0) + { + TextCtrl5->SetBackgroundColour(CR); + TextCtrl5->SetStyle(0, -1, TextCtrl1->GetDefaultStyle()); + + T = wxString::Format("%d", Channels_Avail_To_Slave); + TextCtrl5->SetValue(T); + + T = "No More Slaves Allowed"; + TextCtrl12->SetBackgroundColour(CR); + TextCtrl12->SetStyle(0, -1, TextCtrl1->GetDefaultStyle()); + + + } + else + { + TextCtrl5->SetBackgroundColour(CG); + TextCtrl5->SetStyle(0, -1, TextCtrl1->GetDefaultStyle()); + + T = wxString::Format("%d", Channels_Avail_To_Slave); + TextCtrl5->SetValue(T); + + T = "Acceptable"; + TextCtrl12->SetBackgroundColour(CG); + TextCtrl12->SetStyle(0, -1, TextCtrl1->GetDefaultStyle()); + + } + + TextCtrl12->SetValue(T); + + + return true; +} + +bool EasyLights_Add_Slaves_Dialog::TransferDataFromWindow() +{ + return true; +} + + + +void EasyLights_Add_Slaves_Dialog::OnButton_S1_Add(wxCommandEvent& event) +{ + wxString T; + int ItemData; + wxColour C(150, 150, 255); + int V, SV; + + V = ELC_Status_To_Support_Slaves(EL_EndPoint); + if(V == ELC_Support_NO_Slaves) + { + wxBell(); + return; + } + + if(ListCtrl1->GetSelectedItemCount() == 0) + { + wxBell(); + return; + } + + S1_Selected_EndPoint_Index = ListCtrl1->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if(S1_Selected_EndPoint_Index < 0) + { + wxBell(); + return; + } + + ItemData = (int)ListCtrl1->GetItemData(S1_Selected_EndPoint_Index); + + S1_EndPoint = (EL_Ptr->EL_EndPoints)[ItemData]; + + SV = Slave_Consumes_This_Number_Of_Controllers(S1_EndPoint); + if(SV > 2) + { + wxBell(); + S1_EndPoint = 0; + return; + } + + if(V == ELC_Support_One_Slave && SV > 1) + { + wxBell(); + S1_EndPoint = 0; + return; + } + + if(EL_EndPoint->S1_IP.size() > 3 || EL_EndPoint->S1_IP == S1_EndPoint->IP || EL_EndPoint->S2_IP == S1_EndPoint->IP) // already used? + { + S1_Selected_EndPoint_Index = 0; + S1_EndPoint = 0; + wxMessageBox(wxT("That Attachment has Already Been Selected"), wxT("Selection Error"), wxOK, NULL); + wxBell(); + return; + } + + EL_EndPoint->S1_IP = S1_EndPoint->IP; + S1_EndPoint->Slave_Attached = 1; + + TransferDataToWindow(); + + Dirty = 1; + + ListCtrl1->SetItemState(S1_Selected_EndPoint_Index, 0, wxLIST_STATE_SELECTED); // deselect so color change visible + + ListCtrl1->SetItemBackgroundColour(S1_Selected_EndPoint_Index, C); + +// this used to force color change + + T.Printf("%s", S1_EndPoint->IP); + ListCtrl1->SetItem(S1_Selected_EndPoint_Index, 1, T); + + + +} + +void EasyLights_Add_Slaves_Dialog::OnButton_S1_Remove(wxCommandEvent& event) +{ + wxColour C(255, 255, 255); + wxString T; + + if(S1_EndPoint == 0) + return; + + ListCtrl1->SetItemBackgroundColour(S1_Selected_EndPoint_Index, C); + + // this forces color change + T.Printf("%s", S1_EndPoint->IP); + ListCtrl1->SetItem(S1_Selected_EndPoint_Index, 1, T); + + + S1_EndPoint->Slave_Attached = 0; + EL_EndPoint->S1_IP = ""; + + S1_Selected_EndPoint_Index = 0; + S1_EndPoint = 0; + + TransferDataToWindow(); + + Dirty = 1; +} + +void EasyLights_Add_Slaves_Dialog::OnButton_S2_Add(wxCommandEvent& event) +{ + wxString T; + int ItemData; + wxColour C(150, 150, 255); + int V, SV; + + V = ELC_Status_To_Support_Slaves(EL_EndPoint); + if(V == ELC_Support_NO_Slaves) + { + wxBell(); + return; + } + + + if(ListCtrl1->GetSelectedItemCount() == 0) + { + wxBell(); + return; + } + + S2_Selected_EndPoint_Index = ListCtrl1->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if(S2_Selected_EndPoint_Index < 0) + { + wxBell(); + return; + } + + ItemData = (int)ListCtrl1->GetItemData(S2_Selected_EndPoint_Index); + + S2_EndPoint = (EL_Ptr->EL_EndPoints)[ItemData]; + + SV = Slave_Consumes_This_Number_Of_Controllers(S2_EndPoint); + if(SV > 2) + { + wxBell(); + S2_EndPoint = 0; + return; + } + + if(V == ELC_Support_One_Slave && SV > 1) + { + wxBell(); + S2_EndPoint = 0; + return; + } + + + if(EL_EndPoint->S2_IP.size() > 3 || EL_EndPoint->S1_IP == S2_EndPoint->IP || EL_EndPoint->S2_IP == S2_EndPoint->IP) // already used? + { + S2_Selected_EndPoint_Index = 0; + S2_EndPoint = 0; + wxMessageBox(wxT("That Attachment has Already Been Selected"), wxT("Selection Error"), wxOK, NULL); + wxBell(); + return; + } + + EL_EndPoint->S2_IP = S2_EndPoint->IP; + S2_EndPoint->Slave_Attached = 1; + + TransferDataToWindow(); + + Dirty = 1; + + ListCtrl1->SetItemState(S2_Selected_EndPoint_Index, 0, wxLIST_STATE_SELECTED); // deselect so color change visible + + ListCtrl1->SetItemBackgroundColour(S2_Selected_EndPoint_Index, C); + + // this used to force color change + + T.Printf("%s", S2_EndPoint->IP); + ListCtrl1->SetItem(S2_Selected_EndPoint_Index, 1, T); + + + +} + +void EasyLights_Add_Slaves_Dialog::OnButton_S2_Remove(wxCommandEvent& event) +{ + wxColour C(255, 255, 255); + wxString T; + + if(S2_EndPoint == 0) + return; + + ListCtrl1->SetItemBackgroundColour(S2_Selected_EndPoint_Index, C); + + // this forces color change + T.Printf("%s", S2_EndPoint->IP); + ListCtrl1->SetItem(S2_Selected_EndPoint_Index, 1, T); + + + S2_EndPoint->Slave_Attached = 0; + EL_EndPoint->S2_IP = ""; + + S2_Selected_EndPoint_Index = 0; + S2_EndPoint = 0; + + TransferDataToWindow(); + + Dirty = 1; + +} + +void EasyLights_Add_Slaves_Dialog::OnButtonCloseClick(wxCommandEvent& event) +{ + /** + if(Error_No_Save) + { + wxMessageBox(wxT("You can NOT Close until you REMOVE an Attachment that has caused More Channels to be Used then Available"), wxT("Close Error"), wxOK, NULL); + return; + } + **/ + + EndDialog(0); +} diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_Add_Slaves_Dialog.h b/xLights/controllers/EasyLights_Utils/EasyLights_Add_Slaves_Dialog.h new file mode 100644 index 0000000000..2abf2376d7 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_Add_Slaves_Dialog.h @@ -0,0 +1,139 @@ +#ifndef EASYLIGHTS_ADD_SLAVES_DIALOG_H +#define EASYLIGHTS_ADD_SLAVES_DIALOG_H + +//(*Headers(EasyLights_Add_Slaves_Dialog) +#include +#include +#include +#include +#include +#include +//*) + +class EasyLights_EndPoint; +class EL_Controller_Info; + + +class EasyLights_Add_Slaves_Dialog: public wxDialog +{ + public: + + EasyLights_Add_Slaves_Dialog(wxWindow* parent,wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize); + virtual ~EasyLights_Add_Slaves_Dialog(); + + //(*Declarations(EasyLights_Add_Slaves_Dialog) + wxButton* Button1; + wxButton* Button2; + wxButton* Button3; + wxButton* Button4; + wxListCtrl* ListCtrl1; + wxStaticText* StaticText10; + wxStaticText* StaticText11; + wxStaticText* StaticText12; + wxStaticText* StaticText13; + wxStaticText* StaticText14; + wxStaticText* StaticText15; + wxStaticText* StaticText16; + wxStaticText* StaticText1; + wxStaticText* StaticText2; + wxStaticText* StaticText3; + wxStaticText* StaticText4; + wxStaticText* StaticText5; + wxStaticText* StaticText6; + wxStaticText* StaticText7; + wxStaticText* StaticText8; + wxStaticText* StaticText9; + wxTextCtrl* TextCtrl10; + wxTextCtrl* TextCtrl11; + wxTextCtrl* TextCtrl12; + wxTextCtrl* TextCtrl1; + wxTextCtrl* TextCtrl2; + wxTextCtrl* TextCtrl3; + wxTextCtrl* TextCtrl4; + wxTextCtrl* TextCtrl5; + wxTextCtrl* TextCtrl6; + wxTextCtrl* TextCtrl7; + wxTextCtrl* TextCtrl8; + wxTextCtrl* TextCtrl9; + //*) + + protected: + + //(*Identifiers(EasyLights_Add_Slaves_Dialog) + static const long ID_STATICTEXT1; + static const long ID_LISTCTRL1; + static const long ID_STATICTEXT2; + static const long ID_STATICTEXT3; + static const long ID_TEXTCTRL1; + static const long ID_STATICTEXT4; + static const long ID_TEXTCTRL2; + static const long ID_STATICTEXT5; + static const long ID_TEXTCTRL3; + static const long ID_STATICTEXT6; + static const long ID_TEXTCTRL4; + static const long ID_STATICTEXT7; + static const long ID_TEXTCTRL5; + static const long ID_STATICTEXT16; + static const long ID_TEXTCTRL12; + static const long ID_STATICTEXT8; + static const long ID_STATICTEXT9; + static const long ID_TEXTCTRL6; + static const long ID_STATICTEXT12; + static const long ID_TEXTCTRL8; + static const long ID_STATICTEXT14; + static const long ID_TEXTCTRL10; + static const long ID_BUTTON1; + static const long ID_BUTTON2; + static const long ID_STATICTEXT10; + static const long ID_STATICTEXT11; + static const long ID_TEXTCTRL7; + static const long ID_STATICTEXT13; + static const long ID_TEXTCTRL9; + static const long ID_STATICTEXT15; + static const long ID_TEXTCTRL11; + static const long ID_BUTTON3; + static const long ID_BUTTON4; + //*) + + private: + + //(*Handlers(EasyLights_Add_Slaves_Dialog) + + void InitDialog(wxInitDialogEvent &event); + //*) + + protected: + + void BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size); + + DECLARE_EVENT_TABLE() + +public: + + bool TransferDataToWindow(); + bool TransferDataFromWindow(); + + void OnButton_S1_Add(wxCommandEvent& event); + void OnButton_S1_Remove(wxCommandEvent& event); + void OnButton_S2_Add(wxCommandEvent& event); + void OnButton_S2_Remove(wxCommandEvent& event); + void OnButtonCloseClick(wxCommandEvent& event); + + + EasyLights_EndPoint *Selected_EndPoint; + EasyLights_EndPoint *EL_EndPoint; + EasyLights_EndPoint *S1_EndPoint; + EasyLights_EndPoint *S2_EndPoint; + //int Selected_EndPoint_Index; + int S1_Selected_EndPoint_Index; + int S2_Selected_EndPoint_Index; + int Dirty; + + + int Channels_Avail_To_Slave; + + void Load_S_List(int Ignore_Slaves_Attached); + +}; + +#endif diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_Data.cpp b/xLights/controllers/EasyLights_Utils/EasyLights_Data.cpp new file mode 100644 index 0000000000..011a378bf3 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_Data.cpp @@ -0,0 +1,1457 @@ +#include +#include +#include +#include + +#include +#include + +#include "../../models/Model.h" +#include "../../outputs/OutputManager.h" +#include "../../outputs/Output.h" +#include "../../models/ModelManager.h" + + +#include +#include "UtilFunctions.h" +#include + +#include +#include + +#include "../../models/Model.h" +#include "../../outputs/OutputManager.h" +#include "../../outputs/Output.h" +#include "../../models/ModelManager.h" + +#include "../../FSEQFile.h" + +#include "../EasyLights.h" +#include "EasyLights_Data.h" + +extern "C" +{ +#include +#include +#include +#include + +} + + + + +void Get_EasyLights_Specifications(std::string &ShowDirectory) +{ + EL_Controller_Info *I; + wxDir EL_Dir; + + static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); + + std::string SD = ShowDirectory; + + wxFileName fnDir(SD + "/EasyLightsData"); + std::string _filename = fnDir.GetFullPath(); + + if(!EL_Dir.Exists(_filename)) // is our directory alive + { + EL_Dir.Make(_filename); + } + + wxFileName fn(SD + "/EasyLightsData/EasyLights_Controller_Specification.xml"); + _filename = fn.GetFullPath(); + + if(!fn.FileExists()) + { + wxMessageBox(wxT("Please Download File EasyLights_Controller_Specification.xml from EasyLights.com and Put the file in the Folder EasyLightsData within your Show Directory.\nI will Create a Temporary one for Now"), + wxT("EasyLights_Controller_Specification.xml Missing"), wxOK, NULL); + + Create_Temp_EasyLights_spec_File(); + } + + if(!fn.FileExists()) + { + wxMessageBox(wxT("Failed to Create Temp File. Please Download File EasyLights_Controller_Specification.xml from EasyLights.com and Put the file in the Folder EasyLightsData within your Show Directory."), + wxT("EasyLights_Controller_Specification.xml Missing"), wxOK, NULL); + + return; + } + + + wxXmlDocument doc; + doc.Load(fn.GetFullPath()); + + wxString VendorWho; + + if(doc.IsOk()) + { + for(auto e = doc.GetRoot()->GetChildren(); e != nullptr; e = e->GetNext()) + { + if(e->GetName() == "Vendor") + { + VendorWho = e->GetAttribute("name"); + if(VendorWho == "EasyLights") + { + for(auto ee = doc.GetRoot()->GetChildren()->GetChildren(); ee != nullptr; ee = ee->GetNext()) + { + if(ee->GetName() == "controller") + { + I = new EL_Controller_Info(); + + // + + I->Model = ee->GetAttribute("Model", ""); + + I->MaxChannels = wxAtoi(ee->GetAttribute("MaxChannels", "0")); + I->MaxUniverses = wxAtoi(ee->GetAttribute("MaxUniverses", "0")); + I->Slave_Control = wxAtoi(ee->GetAttribute("Slave_Control", "0")); + I->Max_SPI_Ports = wxAtoi(ee->GetAttribute("Max_SPI_Ports", "0")); + I->Max_Diff_Ports = wxAtoi(ee->GetAttribute("Max_Diff_Ports", "0")); + I->Master_Capable = wxAtoi(ee->GetAttribute("Master_Capable", "0")); + + EL_Ptr->EL_Controller.push_back(I); + } + } + + break; + } + + } + } + } +} + +void Build_EL_EndPoint_Array(std::string &ShowDirectory) +{ + EasyLights_EndPoint *I; + wxDir EL_Dir; + wxXmlDocument doc; + + static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); + + std::string SD = ShowDirectory; + + wxFileName fnDir(SD + "/EasyLightsData"); + std::string _filename = fnDir.GetFullPath(); + + if(!EL_Dir.Exists(_filename)) // is our directory alive + { + EL_Dir.Make(_filename); + } + + wxFileName fn(SD + "/EasyLightsData/EasyLights_EndPoints.xml"); + _filename = fn.GetFullPath(); + + if(fn.FileExists()) + { + doc.Load(fn.GetFullPath()); + + std::string J; + + wxString VendorWho; + + if(doc.IsOk()) + { + for(auto ee = doc.GetRoot()->GetChildren(); ee != nullptr; ee = ee->GetNext()) + { + J = ee->GetName(); + + if(ee->GetName() == "endpoint") + { + I = new EasyLights_EndPoint(); + +// + + I->Model = ee->GetAttribute("Model", ""); + I->MaxChannels = wxAtoi(ee->GetAttribute("MaxChannels", "0")); + I->MaxUniverses = wxAtoi(ee->GetAttribute("MaxUniverses", "0")); + I->Slave_Control = wxAtoi(ee->GetAttribute("Slave_Control", "0")); + I->Max_SPI_Ports = wxAtoi(ee->GetAttribute("Max_SPI_Ports", "0")); + I->Max_Diff_Ports = wxAtoi(ee->GetAttribute("Max_Diff_Ports", "0")); + I->Master_Capable = wxAtoi(ee->GetAttribute("Master_Capable", "0")); + I->Master = wxAtoi(ee->GetAttribute("Master", "0")); + I->Audio = wxAtoi(ee->GetAttribute("Audio", "0")); + I->IP = ee->GetAttribute("IP", ""); + I->S1_IP = ee->GetAttribute("S1_IP", ""); + I->S2_IP = ee->GetAttribute("S2_IP", ""); + I->Name = ee->GetAttribute("Name", ""); + I->Channels_Used = wxAtoi(ee->GetAttribute("Channels_Used", "0")); + I->Slave_Attached = wxAtoi(ee->GetAttribute("Slave_Attached", "0")); + I->Start_Channel = wxAtoi(ee->GetAttribute("Start_Channel", "0")); + I->End_Channel = wxAtoi(ee->GetAttribute("End_Channel", "0")); + + + EL_Ptr->EL_EndPoints.push_back(I); + + } + } + } + } +} + +EasyLights_EndPoint::EasyLights_EndPoint() +{ + MaxChannels = 0; + MaxUniverses = 0; + Slave_Control = 0; + Max_SPI_Ports = 0; + Max_Diff_Ports = 0; + Master_Capable = 0; + Master = 0; + Audio = 0; + Channels_Used = 0; + Slave_Attached = 0; + DDP_Network = 0; + Start_Channel = 0; + End_Channel = 0; + + +} + + +int Add_IPs_From_Output_To_EndPoint_Array() +{ + int Found = 0; + int dirty = 0; + std::string J; + EasyLights_EndPoint *I; + int SC, CH; + + static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); + + std::list OutPuts = EL_Ptr->OutPutMgr->GetAllOutputs(); + +// clear out channels used + + for(auto ep = EL_Ptr->EL_EndPoints.begin(); ep != EL_Ptr->EL_EndPoints.end(); ++ep) + { + (*ep)->Channels_Used = 0; + (*ep)->Start_Channel = 0; + (*ep)->End_Channel = 0; + + Set_EndPoint_EL_Max_Controller_Values(*ep); + + } + + + for(auto it = OutPuts.begin(); it != OutPuts.end(); ++it) + { + Found = 0; + + J = (*it)->GetIP(); + CH = (*it)->GetChannels(); + SC = (*it)->GetStartChannel(); + + + if((*it)->GetType() == OUTPUT_E131) + { + for(auto ep = EL_Ptr->EL_EndPoints.begin(); ep != EL_Ptr->EL_EndPoints.end(); ++ep) + { + if(J == (*ep)->IP) + { + (*ep)->Channels_Used += CH; + if((*ep)->Start_Channel == 0) + (*ep)->Start_Channel = SC; + + (*ep)->End_Channel = (*ep)->Start_Channel + (*ep)->Channels_Used - 1; + + Found++; + break; + } + } + + if(Found == 0) // we have an IP not in the list + { + I = new EasyLights_EndPoint(); + I->IP = J; + I->DDP_Network = 0; + I->Channels_Used = CH; + I->Start_Channel = SC; + I->End_Channel = SC + CH - 1; + EL_Ptr->EL_EndPoints.push_back(I); + + dirty = 1; + } + } + + if((*it)->GetType() == OUTPUT_DDP) + { + for(auto ep = EL_Ptr->EL_EndPoints.begin(); ep != EL_Ptr->EL_EndPoints.end(); ++ep) + { + if(J == (*ep)->IP) + { + (*ep)->Channels_Used += CH; + if((*ep)->Start_Channel == 0) + (*ep)->Start_Channel = SC; + + (*ep)->End_Channel = (*ep)->Start_Channel + (*ep)->Channels_Used - 1; + + Found++; + break; + } + } + + if(Found == 0) // we have an IP not in the list + { + I = new EasyLights_EndPoint(); + I->IP = J; + I->DDP_Network = 1; + I->Channels_Used = CH; + I->End_Channel = SC + CH - 1; + EL_Ptr->EL_EndPoints.push_back(I); + + dirty = 1; + } + } + + + + } + + return dirty; +} + +void Save_EndPoint_Array_to_XML(std::string &ShowDirectory) +{ + wxXmlDocument doc; + std::string _filename; + wxXmlNode *node; + + static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); + + std::string SD = ShowDirectory; + wxFileName fn(SD + "/EasyLightsData/EasyLights_EndPoints.xml"); + _filename = fn.GetFullPath(); + + wxXmlNode* root = new wxXmlNode(wxXML_ELEMENT_NODE, "EndPoints"); + + doc.SetRoot(root); + + + for(auto it = EL_Ptr->EL_EndPoints.begin(); it != EL_Ptr->EL_EndPoints.end(); ++it) + { + + node = new wxXmlNode(wxXML_ELEMENT_NODE, "endpoint"); + + + node->AddAttribute("Model", (*it)->Model); + + node->AddAttribute("MaxChannels", wxString::Format("%d", (*it)->MaxChannels)); + node->AddAttribute("MaxUniverses", wxString::Format("%d", (*it)->MaxUniverses)); + node->AddAttribute("Slave_Control", wxString::Format("%d", (*it)->Slave_Control)); + node->AddAttribute("Max_SPI_Ports", wxString::Format("%d", (*it)->Max_SPI_Ports)); + node->AddAttribute("Max_Diff_Ports", wxString::Format("%d", (*it)->Max_Diff_Ports)); + node->AddAttribute("Master_Capable", wxString::Format("%d", (*it)->Master_Capable)); + node->AddAttribute("Master", wxString::Format("%d", (*it)->Master)); + node->AddAttribute("Audio", wxString::Format("%d", (*it)->Audio)); + node->AddAttribute("Channels_Used", wxString::Format("%d", (*it)->Channels_Used)); + node->AddAttribute("Slave_Attached", wxString::Format("%d", (*it)->Slave_Attached)); + node->AddAttribute("Start_Channel", wxString::Format("%d", (*it)->Start_Channel)); + node->AddAttribute("End_Channel", wxString::Format("%d", (*it)->End_Channel)); + node->AddAttribute("IP", (*it)->IP); + node->AddAttribute("S1_IP", (*it)->S1_IP); + node->AddAttribute("S2_IP", (*it)->S2_IP); + node->AddAttribute("Name", (*it)->Name); + + root->AddChild(node); + + } + + doc.Save(_filename); + doc.DetachRoot(); + +} + + +void Set_EndPoint_EL_Max_Controller_Values(EasyLights_EndPoint *EP) +{ + if(EP->Model.size() < 3 || EP->Model == "Size") + { + EP->MaxChannels = 0; + EP->MaxUniverses = 0; + EP->Slave_Control = 0; + EP->Max_SPI_Ports = 0; + EP->Max_Diff_Ports = 0; + EP->Master_Capable = 0; + EP->Slave_Attached = 0; + } + else + { + for(auto ec = EL_Ptr->EL_Controller.begin(); ec != EL_Ptr->EL_Controller.end(); ++ec) + { + if((*ec)->Model == EP->Model) + { + EP->MaxChannels = (*ec)->MaxChannels; + EP->MaxUniverses = (*ec)->MaxUniverses; + EP->Slave_Control = (*ec)->Slave_Control; + EP->Max_SPI_Ports = (*ec)->Max_SPI_Ports; + EP->Max_Diff_Ports = (*ec)->Max_Diff_Ports; + EP->Master_Capable = (*ec)->Master_Capable; + } + } + + } + + +} + + +void printAudioFrameInfo(const AVCodecContext* codecContext, const AVFrame* frame) +{ + static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); + + + // See the following to know what data type (unsigned char, short, float, etc) to use to access the audio data: + // http://ffmpeg.org/doxygen/trunk/samplefmt_8h.html#af9a51ca15301871723577c730b5865c5 + + std::ostringstream stringStream; + + stringStream << "Audio frame info:\n" + << " Sample count: " << frame->nb_samples << '\n' + << " Channel count: " << codecContext->channels << '\n' + << " Format: " << av_get_sample_fmt_name(codecContext->sample_fmt) << '\n' + << " Bytes per sample: " << av_get_bytes_per_sample(codecContext->sample_fmt) << '\n' + << " Is planar? " << av_sample_fmt_is_planar(codecContext->sample_fmt) << '\n'; + + + stringStream << "frame->linesize[0] tells you the size (in bytes) of each plane\n"; + + if(codecContext->channels > AV_NUM_DATA_POINTERS && av_sample_fmt_is_planar(codecContext->sample_fmt)) + { + stringStream << "The audio stream (and its frames) have too many channels to fit in\n" + << "frame->data. Therefore, to access the audio data, you need to use\n" + << "frame->extended_data to access the audio data. It's planar, so\n" + << "each channel is in a different element. That is:\n" + << " frame->extended_data[0] has the data for channel 1\n" + << " frame->extended_data[1] has the data for channel 2\n" + << " etc.\n"; + } + else + { + stringStream << "Either the audio data is not planar, or there is enough room in\n" + << "frame->data to store all the channels, so you can either use\n" + << "frame->data or frame->extended_data to access the audio data (they\n" + << "should just point to the same data).\n"; + } + + stringStream << "If the frame is planar, each channel is in a different element.\n" + << "That is:\n" + << " frame->data[0]/frame->extended_data[0] has the data for channel 1\n" + << " frame->data[1]/frame->extended_data[1] has the data for channel 2\n" + << " etc.\n"; + + stringStream << "If the frame is packed (not planar), then all the data is in\n" + << "frame->data[0]/frame->extended_data[0] (kind of like how some\n" + << "image formats have RGB pixels packed together, rather than storing\n" + << " the red, green, and blue channels separately in different arrays.\n"; + + std::string copyOfStr = stringStream.str(); + logger_base.debug(copyOfStr); + +} + +int Create_EasyLights_PCM_File(std::string &Xfseq_FN, std::string &FN_pcm, EasyLights_FSEQ_Dialog *Display, uint32_t *Size_PCM_Bytes, uint32_t *Sample_Rate_Used) +{ + wxString T; + std::string TT; + int mp3_info = 0; + int outSamples; + char *p; + int Little_Endian = 0; + uint16_t *W; + int i; + uint32_t Number_PCM_Stereo_Samples = 0; + + static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); + + std::string FN_Audio = FSEQFile::getMediaFilename(Xfseq_FN); + + if(FN_Audio.size() < 3) + { + p = "EL Audio File Name could NOT be extracted from FSEQ file"; + Display->Write_Msg_to_Display(p); + logger_base.debug(p); + return 1; + } + + wxFile fo; + + fo.Open(FN_pcm, wxFile::write); + if(!fo.IsOpened()) + { + T = wxString::Format("Write Open Failed %s", FN_pcm); + Display->Write_Msg_to_Display(T); + logger_base.debug(T); + return 1; + + } + + // Audio samples are signed 16bit ints. EasyLights wants audio sample in little-endian + + outSamples = 1; + p = (char*)&outSamples; + Little_Endian = *p; + + if(Little_Endian) + logger_base.debug("Easylights Audio Decoding is on a Little-Endian machine"); + else + logger_base.debug("Easylights Audio Decoding is on a Big-Endian machine"); + + + + + // Initialize FFmpeg + av_register_all(); // make all codecs available + + AVFrame *frame = av_frame_alloc(); // does not create working buffers + if(!frame) + { + TT = "Error allocating the frame"; + logger_base.debug(TT); + Display->Write_Msg_to_Display(TT); + + return 1; + } + + AVFormatContext* formatContext = NULL; + if(avformat_open_input(&formatContext, FN_Audio.c_str(), NULL, NULL) != 0) + { + av_frame_free(&frame); + TT = "Error opening the Audio file"; + logger_base.debug(TT); + Display->Write_Msg_to_Display(TT); + + return 1; + } + + if(avformat_find_stream_info(formatContext, NULL) < 0) + { + av_frame_free(&frame); + avformat_close_input(&formatContext); + TT = "Error finding the Audio stream info"; + logger_base.debug(TT); + Display->Write_Msg_to_Display(TT); + + return 1; + } + + // Find the audio stream + AVCodec* cdc = nullptr; + int streamIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_AUDIO, -1, -1, &cdc, 0); + if(streamIndex < 0) + { + av_frame_free(&frame); + avformat_close_input(&formatContext); + TT = "Could not find any audio stream in the file"; + logger_base.debug(TT); + Display->Write_Msg_to_Display(TT); + + return 1; + } + + AVStream* audioStream = formatContext->streams[streamIndex]; + AVCodecContext* codecContext = audioStream->codec; + codecContext->codec = cdc; + + if(avcodec_open2(codecContext, codecContext->codec, NULL) != 0) // open the codec + { + av_frame_free(&frame); + avformat_close_input(&formatContext); + TT = "Couldn't open the context with the decoder"; + logger_base.debug(TT); + Display->Write_Msg_to_Display(TT); + + return 1; + } + + T = wxString::Format("This Audio stream has %d channels and a sample rate of %d Hz", codecContext->channels, codecContext->sample_rate); + logger_base.debug(T); + Display->Write_Msg_to_Display(T); + + T = wxString::Format("The Audio data is in the format %s", av_get_sample_fmt_name(codecContext->sample_fmt)); + logger_base.debug(T); + Display->Write_Msg_to_Display(T); + + // setup our conversion format ... we need to conver the input to a standard format before we can process anything + uint64_t out_channel_layout = AV_CH_LAYOUT_STEREO; + int out_channels = av_get_channel_layout_nb_channels(out_channel_layout); + AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16; + int out_sample_rate = 22050; + + *Sample_Rate_Used = out_sample_rate; + +#define CONVERSION_BUFFER_SIZE 192000 + uint8_t* out_buffer = (uint8_t *)av_malloc(CONVERSION_BUFFER_SIZE * out_channels * 2); // 1 second of audio + + int64_t in_channel_layout = av_get_default_channel_layout(codecContext->channels); + + struct SwrContext *au_convert_ctx = swr_alloc_set_opts(nullptr, out_channel_layout, out_sample_fmt, out_sample_rate, + in_channel_layout, codecContext->sample_fmt, codecContext->sample_rate, 0, nullptr); + + if(au_convert_ctx == nullptr) + { + logger_base.error("DoLoadAudioData: swe_alloc_set_opts was null"); + // let it go as it may be the cause of a crash + wxASSERT(false); + } + + swr_init(au_convert_ctx); + + + AVPacket readingPacket; + av_init_packet(&readingPacket); + + // Read the packets in a loop + while(av_read_frame(formatContext, &readingPacket) == 0) + { + if(readingPacket.stream_index == audioStream->index) + { + AVPacket decodingPacket = readingPacket; + + // Audio packets can have multiple audio frames in a single packet + while(decodingPacket.size > 0) + { + // Try to decode the packet into a frame + // Some frames rely on multiple packets, so we have to make sure the frame is finished before + // we can use it + int gotFrame = 0; + int result = avcodec_decode_audio4(codecContext, frame, &gotFrame, &decodingPacket); + + if(result >= 0 && gotFrame) + { + decodingPacket.size -= result; + decodingPacket.data += result; + + // We now have a fully decoded audio frame + outSamples = swr_convert(au_convert_ctx, &out_buffer, CONVERSION_BUFFER_SIZE, (const uint8_t **)frame->data, frame->nb_samples); + + // save pcm data + + Number_PCM_Stereo_Samples += outSamples; + + if(Little_Endian) + fo.Write(out_buffer, (outSamples * out_channels * 2)); + else // big endian - need to swapp + { + W = (uint16_t*)out_buffer; + + for(i = 0; i < (outSamples * 2), i++;) // stereo - two 16 bits words per sample + { + *W = wxUINT16_SWAP_ALWAYS(*W); + W++; + } + } + + + + if(mp3_info == 0) + { + mp3_info = 1; + printAudioFrameInfo(codecContext, frame); + } + } + else + { + decodingPacket.size = 0; + decodingPacket.data = nullptr; + } + } + } + + // You *must* call av_free_packet() after each call to av_read_frame() or else you'll leak memory + av_packet_unref(&readingPacket); + } + + // Some codecs will cause frames to be buffered up in the decoding process. If the CODEC_CAP_DELAY flag + // is set, there can be buffered up frames that need to be flushed, so we'll do that + if(codecContext->codec->capabilities & CODEC_CAP_DELAY) + { + av_init_packet(&readingPacket); + // Decode all the remaining frames in the buffer, until the end is reached + int gotFrame = 0; + while(avcodec_decode_audio4(codecContext, frame, &gotFrame, &readingPacket) >= 0 && gotFrame) + { + // We now have a fully decoded audio frame + outSamples = swr_convert(au_convert_ctx, &out_buffer, CONVERSION_BUFFER_SIZE, (const uint8_t **)frame->data, frame->nb_samples); + + // save pcm data + + Number_PCM_Stereo_Samples += outSamples; + + if(Little_Endian) + fo.Write(out_buffer, (outSamples * out_channels * 2)); + else // big endian - need to swapp + { + W = (uint16_t*)out_buffer; + + for(i = 0; i < (outSamples * 2), i++;) // stereo - two 16 bits words per sample + { + *W = wxUINT16_SWAP_ALWAYS(*W); + W++; + } + } + } + } + + fo.Close(); + + *Size_PCM_Bytes = Number_PCM_Stereo_Samples * 4; // stereo - two channels 16 bits each channel + + T = wxString::Format("Audio PCM - %d seconds in duration", (Number_PCM_Stereo_Samples / out_sample_rate)); + logger_base.debug(T); + Display->Write_Msg_to_Display(T); + + // Clean up! + swr_free(&au_convert_ctx); + av_free(out_buffer); + av_frame_free(&frame); + avcodec_close(codecContext); + avformat_close_input(&formatContext); + + return 0; +} + +int Make_WAV_From_PCM(std::string &EL_PCM, std::string &EL_WAV, uint32_t Size_PCM_Bytes, uint32_t Sample_Rate_Used) +{ + wavHeader WH; + uint32_t r; + uint32_t T; + + + WH.RIFF[0] = 'R'; + WH.RIFF[1] = 'I'; + WH.RIFF[2] = 'F'; + WH.RIFF[3] = 'F'; + + //WH.ChunkSize = Size_PCM_Bytes + 36; + T = Size_PCM_Bytes + 36; + write4ByteUInt((uint8_t*)&WH.ChunkSize, T); + + WH.WAVE[0] = 'W'; + WH.WAVE[1] = 'A'; + WH.WAVE[2] = 'V'; + WH.WAVE[3] = 'E'; + + WH.fmt[0] = 'f'; + WH.fmt[1] = 'm'; + WH.fmt[2] = 't'; + WH.fmt[3] = ' '; + + //WH.Subchunk1Size = 16; + T = 16; + write4ByteUInt((uint8_t*)&WH.Subchunk1Size, T); + + //WH.AudioFormat = 1; + T = 1; + write2ByteUInt((uint8_t*)&WH.AudioFormat, T); + + //WH.NumOfChannels = 2; + T = 2; + write2ByteUInt((uint8_t*)&WH.NumOfChannels, T); + + //WH.SamplesPerSec = 44100; + T = Sample_Rate_Used; + write4ByteUInt((uint8_t*)&WH.SamplesPerSec, T); + + //WH.bytesPerSec = 176400; + T = Sample_Rate_Used * 4; + write4ByteUInt((uint8_t*)&WH.bytesPerSec, T); + + //WH.blockAlign = 4; + T = 4; + write2ByteUInt((uint8_t*)&WH.blockAlign, T); + + //WH.bitsPerSample = 16; + T = 16; + write2ByteUInt((uint8_t*)&WH.bitsPerSample, T); + + + WH.Subchunk2ID[0] = 'd'; + WH.Subchunk2ID[1] = 'a'; + WH.Subchunk2ID[2] = 't'; + WH.Subchunk2ID[3] = 'a'; + + //WH.Subchunk2Size = Size_PCM_Bytes; + T = Size_PCM_Bytes; + write4ByteUInt((uint8_t*)&WH.Subchunk2Size, T); + + + wxFile fo; + wxFile fi; + + fo.Open(EL_WAV, wxFile::write); + if(!fo.IsOpened()) + { + return 1; + } + + fo.Write(&WH, sizeof(WH)); + + fi.Open(EL_PCM, wxFile::read); + if(!fi.IsOpened()) + { + fo.Close(); + return 1; + } + + uint8_t *Buff = (uint8_t*)malloc(Size_PCM_Bytes); + if(Buff == 0) + { + fo.Close(); + fi.Close(); + return 1; + } + + r = fi.Read(Buff, Size_PCM_Bytes); + if(r != Size_PCM_Bytes) + { + fo.Close(); + fi.Close(); + return 1; + } + + + fo.Write(Buff, Size_PCM_Bytes); + + fo.Close(); + fi.Close(); + + return 0; + + +} + + +EasyLights_EndPoint *Find_EndPoint_By_IP(std::string &IP) +{ + for(auto it = EL_Ptr->EL_EndPoints.begin(); it != EL_Ptr->EL_EndPoints.end(); ++it) + { + if((*it)->IP == IP) + return *it; + } + + return 0; +} + + +struct Tag_Controller_Channels +{ + uint32_t Start_Channel_Zero_Base; + uint32_t Num_Channels; +}; + +int Create_EasyLights_FSEQ_File(EL_FSEQ_Info *ELC, EasyLights_FSEQ_Dialog *Display) +{ + FSEQFile *xf; + FSEQFile *ef; + wxString T; + uint32_t xNumber_of_Frames; + uint32_t numChannels; + int xFrame_Rate; + EasyLights_EndPoint *Slave; + uint8_t *VHeader = 0; + int Size_VHeader = 0; + + struct Tag_Controller_Channels Controllers[3]; + + memset(Controllers, 0, sizeof(Controllers)); + int Cindex = 0; + + static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); + + T = wxString::Format("EL FSEQ Creation from %s", ELC->IX ->FN_short); + logger_base.debug(T); + Display->Write_Msg_to_Display(T); + + + xf = FSEQFile::openFSEQFile(ELC->IX->FN_long); + if(!xf) + { + T = wxString::Format("EasyLights Failed opening FSEQ %s", ELC->IX->FN_short); + logger_base.debug(T); + Display->Write_Msg_to_Display(T); + return 1; + } + + xNumber_of_Frames = xf->getNumFrames(); + numChannels = xf->getChannelCount(); + xFrame_Rate = xf->getStepTime(); + + + std::vector> rng; + rng.push_back(std::pair(0, numChannels)); + xf->prepareRead(rng); + +// read file ready -- do write file + + ef = FSEQFile::createFSEQFile(ELC->ELC_FN_long, 1, FSEQFile::none, 0); + if(!ef) + { + T = wxString::Format("EasyLights Failed Write opening FSEQ %s", ELC->ELC_FN_short); + logger_base.debug(T); + Display->Write_Msg_to_Display(T); + delete xf; + return 1; + } + + // acquire channel data on all controllers + + Controllers[0].Start_Channel_Zero_Base = ELC->EP->Start_Channel - 1; + Controllers[0].Num_Channels = ELC->EP->Channels_Used; + Cindex++; + + if(ELC->EP->S1_IP.size() > 3) + { + Slave = Find_EndPoint_By_IP(ELC->EP->S1_IP); + if(Slave) + { + Controllers[Cindex].Start_Channel_Zero_Base = Slave->Start_Channel - 1; + Controllers[Cindex].Num_Channels = Slave->Channels_Used; + Cindex++; + } + } + + if(ELC->EP->S2_IP.size() > 3) + { + Slave = Find_EndPoint_By_IP(ELC->EP->S2_IP); + if(Slave) + { + Controllers[Cindex].Start_Channel_Zero_Base = Slave->Start_Channel - 1; + Controllers[Cindex].Num_Channels = Slave->Channels_Used; + Cindex++; + } + } + + + int ef_Num_Channel_To_Write = Controllers[0].Num_Channels + Controllers[1].Num_Channels + Controllers[2].Num_Channels; + + uint8_t *src, *dest; + + ef->setChannelCount(ef_Num_Channel_To_Write); + ef->setStepTime(xFrame_Rate); + ef->setNumFrames(xNumber_of_Frames); + + if(Cindex > 1) // we have slaves = make variable header for fseq + { + VHeader = Get_VHeader_for_ELC_FSEQ(ELC, &Size_VHeader); + + FSEQFile::VariableHeader header; + header.code[0] = 'e'; + header.code[1] = 'l'; + header.data.resize(Size_VHeader); + memmove(&header.data[0], VHeader, Size_VHeader); + ef->addVariableHeader(header); + + free(VHeader); + VHeader = 0; + } + + ef->writeHeader(); // ready for frame data + + uint8_t *WriteBuf = new uint8_t[ef_Num_Channel_To_Write]; + + // read buff + uint8_t *tmpBuf = new uint8_t[numChannels]; + + uint32_t frame = 0; + + while(frame < xNumber_of_Frames) + { + FSEQFile::FrameData *data = xf->getFrame(frame); + + data->readFrame(tmpBuf); // we have a read frame + + // move wanted write channels into write frame buffer + + src = tmpBuf + Controllers[0].Start_Channel_Zero_Base; // start of my data with global channel array + dest = WriteBuf; + memmove(dest, src, Controllers[0].Num_Channels); + dest += Controllers[0].Num_Channels; + + if(Controllers[1].Num_Channels) + { + src = tmpBuf + Controllers[1].Start_Channel_Zero_Base; // start of my data with global channel array + memmove(dest, src, Controllers[1].Num_Channels); + dest += Controllers[1].Num_Channels; + } + + if(Controllers[2].Num_Channels) + { + src = tmpBuf + Controllers[2].Start_Channel_Zero_Base; // start of my data with global channel array + memmove(dest, src, Controllers[2].Num_Channels); + dest += Controllers[2].Num_Channels; + } + + ef->addFrame(frame, WriteBuf); + + delete data; + frame++; + } + + ef->finalize(); + + delete[]tmpBuf; + delete[]WriteBuf; + + delete xf; + delete ef; + + T = wxString::Format("EasyLights Completed FSEQ %s", ELC->ELC_FN_short); + logger_base.debug(T); + Display->Write_Msg_to_Display(T); + + + return 0; +} + + +int Return_FSEQ_Version(std::string FSEQ_FN) +{ + int V; + FSEQFile *f; + + f = FSEQFile::openFSEQFile(FSEQ_FN); + if(f == 0) + { + return 0; + } + + V = f->getVersionMajor(); + + delete f; + + return V; +} + +#define VHeader_Size 5000 + +uint8_t *Get_VHeader_for_ELC_FSEQ(EL_FSEQ_Info *ELC, int *VHSize) +{ + uint8_t *H = (uint8_t*)malloc(VHeader_Size); // plenty big + struct Tag_FSEQ_Variable_Header_Main *HM = (struct Tag_FSEQ_Variable_Header_Main*)H; + struct Tag_FSEQ_Variable_Header_H1 *H1 = (struct Tag_FSEQ_Variable_Header_H1*)(H + sizeof(struct Tag_FSEQ_Variable_Header_Main)); + uint8_t *D = H + sizeof(struct Tag_FSEQ_Variable_Header_Main) + sizeof(struct Tag_FSEQ_Variable_Header_H1); + EasyLights_EndPoint *Slave; + uint16_t VHsize = 0; + uint32_t Offset; + std::vector< Slave_Univ_Chan> *SUC1 = 0; + std::vector< Slave_Univ_Chan> *SUC2 = 0; + + // fill in H1 + memset(H, 0, VHeader_Size); + + write4ByteUInt((uint8_t*)&H1->Main_Num_Channels, ELC->EP->Channels_Used); + + if(ELC->EP->S1_IP.size() > 3) + { + Slave = Find_EndPoint_By_IP(ELC->EP->S1_IP); + if(Slave) + { + HM->Number_Slaves++; + + H1->Slave1_Active = 1; + write2ByteUInt((uint8_t*)&H1->Slave1_Num_Channels, Slave->Channels_Used); + + SUC1 = Get_Slave_Universe_Channel_Config(ELC->EP->S1_IP); + + H1->Slave1_Num_Univ = SUC1->size(); + + Offset = D - H; + write2ByteUInt((uint8_t*)&H1->Slave1_Univ_Offset, Offset); + D = Add_Slave_Univ_Chan_Data_to_VHeader(D, SUC1); + + SUC1->clear(); + SUC1->shrink_to_fit(); + delete SUC1; + + + } + } + + if(ELC->EP->S2_IP.size() > 3) + { + Slave = Find_EndPoint_By_IP(ELC->EP->S2_IP); + if(Slave) + { + HM->Number_Slaves++; + + H1->Slave2_Active = 1; + write2ByteUInt((uint8_t*)&H1->Slave2_Num_Channels, Slave->Channels_Used); + + SUC2 = Get_Slave_Universe_Channel_Config(ELC->EP->S2_IP); + + H1->Slave2_Num_Univ = SUC2->size(); + + Offset = D - H; + write2ByteUInt((uint8_t*)&H1->Slave2_Univ_Offset, Offset); + D = Add_Slave_Univ_Chan_Data_to_VHeader(D, SUC2); + + SUC2->clear(); + SUC2->shrink_to_fit(); + delete SUC2; + + } + } + + VHsize = D - H; + *VHSize = VHsize; + write2ByteUInt((uint8_t*)&HM->Total_Size_VHeader, VHsize); + + return H; + +} + + +std::vector< Slave_Univ_Chan> *Get_Slave_Universe_Channel_Config(std::string IP) +{ + Slave_Univ_Chan T; + + std::vector< Slave_Univ_Chan> *SUC = new std::vector< Slave_Univ_Chan>; + + // Get universes based on IP + std::list outputs = EL_Ptr->OutPutMgr->GetAllOutputs(IP); + + + for(auto it = outputs.begin(); it != outputs.end(); ++it) + { + + + T.Univ = (*it)->GetUniverse(); + T.Num_Chan = (*it)->GetChannels(); + T.Start_Chan = (*it)->GetStartChannel(); + + SUC->push_back(T); + + } + + return SUC; +} + +uint8_t *Add_Slave_Univ_Chan_Data_to_VHeader(uint8_t *D, std::vector< Slave_Univ_Chan> *SUC) +{ + for(auto it = SUC->begin(); it != SUC->end(); ++it) + { + write2ByteUInt(D, it->Univ); + D+= 2; + write2ByteUInt(D, it->Num_Chan); + D += 2; + write2ByteUInt(D, it->Start_Chan); + D += 2; + } + + return D; + +} + + +int ELC_Status_To_Support_Slaves(EasyLights_EndPoint *ELC) +{ + EasyLights_EndPoint *Slave; + + if(ELC->Channels_Used > ELC_NO_Slaves_Channel_Count) + return ELC_Support_NO_Slaves; + + if(ELC->Channels_Used > ELC_ONE_Slaves_Channel_Count) // only support one small slave + { + if(ELC->S1_IP.size() < 3 && ELC->S2_IP.size() < 3) // no slaves at this time + return ELC_Support_One_Slave; // can only support 1 slave + else + return ELC_Support_NO_Slaves; + } + + // elc can support 1 big slave or 2 little ones + + if(ELC->S1_IP.size() < 3 && ELC->S2_IP.size() < 3) // no slaves at this time + return ELC_Support_TWO_Slaves; + + if(ELC->S1_IP.size() > 3 && ELC->S2_IP.size() > 3) // 2 slaves at this time + return ELC_Support_NO_Slaves; + + if(ELC->S1_IP.size() > 3) + { + Slave = Find_EndPoint_By_IP(ELC->S1_IP); + if(Slave) + { + if(Slave->Channels_Used < Slave_Max_Channel_Count_For_Two) + return ELC_Support_One_Slave; + + return ELC_Support_NO_Slaves; + } + } + + if(ELC->S2_IP.size() > 3) + { + Slave = Find_EndPoint_By_IP(ELC->S2_IP); + if(Slave) + { + if(Slave->Channels_Used < Slave_Max_Channel_Count_For_Two) + return ELC_Support_One_Slave; + + return ELC_Support_NO_Slaves; + } + } + + return ELC_Support_NO_Slaves; +} + +int Slave_Consumes_This_Number_Of_Controllers(std::string IP) +{ + EasyLights_EndPoint *Slave; + + Slave = Find_EndPoint_By_IP(IP); + if(Slave) + { + if(Slave->Channels_Used > Slave_Max_Channel_Count_for_One) + return 10; // too big, can't use + + if(Slave->Channels_Used > Slave_Max_Channel_Count_For_Two) + return 2; + + return 1; + } + + return 0; +} + +int Slave_Consumes_This_Number_Of_Controllers(EasyLights_EndPoint *Slave) +{ + if(Slave->Channels_Used > Slave_Max_Channel_Count_for_One) + return 10; // too big, can use + + if(Slave->Channels_Used > Slave_Max_Channel_Count_For_Two) + return 2; + + return 1; + + +} + +char *Return_EasuLights_FSEQ_FN_Without_IP(char *S) +{ + char *B = (char*)malloc(200); + char *p; + + strncpy(B, S, 199); + + p = B; + while(*p) p++; + while(p > B && *p != ' ') p--; + if(*p == ' ') + { + *p = 0; + p++; + } + else + { + free(B); + return 0; + } + + // this should be start of ip + + if(*p < '0' || *p > '9') + { + free(B); + return 0; + } + + p = strstr(p, ".fseq"); + if(p == 0) + { + free(B); + return 0; + } + + strcat(B, p); + + return B; +} + +char *Get_Next_JArg(char *p, char **JF, char **JV, int *Last_Key, int Ignore_Bracket) +{ + int Quote = 0; + char *k; + + if(Last_Key) + *Last_Key = 0; + + while(*p && (*p == ' ' || *p == '\t' || *p == '{' || *p == '}' || *p == '[' || *p == ']' || *p == ',')) p++; // find start - skip leading space + + if(*p == 0) + return 0; + + // parse KEY + + if(*p == '\"') + { + Quote = 1; + p++; + } + + *JF = p; + + + if(Quote) + { + while(*p && *p != '\"') // cAP and find end + { + *p = toupper(*p); + p++; + } + + if(*p == 0) + return 0; // error + + *p = 0; // terminate quote + p++; // step over + + if(*p != ':') // next char must be colon + return 0; // error + + + p++; // over colon + } + else + { + while(*p && *p != ':') // cAP and find end + { + *p = toupper(*p); + p++; + } + + if(*p == 0) + return 0; // error + + *p = 0; // terminate colon + + p++; // over colon + } + + // parse VALUE + + Quote = 0; + + while(*p && (*p == ' ' || *p == '\t')) p++; // skip leading space + + if(*p == '\"') + { + Quote = 1; + p++; + } + + *JV = p; + + if(Quote) + { + if(Ignore_Bracket) + { + // if data is an array - bracket follows quote + if(*p == '[') // data is an array + { + p++; // step over + + } + } + else + { + // if data is an array - bracket follows quote + if(*p == '[') // data is an array + { + p++; // step over + + while(*p && *p != ']') p++; // find end + + p++; // step over + } + } + + while(*p && *p != '\"') p++; // find end + + if(*p == 0) + return 0; // error + + *p = 0; // terminate quote + p++; // step over + + while(*p && *p != ',' && *p != '{' && *p != '}' && *p != '[' && *p != ']') p++; // find end of value + } + else + { + if(Ignore_Bracket) + { + // if data is an array - bracket follows quote + if(*p == '[') // data is an array + { + p++; // step over + + } + } + else + { + // if data is an array - bracket follows quote + if(*p == '[') // data is an array + { + p++; // step over + + while(*p && *p != ']') p++; // find end + + p++; // step over + } + } + + + + while(*p && *p != ',' && *p != '{' && *p != '}' && *p != '[' && *p != ']') p++; // find end + } + + + if(*p) + { + *p = 0; + p++; + } + + // now see if last key + + if(Last_Key) + { + k = p; + while(*k && *k != ':') k++; + if(*k == 0) + *Last_Key = 1; + } + + + return p; + +} + +static const char *Temp_ELC_Spec = +"\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n"; + + +void Create_Temp_EasyLights_spec_File() +{ + + wxString FN = wxString::Format("%s\\EasyLightsData\\%s", EL_Ptr->ShowDirectory, "EasyLights_Controller_Specification.xml"); + std::string fn = FN; + + FILE *fo = fopen((const char *)fn.c_str(), "w"); + + if(fo == 0) + return; + + fputs(Temp_ELC_Spec, fo); + + fclose(fo); + +} \ No newline at end of file diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_Data.h b/xLights/controllers/EasyLights_Utils/EasyLights_Data.h new file mode 100644 index 0000000000..2218070bd9 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_Data.h @@ -0,0 +1,195 @@ +#ifndef EASYLIGHTS_Data +#define EASYLIGHTS_Data + + +#include +#include + +#include "EasyLights_Schedule_Dialog.h" +#include "EasyLights_PlayList_Dialog.h" +#include "EasyLights_FSEQ_Dialog.h" +#include "EasyLights_Add_Slaves_Dialog.h" +#include "EasyLights_Identify_Dialog.h" +#include "EasyLights_StandAlone_Dialog.h" + + +/***** + +Criteria for driving slaves + +If ELC has less than 16 univ then it can drive 32 external universes on one controller or 2 controllers at 16 each + +If ELS has more than 16 univ but less than 32 univ - than it can drive 1 controller with less than 16 univ + + +***/ + +#define ELC_NO_Slaves_Channel_Count (32 * 512) +#define ELC_ONE_Slaves_Channel_Count (16 * 512) + +#define Slave_Max_Channel_Count_for_One (30 * 512) +#define Slave_Max_Channel_Count_For_Two (16 * 512) + +#define ELC_Support_TWO_Slaves 0 +#define ELC_Support_One_Slave 1 +#define ELC_Support_NO_Slaves 2 + +#define Slave_Allowed_Two 0 +#define Slave_Allowed_One 1 +#define Slave_Allowed_None 2 + +extern EasyLights_StandAlone_Dialog *EL_Ptr; + + +class Slave_Univ_Chan +{ +public: + uint16_t Univ; + uint16_t Num_Chan; + uint16_t Start_Chan; +}; + +struct Tag_FSEQ_Variable_Header_Main +{ + uint8_t Number_Slaves; + uint8_t ELC_Port_Config_ReMap; + uint16_t Total_Size_VHeader; +}; + +struct Tag_FSEQ_Variable_Header_H1 +{ + uint32_t Main_Num_Channels; + uint16_t Num_Remap_Ports; + uint16_t Remap_Ports_Offset; + uint8_t Slave1_Active; + uint8_t Slave2_Active; + uint8_t Slave1_Num_Univ; + uint8_t Slave2_Num_Univ; + uint16_t Slave1_Num_Channels; + uint16_t Slave2_Num_Channels; + uint16_t Slave1_Univ_Offset; + uint16_t Slave2_Univ_Offset; +}; + +inline void write4ByteUInt(uint8_t* data, uint32_t v) +{ + data[0] = (uint8_t)(v & 0xFF); + data[1] = (uint8_t)((v >> 8) & 0xFF); + data[2] = (uint8_t)((v >> 16) & 0xFF); + data[3] = (uint8_t)((v >> 24) & 0xFF); +}; + +inline void write2ByteUInt(uint8_t* data, uint32_t v) +{ + data[0] = (uint8_t)(v & 0xFF); + data[1] = (uint8_t)((v >> 8) & 0xFF); +}; + + + +typedef struct wavHeaderInfo +{ + char RIFF[4]; /* RIFF Header */ //Magic header + unsigned long ChunkSize; /* RIFF Chunk Size */ + char WAVE[4]; /* WAVE Header */ + char fmt[4]; /* FMT header */ + unsigned long Subchunk1Size; /* Size of the fmt chunk */ + unsigned short AudioFormat; /* Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM */ + unsigned short NumOfChannels; /* Number of channels 1=Mono 2=Sterio */ + unsigned long SamplesPerSec; /* Sampling Frequency in Hz */ + unsigned long bytesPerSec; /* bytes per second */ + unsigned short blockAlign; /* 2=16-bit mono, 4=16-bit stereo */ + unsigned short bitsPerSample; /* Number of bits per sample */ + char Subchunk2ID[4]; /* "data" string */ + unsigned long Subchunk2Size; /* Sampled data length */ +} wavHeader; + + +struct Tag_RIFF_Header +{ + char RIFF[4]; /* RIFF Header */ //Magic header + unsigned long ChunkSize; /* RIFF Chunk Size */ + char WAVE[4]; /* WAVE Header */ +}; + +struct Tag_ChunkHeader +{ + char Subchunk2ID[4]; /* "fmt or data" string */ + unsigned long Subchunk2Size; /* Sampled data length */ +}; + + +class EL_Controller_Info +{ +public: + std::string Model; + int MaxChannels; + int MaxUniverses; + bool Slave_Control; + int Max_SPI_Ports; + int Max_Diff_Ports; + bool Master_Capable; +}; + +class EasyLights_EndPoint +{ +public: + std::string Model; + int MaxChannels; + int MaxUniverses; + bool Slave_Control; + int Max_SPI_Ports; + int Max_Diff_Ports; + bool Master_Capable; + bool Master; + bool Audio; + bool DDP_Network; + bool Slave_Attached; + int Channels_Used; + int Start_Channel; + int End_Channel; + std::string IP; + std::string S1_IP; + std::string S2_IP; + std::string Name; + + + EasyLights_EndPoint(); + +}; + +void Get_EasyLights_Specifications(std::string &ShowDirectory); +void Create_Temp_EasyLights_spec_File(); + +void Build_EL_EndPoint_Array(std::string &ShowDirectory); + +int Add_IPs_From_Output_To_EndPoint_Array(); + +void Save_EndPoint_Array_to_XML(std::string &ShowDirectory); + +void Set_EndPoint_EL_Max_Controller_Values(EasyLights_EndPoint *EP); + +int Create_EasyLights_PCM_File(std::string &Xfseq_FN, std::string &FN_pcm, EasyLights_FSEQ_Dialog *Display, uint32_t *Size_PCM_Bytes, uint32_t *Sample_Rate_Used); +int Make_WAV_From_PCM(std::string &EL_PCM, std::string &EL_WAV, uint32_t Size_PCM_Bytes, uint32_t Sample_Rate_Used); +int Create_EasyLights_FSEQ_File(EL_FSEQ_Info *ELC, EasyLights_FSEQ_Dialog *Display); + +EasyLights_EndPoint *Find_EndPoint_By_IP(std::string &IP); + +int Return_FSEQ_Version(std::string FSEQ_FN); + +uint8_t *Get_VHeader_for_ELC_FSEQ(EL_FSEQ_Info *ELC, int *VHSize); + +std::vector< Slave_Univ_Chan> *Get_Slave_Universe_Channel_Config(std::string IP); + +uint8_t *Add_Slave_Univ_Chan_Data_to_VHeader(uint8_t *D, std::vector< Slave_Univ_Chan> *SUC); + +int ELC_Status_To_Support_Slaves(EasyLights_EndPoint *ELC); +int Slave_Consumes_This_Number_Of_Controllers(std::string IP); +int Slave_Consumes_This_Number_Of_Controllers(EasyLights_EndPoint *Slave); + +char *Return_EasuLights_FSEQ_FN_Without_IP(char *S); + +char *Get_Next_JArg(char *p, char **JF, char **JV, int *Last_Key, int Ignore_Bracket); + +#endif + diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_FSEQ_Dialog.cpp b/xLights/controllers/EasyLights_Utils/EasyLights_FSEQ_Dialog.cpp new file mode 100644 index 0000000000..881b20acf5 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_FSEQ_Dialog.cpp @@ -0,0 +1,664 @@ +#include +#include +#include +#include + +#include +#include + +#include "../../models/Model.h" +#include "../../outputs/OutputManager.h" +#include "../../outputs/Output.h" +#include "../../models/ModelManager.h" + + +#include +#include "UtilFunctions.h" +#include +#include + +#include + +#include "../../models/Model.h" +#include "../../outputs/OutputManager.h" +#include "../../outputs/Output.h" +#include "../../models/ModelManager.h" + +#include "../EasyLights.h" + +#include "../EasyLights.h" +#include "EasyLights_Data.h" +#include "EasyLights_FSEQ_Dialog.h" +#include "../../xlightsMain.h" + + +//(*IdInit(EasyLights_FSEQ_Dialog) +const long EasyLights_FSEQ_Dialog::ID_STATICTEXT1 = wxNewId(); +const long EasyLights_FSEQ_Dialog::ID_STATICTEXT2 = wxNewId(); +const long EasyLights_FSEQ_Dialog::ID_GRID1 = wxNewId(); +const long EasyLights_FSEQ_Dialog::ID_LISTCTRL1 = wxNewId(); +const long EasyLights_FSEQ_Dialog::ID_BUTTON1 = wxNewId(); +const long EasyLights_FSEQ_Dialog::ID_BUTTON2 = wxNewId(); +const long EasyLights_FSEQ_Dialog::ID_BUTTON3 = wxNewId(); +const long EasyLights_FSEQ_Dialog::ID_BUTTON4 = wxNewId(); +const long EasyLights_FSEQ_Dialog::ID_TEXTCTRL1 = wxNewId(); +//*) + +BEGIN_EVENT_TABLE(EasyLights_FSEQ_Dialog,wxDialog) + //(*EventTable(EasyLights_FSEQ_Dialog) + EVT_GRID_SELECT_CELL(EasyLights_FSEQ_Dialog::OnGridCellLeftClick) + EVT_INIT_DIALOG(EasyLights_FSEQ_Dialog::InitDialog) + //*) +END_EVENT_TABLE() + +EasyLights_FSEQ_Dialog *EasyLights_FSEQ_Dialog_Ptr = 0; + +EasyLights_FSEQ_Dialog::EasyLights_FSEQ_Dialog(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) +{ + Quit_Now = 0; + FSEQ_Busy = 0; + Button_Active = 0; + Process_Selected_Active = 0; + + + EasyLights_FSEQ_Dialog_Ptr = this; + + + BuildContent(parent,id,pos,size); + + Grid1->SetRowLabelSize(0); + Grid1->HideCol(0); + Grid1->HideCol(1); + Grid1->SetColSize(2, 200); + Grid1->SetColSize(3, 100); + Grid1->SetColSize(4, 150); + Grid1->SetColSize(5, 100); + Grid1->SetColSize(6, 100); + + Connect(wxID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_FSEQ_Dialog::OnButtonCloseClick); + Connect(wxID_ANY, wxEVT_CLOSE_WINDOW, (wxObjectEventFunction)&EasyLights_FSEQ_Dialog::OnButtonCloseClick); + Connect(ID_BUTTON1, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_FSEQ_Dialog::OnButtonCloseClick); + Connect(ID_BUTTON2, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_FSEQ_Dialog::OnButton_Fseq_Selected); + Connect(ID_BUTTON3, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_FSEQ_Dialog::OnButton_Fseq_All); + Connect(ID_BUTTON4, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_FSEQ_Dialog::OnButton_Fseq_Required); + + Set_Busy_Status(0); + +} + +void EasyLights_FSEQ_Dialog::BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) +{ + //(*Initialize(EasyLights_FSEQ_Dialog) + wxFlexGridSizer* FlexGridSizer1; + wxFlexGridSizer* FlexGridSizer2; + + Create(parent, wxID_ANY, _("EasyLights FSEQ Management"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("wxID_ANY")); + FlexGridSizer1 = new wxFlexGridSizer(0, 2, 0, 0); + StaticText1 = new wxStaticText(this, ID_STATICTEXT1, _("Xlights FSEQ related to EasyLights StandAlone FSEQ by Controller"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1")); + FlexGridSizer1->Add(StaticText1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText2 = new wxStaticText(this, ID_STATICTEXT2, _("Status / Build Information"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2")); + FlexGridSizer1->Add(StaticText2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Grid1 = new wxGrid(this, ID_GRID1, wxDefaultPosition, wxDefaultSize, wxVSCROLL, _T("ID_GRID1")); + Grid1->CreateGrid(0,7); + Grid1->EnableEditing(false); + Grid1->EnableGridLines(true); + Grid1->SetColLabelValue(0, _("Hidden")); + Grid1->SetColLabelValue(1, _("Hidden")); + Grid1->SetColLabelValue(2, _("Xlights FSEQ")); + Grid1->SetColLabelValue(3, _("FSEQ Date")); + Grid1->SetColLabelValue(4, _("EL Controller Name")); + Grid1->SetColLabelValue(5, _("ELC IP Address")); + Grid1->SetColLabelValue(6, _("ELC FSEQ Date")); + Grid1->SetDefaultCellFont( Grid1->GetFont() ); + Grid1->SetDefaultCellTextColour( Grid1->GetForegroundColour() ); + FlexGridSizer1->Add(Grid1, 1, wxALL, 5); + ListCtrl1 = new wxListCtrl(this, ID_LISTCTRL1, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_NO_HEADER|wxVSCROLL|wxHSCROLL, wxDefaultValidator, _T("ID_LISTCTRL1")); + ListCtrl1->SetMinSize(wxSize(250,400)); + ListCtrl1->SetMaxSize(wxSize(-1,-1)); + FlexGridSizer1->Add(ListCtrl1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer2 = new wxFlexGridSizer(0, 4, 0, 0); + Button1 = new wxButton(this, ID_BUTTON1, _("Quit"), wxDefaultPosition, wxSize(150,25), 0, wxDefaultValidator, _T("ID_BUTTON1")); + FlexGridSizer2->Add(Button1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button2 = new wxButton(this, ID_BUTTON2, _("Update Selected"), wxDefaultPosition, wxSize(150,25), 0, wxDefaultValidator, _T("ID_BUTTON2")); + FlexGridSizer2->Add(Button2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button3 = new wxButton(this, ID_BUTTON3, _("Update ALL"), wxDefaultPosition, wxSize(150,25), 0, wxDefaultValidator, _T("ID_BUTTON3")); + FlexGridSizer2->Add(Button3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button4 = new wxButton(this, ID_BUTTON4, _("Update only those Required"), wxDefaultPosition, wxSize(150,25), 0, wxDefaultValidator, _T("ID_BUTTON4")); + FlexGridSizer2->Add(Button4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer1->Add(FlexGridSizer2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl1 = new wxTextCtrl(this, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL1")); + TextCtrl1->SetMinSize(wxSize(200,25)); + FlexGridSizer1->Add(TextCtrl1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + SetSizer(FlexGridSizer1); + FlexGridSizer1->Fit(this); + FlexGridSizer1->SetSizeHints(this); + //*) +} + +EasyLights_FSEQ_Dialog::~EasyLights_FSEQ_Dialog() +{ + //(*Destroy(EasyLights_FSEQ_Dialog) + //*) +} + + +void EasyLights_FSEQ_Dialog::InitDialog(wxInitDialogEvent &WXUNUSED(event)) +{ + Get_All_Xlights_FSEQ_Files(); +} + +void EasyLights_FSEQ_Dialog::Set_Busy_Status(int Busy) +{ + wxColour CR(255, 150, 150); + wxColour CG(150, 255, 150); + std::string T; + + FSEQ_Busy = Busy; + + if(Busy) + { + TextCtrl1->SetBackgroundColour(CR); + TextCtrl1->SetStyle(0, -1, TextCtrl1->GetDefaultStyle()); + + T = "Busy Working"; // if blank color won't change + TextCtrl1->SetValue(T); + TextCtrl1->Refresh(); + TextCtrl1->Update(); + + } + else + { + TextCtrl1->SetBackgroundColour(CG); + TextCtrl1->SetStyle(0, -1, TextCtrl1->GetDefaultStyle()); + + T = "Waiting for a Request"; // if blank color won't change + TextCtrl1->SetValue(T); + TextCtrl1->Refresh(); + TextCtrl1->Update(); + + } + + + + +} + +void EasyLights_FSEQ_Dialog::OnButtonCloseClick(wxCommandEvent& event) +{ + Quit_Now = 1; + + while(FSEQ_Busy) + { + wxMilliSleep(100); + } + + // release memory acquired + + for(auto e = FSEQ_Array.begin(); e != FSEQ_Array.end(); ++e) + delete *e; + + for(auto x = FSEQ_Array_Xlights.begin(); x != FSEQ_Array_Xlights.end(); ++x) + delete *x; + + FSEQ_Array.clear(); + FSEQ_Array_Xlights.clear(); + + EasyLights_FSEQ_Dialog_Ptr = 0; + + EndDialog(0); + +} + + +void EasyLights_FSEQ_Dialog::OnButton_Fseq_Selected(wxCommandEvent& event) +{ + if(Button_Active) + return; + + Button_Active = 1; + + Process_Selected_Active = 1; + + Button_Active = 0; + + OnButton_Fseq_Required(event); // this rebuilds as required + + +} + +void EasyLights_FSEQ_Dialog::OnButton_Fseq_All(wxCommandEvent& event) +{ + wxString T; + + if(Button_Active) + return; + + Button_Active = 1; + + if(wxNO == wxMessageBox("Are you Sure you want to Delete all the EasyLights FSEQs and Rebuild them", "Delete and Rebuild All", wxICON_QUESTION | wxYES_NO)) + { + Button_Active = 0; + + return; + } + + Set_Busy_Status(1); + + int i = 0; + + for(auto e = FSEQ_Array.begin(); e != FSEQ_Array.end(); ++e, i++) + { + if(Quit_Now) + break; + + if((*e)->ELC_FN_DT_Value != 0) // valid file + { + T = wxString::Format("Removing %s", (*e)->ELC_FN_short); + Write_Msg_to_Display(T); + + wxRemove((*e)->ELC_FN_long); + (*e)->ELC_FN_DT_Value = 0; + (*e)->ELC_FN_DT = 0; + Grid1->SetCellValue(i, 6, ""); + } + } + +// now remove PCM files + + std::string FN_search; + std::string FN; + + + FN_search = EL_Ptr->ShowDirectory + "\\EasyLightsData\\*.wav"; + + FN = wxFindFirstFile(FN_search); + + while(!FN.empty()) + { + T = wxString::Format("Removing %s", FN); + Write_Msg_to_Display(T); + + wxRemove(FN); + FN = wxFindNextFile(); + } + + + + Button_Active = 0; + + OnButton_Fseq_Required(event); // this rebuilds as required + + +} + +void EasyLights_FSEQ_Dialog::OnButton_Fseq_Required(wxCommandEvent& event) +{ + int i = 0; + wxString T; + std::string EL_Dir_Path; + std::string EL_WAV; + std::string EL_PCM; + wxFileName FN; + int r; + int Create_WAV = 0; + uint32_t Size_PCM_Bytes; + uint32_t Sample_Rate_Used; + wxColour CW(255, 255, 255); + + + + if(Button_Active) + return; + + Button_Active = 1; + Set_Busy_Status(1); + + EL_Dir_Path = EL_Ptr->ShowDirectory + "\\EasyLightsData\\"; + + + for(auto e = FSEQ_Array.begin(); e != FSEQ_Array.end(); ++e, i++) + { + if(Quit_Now) + break; + + if(Process_Selected_Active && (*e)->Process == 0) + continue; + + if(Process_Selected_Active && (*e)->Process) + { + (*e)->Process = 0; // kill process flag as we are doing it + Grid1->SetCellBackgroundColour((*e)->Grid_Row, 2, CW); + Grid1->SetCellValue((*e)->Grid_Row, 2, (*e)->IX->FN_short); + } + + if(Process_Selected_Active || ((*e)->ELC_FN_DT_Value < (*e)->IX->FN_DT_Value)) // xlights fseq newer + { + if((*e)->ELC_FN_DT_Value != 0) // valid file + { + T = wxString::Format("Removing %s", (*e)->ELC_FN_short); + Write_Msg_to_Display(T); + + wxRemove((*e)->ELC_FN_long); + (*e)->ELC_FN_DT_Value = 0; + (*e)->ELC_FN_DT = 0; + Grid1->SetCellValue(i, 6, ""); + } + + // check if audio is needed + + FN = EL_Dir_Path + (*e)->IX->FN_short + ".wav"; + + EL_PCM = EL_Dir_Path + "PCM"; + + Create_WAV = 0; + + if(!FN.Exists()) // we need to make it + Create_WAV = 1; + else if(FN.GetSize() < 2048) // previous conversion failed + Create_WAV = 1; + + + if(Create_WAV || Process_Selected_Active) // we need to make it + { + T = wxString::Format("Creating Audio PCM file for %s.fseq", (*e)->IX->FN_short); + Write_Msg_to_Display(T); + + EL_WAV = FN.GetFullPath(); + + r = Create_EasyLights_PCM_File((*e)->IX->FN_long, EL_PCM, this, &Size_PCM_Bytes, &Sample_Rate_Used); // path to xlights fseq and wxfilename to pcm + + if(r == 0) + { + r = Make_WAV_From_PCM(EL_PCM, EL_WAV, Size_PCM_Bytes, Sample_Rate_Used); + + if(r == 0) + { + Write_Msg_to_Display("ELC Audio File Completed - no Errors"); + } + } + + } + + // check if we need to build a EL fseq + + FN = (*e)->ELC_FN_long; + + if(!FN.Exists()) // we need to make it + { + r = Create_EasyLights_FSEQ_File(*e, this); // path to xlights fseq and wxfilename to pcm + if(r == 0) + { + (*e)->ELC_FN_DT = FN.GetModificationTime(); + + if((*e)->ELC_FN_DT.IsValid()) + (*e)->ELC_FN_DT_Value = (*e)->ELC_FN_DT.GetValue(); + else + (*e)->ELC_FN_DT_Value = 0; // should never happen + + if((*e)->ELC_FN_DT_Value != 0) + Grid1->SetCellValue((*e)->Grid_Row, 6, (*e)->ELC_FN_DT.FormatDate()); + + + Write_Msg_to_Display("ELC FSEQ File Completed - no Errors"); + } + + + + } + + + + } + } + + + + + Process_Selected_Active = 0; + Set_Busy_Status(0); + Button_Active = 0; + +} + + + +void EasyLights_FSEQ_Dialog::Get_All_Xlights_FSEQ_Files() +{ + + wxFileName fseq_file = "*.fseq"; + std::string FN; + std::string fsearch; + EL_FSEQ_Info *I; + EL_FSEQ_Info_Xlights *IX; + std::string EL_Dir_Path; + wxFileName ELC_fseq; + std::string IPdash; + int i; + + // set up list display + + wxListItem itemCol; + + itemCol.SetText(wxT("Name")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(0, itemCol); + ListCtrl1->SetColumnWidth(0, 1000); + + + Write_Msg_to_Display("Fseq Searching Now"); + + // Only Look for FSEQ file in FSEQ FOLDER, if folder are unlinked + if(wxFileName(EL_Ptr->FseqDirectory) != wxFileName(EL_Ptr->ShowDirectory)) + { + fseq_file.SetPath(EL_Ptr->FseqDirectory); + } + else + { + fseq_file.SetPath(EL_Ptr->ShowDirectory); + } + + + fsearch = fseq_file.GetFullPath(); + + FN = wxFindFirstFile(fsearch); + +/*** + std::string FN_long; + std::string FN_short; + wxDateTime FN_DT; + int FN_DT_Value; + + + EL_FSEQ_Info_Xlights *X; + std::string ELC_IP; + std::string ELC_FN_long; + std::string ELC_FN_short; + wxDateTime ELC_FN_DT; + wxLongLong ELC_FN_DT_Value; +**/ + + while(!FN.empty()) + { + fseq_file = FN; + + IX = new EL_FSEQ_Info_Xlights; + IX->FN_long = FN; + IX->FN_short = fseq_file.GetName(); + + IX->Version = Return_FSEQ_Version(FN); + + IX->FN_DT = fseq_file.GetModificationTime(); + + if(IX->FN_DT.IsValid()) + IX->FN_DT_Value = IX->FN_DT.GetValue(); + else + IX->FN_DT_Value = 0; // should never happen + + FSEQ_Array_Xlights.push_back(IX); + + // now add ELC's + + for(auto it = EL_Ptr->EL_EndPoints.begin(); it != EL_Ptr->EL_EndPoints.end(); ++it) + { + if((*it)->Model != "Undefined") // we have a ELC + { + I = new EL_FSEQ_Info; + I->IX = IX; + I->EP = *it; + I->ELC_IP = (*it)->IP; + I->ELC_FN_DT = 0; + I->ELC_FN_DT_Value = 0; + I->ELC_Name = (*it)->Name; + I->Process = 0; + I->Grid_Row = 0; + + FSEQ_Array.push_back(I); + } + } + + FN = wxFindNextFile(); + } + + // get here with all Xlights FSEQs in and array and an array of ELC fseq that may need to be created + + EL_Dir_Path = EL_Ptr->ShowDirectory + "\\EasyLightsData\\"; + + for(auto e = FSEQ_Array.begin(); e != FSEQ_Array.end(); ++e) + { + // construct base file name for this IP's fseq file + + IPdash = (*e)->ELC_IP; + + for(i = 0; i < IPdash.size(); i++) + { + if(IPdash[i] == '.') + IPdash[i] = '_'; + } + + FN = (*e)->IX->FN_short + " " + IPdash + ".fseq"; + + ELC_fseq = EL_Dir_Path + FN; + + // test for well formed file name + + if(!ELC_fseq.IsOk()) + { + wxString Z = wxString::Format("Bad File Name %s", ELC_fseq.GetFullPath()); + Write_Msg_to_Display(Z); + continue; + } + + (*e)->ELC_FN_short = FN; + + (*e)->ELC_FN_long = ELC_fseq.GetFullPath(); + + if(ELC_fseq.FileExists()) // we have a real file out there, get values + { + (*e)->ELC_FN_DT = ELC_fseq.GetModificationTime(); + + if((*e)->ELC_FN_DT.IsValid()) + (*e)->ELC_FN_DT_Value = (*e)->ELC_FN_DT.GetValue(); + else + (*e)->ELC_FN_DT_Value = 0; // should never happen + } + else + { + (*e)->ELC_FN_DT = 0; + (*e)->ELC_FN_DT_Value = 0; + } + + + } + + // we can now build the grid + + i = 0; + + + //wxColour CR(255, 150, 150); + + + + + + for(auto e = FSEQ_Array.begin(); e != FSEQ_Array.end(); ++e, i++) + { + // have two hidden rows - not using them right now -- using vector instead + + Grid1->InsertRows(i, 1); + Grid1->SetCellValue(i, 2, (*e)->IX->FN_short); + Grid1->SetCellValue(i, 3, (*e)->IX->FN_DT.FormatDate()); + Grid1->SetCellValue(i, 4, (*e)->ELC_Name); + Grid1->SetCellValue(i, 5, (*e)->ELC_IP); + + (*e)->Grid_Row = i; + + //if((*e)->IX->Version != 1) + // Grid1->SetCellBackgroundColour(i, 2, CR); + + if((*e)->ELC_FN_DT_Value != 0) + Grid1->SetCellValue(i, 6, (*e)->ELC_FN_DT.FormatDate()); + } +} + + +void EasyLights_FSEQ_Dialog::Write_Msg_to_Display(char *S) +{ + int r = ListCtrl1->GetItemCount(); + + ListCtrl1->InsertItem(r, S); +} + +void EasyLights_FSEQ_Dialog::Write_Msg_to_Display(std::string &S) +{ + int r = ListCtrl1->GetItemCount(); + + ListCtrl1->InsertItem(r, S); + +} + + +void EasyLights_FSEQ_Dialog::Write_Msg_to_Display(wxString &S) +{ + int r = ListCtrl1->GetItemCount(); + + ListCtrl1->InsertItem(r, S); + +} + + +void EasyLights_FSEQ_Dialog::OnGridCellLeftClick(wxGridEvent &event) +{ + int Row = event.GetRow(); + int Col = event.GetCol(); + wxColour CB(200, 200, 255); + wxColour CW(255, 255, 255); + EL_FSEQ_Info *e; + + + if(Col != 2) + return; + + + if(Row < 0 || Row > EasyLights_FSEQ_Dialog_Ptr->FSEQ_Array.size()) + return; + + e = EasyLights_FSEQ_Dialog_Ptr->FSEQ_Array[Row]; + + if(e->Process == 0) + { + e->Process = 1; + + EasyLights_FSEQ_Dialog_Ptr->Grid1->SetCellBackgroundColour(Row, 2, CB); + EasyLights_FSEQ_Dialog_Ptr->Grid1->SetCellValue(Row, 2, e->IX->FN_short); + } + else + { + e->Process = 0; + + EasyLights_FSEQ_Dialog_Ptr->Grid1->SetCellBackgroundColour(Row, 2, CW); + EasyLights_FSEQ_Dialog_Ptr->Grid1->SetCellValue(Row, 2, e->IX->FN_short); + } + + +} \ No newline at end of file diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_FSEQ_Dialog.h b/xLights/controllers/EasyLights_Utils/EasyLights_FSEQ_Dialog.h new file mode 100644 index 0000000000..6cf4583ac3 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_FSEQ_Dialog.h @@ -0,0 +1,121 @@ +#ifndef EASYLIGHTS_FSEQ_DIALOG_H +#define EASYLIGHTS_FSEQ_DIALOG_H + +//(*Headers(EasyLights_FSEQ_Dialog) +#include +#include +#include +#include +#include +#include +#include +//*) + +class EasyLights_EndPoint; + +class EL_FSEQ_Info_Xlights +{ +public: + std::string FN_long; + std::string FN_short; + wxDateTime FN_DT; + wxLongLong FN_DT_Value; + int Version; +}; + +class EL_FSEQ_Info +{ +public: + EL_FSEQ_Info_Xlights *IX; + EasyLights_EndPoint *EP; + std::string ELC_IP; + std::string ELC_Name; + std::string ELC_FN_long; + std::string ELC_FN_short; + wxDateTime ELC_FN_DT; + wxLongLong ELC_FN_DT_Value; + int Process; + int Grid_Row; +}; + + +class EasyLights_FSEQ_Dialog: public wxDialog +{ + public: + + EasyLights_FSEQ_Dialog(wxWindow* parent,wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize); + virtual ~EasyLights_FSEQ_Dialog(); + + //(*Declarations(EasyLights_FSEQ_Dialog) + wxButton* Button1; + wxButton* Button2; + wxButton* Button3; + wxButton* Button4; + wxGrid* Grid1; + wxListCtrl* ListCtrl1; + wxStaticText* StaticText1; + wxStaticText* StaticText2; + wxTextCtrl* TextCtrl1; + //*) + + protected: + + //(*Identifiers(EasyLights_FSEQ_Dialog) + static const long ID_STATICTEXT1; + static const long ID_STATICTEXT2; + static const long ID_GRID1; + static const long ID_LISTCTRL1; + static const long ID_BUTTON1; + static const long ID_BUTTON2; + static const long ID_BUTTON3; + static const long ID_BUTTON4; + static const long ID_TEXTCTRL1; + //*) + + private: + + //(*Handlers(EasyLights_FSEQ_Dialog) + void OnInit(wxInitDialogEvent& event); + //*) + + void OnGridCellLeftClick(wxGridEvent &event); + void InitDialog(wxInitDialogEvent &event); + + protected: + + void BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size); + + DECLARE_EVENT_TABLE() + + + + +public: + + void Get_All_Xlights_FSEQ_Files(); + + std::vector< EL_FSEQ_Info*> FSEQ_Array; + std::vector< EL_FSEQ_Info_Xlights*> FSEQ_Array_Xlights; + + void Write_Msg_to_Display(char *S); + void Write_Msg_to_Display(std::string &S); + void Write_Msg_to_Display(wxString &S); + + + + + void OnButtonCloseClick(wxCommandEvent& event); + void OnButton_Fseq_Selected(wxCommandEvent& event); + void OnButton_Fseq_All(wxCommandEvent& event); + void OnButton_Fseq_Required(wxCommandEvent& event); + + void Set_Busy_Status(int Busy); + + int Quit_Now; + int FSEQ_Busy; + int Button_Active; + int Process_Selected_Active; + +}; + +#endif diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_Identify_Dialog.cpp b/xLights/controllers/EasyLights_Utils/EasyLights_Identify_Dialog.cpp new file mode 100644 index 0000000000..2fa851b126 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_Identify_Dialog.cpp @@ -0,0 +1,450 @@ +#include +#include +#include +#include + +#include +#include + + +#include "../../models/Model.h" +#include "../../outputs/OutputManager.h" +#include "../../outputs/Output.h" +#include "../../models/ModelManager.h" + + +#include +#include "UtilFunctions.h" +#include + +#include + +#include "../../models/Model.h" +#include "../../outputs/OutputManager.h" +#include "../../outputs/Output.h" +#include "../../models/ModelManager.h" + +#include "EasyLights_Identify_Dialog.h" +#include "../EasyLights.h" +#include "EasyLights_Data.h" + + + +//(*InternalHeaders(EasyLights_Identify_Dialog) +#include +#include +//*) + +//(*IdInit(EasyLights_Identify_Dialog) +const long EasyLights_Identify_Dialog::ID_STATICTEXT1 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_LISTCTRL1 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_STATICTEXT2 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_TEXTCTRL1 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_STATICTEXT3 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_TEXTCTRL2 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_STATICTEXT5 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_CHOICE2 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_CHECKBOX1 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_CHECKBOX2 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_BUTTON1 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_BUTTON2 = wxNewId(); +const long EasyLights_Identify_Dialog::ID_BUTTON3 = wxNewId(); +//*) + +BEGIN_EVENT_TABLE(EasyLights_Identify_Dialog,wxDialog) + //(*EventTable(EasyLights_Identify_Dialog) + EVT_INIT_DIALOG(EasyLights_Identify_Dialog::InitDialog) + //*) +END_EVENT_TABLE() + +EasyLights_Identify_Dialog::EasyLights_Identify_Dialog(wxWindow* parent, wxWindowID id,const wxPoint& pos,const wxSize& size) +{ + Selected_EndPoint = 0; + Dirty = 0; + Selected_EndPoint_Index = 0; + + BuildContent(parent,id,pos,size); + + + wxListItem itemCol; + + itemCol.SetText(wxT("Name")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(0, itemCol); + ListCtrl1->SetColumnWidth(0, 200); + + itemCol.SetText(wxT("IP")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(1, itemCol); + ListCtrl1->SetColumnWidth(1, 100); + + itemCol.SetText(wxT("Type")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(2, itemCol); + ListCtrl1->SetColumnWidth(2, 150); + + itemCol.SetText(wxT("Channels")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(3, itemCol); + ListCtrl1->SetColumnWidth(3, 150); + + + itemCol.SetText(wxT("Master")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(4, itemCol); + ListCtrl1->SetColumnWidth(4, 100); + + + itemCol.SetText(wxT("Audio")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(5, itemCol); + ListCtrl1->SetColumnWidth(5, 100); + + Connect(ID_BUTTON1, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Identify_Dialog::OnButton_Cancel); + Connect(ID_BUTTON2, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Identify_Dialog::OnButton_Edit); + Connect(ID_BUTTON3, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Identify_Dialog::OnButton_Apply); + + +} + +void EasyLights_Identify_Dialog::BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) +{ + //(*Initialize(EasyLights_Identify_Dialog) + wxFlexGridSizer* FlexGridSizer1; + wxFlexGridSizer* FlexGridSizer2; + wxFlexGridSizer* FlexGridSizer3; + + Create(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("id")); + SetClientSize(wxDefaultSize); + Move(wxDefaultPosition); + FlexGridSizer1 = new wxFlexGridSizer(0, 1, 0, 0); + StaticText1 = new wxStaticText(this, ID_STATICTEXT1, _("E131 Controllers on your Network"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1")); + FlexGridSizer1->Add(StaticText1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + ListCtrl1 = new wxListCtrl(this, ID_LISTCTRL1, wxDefaultPosition, wxSize(850,250), wxLC_REPORT|wxLC_SINGLE_SEL|wxVSCROLL, wxDefaultValidator, _T("ID_LISTCTRL1")); + FlexGridSizer1->Add(ListCtrl1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer2 = new wxFlexGridSizer(5, 2, 0, 0); + StaticText2 = new wxStaticText(this, ID_STATICTEXT2, _("IP Address"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2")); + FlexGridSizer2->Add(StaticText2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl1 = new wxTextCtrl(this, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxSize(100,25), wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL1")); + FlexGridSizer2->Add(TextCtrl1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText3 = new wxStaticText(this, ID_STATICTEXT3, _("Controller\'s Name"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT3")); + FlexGridSizer2->Add(StaticText3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl2 = new wxTextCtrl(this, ID_TEXTCTRL2, wxEmptyString, wxDefaultPosition, wxSize(200,25), 0, wxDefaultValidator, _T("ID_TEXTCTRL2")); + FlexGridSizer2->Add(TextCtrl2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText5 = new wxStaticText(this, ID_STATICTEXT5, _("Controller Model"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT5")); + FlexGridSizer2->Add(StaticText5, 1, wxALL|wxALIGN_TOP|wxALIGN_CENTER_HORIZONTAL, 5); + Choice2 = new wxChoice(this, ID_CHOICE2, wxDefaultPosition, wxSize(200,88), 0, 0, 0, wxDefaultValidator, _T("ID_CHOICE2")); + FlexGridSizer2->Add(Choice2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer2->Add(-1,-1,1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + CheckBox1 = new wxCheckBox(this, ID_CHECKBOX1, _("StandAlone Master"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHECKBOX1")); + CheckBox1->SetValue(false); + FlexGridSizer2->Add(CheckBox1, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer2->Add(-1,-1,1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + CheckBox2 = new wxCheckBox(this, ID_CHECKBOX2, _("Plays the Audio"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHECKBOX2")); + CheckBox2->SetValue(false); + FlexGridSizer2->Add(CheckBox2, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer1->Add(FlexGridSizer2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer3 = new wxFlexGridSizer(0, 3, 0, 0); + Button1 = new wxButton(this, ID_BUTTON1, _("Cancel Change"), wxDefaultPosition, wxSize(100,25), 0, wxDefaultValidator, _T("ID_BUTTON1")); + FlexGridSizer3->Add(Button1, 1, wxALL|wxEXPAND, 5); + Button2 = new wxButton(this, ID_BUTTON2, _("Edit"), wxDefaultPosition, wxSize(75,25), 0, wxDefaultValidator, _T("ID_BUTTON2")); + FlexGridSizer3->Add(Button2, 1, wxALL|wxEXPAND, 5); + Button3 = new wxButton(this, ID_BUTTON3, _("Accept Change"), wxDefaultPosition, wxSize(100,25), 0, wxDefaultValidator, _T("ID_BUTTON3")); + FlexGridSizer3->Add(Button3, 1, wxALL|wxEXPAND, 5); + FlexGridSizer1->Add(FlexGridSizer3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + SetSizer(FlexGridSizer1); + FlexGridSizer1->Fit(this); + FlexGridSizer1->SetSizeHints(this); + //*) +} + +EasyLights_Identify_Dialog::~EasyLights_Identify_Dialog() +{ + //(*Destroy(EasyLights_Identify_Dialog) + //*) +} + +void EasyLights_Identify_Dialog::InitDialog(wxInitDialogEvent &WXUNUSED(event)) +{ + Load_Combo(); + + Load_I_List(); + +} + +void EasyLights_Identify_Dialog::Load_I_List() +{ + wxString T; + int i = 0; + + for(auto it = EL_Ptr->EL_EndPoints.begin(); it != EL_Ptr->EL_EndPoints.end(); ++it, i++) + { + T.Printf("%s", (*it)->Name); + ListCtrl1->InsertItem(i, T, -1); + ListCtrl1->SetItemData(i, i); + + T.Printf("%s", (*it)->IP); + ListCtrl1->SetItem(i, 1, T); + + if((*it)->Model.size() == 0) + (*it)->Model = "Undefined"; + + T.Printf("%s", (*it)->Model); + ListCtrl1->SetItem(i, 2, T); + + T.Printf("%d", (*it)->Channels_Used); + ListCtrl1->SetItem(i, 3, T); + + if((*it)->Master) + T = "Yes"; + else + T = "No"; + ListCtrl1->SetItem(i, 4, T); + + if((*it)->Audio) + T = "Yes"; + else + T = "No"; + ListCtrl1->SetItem(i, 5, T); + + + } +} + + + +void EasyLights_Identify_Dialog::Load_Combo() +{ + wxString T; + + + Choice2->Append(wxT("Undefined")); + + for(auto it = EL_Ptr->EL_Controller.begin(); it != EL_Ptr->EL_Controller.end(); ++it) + { + T = (*it)->Model; + Choice2->Append(T); + } +} + +void EasyLights_Identify_Dialog::OnButton_Cancel(wxCommandEvent& event) +{ + Selected_EndPoint = 0; + TransferDataToWindow(); + +} + +void EasyLights_Identify_Dialog::OnButton_Edit(wxCommandEvent& event) +{ + if(ListCtrl1->GetSelectedItemCount() == 0) + return; + + Selected_EndPoint_Index = ListCtrl1->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if(Selected_EndPoint_Index < 0) + return; + + Selected_EndPoint = (EL_Ptr->EL_EndPoints)[Selected_EndPoint_Index]; + + if(EL_Ptr->ELC_Master && Selected_EndPoint != EL_Ptr->ELC_Master) // can't allow Master to be modified + { + CheckBox1->Enable(FALSE); + } + else // allow modification + { + CheckBox1->Enable(TRUE); + } + + if(EL_Ptr->ELC_Audio && Selected_EndPoint != EL_Ptr->ELC_Audio) // can't allow Master to be modified + { + CheckBox2->Enable(FALSE); + } + else // allow modification + { + CheckBox2->Enable(TRUE); + } + + + TransferDataToWindow(); + +} + +void EasyLights_Identify_Dialog::OnButton_Apply(wxCommandEvent& event) +{ + if(Selected_EndPoint == 0) + return; + + TransferDataFromWindow(); + +// record any changes to Master and Audio + + if(Selected_EndPoint->Master && EL_Ptr->ELC_Master == 0) + EL_Ptr->ELC_Master = Selected_EndPoint; + + if(Selected_EndPoint->Audio && EL_Ptr->ELC_Audio == 0) + EL_Ptr->ELC_Audio = Selected_EndPoint; + + if(Selected_EndPoint == EL_Ptr->ELC_Master && Selected_EndPoint->Master == 0) + EL_Ptr->ELC_Master = 0; + + if(Selected_EndPoint == EL_Ptr->ELC_Audio && Selected_EndPoint->Audio == 0) + EL_Ptr->ELC_Audio = 0; + + + + Update_Selected_List_Item(); + + Dirty = 1; + + Selected_EndPoint = 0; // make the input blank + TransferDataToWindow(); + +} + +bool EasyLights_Identify_Dialog::TransferDataToWindow() +{ + wxString T; + int Choice; + wxColour CR(255, 150, 150); + wxColour CG(150, 255, 150); + + if(Selected_EndPoint == 0) + { + T = ""; + TextCtrl1->SetValue(T); + + TextCtrl2->SetBackgroundColour(CR); + TextCtrl2->SetStyle(0, -1, TextCtrl1->GetDefaultStyle()); + + T = "test"; + TextCtrl2->SetValue(T); + T = ""; + TextCtrl2->SetValue(T); + + Choice2->SetSelection(0); + + CheckBox1->SetValue(0); + CheckBox2->SetValue(0); + + return true; + } + + T = Selected_EndPoint->IP; + TextCtrl1->SetValue(T); + + TextCtrl2->SetBackgroundColour(CG); + TextCtrl2->SetStyle(0, -1, TextCtrl1->GetDefaultStyle()); + + T = "test"; // if blank color won't change + TextCtrl2->SetValue(T); + + T = Selected_EndPoint->Name; + TextCtrl2->SetValue(T); + + Choice = Return_Model_Selection_Index(Selected_EndPoint->Model); + Choice2->SetSelection(Choice); + + CheckBox1->SetValue(Selected_EndPoint->Master); + CheckBox2->SetValue(Selected_EndPoint->Audio); + + return true; +} + +bool EasyLights_Identify_Dialog::TransferDataFromWindow() +{ + int Choice; + + if(Selected_EndPoint == 0) + return true; + + Selected_EndPoint->Name = TextCtrl2->GetValue(); + + Choice = Choice2->GetSelection(); + Set_EndPoint_Model_String_From_Choice_Index(Choice); + + // Choice == 0 for slave + + if(Choice) // only for ELC + { + Selected_EndPoint->Master = CheckBox1->GetValue(); + Selected_EndPoint->Audio = CheckBox2->GetValue(); + } + + return true; +} + + +int EasyLights_Identify_Dialog::Return_Model_Selection_Index(std::string &M) +{ + int i = 1; + + if(M == "Undefined") + return 0; + + for(auto it = EL_Ptr->EL_Controller.begin(); it != EL_Ptr->EL_Controller.end(); ++it, i++) + { + if((*it)->Model == M) + return i; + } + + return 0; + +} + +void EasyLights_Identify_Dialog::Set_EndPoint_Model_String_From_Choice_Index(int I) +{ + if(Selected_EndPoint == 0) + return; + + if(I == 0) + Selected_EndPoint->Model = "Undefined"; + else + { + Selected_EndPoint->Model = (EL_Ptr->EL_Controller)[I-1]->Model; + } +} + + +void EasyLights_Identify_Dialog::Update_Selected_List_Item() +{ + wxString T; + + if(Selected_EndPoint == 0) + return; + + T.Printf("%s", Selected_EndPoint->Name); + ListCtrl1->SetItem(Selected_EndPoint_Index, 0, T); + + if(Selected_EndPoint->Model.size() == 0) + Selected_EndPoint->Model = "Undefined"; + + T.Printf("%s", Selected_EndPoint->Model); + ListCtrl1->SetItem(Selected_EndPoint_Index, 2, T); + + if(Selected_EndPoint->Model != "Undefined") + { + if(Selected_EndPoint->Master) + T = "Yes"; + else + T = "No"; + ListCtrl1->SetItem(Selected_EndPoint_Index, 4, T); + + if(Selected_EndPoint->Audio) + T = "Yes"; + else + T = "No"; + ListCtrl1->SetItem(Selected_EndPoint_Index, 5, T); + + // we have a easylights controller - update all controller max values + + Set_EndPoint_EL_Max_Controller_Values(Selected_EndPoint); + + } + else + { + T = "No"; + ListCtrl1->SetItem(Selected_EndPoint_Index, 4, T); + ListCtrl1->SetItem(Selected_EndPoint_Index, 5, T); + } + + +} diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_Identify_Dialog.h b/xLights/controllers/EasyLights_Utils/EasyLights_Identify_Dialog.h new file mode 100644 index 0000000000..4073aa6f09 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_Identify_Dialog.h @@ -0,0 +1,95 @@ +#ifndef EASYLIGHTS_IDENTIFY_DIALOG_H +#define EASYLIGHTS_IDENTIFY_DIALOG_H + +//(*Headers(EasyLights_Identify_Dialog) +#include +#include +#include +#include +#include +#include +#include +#include +//*) + +class EasyLights_EndPoint; +class EL_Controller_Info; + +class EasyLights_Identify_Dialog: public wxDialog +{ + public: + + EasyLights_Identify_Dialog(wxWindow* parent, wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize); + virtual ~EasyLights_Identify_Dialog(); + + //(*Declarations(EasyLights_Identify_Dialog) + wxButton* Button1; + wxButton* Button2; + wxButton* Button3; + wxCheckBox* CheckBox1; + wxCheckBox* CheckBox2; + wxChoice* Choice2; + wxListCtrl* ListCtrl1; + wxStaticText* StaticText1; + wxStaticText* StaticText2; + wxStaticText* StaticText3; + wxStaticText* StaticText5; + wxTextCtrl* TextCtrl1; + wxTextCtrl* TextCtrl2; + //*) + + protected: + + //(*Identifiers(EasyLights_Identify_Dialog) + static const long ID_STATICTEXT1; + static const long ID_LISTCTRL1; + static const long ID_STATICTEXT2; + static const long ID_TEXTCTRL1; + static const long ID_STATICTEXT3; + static const long ID_TEXTCTRL2; + static const long ID_STATICTEXT5; + static const long ID_CHOICE2; + static const long ID_CHECKBOX1; + static const long ID_CHECKBOX2; + static const long ID_BUTTON1; + static const long ID_BUTTON2; + static const long ID_BUTTON3; + //*) + + private: + + //(*Handlers(EasyLights_Identify_Dialog) + + void OnButton_Cancel(wxCommandEvent& event); + void OnButton_Edit(wxCommandEvent& event); + void OnButton_Apply(wxCommandEvent& event); + bool TransferDataToWindow(); + bool TransferDataFromWindow(); + void InitDialog(wxInitDialogEvent &event); + + //*) + + protected: + + void BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size); + + DECLARE_EVENT_TABLE() + +public: + + void Load_Combo(); + void Load_I_List(); + + EasyLights_EndPoint *Selected_EndPoint; + + + int Selected_EndPoint_Index; + int Return_Model_Selection_Index(std::string &M); + void Set_EndPoint_Model_String_From_Choice_Index(int I); + void Update_Selected_List_Item(); + + int Dirty; + +}; + +#endif diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_PlayList_Dialog.cpp b/xLights/controllers/EasyLights_Utils/EasyLights_PlayList_Dialog.cpp new file mode 100644 index 0000000000..7a3a9c50e9 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_PlayList_Dialog.cpp @@ -0,0 +1,678 @@ +#include +#include +#include +#include + +#include +#include + +#include "../../models/Model.h" +#include "../../outputs/OutputManager.h" +#include "../../outputs/Output.h" +#include "../../models/ModelManager.h" + + +#include +#include "UtilFunctions.h" +#include +#include + +#include + +#include "../../models/Model.h" +#include "../../outputs/OutputManager.h" +#include "../../outputs/Output.h" +#include "../../models/ModelManager.h" + +#include "../EasyLights.h" + +#include "../EasyLights.h" +#include "EasyLights_Data.h" +#include "EasyLights_PlayList_Dialog.h" +#include "../../xlightsMain.h" + + +//(*IdInit(EasyLights_PlayList_Dialog) +const long EasyLights_PlayList_Dialog::ID_STATICTEXT1 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_LISTCTRL1 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_STATICTEXT2 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_LISTCTRL2 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_STATICTEXT4 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_BUTTON7 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_TEXTCTRL1 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_BUTTON2 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_BUTTON3 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_STATICTEXT3 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_TEXTCTRL2 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_GRID1 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_BUTTON1 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_BUTTON5 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_BUTTON6 = wxNewId(); +const long EasyLights_PlayList_Dialog::ID_STATICTEXT5 = wxNewId(); +//*) + +BEGIN_EVENT_TABLE(EasyLights_PlayList_Dialog,wxDialog) + //(*EventTable(EasyLights_PlayList_Dialog) + EVT_INIT_DIALOG(EasyLights_PlayList_Dialog::InitDialog) + EVT_LIST_ITEM_SELECTED(EasyLights_PlayList_Dialog::ID_LISTCTRL1, EasyLights_PlayList_Dialog::OnList1_Seq_Selected) + EVT_GRID_SELECT_CELL(EasyLights_PlayList_Dialog::OnGridCellLeftClick) + EVT_GRID_CELL_RIGHT_CLICK(EasyLights_PlayList_Dialog::OnGridCellRightClick) + + + //*) +END_EVENT_TABLE() + +EasyLights_PlayList_Dialog::EasyLights_PlayList_Dialog(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) +{ + PLWork_Active = 0; + Grid_Left_Row = 0; + Grid_Left_Col = 0; + + + BuildContent(parent,id,pos,size); + + Connect(ID_BUTTON7, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_PlayList_Dialog::OnButton_New_PlayList); + Connect(ID_BUTTON2, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_PlayList_Dialog::OnButton_Edit_PlayList); + Connect(ID_BUTTON3, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_PlayList_Dialog::OnButton_Delete_PlayList); + Connect(ID_BUTTON5, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_PlayList_Dialog::OnButton_Remove_PlayList); + Connect(ID_BUTTON6, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_PlayList_Dialog::OnButton_Save_PlayList); + Connect(ID_BUTTON1, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_PlayList_Dialog::OnButton_Add_End_PlayList); + + + + Connect(wxID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_PlayList_Dialog::OnButtonCloseClick); + Connect(wxID_ANY, wxEVT_CLOSE_WINDOW, (wxObjectEventFunction)&EasyLights_PlayList_Dialog::OnButtonCloseClick); + +} + +void EasyLights_PlayList_Dialog::BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) +{ + //(*Initialize(EasyLights_PlayList_Dialog) + wxFlexGridSizer* FlexGridSizer1; + wxFlexGridSizer* FlexGridSizer2; + wxFlexGridSizer* FlexGridSizer3; + wxFlexGridSizer* FlexGridSizer4; + wxFlexGridSizer* FlexGridSizer5; + wxFlexGridSizer* FlexGridSizer6; + + Create(parent, wxID_ANY, _("EasyLights PlayList Manager"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("wxID_ANY")); + FlexGridSizer1 = new wxFlexGridSizer(0, 2, 0, 0); + FlexGridSizer2 = new wxFlexGridSizer(0, 1, 0, 0); + StaticText1 = new wxStaticText(this, ID_STATICTEXT1, _("Sequences"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1")); + FlexGridSizer2->Add(StaticText1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + ListCtrl1 = new wxListCtrl(this, ID_LISTCTRL1, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_NO_HEADER|wxVSCROLL, wxDefaultValidator, _T("ID_LISTCTRL1")); + ListCtrl1->SetMinSize(wxSize(300,200)); + FlexGridSizer2->Add(ListCtrl1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText2 = new wxStaticText(this, ID_STATICTEXT2, _("PlayLists"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2")); + FlexGridSizer2->Add(StaticText2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + ListCtrl2 = new wxListCtrl(this, ID_LISTCTRL2, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_NO_HEADER|wxVSCROLL, wxDefaultValidator, _T("ID_LISTCTRL2")); + ListCtrl2->SetMinSize(wxSize(300,150)); + FlexGridSizer2->Add(ListCtrl2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer6 = new wxFlexGridSizer(0, 2, 0, 0); + FlexGridSizer6->Add(-1,-1,1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText4 = new wxStaticText(this, ID_STATICTEXT4, _("New PlayList Name"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT4")); + FlexGridSizer6->Add(StaticText4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button7 = new wxButton(this, ID_BUTTON7, _("New Playlist"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON7")); + FlexGridSizer6->Add(Button7, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl1 = new wxTextCtrl(this, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TEXTCTRL1")); + TextCtrl1->SetMinSize(wxSize(200,25)); + FlexGridSizer6->Add(TextCtrl1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer2->Add(FlexGridSizer6, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer4 = new wxFlexGridSizer(0, 2, 0, 0); + Button2 = new wxButton(this, ID_BUTTON2, _("Edit"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON2")); + FlexGridSizer4->Add(Button2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button3 = new wxButton(this, ID_BUTTON3, _("Delete"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON3")); + FlexGridSizer4->Add(Button3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer2->Add(FlexGridSizer4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer1->Add(FlexGridSizer2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer3 = new wxFlexGridSizer(0, 1, 0, 0); + StaticText3 = new wxStaticText(this, ID_STATICTEXT3, _("PlayList Details"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT3")); + FlexGridSizer3->Add(StaticText3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl2 = new wxTextCtrl(this, ID_TEXTCTRL2, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL2")); + TextCtrl2->SetMinSize(wxSize(250,25)); + FlexGridSizer3->Add(TextCtrl2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Grid1 = new wxGrid(this, ID_GRID1, wxDefaultPosition, wxDefaultSize, wxVSCROLL, _T("ID_GRID1")); + Grid1->CreateGrid(0,2); + Grid1->SetMinSize(wxSize(300,350)); + Grid1->EnableEditing(true); + Grid1->EnableGridLines(true); + Grid1->SetColLabelValue(0, _("Sequence")); + Grid1->SetColLabelValue(1, _("Delay")); + Grid1->SetDefaultCellFont( Grid1->GetFont() ); + Grid1->SetDefaultCellTextColour( Grid1->GetForegroundColour() ); + FlexGridSizer3->Add(Grid1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer5 = new wxFlexGridSizer(0, 3, 0, 0); + Button1 = new wxButton(this, ID_BUTTON1, _("Add End"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1")); + FlexGridSizer5->Add(Button1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button5 = new wxButton(this, ID_BUTTON5, _("Remove"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON5")); + FlexGridSizer5->Add(Button5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button6 = new wxButton(this, ID_BUTTON6, _("Save"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON6")); + FlexGridSizer5->Add(Button6, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer3->Add(FlexGridSizer5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText5 = new wxStaticText(this, ID_STATICTEXT5, _("Right Mouse Clickto Insert Sequence"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT5")); + FlexGridSizer3->Add(StaticText5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer1->Add(FlexGridSizer3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + SetSizer(FlexGridSizer1); + FlexGridSizer1->Fit(this); + FlexGridSizer1->SetSizeHints(this); + Center(); + //*) +} + +EasyLights_PlayList_Dialog::~EasyLights_PlayList_Dialog() +{ + //(*Destroy(EasyLights_PlayList_Dialog) + //*) +} + +void EasyLights_PlayList_Dialog::InitDialog(wxInitDialogEvent &WXUNUSED(event)) +{ + wxListItem itemCol; + + itemCol.SetText(wxT("Name")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(0, itemCol); + ListCtrl1->SetColumnWidth(0, 250); + + ListCtrl2->InsertColumn(0, itemCol); + ListCtrl2->SetColumnWidth(0, 250); + + Display_Sequences(); + + Grid1->SetRowLabelSize(0); + Grid1->SetColSize(0, 225); + Grid1->SetColSize(1, 75); + + Display_PlayLists(); +} + +void EasyLights_PlayList_Dialog::OnButtonCloseClick(wxCommandEvent& event) +{ + + EndDialog(0); +} + +void EasyLights_PlayList_Dialog::OnButton_New_PlayList(wxCommandEvent& event) +{ + char B[200]; + char *p; + std::string PLnew; + + if(PLWork_Active) + { + wxMessageBox(wxT("A PlayList is currently being worked on - Please Save first "), wxT("New PlayList"), wxOK, NULL); + + return; + } + + PLnew = TextCtrl1->GetValue(); + + + if(PLnew.size() < 2) + { + wxMessageBox(wxT("Name of New PlayList is Missing"), wxT("New PlayList"), wxOK, NULL); + + return; + } + + PLWork_Active = 1; + + strncpy(B, PLnew.c_str(), 199); + p = B; + + while(*p && *p != '.') p++; + if(*p) + *p = 0; + + PLwork = B; + PLwork += ".ply"; + + TextCtrl2->SetValue(PLwork); + TextCtrl2->Refresh(); + TextCtrl2->Update(); + + TextCtrl1->SetValue(""); + TextCtrl1->Refresh(); + TextCtrl1->Update(); + +} + +void EasyLights_PlayList_Dialog::OnButton_Edit_PlayList(wxCommandEvent& event) +{ + int IDX; + + if(PLWork_Active) + { + wxMessageBox(wxT("A PlayList being Edited - Please Save First"), wxT("PlayList"), wxOK, NULL); + + return; + } + + + if(ListCtrl2->GetSelectedItemCount() == 0) + return; + + IDX = ListCtrl2->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + + PLwork = ListCtrl2->GetItemText(IDX); + PLWork_Active = 1; + + TextCtrl2->SetValue(PLwork); + TextCtrl2->Refresh(); + TextCtrl2->Update(); + + Load_PlayList_to_Work_on(); + +} + +void EasyLights_PlayList_Dialog::OnButton_Delete_PlayList(wxCommandEvent& event) +{ + int IDX; + std::string FN; + + if(PLWork_Active) + { + wxMessageBox(wxT("A PlayList being Edited - Please Save First"), wxT("PlayList"), wxOK, NULL); + + return; + } + + + if(ListCtrl2->GetSelectedItemCount() == 0) + return; + + IDX = ListCtrl2->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + + FN = ListCtrl2->GetItemText(IDX); + + wxString FNL = wxString::Format("%s\\EasyLightsData\\%s", EL_Ptr->ShowDirectory, FN); + + + wxRemove(FNL); + + ListCtrl2->DeleteItem(IDX); + +} + + +void EasyLights_PlayList_Dialog::OnButton_Remove_PlayList(wxCommandEvent& event) +{ + if(Grid_Left_Row >= 0) + { + Grid1->DeleteRows(Grid_Left_Row, 1); + + Grid_Left_Row = -1; // selection row is gone + } + +} + +void EasyLights_PlayList_Dialog::OnButton_Save_PlayList(wxCommandEvent& event) +{ + if(PLWork_Active == 0) + return; + + Save_Work_on_Play_List(); + + Add_PlayList_to_Display_if_New(PLwork); + + + PLwork = ""; + + TextCtrl2->SetValue(""); + TextCtrl2->Refresh(); + TextCtrl2->Update(); + + int i = Grid1->GetNumberRows(); + + Grid1->DeleteRows(0, i); + + PLWork_Active = 0; + +} + +void EasyLights_PlayList_Dialog::OnButton_Add_End_PlayList(wxCommandEvent& event) +{ + if(PLWork_Active == 0) + { + wxMessageBox(wxT("No Active PlayList being Edited"), wxT("PlayList"), wxOK, NULL); + + return; + } + + + if(Selected_List1_Sequence.size() < 3) + { + wxMessageBox(wxT("No Sequence Selected"), wxT("Selection Error"), wxOK, NULL); + + return; + } + + int i = Grid1->GetNumberRows(); + + Grid1->InsertRows(i, 1); + Grid1->SetCellValue(i, 0, Selected_List1_Sequence); + Grid1->SetReadOnly(i, 0, true); + Grid1->SetCellValue(i, 1, "4"); + + +} + +void EasyLights_PlayList_Dialog::OnList1_Seq_Selected(wxListEvent& event) +{ + int IDX; + + if(ListCtrl1->GetSelectedItemCount() == 0) + return; + + IDX = ListCtrl1->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + + Selected_List1_Sequence = ListCtrl1->GetItemText(IDX); +} + +void EasyLights_PlayList_Dialog::OnGridCellLeftClick(wxGridEvent &event) +{ + Grid_Left_Row = event.GetRow(); + Grid_Left_Col = event.GetCol(); + +} + +void EasyLights_PlayList_Dialog::OnGridCellRightClick(wxGridEvent &event) +{ + int Row = event.GetRow(); + int Col = event.GetCol(); + + if(PLWork_Active == 0) + { + wxMessageBox(wxT("No Active PlayList being Edited"), wxT("PlayList"), wxOK, NULL); + + return; + } + + + if(Selected_List1_Sequence.size() < 3) + { + wxMessageBox(wxT("No Sequence Selected for Insert"), wxT("Selection Error"), wxOK, NULL); + + return; + } + + Grid1->InsertRows(Row, 1); + Grid1->SetCellValue(Row, 0, Selected_List1_Sequence); + Grid1->SetReadOnly(Row, 0, true); + Grid1->SetCellValue(Row, 1, "4"); +} + + + + +//[{"S":"Christmas Eve Sarajevo.fseq","A":"Christmas Eve Sarajevo.wav","D":4}] + +void EasyLights_PlayList_Dialog::Load_PlayList_to_Work_on() +{ + wxString FN = wxString::Format("%s\\EasyLightsData\\%s", EL_Ptr->ShowDirectory, PLwork); + std::string fn = FN; + + FILE *fo = fopen((const char *)fn.c_str(), "r"); + + int FSZ, r; + char *B; + char *p, *JF, *JV; + char *EOL; + std::string SQ; + std::string Audio; + std::string Delay; + int Row = 0; + + + if(fo == 0) + { + wxMessageBox(wxT("Failed to Open the PlayList"), wxT("File Open"), wxOK, NULL); + return; + } + + fseek(fo, 0L, SEEK_END); + FSZ = ftell(fo); + fseek(fo, 0L, SEEK_SET); + + B = (char*)malloc(FSZ+5); + if(B == 0) + { + fclose(fo); + wxMessageBox(wxT("Failed to Acquire Memory for PlayList"), wxT("File Edit"), wxOK, NULL); + + return; + } + + memset(B, 0, FSZ+3); + + r = fread(B, 1, FSZ+2, fo); + + fclose(fo); + + EOL = B; + + while(1) // parse file + { + if(*EOL == 0) + break; + + p = EOL; + + // find start of jason line + + while(*p && *p != '{') p++; + if(*p == 0) + break; // done + + p++; // skip over { + +// find end of jason line + EOL = p; + + while(*EOL && *EOL != '}') EOL++; + if(*EOL == 0) + break; // ERROR!!! - done + + *EOL = 0; + EOL++; + + SQ = ""; + Audio = ""; + Delay = ""; + + while(p) // get all wanted fields + { + p = Get_Next_JArg(p, &JF, &JV, 0, 1); + + if(p) + { + switch(*JF) + { + case 'S': // sequence file name + SQ = JV; + break; + + case 'A': + Audio = JV; + break; + + case 'D': + Delay = JV; + break; + + } + + } // end of if p + } // end of while fields + + // we have a jason package decoded + + Grid1->InsertRows(Row, 1); + Grid1->SetCellValue(Row, 0, SQ); + Grid1->SetReadOnly(Row, 0, true); + Grid1->SetCellValue(Row, 1, Delay); + + Row++; + + } + +} + +void EasyLights_PlayList_Dialog::Save_Work_on_Play_List() +{ + wxString FN = wxString::Format("%s\\EasyLightsData\\%s", EL_Ptr->ShowDirectory, PLwork); + std::string fn = FN; + std::string T0; + std::string T1; + char B[200]; + char *p; + + FILE *fo = fopen((const char *)fn.c_str(), "w"); + + if(fo == 0) + { + wxMessageBox(wxT("Failed to Save the PlayList"), wxT("File Save"), wxOK, NULL); + + return; + } + + int i = Grid1->GetNumberRows(); + int j; + + fprintf(fo, "["); + + // [{"H":"Steve.ezls","D":3},{"H":"Steve.ezls","D":3}] + + for(j = 0; j < i; j++) + { + T0 = Grid1->GetCellValue(j, 0); + T1 = Grid1->GetCellValue(j, 1); + + strncpy(B, T0.c_str(), 199); + p = strstr(B, ".fseq"); + if(p) + strcpy(p, ".wav"); + + + fprintf(fo, "{\"S\":\"%s\",\"A\":\"%s\",\"D\":%s}", T0.c_str(), B, T1.c_str()); + + if(j < (i - 1)) + fprintf(fo, ","); + } + + fprintf(fo, "]"); + + fclose(fo); + +} + +void EasyLights_PlayList_Dialog::Add_PlayList_to_Display_if_New(std::string PL) +{ + int i = ListCtrl2->GetItemCount(); + int j; + std::string T; + + + for(j = 0; j < i; j++) + { + T = ListCtrl2->GetItemText(j); + if(T == PL) + return; + } + + ListCtrl2->InsertItem(i, PL, -1); +} + + + +void EasyLights_PlayList_Dialog::Display_Sequences() +{ + + std::string FN_search; + std::string FN; + wxString T; + std::string TS; + int i = 0; + char *S; + wxFileName wxFN; + + + + FN_search = EL_Ptr->ShowDirectory + "\\EasyLightsData\\*.fseq"; + + FN = wxFindFirstFile(FN_search); + + while(!FN.empty()) + { + wxFN = FN; + + T = wxString::Format("%s.%s", wxFN.GetName(), wxFN.GetExt()); + TS = T; + S = Return_EasuLights_FSEQ_FN_Without_IP((char*)TS.c_str()); + if(S == 0) + goto next; + + TS = S; + free(S); + + // we can have the same fseq name but for multiple controllers + + for(auto it = Seq_Array.begin(); it != Seq_Array.end(); ++it, i++) + { + if(*it == TS) + goto next; + } + + ListCtrl1->InsertItem(i, TS, -1); + + Seq_Array.push_back(TS); + i++; + +next: + FN = wxFindNextFile(); + } + + +} + + +void EasyLights_PlayList_Dialog::Display_PlayLists() +{ + + std::string FN_search; + std::string FN; + wxString T; + int i = 0; + wxFileName wxFN; + + ListCtrl2->DeleteAllItems(); + + + FN_search = EL_Ptr->ShowDirectory + "\\EasyLightsData\\*.ply"; + + FN = wxFindFirstFile(FN_search); + + while(!FN.empty()) + { + wxFN = FN; + + T = wxString::Format("%s.%s", wxFN.GetName(), wxFN.GetExt()); + + ListCtrl2->InsertItem(i, T, -1); + + i++; + FN = wxFindNextFile(); + } + + +} + +/*** +bool EasyLights_PlayList_Dialog::TransferDataFromWindow() +{ + + PLnew = TextCtrl1->GetValue(); + + return true; +} +***/ diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_PlayList_Dialog.h b/xLights/controllers/EasyLights_Utils/EasyLights_PlayList_Dialog.h new file mode 100644 index 0000000000..3a1c087652 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_PlayList_Dialog.h @@ -0,0 +1,107 @@ +#ifndef EASYLIGHTS_PLAYLIST_DIALOG_H +#define EASYLIGHTS_PLAYLIST_DIALOG_H + +//(*Headers(EasyLights_PlayList_Dialog) +#include +#include +#include +#include +#include +#include +#include +//*) + + +class EasyLights_PlayList_Dialog: public wxDialog +{ + public: + + EasyLights_PlayList_Dialog(wxWindow* parent,wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize); + virtual ~EasyLights_PlayList_Dialog(); + + //(*Declarations(EasyLights_PlayList_Dialog) + wxButton* Button1; + wxButton* Button2; + wxButton* Button3; + wxButton* Button5; + wxButton* Button6; + wxButton* Button7; + wxGrid* Grid1; + wxListCtrl* ListCtrl1; + wxListCtrl* ListCtrl2; + wxStaticText* StaticText1; + wxStaticText* StaticText2; + wxStaticText* StaticText3; + wxStaticText* StaticText4; + wxStaticText* StaticText5; + wxTextCtrl* TextCtrl1; + wxTextCtrl* TextCtrl2; + //*) + + void Display_Sequences(); + void Display_PlayLists(); + //bool TransferDataFromWindow(); + std::vector Seq_Array; + + + std::string PLwork; + std::string Selected_List1_Sequence; + + int PLWork_Active; + int Grid_Left_Row; + int Grid_Left_Col; + + void Load_PlayList_to_Work_on(); + void Save_Work_on_Play_List(); + void Add_PlayList_to_Display_if_New(std::string PL); + + + protected: + + //(*Identifiers(EasyLights_PlayList_Dialog) + static const long ID_STATICTEXT1; + static const long ID_LISTCTRL1; + static const long ID_STATICTEXT2; + static const long ID_LISTCTRL2; + static const long ID_STATICTEXT4; + static const long ID_BUTTON7; + static const long ID_TEXTCTRL1; + static const long ID_BUTTON2; + static const long ID_BUTTON3; + static const long ID_STATICTEXT3; + static const long ID_TEXTCTRL2; + static const long ID_GRID1; + static const long ID_BUTTON1; + static const long ID_BUTTON5; + static const long ID_BUTTON6; + static const long ID_STATICTEXT5; + //*) + + private: + + //(*Handlers(EasyLights_PlayList_Dialog) + void InitDialog(wxInitDialogEvent &event); + void OnButtonCloseClick(wxCommandEvent& event); + void OnButton_New_PlayList(wxCommandEvent& event); + void OnButton_Edit_PlayList(wxCommandEvent& event); + void OnButton_Delete_PlayList(wxCommandEvent& event); + void OnButton_Remove_PlayList(wxCommandEvent& event); + void OnButton_Save_PlayList(wxCommandEvent& event); + void OnButton_Add_End_PlayList(wxCommandEvent& event); + void OnList1_Seq_Selected(wxListEvent& event); + void OnGridCellLeftClick(wxGridEvent &event); + void OnGridCellRightClick(wxGridEvent &event); + + + + + //*) + + protected: + + void BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size); + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_Schedule_Dialog.cpp b/xLights/controllers/EasyLights_Utils/EasyLights_Schedule_Dialog.cpp new file mode 100644 index 0000000000..238e39f9d5 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_Schedule_Dialog.cpp @@ -0,0 +1,703 @@ + + +//(*InternalHeaders(EasyLights_StandAlone_Dialog) +#include +#include +//*) + + +#include +#include +#include +#include +#include +#include "../../xLightsMain.h" +#include "../FPP.h" +#include "../../xLightsXmlFile.h" +#include "../../outputs/Output.h" +#include "../../outputs/OutputManager.h" +#include "../../UtilFunctions.h" + +#include +#include "../../../xSchedule/wxJSON/jsonreader.h" + +#include "../../../include/spxml-0.5/spxmlparser.hpp" +#include "../../../include/spxml-0.5/spxmlevent.hpp" +#include "../../FSEQFile.h" +#include "../../Parallel.h" + +#include "EasyLights_Data.h" +#include "EasyLights_Schedule_Dialog.h" + +//(*IdInit(EasyLights_Schedule_Dialog) +const long EasyLights_Schedule_Dialog::ID_STATICTEXT1 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_LISTCTRL1 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_STATICTEXT2 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_LISTCTRL2 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_BUTTON2 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_BUTTON3 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_BUTTON4 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_STATICTEXT3 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_TEXTCTRL2 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_GRID1 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_BUTTON1 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_BUTTON5 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_BUTTON6 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_BUTTON7 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_STATICTEXT5 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_STATICTEXT4 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_STATICTEXT6 = wxNewId(); +const long EasyLights_Schedule_Dialog::ID_STATICTEXT7 = wxNewId(); +//*) + +BEGIN_EVENT_TABLE(EasyLights_Schedule_Dialog,wxDialog) + //(*EventTable(EasyLights_Schedule_Dialog) + EVT_INIT_DIALOG(EasyLights_Schedule_Dialog::InitDialog) + EVT_LIST_ITEM_SELECTED(EasyLights_Schedule_Dialog::ID_LISTCTRL1, EasyLights_Schedule_Dialog::OnList1_Seq_Selected) + EVT_GRID_SELECT_CELL(EasyLights_Schedule_Dialog::OnGridCellLeftClick) + EVT_GRID_CELL_RIGHT_CLICK(EasyLights_Schedule_Dialog::OnGridCellRightClick) + + //*) +END_EVENT_TABLE() + +EasyLights_Schedule_Dialog::EasyLights_Schedule_Dialog(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) +{ + SchedWork_Active = 0; + + BuildContent(parent,id,pos,size); + + Connect(ID_BUTTON2, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Schedule_Dialog::OnButton_Edit_PlayList); + Connect(ID_BUTTON3, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Schedule_Dialog::OnButton_NoSchedule); + Connect(ID_BUTTON4, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Schedule_Dialog::OnButton_Copy_Schedule); + + Connect(ID_BUTTON1, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Schedule_Dialog::OnButton_Add_End_Schedule); + Connect(ID_BUTTON5, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Schedule_Dialog::OnButton_Remove_Schedule); + Connect(ID_BUTTON6, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Schedule_Dialog::OnButton_Save_Schedule); + Connect(ID_BUTTON7, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Schedule_Dialog::OnButton_Sanity_Check); + + + Connect(wxID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_Schedule_Dialog::OnButtonCloseClick); + Connect(wxID_ANY, wxEVT_CLOSE_WINDOW, (wxObjectEventFunction)&EasyLights_Schedule_Dialog::OnButtonCloseClick); + +} + +void EasyLights_Schedule_Dialog::BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) +{ + //(*Initialize(EasyLights_Schedule_Dialog) + wxFlexGridSizer* FlexGridSizer1; + wxFlexGridSizer* FlexGridSizer2; + wxFlexGridSizer* FlexGridSizer3; + wxFlexGridSizer* FlexGridSizer4; + wxFlexGridSizer* FlexGridSizer5; + + Create(parent, wxID_ANY, _("EasyLights PlayList Manager"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("wxID_ANY")); + FlexGridSizer1 = new wxFlexGridSizer(0, 2, 0, 0); + FlexGridSizer2 = new wxFlexGridSizer(0, 1, 0, 0); + StaticText1 = new wxStaticText(this, ID_STATICTEXT1, _("PlayLists"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1")); + FlexGridSizer2->Add(StaticText1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + ListCtrl1 = new wxListCtrl(this, ID_LISTCTRL1, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_NO_HEADER|wxVSCROLL, wxDefaultValidator, _T("ID_LISTCTRL1")); + ListCtrl1->SetMinSize(wxSize(300,200)); + FlexGridSizer2->Add(ListCtrl1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText2 = new wxStaticText(this, ID_STATICTEXT2, _("Schedules for Day of Week"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2")); + FlexGridSizer2->Add(StaticText2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + ListCtrl2 = new wxListCtrl(this, ID_LISTCTRL2, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_NO_HEADER|wxVSCROLL, wxDefaultValidator, _T("ID_LISTCTRL2")); + ListCtrl2->SetMinSize(wxSize(300,150)); + FlexGridSizer2->Add(ListCtrl2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer4 = new wxFlexGridSizer(0, 3, 0, 0); + Button2 = new wxButton(this, ID_BUTTON2, _("Edit"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON2")); + FlexGridSizer4->Add(Button2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button3 = new wxButton(this, ID_BUTTON3, _("No Schedule"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON3")); + FlexGridSizer4->Add(Button3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button4 = new wxButton(this, ID_BUTTON4, _("Copy"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON4")); + FlexGridSizer4->Add(Button4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer2->Add(FlexGridSizer4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer1->Add(FlexGridSizer2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer3 = new wxFlexGridSizer(0, 1, 0, 0); + StaticText3 = new wxStaticText(this, ID_STATICTEXT3, _("Schedule Details"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT3")); + FlexGridSizer3->Add(StaticText3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + TextCtrl2 = new wxTextCtrl(this, ID_TEXTCTRL2, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY, wxDefaultValidator, _T("ID_TEXTCTRL2")); + TextCtrl2->SetMinSize(wxSize(175,25)); + FlexGridSizer3->Add(TextCtrl2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Grid1 = new wxGrid(this, ID_GRID1, wxDefaultPosition, wxDefaultSize, wxVSCROLL, _T("ID_GRID1")); + Grid1->CreateGrid(0,4); + Grid1->SetMinSize(wxSize(500,350)); + Grid1->EnableEditing(true); + Grid1->EnableGridLines(true); + Grid1->SetColLabelValue(0, _("PlayList")); + Grid1->SetColLabelValue(1, _("Start Time")); + Grid1->SetColLabelValue(2, _("End Time")); + Grid1->SetColLabelValue(3, _("# Loops")); + Grid1->SetDefaultCellFont( Grid1->GetFont() ); + Grid1->SetDefaultCellTextColour( Grid1->GetForegroundColour() ); + FlexGridSizer3->Add(Grid1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer5 = new wxFlexGridSizer(0, 4, 0, 0); + Button1 = new wxButton(this, ID_BUTTON1, _("Add End"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1")); + FlexGridSizer5->Add(Button1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button5 = new wxButton(this, ID_BUTTON5, _("Remove"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON5")); + FlexGridSizer5->Add(Button5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button6 = new wxButton(this, ID_BUTTON6, _("Save"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON6")); + FlexGridSizer5->Add(Button6, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button7 = new wxButton(this, ID_BUTTON7, _("Sanity Check"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON7")); + FlexGridSizer5->Add(Button7, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer3->Add(FlexGridSizer5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText5 = new wxStaticText(this, ID_STATICTEXT5, _("Right Mouse Clickto Insert Sequence"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT5")); + FlexGridSizer3->Add(StaticText5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText4 = new wxStaticText(this, ID_STATICTEXT4, _("Time format is Hour minutes e.g. 3:30pm is Entered as 1530 -- Hour is 0 to 23 -- Schedule Ends at Midnight"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT4")); + FlexGridSizer3->Add(StaticText4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText6 = new wxStaticText(this, ID_STATICTEXT6, _("PlayList becomes Active when the PlayList before it Completes"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT6")); + FlexGridSizer3->Add(StaticText6, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + StaticText7 = new wxStaticText(this, ID_STATICTEXT7, _("PlayList ends at EndTime or Loop Count is Loop Count is not Zero"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT7")); + FlexGridSizer3->Add(StaticText7, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + FlexGridSizer1->Add(FlexGridSizer3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + SetSizer(FlexGridSizer1); + FlexGridSizer1->Fit(this); + FlexGridSizer1->SetSizeHints(this); + Center(); + //*) +} + +EasyLights_Schedule_Dialog::~EasyLights_Schedule_Dialog() +{ + //(*Destroy(EasyLights_Schedule_Dialog) + //*) +} + +//(*Handlers(EasyLights_PlayList_Dialog) + +void EasyLights_Schedule_Dialog::InitDialog(wxInitDialogEvent &WXUNUSED(event)) +{ + wxListItem itemCol; + + itemCol.SetText(wxT("Name")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(0, itemCol); + ListCtrl1->SetColumnWidth(0, 250); + + ListCtrl2->InsertColumn(0, itemCol); + ListCtrl2->SetColumnWidth(0, 250); + + Display_PlayLists(); + + Grid1->SetRowLabelSize(0); + Grid1->SetColSize(0, 225); + Grid1->SetColSize(1, 75); + + Display_DOW(); +} + +void EasyLights_Schedule_Dialog::OnButtonCloseClick(wxCommandEvent& event) +{ + + EndDialog(0); +} + + +void EasyLights_Schedule_Dialog::OnButton_Edit_PlayList(wxCommandEvent& event) +{ + int IDX; + + if(SchedWork_Active) + { + wxMessageBox(wxT("A Schedule being Edited - Please Save First"), wxT("Schedule"), wxOK, NULL); + + return; + } + + + if(ListCtrl2->GetSelectedItemCount() == 0) + return; + + IDX = ListCtrl2->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + + Sched_Work = ListCtrl2->GetItemText(IDX); + SchedWork_Active = 1; + + TextCtrl2->SetValue(Sched_Work); + TextCtrl2->Refresh(); + TextCtrl2->Update(); + + Load_Schedule_to_Work_on(); + +} + +void EasyLights_Schedule_Dialog::OnButton_NoSchedule(wxCommandEvent& event) +{ + int IDX; + std::string FN; + + + if(ListCtrl2->GetSelectedItemCount() == 0) + return; + + IDX = ListCtrl2->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + + FN = ListCtrl2->GetItemText(IDX); + + wxString FNL = wxString::Format("%s\\EasyLightsData\\%s", EL_Ptr->ShowDirectory, FN); + std::string fn = FNL; + + FILE *fo = fopen((const char *)fn.c_str(), "w"); + + if(fo) + fclose(fo); +} + +void EasyLights_Schedule_Dialog::OnButton_Copy_Schedule(wxCommandEvent& event) +{ + std::string Saved_Edit_Schedule; + int IDX; + + if(SchedWork_Active == 0) + { + wxMessageBox(wxT("No Active Schedule being Edited - Only Copy Schedule Open for Edit"), wxT("Schedule"), wxOK, NULL); + + return; + } + + + if(ListCtrl2->GetSelectedItemCount() == 0) + return; + + IDX = ListCtrl2->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + + Saved_Edit_Schedule = Sched_Work; + + Sched_Work = ListCtrl2->GetItemText(IDX); + + Save_Work_on_Schedule(); + + Sched_Work = Saved_Edit_Schedule; + + wxMessageBox(wxT("Schedule being Edited was Copy into the requested Schedule"), wxT("Schedule"), wxOK, NULL); + + +} + + +void EasyLights_Schedule_Dialog::OnButton_Remove_Schedule(wxCommandEvent& event) +{ + if(Grid_Left_Row >= 0) + { + Grid1->DeleteRows(Grid_Left_Row, 1); + + Grid_Left_Row = -1; // selection row is gone + } + +} + +void EasyLights_Schedule_Dialog::OnButton_Save_Schedule(wxCommandEvent& event) +{ + if(SchedWork_Active == 0) + return; + + Save_Work_on_Schedule(); + + Sched_Work = ""; + + TextCtrl2->SetValue(""); + TextCtrl2->Refresh(); + TextCtrl2->Update(); + + int i = Grid1->GetNumberRows(); + + if(i) + Grid1->DeleteRows(0, i); + + SchedWork_Active = 0; + + +} + +void EasyLights_Schedule_Dialog::OnButton_Add_End_Schedule(wxCommandEvent& event) +{ + if(SchedWork_Active == 0) + { + wxMessageBox(wxT("No Active Schedule being Edited"), wxT("Schedule"), wxOK, NULL); + + return; + } + + + if(Selected_List1_PlayList.size() < 3) + { + wxMessageBox(wxT("No PlayList Selected"), wxT("Selection Error"), wxOK, NULL); + + return; + } + + int i = Grid1->GetNumberRows(); + + Grid1->InsertRows(i, 1); + Grid1->SetCellValue(i, 0, Selected_List1_PlayList); + Grid1->SetReadOnly(i, 0, true); + Grid1->SetCellValue(i, 1, "1"); + Grid1->SetCellValue(i, 2, "2"); + Grid1->SetCellValue(i, 3, "0"); + +} + +void EasyLights_Schedule_Dialog::OnButton_Sanity_Check(wxCommandEvent& event) +{ + std::string T0; + std::string T1; + std::string T2; + std::string T3; + + char TMBuff[20]; + int TM; + + + int i = Grid1->GetNumberRows(); + int j; + + if(i == 0) // empty sched + { + return; + } + + + for(j = 0; j < i; j++) + { + T0 = Grid1->GetCellValue(j, 0); + T1 = Grid1->GetCellValue(j, 1); + T2 = Grid1->GetCellValue(j, 2); + T3 = Grid1->GetCellValue(j, 3); + + + TM = atoi(T1.c_str()); + if(TM <= 0) + TM = 1200; + if(TM > 2355) + TM = 2355; + sprintf(TMBuff, "%d", TM); + T1 = TMBuff; + Grid1->SetCellValue(j, 1, T1); + + + TM = atoi(T2.c_str()); + if(TM <= 0) + TM = 1200; + if(TM > 2355) + TM = 2355; + sprintf(TMBuff, "%d", TM); + T2 = TMBuff; + Grid1->SetCellValue(j, 2, T2); + + TM = atoi(T3.c_str()); + if(TM < 0) + TM = 0; + sprintf(TMBuff, "%d", TM); + T3 = TMBuff; + Grid1->SetCellValue(j, 3, T3); + + } + + +} + +void EasyLights_Schedule_Dialog::OnList1_Seq_Selected(wxListEvent& event) +{ + int IDX; + + if(ListCtrl1->GetSelectedItemCount() == 0) + return; + + IDX = ListCtrl1->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + + Selected_List1_PlayList = ListCtrl1->GetItemText(IDX); + +} +void EasyLights_Schedule_Dialog::OnGridCellLeftClick(wxGridEvent &event) +{ + Grid_Left_Row = event.GetRow(); + Grid_Left_Col = event.GetCol(); + +} + +void EasyLights_Schedule_Dialog::OnGridCellRightClick(wxGridEvent &event) +{ + int Row = event.GetRow(); + int Col = event.GetCol(); + + if(SchedWork_Active == 0) + { + wxMessageBox(wxT("No Active Schedule being Edited"), wxT("Schedule"), wxOK, NULL); + + return; + } + + + if(Selected_List1_PlayList.size() < 3) + { + wxMessageBox(wxT("No PlayList Selected for Insert"), wxT("Selection Error"), wxOK, NULL); + + return; + } + + Grid1->InsertRows(Row, 1); + Grid1->SetCellValue(Row, 0, Selected_List1_PlayList); + Grid1->SetReadOnly(Row, 0, true); + Grid1->SetCellValue(Row, 1, "1"); + Grid1->SetCellValue(Row, 2, "2"); + Grid1->SetCellValue(Row, 3, "0"); +} + +void EasyLights_Schedule_Dialog::Display_PlayLists() +{ + + std::string FN_search; + std::string FN; + wxString T; + int i = 0; + wxFileName wxFN; + + + + FN_search = EL_Ptr->ShowDirectory + "\\EasyLightsData\\*.ply"; + + FN = wxFindFirstFile(FN_search); + + while(!FN.empty()) + { + wxFN = FN; + + T = wxString::Format("%s.%s", wxFN.GetName(), wxFN.GetExt()); + + ListCtrl1->InsertItem(i, T, -1); + + i++; + + + FN = wxFindNextFile(); + } + + +} + +void EasyLights_Schedule_Dialog::Display_DOW() +{ + ListCtrl2->InsertItem(0, "Sunday.sched", -1); + ListCtrl2->InsertItem(1, "Monday.sched", -1); + ListCtrl2->InsertItem(2, "Tuesday.sched", -1); + ListCtrl2->InsertItem(3, "Wednesday.sched", -1); + ListCtrl2->InsertItem(4, "Thursday.sched", -1); + ListCtrl2->InsertItem(5, "Friday.sched", -1); + ListCtrl2->InsertItem(6, "Saturday.sched", -1); + +} + + + +void EasyLights_Schedule_Dialog::Load_Schedule_to_Work_on() +{ + wxString FN = wxString::Format("%s\\EasyLightsData\\%s", EL_Ptr->ShowDirectory, Sched_Work); + std::string fn = FN; + + FILE *fo = fopen((const char *)fn.c_str(), "r"); + + int FSZ, r; + char *B; + char *p, *JF, *JV; + char *EOL; + std::string PL; + std::string StartTM; + std::string EndTM; + std::string Loops; + int Row = 0; + + int TM; + char TMBuff[50]; + + + if(fo == 0) + { + return; + } + + fseek(fo, 0L, SEEK_END); + FSZ = ftell(fo); + fseek(fo, 0L, SEEK_SET); + + B = (char*)malloc(FSZ + 5); + if(B == 0) + { + fclose(fo); + wxMessageBox(wxT("Failed to Acquire Memory for Schedule"), wxT("File Edit"), wxOK, NULL); + + return; + } + + memset(B, 0, FSZ + 3); + + r = fread(B, 1, FSZ + 2, fo); + + fclose(fo); + + EOL = B; + + while(1) // parse file + { + if(*EOL == 0) + break; + + p = EOL; + + // find start of jason line + + while(*p && *p != '{') p++; + if(*p == 0) + break; // done + + p++; // skip over { + +// find end of jason line + EOL = p; + + while(*EOL && *EOL != '}') EOL++; + if(*EOL == 0) + break; // ERROR!!! - done + + *EOL = 0; + EOL++; + + PL = ""; + StartTM = ""; + EndTM = ""; + Loops = "0"; + + while(p) // get all wanted fields + { + p = Get_Next_JArg(p, &JF, &JV, 0, 1); + + if(p) + { + switch(*JF) + { + case 'S': // sequence file name + StartTM = JV; + break; + + case 'E': + EndTM = JV; + break; + + case 'P': + PL = JV; + break; + + case 'L': + Loops = JV; + break; + + + } + + } // end of if p + } // end of while fields + + // we have a jason package decoded + + Grid1->InsertRows(Row, 1); + Grid1->SetCellValue(Row, 0, PL); + Grid1->SetReadOnly(Row, 0, true); + + TM = atoi(StartTM.c_str()); + if(TM <= 0) + TM = 1200; + sprintf(TMBuff, "%d", TM); + Grid1->SetCellValue(Row, 1, TMBuff); + + TM = atoi(EndTM.c_str()); + if(TM <= 0) + TM = 1200; + sprintf(TMBuff, "%d", TM); + Grid1->SetCellValue(Row, 2, TMBuff); + + TM = atoi(Loops.c_str()); + if(TM < 0) + TM = 0; + sprintf(TMBuff, "%d", TM); + Grid1->SetCellValue(Row, 3, TMBuff); + + Row++; + + } + +} + + +void EasyLights_Schedule_Dialog::Save_Work_on_Schedule() +{ + wxString FN = wxString::Format("%s\\EasyLightsData\\%s", EL_Ptr->ShowDirectory, Sched_Work); + std::string fn = FN; + std::string T0; + std::string T1; + std::string T2; + std::string T3; + + char TMBuff[20]; + int TM; + + FILE *fo = fopen((const char *)fn.c_str(), "w"); + + if(fo == 0) + { + wxMessageBox(wxT("Failed to Save the Schedule"), wxT("File Save"), wxOK, NULL); + + return; + } + + int i = Grid1->GetNumberRows(); + int j; + + if(i == 0) // empty sched + { + fclose(fo); + return; + } + + fprintf(fo, "["); + + + for(j = 0; j < i; j++) + { + T0 = Grid1->GetCellValue(j, 0); + T1 = Grid1->GetCellValue(j, 1); + T2 = Grid1->GetCellValue(j, 2); + T3 = Grid1->GetCellValue(j, 3); + + + TM = atoi(T1.c_str()); + if(TM <= 0) + TM = 1200; + if(TM > 2355) + TM = 2355; + sprintf(TMBuff, "%d", TM); + T1 = TMBuff; + + TM = atoi(T2.c_str()); + if(TM <= 0) + TM = 1200; + if(TM > 2355) + TM = 2355; + sprintf(TMBuff, "%d", TM); + T2 = TMBuff; + + TM = atoi(T3.c_str()); + if(TM < 0) + TM = 0; + sprintf(TMBuff, "%d", TM); + T3 = TMBuff; + + + fprintf(fo, "{\"PS\":\"%s\",\"S\":%s,\"E\":%s,\"L\":%s}", T0.c_str(), T1.c_str(), T2.c_str(), T3.c_str()); + + if(j < (i - 1)) + fprintf(fo, ","); + } + + fprintf(fo, "]"); + + fclose(fo); + +} diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_Schedule_Dialog.h b/xLights/controllers/EasyLights_Utils/EasyLights_Schedule_Dialog.h new file mode 100644 index 0000000000..1176ad3220 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_Schedule_Dialog.h @@ -0,0 +1,104 @@ +#ifndef EASYLIGHTS_SCHEDULE_DIALOG_H +#define EASYLIGHTS_SCHEDULE_DIALOG_H + +//(*Headers(EasyLights_Schedule_Dialog) +#include +#include +#include +#include +#include +#include +#include +//*) + +class EasyLights_Schedule_Dialog: public wxDialog +{ + public: + + EasyLights_Schedule_Dialog(wxWindow* parent,wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize); + virtual ~EasyLights_Schedule_Dialog(); + + //(*Declarations(EasyLights_Schedule_Dialog) + wxButton* Button1; + wxButton* Button2; + wxButton* Button3; + wxButton* Button4; + wxButton* Button5; + wxButton* Button6; + wxButton* Button7; + wxGrid* Grid1; + wxListCtrl* ListCtrl1; + wxListCtrl* ListCtrl2; + wxStaticText* StaticText1; + wxStaticText* StaticText2; + wxStaticText* StaticText3; + wxStaticText* StaticText4; + wxStaticText* StaticText5; + wxStaticText* StaticText6; + wxStaticText* StaticText7; + wxTextCtrl* TextCtrl2; + //*) + + void Display_PlayLists(); + void Display_DOW(); + void Load_Schedule_to_Work_on(); + void Save_Work_on_Schedule(); + + int SchedWork_Active; + int Grid_Left_Row; + int Grid_Left_Col; + + + std::string Sched_Work; + std::string Selected_List1_PlayList; + + protected: + + //(*Identifiers(EasyLights_Schedule_Dialog) + static const long ID_STATICTEXT1; + static const long ID_LISTCTRL1; + static const long ID_STATICTEXT2; + static const long ID_LISTCTRL2; + static const long ID_BUTTON2; + static const long ID_BUTTON3; + static const long ID_BUTTON4; + static const long ID_STATICTEXT3; + static const long ID_TEXTCTRL2; + static const long ID_GRID1; + static const long ID_BUTTON1; + static const long ID_BUTTON5; + static const long ID_BUTTON6; + static const long ID_BUTTON7; + static const long ID_STATICTEXT5; + static const long ID_STATICTEXT4; + static const long ID_STATICTEXT6; + static const long ID_STATICTEXT7; + //*) + + private: + + //(*Handlers(EasyLights_Schedule_Dialog) + void InitDialog(wxInitDialogEvent &event); + void OnButtonCloseClick(wxCommandEvent& event); + void OnButton_Edit_PlayList(wxCommandEvent& event); + void OnButton_NoSchedule(wxCommandEvent& event); + void OnButton_Copy_Schedule(wxCommandEvent& event); + void OnButton_Remove_Schedule(wxCommandEvent& event); + void OnButton_Save_Schedule(wxCommandEvent& event); + void OnButton_Add_End_Schedule(wxCommandEvent& event); + void OnButton_Sanity_Check(wxCommandEvent& event); + + void OnList1_Seq_Selected(wxListEvent& event); + void OnGridCellLeftClick(wxGridEvent &event); + void OnGridCellRightClick(wxGridEvent &event); + + //*) + + protected: + + void BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size); + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_StandAlone_Dialog.cpp b/xLights/controllers/EasyLights_Utils/EasyLights_StandAlone_Dialog.cpp new file mode 100644 index 0000000000..d475c6c5ff --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_StandAlone_Dialog.cpp @@ -0,0 +1,464 @@ + + +//(*InternalHeaders(EasyLights_StandAlone_Dialog) +#include +#include +//*) + + +#include +#include +#include +#include +#include +#include "../../xLightsMain.h" +#include "../FPP.h" +#include "../../xLightsXmlFile.h" +#include "../../outputs/Output.h" +#include "../../outputs/OutputManager.h" +#include "../../UtilFunctions.h" + +#include +#include "../../../xSchedule/wxJSON/jsonreader.h" + +#include "../../../include/spxml-0.5/spxmlparser.hpp" +#include "../../../include/spxml-0.5/spxmlevent.hpp" +#include "../../FSEQFile.h" +#include "../../Parallel.h" + +#include "EasyLights_Data.h" +#include "EasyLights_StandAlone_Dialog.h" + + + + +//(*IdInit(EasyLights_StandAlone_Dialog) +const long EasyLights_StandAlone_Dialog::ID_STATICTEXT1 = wxNewId(); +const long EasyLights_StandAlone_Dialog::ID_LISTCTRL1 = wxNewId(); +const long EasyLights_StandAlone_Dialog::ID_STATICTEXT2 = wxNewId(); +const long EasyLights_StandAlone_Dialog::ID_LISTCTRL2 = wxNewId(); +const long EasyLights_StandAlone_Dialog::ID_BUTTON4 = wxNewId(); +const long EasyLights_StandAlone_Dialog::ID_BUTTON6 = wxNewId(); +const long EasyLights_StandAlone_Dialog::ID_BUTTON2 = wxNewId(); +const long EasyLights_StandAlone_Dialog::ID_BUTTON3 = wxNewId(); +const long EasyLights_StandAlone_Dialog::ID_BUTTON1 = wxNewId(); +const long EasyLights_StandAlone_Dialog::ID_BUTTON5 = wxNewId(); +const long EasyLights_StandAlone_Dialog::ID_BUTTON7 = wxNewId(); +const long EasyLights_StandAlone_Dialog::ID_BUTTON8 = wxNewId(); +//*) + +BEGIN_EVENT_TABLE(EasyLights_StandAlone_Dialog,wxDialog) + //(*EventTable(EasyLights_StandAlone_Dialog) + EVT_INIT_DIALOG(EasyLights_StandAlone_Dialog::InitDialog) + //*) +END_EVENT_TABLE() + +EasyLights_StandAlone_Dialog *EL_Ptr = 0; + +//EasyLights_StandAlone_Dialog::EasyLights_StandAlone_Dialog(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) +EasyLights_StandAlone_Dialog::EasyLights_StandAlone_Dialog(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size) +{ + // init class data + + EndPoints_Dirty = 0; + ELC_Master = 0; + ELC_Audio = 0; + EL_Ptr = this; + + Selected_EndPoint = 0; + Selected_EndPoint_Index = 0; + + + BuildContent(parent,id,pos,size); + + Connect(ID_BUTTON4, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_StandAlone_Dialog::OnButton_ModifySlaves); + Connect(ID_BUTTON6, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_StandAlone_Dialog::OnButton_fseq); + Connect(ID_BUTTON2, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_StandAlone_Dialog::OnButton_PlayList); + Connect(ID_BUTTON3, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_StandAlone_Dialog::OnButton_Upload_fseq); + Connect(ID_BUTTON1, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_StandAlone_Dialog::OnButton_EasyLights_Controller); + Connect(ID_BUTTON7, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_StandAlone_Dialog::OnButton_Schedule); + Connect(ID_BUTTON8, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_StandAlone_Dialog::OnButton_Upload_PlayList); + Connect(ID_BUTTON5, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_StandAlone_Dialog::OnButton_Controller_Management); + + Connect(wxID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)&EasyLights_StandAlone_Dialog::OnButtonCloseClick); + Connect(wxID_ANY, wxEVT_CLOSE_WINDOW, (wxObjectEventFunction)&EasyLights_StandAlone_Dialog::OnButtonCloseClick); + + + /*** + EVT_COMMAND(wxID_OK, wxEVT_BUTTON, wxMyDialog::onOkPressed) + EVT_COMMAND(wxID_CANCEL, wxEVT_BUTTON, wxMyDialog::onCancelPressed) + + plus a close event handler + EVT_CLOSE(wxMyDialog::onClosePressed) +***/ + +} + +void EasyLights_StandAlone_Dialog::BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) +{ + + //(*Initialize(EasyLights_StandAlone_Dialog) + wxFlexGridSizer* FlexGridSizer1; + wxGridSizer* GridSizer1; + + Create(parent, wxID_ANY, _("EasyLights StandAlone"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("wxID_ANY")); + Move(wxPoint(-1,-1)); + FlexGridSizer1 = new wxFlexGridSizer(0, 1, 0, 0); + StaticText1 = new wxStaticText(this, ID_STATICTEXT1, _("EasyLights Controllers and Attachments"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1")); + FlexGridSizer1->Add(StaticText1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + ListCtrl1 = new wxListCtrl(this, ID_LISTCTRL1, wxDefaultPosition, wxSize(850,250), wxLC_REPORT|wxLC_SINGLE_SEL|wxVSCROLL, wxDefaultValidator, _T("ID_LISTCTRL1")); + FlexGridSizer1->Add(ListCtrl1, 1, wxALL|wxEXPAND, 5); + StaticText2 = new wxStaticText(this, ID_STATICTEXT2, _("Sequences"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2")); + FlexGridSizer1->Add(StaticText2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + ListCtrl2 = new wxListCtrl(this, ID_LISTCTRL2, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_NO_HEADER|wxLC_SINGLE_SEL|wxVSCROLL, wxDefaultValidator, _T("ID_LISTCTRL2")); + ListCtrl2->SetMinSize(wxSize(400,200)); + FlexGridSizer1->Add(ListCtrl2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + GridSizer1 = new wxGridSizer(2, 4, 0, 0); + Button4 = new wxButton(this, ID_BUTTON4, _("Add / Modify Attachment"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON4")); + GridSizer1->Add(Button4, 1, wxALL|wxEXPAND, 5); + Button6 = new wxButton(this, ID_BUTTON6, _("Generate FSEQ"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON6")); + GridSizer1->Add(Button6, 1, wxALL|wxEXPAND, 5); + Button2 = new wxButton(this, ID_BUTTON2, _("PlayList"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON2")); + GridSizer1->Add(Button2, 1, wxALL|wxEXPAND, 5); + Button3 = new wxButton(this, ID_BUTTON3, _("Upload Sequence"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON3")); + GridSizer1->Add(Button3, 1, wxALL|wxEXPAND, 5); + Button1 = new wxButton(this, ID_BUTTON1, _("EasyLights Controllers"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1")); + GridSizer1->Add(Button1, 1, wxALL|wxEXPAND, 5); + Button5 = new wxButton(this, ID_BUTTON5, _("Controller Management"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON5")); + GridSizer1->Add(Button5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + Button7 = new wxButton(this, ID_BUTTON7, _("Schedule"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON7")); + GridSizer1->Add(Button7, 1, wxALL|wxEXPAND, 5); + Button8 = new wxButton(this, ID_BUTTON8, _("Upload Schedule Playlist"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON8")); + GridSizer1->Add(Button8, 1, wxALL|wxEXPAND, 5); + FlexGridSizer1->Add(GridSizer1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); + SetSizer(FlexGridSizer1); + FlexGridSizer1->Fit(this); + FlexGridSizer1->SetSizeHints(this); + Center(); + //*) +} + +void EasyLights_StandAlone_Dialog::InitDialog(wxInitDialogEvent &WXUNUSED(event)) +{ + + Get_EasyLights_Specifications(ShowDirectory); + Build_EL_EndPoint_Array(ShowDirectory); + EndPoints_Dirty = Add_IPs_From_Output_To_EndPoint_Array(); + + Initialize_EndPoint_View(); + + Load_SA_List(); + Display_SA_FSEQ_and_Audio(); + +} + + +EasyLights_StandAlone_Dialog::~EasyLights_StandAlone_Dialog() +{ + //(*Destroy(EasyLights_StandAlone_Dialog) + //*) +} + + + +void EasyLights_StandAlone_Dialog::OnButton_ModifySlaves(wxCommandEvent& event) // add - Modify Slave +{ + EasyLights_Add_Slaves_Dialog dlg(this); + + if(ListCtrl1->GetSelectedItemCount() == 0) + return; + + if(ListCtrl1->GetSelectedItemCount() > 1) + { + wxMessageBox(wxT("Only ONE Selection Allowed for this Task"), wxT("Selection Error"), wxOK, NULL); + + return; + } + + Selected_EndPoint_Index = ListCtrl1->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if(Selected_EndPoint_Index < 0) + return; + + Selected_EndPoint = EL_EndPoints[Selected_EndPoint_Index]; + + if(Selected_EndPoint->Model.size() == 0 || Selected_EndPoint->Model == "Undefined") + { + wxMessageBox(wxT("Action Requires Selection of an EasyLights Controller - Not an Attachment"), wxT("Selection Error"), wxOK, NULL); + + return; + } + + + + dlg.EL_EndPoint = Selected_EndPoint; + + dlg.ShowModal(); + + if(dlg.Dirty) + { + EndPoints_Dirty = 1; + + ListCtrl1->DeleteAllItems(); + + Load_SA_List(); + } + +} + +void EasyLights_StandAlone_Dialog::OnButton_EasyLights_Controller(wxCommandEvent& event) // easylights controller +{ + EasyLights_Identify_Dialog dlg(this); + + dlg.ShowModal(); + + if(dlg.Dirty) + { + EndPoints_Dirty = 1; + + ListCtrl1->DeleteAllItems(); + + Load_SA_List(); + } + +} + + + +void EasyLights_StandAlone_Dialog::OnButton_fseq(wxCommandEvent& event) // generate fseq +{ + EasyLights_FSEQ_Dialog dlg(this); + + dlg.ShowModal(); + + Display_SA_FSEQ_and_Audio(); + +} + +void EasyLights_StandAlone_Dialog::OnButton_PlayList(wxCommandEvent& event) // playlist +{ + + EasyLights_PlayList_Dialog dlg(this); + + dlg.ShowModal(); + +} + +void EasyLights_StandAlone_Dialog::OnButton_Schedule(wxCommandEvent& event) // schedule +{ + + EasyLights_Schedule_Dialog dlg(this); + + dlg.ShowModal(); + + + +} + +void EasyLights_StandAlone_Dialog::OnButton_Upload_fseq(wxCommandEvent& event) // upload sequence +{ + +} + +void EasyLights_StandAlone_Dialog::OnButton_Upload_PlayList(wxCommandEvent& event) // upload schedule playlist +{ + +} + +void EasyLights_StandAlone_Dialog::OnButton_Controller_Management(wxCommandEvent& event) +{ + +} + + +void EasyLights_StandAlone_Dialog::OnButtonCloseClick(wxCommandEvent& event) +{ + if(EndPoints_Dirty) + Save_EndPoint_Array_to_XML(ShowDirectory); + + EL_Ptr = 0; + +// release memory + + for(auto e = EL_EndPoints.begin(); e != EL_EndPoints.end(); ++e) + delete *e; + + for(auto x = EL_Controller.begin(); x != EL_Controller.end(); ++x) + delete *x; + + EL_EndPoints.clear(); + EL_Controller.clear(); + + EndDialog(0); +} + +void EasyLights_StandAlone_Dialog::Initialize_EndPoint_View() +{ + // view has 5 columns + + wxListItem itemCol; + + itemCol.SetText(wxT("Name")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(0, itemCol); + ListCtrl1->SetColumnWidth(0, 200); + + itemCol.SetText(wxT("IP")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(1, itemCol); + ListCtrl1->SetColumnWidth(1, 100); + + itemCol.SetText(wxT("Type")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(2, itemCol); + ListCtrl1->SetColumnWidth(2, 150); + + itemCol.SetText(wxT("Master")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(3, itemCol); + ListCtrl1->SetColumnWidth(3, 75); + + itemCol.SetText(wxT("Audio")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(4, itemCol); + ListCtrl1->SetColumnWidth(4, 75); + + + itemCol.SetText(wxT("Attachment 1 IP")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(5, itemCol); + ListCtrl1->SetColumnWidth(5, 100); + + itemCol.SetText(wxT("Attachment 2 IP")); + itemCol.SetImage(-1); + ListCtrl1->InsertColumn(6, itemCol); + ListCtrl1->SetColumnWidth(6, 100); + + + itemCol.SetText(wxT("Name")); + itemCol.SetImage(-1); + ListCtrl2->InsertColumn(0, itemCol); + ListCtrl2->SetColumnWidth(0, 400); + + + +} + +void EasyLights_StandAlone_Dialog::Load_SA_List() +{ + wxString T; + int i = 0; + wxColor CG(150, 255, 150); + wxColor CB(200, 200, 255); + int V; + + ELC_Master = 0; + ELC_Audio = 0; + + for(auto it = EL_EndPoints.begin(); it != EL_EndPoints.end(); ++it, i++) + { + if((*it)->Master) + ELC_Master = *it; + + if((*it)->Audio) + ELC_Audio = *it; + + + T.Printf("%s", (*it)->Name); + ListCtrl1->InsertItem(i, T, -1); + ListCtrl1->SetItemData(i, i); + + T.Printf("%s", (*it)->IP); + ListCtrl1->SetItem(i, 1, T); + + if((*it)->Model.size() == 0) + (*it)->Model = "Undefined"; + + if((*it)->Model == "Undefined" && (*it)->Slave_Attached) + T.Printf("%s", "Attached"); + else + T.Printf("%s", (*it)->Model); + + ListCtrl1->SetItem(i, 2, T); + if((*it)->Model != "Undefined") + { + V = ELC_Status_To_Support_Slaves(*it); + if(V == ELC_Support_NO_Slaves) + ListCtrl1->SetItemBackgroundColour(i, CB); + else + ListCtrl1->SetItemBackgroundColour(i, CG); + } + + if((*it)->Master) + T = "Yes"; + else + T = "No"; + ListCtrl1->SetItem(i, 3, T); + + if((*it)->Audio) + T = "Yes"; + else + T = "No"; + ListCtrl1->SetItem(i, 4, T); + + T.Printf("%s", (*it)->S1_IP); + ListCtrl1->SetItem(i, 5, T); + + T.Printf("%s", (*it)->S2_IP); + ListCtrl1->SetItem(i, 6, T); + + } +} + +void EasyLights_StandAlone_Dialog::Display_SA_FSEQ_and_Audio() +{ + ListCtrl2->DeleteAllItems(); + + std::string FN_search; + std::string FN; + wxString T; + int i = 0; + wxFileName wxFN; + + + + FN_search = ShowDirectory + "\\EasyLightsData\\*.fseq"; + + FN = wxFindFirstFile(FN_search); + + while(!FN.empty()) + { + wxFN = FN; + + ListCtrl2->InsertItem(i, T, -1); + + + T = wxString::Format("%s.%s", wxFN.GetName(), wxFN.GetExt()); + ListCtrl2->SetItem(i, 0, T); + + i++; + FN = wxFindNextFile(); + } + + /*** + FN_search = showDirectory + "\\EasyLightsData\\*.wav"; + + FN = wxFindFirstFile(FN_search); + + while(!FN.empty()) + { + wxFN = FN; + + ListCtrl2->InsertItem(i, T, -1); + + + T = wxString::Format("%s.%s", wxFN.GetName(), wxFN.GetExt()); + ListCtrl2->SetItem(i, 0, T); + + i++; + FN = wxFindNextFile(); + } + **/ + +} + + diff --git a/xLights/controllers/EasyLights_Utils/EasyLights_StandAlone_Dialog.h b/xLights/controllers/EasyLights_Utils/EasyLights_StandAlone_Dialog.h new file mode 100644 index 0000000000..15676fbec7 --- /dev/null +++ b/xLights/controllers/EasyLights_Utils/EasyLights_StandAlone_Dialog.h @@ -0,0 +1,106 @@ +#ifndef EASYLIGHTS_STANDALONE_DIALOG_H +#define EASYLIGHTS_STANDALONE_DIALOG_H + + +#include +#include + +//(*Headers(EasyLights_StandAlone_Dialog) +#include +#include +#include +#include +#include +//*) + +#include +#include "../FPP.h" + +class EL_Controller_Info; +class EasyLights_EndPoint; + +class EasyLights_StandAlone_Dialog: public wxDialog +{ + public: + + EasyLights_StandAlone_Dialog(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); + virtual ~EasyLights_StandAlone_Dialog(); + + //(*Declarations(EasyLights_StandAlone_Dialog) + wxButton* Button1; + wxButton* Button2; + wxButton* Button3; + wxButton* Button4; + wxButton* Button5; + wxButton* Button6; + wxButton* Button7; + wxButton* Button8; + wxListCtrl* ListCtrl1; + wxListCtrl* ListCtrl2; + wxStaticText* StaticText1; + wxStaticText* StaticText2; + //*) + + std::vector EL_Controller; + std::vector EL_EndPoints; + int EndPoints_Dirty; + + std::string ShowDirectory; + std::string FseqDirectory; + + OutputManager *OutPutMgr; + + EasyLights_EndPoint *Selected_EndPoint; + int Selected_EndPoint_Index; + + EasyLights_EndPoint *ELC_Master; // can only be one for each + EasyLights_EndPoint *ELC_Audio; + + + void Display_SA_FSEQ_and_Audio(); + + protected: + + //(*Identifiers(EasyLights_StandAlone_Dialog) + static const long ID_STATICTEXT1; + static const long ID_LISTCTRL1; + static const long ID_STATICTEXT2; + static const long ID_LISTCTRL2; + static const long ID_BUTTON4; + static const long ID_BUTTON6; + static const long ID_BUTTON2; + static const long ID_BUTTON3; + static const long ID_BUTTON1; + static const long ID_BUTTON5; + static const long ID_BUTTON7; + static const long ID_BUTTON8; + //*) + + private: + + //(*Handlers(EasyLights_StandAlone_Dialog) + void OnButton_ModifySlaves(wxCommandEvent& event); + void OnButton_EasyLights_Controller(wxCommandEvent& event); + void OnButton_fseq(wxCommandEvent& event); + void OnButton_PlayList(wxCommandEvent& event); + void OnButton_Schedule(wxCommandEvent& event); + void OnButton_Upload_fseq(wxCommandEvent& event); + void OnButton_Upload_PlayList(wxCommandEvent& event); + void OnButtonCloseClick(wxCommandEvent& event); + void OnButton_Controller_Management(wxCommandEvent& event); + + void Load_SA_List(); + void InitDialog(wxInitDialogEvent &event); + + + void Initialize_EndPoint_View(); + //*) + + protected: + + void BuildContent(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size); + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/xLights/xLightsMain.cpp b/xLights/xLightsMain.cpp index e8f26b5bf7..87e34ffa49 100644 --- a/xLights/xLightsMain.cpp +++ b/xLights/xLightsMain.cpp @@ -69,6 +69,7 @@ #include "LyricUserDictDialog.h" #include "models/ViewObject.h" #include "models/SubModel.h" +#include "controllers/EasyLights_Utils/EasyLights_StandAlone_Dialog.h" // image files #include "../include/control-pause-blue-icon.xpm" @@ -315,6 +316,7 @@ const long xLightsFrame::ID_MENU_OPENGL_3 = wxNewId(); const long xLightsFrame::ID_MENU_OPENGL_2 = wxNewId(); const long xLightsFrame::ID_MENU_OPENGL_1 = wxNewId(); const long xLightsFrame::ID_MENUITEM19 = wxNewId(); +const long xLightsFrame::MenuItem_Controller_Connect = wxNewId(); const long xLightsFrame::ID_MNU_PLAYCONTROLSONPREVIEW = wxNewId(); const long xLightsFrame::ID_MNU_AUTOSHOWHOUSEPREVIEW = wxNewId(); const long xLightsFrame::ID_MENUITEM_AUTOSAVE_0 = wxNewId(); @@ -353,6 +355,7 @@ const long xLightsFrame::ID_MNU_UPDATE = wxNewId(); const long xLightsFrame::ID_TIMER1 = wxNewId(); const long xLightsFrame::ID_TIMER2 = wxNewId(); const long xLightsFrame::ID_TIMER_EFFECT_SETTINGS = wxNewId(); +const long xLightsFrame::ID_MENU_EASYLIGHTS_STANDALONE = wxNewId(); //*) // For new sequencer @@ -865,8 +868,12 @@ xLightsFrame::xLightsFrame(wxWindow* parent, wxWindowID id) : mSequenceElements( Menu1->Append(mExportModelsMenuItem); MenuItem_ExportEffects = new wxMenuItem(Menu1, ID_MNU_EXPORT_EFFECTS, _("Export &Effects"), wxEmptyString, wxITEM_NORMAL); Menu1->Append(MenuItem_ExportEffects); - MenuItem_FPP_Connect = new wxMenuItem(Menu1, ID_MENU_FPP_CONNECT, _("&FPP Connect"), wxEmptyString, wxITEM_NORMAL); - Menu1->Append(MenuItem_FPP_Connect); + ControllerConnectMenu = new wxMenu(); + MenuItem_FPP_Connect = new wxMenuItem(ControllerConnectMenu, ID_MENU_FPP_CONNECT, _("&FPP Connect"), wxEmptyString, wxITEM_NORMAL); + ControllerConnectMenu->Append(MenuItem_FPP_Connect); + MenuItem_EasyLights_Stand_Alone = new wxMenuItem(Menu1, ID_MENU_EASYLIGHTS_STANDALONE, _("&EasyLights StandAlone"), wxEmptyString, wxITEM_NORMAL); + ControllerConnectMenu->Append(MenuItem_EasyLights_Stand_Alone); + Menu1->Append(MenuItem_Controller_Connect, _("Controller Connect"), ControllerConnectMenu, wxEmptyString); MenuItem_PackageSequence = new wxMenuItem(Menu1, ID_MNU_PACKAGESEQUENCE, _("Package &Sequence"), wxEmptyString, wxITEM_NORMAL); Menu1->Append(MenuItem_PackageSequence); MenuItemUserDict = new wxMenuItem(Menu1, ID_MENU_USER_DICT, _("User Lyric Dictionary"), wxEmptyString, wxITEM_NORMAL); @@ -1391,6 +1398,7 @@ xLightsFrame::xLightsFrame(wxWindow* parent, wxWindowID id) : mSequenceElements( Connect(wxID_ANY,wxEVT_CLOSE_WINDOW,(wxObjectEventFunction)&xLightsFrame::OnClose); Connect(wxEVT_CHAR,(wxObjectEventFunction)&xLightsFrame::OnChar); Connect(wxEVT_SIZE,(wxObjectEventFunction)&xLightsFrame::OnResize); + Connect(ID_MENU_EASYLIGHTS_STANDALONE, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)&xLightsFrame::OnMenuItem_EasyLights_StandAloneSelected); //*) Connect(wxID_ANY, wxEVT_CHAR_HOOK, wxKeyEventHandler(xLightsFrame::OnCharHook), nullptr, this); @@ -6710,6 +6718,23 @@ void xLightsFrame::OnMenuItem_FPP_ConnectSelected(wxCommandEvent& event) dlg.ShowModal(); } +void xLightsFrame::OnMenuItem_EasyLights_StandAloneSelected(wxCommandEvent& event) +{ + // make sure everything is up to date + if(Notebook1->GetSelection() != LAYOUTTAB) + layoutPanel->UnSelectAllModels(); + RecalcModels(); + + EasyLights_StandAlone_Dialog dlg(this); + + dlg.FseqDirectory = fseqDirectory; + dlg.ShowDirectory = showDirectory; + dlg.OutPutMgr = &_outputManager; + + dlg.ShowModal(); +} + + void xLightsFrame::OnMenuItem_PackageSequenceSelected(wxCommandEvent& event) { static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); diff --git a/xLights/xLightsMain.h b/xLights/xLightsMain.h index 83491a7168..f1f957df60 100644 --- a/xLights/xLightsMain.h +++ b/xLights/xLightsMain.h @@ -559,6 +559,7 @@ class xLightsFrame: public wxFrame void OnMenuItemFSEQV2Selected(wxCommandEvent& event); //*) void OnCharHook(wxKeyEvent& event); + void OnMenuItem_EasyLights_StandAloneSelected(wxCommandEvent& event); private: //void OnMenuItem53Selected(wxCommandEvent& event); @@ -774,6 +775,7 @@ class xLightsFrame: public wxFrame static const long ID_MENU_OPENGL_3; static const long ID_MENU_OPENGL_2; static const long ID_MENU_OPENGL_1; + static const long MenuItem_Controller_Connect; static const long ID_MENUITEM19; static const long ID_MNU_PLAYCONTROLSONPREVIEW; static const long ID_MNU_AUTOSHOWHOUSEPREVIEW; @@ -813,6 +815,7 @@ class xLightsFrame: public wxFrame static const long ID_TIMER1; static const long ID_TIMER2; static const long ID_TIMER_EFFECT_SETTINGS; + static const long ID_MENU_EASYLIGHTS_STANDALONE; //*) static const long ID_PANEL_EFFECTS1; @@ -874,6 +877,7 @@ class xLightsFrame: public wxFrame wxMenu* MenuSettings; wxMenu* MenuView; wxMenu* OpenGLMenu; + wxMenu* ControllerConnectMenu; wxMenu* ToolIconSizeMenu; wxMenuBar* MenuBar; wxMenuItem* ActionTestMenuItem; @@ -993,6 +997,7 @@ class xLightsFrame: public wxFrame wxMenuItem* mExportModelsMenuItem; wxMenuItem* mRenderOnSaveMenuItem; wxMenuItem* mSaveFseqOnSaveMenuItem; + wxMenuItem* MenuItem_EasyLights_Stand_Alone; wxPanel* AUIStatusBar; wxPanel* PanelPreview; wxPanel* PanelSequencer;