mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-31 07:59:27 +02:00
Add generic plot widget.
This widget will be used in the new Compressor2 effect but it is designed for use in other effects as well. Signed-off-by: Max Maisel <max.maisel@posteo.de>
This commit is contained in:
parent
2555b68a04
commit
bcdc47bc34
@ -949,6 +949,8 @@ list( APPEND SOURCES PRIVATE
|
||||
widgets/Overlay.h
|
||||
widgets/OverlayPanel.cpp
|
||||
widgets/OverlayPanel.h
|
||||
widgets/Plot.cpp
|
||||
widgets/Plot.h
|
||||
widgets/PopupMenuTable.cpp
|
||||
widgets/PopupMenuTable.h
|
||||
widgets/ProgressDialog.cpp
|
||||
|
@ -121,6 +121,7 @@ for registering for changes.
|
||||
#include "widgets/wxTextCtrlWrapper.h"
|
||||
#include "AllThemeResources.h"
|
||||
|
||||
#include "widgets/Plot.h"
|
||||
#include "widgets/SliderTextCtrl.h"
|
||||
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
@ -777,6 +778,33 @@ void ShuttleGuiBase::AddConstTextBox(
|
||||
UpdateSizers();
|
||||
}
|
||||
|
||||
Plot* ShuttleGuiBase::AddPlot( const TranslatableString &Prompt,
|
||||
double x_min, double x_max, double y_min, double y_max,
|
||||
const TranslatableString& x_label, const TranslatableString& y_label,
|
||||
int x_format, int y_format, int count)
|
||||
{
|
||||
HandleOptionality( Prompt );
|
||||
AddPrompt( Prompt );
|
||||
UseUpId();
|
||||
if( mShuttleMode != eIsCreating )
|
||||
return wxDynamicCast(wxWindow::FindWindowById(miId, mpDlg), Plot);
|
||||
Plot* pPlot;
|
||||
mpWind = pPlot = safenew Plot(GetParent(), miId,
|
||||
x_min, x_max, y_min, y_max, x_label, y_label,
|
||||
x_format, y_format, count,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
GetStyle( SliderTextCtrl::HORIZONTAL )
|
||||
);
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
// so that name can be set on a standard control
|
||||
mpWind->SetAccessible(safenew WindowAccessible(mpWind));
|
||||
#endif
|
||||
mpWind->SetName(wxStripMenuCodes(Prompt.Translation()));
|
||||
miProp=1;
|
||||
UpdateSizers();
|
||||
return pPlot;
|
||||
}
|
||||
|
||||
wxListBox * ShuttleGuiBase::AddListBox(const wxArrayStringEx &choices)
|
||||
{
|
||||
UseUpId();
|
||||
|
@ -28,6 +28,7 @@
|
||||
class ChoiceSetting;
|
||||
|
||||
class wxArrayStringEx;
|
||||
class Plot;
|
||||
class SliderTextCtrl;
|
||||
|
||||
|
||||
@ -348,6 +349,11 @@ public:
|
||||
void AddConstTextBox(
|
||||
const TranslatableString &Caption, const TranslatableString & Value );
|
||||
|
||||
Plot* AddPlot( const TranslatableString &Prompt,
|
||||
double x_min, double x_max, double y_min, double y_max,
|
||||
const TranslatableString& x_label, const TranslatableString& y_label,
|
||||
int x_format = 1, int y_format = 1, int count = 1 );
|
||||
|
||||
//-- Start and end functions. These are used for sizer, or other window containers
|
||||
// and create the appropriate widget.
|
||||
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1);
|
||||
|
136
src/widgets/Plot.cpp
Normal file
136
src/widgets/Plot.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
Plot.cpp
|
||||
|
||||
Max Maisel
|
||||
|
||||
*******************************************************************//**
|
||||
|
||||
\class Plot
|
||||
\brief A customizable generic plot widget.
|
||||
|
||||
*//*******************************************************************/
|
||||
|
||||
|
||||
#include "../Audacity.h"
|
||||
#include "audacity/Types.h"
|
||||
#include "Plot.h"
|
||||
#include "Ruler.h"
|
||||
#include "../AColor.h"
|
||||
#include "../Theme.h"
|
||||
#include "../AllThemeResources.h"
|
||||
|
||||
#include <wx/brush.h>
|
||||
#include <wx/dcclient.h>
|
||||
#include <wx/dcmemory.h>
|
||||
|
||||
Plot::Plot(wxWindow *parent, wxWindowID winid,
|
||||
float x_min, float x_max, float y_min, float y_max,
|
||||
const TranslatableString& xlabel, const TranslatableString& ylabel,
|
||||
int xformat, int yformat, int count,
|
||||
const wxPoint& pos, const wxSize& size, long style)
|
||||
:
|
||||
wxPanelWrapper(parent, winid, pos, size, style),
|
||||
m_xmin(x_min), m_xmax(x_max), m_ymin(y_min), m_ymax(y_max),
|
||||
m_plots(count)
|
||||
{
|
||||
m_xruler = std::unique_ptr<Ruler>(safenew Ruler);
|
||||
m_xruler->SetOrientation(wxHORIZONTAL);
|
||||
m_xruler->SetFormat(static_cast<Ruler::RulerFormat>(xformat));
|
||||
m_xruler->SetUnits(xlabel);
|
||||
m_xruler->SetFlip(true);
|
||||
|
||||
m_yruler = std::unique_ptr<Ruler>(safenew Ruler);
|
||||
m_yruler->SetOrientation(wxVERTICAL);
|
||||
m_yruler->SetFormat(static_cast<Ruler::RulerFormat>(yformat));
|
||||
m_yruler->SetUnits(ylabel);
|
||||
}
|
||||
|
||||
void Plot::OnPaint(wxPaintEvent & evt)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
|
||||
int width, height;
|
||||
GetSize(&width, &height);
|
||||
|
||||
#if defined(__WXMSW__)
|
||||
dc.Clear();
|
||||
#endif
|
||||
|
||||
// Ruler
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
|
||||
m_xruler->SetBounds(0, 0, width, height);
|
||||
m_xruler->SetRange(m_xmin, m_xmax);
|
||||
m_xruler->GetMaxSize(NULL, &h);
|
||||
|
||||
m_yruler->SetBounds(0, 0, width, height);
|
||||
m_yruler->SetRange(m_ymax, m_ymin);
|
||||
m_yruler->GetMaxSize(&w, NULL);
|
||||
|
||||
m_xruler->SetBounds(w, height - h, width, height);
|
||||
m_yruler->SetBounds(0, 0, w, height - h);
|
||||
|
||||
m_xruler->SetTickColour( theTheme.Colour( clrGraphLabels ));
|
||||
m_yruler->SetTickColour( theTheme.Colour( clrGraphLabels ));
|
||||
|
||||
wxRect border;
|
||||
border.x = w;
|
||||
border.y = 0;
|
||||
border.width = width - w;
|
||||
border.height = height - h + 1;
|
||||
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.DrawRectangle(border);
|
||||
|
||||
m_xruler->DrawGrid(dc, border.height, true, true, border.x, border.y);
|
||||
m_yruler->DrawGrid(dc, border.width, true, true, border.x, border.y);
|
||||
|
||||
for(const auto& plot : m_plots)
|
||||
{
|
||||
wxASSERT(plot.xdata.size() == plot.ydata.size());
|
||||
if(plot.xdata.size() == 0)
|
||||
continue;
|
||||
dc.SetPen(*plot.pen);
|
||||
|
||||
size_t xsize = plot.xdata.size();
|
||||
for(size_t i = 1; i < xsize; ++i)
|
||||
{
|
||||
AColor::Line(dc,
|
||||
XToScreen(plot.xdata[i-1], border),
|
||||
YToScreen(plot.ydata[i-1], border),
|
||||
XToScreen(plot.xdata[i], border),
|
||||
YToScreen(plot.ydata[i], border));
|
||||
}
|
||||
}
|
||||
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.SetPen(*wxBLACK_PEN);
|
||||
dc.DrawRectangle(border);
|
||||
m_xruler->Draw(dc);
|
||||
m_yruler->Draw(dc);
|
||||
}
|
||||
|
||||
void Plot::OnSize(wxSizeEvent & evt)
|
||||
{
|
||||
Refresh(false);
|
||||
}
|
||||
|
||||
int Plot::XToScreen(float x, wxRect& rect)
|
||||
{
|
||||
return rect.x + lrint((x-m_xmin)*rect.width/(m_xmax-m_xmin));
|
||||
}
|
||||
|
||||
int Plot::YToScreen(float y, wxRect& rect)
|
||||
{
|
||||
return rect.y + rect.height - lrint((y-m_ymin)*rect.height/(m_ymax-m_ymin));
|
||||
}
|
||||
|
||||
BEGIN_EVENT_TABLE(Plot, wxPanelWrapper)
|
||||
EVT_PAINT(Plot::OnPaint)
|
||||
EVT_SIZE(Plot::OnSize)
|
||||
END_EVENT_TABLE()
|
58
src/widgets/Plot.h
Normal file
58
src/widgets/Plot.h
Normal file
@ -0,0 +1,58 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
Plot.h
|
||||
|
||||
Max Maisel
|
||||
|
||||
This class is a generic plot.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_PLOT__
|
||||
#define __AUDACITY_PLOT__
|
||||
|
||||
#include "wxPanelWrapper.h" // to inherit
|
||||
|
||||
#include "MemoryX.h"
|
||||
|
||||
class Ruler;
|
||||
|
||||
struct PlotData
|
||||
{
|
||||
std::unique_ptr<wxPen> pen;
|
||||
std::vector<float> xdata;
|
||||
std::vector<float> ydata;
|
||||
};
|
||||
|
||||
class Plot : public wxPanelWrapper
|
||||
{
|
||||
public:
|
||||
Plot(wxWindow *parent, wxWindowID winid,
|
||||
float x_min, float x_max, float y_min, float y_max,
|
||||
const TranslatableString& xlabel, const TranslatableString& ylabel,
|
||||
int xformat = 1, int yformat = 1, //Ruler::RealFormat
|
||||
int count = 1, const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxTAB_TRAVERSAL | wxNO_BORDER);
|
||||
|
||||
inline PlotData* GetPlotData(int id)
|
||||
{ return &m_plots[id]; }
|
||||
|
||||
private:
|
||||
void OnPaint(wxPaintEvent & evt);
|
||||
void OnSize(wxSizeEvent & evt);
|
||||
|
||||
float m_xmin, m_xmax;
|
||||
float m_ymin, m_ymax;
|
||||
std::vector<PlotData> m_plots;
|
||||
std::unique_ptr<Ruler> m_xruler, m_yruler;
|
||||
|
||||
int XToScreen(float x, wxRect& rect);
|
||||
int YToScreen(float y, wxRect& rect);
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user