#pragma hdrstop
#endif
+#if wxUSE_PLOT
+
#ifndef WX_PRECOMP
#include "wx/object.h"
#include "wx/font.h"
static wxBitmap *GetUpBitmap();
static wxBitmap *GetDownBitmap();
+//-----------------------------------------------------------------------------
+// consts
+//-----------------------------------------------------------------------------
+
+#define wxPLOT_SCROLL_STEP 30
+
//-----------------------------------------------------------------------------
// wxPlotEvent
//-----------------------------------------------------------------------------
m_endY = endY;
}
+//-----------------------------------------------------------------------------
+// wxPlotOnOffCurve
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_CLASS(wxPlotOnOffCurve, wxObject)
+
+#include "wx/arrimpl.cpp"
+WX_DEFINE_OBJARRAY(wxArrayPlotOnOff);
+
+wxPlotOnOffCurve::wxPlotOnOffCurve( int offsetY )
+{
+ m_offsetY = offsetY;
+ m_minX = -1;
+ m_maxX = -1;
+}
+
+void wxPlotOnOffCurve::Add( wxInt32 on, wxInt32 off, void *clientData )
+{
+ wxASSERT_MSG( on > 0, wxT("plot index < 0") );
+ wxASSERT( on <= off );
+
+ if (m_minX == -1)
+ m_minX = on;
+ if (off > m_maxX)
+ m_maxX = off;
+
+ wxPlotOnOff *v = new wxPlotOnOff;
+ v->m_on = on;
+ v->m_off = off;
+ v->m_clientData = clientData;
+ m_marks.Add( v );
+}
+
+size_t wxPlotOnOffCurve::GetCount()
+{
+ return m_marks.GetCount();
+}
+
+wxInt32 wxPlotOnOffCurve::GetOn( size_t index )
+{
+ wxPlotOnOff *v = &m_marks.Item( index );
+ return v->m_on;
+}
+
+wxInt32 wxPlotOnOffCurve::GetOff( size_t index )
+{
+ wxPlotOnOff *v = &m_marks.Item( index );
+ return v->m_off;
+}
+
+void* wxPlotOnOffCurve::GetClientData( size_t index )
+{
+ wxPlotOnOff *v = &m_marks.Item( index );
+ return v->m_clientData;
+}
+
+wxPlotOnOff *wxPlotOnOffCurve::GetAt( size_t index )
+{
+ return &m_marks.Item( index );
+}
+
+void wxPlotOnOffCurve::DrawOnLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end, void *WXUNUSED(clientData) )
+{
+ dc.DrawLine( start, y, start, y-30 );
+ dc.DrawLine( start, y-30, end, y-30 );
+ dc.DrawLine( end, y-30, end, y );
+}
+
+void wxPlotOnOffCurve::DrawOffLine( wxDC &dc, wxCoord y, wxCoord start, wxCoord end )
+{
+ dc.DrawLine( start, y, end, y );
+}
+
//-----------------------------------------------------------------------------
// wxPlotArea
//-----------------------------------------------------------------------------
int view_x;
int view_y;
m_owner->GetViewStart( &view_x, &view_y );
- view_x *= 10;
- view_y *= 10;
+ view_x *= wxPLOT_SCROLL_STEP;
+ view_y *= wxPLOT_SCROLL_STEP;
- int x = event.GetX();
- int y = event.GetY();
+ wxCoord x = event.GetX();
+ wxCoord y = event.GetY();
x += view_x;
y += view_y;
double end = curve->GetEndY();
wxCoord offset_y = curve->GetOffsetY();
- double dy = (end - curve->GetY( x/m_owner->GetZoom() )) / range;
+ double dy = (end - curve->GetY( (wxInt32)(x/m_owner->GetZoom()) )) / range;
wxCoord curve_y = (wxCoord)(dy * double_client_height) - offset_y - 1;
if ((y-curve_y < 4) && (y-curve_y > -4))
event1.SetPosition( (int)floor(x/m_owner->GetZoom()) );
m_owner->GetEventHandler()->ProcessEvent( event1 );
- if (curve != m_owner->GetCurrent());
+ if (curve != m_owner->GetCurrent())
{
wxPlotEvent event2( wxEVT_PLOT_SEL_CHANGING, m_owner->GetId() );
event2.SetEventObject( m_owner );
int view_x;
int view_y;
m_owner->GetViewStart( &view_x, &view_y );
- view_x *= 10;
+ view_x *= wxPLOT_SCROLL_STEP;
if (from == -1)
from = view_x;
if (to == -1)
to = view_x + client_width;
-
+
double zoom = m_owner->GetZoom();
int start_x = wxMax( from, (int)floor(curve->GetStartX()*zoom) );
start_x = wxMax( view_x, start_x );
end_x = wxMin( view_x + client_width, end_x );
+ end_x++;
+
double double_client_height = (double)client_height;
double range = curve->GetEndY() - curve->GetStartY();
double end = curve->GetEndY();
wxCoord y=0,last_y=0;
for (int x = start_x; x < end_x; x++)
{
- double dy = (end - curve->GetY( x/zoom )) / range;
+ double dy = (end - curve->GetY( (wxInt32)(x/zoom) )) / range;
y = (wxCoord)(dy * double_client_height) - offset_y - 1;
if (x != start_x)
}
}
+void wxPlotArea::DrawOnOffCurve( wxDC *dc, wxPlotOnOffCurve *curve, int from, int to )
+{
+ int view_x;
+ int view_y;
+ m_owner->GetViewStart( &view_x, &view_y );
+ view_x *= wxPLOT_SCROLL_STEP;
+
+ if (from == -1)
+ from = view_x;
+
+ int client_width;
+ int client_height;
+ GetClientSize( &client_width, &client_height);
+
+ if (to == -1)
+ to = view_x + client_width;
+
+ double zoom = m_owner->GetZoom();
+
+ int start_x = wxMax( from, (int)floor(curve->GetStartX()*zoom) );
+ int end_x = wxMin( to, (int)floor(curve->GetEndX()*zoom) );
+
+ start_x = wxMax( view_x, start_x );
+ end_x = wxMin( view_x + client_width, end_x );
+
+ end_x++;
+
+ wxCoord offset_y = curve->GetOffsetY();
+ wxCoord last_off = -5;
+
+ if (curve->GetCount() == 0)
+ return;
+
+ for (size_t index = 0; index < curve->GetCount(); index++)
+ {
+ wxPlotOnOff *p = curve->GetAt( index );
+
+ wxCoord on = (wxCoord)(p->m_on*zoom);
+ wxCoord off = (wxCoord)(p->m_off*zoom);
+
+ if (end_x < on)
+ {
+ curve->DrawOffLine( *dc, client_height-offset_y, last_off, on );
+ break;
+ }
+
+ if (off >= start_x)
+ {
+ curve->DrawOffLine( *dc, client_height-offset_y, last_off, on );
+ curve->DrawOnLine( *dc, client_height-offset_y, on, off, p->m_clientData );
+ }
+ last_off = off;
+ }
+
+ wxPlotOnOff *p = curve->GetAt( curve->GetCount()-1 );
+ wxCoord off = (wxCoord)(p->m_off*zoom);
+ if (off < end_x)
+ curve->DrawOffLine( *dc, client_height-offset_y, off, to );
+}
+
void wxPlotArea::OnPaint( wxPaintEvent &WXUNUSED(event) )
{
int view_x;
int view_y;
m_owner->GetViewStart( &view_x, &view_y );
- view_x *= 10;
- view_y *= 10;
+ view_x *= wxPLOT_SCROLL_STEP;
+ view_y *= wxPLOT_SCROLL_STEP;
wxPaintDC dc( this );
m_owner->PrepareDC( dc );
wxNode *node = m_owner->m_curves.First();
while (node)
{
- wxPlotCurve *curve = (wxPlotCurve*)node->Data();
+ wxPlotCurve *curve = (wxPlotCurve*) node->Data();
if (curve == m_owner->GetCurrent())
dc.SetPen( *wxBLACK_PEN );
node = node->Next();
}
+
+ dc.SetPen( *wxRED_PEN );
+
+ node = m_owner->m_onOffCurves.First();
+ while (node)
+ {
+ wxPlotOnOffCurve *curve = (wxPlotOnOffCurve*) node->Data();
+
+ DrawOnOffCurve( &dc, curve, update_x-1, update_x+update_width+2 );
+
+ node = node->Next();
+ }
+
upd ++;
}
}
m_owner = parent;
SetBackgroundColour( *wxWHITE );
+ SetFont( *wxSMALL_FONT );
}
void wxPlotXAxisArea::OnMouse( wxMouseEvent &event )
int view_x;
int view_y;
m_owner->GetViewStart( &view_x, &view_y );
- view_x *= 10;
- view_y *= 10;
+ view_x *= wxPLOT_SCROLL_STEP;
+ view_y *= wxPLOT_SCROLL_STEP;
- int x = event.GetX();
- int y = event.GetY();
+ wxCoord x = event.GetX();
+ wxCoord y = event.GetY();
x += view_x;
y += view_y;
int view_x;
int view_y;
m_owner->GetViewStart( &view_x, &view_y );
- view_x *= 10;
- view_y *= 10;
+ view_x *= wxPLOT_SCROLL_STEP;
+ view_y *= wxPLOT_SCROLL_STEP;
wxPaintDC dc( this );
{
dc.DrawLine( x, 5, x, 15 );
wxString label;
- if (range < 10)
- label.Printf( wxT("%.1f"), current );
+ if (range < 50)
+ {
+ label.Printf( wxT("%f"), current );
+ while (label.Last() == wxT('0'))
+ label.RemoveLast();
+ if ((label.Last() == wxT('.')) || (label.Last() == wxT(',')))
+ label.Append( wxT('0') );
+ }
else
label.Printf( wxT("%d"), (int)floor(current) );
dc.DrawText( label, x-4, 20 );
m_owner = parent;
SetBackgroundColour( *wxWHITE );
+ SetFont( *wxSMALL_FONT );
}
void wxPlotYAxisArea::OnMouse( wxMouseEvent &WXUNUSED(event) )
{
dc.DrawLine( client_width-15, y, client_width-7, y );
wxString label;
- label.Printf( wxT("%.1f"), current );
+ if (range < 50)
+ {
+ label.Printf( wxT("%f"), current );
+ while (label.Last() == wxT('0'))
+ label.RemoveLast();
+ if ((label.Last() == wxT('.')) || (label.Last() == wxT(',')))
+ label.Append( wxT('0') );
+ }
+ else
+ label.Printf( wxT("%d"), (int)floor(current) );
dc.DrawText( label, 5, y-7 );
}
{
m_xUnitsPerValue = 1.0;
m_xZoom = 1.0;
+
+ m_enlargeAroundWindowCentre = FALSE;
+ m_scrollOnThumbRelease = FALSE;
m_area = new wxPlotArea( this );
wxBoxSizer *mainsizer = new wxBoxSizer( wxHORIZONTAL );
return m_current;
}
+void wxPlotWindow::Add( wxPlotOnOffCurve *curve )
+{
+ m_onOffCurves.Append( curve );
+}
+
+void wxPlotWindow::Delete( wxPlotOnOffCurve* curve )
+{
+ wxNode *node = m_onOffCurves.Find( curve );
+ if (!node) return;
+
+ m_onOffCurves.DeleteObject( curve );
+}
+
+size_t wxPlotWindow::GetOnOffCurveCount()
+{
+ return m_onOffCurves.GetCount();
+}
+
+wxPlotOnOffCurve *wxPlotWindow::GetOnOffCurveAt( size_t n )
+{
+ wxNode *node = m_onOffCurves.Nth( n );
+ if (!node)
+ return (wxPlotOnOffCurve*) NULL;
+
+ return (wxPlotOnOffCurve*) node->Data();
+}
+
void wxPlotWindow::Move( wxPlotCurve* curve, int pixels_up )
{
m_area->DeleteCurve( curve );
{
m_area->DeleteCurve( curve );
+ int client_width;
+ int client_height;
+ m_area->GetClientSize( &client_width, &client_height);
+ double offset = (double)curve->GetOffsetY() / (double)client_height;
+
double range = curve->GetEndY() - curve->GetStartY();
+ offset *= range;
+
double new_range = range / factor;
- double middle = curve->GetEndY() - range/2;
- curve->SetStartY( middle - new_range / 2 );
- curve->SetEndY( middle + new_range / 2 );
+ double new_offset = offset / factor;
+
+ if (m_enlargeAroundWindowCentre)
+ {
+ double middle = curve->GetStartY() - offset + range/2;
+
+ curve->SetStartY( middle - new_range / 2 + new_offset );
+ curve->SetEndY( middle + new_range / 2 + new_offset );
+ }
+ else
+ {
+ curve->SetStartY( (curve->GetStartY() - offset)/factor + new_offset );
+ curve->SetEndY( (curve->GetEndY() - offset)/factor + new_offset );
+ }
m_area->Refresh( FALSE );
RedrawYAxis();
max = curve->GetEndX();
node = node->Next();
}
- SetScrollbars( 10, 10, (int)((max*m_xZoom)/10)+1, 0, (int)view_x*zoom/old_zoom, 0 );
+ SetScrollbars( wxPLOT_SCROLL_STEP, wxPLOT_SCROLL_STEP,
+ (int)((max*m_xZoom)/wxPLOT_SCROLL_STEP)+1, 0,
+ (int)(view_x*zoom/old_zoom), 0,
+ TRUE );
RedrawXAxis();
m_area->Refresh( TRUE );
node = node->Next();
}
- SetScrollbars( 10, 10, ((max*m_xZoom)/10)+1, 0 );
+ SetScrollbars( wxPLOT_SCROLL_STEP, wxPLOT_SCROLL_STEP,
+ (int)(((max*m_xZoom)/wxPLOT_SCROLL_STEP)+1), 0 );
}
void wxPlotWindow::RedrawXAxis()
void wxPlotWindow::OnScroll2( wxScrollWinEvent& event )
{
- wxScrolledWindow::OnScroll( event );
-
- RedrawXAxis();
+ if ((!m_scrollOnThumbRelease) || (event.GetEventType() != wxEVT_SCROLLWIN_THUMBTRACK))
+ {
+ wxScrolledWindow::OnScroll( event );
+ RedrawXAxis();
+ }
}
// ----------------------------------------------------------------------------
return s_bitmap;
}
+
+#endif // wxUSE_PLOT