FreqWindow::FreqWindow(wxWindow * parent, wxWindowID id,
                           const wxString & title,
                           const wxPoint & pos)
:  wxDialogWrapper(parent, id, title, pos, wxDefaultSize,
            wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX),
   mAnalyst(std::make_unique<SpectrumAnalyst>())
{
   SetName(GetTitle());

   mMouseX = 0;
   mMouseY = 0;
   mRate = 0;
   mDataLen = 0;

   p = GetActiveProject();
   if (!p)
      return;

   wxArrayString algChoices;
   algChoices.Add(_("Spectrum"));
   algChoices.Add(_("Standard Autocorrelation"));
   algChoices.Add(_("Cuberoot Autocorrelation"));
   algChoices.Add(_("Enhanced Autocorrelation"));
     /* i18n-hint: This is a technical term, derived from the word
      * "spectrum".  Do not translate it unless you are sure you
      * know the correct technical word in your language. */
   algChoices.Add(_("Cepstrum"));

   wxArrayString sizeChoices;
   sizeChoices.Add(wxT("128"));
   sizeChoices.Add(wxT("256"));
   sizeChoices.Add(wxT("512"));
   sizeChoices.Add(wxT("1024"));
   sizeChoices.Add(wxT("2048"));
   sizeChoices.Add(wxT("4096"));
   sizeChoices.Add(wxT("8192"));
   sizeChoices.Add(wxT("16384"));
   sizeChoices.Add(wxT("32768"));
   sizeChoices.Add(wxT("65536"));

   wxArrayString funcChoices;
   for (int i = 0, cnt = NumWindowFuncs(); i < cnt; i++)
   {
      /* i18n-hint: This refers to a "window function",
       * such as Hann or Rectangular, used in the
       * Frequency analyze dialog box. */
      funcChoices.Add(wxString::Format("%s window",  WindowFuncName(i) ) );
   }

   wxArrayString axisChoices;
   axisChoices.Add(_("Linear frequency"));
   axisChoices.Add(_("Log frequency"));

   mFreqFont = wxFont(fontSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
   mArrowCursor = std::make_unique<wxCursor>(wxCURSOR_ARROW);
   mCrossCursor = std::make_unique<wxCursor>(wxCURSOR_CROSS);

   gPrefs->Read(wxT("/FreqWindow/DrawGrid"), &mDrawGrid, true);

   long size;
   gPrefs->Read(wxT("/FreqWindow/SizeChoice"), &mSize, 3);
   sizeChoices[mSize].ToLong(&size);
   mWindowSize = size;

   int alg;
   gPrefs->Read(wxT("/FreqWindow/AlgChoice"), &alg, 0);
   mAlg = static_cast<SpectrumAnalyst::Algorithm>(alg);

   gPrefs->Read(wxT("/FreqWindow/FuncChoice"), &mFunc, 3);
   gPrefs->Read(wxT("/FreqWindow/AxisChoice"), &mAxis, 1);
   gPrefs->Read(ENV_DB_KEY, &dBRange, ENV_DB_RANGE);
   if(dBRange < 90.)
      dBRange = 90.;

   ShuttleGui S(this, eIsCreating);

   S.SetBorder(0);

   S.AddSpace(5);

   S.SetSizerProportion(1);
   S.StartMultiColumn(3, wxEXPAND);
   {
      S.SetStretchyCol(1);
      S.SetStretchyRow(0);

      // -------------------------------------------------------------------
      // ROW 1: Freq response panel and sliders for vertical scale
      // -------------------------------------------------------------------

      S.StartVerticalLay(2);
      {
         vRuler = safenew RulerPanel(this, wxID_ANY);
         vRuler->ruler.SetBounds(0, 0, 100, 100); // Ruler can't handle small sizes
         vRuler->ruler.SetOrientation(wxVERTICAL);
         vRuler->ruler.SetRange(0.0, -dBRange);
         vRuler->ruler.SetFormat(Ruler::LinearDBFormat);
         vRuler->ruler.SetUnits(_("dB"));
         vRuler->ruler.SetLabelEdges(true);
         int w;
         vRuler->ruler.GetMaxSize(&w, NULL);
         vRuler->SetMinSize(wxSize(w, 150));  // height needed for wxGTK
         vRuler->SetTickColour( theTheme.Colour( clrGraphLabels ));

         S.AddSpace(wxDefaultCoord, 1);
         S.Prop(1);
         S.AddWindow(vRuler, wxALIGN_RIGHT | wxALIGN_TOP);
         S.AddSpace(wxDefaultCoord, 1);
      }
      S.EndVerticalLay();

      mFreqPlot = safenew FreqPlot(this);
      mFreqPlot->SetMinSize(wxSize(wxDefaultCoord, FREQ_WINDOW_HEIGHT));
      S.Prop(1);
      S.AddWindow(mFreqPlot, wxEXPAND);

      S.StartHorizontalLay(wxEXPAND, 0);
      {
         S.StartVerticalLay();
         {
            mPanScroller = safenew wxScrollBar(this, FreqPanScrollerID,
               wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL);
            mPanScroller->SetName(_("Scroll"));
            S.Prop(1);
            S.AddWindow(mPanScroller, wxALIGN_LEFT | wxTOP);
         }
         S.EndVerticalLay();

         S.StartVerticalLay();
         {
            wxStaticBitmap *zi = safenew wxStaticBitmap(this, wxID_ANY, wxBitmap(ZoomIn));
            S.AddWindow((wxWindow *) zi, wxALIGN_CENTER);

            S.AddSpace(5);

            mZoomSlider = safenew wxSlider(this, FreqZoomSliderID, 100, 1, 100,
               wxDefaultPosition, wxDefaultSize, wxSL_VERTICAL);
            S.Prop(1);
            S.AddWindow(mZoomSlider, wxALIGN_CENTER_HORIZONTAL);
            mZoomSlider->SetName(_("Zoom"));

            S.AddSpace(5);

            wxStaticBitmap *zo = safenew wxStaticBitmap(this, wxID_ANY, wxBitmap(ZoomOut));
            S.AddWindow((wxWindow *) zo, wxALIGN_CENTER);
         }
         S.EndVerticalLay();

         S.AddSpace(5, wxDefaultCoord);
      }
      S.EndHorizontalLay();

      // -------------------------------------------------------------------
      // ROW 2: Frequency ruler
      // -------------------------------------------------------------------

      S.AddSpace(1);

      S.StartHorizontalLay(wxEXPAND, 0);
      {
         hRuler  = safenew RulerPanel(this, wxID_ANY);
         hRuler->ruler.SetBounds(0, 0, 100, 100); // Ruler can't handle small sizes
         hRuler->ruler.SetOrientation(wxHORIZONTAL);
         hRuler->ruler.SetLog(true);
         hRuler->ruler.SetRange(10, 20000);
         hRuler->ruler.SetFormat(Ruler::RealFormat);
         hRuler->ruler.SetUnits(_("Hz"));
         hRuler->ruler.SetFlip(true);
         hRuler->ruler.SetLabelEdges(true);
         int h;
         hRuler->ruler.GetMaxSize(NULL, &h);
         hRuler->SetMinSize(wxSize(wxDefaultCoord, h));
         hRuler->SetTickColour( theTheme.Colour( clrGraphLabels ));

         S.AddSpace(1, wxDefaultCoord);
         S.Prop(1);
         S.AddWindow(hRuler, wxALIGN_LEFT | wxALIGN_TOP);
         S.AddSpace(1, wxDefaultCoord);
      }
      S.EndHorizontalLay();

      S.AddSpace(1);

      // -------------------------------------------------------------------
      // ROW 3: Spacer
      // -------------------------------------------------------------------
      S.AddSpace(5);
      S.AddSpace(5);
      S.AddSpace(5);

      // -------------------------------------------------------------------
      // ROW 4: Info
      // -------------------------------------------------------------------

      S.AddSpace(1);

      S.StartHorizontalLay(wxEXPAND);
      {
         S.SetSizerProportion(1);
         S.StartMultiColumn(6);
         S.SetStretchyCol(1);
         S.SetStretchyCol(3);
         {
            S.AddPrompt(_("Cursor:"));

            S.SetStyle(wxTE_READONLY);
            mCursorText = S.AddTextBox( {}, wxT(""), 10);

            S.AddPrompt(_("Peak:"));

            S.SetStyle(wxTE_READONLY);
            mPeakText = S.AddTextBox( {}, wxT(""), 10);
            S.AddSpace(5);

            mGridOnOff = S.Id(GridOnOffID).AddCheckBox(_("&Grids"), wxT("false"));
            mGridOnOff->SetValue(mDrawGrid);
         }
         S.EndMultiColumn();
      }
      S.EndHorizontalLay();

      S.AddSpace(1);
   }
   S.EndMultiColumn();

   // -------------------------------------------------------------------
   // ROW 5: Spacer
   // -------------------------------------------------------------------
   
   S.AddSpace(5);

   S.SetBorder(2);
   S.SetSizerProportion(0);
   S.StartMultiColumn(9, wxALIGN_CENTER);
   {
      // ----------------------------------------------------------------
      // ROW 6: Algorithm, Size, Export, Replot
      // ----------------------------------------------------------------

      S.AddSpace(5);

      mAlgChoice = S.Id(FreqAlgChoiceID).AddChoice(_("&Algorithm:"), wxT(""), &algChoices);
      mAlgChoice->SetSelection(mAlg);
      S.SetSizeHints(wxDefaultCoord, wxDefaultCoord);

      S.AddSpace(5);

      mSizeChoice = S.Id(FreqSizeChoiceID).AddChoice(_("&Size:"), wxT(""), &sizeChoices);
      mSizeChoice->SetSelection(mSize);
      S.SetSizeHints(wxDefaultCoord, wxDefaultCoord);

      S.AddSpace(5);

      mExportButton = S.Id(FreqExportButtonID).AddButton(_("&Export..."));

      S.AddSpace(5);


      // ----------------------------------------------------------------
      // ROW 7: Function, Axix, Grids, Close
      // ----------------------------------------------------------------

      S.AddSpace(5);

      mFuncChoice = S.Id(FreqFuncChoiceID).AddChoice(_("&Function:"), wxT(""), &funcChoices);
      mFuncChoice->SetSelection(mFunc);
      S.SetSizeHints(wxDefaultCoord, wxDefaultCoord);
      mFuncChoice->MoveAfterInTabOrder(mSizeChoice);

      S.AddSpace(5);

      mAxisChoice = S.Id(FreqAxisChoiceID).AddChoice(_("&Axis:"), wxT(""), &axisChoices);
      mAxisChoice->SetSelection(mAxis);
      S.SetSizeHints(wxDefaultCoord, wxDefaultCoord);
      mAxisChoice->MoveAfterInTabOrder(mFuncChoice);

      S.AddSpace(5);

      mReplotButton = S.Id(ReplotButtonID).AddButton(_("&Replot..."));

      S.AddSpace(5);

      //mCloseButton = S.Id(wxID_CANCEL).AddButton(_("&Close"));

      //S.AddSpace(5);
   }
   S.EndMultiColumn();
   S.AddStandardButtons( eHelpButton | eCloseButton );

   // -------------------------------------------------------------------
   // ROW 8: Spacer
   // -------------------------------------------------------------------

   S.AddSpace(5);

   mProgress = safenew FreqGauge(this); //, wxID_ANY, wxST_SIZEGRIP);
   S.AddWindow(mProgress, wxEXPAND);

   // Log-frequency axis works for spectrum plots only.
   if (mAlg != SpectrumAnalyst::Spectrum)
   {
      mAxis = 0;
      mAxisChoice->Disable();
   }
   mLogAxis = mAxis != 0;

   mCloseButton = reinterpret_cast<wxButton*>(FindWindowById( wxID_CANCEL ));
   mCloseButton->SetDefault();
   mCloseButton->SetFocus();

   Layout();
   Fit();
   // Bug 1607:
   Center();

   SetMinSize(GetSize());
   mAlgChoice->SetFocus();

#if defined(__WXGTK__)
   // This should be rechecked with wx3.
   //
   // The scrollbar (focus some reason) doesn't allow tabbing past it
   // because it can't receive focus.  So, convince it otherwise.
   //
   // Unfortunately, this still doesn't let you adjust the scrollbar
   // from the keyboard.  Near as I can tell, wxWGTK is capturing the
   // keyboard input, so the GTK widget doesn't see it, preventing
   // the normal scroll events from being generated.
   //
   // I guess the only way round it would be to handle key actions
   // ourselves, but we'll leave that for a future date.
//   gtk_widget_set_can_focus(mPanScroller->m_widget, true);
#endif
}
Beispiel #2
0
void EffectScienFilter::PopulateOrExchange(ShuttleGui & S)
{
   wxWindow *const parent = S.GetParent();

   S.AddSpace(5);
   S.SetSizerProportion(1);
   S.StartMultiColumn(3, wxEXPAND);
   {
      S.SetStretchyCol(1);
      S.SetStretchyRow(0);

      // -------------------------------------------------------------------
      // ROW 1: Freq response panel and sliders for vertical scale
      // -------------------------------------------------------------------

      S.StartVerticalLay();
      {
         mdBRuler = safenew RulerPanel(
            parent, wxID_ANY, wxVERTICAL,
            wxSize{ 100, 100 }, // Ruler can't handle small sizes
            RulerPanel::Range{ 30.0, -120.0 },
            Ruler::LinearDBFormat,
            _("dB"),
            RulerPanel::Options{}
               .LabelEdges(true)
         );

         S.SetBorder(1);
         S.AddSpace(1, 1);
         S.Prop(1);
         S.AddWindow(mdBRuler, wxALIGN_RIGHT | wxTOP);
         S.AddSpace(1, 1);
      }
      S.EndVerticalLay();

      mPanel = safenew EffectScienFilterPanel(
         parent, wxID_ANY,
         this, mLoFreq, mNyquist
      );

      S.SetBorder(5);
      S.Prop(1);
      S.AddWindow(mPanel, wxEXPAND | wxRIGHT);
      S.SetSizeHints(-1, -1);

      S.StartVerticalLay();
      {
         S.AddVariableText(_("+ dB"), false, wxCENTER);
         S.SetStyle(wxSL_VERTICAL | wxSL_INVERSE);
         mdBMaxSlider = S.Id(ID_dBMax).AddSlider( {}, 10, 20, 0);
#if wxUSE_ACCESSIBILITY
         mdBMaxSlider->SetName(_("Max dB"));
         mdBMaxSlider->SetAccessible(safenew SliderAx(mdBMaxSlider, _("%d dB")));
#endif

         S.SetStyle(wxSL_VERTICAL | wxSL_INVERSE);
         mdBMinSlider = S.Id(ID_dBMin).AddSlider( {}, -10, -10, -120);
         S.AddVariableText(_("- dB"), false, wxCENTER);
#if wxUSE_ACCESSIBILITY
         mdBMinSlider->SetName(_("Min dB"));
         mdBMinSlider->SetAccessible(safenew SliderAx(mdBMinSlider, _("%d dB")));
#endif
      }
      S.EndVerticalLay();

      // -------------------------------------------------------------------
      // ROW 2: Frequency ruler
      // -------------------------------------------------------------------

      S.AddSpace(1, 1);

      mfreqRuler  = safenew RulerPanel(
         parent, wxID_ANY, wxHORIZONTAL,
         wxSize{ 100, 100 }, // Ruler can't handle small sizes
         RulerPanel::Range{ mLoFreq, mNyquist },
         Ruler::IntFormat,
         wxT(""),
         RulerPanel::Options{}
            .Log(true)
            .Flip(true)
            .LabelEdges(true)
      );

      S.Prop(1);
      S.AddWindow(mfreqRuler, wxEXPAND | wxALIGN_LEFT | wxRIGHT);

      S.AddSpace(1, 1);

      // -------------------------------------------------------------------
      // ROW 3 and 4: Type, Order, Ripple, Subtype, Cutoff
      // -------------------------------------------------------------------

      S.AddSpace(1, 1);
      S.SetSizerProportion(0);
      S.StartMultiColumn(8, wxALIGN_CENTER);
      {
         wxASSERT(nTypes == WXSIZEOF(kTypeStrings));

         auto typeChoices = LocalizedStrings(kTypeStrings, nTypes);
         mFilterTypeCtl = S.Id(ID_Type).AddChoice(_("&Filter Type:"), wxT(""), &typeChoices);
         mFilterTypeCtl->SetValidator(wxGenericValidator(&mFilterType));
         S.SetSizeHints(-1, -1);

         wxArrayString orders;
         for (int i = 1; i <= 10; i++)
         {
            orders.Add(wxString::Format(wxT("%d"), i));
         }
         /*i18n-hint: 'Order' means the complexity of the filter, and is a number between 1 and 10.*/
         mFilterOrderCtl = S.Id(ID_Order).AddChoice(_("O&rder:"), wxT(""), &orders);
         mFilterOrderCtl->SetValidator(wxGenericValidator(&mOrderIndex));
         S.SetSizeHints(-1, -1);
         S.AddSpace(1, 1);

         FloatingPointValidator<float> vldRipple(1, &mRipple);
         vldRipple.SetRange(MIN_Passband, MAX_Passband);
         
         mRippleCtlP = S.AddVariableText(_("&Passband Ripple:"), false, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
         mRippleCtl = S.Id(ID_Ripple).AddTextBox( {}, wxT(""), 10);
         mRippleCtl->SetName(_("Passband Ripple (dB)"));
         mRippleCtl->SetValidator(vldRipple);
         mRippleCtlU = S.AddVariableText(_("dB"), false, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);

         wxASSERT(nSubTypes == WXSIZEOF(kSubTypeStrings));

         auto subTypeChoices = LocalizedStrings(kSubTypeStrings, nSubTypes);
         mFilterSubTypeCtl = S.Id(ID_SubType).AddChoice(_("&Subtype:"), wxT(""), &subTypeChoices);
         mFilterSubTypeCtl->SetValidator(wxGenericValidator(&mFilterSubtype));
         S.SetSizeHints(-1, -1);
      
         FloatingPointValidator<float> vldCutoff(1, &mCutoff);
         vldCutoff.SetRange(MIN_Cutoff, mNyquist - 1);
         
         mCutoffCtl = S.Id(ID_Cutoff).AddTextBox(_("C&utoff:"), wxT(""), 10);
         mCutoffCtl->SetName(_("Cutoff (Hz)"));
         mCutoffCtl->SetValidator(vldCutoff);
         S.AddUnits(_("Hz"));

         FloatingPointValidator<float> vldStopbandRipple(1, &mStopbandRipple);
         vldStopbandRipple.SetRange(MIN_Stopband, MAX_Stopband);
         
         mStopbandRippleCtlP = S.AddVariableText(_("Minimum S&topband Attenuation:"), false, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
         mStopbandRippleCtl = S.Id(ID_StopbandRipple).AddTextBox( {}, wxT(""), 10);
         mStopbandRippleCtl->SetName(_("Minimum S&topband Attenuation (dB)"));
         mStopbandRippleCtl->SetValidator(vldStopbandRipple);
         mStopbandRippleCtlU = S.AddVariableText(_("dB"), false, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
      }
      S.EndMultiColumn();
      S.AddSpace(1, 1);
   }
   S.EndMultiColumn();

   mFilterTypeCtl->SetFocus();

   return;
}