2
* animateFilterDialog.cpp - Framewise animation of filter properties
3
* Copyright (C) 2013, D Haley
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18
// -*- C++ -*- generated by wxGlade b48da20df8f4++ on Mon May 7 22:48:14 2012
20
#include "animateFilterDialog.h"
21
#include "resolutionDialog.h"
24
#include "./animateSubDialogs/realKeyFrameDialog.h"
25
#include "./animateSubDialogs/colourKeyFrameDialog.h"
26
#include "./animateSubDialogs/stringKeyFrameDialog.h"
27
#include "./animateSubDialogs/choiceKeyFrameDialog.h"
28
// begin wxGlade: ::extracode
32
#include <wx/filename.h>
33
#include "common/translation.h"
34
#include "common/stringFuncs.h"
35
#include "wxcomponents.h"
41
ID_ANIMATION_GRID_CTRL,
42
ID_BUTTON_FRAME_REMOVE,
46
ID_TEXTBOX_IMAGEPREFIX,
49
ID_CHECK_ONLYDATACHANGE,
60
ID_FILTER_PROPERTY_VALUE_GRID
73
FRAME_CELL_FILTERNAME,
78
const size_t RANGE_FORMAT_NUM_OPTIONS=3;
81
//TODO: This should be merged into aptclasses?
82
const char *extension[RANGE_FORMAT_NUM_OPTIONS] =
89
const char * comboRange_choices[RANGE_FORMAT_NUM_OPTIONS] =
91
NTRANS("Oak-Ridge RNG"),
92
NTRANS("Cameca/Ametek RRNG"),
93
NTRANS("Cameca/Ametek ENV")
102
bool getRealKeyFrame(FrameProperties &frameProp,
103
FilterProperty &filterProp, RealKeyFrameDialog<T> *r)
105
if( r->ShowModal() != wxID_OK)
111
//Copy out the data obtained from the dialog
112
size_t transitionMode;
114
transitionMode=r->getTransitionMode();
115
frameProp.setInterpMode(transitionMode);
117
value=r->getStartValue();
118
stream_cast(filterProp.data,value);
120
frameProp.addKeyFrame(r->getStartFrame(),filterProp);
122
//Add end value as needed
123
switch(transitionMode)
125
case TRANSITION_STEP:
127
case TRANSITION_INTERP:
128
value=r->getEndValue();
129
stream_cast(filterProp.data,value);
130
frameProp.addKeyFrame(r->getEndFrame(),filterProp);
141
ExportAnimationDialog::ExportAnimationDialog(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
142
wxDialog(parent, id, title, pos, size, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX|wxMINIMIZE_BOX)
144
// begin wxGlade: ExportAnimationDialog::ExportAnimationDialog
145
viewNotebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
146
frameViewPane = new wxPanel(viewNotebook, wxID_ANY);
147
filterViewPane = new wxPanel(viewNotebook, wxID_ANY);
148
splitPaneFilter = new wxSplitterWindow(filterViewPane, ID_SPLIT_FILTERVIEW, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_BORDER);
149
filterRightPane = new wxPanel(splitPaneFilter, wxID_ANY);
150
filterLeftPane = new wxPanel(splitPaneFilter, wxID_ANY);
151
keyFramesSizer_staticbox = new wxStaticBox(filterRightPane, -1, wxTRANS("Key frames"));
152
outputDataSizer_staticbox = new wxStaticBox(frameViewPane, -1, wxTRANS("Output Data"));
153
filterPropertySizer_staticbox = new wxStaticBox(filterLeftPane, -1, wxTRANS("Filters and properties"));
154
filterTreeCtrl =new wxTreeCtrl(filterLeftPane,ID_FILTER_TREE_CTRL , wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_NO_LINES|wxTR_HIDE_ROOT|wxTR_DEFAULT_STYLE|wxSUNKEN_BORDER|wxTR_EDIT_LABELS);
156
propertyGrid = new wxPropertyGrid(filterLeftPane, ID_PROPERTY_GRID);
157
animationGrid = new wxGrid(filterRightPane, ID_ANIMATION_GRID_CTRL);
158
keyFrameRemoveButton = new wxButton(filterRightPane, wxID_REMOVE, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
159
labelWorkDir = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("Dir : "));
160
textWorkDir = new wxTextCtrl(frameViewPane, ID_TEXTBOX_WORKDIR, wxEmptyString);
161
buttonWorkDir = new wxButton(frameViewPane, wxID_OPEN, wxEmptyString);
162
checkOutOnlyChanged = new wxCheckBox(frameViewPane, ID_CHECK_ONLYDATACHANGE, wxTRANS("Output only when refresh required"));
163
outputDataSepLine = new wxStaticLine(frameViewPane, wxID_ANY);
164
labelDataType = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("Data Types:"));
165
checkImageOutput = new wxCheckBox(frameViewPane, ID_CHECK_IMAGE_OUT, wxTRANS("3D Images"));
166
lblImageName = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("File Prefix: "));
167
textImageName = new wxTextCtrl(frameViewPane, ID_TEXTBOX_IMAGEPREFIX, wxEmptyString);
168
labelImageSize = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("Size : "));
169
textImageSize = new wxTextCtrl(frameViewPane, ID_TEXTBOX_IMAGESIZE, wxEmptyString);
170
buttonImageSize = new wxButton(frameViewPane, ID_BUTTON_IMAGE_RES, wxTRANS("..."));
171
checkPoints = new wxCheckBox(frameViewPane, ID_CHECK_POINT_OUT, wxTRANS("Point data"));
172
checkPlotData = new wxCheckBox(frameViewPane, ID_CHECK_PLOT_OUT, wxTRANS("Plots"));
173
checkVoxelData = new wxCheckBox(frameViewPane, ID_CHECK_VOXEL_OUT, wxTRANS("Voxel data"));
174
checkRangeData = new wxCheckBox(frameViewPane, ID_CHECK_RANGE_OUT, wxTRANS("Range files"));
175
labelRangeFormat = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("Format"));
177
//Workaround for wx bug http://trac.wxwidgets.org/ticket/4398
178
wxSortedArrayString rangeNames;
179
for(unsigned int ui=0;ui<RANGE_FORMAT_NUM_OPTIONS; ui++)
181
const char * str = comboRange_choices[ui];
183
//construct translation->comboRange_choices offset.
184
rangeMap[TRANS(str)] = ui;
185
//Add to filter name wxArray
186
wxString wxStrTrans = wxTRANS(str);
187
rangeNames.Add(wxStrTrans);
189
comboRangeFormat = new wxChoice(frameViewPane, ID_COMBO_RANGE_TYPE, wxDefaultPosition, wxDefaultSize, rangeNames);
190
static_line_1 = new wxStaticLine(frameViewPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL);
191
labelFrame = new wxStaticText(frameViewPane, wxID_ANY, wxTRANS("Frame"));
192
frameSlider = new wxSlider(frameViewPane, ID_FRAME_SLIDER, 1, 1, 1);
193
textFrame = new wxTextCtrl(frameViewPane, ID_FRAME_TEXTBOX, wxEmptyString);
194
framePropGrid = new wxGrid(frameViewPane, ID_FILTER_PROPERTY_VALUE_GRID);
195
cancelButton = new wxButton(this, wxID_CANCEL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
196
okButton = new wxButton(this, wxID_OK, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
204
#if wxCHECK_VERSION(2,9,0)
205
//Manually tuned splitter parameters
206
splitPaneFilter->SetMinimumPaneSize(220);
208
GetClientSize(&w,&h);
212
splitPaneFilter->SetSashPosition((int)(sashFrac*w));
215
programmaticEvent=true;
217
//-- set up the default properties for dialog back-end data
223
wantPlotOutput=checkPlotData->IsChecked();
224
wantImageOutput=checkImageOutput->IsChecked();
225
wantIonOutput=checkPoints->IsChecked();
226
wantPlotOutput=checkPlotData->IsChecked();
227
wantVoxelOutput=checkVoxelData->IsChecked();
228
wantRangeOutput=checkRangeData->IsChecked();
229
wantOnlyChanges=checkOutOnlyChanged->IsChecked();
231
string sFirst,sSecond;
232
stream_cast(sFirst,imageWidth);
233
stream_cast(sSecond,imageHeight);
234
textImageSize->SetValue(wxStr(string(sFirst+string("x")+sSecond)));
235
textImageSize->SetBackgroundColour(wxNullColour);
237
comboRangeFormat->Enable(checkRangeData->IsChecked());
240
existsConflicts=false;
243
programmaticEvent=false;
246
ExportAnimationDialog::~ExportAnimationDialog()
251
BEGIN_EVENT_TABLE(ExportAnimationDialog, wxDialog)
252
// begin wxGlade: ExportAnimationDialog::event_table
253
EVT_TREE_SEL_CHANGED(ID_FILTER_TREE_CTRL, ExportAnimationDialog::OnFilterTreeCtrlSelChanged)
254
EVT_GRID_CMD_EDITOR_SHOWN(ID_PROPERTY_GRID, ExportAnimationDialog::OnFilterGridCellEditorShow)
255
EVT_GRID_CMD_EDITOR_SHOWN(ID_ANIMATION_GRID_CTRL, ExportAnimationDialog::OnFrameGridCellEditorShow)
256
EVT_GRID_CMD_EDITOR_SHOWN(ID_FILTER_TREE_CTRL, ExportAnimationDialog::OnAnimateGridCellEditorShow)
257
EVT_SPLITTER_UNSPLIT(ID_SPLIT_FILTERVIEW, ExportAnimationDialog::OnFilterViewUnsplit)
258
EVT_BUTTON(wxID_REMOVE, ExportAnimationDialog::OnButtonKeyFrameRemove)
259
EVT_TEXT(ID_TEXTBOX_WORKDIR, ExportAnimationDialog::OnOutputDirText)
260
EVT_BUTTON(wxID_OPEN, ExportAnimationDialog::OnButtonWorkDir)
261
EVT_CHECKBOX(ID_CHECK_ONLYDATACHANGE, ExportAnimationDialog::OnCheckOutDataChange)
262
EVT_CHECKBOX(ID_CHECK_IMAGE_OUT, ExportAnimationDialog::OnCheckImageOutput)
263
EVT_TEXT(ID_TEXTBOX_IMAGEPREFIX, ExportAnimationDialog::OnImageFilePrefix)
264
EVT_TEXT(ID_TEXTBOX_IMAGESIZE, ExportAnimationDialog::OnTextImageSize)
265
EVT_BUTTON(ID_BUTTON_IMAGE_RES, ExportAnimationDialog::OnBtnResolution)
266
EVT_CHECKBOX(ID_CHECK_POINT_OUT, ExportAnimationDialog::OnCheckPointOutput)
267
EVT_CHECKBOX(ID_CHECK_PLOT_OUT, ExportAnimationDialog::OnCheckPlotOutput)
268
EVT_CHECKBOX(ID_CHECK_VOXEL_OUT, ExportAnimationDialog::OnCheckVoxelOutput)
269
EVT_CHECKBOX(ID_CHECK_RANGE_OUT, ExportAnimationDialog::OnCheckRangeOutput)
270
EVT_CHOICE(ID_COMBO_RANGE_TYPE, ExportAnimationDialog::OnRangeTypeCombo)
271
EVT_COMMAND_SCROLL(ID_FRAME_SLIDER, ExportAnimationDialog::OnFrameViewSlider)
272
EVT_TEXT(ID_FRAME_TEXTBOX, ExportAnimationDialog::OnTextFrame)
273
EVT_BUTTON(ID_BTN_CANCEL, ExportAnimationDialog::OnButtonCancel)
274
EVT_BUTTON(ID_BTN_OK, ExportAnimationDialog::OnButtonOK)
279
bool ExportAnimationDialog::getModifiedTree(size_t frame, FilterTree &t,bool &needsUp) const
281
vector<FrameProperties> propsAtFrame;
282
vector<size_t> propIds;
284
propertyAnimator.getPropertiesAtFrame(frame,propIds,propsAtFrame);
287
for(size_t ui=0;ui<propsAtFrame.size();ui++)
289
//Get the animated value for the current property
291
std::string animatedValue;
292
animatedValue=propertyAnimator.getInterpolatedFilterData(
293
propsAtFrame[ui].getFilterId(),
294
propsAtFrame[ui].getPropertyKey(),frame);
296
//Set that property in the filter, aborting if unable to
299
//Obtain pointer to filter that we wish to modify
301
filterPtr= filterMap.at(propsAtFrame[ui].getFilterId());
303
bool needUpThisFrame;
304
if(!t.setFilterProperty(filterPtr,propsAtFrame[ui].getPropertyKey(),
305
animatedValue,needUpThisFrame))
308
needsUp|=needUpThisFrame;
315
std::string ExportAnimationDialog::getFilename(unsigned int frame,
316
unsigned int type,unsigned int number) const
319
stream_cast(s,frame);
321
s=workDir+stlStr(wxFileName::GetPathSeparator())+s + string("-");
326
s+=std::string(".png");
329
s+=std::string(".pos");
333
ASSERT(rangeExportMode<RANGE_FORMAT_NUM_OPTIONS);
336
stream_cast(tmp,number);
337
s+=tmp + string(".");
338
s+=extension[rangeExportMode];
344
stream_cast(tmp,number);
345
s+="-" + tmp + ".txt";
349
s+=std::string(".raw");
358
void ExportAnimationDialog::prepare()
360
vector<const Filter*> dummyVec;
361
upWxTreeCtrl(*filterTree,filterTreeCtrl,filterMap,
367
void ExportAnimationDialog::updateFilterViewGrid()
370
animationGrid->BeginBatch();
371
if(animationGrid->GetNumberRows())
372
animationGrid->DeleteRows(0,animationGrid->GetNumberRows());
373
animationGrid->EndBatch();
376
animationGrid->AppendRows(propertyAnimator.getNumProps());
377
for(size_t ui=0;ui<propertyAnimator.getNumProps(); ui++)
379
FrameProperties frameProps;
380
propertyAnimator.getNthKeyFrame(ui,frameProps);
382
//Obtain pointer to filter
383
const Filter *filterPtr;
384
filterPtr= filterMap[frameProps.getFilterId()];
386
//Get (generic) properties from that filter
387
FilterPropGroup filtPropGroup;
388
filterPtr->getProperties(filtPropGroup);
389
FilterProperty filtProp;
390
filtProp=filtPropGroup.getPropValue(frameProps.getPropertyKey());
392
animationGrid->SetCellValue(ui,CELL_FILTERNAME,
393
wxStr(filterPtr->getUserString()));
394
animationGrid->SetCellValue(ui,CELL_PROPERTYNAME,
395
wxStr(filtProp.name));
396
animationGrid->SetCellValue(ui,CELL_KEYINTERPMODE,
397
wxCStr(INTERP_NAME[frameProps.getInterpMode()]));
400
stream_cast(str,frameProps.getMinFrame());
401
animationGrid->SetCellValue(ui,CELL_STARTFRAME, wxStr(str));
402
stream_cast(str,frameProps.getMaxFrame());
403
animationGrid->SetCellValue(ui,CELL_ENDFRAME, wxStr(str));
406
//Check for conflicting rows in the animation dialog,
407
// and highlight them in colour
408
set<size_t> conflictRows;
409
if(!propertyAnimator.checkSelfConsistent(conflictRows))
411
existsConflicts=true;
412
for(std::set<size_t>::const_iterator it=conflictRows.begin();
413
it!=conflictRows.end();++it)
415
wxGridCellAttr *colourRowAttr=new wxGridCellAttr;
416
colourRowAttr->SetBackgroundColour(wxColour(*wxCYAN));
417
animationGrid->SetRowAttr(*it,colourRowAttr);
422
void ExportAnimationDialog::updateFrameViewGrid()
424
ASSERT(currentFrame <= frameSlider->GetMax());
427
framePropGrid->BeginBatch();
428
if(framePropGrid->GetNumberRows())
429
framePropGrid->DeleteRows(0,animationGrid->GetNumberRows());
430
framePropGrid->EndBatch();
432
std::set<size_t> conflictProps;
433
if(!propertyAnimator.checkSelfConsistent(conflictProps))
436
vector<FrameProperties> alteredProperties;
437
vector<size_t> propertyIds;
438
//Grab the properties that have been modified from their initial value
439
// and then refill the grid with this data
440
propertyAnimator.getPropertiesAtFrame(currentFrame,
441
propertyIds,alteredProperties);
443
framePropGrid->AppendRows(alteredProperties.size());
445
for(size_t ui=0; ui<alteredProperties.size();ui++)
447
//Obtain filter and property name for the current property
449
std::string filterName,propertyName;
453
idFilter=alteredProperties[ui].getFilterId();
454
filterName= filterMap[idFilter]->getUserString();
459
//obtain filter properties
460
filterMap.at(idFilter)->getProperties(p);
461
prop=p.getPropValue(alteredProperties[ui].getPropertyKey());
462
propertyName=prop.name;
465
std::string animatedValue;
466
animatedValue=propertyAnimator.getInterpolatedFilterData(
467
alteredProperties[ui].getFilterId(),prop.key,currentFrame);
470
//Modify the grid properties with the appropriate data
471
framePropGrid->SetCellValue(ui,FRAME_CELL_FILTERNAME,
473
framePropGrid->SetCellValue(ui,FRAME_CELL_PROPNAME,
474
wxStr(propertyName));
475
framePropGrid->SetCellValue(ui,FRAME_CELL_VALUE,
476
wxStr(animatedValue));
481
void ExportAnimationDialog::updateFrameViewSlider()
484
programmaticEvent=true;
486
//reset the range on the frame slider
488
maxFrameVal=propertyAnimator.getMaxFrame();
489
frameSlider->SetMin(0);
490
frameSlider->SetMax(maxFrameVal);
493
std::string textCurrent,textMax;
494
stream_cast(textCurrent,frameSlider->GetValue());
495
stream_cast(textMax,propertyAnimator.getMaxFrame());
497
textCurrent= (textCurrent + std::string("/") + textMax);
498
textFrame->SetValue( wxStr(textCurrent));
500
programmaticEvent=false;
504
void ExportAnimationDialog::OnTextFrame(wxCommandEvent &event)
506
if(programmaticEvent)
510
s=stlStr(textFrame->GetValue());
516
if(pos==string::npos)
521
first = s.substr(0,pos);
522
last=s.substr(pos+1);
525
if(stream_cast(frameCur,first))
530
if(stream_cast(frameEnd,last))
535
textFrame->SetBackgroundColour(*wxCYAN);
538
textFrame->SetBackgroundColour(wxNullColour);
540
currentFrame=frameCur;
542
updateFrameViewGrid();
549
void ExportAnimationDialog::OnFrameViewSlider(wxScrollEvent &event)
551
programmaticEvent=true;
552
size_t sliderVal=frameSlider->GetValue();
555
std::string frameText,tmp;
556
stream_cast(frameText,sliderVal);
558
stream_cast(tmp,frameSlider->GetMax());
561
textFrame->SetValue( wxStr(frameText));
563
currentFrame=sliderVal;
564
updateFrameViewGrid();
565
programmaticEvent=false;
568
void ExportAnimationDialog::OnButtonCancel(wxCommandEvent &event)
573
void ExportAnimationDialog::update()
575
programmaticEvent=true;
576
updateFilterViewGrid();
577
updateFrameViewGrid();
578
updateFrameViewSlider();
580
programmaticEvent=false;
583
void ExportAnimationDialog::OnFilterTreeCtrlSelChanged(wxTreeEvent &event)
585
//Get the parent filter pointer
586
wxTreeItemId id=filterTreeCtrl->GetSelection();;
588
if(id !=filterTreeCtrl->GetRootItem() && id.IsOk())
590
wxTreeItemData *parentData=filterTreeCtrl->GetItemData(id);
591
updateFilterPropertyGrid(propertyGrid,
592
filterMap[((wxTreeUint *)parentData)->value]);
599
void ExportAnimationDialog::OnFilterGridCellEditorShow(wxGridEvent &event)
602
wxTreeItemId id=filterTreeCtrl->GetSelection();;
604
if(id ==filterTreeCtrl->GetRootItem() || !id.IsOk())
609
key=propertyGrid->getKeyFromRow(event.GetRow());
611
//Get the filter ID value
613
wxTreeItemId tId = filterTreeCtrl->GetSelection();
617
wxTreeItemData *tData=filterTreeCtrl->GetItemData(tId);
618
filterId = ((wxTreeUint *)tData)->value;
621
f=filterMap.at(filterId);
623
//Obtain the filter property that was selected by the user
625
FilterPropGroup propGroup;
626
f->getProperties(propGroup);
628
FilterProperty filterProp;
629
filterProp=propGroup.getPropValue(key);
632
//Create a property entry for this, and get values from user
633
FrameProperties frameProp(filterId,key);
634
switch(filterProp.type)
636
case PROPERTY_TYPE_BOOL:
638
wxTextEntryDialog *teD = new wxTextEntryDialog(this,wxTRANS("transition frame"),wxTRANS("Frame count"),
639
wxT("0"),(long int)wxOK|wxCANCEL);
645
if(teD->ShowModal() == wxID_CANCEL)
651
s=stlStr(teD->GetValue());
653
while(stream_cast(frameValue,s));
654
ASSERT(filterProp.data == "1" || filterProp.data == "0");
657
//Find the last property for the filter from the animator
660
sData=propertyAnimator.getInterpolatedFilterData(filterId,
661
key,std::min(frameValue,
662
propertyAnimator.getMaxFrame()));
666
ASSERT(sData == "0" || sData == "1");
667
filterProp.data=sData;
671
if(filterProp.data == "1")
676
frameProp.setInterpMode(INTERP_STEP);
677
frameProp.addKeyFrame(frameValue,filterProp);
682
case PROPERTY_TYPE_CHOICE:
684
vector<string> choiceVec;
685
unsigned int activeChoice;
686
choiceStringToVector(filterProp.data,choiceVec,activeChoice);
688
ChoiceKeyFrameDialog *cD = new ChoiceKeyFrameDialog(this,
690
cD->setChoices(choiceVec);
692
if( cD->ShowModal() != wxID_OK)
698
filterProp.data=cD->getChoice();
699
frameProp.setInterpMode(INTERP_STEP);
700
frameProp.addKeyFrame(cD->getStartFrame(),filterProp);
707
case PROPERTY_TYPE_COLOUR:
709
ColourKeyFrameDialog *colDlg = new ColourKeyFrameDialog(this,
710
wxID_ANY,wxTRANS("Key frame : Colour")) ;
711
if( colDlg->ShowModal() != wxID_OK)
717
//Copy out the data obtained from the dialog
718
size_t transitionMode;
719
transitionMode=colDlg->getTransitionMode();
721
frameProp.setInterpMode(transitionMode);
722
filterProp.data=colDlg->getStartValue();
724
frameProp.addKeyFrame(colDlg->getStartFrame(),filterProp);
725
//Add end value as needed
726
switch(transitionMode)
728
case TRANSITION_STEP:
730
case TRANSITION_INTERP:
731
filterProp.data=colDlg->getEndValue();
732
frameProp.setInterpMode(INTERP_LINEAR_COLOUR);
733
frameProp.addKeyFrame(colDlg->getEndFrame(),filterProp);
742
case PROPERTY_TYPE_STRING:
744
//Create and show the string keyframe input dialog
745
StringKeyFrameDialog *sd = new StringKeyFrameDialog(this,
748
if(sd->ShowModal() != wxID_OK)
754
//set the interpolator to step-by-step interp
755
frameProp.setInterpMode(INTERP_LIST);
757
//Grab the data vector we need to insert the keyframes
758
vector<string> dataVec;
759
if(!sd->getStrings(dataVec))
762
wxMessageDialog *wxD =new wxMessageDialog(this,
763
wxTRANS("File existed, but was unable to read or interpret file contents."),
764
wxTRANS("String load failed"),wxICON_ERROR|wxOK);
771
for(size_t ui=0;ui<dataVec.size();ui++)
773
filterProp.data=dataVec[ui];
774
frameProp.addKeyFrame(sd->getStartFrame()+ui,filterProp);
782
case PROPERTY_TYPE_REAL:
784
RealKeyFrameDialog<float> *r = new RealKeyFrameDialog<float>(this,
785
wxID_ANY,wxTRANS("Keyframe : decimal"));
786
if(!getRealKeyFrame(frameProp,filterProp,r))
788
frameProp.setInterpMode(r->getTransitionMode());
791
case PROPERTY_TYPE_INTEGER:
793
RealKeyFrameDialog<int> *r = new RealKeyFrameDialog<int>(this,
794
wxID_ANY,wxTRANS("Keyframe : integer"));
795
if(!getRealKeyFrame(frameProp,filterProp,r))
797
frameProp.setInterpMode(r->getTransitionMode());
800
case PROPERTY_TYPE_POINT3D:
802
RealKeyFrameDialog<Point3D> *r = new RealKeyFrameDialog<Point3D>(this,
803
wxID_ANY,wxTRANS("Keyframe : 3D Point"));
804
if(!getRealKeyFrame(frameProp,filterProp,r))
806
//Animator needs special Linear ramping code, so select that
807
// if user chooses a linear ramp
808
if(frameProp.getInterpMode()==INTERP_LINEAR_FLOAT)
809
frameProp.setInterpMode(INTERP_LINEAR_POINT3D);
811
frameProp.setInterpMode(r->getTransitionMode());
816
ASSERT(false); // that should cover all data types...
819
//Add property to animator
820
propertyAnimator.addProp(frameProp);
822
//update the user interface controls
827
void ExportAnimationDialog::OnFrameGridCellEditorShow(wxGridEvent &event)
832
void ExportAnimationDialog::OnFilterViewUnsplit(wxSplitterEvent &evt)
837
void ExportAnimationDialog::OnAnimateGridCellEditorShow(wxGridEvent &event)
842
void ExportAnimationDialog::OnButtonKeyFrameRemove(wxCommandEvent &event)
844
if(!animationGrid->GetNumberRows())
846
//Obtain the IDs of the selected rows, or partially selected rows
849
//Rectangular selection
850
// This is an undocumented class AFAIK. :(
851
wxGridCellCoordsArray arrayTL(animationGrid->GetSelectionBlockTopLeft());
852
wxGridCellCoordsArray arrayBR(animationGrid->GetSelectionBlockBottomRight());
854
//Row prefix or header selection
855
const wxArrayInt& selectedRows(animationGrid->GetSelectedRows());
856
const wxGridCellCoordsArray& cells(animationGrid->GetSelectedCells());
858
vector<size_t> rowsToKill;
860
if(arrayTL.Count() && arrayBR.Count())
862
wxGridCellCoords coordTL = arrayTL.Item(0);
863
wxGridCellCoords coordBR = arrayBR.Item(0);
865
size_t rows = coordBR.GetRow() - coordTL.GetRow() +1;
867
rowsToKill.resize(rows);
869
for(size_t r=0; r<rows; r++)
870
rowsToKill[r]= coordTL.GetRow() + r;
873
else if(selectedRows.size()) //Selection from table row prefix
875
rowsToKill.resize(selectedRows.size());
877
for(size_t ui=0;ui<selectedRows.size();ui++)
878
rowsToKill[ui]=selectedRows[ui];
881
rowsToKill.push_back(animationGrid->GetGridCursorRow());
883
propertyAnimator.removeKeyFrames(rowsToKill);
884
//update user interface
889
void ExportAnimationDialog::updateOKButton()
891
bool badStatus=false;
893
badStatus|=workDir.empty();
894
badStatus|=filterMap.empty();
895
badStatus|=(imagePrefix.empty() && wantImageOutput);
896
badStatus|=(propertyAnimator.getNumProps() == 0);
898
//Ensure that there were no inconsistent properties in
900
std::set<size_t> inconsistentProps;
901
badStatus|=!propertyAnimator.checkSelfConsistent(inconsistentProps);
902
okButton->Enable(!badStatus);
905
void ExportAnimationDialog::OnOutputDirText(wxCommandEvent &event)
907
if(programmaticEvent)
910
if(!wxDirExists(textWorkDir->GetValue()))
912
textWorkDir->SetBackgroundColour(*wxCYAN);
917
textWorkDir->SetBackgroundColour(wxNullColour);
918
workDir=stlStr(textWorkDir->GetValue());
921
//update the user interface controls
926
void ExportAnimationDialog::OnButtonWorkDir(wxCommandEvent &event)
928
//Pop up a directory dialog, to choose the base path for the new folder
929
wxDirDialog *wxD = new wxDirDialog(this, wxTRANS("Select or create new folder"),
930
wxFileSelectorDefaultWildcardStr, wxFD_SAVE);
933
res = wxD->ShowModal();
935
while(res != wxID_CANCEL)
937
//If dir exists, exit
938
if(wxDirExists(wxD->GetPath()))
941
res=wxD->ShowModal();
944
//User aborted directory choice.
951
textWorkDir->SetValue(wxD->GetPath());
952
workDir=stlStr(textWorkDir->GetValue());
955
//update the user interface controls
959
void ExportAnimationDialog::OnCheckOutDataChange(wxCommandEvent &event)
961
if(programmaticEvent)
964
wantOnlyChanges=checkOutOnlyChanged->IsChecked();
967
void ExportAnimationDialog::OnCheckImageOutput(wxCommandEvent &event)
969
if(programmaticEvent)
972
wantImageOutput=checkImageOutput->IsChecked();
973
//update UI (eg OK button)
978
void ExportAnimationDialog::OnImageFilePrefix(wxCommandEvent &event)
980
if(programmaticEvent)
983
imagePrefix=stlStr(textImageName->GetValue());
985
//update UI (eg OK button)
990
void ExportAnimationDialog::OnTextImageSize(wxCommandEvent &event)
993
if(programmaticEvent)
997
s=stlStr(textImageSize->GetValue());
1002
if(pos==string::npos)
1007
first = s.substr(0,pos);
1008
last=s.substr(pos+1);
1012
if(stream_cast(w,first))
1016
if(stream_cast(h,last))
1021
textImageSize->SetBackgroundColour(*wxCYAN);
1023
textImageSize->SetBackgroundColour(wxNullColour);
1025
//update UI (eg OK button)
1030
void ExportAnimationDialog::OnBtnResolution(wxCommandEvent &event)
1032
ResolutionDialog *r = new ResolutionDialog(this,wxID_ANY,wxT("Choose Resolution"));
1034
r->setRes(imageWidth,imageHeight);
1036
if(r->ShowModal() != wxID_OK)
1042
imageWidth=r->getWidth();
1043
imageHeight=r->getHeight();
1045
string sWidth,sHeight;
1046
stream_cast(sWidth,imageWidth);
1047
stream_cast(sHeight,imageHeight);
1050
s=sWidth+"x" + sHeight;
1051
textImageSize->SetValue(wxStr(s));
1057
void ExportAnimationDialog::OnCheckPointOutput(wxCommandEvent &event)
1059
wantIonOutput=checkPoints->IsChecked();
1063
void ExportAnimationDialog::OnCheckPlotOutput(wxCommandEvent &event)
1065
wantPlotOutput=checkPlotData->IsChecked();
1069
void ExportAnimationDialog::OnCheckVoxelOutput(wxCommandEvent &event)
1071
wantVoxelOutput=checkVoxelData->IsChecked();
1075
void ExportAnimationDialog::OnCheckRangeOutput(wxCommandEvent &event)
1077
wantRangeOutput=checkRangeData->IsChecked();
1079
comboRangeFormat->Enable(checkRangeData->IsChecked());
1082
void ExportAnimationDialog::OnRangeTypeCombo(wxCommandEvent &event)
1084
rangeExportMode=event.GetSelection();
1088
void ExportAnimationDialog::OnButtonOK(wxCommandEvent &event)
1093
size_t ExportAnimationDialog::getRangeFormat() const
1095
return rangeExportMode;
1099
// wxGlade: add ExportAnimationDialog event handlers
1102
void ExportAnimationDialog::set_properties()
1104
// begin wxGlade: ExportAnimationDialog::set_properties
1105
SetTitle(wxTRANS("Export Animation"));
1106
filterTreeCtrl->SetToolTip(wxTRANS("Select filter"));
1107
propertyGrid->CreateGrid(0, 2);
1108
propertyGrid->SetColLabelValue(0, wxTRANS("Property"));
1109
propertyGrid->SetColLabelValue(1, wxTRANS("Value"));
1110
propertyGrid->SetToolTip(wxTRANS("Select property"));
1111
animationGrid->CreateGrid(0, 5);
1112
animationGrid->SetColLabelValue(0, wxTRANS("Filter"));
1113
animationGrid->SetColLabelValue(1, wxTRANS("Property"));
1114
animationGrid->SetColLabelValue(2, wxTRANS("Mode"));
1115
animationGrid->SetColLabelValue(3, wxTRANS("Start Frame"));
1116
animationGrid->SetColLabelValue(4, wxTRANS("End Frame"));
1117
animationGrid->SetToolTip(wxTRANS("Keyframe table"));
1118
keyFrameRemoveButton->SetToolTip(wxTRANS("Remove the selected keyframe from the table"));
1119
textWorkDir->SetToolTip(wxTRANS("Enter where the animation frames will be exported to"));
1120
buttonWorkDir->SetToolTip(wxTRANS("Browse to directory where the animation frames will be exported to"));
1121
checkImageOutput->SetValue(1);
1122
textImageName->SetToolTip(wxTRANS("Enter a descriptive name for output files"));
1123
textImageSize->SetToolTip(wxTRANS("Enter the target resoltuion (image size)"));
1124
comboRangeFormat->SetSelection(-1);
1125
frameSlider->SetToolTip(wxTRANS("Select frame for property display"));
1126
textFrame->SetToolTip(wxTRANS("Enter frame number to change frame (eg 1/20)"));
1127
checkPoints->SetToolTip(wxTRANS("Save point data (POS files) in output folder?"));
1128
checkPlotData->SetToolTip(wxTRANS("Save plots (as text files) in output folder?"));
1129
checkVoxelData->SetToolTip(wxTRANS("Save voxel data (raw files) in output folder?"));
1130
checkRangeData->SetToolTip(wxTRANS("Save range files in output folder?"));
1131
framePropGrid->CreateGrid(0, 3);
1132
framePropGrid->SetColLabelValue(0, wxTRANS("Filter"));
1133
framePropGrid->SetColLabelValue(1, wxTRANS("Property"));
1134
framePropGrid->SetColLabelValue(2, wxTRANS("Value"));
1135
framePropGrid->SetToolTip(wxTRANS("Animation parameters for current frame"));
1136
cancelButton->SetToolTip(wxTRANS("Abort animation"));
1137
okButton->SetToolTip(wxTRANS("Run Animation"));
1142
void ExportAnimationDialog::do_layout()
1144
// begin wxGlade: ExportAnimationDialog::do_layout
1145
wxBoxSizer* animateSizer = new wxBoxSizer(wxVERTICAL);
1146
wxBoxSizer* globalButtonSizer = new wxBoxSizer(wxHORIZONTAL);
1147
wxBoxSizer* frameViewSizer = new wxBoxSizer(wxHORIZONTAL);
1148
wxBoxSizer* propGridSizer = new wxBoxSizer(wxVERTICAL);
1149
wxBoxSizer* frameSliderSizer = new wxBoxSizer(wxHORIZONTAL);
1150
wxStaticBoxSizer* outputDataSizer = new wxStaticBoxSizer(outputDataSizer_staticbox, wxVERTICAL);
1151
wxBoxSizer* rangeFileDropDownSizer = new wxBoxSizer(wxHORIZONTAL);
1152
wxBoxSizer* outputImageOptionsSizer = new wxBoxSizer(wxVERTICAL);
1153
wxBoxSizer* imageSizeSizer = new wxBoxSizer(wxHORIZONTAL);
1154
wxBoxSizer* filePrefixSizer = new wxBoxSizer(wxHORIZONTAL);
1155
wxBoxSizer* sizer_1 = new wxBoxSizer(wxHORIZONTAL);
1156
wxBoxSizer* outputDirHorizSizer = new wxBoxSizer(wxHORIZONTAL);
1157
wxBoxSizer* filterViewPaneSizerH = new wxBoxSizer(wxHORIZONTAL);
1158
wxStaticBoxSizer* keyFramesSizer = new wxStaticBoxSizer(keyFramesSizer_staticbox, wxVERTICAL);
1159
wxBoxSizer* keyFrameButtonSizer = new wxBoxSizer(wxHORIZONTAL);
1160
wxBoxSizer* animationGridSizer = new wxBoxSizer(wxHORIZONTAL);
1161
wxStaticBoxSizer* filterPropertySizer = new wxStaticBoxSizer(filterPropertySizer_staticbox, wxVERTICAL);
1162
filterPropertySizer->Add(filterTreeCtrl, 1, wxALL|wxEXPAND, 3);
1163
filterPropertySizer->Add(propertyGrid, 1, wxALL|wxEXPAND, 3);
1164
filterLeftPane->SetSizer(filterPropertySizer);
1165
animationGridSizer->Add(animationGrid, 1, wxALL|wxEXPAND, 3);
1166
keyFramesSizer->Add(animationGridSizer, 1, wxEXPAND, 0);
1167
keyFrameButtonSizer->Add(keyFrameRemoveButton, 0, wxALIGN_CENTER_HORIZONTAL, 0);
1168
keyFramesSizer->Add(keyFrameButtonSizer, 0, wxALL|wxEXPAND, 3);
1169
filterRightPane->SetSizer(keyFramesSizer);
1170
splitPaneFilter->SplitVertically(filterLeftPane, filterRightPane);
1171
filterViewPaneSizerH->Add(splitPaneFilter, 1, wxEXPAND, 0);
1172
filterViewPane->SetSizer(filterViewPaneSizerH);
1173
outputDirHorizSizer->Add(labelWorkDir, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 3);
1174
outputDirHorizSizer->Add(textWorkDir, 1, wxEXPAND, 0);
1175
outputDirHorizSizer->Add(buttonWorkDir, 0, wxLEFT|wxRIGHT, 2);
1176
outputDataSizer->Add(outputDirHorizSizer, 0, wxALL|wxEXPAND, 4);
1177
sizer_1->Add(20, 20, 0, 0, 0);
1178
sizer_1->Add(checkOutOnlyChanged, 0, 0, 0);
1179
outputDataSizer->Add(sizer_1, 0, wxBOTTOM|wxEXPAND, 5);
1180
outputDataSizer->Add(outputDataSepLine, 0, wxTOP|wxBOTTOM|wxEXPAND, 3);
1181
outputDataSizer->Add(labelDataType, 0, wxTOP|wxBOTTOM, 4);
1182
outputDataSizer->Add(checkImageOutput, 0, wxLEFT|wxTOP, 3);
1183
filePrefixSizer->Add(lblImageName, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 3);
1184
filePrefixSizer->Add(textImageName, 1, wxALL|wxEXPAND, 4);
1185
outputImageOptionsSizer->Add(filePrefixSizer, 0, wxALL|wxEXPAND, 3);
1186
imageSizeSizer->Add(labelImageSize, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 3);
1187
imageSizeSizer->Add(textImageSize, 1, wxALL|wxEXPAND, 4);
1188
imageSizeSizer->Add(buttonImageSize, 0, wxALL, 4);
1189
outputImageOptionsSizer->Add(imageSizeSizer, 0, wxALL|wxEXPAND, 3);
1190
outputDataSizer->Add(outputImageOptionsSizer, 0, wxEXPAND, 0);
1191
outputDataSizer->Add(checkPoints, 1, wxLEFT|wxBOTTOM, 3);
1192
outputDataSizer->Add(checkPlotData, 1, wxLEFT|wxTOP, 3);
1193
outputDataSizer->Add(checkVoxelData, 1, wxLEFT|wxTOP|wxBOTTOM, 3);
1194
outputDataSizer->Add(checkRangeData, 1, wxALL, 3);
1195
rangeFileDropDownSizer->Add(labelRangeFormat, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 3);
1196
rangeFileDropDownSizer->Add(comboRangeFormat, 1, wxLEFT|wxRIGHT|wxEXPAND, 3);
1197
outputDataSizer->Add(rangeFileDropDownSizer, 0, wxLEFT|wxBOTTOM|wxEXPAND, 5);
1198
outputDataSizer->Add(20, 20, 2, 0, 0);
1199
frameViewSizer->Add(outputDataSizer, 1, wxEXPAND, 0);
1200
frameViewSizer->Add(static_line_1, 0, wxLEFT|wxRIGHT|wxEXPAND, 5);
1201
frameSliderSizer->Add(labelFrame, 0, wxALIGN_CENTER_VERTICAL, 0);
1202
frameSliderSizer->Add(frameSlider, 1, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 5);
1203
frameSliderSizer->Add(textFrame, 0, wxALIGN_CENTER_VERTICAL, 0);
1204
propGridSizer->Add(frameSliderSizer, 0, wxALL|wxEXPAND, 3);
1205
propGridSizer->Add(framePropGrid, 1, wxEXPAND, 0);
1206
frameViewSizer->Add(propGridSizer, 2, wxALL|wxEXPAND, 3);
1207
frameViewPane->SetSizer(frameViewSizer);
1208
viewNotebook->AddPage(filterViewPane, wxTRANS("Filter view"));
1209
viewNotebook->AddPage(frameViewPane, wxTRANS("Frame view"));
1210
animateSizer->Add(viewNotebook, 1, wxEXPAND, 0);
1211
globalButtonSizer->Add(20, 1, 1, wxEXPAND, 0);
1212
globalButtonSizer->Add(cancelButton, 0, wxALL|wxALIGN_BOTTOM, 3);
1213
globalButtonSizer->Add(okButton, 0, wxALL|wxALIGN_BOTTOM, 3);
1214
animateSizer->Add(globalButtonSizer, 0, wxEXPAND, 0);
1215
SetSizer(animateSizer);
1216
animateSizer->Fit(this);