mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-19 14:53:56 -07:00
Removed a few global variables from Atlas. Added call to srand(time). Restored NotebookEvent in wxJS. Fixed CPU-detection in Valgrind. This was SVN commit r5318.
1733 lines
55 KiB
C++
1733 lines
55 KiB
C++
#include "precompiled.h"
|
|
|
|
#include "Trigger.h"
|
|
#include "GameInterface/Messages.h"
|
|
#include "CustomControls/Buttons/ActionButton.h"
|
|
#include "ScenarioEditor/ScenarioEditor.h"
|
|
#include "ScenarioEditor/Tools/Common/MiscState.h"
|
|
|
|
#include "wx/treectrl.h"
|
|
#include "wx/listctrl.h"
|
|
#include "wx/notebook.h"
|
|
#include <sstream>
|
|
#include <list>
|
|
|
|
using namespace AtlasMessage;
|
|
|
|
BEGIN_EVENT_TABLE(TriggerSidebar, Sidebar)
|
|
EVT_TREE_BEGIN_DRAG(wxID_ANY, TriggerSidebar::onTreeDrag)
|
|
EVT_TREE_END_LABEL_EDIT(wxID_ANY, TriggerSidebar::onTreeNameChange)
|
|
EVT_TREE_SEL_CHANGED(wxID_ANY, TriggerSidebar::onTreeSelChange)
|
|
EVT_LIST_ITEM_SELECTED(TriggerSidebar::ID_CondList, TriggerSidebar::onCondSelect)
|
|
EVT_LIST_ITEM_SELECTED(TriggerSidebar::ID_EffectList, TriggerSidebar::onEffectSelect)
|
|
EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, TriggerSidebar::onPageChange)
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
class TriggerTreeCtrl : public wxTreeCtrl
|
|
{
|
|
public:
|
|
TriggerTreeCtrl(TriggerSidebar* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
|
|
const wxSize& size = wxDefaultSize, long style = wxTR_HAS_BUTTONS )
|
|
: wxTreeCtrl(parent, id, pos, size, style), m_Sidebar(parent) { }
|
|
|
|
void onClick(wxMouseEvent& evt);
|
|
|
|
private:
|
|
TriggerSidebar* m_Sidebar;
|
|
DECLARE_EVENT_TABLE();
|
|
};
|
|
|
|
BEGIN_EVENT_TABLE(TriggerTreeCtrl, wxTreeCtrl)
|
|
EVT_LEFT_DOWN(TriggerTreeCtrl::onClick)
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
struct LogicBlockHelper
|
|
{
|
|
LogicBlockHelper() { index = -1; end = false; }
|
|
LogicBlockHelper(int _index, bool _end) : index(_index), end(_end) {}
|
|
int index;
|
|
bool end;
|
|
|
|
bool operator< ( const LogicBlockHelper& rhs ) const
|
|
{
|
|
return index < rhs.index;
|
|
}
|
|
bool operator== ( const LogicBlockHelper& rhs ) const
|
|
{
|
|
return index == rhs.index;
|
|
}
|
|
};
|
|
class TriggerSpecText : public wxTextCtrl
|
|
{
|
|
typedef void (*callback)(void* data, std::wstring input, int parameter);
|
|
|
|
public:
|
|
TriggerSpecText(wxWindow* parent, std::wstring label, const wxPoint& pos, const wxSize& size,
|
|
int parameter, std::wstring dataType, callback func, void* data)
|
|
: wxTextCtrl(parent, wxID_ANY, wxString( label.c_str() ), pos, size, wxTE_PROCESS_ENTER),
|
|
m_DataType(dataType), m_Parameter(parameter), m_Data(data), m_Callback(func)
|
|
{
|
|
}
|
|
void onTextEnter(wxCommandEvent& WXUNUSED(evt));
|
|
|
|
//Disallow invalid input
|
|
bool VerifyInput(std::wstring& input)
|
|
{
|
|
std::wstringstream stream(input);
|
|
if ( m_DataType == L"int" )
|
|
{
|
|
int test;
|
|
stream >> test;
|
|
return !stream.fail();
|
|
}
|
|
else if ( m_DataType == L"real" )
|
|
{
|
|
float test;
|
|
stream >> test;
|
|
return !stream.fail();
|
|
}
|
|
else if ( m_DataType == L"bool" )
|
|
{
|
|
bool test;
|
|
stream >> test;
|
|
return !stream.fail();
|
|
}
|
|
else if ( m_DataType == L"string" )
|
|
{
|
|
//Make strings appear as strings to javascript
|
|
std::wstring quote(L"\"");
|
|
input.insert(0, quote);
|
|
input.append(quote);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
wxFAIL_MSG(L"Invalid input type for trigger specification");
|
|
return false;
|
|
}
|
|
}
|
|
private:
|
|
void* m_Data;
|
|
int m_Parameter;
|
|
std::wstring m_DataType;
|
|
callback m_Callback;
|
|
|
|
DECLARE_EVENT_TABLE();
|
|
|
|
};
|
|
BEGIN_EVENT_TABLE(TriggerSpecText, wxTextCtrl)
|
|
EVT_TEXT_ENTER(wxID_ANY, TriggerSpecText::onTextEnter)
|
|
END_EVENT_TABLE()
|
|
|
|
class TriggerSpecChoice : public wxChoice
|
|
{
|
|
typedef void (*callback)(void* data, std::wstring input, int parameter);
|
|
|
|
public:
|
|
TriggerSpecChoice(TriggerBottomBar* parent, std::wstring label, const wxPoint& pos,
|
|
const wxSize& size, const wxArrayString& strings, int parameter, callback func, void* data);
|
|
|
|
void onChoice(wxCommandEvent& evt);
|
|
|
|
private:
|
|
TriggerBottomBar* m_Parent;
|
|
callback m_Callback;
|
|
int m_Parameter;
|
|
void* m_Data;
|
|
|
|
DECLARE_EVENT_TABLE();
|
|
};
|
|
|
|
BEGIN_EVENT_TABLE(TriggerSpecChoice, wxChoice)
|
|
EVT_CHOICE(wxID_ANY, TriggerSpecChoice::onChoice)
|
|
END_EVENT_TABLE()
|
|
|
|
class TriggerBottomBar;
|
|
|
|
class TriggerEntitySelector : public wxPanel
|
|
{
|
|
typedef void (*callback)(void* data, std::wstring input, int parameter);
|
|
enum { ID_SELECTION, ID_VIEW };
|
|
public:
|
|
|
|
TriggerEntitySelector(TriggerBottomBar* parent, std::wstring label, const wxPoint& pos,
|
|
const wxSize& size, int parameter, callback func, void* data);
|
|
|
|
void onSelectionClick(wxCommandEvent& WXUNUSED(evt))
|
|
{
|
|
std::wstring code(L"[");
|
|
std::wstringstream stream;
|
|
for ( size_t i = 0; i < g_SelectedObjects.size(); ++i )
|
|
{
|
|
stream << g_SelectedObjects[i];
|
|
if ( i != g_SelectedObjects.size()-1 )
|
|
stream << L", ";
|
|
}
|
|
|
|
code.append(stream.str());
|
|
code.append(L"]");
|
|
(*m_Callback)(m_Data, code, m_Parameter);
|
|
POST_MESSAGE(SetSelectionPreview, (g_SelectedObjects));
|
|
}
|
|
void onViewClick(wxCommandEvent& WXUNUSED(evt));
|
|
|
|
private:
|
|
int m_Parameter;
|
|
callback m_Callback;
|
|
TriggerBottomBar* m_Parent;
|
|
void* m_Data;
|
|
|
|
DECLARE_EVENT_TABLE();
|
|
};
|
|
BEGIN_EVENT_TABLE(TriggerEntitySelector, wxPanel)
|
|
EVT_BUTTON(TriggerEntitySelector::ID_SELECTION, TriggerEntitySelector::onSelectionClick)
|
|
EVT_BUTTON(TriggerEntitySelector::ID_VIEW, TriggerEntitySelector::onViewClick)
|
|
END_EVENT_TABLE()
|
|
|
|
class TriggerPointPlacer : public wxPanel
|
|
{
|
|
enum { ID_Set, ID_View };
|
|
typedef void (*callback)(void* data, std::wstring input, int parameter);
|
|
public:
|
|
|
|
TriggerPointPlacer(wxWindow* parent, const wxPoint& pos,
|
|
const wxSize& size, int parameter, callback func, void* data) : m_Callback(func),
|
|
wxPanel(parent, wxID_ANY, pos), m_Parameter(parameter), m_Data(data)
|
|
{
|
|
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
|
|
SetSizer(mainSizer);
|
|
mainSizer->Add( new wxButton(this, ID_Set, L"Set point", pos, size) );
|
|
mainSizer->Add( new wxButton(this, ID_View, L"View", pos, size) );
|
|
}
|
|
|
|
|
|
void onSet(wxCommandEvent& WXUNUSED(evt))
|
|
{
|
|
qGetWorldPosition query( wxGetMousePosition().x, wxGetMousePosition().y );
|
|
query.Post();
|
|
Position pos = query.position;
|
|
wxString wxForm = wxString::Format(L"Vector(%f, %f, %f)", pos.type0.x, pos.type0.y, pos.type0.z);
|
|
|
|
std::wstring convert = (std::wstring)wxForm;
|
|
(*m_Callback)(m_Data, convert, m_Parameter);
|
|
POST_MESSAGE(TriggerToggleSelector, (true, pos));
|
|
}
|
|
|
|
void onView(wxCommandEvent& WXUNUSED(evt))
|
|
{
|
|
//POST_MESSAGE( TriggerToggleSelector, (pos) );
|
|
}
|
|
|
|
private:
|
|
int m_Parameter;
|
|
void* m_Data;
|
|
callback m_Callback;
|
|
bool m_MouseCapture;
|
|
|
|
DECLARE_EVENT_TABLE();
|
|
};
|
|
|
|
BEGIN_EVENT_TABLE(TriggerPointPlacer, wxPanel)
|
|
EVT_BUTTON(TriggerPointPlacer::ID_Set, TriggerPointPlacer::onSet)
|
|
EVT_BUTTON(TriggerPointPlacer::ID_View, TriggerPointPlacer::onView)
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
class TriggerListCtrl : public wxListCtrl
|
|
{
|
|
public:
|
|
TriggerListCtrl(wxWindow* parent, TriggerSidebar* sidebar, bool condition, wxWindowID id, const wxPoint& pos = wxDefaultPosition,
|
|
const wxSize& size = wxDefaultSize, long style = wxLC_ICON)
|
|
: wxListCtrl(parent, id, pos, size, style), m_Sidebar(sidebar), m_Condition(condition)
|
|
{
|
|
}
|
|
void onClick(wxMouseEvent& evt);
|
|
|
|
TriggerSidebar* m_Sidebar;
|
|
bool m_Condition;
|
|
private:
|
|
DECLARE_EVENT_TABLE();
|
|
};
|
|
BEGIN_EVENT_TABLE(TriggerListCtrl, wxListCtrl)
|
|
EVT_LEFT_DOWN(TriggerListCtrl::onClick)
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
class TriggerPage : public wxPanel
|
|
{
|
|
public:
|
|
TriggerPage(wxWindow* parent, TriggerSidebar* sidebar, long ID, wxString title, bool condition)
|
|
: wxPanel(parent), m_Sidebar(sidebar), m_Condition(condition)
|
|
|
|
{
|
|
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
|
|
m_List = new TriggerListCtrl(this, sidebar, condition, ID, wxDefaultPosition,
|
|
wxSize(132, 210), wxLC_REPORT | wxLC_SINGLE_SEL);
|
|
m_List->InsertColumn(0, title, wxLIST_FORMAT_LEFT, 100);
|
|
|
|
sizer->Add(m_List);
|
|
SetSizer(sizer);
|
|
}
|
|
|
|
wxListCtrl* m_List;
|
|
TriggerSidebar* m_Sidebar;
|
|
bool m_Condition;
|
|
};
|
|
|
|
|
|
class TriggerItemData : public wxTreeItemData, public sTrigger
|
|
{
|
|
public:
|
|
TriggerItemData(TriggerSidebar* sidebar, const std::wstring& name, bool group)
|
|
: m_Sidebar(sidebar), sTrigger(name), m_Group(group), m_CondCount(0), m_EffectCount(0) {}
|
|
TriggerItemData(TriggerSidebar* sidebar, const sTrigger& trigger, bool group)
|
|
: m_Sidebar(sidebar), sTrigger(trigger), m_Group(group), m_CondCount(0), m_EffectCount(0) {}
|
|
|
|
TriggerSidebar* m_Sidebar;
|
|
size_t m_CondCount, m_EffectCount;
|
|
bool m_Group;
|
|
std::list<int> m_BlockIndices, m_BlockEndIndices; //index in sidebar list
|
|
|
|
void AddBlock(const int block, const int index)
|
|
{
|
|
std::vector<int> copy = *logicBlocks;
|
|
std::vector<bool> notCopy = *logicNots;
|
|
copy.push_back(block);
|
|
notCopy.push_back(false);
|
|
|
|
logicBlocks = copy;
|
|
logicNots = notCopy;
|
|
m_BlockIndices.push_back(index);
|
|
}
|
|
void AddBlockEnd(const int block, const int index)
|
|
{
|
|
std::vector<int> copy = *logicBlockEnds;
|
|
copy.push_back(block);
|
|
logicBlockEnds = copy;
|
|
m_BlockEndIndices.push_back(index);
|
|
}
|
|
|
|
void ResetBlockIndices()
|
|
{
|
|
std::vector<int> newLogicBlocks, newLogicBlockEnds;
|
|
m_BlockIndices.clear();
|
|
m_BlockEndIndices.clear();
|
|
int conditionCount = 0;
|
|
|
|
for (int i=0; i<m_Sidebar->m_ConditionPage->m_List->GetItemCount(); ++i)
|
|
{
|
|
if ( m_Sidebar->m_ConditionPage->m_List->GetItemText(i) == m_Sidebar->m_LogicBlockString )
|
|
{
|
|
newLogicBlocks.push_back(conditionCount);
|
|
m_BlockIndices.push_back(i);
|
|
}
|
|
|
|
//Block ends belong to current condition, hence conditionCount-1
|
|
else if ( m_Sidebar->m_ConditionPage->m_List->GetItemText(i) == m_Sidebar->m_LogicBlockEndString )
|
|
{
|
|
if ( conditionCount == 0 )
|
|
newLogicBlockEnds.push_back(0);
|
|
else
|
|
newLogicBlockEnds.push_back(conditionCount-1);
|
|
m_BlockEndIndices.push_back(i);
|
|
}
|
|
else
|
|
++conditionCount;
|
|
}
|
|
logicBlocks = newLogicBlocks;
|
|
logicBlockEnds = newLogicBlockEnds;
|
|
}
|
|
};
|
|
|
|
|
|
void onTriggerParameter(void* data, std::wstring paramString, int parameter);
|
|
|
|
|
|
class TriggerBottomBar : public wxPanel
|
|
{
|
|
enum { ID_TimeEdit, ID_CondNameEdit, ID_EffectNameEdit, ID_TriggerNameEdit, ID_RunsEdit,
|
|
ID_EffectChoice, ID_CondChoice,
|
|
ID_TimeRadio, ID_LogicRadio,
|
|
ID_NotCheck, ID_ActiveCheck, ID_LogicNotCheck };
|
|
|
|
public:
|
|
enum { NO_VIEW, TRIGGER_VIEW, CONDITION_VIEW, EFFECT_VIEW, LOGIC_END_VIEW, LOGIC_VIEW };
|
|
|
|
TriggerBottomBar(TriggerSidebar* sidebar, wxWindow* parent)
|
|
: wxPanel(parent), m_Sidebar(sidebar)
|
|
{
|
|
m_Sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
SetSizer(m_Sizer);
|
|
m_DependentStatus = NO_VIEW;
|
|
}
|
|
|
|
int GetDependentStatus()
|
|
{
|
|
return m_DependentStatus;
|
|
}
|
|
void SetSpecs(std::vector<sTriggerSpec> conditions, std::vector<sTriggerSpec> effects)
|
|
{
|
|
m_ConditionSpecs = conditions;
|
|
m_EffectSpecs = effects;
|
|
}
|
|
|
|
wxArrayString GetConditionNames()
|
|
{
|
|
wxArrayString ret;
|
|
for ( size_t i = 0; i < m_ConditionSpecs.size(); ++i )
|
|
ret.Add( wxString(m_ConditionSpecs[i].displayName.c_str()) );
|
|
return ret;
|
|
}
|
|
wxArrayString GetEffectNames()
|
|
{
|
|
wxArrayString ret;
|
|
for ( size_t i = 0; i < m_EffectSpecs.size(); ++i )
|
|
ret.Add( wxString(m_EffectSpecs[i].displayName.c_str()) );
|
|
return ret;
|
|
}
|
|
|
|
void onEffectChoice(wxCommandEvent& evt)
|
|
{
|
|
//Retrieve specification corresponding to selection
|
|
if ( m_Sidebar->m_SelectedEffect != -1 )
|
|
{
|
|
std::vector<sTriggerSpec>::iterator it = std::find( m_EffectSpecs.begin(),
|
|
m_EffectSpecs.end(), std::wstring(evt.GetString()) );
|
|
DisplayTriggerSpec(*it);
|
|
}
|
|
}
|
|
|
|
void onCondChoice(wxCommandEvent& evt)
|
|
{
|
|
if ( m_Sidebar->m_SelectedCond != -1 )
|
|
{
|
|
std::vector<sTriggerSpec>::iterator it = std::find( m_ConditionSpecs.begin(),
|
|
m_ConditionSpecs.end(), std::wstring(evt.GetString()) );
|
|
DisplayTriggerSpec(*it);
|
|
}
|
|
}
|
|
|
|
void onTimeEnter(wxCommandEvent& WXUNUSED(evt))
|
|
{
|
|
float fValue;
|
|
std::wstringstream stream( std::wstring(m_TimeEdit->GetValue()) );
|
|
stream >> fValue;
|
|
|
|
if ( stream.fail() )
|
|
{
|
|
wxBell();
|
|
return;
|
|
}
|
|
|
|
m_Sidebar->GetSelectedItemData()->timeValue = fValue;
|
|
wxString value = wxString::Format(L"%.2f", fValue);
|
|
m_TimeEdit->SetValue(value);
|
|
m_Sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onConditionEnter(wxCommandEvent& WXUNUSED(evt))
|
|
{
|
|
if ( m_Sidebar->m_SelectedCond == -1 )
|
|
return;
|
|
|
|
std::vector<sTriggerCondition> conditions = *m_Sidebar->GetSelectedItemData()->conditions;
|
|
int condition = m_Sidebar->GetConditionCount(m_Sidebar->m_SelectedCond);
|
|
|
|
if ( condition == 0 )
|
|
conditions[0].name = std::wstring( m_ConditionEdit->GetValue() );
|
|
else
|
|
conditions[condition-1] = std::wstring( m_ConditionEdit->GetValue() );
|
|
|
|
m_Sidebar->GetSelectedItemData()->conditions = conditions;
|
|
m_Sidebar->UpdateLists();
|
|
m_Sidebar->UpdateEngineData();
|
|
}
|
|
void onEffectEnter(wxCommandEvent& WXUNUSED(evt))
|
|
{
|
|
if ( m_Sidebar->m_SelectedEffect== -1 )
|
|
return;
|
|
|
|
std::vector<sTriggerEffect> effects = *m_Sidebar->GetSelectedItemData()->effects;
|
|
effects[m_Sidebar->m_SelectedEffect].name = std::wstring( m_EffectEdit->GetValue() );
|
|
m_Sidebar->GetSelectedItemData()->effects = effects;
|
|
m_Sidebar->UpdateLists();
|
|
m_Sidebar->UpdateEngineData();
|
|
}
|
|
void onTriggerEnter(wxCommandEvent& WXUNUSED(evt))
|
|
{
|
|
TriggerItemData* data = m_Sidebar->GetSelectedItemData();
|
|
if ( data == NULL || m_Sidebar->m_TriggerTree->GetSelection() == m_Sidebar->m_TriggerTree->GetRootItem() )
|
|
return;
|
|
|
|
wxString name = m_TriggerEdit->GetValue();
|
|
data->name = std::wstring(name);
|
|
m_Sidebar->m_TriggerTree->SetItemText(m_Sidebar->m_TriggerTree->GetSelection(), name);
|
|
m_Sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onRunsEnter(wxCommandEvent& WXUNUSED(evt))
|
|
{
|
|
int iValue;
|
|
std::wstringstream stream( std::wstring(m_RunsEdit->GetValue()) );
|
|
stream >> iValue;
|
|
|
|
if ( stream.fail() )
|
|
{
|
|
wxBell();
|
|
return;
|
|
}
|
|
|
|
m_Sidebar->GetSelectedItemData()->maxRuns = iValue;
|
|
m_Sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onLogicRadio(wxCommandEvent& evt)
|
|
{
|
|
if ( m_Sidebar->m_SelectedCond == -1 )
|
|
return;
|
|
std::vector<sTriggerCondition> conditions = *m_Sidebar->GetSelectedItemData()->conditions;
|
|
int condition = m_Sidebar->GetConditionCount(m_Sidebar->m_SelectedCond);
|
|
conditions[condition-1].linkLogic = evt.GetInt() + 1;
|
|
|
|
m_Sidebar->GetSelectedItemData()->conditions = conditions;
|
|
m_Sidebar->UpdateLists();
|
|
m_Sidebar->UpdateEngineData();
|
|
}
|
|
void onActiveCheck(wxCommandEvent& evt)
|
|
{
|
|
m_Sidebar->GetSelectedItemData()->active = (evt.GetInt() == 1);
|
|
m_Sidebar->UpdateEngineData();
|
|
}
|
|
void onNotCheck(wxCommandEvent& evt)
|
|
{
|
|
if ( m_Sidebar->m_SelectedCond == -1 )
|
|
return;
|
|
std::vector<sTriggerCondition> conditions = *m_Sidebar->GetSelectedItemData()->conditions;
|
|
int condition = m_Sidebar->GetConditionCount(m_Sidebar->m_SelectedCond);
|
|
bool value = (evt.GetInt() == 1);
|
|
conditions[condition-1].negated = value;
|
|
|
|
m_Sidebar->GetSelectedItemData()->conditions = conditions;
|
|
m_Sidebar->UpdateLists();
|
|
m_Sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onLogicNotCheck(wxCommandEvent& evt)
|
|
{
|
|
TriggerItemData* data = m_Sidebar->GetSelectedItemData();
|
|
|
|
int logicIndex = m_Sidebar->GetLogicBlockCount(m_Sidebar->m_SelectedCond) - 1;
|
|
std::vector<bool> nots = *data->logicNots;
|
|
nots[logicIndex] = evt.IsChecked();
|
|
data->logicNots = nots;
|
|
}
|
|
|
|
void DisplayTriggerSpec(const sTriggerSpec& spec)
|
|
{
|
|
if ( m_Sizer->Detach(m_ParameterSizer) )
|
|
{
|
|
m_ParameterSizer->DeleteWindows();
|
|
delete m_ParameterSizer;
|
|
//m_Sizer->Layout();
|
|
// Layout();
|
|
}
|
|
|
|
//m_ParameterSizer = new wxStaticBoxSizer(wxVERTICAL, this, L"Parameters");
|
|
m_ParameterSizer = new wxBoxSizer(wxVERTICAL);
|
|
wxBoxSizer* hRow = NULL;
|
|
std::vector<sTriggerParameter> parameters = *spec.parameters;
|
|
std::vector<std::wstring> stringParameters;
|
|
int row = -1;
|
|
|
|
//Set parameter data to new data if change is needed
|
|
if ( m_Sidebar->m_Notebook->GetCurrentPage() == m_Sidebar->m_ConditionPage )
|
|
{
|
|
std::vector<sTriggerCondition> conditions = *m_Sidebar->GetSelectedItemData()->conditions;
|
|
int condition = m_Sidebar->GetConditionCount(m_Sidebar->m_SelectedCond) - 1 ;
|
|
if ( *conditions[condition].displayName != *spec.displayName )
|
|
{
|
|
std::vector<std::wstring> newParameters(parameters.size());
|
|
conditions[condition].parameters = newParameters;
|
|
conditions[condition].displayName = *spec.displayName;
|
|
conditions[condition].functionName = *spec.functionName;
|
|
m_Sidebar->GetSelectedItemData()->conditions = conditions;
|
|
m_Sidebar->UpdateEngineData();
|
|
}
|
|
stringParameters = *(*m_Sidebar->GetSelectedItemData()->conditions)
|
|
[m_Sidebar->m_SelectedCond].parameters;
|
|
}
|
|
else
|
|
{
|
|
std::vector<sTriggerEffect> effects = *m_Sidebar->GetSelectedItemData()->effects;
|
|
if ( *effects[m_Sidebar->m_SelectedEffect].displayName != *spec.displayName )
|
|
{
|
|
std::vector<std::wstring> newParameters(parameters.size());
|
|
effects[m_Sidebar->m_SelectedEffect].parameters = newParameters;
|
|
effects[m_Sidebar->m_SelectedEffect].displayName = *spec.displayName;
|
|
effects[m_Sidebar->m_SelectedEffect].functionName = *spec.functionName;
|
|
m_Sidebar->GetSelectedItemData()->effects = effects;
|
|
m_Sidebar->UpdateEngineData();
|
|
}
|
|
stringParameters = *(*m_Sidebar->GetSelectedItemData()->effects)
|
|
[m_Sidebar->m_SelectedEffect].parameters;
|
|
}
|
|
|
|
//Add all parameters to sizer
|
|
for ( std::vector<sTriggerParameter>::iterator it=parameters.begin(); it!=parameters.end(); ++it )
|
|
{
|
|
if ( it->row != row )
|
|
{
|
|
row = it->row;
|
|
hRow = new wxBoxSizer(wxHORIZONTAL);
|
|
m_ParameterSizer->Add(hRow);
|
|
}
|
|
|
|
|
|
if ( *it->windowType == std::wstring(L"text") )
|
|
{
|
|
hRow->Add( new wxStaticText(this, wxID_ANY, wxString( (*it->name).c_str() ),
|
|
wxPoint(it->xPos, it->yPos)) );
|
|
wxTextCtrl* text = new TriggerSpecText(this, L"", wxDefaultPosition, wxSize(it->xSize, it->ySize),
|
|
it->parameterOrder, *it->inputType, &onTriggerParameter, this);
|
|
|
|
hRow->Add( text, 0, wxLEFT, 5 );
|
|
wxString fill( stringParameters[it->parameterOrder].c_str() );
|
|
|
|
//Trim quotes
|
|
if ( *it->inputType == L"string" && fill.size() > 0 )
|
|
{
|
|
fill.erase(0, 1);
|
|
fill.erase(fill.size()-1, 1);
|
|
}
|
|
text->SetValue(fill);
|
|
}
|
|
|
|
else if ( *it->windowType == std::wstring(L"choice") )
|
|
{
|
|
qGetTriggerChoices qChoices(*spec.functionName + *it->name);
|
|
qChoices.Post();
|
|
std::vector<std::wstring> choices = *qChoices.choices;
|
|
wxArrayString strings;
|
|
|
|
for ( size_t i = 0; i < choices.size(); ++i )
|
|
strings.Add( wxString(choices[i].c_str()) );
|
|
|
|
hRow->Add( new wxStaticText(this, wxID_ANY, wxString( (*it->name).c_str() ),
|
|
wxPoint(it->xPos, it->yPos)) );
|
|
wxChoice* choice = new TriggerSpecChoice( this, L"", wxDefaultPosition, wxSize(it->xSize, it->ySize),
|
|
strings, it->parameterOrder, &onTriggerParameter, this );
|
|
|
|
hRow->Add(choice);
|
|
choice->SetStringSelection( wxString(stringParameters[it->parameterOrder].c_str()) );
|
|
}
|
|
|
|
else if ( *it->windowType == std::wstring(L"entity_selector") )
|
|
{
|
|
hRow->Add( new wxStaticText(this, wxID_ANY, wxString((*it->name).c_str())) );
|
|
hRow->Add( new TriggerEntitySelector(this, L"Select", wxDefaultPosition,
|
|
wxSize(it->xSize, it->ySize), it->parameterOrder, &onTriggerParameter, this) );
|
|
}
|
|
|
|
else if ( *it->windowType == std::wstring(L"point_placer") )
|
|
{
|
|
hRow->Add( new wxStaticText(this, wxID_ANY, wxString((*it->name).c_str())) );
|
|
hRow->Add( new TriggerPointPlacer(this, wxDefaultPosition, wxSize(it->xSize, it->ySize),
|
|
it->parameterOrder, &onTriggerParameter, this) );
|
|
}
|
|
else
|
|
{
|
|
wxFAIL_MSG(L"Invalid window type for trigger specification");
|
|
row = -1;
|
|
//do something else...
|
|
}
|
|
}
|
|
|
|
//(If nothing was added, it won't be automatically delted)
|
|
if ( row < 0 )
|
|
{
|
|
delete hRow;
|
|
delete m_ParameterSizer;
|
|
}
|
|
else
|
|
m_Sizer->Add(m_ParameterSizer, 0, wxLEFT, 5);
|
|
|
|
m_Sizer->Layout();
|
|
Layout();
|
|
}
|
|
|
|
void FillConditionData()
|
|
{
|
|
if ( m_Sidebar->m_SelectedCond == -1 )
|
|
return;
|
|
|
|
TriggerItemData* itemData = m_Sidebar->GetSelectedItemData();
|
|
int iCondition = m_Sidebar->GetConditionCount(m_Sidebar->m_SelectedCond);
|
|
if ( iCondition <= 0 )
|
|
return;
|
|
sTriggerCondition condition = (*itemData->conditions)[iCondition-1];
|
|
wxString display( (*condition.displayName).c_str() );
|
|
m_ConditionEdit->SetValue( wxString(condition.name.c_str()) );
|
|
|
|
if ( display != L"" )
|
|
{
|
|
std::vector<sTriggerSpec>::iterator it = std::find( m_ConditionSpecs.begin(),
|
|
m_ConditionSpecs.end(), std::wstring(display) );
|
|
if ( it != m_ConditionSpecs.end() )
|
|
{
|
|
m_ConditionChoice->SetStringSelection(display);
|
|
DisplayTriggerSpec(*it);
|
|
}
|
|
}
|
|
else
|
|
m_ConditionChoice->SetStringSelection(display);
|
|
|
|
if ( condition.linkLogic == 0 || condition.linkLogic == 1 )
|
|
m_LogicRadio->SetSelection(0);
|
|
else
|
|
m_LogicRadio->SetSelection(1);
|
|
|
|
m_NotCheck->SetValue(condition.negated);
|
|
}
|
|
|
|
void FillEffectData()
|
|
{
|
|
TriggerItemData* itemData = m_Sidebar->GetSelectedItemData();
|
|
sTriggerEffect effect = (*itemData->effects)[m_Sidebar->m_SelectedEffect];
|
|
wxString display( (*effect.displayName).c_str() );
|
|
|
|
m_EffectEdit->SetValue( wxString(effect.name.c_str()) );
|
|
if ( display != L"" )
|
|
{
|
|
std::vector<sTriggerSpec>::iterator it = std::find( m_EffectSpecs.begin(),
|
|
m_EffectSpecs.end(), std::wstring(display) );
|
|
if ( it != m_EffectSpecs.end() )
|
|
{
|
|
m_EffectChoice->SetStringSelection(display);
|
|
DisplayTriggerSpec(*it);
|
|
}
|
|
}
|
|
//m_TimeRadio->SetSelection(effect.loop);
|
|
|
|
float timeVal = itemData->timeValue;
|
|
wxString value = wxString::Format(L"%.2f", timeVal);
|
|
m_TimeEdit->SetValue(value);
|
|
}
|
|
|
|
void FillTriggerData()
|
|
{
|
|
if ( m_DependentStatus != TRIGGER_VIEW )
|
|
return;
|
|
TriggerItemData* itemData = m_Sidebar->GetSelectedItemData();
|
|
m_TriggerEdit->SetValue( wxString( (*itemData->name).c_str()) );
|
|
m_ActiveCheck->SetValue(itemData->active);
|
|
int runs = itemData->maxRuns;
|
|
m_RunsEdit->SetValue( wxString( wxString::Format(L"%d", runs)) );
|
|
|
|
}
|
|
|
|
void FillLogicData()
|
|
{
|
|
std::vector<bool> nots = *m_Sidebar->GetSelectedItemData()->logicNots;
|
|
m_LogicNotCheck->SetValue( nots[m_Sidebar->GetLogicBlockCount(m_Sidebar->m_SelectedCond)-1] );
|
|
}
|
|
|
|
|
|
void ToEffectView()
|
|
{
|
|
DestroyChildren();
|
|
m_Sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
m_DependentSizer = new wxStaticBoxSizer(wxVERTICAL, this, wxString(L"Trigger Editor"));
|
|
SetSizer(m_Sizer, true);
|
|
|
|
m_DependentSizer = new wxStaticBoxSizer(wxVERTICAL, this, wxString(L"Trigger Editor"));
|
|
wxStaticText* name = new wxStaticText(this, wxID_ANY, wxString(L"Name:"));
|
|
wxStaticText* effect = new wxStaticText(this, wxID_ANY, wxString(L"Effect:"));
|
|
m_EffectEdit = new wxTextCtrl(this, ID_EffectNameEdit, _T(""), wxDefaultPosition,
|
|
wxSize(100, 18), wxTE_PROCESS_ENTER);
|
|
|
|
wxArrayString effectNames = GetEffectNames();
|
|
wxString radioChoice[] = { wxString(L"Delay"), wxString(L"Loop") };
|
|
m_EffectChoice = new wxChoice(this, ID_EffectChoice, wxDefaultPosition, wxSize(100, 13), effectNames);
|
|
|
|
m_TimeRadio = new wxRadioBox(this, ID_TimeRadio, _T("Execution type"),
|
|
wxDefaultPosition, wxDefaultSize, 2, radioChoice, 2, wxRA_SPECIFY_COLS);
|
|
|
|
wxStaticText* time = new wxStaticText(this, wxID_ANY, wxString(L"Time:"));
|
|
m_TimeEdit = new wxTextCtrl(this, ID_TimeEdit, _T(""), wxDefaultPosition,
|
|
wxSize(100, 18), wxTE_PROCESS_ENTER);
|
|
|
|
wxBoxSizer* hNameHolder = new wxBoxSizer(wxHORIZONTAL);
|
|
wxBoxSizer* hEffectHolder = new wxBoxSizer(wxHORIZONTAL);
|
|
wxBoxSizer* hTimeHolder = new wxBoxSizer(wxHORIZONTAL);
|
|
|
|
hNameHolder->Add(name);
|
|
hNameHolder->Add(m_EffectEdit, 0, wxLEFT, 5);
|
|
hEffectHolder->Add(effect);
|
|
hEffectHolder->Add(m_EffectChoice, 0, wxLEFT, 5);
|
|
hTimeHolder->Add(time);
|
|
hTimeHolder->Add(m_TimeEdit, 0, wxLEFT, 5);
|
|
|
|
m_DependentSizer->Add(hNameHolder, 0, wxTOP, 5);
|
|
m_DependentSizer->Add(hEffectHolder, 0, wxTOP, 5);
|
|
m_DependentSizer->Add(m_TimeRadio, 0, wxTOP | wxALIGN_CENTER, 10);
|
|
m_DependentSizer->Add(hTimeHolder, 0, wxTOP | wxALIGN_CENTER, 5);
|
|
|
|
m_Sizer->Add(m_DependentSizer);
|
|
m_Sizer->Layout();
|
|
Layout();
|
|
m_DependentStatus = EFFECT_VIEW;
|
|
}
|
|
|
|
void ToConditionView()
|
|
{
|
|
DestroyChildren();
|
|
m_Sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
m_DependentSizer = new wxStaticBoxSizer(wxVERTICAL, this, wxString(L"Trigger Editor"));
|
|
SetSizer(m_Sizer, true);
|
|
|
|
wxStaticText* name = new wxStaticText(this, wxID_ANY, wxString(L"Name:"));
|
|
wxStaticText* condition = new wxStaticText(this, wxID_ANY, wxString(L"Condition:"));
|
|
m_ConditionEdit = new wxTextCtrl(this, ID_CondNameEdit, _T(""), wxDefaultPosition,
|
|
wxSize(100, 18), wxTE_PROCESS_ENTER);
|
|
|
|
wxArrayString conditionNames = GetConditionNames();
|
|
wxString radioChoice[] = { wxString(L"And"), wxString(L"Or") };
|
|
m_ConditionChoice = new wxChoice(this, ID_CondChoice, wxDefaultPosition,
|
|
wxSize(100, 13), conditionNames);
|
|
|
|
m_LogicRadio = new wxRadioBox(this, ID_LogicRadio, _T("Link logic:"),
|
|
wxDefaultPosition, wxDefaultSize, 2, radioChoice, 2, wxRA_SPECIFY_COLS);
|
|
|
|
m_NotCheck = new wxCheckBox(this, ID_NotCheck, wxString(L"Not "));
|
|
|
|
wxBoxSizer* hNameHolder = new wxBoxSizer(wxHORIZONTAL);
|
|
wxBoxSizer* hConditionHolder = new wxBoxSizer(wxHORIZONTAL);
|
|
wxBoxSizer* hLogicHolder = new wxBoxSizer(wxHORIZONTAL);
|
|
|
|
hNameHolder->Add(name);
|
|
hNameHolder->Add(m_ConditionEdit, 0, wxLEFT | wxALIGN_CENTER, 5);
|
|
hConditionHolder->Add(condition);
|
|
hConditionHolder->Add(m_ConditionChoice, 0, wxLEFT | wxALIGN_CENTER, 5);
|
|
hLogicHolder->Add(m_LogicRadio, 0, 0, 5);
|
|
hLogicHolder->Add(m_NotCheck, 0, wxLEFT | wxALIGN_CENTER, 5);
|
|
|
|
m_DependentSizer->Add(hNameHolder, 0, wxTOP, 5);
|
|
m_DependentSizer->Add(hConditionHolder, 0, wxTOP, 5);
|
|
m_DependentSizer->Add(hLogicHolder, 0, wxALIGN_CENTER | wxTOP, 10);
|
|
|
|
m_Sizer->Add(m_DependentSizer);
|
|
m_Sizer->Layout();
|
|
Layout();
|
|
m_DependentStatus = CONDITION_VIEW;
|
|
}
|
|
|
|
void ToTriggerView()
|
|
{
|
|
DestroyChildren();
|
|
m_Sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
m_DependentSizer = new wxStaticBoxSizer(wxVERTICAL, this, wxString(L"Trigger Editor"));
|
|
SetSizer(m_Sizer, true);
|
|
|
|
wxStaticText* name = new wxStaticText(this, wxID_ANY, wxString(L"Name:"));
|
|
m_TriggerEdit = new wxTextCtrl(this, ID_TriggerNameEdit, _T(""), wxDefaultPosition,
|
|
wxSize(100, 18), wxTE_PROCESS_ENTER);
|
|
|
|
wxStaticText* runs = new wxStaticText(this, wxID_ANY, wxString(L"Maximum runs:"));
|
|
m_RunsEdit = new wxTextCtrl(this, ID_RunsEdit, wxString(L"-1"), wxDefaultPosition, wxSize(100, 18));
|
|
m_ActiveCheck = new wxCheckBox(this, ID_ActiveCheck, wxString(L"Active: "));
|
|
|
|
wxBoxSizer* nameHolder = new wxBoxSizer(wxHORIZONTAL), *runsHolder = new wxBoxSizer(wxHORIZONTAL);
|
|
|
|
nameHolder->Add(name);
|
|
nameHolder->Add(m_TriggerEdit, 0, wxLEFT, 5);
|
|
runsHolder->Add(runs);
|
|
runsHolder->Add(m_RunsEdit, 0, wxLEFT, 5);
|
|
|
|
m_DependentSizer->Add(nameHolder);
|
|
m_DependentSizer->Add(runsHolder, 0, wxTOP, 5);
|
|
m_DependentSizer->Add(m_ActiveCheck, 0, wxTOP, 5);
|
|
|
|
m_Sizer->Add(m_DependentSizer);
|
|
m_Sizer->Layout();
|
|
Layout();
|
|
m_DependentStatus = TRIGGER_VIEW;
|
|
}
|
|
//void ToLogicEndView();
|
|
|
|
void ToLogicView()
|
|
{
|
|
DestroyChildren();
|
|
m_Sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
m_DependentSizer = new wxStaticBoxSizer(wxVERTICAL, this, wxString(L"Trigger Editor"));
|
|
SetSizer(m_Sizer, true);
|
|
|
|
m_LogicNotCheck = new wxCheckBox(this, ID_LogicNotCheck, L"Not");
|
|
m_DependentSizer->Add(m_LogicNotCheck);
|
|
m_Sizer->Add(m_DependentSizer, 0, wxTOP | wxLEFT | wxALIGN_LEFT, 10);
|
|
m_Sizer->Layout();
|
|
Layout();
|
|
m_DependentStatus = LOGIC_VIEW;
|
|
}
|
|
void ToNoView()
|
|
{
|
|
if ( m_DependentStatus == NO_VIEW )
|
|
return;
|
|
DestroyChildren();
|
|
m_DependentStatus = NO_VIEW;
|
|
m_Sidebar->m_ConditionPage->m_List->DeleteAllItems();
|
|
m_Sidebar->m_EffectPage->m_List->DeleteAllItems();
|
|
}
|
|
|
|
TriggerSidebar* m_Sidebar;
|
|
|
|
private:
|
|
|
|
wxBoxSizer* m_Sizer, *m_ParameterSizer;
|
|
wxStaticBoxSizer* m_DependentSizer; //dependent = effect/condition
|
|
|
|
wxTextCtrl* m_TimeEdit, *m_ConditionEdit, *m_EffectEdit, *m_TriggerEdit, *m_RunsEdit;
|
|
wxCheckBox* m_ActiveCheck, *m_NotCheck, *m_LogicNotCheck;
|
|
wxChoice* m_ConditionChoice, *m_EffectChoice;
|
|
wxRadioBox* m_LogicRadio, *m_TimeRadio, m_LogicEndRadio;
|
|
|
|
std::vector<sTriggerSpec> m_ConditionSpecs, m_EffectSpecs;
|
|
|
|
int m_DependentStatus;
|
|
|
|
DECLARE_EVENT_TABLE();
|
|
};
|
|
|
|
|
|
BEGIN_EVENT_TABLE(TriggerBottomBar, wxPanel)
|
|
EVT_TEXT_ENTER(TriggerBottomBar::ID_TimeEdit, TriggerBottomBar::onTimeEnter)
|
|
EVT_TEXT_ENTER(TriggerBottomBar::ID_CondNameEdit, TriggerBottomBar::onConditionEnter)
|
|
EVT_TEXT_ENTER(TriggerBottomBar::ID_EffectNameEdit, TriggerBottomBar::onEffectEnter)
|
|
EVT_TEXT_ENTER(TriggerBottomBar::ID_TriggerNameEdit, TriggerBottomBar::onTriggerEnter)
|
|
EVT_TEXT_ENTER(TriggerBottomBar::ID_RunsEdit, TriggerBottomBar::onRunsEnter)
|
|
EVT_CHOICE(TriggerBottomBar::ID_EffectChoice, TriggerBottomBar::onEffectChoice)
|
|
EVT_CHOICE(TriggerBottomBar::ID_CondChoice, TriggerBottomBar::onCondChoice)
|
|
|
|
EVT_RADIOBOX(TriggerBottomBar::ID_LogicRadio, TriggerBottomBar::onLogicRadio)
|
|
EVT_CHECKBOX(TriggerBottomBar::ID_ActiveCheck, TriggerBottomBar::onActiveCheck)
|
|
EVT_CHECKBOX(TriggerBottomBar::ID_NotCheck, TriggerBottomBar::onNotCheck)
|
|
EVT_CHECKBOX(TriggerBottomBar::ID_LogicNotCheck, TriggerBottomBar::onLogicNotCheck)
|
|
//EVT_RADIOBOX(TriggerBotomBar::ID_TimeRadio, TriggerBottomBar::onTimeRadio)
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
void TriggerTreeCtrl::onClick(wxMouseEvent& evt)
|
|
{
|
|
if ( m_Sidebar->m_TriggerTree->GetSelection() == m_Sidebar->m_TriggerTree->GetRootItem() ||
|
|
!m_Sidebar->m_TriggerTree->GetSelection() )
|
|
{
|
|
m_Sidebar->m_TriggerBottom->ToNoView();
|
|
}
|
|
else
|
|
{
|
|
m_Sidebar->m_TriggerBottom->ToTriggerView();
|
|
m_Sidebar->m_TriggerBottom->FillTriggerData();
|
|
}
|
|
evt.Skip();
|
|
}
|
|
|
|
void TriggerListCtrl::onClick(wxMouseEvent& evt)
|
|
{
|
|
evt.Skip();
|
|
if ( m_Condition )
|
|
{
|
|
if ( m_Sidebar->m_SelectedCond < 0 )
|
|
return;
|
|
|
|
if ( m_Sidebar->m_ConditionPage->m_List->GetItemText(m_Sidebar->m_SelectedCond)
|
|
== m_Sidebar->m_LogicBlockEndString )
|
|
{
|
|
m_Sidebar->m_TriggerBottom->ToNoView();
|
|
}
|
|
else if ( m_Sidebar->m_ConditionPage->m_List->GetItemText(m_Sidebar->m_SelectedCond)
|
|
== m_Sidebar->m_LogicBlockString )
|
|
{
|
|
m_Sidebar->m_TriggerBottom->ToLogicView();
|
|
m_Sidebar->m_TriggerBottom->FillLogicData();
|
|
}
|
|
else
|
|
{
|
|
m_Sidebar->m_TriggerBottom->ToConditionView();
|
|
m_Sidebar->m_TriggerBottom->FillConditionData();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_Sidebar->m_TriggerBottom->ToEffectView();
|
|
if ( m_Sidebar->m_SelectedEffect != -1 )
|
|
m_Sidebar->m_TriggerBottom->FillEffectData();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
TriggerEntitySelector::TriggerEntitySelector(TriggerBottomBar* parent, std::wstring label,
|
|
const wxPoint& pos, const wxSize& size, int parameter, callback func, void* data)
|
|
: wxPanel(parent), m_Parent(parent), m_Parameter(parameter), m_Callback(func), m_Data(data)
|
|
{
|
|
wxBoxSizer* MainSizer = new wxBoxSizer(wxVERTICAL);
|
|
SetSizer(MainSizer);
|
|
MainSizer->Add( new wxButton(this, ID_SELECTION, wxString(label.c_str()), pos, size) );
|
|
MainSizer->Add( new wxButton(this, ID_VIEW, L"View", pos, size) );
|
|
}
|
|
void TriggerEntitySelector::onViewClick(wxCommandEvent& WXUNUSED(evt))
|
|
{
|
|
std::wstring handles;
|
|
if ( m_Parent->m_Sidebar->m_Notebook->GetCurrentPage() == m_Parent->m_Sidebar->m_ConditionPage )
|
|
{
|
|
std::vector<sTriggerCondition> conditions = *m_Parent->m_Sidebar->GetSelectedItemData()->conditions;
|
|
int condition = m_Parent->m_Sidebar->GetConditionCount(m_Parent->m_Sidebar->m_SelectedCond) - 1 ;
|
|
std::vector<std::wstring> parameters = *conditions[condition].parameters;
|
|
handles = parameters[m_Parameter];
|
|
}
|
|
else
|
|
{
|
|
std::vector<sTriggerEffect> effects = *m_Parent->m_Sidebar->GetSelectedItemData()->effects;
|
|
int effect = m_Parent->m_Sidebar->m_SelectedEffect;
|
|
std::vector<std::wstring> parameters = *effects[effect].parameters;
|
|
handles = parameters[m_Parameter];
|
|
}
|
|
|
|
std::vector<ObjectID> IDList;
|
|
size_t previous = handles.find(L"[")+1, current;
|
|
|
|
//remove "]"
|
|
if ( handles.size() )
|
|
handles.erase(handles.size()-1);
|
|
|
|
while ( (current = handles.find(L", ", previous)) != std::wstring::npos )
|
|
{
|
|
std::wstringstream toInt(handles.substr(previous, current - previous));
|
|
int newID;
|
|
toInt >> newID;
|
|
IDList.push_back(newID);
|
|
previous = current+1;
|
|
}
|
|
|
|
std::wstringstream toInt( handles.substr(previous) );
|
|
int newID;
|
|
toInt >> newID;
|
|
IDList.push_back(newID);
|
|
g_SelectedObjects = IDList;
|
|
POST_MESSAGE(SetSelectionPreview, (g_SelectedObjects));
|
|
}
|
|
|
|
void TriggerSpecText::onTextEnter(wxCommandEvent& WXUNUSED(evt))
|
|
{
|
|
std::wstring text( GetValue().wc_str() );
|
|
|
|
if ( VerifyInput(text) )
|
|
(*m_Callback)(m_Data, text, m_Parameter );
|
|
else
|
|
wxBell();
|
|
}
|
|
|
|
TriggerSpecChoice::TriggerSpecChoice(TriggerBottomBar* parent, std::wstring label, const wxPoint& pos,
|
|
const wxSize& size, const wxArrayString& strings, int parameter, callback func, void* data)
|
|
: wxChoice(parent, wxID_ANY, pos, size, strings), m_Callback(func), m_Data(data),
|
|
m_Parent(parent), m_Parameter(parameter)
|
|
{
|
|
}
|
|
void TriggerSpecChoice::onChoice(wxCommandEvent& evt)
|
|
{
|
|
(*m_Callback)(m_Data, std::wstring( evt.GetString().wc_str() ), m_Parameter);
|
|
}
|
|
void onTriggerParameter(void* data, std::wstring paramString, int parameter)
|
|
{
|
|
TriggerBottomBar* bottomBar = static_cast<TriggerBottomBar*>(data);
|
|
|
|
if ( bottomBar->m_Sidebar->m_Notebook->GetSelection() == 0 )
|
|
{
|
|
if ( bottomBar->m_Sidebar->m_SelectedCond == -1 )
|
|
return;
|
|
std::vector<sTriggerCondition> conditions = *bottomBar->m_Sidebar->GetSelectedItemData()->conditions;
|
|
std::vector<std::wstring> parameters = *conditions[bottomBar->m_Sidebar->m_SelectedCond].parameters;
|
|
|
|
parameters[parameter] = paramString;
|
|
conditions[bottomBar->m_Sidebar->m_SelectedCond].parameters = parameters;
|
|
bottomBar->m_Sidebar->GetSelectedItemData()->conditions = conditions;
|
|
}
|
|
else
|
|
{
|
|
if ( bottomBar->m_Sidebar->m_SelectedEffect == -1 )
|
|
return;
|
|
std::vector<sTriggerEffect> effects = *bottomBar->m_Sidebar->GetSelectedItemData()->effects;
|
|
std::vector<std::wstring> parameters = *effects[bottomBar->m_Sidebar->m_SelectedEffect].parameters;
|
|
|
|
parameters[parameter] = paramString;
|
|
effects[bottomBar->m_Sidebar->m_SelectedEffect].parameters = parameters;
|
|
bottomBar->m_Sidebar->GetSelectedItemData()->effects = effects;
|
|
}
|
|
bottomBar->m_Sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onGroupPush(void* data)
|
|
{
|
|
TriggerSidebar* sidebar = static_cast<TriggerSidebar*>(data);
|
|
if ( !sidebar->m_TriggerTree->GetSelection())
|
|
return;
|
|
if ( !sidebar->IsGroupSelected() )
|
|
return;
|
|
|
|
wxString name = wxString::Format(L"Group %d", sidebar->m_GroupCount);
|
|
wxTreeItemId ID = sidebar->m_TriggerTree->AppendItem( sidebar->m_TriggerTree->GetSelection(),
|
|
name, -1, -1, new TriggerItemData(sidebar, std::wstring(name), true) );
|
|
sidebar->m_TriggerTree->EnsureVisible(ID);
|
|
++sidebar->m_GroupCount;
|
|
|
|
sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onTriggerPush(void* data)
|
|
{
|
|
TriggerSidebar* sidebar = static_cast<TriggerSidebar*>(data);
|
|
wxTreeItemId ID = sidebar->m_TriggerTree->GetSelection();
|
|
|
|
if ( !sidebar->IsGroupSelected() )
|
|
ID = sidebar->m_TriggerTree->GetItemParent(ID);
|
|
|
|
wxString name = wxString::Format(L"Trigger %d", sidebar->m_TriggerCount);
|
|
TriggerItemData* itemData = new TriggerItemData(sidebar, std::wstring(name), false);
|
|
itemData->group = std::wstring( sidebar->m_TriggerTree->GetItemText(ID) );
|
|
|
|
ID = sidebar->m_TriggerTree->AppendItem(ID, name, -1, -1, itemData);
|
|
sidebar->m_TriggerTree->Expand( sidebar->m_TriggerTree->GetRootItem() );
|
|
|
|
++sidebar->m_TriggerCount;
|
|
sidebar->m_TriggerTree->SelectItem(ID);
|
|
sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onDeleteTreePush(void* data)
|
|
{
|
|
TriggerSidebar* sidebar = static_cast<TriggerSidebar*>(data);
|
|
if ( sidebar->m_TriggerTree->GetSelection() == sidebar->m_TriggerTree->GetRootItem() )
|
|
return;
|
|
|
|
if ( wxMessageBox( wxString(L"Are you sure you want to delete this item?"),
|
|
wxString(L"Caution"), wxYES_NO ) == wxYES )
|
|
{
|
|
sidebar->m_TriggerTree->Delete(sidebar->m_TriggerTree->GetSelection());
|
|
sidebar->m_TriggerTree->EnsureVisible( sidebar->m_TriggerTree->GetRootItem() );
|
|
sidebar->m_TriggerBottom->FillTriggerData();
|
|
}
|
|
|
|
sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onConditionPush(void* data)
|
|
{
|
|
TriggerSidebar* sidebar = static_cast<TriggerSidebar*>(data);
|
|
if ( sidebar->IsGroupSelected() )
|
|
return;
|
|
|
|
sidebar->m_Notebook->SetSelection(0);
|
|
TriggerItemData* itemData = sidebar->GetSelectedItemData();
|
|
std::wstring name = std::wstring( wxString::Format(L"Condition %d", itemData->m_CondCount).wc_str() );
|
|
|
|
if ( itemData->m_CondCount == 0 )
|
|
sidebar->m_SelectedCond = 0;
|
|
|
|
++itemData->m_CondCount;
|
|
|
|
std::vector<sTriggerCondition> conditions = *itemData->conditions;
|
|
conditions.push_back( sTriggerCondition(name) );
|
|
itemData->conditions = conditions;
|
|
|
|
long count = sidebar->m_ConditionPage->m_List->GetItemCount();
|
|
|
|
sidebar->m_ConditionPage->m_List->InsertItem(count, wxString(name.c_str()) );
|
|
sidebar->m_ConditionPage->m_List->EnsureVisible(count);
|
|
sidebar->m_ConditionPage->m_List->SetItemState(count, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
|
|
|
sidebar->m_TriggerBottom->ToConditionView(); //Some data is not valid, so reset
|
|
sidebar->m_TriggerBottom->FillConditionData();
|
|
|
|
sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onEffectPush(void* data)
|
|
{
|
|
TriggerSidebar* sidebar = static_cast<TriggerSidebar*>(data);
|
|
if ( sidebar->IsGroupSelected() )
|
|
return;
|
|
|
|
sidebar->m_Notebook->SetSelection(1);
|
|
TriggerItemData* itemData = sidebar->GetSelectedItemData();
|
|
std::wstring name = std::wstring( wxString::Format(L"Effect %d", itemData->m_EffectCount).wc_str() );
|
|
|
|
if ( itemData->m_EffectCount == 0 )
|
|
sidebar->m_SelectedEffect = 0;
|
|
++itemData->m_EffectCount;
|
|
|
|
std::vector<sTriggerEffect> effects = *itemData->effects;
|
|
effects.push_back( sTriggerEffect(name) );
|
|
itemData->effects = effects;
|
|
|
|
long count = sidebar->m_EffectPage->m_List->GetItemCount();
|
|
sidebar->m_EffectPage->m_List->InsertItem(count, wxString(name.c_str()) );
|
|
sidebar->m_EffectPage->m_List->EnsureVisible(count);
|
|
sidebar->m_EffectPage->m_List->SetItemState(count, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
|
|
|
sidebar->m_TriggerBottom->ToEffectView();
|
|
sidebar->m_TriggerBottom->FillEffectData();
|
|
|
|
sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onDeleteBookPush(void* data)
|
|
{
|
|
TriggerSidebar* sidebar = static_cast<TriggerSidebar*>(data);
|
|
wxListCtrl* list = static_cast<TriggerPage*>(sidebar->m_Notebook->GetCurrentPage())->m_List;
|
|
if ( !list )
|
|
return;
|
|
|
|
TriggerItemData* itemData = sidebar->GetSelectedItemData();
|
|
//Is condition? -- valid selection?
|
|
if ( list == sidebar->m_ConditionPage->m_List && sidebar->m_SelectedCond != -1 )
|
|
{
|
|
std::wstring text(sidebar->m_ConditionPage->m_List->GetItemText(sidebar->m_SelectedCond) );
|
|
int conditionCount = sidebar->GetConditionCount(sidebar->m_SelectedCond);
|
|
|
|
if ( text == std::wstring(sidebar->m_LogicBlockString.wc_str()) )
|
|
{
|
|
std::vector<int> blocks = *itemData->logicBlocks;
|
|
if ( conditionCount == 0 )
|
|
{
|
|
blocks.erase( std::find(blocks.begin(), blocks.end(), 0) );
|
|
itemData->m_BlockIndices.erase( std::find( itemData->m_BlockIndices.begin(),
|
|
itemData->m_BlockIndices.end(), sidebar->m_SelectedCond ) );
|
|
}
|
|
else
|
|
{
|
|
blocks.erase( std::find(blocks.begin(), blocks.end(), conditionCount) );
|
|
itemData->m_BlockIndices.erase( std::find( itemData->m_BlockIndices.begin(),
|
|
itemData->m_BlockIndices.end(), sidebar->m_SelectedCond ) );
|
|
}
|
|
itemData->logicBlocks = blocks;
|
|
}
|
|
|
|
else if ( text == std::wstring(sidebar->m_LogicBlockEndString.wc_str()) )
|
|
{
|
|
std::vector<int> blockEnds = *itemData->logicBlockEnds;
|
|
if ( conditionCount == 0 )
|
|
{
|
|
blockEnds.erase( std::find(blockEnds.begin(), blockEnds.end(), 0) );
|
|
itemData->m_BlockEndIndices.erase( std::find( itemData->m_BlockEndIndices.begin(),
|
|
itemData->m_BlockEndIndices.end(), sidebar->m_SelectedCond ) );
|
|
}
|
|
else
|
|
{
|
|
blockEnds.erase( std::find(blockEnds.begin(), blockEnds.end(), conditionCount-1) );
|
|
itemData->m_BlockEndIndices.erase( std::find( itemData->m_BlockEndIndices.begin(),
|
|
itemData->m_BlockEndIndices.end(), sidebar->m_SelectedCond ) );
|
|
}
|
|
itemData->logicBlockEnds = blockEnds;
|
|
}
|
|
|
|
else
|
|
{
|
|
std::vector<sTriggerCondition> conditions = *itemData->conditions;
|
|
conditions.erase( std::find(conditions.begin(), conditions.end(), text) );
|
|
itemData->conditions = conditions;
|
|
}
|
|
|
|
list->DeleteItem( sidebar->m_SelectedCond );
|
|
itemData->ResetBlockIndices();
|
|
|
|
if ( sidebar->m_SelectedCond == list->GetItemCount() )
|
|
{
|
|
sidebar->m_SelectedCond = -1;
|
|
sidebar->m_TriggerBottom->ToNoView();
|
|
}
|
|
else
|
|
sidebar->m_TriggerBottom->FillConditionData();
|
|
}
|
|
|
|
else if ( list == sidebar->m_EffectPage->m_List && sidebar->m_SelectedEffect != -1)
|
|
{
|
|
std::vector<sTriggerEffect> effects = *itemData->effects;
|
|
effects.erase( std::find( effects.begin(), effects.end(), std::wstring(
|
|
list->GetItemText(sidebar->m_SelectedEffect)) ) );
|
|
itemData->effects = effects;
|
|
|
|
list->DeleteItem( sidebar->m_SelectedEffect );
|
|
|
|
if ( itemData->effects.GetSize() == 0 || sidebar->m_SelectedEffect == list->GetItemCount() )
|
|
{
|
|
sidebar->m_SelectedEffect = -1;
|
|
sidebar->m_TriggerBottom->ToNoView();
|
|
}
|
|
else
|
|
sidebar->m_TriggerBottom->FillEffectData();
|
|
}
|
|
sidebar->UpdateLists();
|
|
sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onLogicBlockPush(void* data)
|
|
{
|
|
TriggerSidebar* sidebar = static_cast<TriggerSidebar*>(data);
|
|
sidebar->m_Notebook->SetSelection(0);
|
|
|
|
if ( sidebar->IsGroupSelected() )
|
|
return;
|
|
|
|
int limit = sidebar->m_SelectedCond;
|
|
if ( sidebar->m_SelectedCond == -1 )
|
|
limit = sidebar->m_ConditionPage->m_List->GetItemCount()-1;
|
|
|
|
int conditionCount = sidebar->GetConditionCount(limit);
|
|
if ( conditionCount == 0 )
|
|
{
|
|
sidebar->GetSelectedItemData()->AddBlock(0, 0);
|
|
sidebar->UpdateLists();
|
|
return;
|
|
}
|
|
|
|
sidebar->GetSelectedItemData()->AddBlock(conditionCount, limit);
|
|
sidebar->UpdateLists();
|
|
sidebar->m_TriggerBottom->ToLogicView(); //Some data is not valid, so reset
|
|
sidebar->m_TriggerBottom->FillLogicData();
|
|
sidebar->UpdateEngineData();
|
|
}
|
|
|
|
void onBlockEndPush(void* data)
|
|
{
|
|
TriggerSidebar* sidebar = static_cast<TriggerSidebar*>(data);
|
|
sidebar->m_Notebook->SetSelection(0);
|
|
|
|
if ( sidebar->IsGroupSelected() )
|
|
return;
|
|
|
|
int limit = sidebar->m_SelectedCond;
|
|
if ( sidebar->m_SelectedCond == -1 )
|
|
limit = sidebar->m_ConditionPage->m_List->GetItemCount()-1;
|
|
|
|
int conditionCount = sidebar->GetConditionCount(limit);
|
|
if ( conditionCount == 0 )
|
|
{
|
|
sidebar->GetSelectedItemData()->AddBlockEnd(0, 0);
|
|
sidebar->UpdateLists();
|
|
return;
|
|
}
|
|
|
|
sidebar->GetSelectedItemData()->AddBlockEnd(conditionCount-1, limit);
|
|
sidebar->UpdateLists();
|
|
}
|
|
|
|
|
|
TriggerSidebar::TriggerSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer)
|
|
: Sidebar(scenarioEditor, sidebarContainer, bottomBarContainer), m_GroupCount(0), m_TriggerCount(0),
|
|
m_SelectedCond(-1), m_SelectedEffect(-1)
|
|
{
|
|
m_TriggerBottom = new TriggerBottomBar(this, bottomBarContainer);
|
|
m_BottomBar = m_TriggerBottom;
|
|
|
|
m_TriggerTree = new TriggerTreeCtrl(this, wxID_ANY, wxDefaultPosition,
|
|
wxSize(140, 220), wxTR_HAS_BUTTONS | wxTR_EDIT_LABELS);
|
|
m_TriggerTree->AddRoot(L"Triggers", -1, -1, new TriggerItemData(this, L"Triggers", true));
|
|
m_TriggerTree->SelectItem( m_TriggerTree->GetRootItem() );
|
|
m_TriggerTree->Expand( m_TriggerTree->GetRootItem() );
|
|
|
|
|
|
wxBoxSizer* hHolder = new wxBoxSizer(wxHORIZONTAL);
|
|
wxBoxSizer* vHolder = new wxBoxSizer(wxVERTICAL);
|
|
wxBoxSizer* vButtons = new wxBoxSizer(wxVERTICAL);
|
|
|
|
ActionButton* trigButton = new ActionButton( this, L"Trigger", &onTriggerPush,
|
|
this, wxSize(50, 20) );
|
|
ActionButton* groupButton = new ActionButton( this, L"Group", &onGroupPush,
|
|
this, wxSize(50, 20) );
|
|
ActionButton* deleteButton = new ActionButton( this, L"Delete", &onDeleteTreePush,
|
|
this, wxSize(50, 20) );
|
|
|
|
ActionButton* conditionButton = new ActionButton( this, L"Condition",
|
|
&onConditionPush, this, wxSize(54, 20) );
|
|
ActionButton* effectButton = new ActionButton( this, L"Effect",
|
|
&onEffectPush, this, wxSize(50, 20) );
|
|
ActionButton* bookDelete = new ActionButton( this, L"Delete",
|
|
&onDeleteBookPush, this, wxSize(50, 20) );
|
|
ActionButton* logicBlock = new ActionButton( this, L"Block",
|
|
&onLogicBlockPush, this, wxSize(50, 20) );
|
|
ActionButton* logicBlockEnd = new ActionButton( this, L"Block End",
|
|
&onBlockEndPush, this, wxSize(50, 20) );
|
|
|
|
|
|
m_LogicBlockString = wxString(L"--------------------");
|
|
m_LogicBlockEndString = wxString(L"===========");
|
|
wxStaticText* bottomTitle = new wxStaticText( this, wxID_ANY, _T("Conditions and Effects") );
|
|
m_Notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition,
|
|
wxSize(132, 210), wxNB_TOP);
|
|
|
|
m_ConditionPage = new TriggerPage(m_Notebook, this, ID_CondList, wxString(L"Conditions"), true);
|
|
m_EffectPage = new TriggerPage(m_Notebook, this, ID_EffectList, wxString(L"Effects"), false);
|
|
|
|
m_Notebook->AddPage( m_ConditionPage, _T("Conditions") );
|
|
m_Notebook->AddPage( m_EffectPage, _T("Effects") );
|
|
m_Notebook->SetPageSize(wxSize(130, 240));
|
|
|
|
vButtons->Add(trigButton);
|
|
vButtons->Add(groupButton);
|
|
vButtons->Add(deleteButton);
|
|
vButtons->Add(conditionButton, 0, wxTOP, 190);
|
|
vButtons->Add(effectButton);
|
|
vButtons->Add(bookDelete);
|
|
vButtons->Add(logicBlock);
|
|
vButtons->Add(logicBlockEnd);
|
|
|
|
vHolder->Add(m_TriggerTree, 0, wxTOP, 15);
|
|
vHolder->Add(bottomTitle, 0, wxALIGN_CENTER | wxTOP, 5);
|
|
vHolder->Add(m_Notebook, 0, wxTOP, 5 );
|
|
|
|
hHolder->Add(vHolder);
|
|
hHolder->Add(vButtons, 0, wxALIGN_CENTER);
|
|
m_MainSizer->Add(hHolder);
|
|
}
|
|
|
|
int TriggerSidebar::GetConditionCount(int limit)
|
|
{
|
|
int conditionCount = 0;
|
|
wxListCtrl* list = m_ConditionPage->m_List;
|
|
for ( int i = 0; i <= limit; ++i )
|
|
{
|
|
if ( list->GetItemText(i) != m_LogicBlockString && list->GetItemText(i) != m_LogicBlockEndString)
|
|
++conditionCount;
|
|
}
|
|
return conditionCount;
|
|
}
|
|
|
|
int TriggerSidebar::GetLogicBlockCount(int limit)
|
|
{
|
|
int logicCount = 0;
|
|
wxListCtrl* list = m_ConditionPage->m_List;
|
|
for ( int i = 0; i <= limit; ++i )
|
|
{
|
|
if ( list->GetItemText(i) == m_LogicBlockString )
|
|
++logicCount;
|
|
}
|
|
return logicCount;
|
|
}
|
|
void TriggerSidebar::OnFirstDisplay()
|
|
{
|
|
qGetTriggerData dataQuery;
|
|
dataQuery.Post();
|
|
m_TriggerBottom->SetSpecs(*dataQuery.conditions, *dataQuery.effects);
|
|
|
|
//Add all loaded triggers to the tree
|
|
const std::vector<sTriggerGroup> triggerGroups = *dataQuery.groups;
|
|
std::vector<sTriggerGroup>::const_iterator it = std::find( triggerGroups.begin(),
|
|
triggerGroups.end(), std::wstring(L"Triggers") );
|
|
|
|
if ( it != triggerGroups.end() )
|
|
{
|
|
wxTreeItemId invalid;
|
|
AddGroupTree(*it, invalid);
|
|
m_TriggerTree->Expand( m_TriggerTree->GetRootItem() );
|
|
}
|
|
}
|
|
|
|
void TriggerSidebar::AddGroupTree(const sTriggerGroup& group, wxTreeItemId parent)
|
|
{
|
|
wxTreeItemId newID;
|
|
wxString text( (*group.name).c_str() );
|
|
|
|
//Make sure root item doesn't already exist
|
|
if ( !parent && !m_TriggerTree->GetRootItem() )
|
|
newID = m_TriggerTree->AddRoot(text, -1, -1, new TriggerItemData(this, *group.name, true));
|
|
else if ( parent )
|
|
newID = m_TriggerTree->AppendItem(parent, text);
|
|
else
|
|
newID = m_TriggerTree->GetRootItem();
|
|
|
|
const std::vector<sTrigger> triggerBuf = *group.triggers;
|
|
const std::vector<std::wstring> groupBuf = *group.children;
|
|
|
|
for ( size_t i = 0; i < group.children.GetSize(); ++i )
|
|
AddGroupTree( *std::find(m_TriggerGroups.begin(), m_TriggerGroups.end(), groupBuf[i]), newID );
|
|
|
|
for ( size_t i = 0; i < group.triggers.GetSize(); ++i )
|
|
{
|
|
std::wstring trigName = *triggerBuf[i].name;
|
|
size_t condMax = 0, effectMax = 0;
|
|
|
|
//Make triggers start where user last left off
|
|
if ( trigName.find(L"Trigger ") == 0 )
|
|
{
|
|
trigName.erase(0, 8); //remove "Trigger "
|
|
std::wstringstream toInt(trigName);
|
|
size_t convert;
|
|
toInt >> convert;
|
|
++convert;
|
|
|
|
if ( !toInt.fail() )
|
|
{
|
|
if ( convert > m_TriggerCount )
|
|
m_TriggerCount = convert;
|
|
}
|
|
}
|
|
std::vector<sTriggerCondition> conditions = *triggerBuf[i].conditions;
|
|
std::vector<sTriggerEffect> effects = *triggerBuf[i].effects;
|
|
|
|
for ( size_t j = 0; j < conditions.size(); ++j )
|
|
{
|
|
std::wstring condName = *conditions[j].name;
|
|
|
|
if ( condName.find(L"Condition ") == 0 )
|
|
{
|
|
condName.erase(0, 10);
|
|
std::wstringstream toInt(condName);
|
|
size_t convert;
|
|
toInt >> convert;
|
|
++convert;
|
|
|
|
if ( !toInt.fail() )
|
|
{
|
|
if ( convert > condMax )
|
|
condMax = convert;
|
|
}
|
|
}
|
|
}
|
|
|
|
for ( size_t j = 0; j < effects.size(); ++j )
|
|
{
|
|
std::wstring effectName = *effects[j].name;
|
|
|
|
if ( effectName .find(L"Effect ") == 0 )
|
|
{
|
|
effectName.erase(0, 7);
|
|
std::wstringstream toInt(effectName);
|
|
size_t convert;
|
|
toInt >> convert;
|
|
++convert;
|
|
|
|
if ( !toInt.fail() )
|
|
{
|
|
if ( convert > effectMax )
|
|
effectMax = convert;
|
|
}
|
|
}
|
|
}
|
|
TriggerItemData* newTriggerData = new TriggerItemData(this, triggerBuf[i], false);
|
|
newTriggerData->m_CondCount = condMax;
|
|
newTriggerData->m_EffectCount = effectMax;
|
|
m_TriggerTree->AppendItem( newID, wxString( triggerBuf[i].name.c_str() ), -1, -1, newTriggerData);
|
|
}
|
|
}
|
|
|
|
|
|
void TriggerSidebar::onPageChange(wxNotebookEvent& evt)
|
|
{
|
|
if ( evt.GetSelection() == 0 )
|
|
{
|
|
m_TriggerBottom->ToConditionView();
|
|
if ( m_SelectedCond != -1 )
|
|
m_TriggerBottom->FillConditionData();
|
|
return;
|
|
}
|
|
m_TriggerBottom->ToEffectView();
|
|
if ( m_SelectedEffect != -1 )
|
|
m_TriggerBottom->FillEffectData();
|
|
}
|
|
|
|
void TriggerSidebar::onTreeDrag(wxTreeEvent& WXUNUSED(evt))
|
|
{
|
|
//evt.Allow();
|
|
}
|
|
|
|
void TriggerSidebar::onTreeNameChange(wxTreeEvent& evt)
|
|
{
|
|
ToDerived( m_TriggerTree->GetItemData(evt.GetItem()) )->name = std::wstring(
|
|
evt.GetLabel().wc_str());
|
|
UpdateEngineData();
|
|
}
|
|
|
|
void TriggerSidebar::onTreeSelChange(wxTreeEvent& evt)
|
|
{
|
|
//Prevent other triggers from trying to use previous data
|
|
m_SelectedCond = -1;
|
|
m_SelectedEffect = -1;
|
|
|
|
if ( evt.GetItem() == m_TriggerTree->GetRootItem() )
|
|
{
|
|
m_TriggerBottom->ToNoView();
|
|
return;
|
|
}
|
|
|
|
if ( m_TriggerBottom->GetDependentStatus() != TriggerBottomBar::TRIGGER_VIEW )
|
|
m_TriggerBottom->ToTriggerView();
|
|
m_TriggerBottom->FillTriggerData();
|
|
|
|
UpdateLists();
|
|
}
|
|
void TriggerSidebar::UpdateLists()
|
|
{
|
|
TriggerItemData* data = GetSelectedItemData();
|
|
m_ConditionPage->m_List->Freeze();
|
|
m_ConditionPage->m_List->DeleteAllItems();
|
|
m_EffectPage->m_List->Freeze();
|
|
m_EffectPage->m_List->DeleteAllItems();
|
|
|
|
const Shareable<sTriggerCondition>* conditions = data->conditions.GetBuffer();
|
|
for ( size_t i = 0; i < data->conditions.GetSize(); ++i )
|
|
{
|
|
m_ConditionPage->m_List->InsertItem( m_ConditionPage->m_List->
|
|
GetItemCount(), wxString(conditions[i]->name.c_str()) );
|
|
}
|
|
|
|
const Shareable<sTriggerEffect>* effects = data->effects.GetBuffer();
|
|
for ( size_t i = 0; i < data->effects.GetSize(); ++i )
|
|
{
|
|
m_EffectPage->m_List->InsertItem(m_EffectPage->m_List->GetItemCount(),
|
|
wxString(effects[i]->name.c_str()) );
|
|
}
|
|
|
|
//These must be merged and sorted because adding them out-of-order screws up the list
|
|
std::list<LogicBlockHelper> sortedBlocks;
|
|
std::list<int> blocks = data->m_BlockIndices, blockEnds = data->m_BlockEndIndices;
|
|
|
|
for ( std::list<int>::iterator it = blocks.begin(); it != blocks.end(); ++it )
|
|
sortedBlocks.push_back( LogicBlockHelper(*it, false) );
|
|
for ( std::list<int>::iterator it = blockEnds.begin(); it != blockEnds.end(); ++it )
|
|
sortedBlocks.push_back( LogicBlockHelper(*it, true) );
|
|
|
|
sortedBlocks.sort();
|
|
for ( std::list<LogicBlockHelper>::iterator it = sortedBlocks.begin(); it != sortedBlocks.end(); ++it )
|
|
{
|
|
if ( it->end )
|
|
m_ConditionPage->m_List->InsertItem(it->index, m_LogicBlockEndString);
|
|
else
|
|
m_ConditionPage->m_List->InsertItem(it->index, m_LogicBlockString);
|
|
}
|
|
|
|
m_ConditionPage->m_List->Thaw();
|
|
m_EffectPage->m_List->Thaw();
|
|
}
|
|
|
|
void TriggerSidebar::onCondSelect(wxListEvent& evt)
|
|
{
|
|
m_SelectedCond = evt.GetIndex();
|
|
//if ( m_TriggerBottom->GetDependentStatus() != TriggerBottomBar::CONDITION_VIEW )
|
|
if ( m_ConditionPage->m_List->GetItemText(m_SelectedCond)
|
|
== m_LogicBlockEndString )
|
|
{
|
|
m_TriggerBottom->ToNoView();
|
|
}
|
|
else if ( m_ConditionPage->m_List->GetItemText(m_SelectedCond)
|
|
== m_LogicBlockString )
|
|
{
|
|
m_TriggerBottom->ToLogicView();
|
|
|
|
if ( m_SelectedCond != -1 )
|
|
m_TriggerBottom->FillLogicData();
|
|
}
|
|
else
|
|
{
|
|
m_TriggerBottom->ToConditionView();
|
|
if ( m_SelectedCond != -1 )
|
|
m_TriggerBottom->FillConditionData();
|
|
}
|
|
}
|
|
void TriggerSidebar::onEffectSelect(wxListEvent& evt)
|
|
{
|
|
m_SelectedEffect = evt.GetIndex();
|
|
//if ( m_TriggerBottom->GetDependentStatus() != TriggerBottomBar::EFFECT_VIEW )
|
|
m_TriggerBottom->ToEffectView();
|
|
m_TriggerBottom->FillEffectData();
|
|
}
|
|
|
|
bool TriggerSidebar::IsGroupSelected()
|
|
{
|
|
if ( ToDerived( m_TriggerTree->GetItemData(m_TriggerTree->GetSelection()) )->m_Group )
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
sTrigger TriggerSidebar::CreateTrigger(TriggerItemData* data)
|
|
{
|
|
sTrigger trigger;
|
|
|
|
trigger.active = data->active;
|
|
trigger.group = data->group;
|
|
trigger.maxRuns = data->maxRuns;
|
|
trigger.name = data->name;
|
|
trigger.timeValue = data->timeValue;
|
|
|
|
trigger.logicBlockEnds = data->logicBlockEnds;
|
|
trigger.logicBlocks = data->logicBlocks;
|
|
trigger.conditions = data->conditions;
|
|
trigger.effects = data->effects;
|
|
trigger.logicNots = data->logicNots;
|
|
|
|
return trigger;
|
|
}
|
|
|
|
void TriggerSidebar::CreateGroup(std::vector<sTriggerGroup>& groupList, sTriggerGroup& parent, wxTreeItemId index)
|
|
{
|
|
wxTreeItemIdValue cookie;
|
|
std::vector<sTrigger> triggers;
|
|
sTriggerGroup group( std::wstring(m_TriggerTree->GetItemText(index)) );
|
|
group.parentName = parent.name;
|
|
|
|
//Add this group to parent's child group
|
|
std::vector<std::wstring> parentChildren = *parent.children;
|
|
parentChildren.push_back(*group.parentName);
|
|
parent.children = parentChildren;
|
|
|
|
for ( wxTreeItemId ID = m_TriggerTree->GetFirstChild(index, cookie); ID.IsOk();
|
|
ID = m_TriggerTree->GetNextChild(index, cookie) )
|
|
{
|
|
TriggerItemData* itemData = ToDerived( m_TriggerTree->GetItemData(ID) );
|
|
if ( itemData->m_Group )
|
|
CreateGroup(groupList, group, ID);
|
|
else
|
|
triggers.push_back( CreateTrigger(itemData) );
|
|
}
|
|
|
|
group.triggers = triggers;
|
|
groupList.push_back(group);
|
|
}
|
|
|
|
void TriggerSidebar::UpdateEngineData()
|
|
{
|
|
wxTreeItemIdValue cookie;
|
|
wxTreeItemId root = m_TriggerTree->GetRootItem();
|
|
|
|
//Find all root groups
|
|
std::vector<sTriggerGroup> groups;
|
|
std::vector<sTrigger> triggers;
|
|
sTriggerGroup rootGroup(L"Triggers");
|
|
|
|
for ( wxTreeItemId ID = m_TriggerTree->GetFirstChild(root, cookie); ID.IsOk();
|
|
ID = m_TriggerTree->GetNextChild(root, cookie) )
|
|
{
|
|
TriggerItemData* itemData = ToDerived( m_TriggerTree->GetItemData(ID) );
|
|
if ( itemData->m_Group )
|
|
CreateGroup(groups, rootGroup, ID);
|
|
else
|
|
triggers.push_back( CreateTrigger(itemData) );
|
|
}
|
|
|
|
rootGroup.triggers = triggers;
|
|
groups.push_back(rootGroup);
|
|
POST_COMMAND( SetAllTriggers, (groups) );
|
|
}
|
|
TriggerItemData* TriggerSidebar::ToDerived(wxTreeItemData* data)
|
|
{
|
|
return ( static_cast<TriggerItemData*>(data) );
|
|
}
|
|
TriggerItemData* TriggerSidebar::GetSelectedItemData()
|
|
{
|
|
if ( !m_TriggerTree->GetSelection() )
|
|
m_TriggerTree->SelectItem(m_TriggerTree->GetRootItem());
|
|
return ToDerived( m_TriggerTree->GetItemData(m_TriggerTree->GetSelection()) );
|
|
|
|
}
|
|
|