diff --git a/src/wxNcVisFrame.cpp b/src/wxNcVisFrame.cpp index 7f3aaff..3ffb851 100644 --- a/src/wxNcVisFrame.cpp +++ b/src/wxNcVisFrame.cpp @@ -38,6 +38,7 @@ enum { ID_SAMPLER = 12, ID_EXPORT = 13, ID_COLORMAPINVERT = 14, + ID_RANGECENTERMINMAX = 15, ID_VARSELECTOR = 100, ID_DIMEDIT = 200, ID_DIMDOWN = 300, @@ -64,6 +65,7 @@ wxBEGIN_EVENT_TABLE(wxNcVisFrame, wxFrame) EVT_TEXT_ENTER(ID_RANGEMIN, wxNcVisFrame::OnRangeChanged) EVT_TEXT_ENTER(ID_RANGEMAX, wxNcVisFrame::OnRangeChanged) EVT_BUTTON(ID_RANGERESETMINMAX, wxNcVisFrame::OnRangeResetMinMax) + EVT_BUTTON(ID_RANGECENTERMINMAX, wxNcVisFrame::OnRangeCenterMinMax) EVT_BUTTON(ID_COLORMAPINVERT, wxNcVisFrame::OnColorMapInvertClicked) EVT_COMBOBOX(ID_COLORMAP, wxNcVisFrame::OnColorMapCombo) EVT_COMBOBOX(ID_GRIDLINES, wxNcVisFrame::OnGridLinesCombo) @@ -1441,6 +1443,70 @@ void wxNcVisFrame::SetDataRangeByMinMax( //////////////////////////////////////////////////////////////////////////////// +void wxNcVisFrame::SetDataRangeCenteredOnZero(bool fRedraw) { + if (m_data.size() == 0) { + return; + } + + float dDataMin = 0.0f; + float dDataMax = 0.0f; + + int i; + + if ((!m_fDataHasMissingValue) || (std::isnan(m_dMissingValueFloat))) { + for (i = 0; i < (int)m_data.size(); i++) { + if (!std::isnan(m_data[i])) { + break; + } + } + if (i == (int)m_data.size()) { + return; // no valid data + } + + dDataMin = m_data[i]; + dDataMax = m_data[i]; + + for (i++; i < (int)m_data.size(); i++) { + if (std::isnan(m_data[i])) { + continue; + } + if (m_data[i] < dDataMin) dDataMin = m_data[i]; + if (m_data[i] > dDataMax) dDataMax = m_data[i]; + } + + } else { + for (i = 0; i < (int)m_data.size(); i++) { + if ((m_data[i] != m_dMissingValueFloat) && (!std::isnan(m_data[i]))) { + break; + } + } + if (i == (int)m_data.size()) { + return; // no valid data + } + + dDataMin = m_data[i]; + dDataMax = m_data[i]; + + for (i++; i < (int)m_data.size(); i++) { + if ((m_data[i] == m_dMissingValueFloat) || (std::isnan(m_data[i]))) { + continue; + } + if (m_data[i] < dDataMin) dDataMin = m_data[i]; + if (m_data[i] > dDataMax) dDataMax = m_data[i]; + } + } + + // Center on 0: make range symmetric around zero + const float M = std::max(std::fabs(dDataMin), std::fabs(dDataMax)); + if (!(M > 0.0f) || std::isnan(M)) { + return; + } + + m_imagepanel->SetDataRange(-M, M, fRedraw); +} + +//////////////////////////////////////////////////////////////////////////////// + void wxNcVisFrame::SetDisplayedDimensionValue( long lDim, long lValue @@ -1887,7 +1953,7 @@ void wxNcVisFrame::GenerateDimensionControls() { varboundsminmax->Add(m_vecwxRange[0], 1, wxEXPAND | wxALL, 0); varboundsminmax->Add(m_vecwxRange[1], 1, wxEXPAND | wxALL, 0); - m_vardimsizer->Add(new wxStaticText(this, -1, _T("")), 0, wxEXPAND | wxALL, 0); + m_vardimsizer->Add(new wxButton(this, ID_RANGECENTERMINMAX, _T("Center")), 0, wxEXPAND | wxALL, 0); m_vardimsizer->Add(new wxStaticText(this, -1, _T("range"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE_HORIZONTAL | wxALIGN_CENTER_VERTICAL), 1, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, 4); m_vardimsizer->Add(varboundsminmax, 0, wxEXPAND | wxALL, 2); m_vardimsizer->Add(new wxButton(this, ID_RANGERESETMINMAX, _T("Reset"), wxDefaultPosition, wxSize(3*nCtrlHeight,nCtrlHeight)), 0, wxEXPAND | wxALL, 0); @@ -1895,6 +1961,7 @@ void wxNcVisFrame::GenerateDimensionControls() { m_vecwxRange[0]->Enable(true); m_vecwxRange[1]->Enable(true); + SetDataRangeCenteredOnZero(false); SetDataRangeByMinMax(false); // Resize window if needed @@ -2261,6 +2328,16 @@ void wxNcVisFrame::OnRangeResetMinMax( //////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +void wxNcVisFrame::OnRangeCenterMinMax( + wxCommandEvent & event +) { + SetDataRangeCenteredOnZero(true); +} + +//////////////////////////////////////////////////////////////////////////////// + //TODO: Verify that timer is actually able to execute with the desired frequency void wxNcVisFrame::OnDimTimer(wxTimerEvent & event) { if (m_fVerbose) { diff --git a/src/wxNcVisFrame.h b/src/wxNcVisFrame.h index ac85ded..bb792d6 100644 --- a/src/wxNcVisFrame.h +++ b/src/wxNcVisFrame.h @@ -273,6 +273,13 @@ class wxNcVisFrame : public wxFrame { bool fRedraw = false ); + /// + /// Set the data range centered on zero. + /// + void SetDataRangeCenteredOnZero( + bool fRedraw = false + ); + /// /// Set the dimension value displayed. /// @@ -373,6 +380,11 @@ class wxNcVisFrame : public wxFrame { /// void OnRangeResetMinMax(wxCommandEvent & event); + /// + /// Callback triggered when the range center min/max button is pressed. + /// + void OnRangeCenterMinMax(wxCommandEvent & event); + /// /// Callback triggered when the dimension timer is triggered. ///