void RoutePoint::Draw( ocpnDC& dc, wxPoint *rpn )
{
    wxPoint r;
    wxRect hilitebox;

    cc1->GetCanvasPointPix( m_lat, m_lon, &r );

    //  return the home point in this dc to allow "connect the dots"
    if( NULL != rpn ) *rpn = r;

    if( !m_bIsVisible )     // pjotrc 2010.02.13, 2011.02.24
        return;

    //    Optimization, especially apparent on tracks in normal cases
    if( m_IconName == _T("empty") && !m_bShowName && !m_bPtIsSelected ) return;

    wxPen *pen;
    if( m_bBlink )
        pen = g_pRouteMan->GetActiveRoutePointPen();
    else
        pen = g_pRouteMan->GetRoutePointPen();

//    Substitue icon?
    wxBitmap *pbm;
    if( ( m_bIsActive ) && ( m_IconName != _T("mob") ) )
        pbm = pWayPointMan->GetIconBitmap( _T ( "activepoint" ) );
    else
        pbm = m_pbmIcon;

    wxBitmap *pbms = NULL;
    if( g_ChartScaleFactorExp > 1.0){
        if(m_IconScaleFactor != g_ChartScaleFactorExp){
            wxImage scaled_image = pbm->ConvertToImage();
            int new_width = pbm->GetWidth() * g_ChartScaleFactorExp;
            int new_height = pbm->GetHeight() * g_ChartScaleFactorExp;
            m_ScaledBMP = wxBitmap(scaled_image.Scale(new_width, new_height, wxIMAGE_QUALITY_HIGH));
           
            m_IconScaleFactor = g_ChartScaleFactorExp;
        }
        if( m_ScaledBMP.IsOk() )
            pbm = &m_ScaledBMP;
    }
        
    int sx2 = pbm->GetWidth() / 2;
    int sy2 = pbm->GetHeight() / 2;

//    Calculate the mark drawing extents
    wxRect r1( r.x - sx2, r.y - sy2, sx2 * 2, sy2 * 2 );           // the bitmap extents

    if( m_bShowName ) {
        if( 0 == m_pMarkFont ) {
            m_pMarkFont = FontMgr::Get().GetFont( _( "Marks" ) );
            m_FontColor = FontMgr::Get().GetFontColor( _( "Marks" ) );
            CalculateNameExtents();
        }

        if( m_pMarkFont ) {
            wxRect r2( r.x + m_NameLocationOffsetX, r.y + m_NameLocationOffsetY, m_NameExtents.x,
                    m_NameExtents.y );
            r1.Union( r2 );
        }
    }

    hilitebox = r1;
    hilitebox.x -= r.x;
    hilitebox.y -= r.y;
    float radius;
    if( g_btouch ){
        hilitebox.Inflate( 20 );
        radius = 20.0f;
    }
    else{
        hilitebox.Inflate( 4 );
        radius = 4.0f;
    }

    wxColour hi_colour = pen->GetColour();
    unsigned char transparency = 100;
    if( m_bIsBeingEdited ){
        hi_colour = GetGlobalColor( _T ( "YELO1" ) );
        transparency = 150;
    }
    
        
    //  Highlite any selected point
    if( m_bPtIsSelected || m_bIsBeingEdited) {
        AlphaBlending( dc, r.x + hilitebox.x, r.y + hilitebox.y, hilitebox.width, hilitebox.height, radius,
                hi_colour, transparency );
    }

    bool bDrawHL = false;

    if( m_bBlink && ( gFrame->nBlinkerTick & 1 ) ) bDrawHL = true;

    if( ( !bDrawHL ) && ( NULL != m_pbmIcon ) ) {
        dc.DrawBitmap( *pbm, r.x - sx2, r.y - sy2, true );
        // on MSW, the dc Bounding box is not updated on DrawBitmap() method.
        // Do it explicitely here for all platforms.
        dc.CalcBoundingBox( r.x - sx2, r.y - sy2 );
        dc.CalcBoundingBox( r.x + sx2, r.y + sy2 );
    }

    if( m_bShowName ) {
        if( m_pMarkFont ) {
            dc.SetFont( *m_pMarkFont );
            dc.SetTextForeground( m_FontColor );

            dc.DrawText( m_MarkName, r.x + m_NameLocationOffsetX, r.y + m_NameLocationOffsetY );
        }
    }

    // Draw waypoint radar rings if activated
    if( m_iWaypointRangeRingsNumber && m_bShowWaypointRangeRings ) {
        double factor = 1.00;
        if( m_iWaypointRangeRingsStepUnits == 1 )          // nautical miles
            factor = 1 / 1.852;

        factor *= m_fWaypointRangeRingsStep;

        double tlat, tlon;
        wxPoint r1;
        ll_gc_ll( m_lat, m_lon, 0, factor, &tlat, &tlon );
        cc1->GetCanvasPointPix( tlat, tlon, &r1 );

        double lpp = sqrt( pow( (double) (r.x - r1.x), 2) +
                           pow( (double) (r.y - r1.y), 2 ) );
        int pix_radius = (int) lpp;

        wxPen ppPen1( m_wxcWaypointRangeRingsColour, 2 );
        wxBrush saveBrush = dc.GetBrush();
        wxPen savePen = dc.GetPen();
        dc.SetPen( ppPen1 );
        dc.SetBrush( wxBrush( m_wxcWaypointRangeRingsColour, wxBRUSHSTYLE_TRANSPARENT ) );

        for( int i = 1; i <= m_iWaypointRangeRingsNumber; i++ )
            dc.StrokeCircle( r.x, r.y, i * pix_radius );
        dc.SetPen( savePen );
        dc.SetBrush( saveBrush );
    }
    
    //  Save the current draw rectangle in the current DC
    //    This will be useful for fast icon redraws
    CurrentRect_in_DC.x = r.x + hilitebox.x;
    CurrentRect_in_DC.y = r.y + hilitebox.y;
    CurrentRect_in_DC.width = hilitebox.width;
    CurrentRect_in_DC.height = hilitebox.height;

    if( m_bBlink ) g_blink_rect = CurrentRect_in_DC;               // also save for global blinker

    delete pbms;        // the potentially scaled bitmap
}
Exemple #2
0
void Route::Draw( ocpnDC& dc, ViewPort &VP )
{
    if( m_nPoints == 0 ) return;

    if( m_bVisible && m_bRtIsSelected ) {
        dc.SetPen( *g_pRouteMan->GetSelectedRoutePen() );
        dc.SetBrush( *g_pRouteMan->GetSelectedRouteBrush() );
    }
    else if ( m_bVisible )
    {
        int style = wxSOLID;
        int width = g_route_line_width;
        wxColour col;
        if( m_style != STYLE_UNDEFINED ) style = m_style;
        if( m_width != STYLE_UNDEFINED ) width = m_width;
        if( m_Colour == wxEmptyString ) {
            col = g_pRouteMan->GetRoutePen()->GetColour();
        } else {
            for( unsigned int i = 0; i < sizeof( ::GpxxColorNames ) / sizeof(wxString); i++ ) {
                if( m_Colour == ::GpxxColorNames[i] ) {
                    col = ::GpxxColors[i];
                    break;
                }
            }
        }
        dc.SetPen( *wxThePenList->FindOrCreatePen( col, width, style ) );
        dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( col, wxSOLID ) );
    }

    if( m_bVisible && m_bRtIsActive )
    {
        dc.SetPen( *g_pRouteMan->GetActiveRoutePen() );
        dc.SetBrush( *g_pRouteMan->GetActiveRouteBrush() );
    }

    wxPoint rpt1, rpt2;
    if ( m_bVisible )
        DrawPointWhich( dc, 1, &rpt1 );

    wxRoutePointListNode *node = pRoutePointList->GetFirst();
    RoutePoint *prp1 = node->GetData();
    node = node->GetNext();

    if ( !m_bVisible && prp1->m_bKeepXRoute )
            prp1->Draw( dc );

    while( node ) {

        RoutePoint *prp2 = node->GetData();
        if ( !m_bVisible && prp2->m_bKeepXRoute )
            prp2->Draw( dc );
        else if (m_bVisible)
            prp2->Draw( dc, &rpt2 );

        if ( m_bVisible )
        {
            //    Handle offscreen points
            bool b_2_on = VP.GetBBox().PointInBox( prp2->m_lon, prp2->m_lat, 0 );
            bool b_1_on = VP.GetBBox().PointInBox( prp1->m_lon, prp1->m_lat, 0 );

            //TODO This logic could be simpliifed
            //Simple case
            if( b_1_on && b_2_on ) RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x, rpt2.y, VP, true ); // with arrows

            //    In the cases where one point is on, and one off
            //    we must decide which way to go in longitude
            //     Arbitrarily, we will go the shortest way

            double pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI
                * VP.view_scale_ppm;
            double dp = pow( (double) ( rpt1.x - rpt2.x ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 );
            double dtest;
            int adder;
            if( b_1_on && !b_2_on ) {
                if( rpt2.x < rpt1.x ) adder = (int) pix_full_circle;
                else
                    adder = -(int) pix_full_circle;

                dtest = pow( (double) ( rpt1.x - ( rpt2.x + adder ) ), 2 )
                    + pow( (double) ( rpt1.y - rpt2.y ), 2 );

                if( dp < dtest ) adder = 0;

                RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x + adder, rpt2.y, VP, true );
            } else
                if( !b_1_on && b_2_on ) {
                    if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle;
                    else
                        adder = -(int) pix_full_circle;

                    dtest = pow( (double) ( rpt2.x - ( rpt1.x + adder ) ), 2 )
                        + pow( (double) ( rpt1.y - rpt2.y ), 2 );

                    if( dp < dtest ) adder = 0;

                    RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, VP, true );
                }

                //Both off, need to check shortest distance
                else
                    if( !b_1_on && !b_2_on ) {
                        if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle;
                        else
                            adder = -(int) pix_full_circle;

                        dtest = pow( (double) ( rpt2.x - ( rpt1.x + adder ) ), 2 )
                            + pow( (double) ( rpt1.y - rpt2.y ), 2 );

                        if( dp < dtest ) adder = 0;

                        RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, VP, true );
                    }
        }
        rpt1 = rpt2;
        prp1 = prp2;

        node = node->GetNext();
    }
}
Exemple #3
0
void Piano::Paint( int y, ocpnDC& dc, wxDC *shapeDC )
{
    if(shapeDC) {
        shapeDC->SetBackground( *wxBLACK_BRUSH);
        shapeDC->SetBrush( *wxWHITE_BRUSH);
        shapeDC->SetPen( *wxWHITE_PEN);
        shapeDC->Clear();
    }

    ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
    if(!style->chartStatusWindowTransparent) {
        dc.SetPen( *wxTRANSPARENT_PEN );
        dc.SetBrush( m_backBrush );
        dc.DrawRectangle( 0, y, cc1->GetClientSize().x, GetHeight() );
    }

//    Create the Piano Keys

    int nKeys = m_key_array.GetCount();

    wxPen ppPen( GetGlobalColor( _T("CHBLK") ), 1, wxPENSTYLE_SOLID );
    dc.SetPen( ppPen );

    for( int i = 0; i < nKeys; i++ ) {
        int key_db_index = m_key_array.Item( i );

        if( -1 == key_db_index ) continue;

        bool selected = InArray(m_active_index_array, key_db_index);

        if( ChartData->GetDBChartType( key_db_index ) == CHART_TYPE_CM93 ||
            ChartData->GetDBChartType( key_db_index ) == CHART_TYPE_CM93COMP ) {
            if(selected)
                dc.SetBrush( m_scBrush );
            else
                dc.SetBrush( m_cBrush );
        } else if( ChartData->GetDBChartFamily( key_db_index ) == CHART_FAMILY_VECTOR ) {
            if(selected)
                dc.SetBrush( m_svBrush );
            else
                dc.SetBrush( m_vBrush );
        } else { // Raster Chart
            if(selected)
                dc.SetBrush( m_slBrush );
            else
                dc.SetBrush( m_tBrush );
        }

#if 0
        // Check to see if this box appears in the sub_light array
        // If so, add a crosshatch pattern to the brush
        if(InArray(m_eclipsed_index_array, key_db_index)) {
            wxBrush ebrush( dc.GetBrush().GetColour(), wxCROSSDIAG_HATCH );
            dc.SetBrush(ebrush);
        }
#endif

        if(m_bBusy)
            dc.SetBrush( m_uvBrush );
            
        wxRect box = KeyRect.Item( i );
        box.y += y;

        if( m_brounded ) {
            dc.DrawRoundedRectangle( box.x, box.y, box.width, box.height, 4 );
            if(shapeDC)
                shapeDC->DrawRoundedRectangle( box.x, box.y, box.width, box.height, 4 );
        } else {
            dc.DrawRectangle( box.x, box.y, box.width, box.height );
            if(shapeDC)
                shapeDC->DrawRectangle( box );
        }

        if(InArray(m_eclipsed_index_array, key_db_index)) {
            dc.SetBrush( m_backBrush );
            int w = 3;
            dc.DrawRoundedRectangle( box.x + w, box.y + w, box.width - ( 2 * w ),
                                     box.height - ( 2 * w ), 3 );
        }

        //    Look in the current noshow array for this index
        if(InArray(m_noshow_index_array, key_db_index) &&
           m_pInVizIconBmp && m_pInVizIconBmp->IsOk() )
            dc.DrawBitmap(ConvertTo24Bit( dc.GetBrush().GetColour(), *m_pInVizIconBmp ),
                          box.x + 4, box.y + 3, false );

        //    Look in the current skew array for this index
        if(InArray(m_skew_index_array, key_db_index) &&
           m_pSkewIconBmp && m_pSkewIconBmp->IsOk())
            dc.DrawBitmap(ConvertTo24Bit( dc.GetBrush().GetColour(), *m_pSkewIconBmp ),
                          box.x + box.width - m_pSkewIconBmp->GetWidth() - 4, box.y + 2, false );

        //    Look in the current tmerc array for this index
        if(InArray(m_tmerc_index_array, key_db_index) &&
           m_pTmercIconBmp && m_pTmercIconBmp->IsOk() )
            dc.DrawBitmap(ConvertTo24Bit( dc.GetBrush().GetColour(), *m_pTmercIconBmp ),
                          box.x + box.width - m_pTmercIconBmp->GetWidth() - 4, box.y + 2, false );

        //    Look in the current poly array for this index
        if(InArray(m_poly_index_array, key_db_index) &&
           m_pPolyIconBmp && m_pPolyIconBmp->IsOk() )
            dc.DrawBitmap(ConvertTo24Bit( dc.GetBrush().GetColour(), *m_pPolyIconBmp ),
                          box.x + box.width - m_pPolyIconBmp->GetWidth() - 4, box.y + 2, false );
    }
}
Exemple #4
0
void Route::Draw( ocpnDC& dc, ViewPort &vp, const LLBBox &box )
{
    if( pRoutePointList->empty() )
        return;

    LLBBox test_box = GetBBox();
    if( box.IntersectOut( test_box ) ) // Route is wholly outside window
        return;

    int width = g_route_line_width;
    if( m_width != WIDTH_UNDEFINED ) width = m_width;

    if( m_bVisible && m_bRtIsSelected ) {
        wxPen spen = *g_pRouteMan->GetSelectedRoutePen();
        spen.SetWidth( width );
        dc.SetPen( spen );
        dc.SetBrush( *g_pRouteMan->GetSelectedRouteBrush() );
    }
    else if ( m_bVisible )
    {
        wxPenStyle style = wxPENSTYLE_SOLID;
        wxColour col;
        if( m_style != wxPENSTYLE_INVALID ) style = m_style;
        if( m_Colour == wxEmptyString ) {
            col = g_pRouteMan->GetRoutePen()->GetColour();
        } else {
            for( unsigned int i = 0; i < sizeof( ::GpxxColorNames ) / sizeof(wxString); i++ ) {
                if( m_Colour == ::GpxxColorNames[i] ) {
                    col = ::GpxxColors[i];
                    break;
                }
            }
        }
        dc.SetPen( *wxThePenList->FindOrCreatePen( col, width, style ) );
        dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( col, wxBRUSHSTYLE_SOLID ) );
    }

    if( m_bVisible && m_bRtIsActive )
    {
        wxPen spen = *g_pRouteMan->GetActiveRoutePen();
        spen.SetWidth( width );
        dc.SetPen( spen );
        dc.SetBrush( *g_pRouteMan->GetActiveRouteBrush() );
    }

    wxPoint rpt1, rpt2;
    if ( m_bVisible )
        DrawPointWhich( dc, 1, &rpt1 );

    wxRoutePointListNode *node = pRoutePointList->GetFirst();
    RoutePoint *prp1 = node->GetData();
    node = node->GetNext();

    if ( !m_bVisible && prp1->m_bKeepXRoute )
        prp1->Draw( dc );

    while( node ) {

        RoutePoint *prp2 = node->GetData();
        if ( !m_bVisible && prp2->m_bKeepXRoute )
            prp2->Draw( dc );
        else if (m_bVisible)
            prp2->Draw( dc, &rpt2 );

        if ( m_bVisible )
        {
            //    Handle offscreen points
            bool b_2_on = vp.GetBBox().Contains( prp2->m_lat,  prp2->m_lon );
            bool b_1_on = vp.GetBBox().Contains( prp1->m_lat,  prp1->m_lon );

            //Simple case
            if( b_1_on && b_2_on ) RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x, rpt2.y, vp, true, m_hiliteWidth ); // with arrows

            //    In the cases where one point is on, and one off
            //    we must decide which way to go in longitude
            //     Arbitrarily, we will go the shortest way

            double pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI
                                     * vp.view_scale_ppm;
            double dp = pow( (double) ( rpt1.x - rpt2.x ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 );
            double dtest;
            int adder;
            if( b_1_on && !b_2_on ) {
                if( rpt2.x < rpt1.x ) adder = (int) pix_full_circle;
                else
                    adder = -(int) pix_full_circle;

                dtest = pow( (double) ( rpt1.x - ( rpt2.x + adder ) ), 2 )
                        + pow( (double) ( rpt1.y - rpt2.y ), 2 );

                if( dp < dtest ) adder = 0;

                RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x + adder, rpt2.y, vp, true, m_hiliteWidth );
            } else if( !b_1_on ) {
                if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle;
                else
                    adder = -(int) pix_full_circle;

                float rxd = rpt2.x - ( rpt1.x + adder );
                float ryd = rpt1.y - rpt2.y;
                dtest = rxd*rxd + ryd*ryd;

                if( dp < dtest ) adder = 0;

                RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, vp, true, m_hiliteWidth );
            }
        }

        rpt1 = rpt2;
        prp1 = prp2;

        node = node->GetNext();
    }
}
Exemple #5
0
void Track::Draw( ocpnDC& dc, ViewPort &VP, const LLBBox &box )
{
    std::list< std::list<wxPoint> > pointlists;
    GetPointLists(pointlists, VP, box);

    if(!pointlists.size())
        return;

    unsigned short int FromSegNo = 1;

    //  Establish basic colour
    wxColour basic_colour;
    if( IsRunning() )
        basic_colour = GetGlobalColor( _T ( "URED" ) );
    else
        basic_colour = GetDimColor(g_colourTrackLineColour);

    wxPenStyle style = wxPENSTYLE_SOLID;
    int width = g_pRouteMan->GetTrackPen()->GetWidth();
    wxColour col;
    if( m_style != wxPENSTYLE_INVALID )
        style = m_style;
    if( m_width != WIDTH_UNDEFINED )
        width = m_width;
    if( m_Colour == wxEmptyString ) {
        col = basic_colour;
    } else {
        for( unsigned int i = 0; i < sizeof( ::GpxxColorNames ) / sizeof(wxString); i++ ) {
            if( m_Colour == ::GpxxColorNames[i] ) {
                col = ::GpxxColors[i];
                break;
            }
        }
    }

    double radius = 0.;
    if( g_bHighliteTracks ) {
        double radius_meters = 20; //Current_Ch->GetNativeScale() * .0015;         // 1.5 mm at original scale
        radius = radius_meters * VP.view_scale_ppm;
        if(radius < 1.0)
            radius = 0;
    }

    if( dc.GetDC() || radius ) {
        dc.SetPen( *wxThePenList->FindOrCreatePen( col, width, style ) );
        dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( col, wxBRUSHSTYLE_SOLID ) );
        for(std::list< std::list<wxPoint> >::iterator lines = pointlists.begin();
        lines != pointlists.end(); lines++) {
            // convert from linked list to array
            wxPoint *points = new wxPoint[lines->size()];
            int i = 0;
            for(std::list<wxPoint>::iterator line = lines->begin();
                line != lines->end(); line++) {
                points[i] = *line;
                i++;
            }

            int hilite_width = radius;
            if( hilite_width ) {
                wxPen psave = dc.GetPen();

                dc.StrokeLines( i, points );

                wxColor trackLine_dim_colour = GetDimColor(g_colourTrackLineColour);
                wxColour hilt( trackLine_dim_colour.Red(), trackLine_dim_colour.Green(), trackLine_dim_colour.Blue(), 128 );

                wxPen HiPen( hilt, hilite_width, wxPENSTYLE_SOLID );
                dc.SetPen( HiPen );

                dc.StrokeLines( i, points );

                dc.SetPen( psave );
            } else
                dc.StrokeLines( i, points );

            delete [] points;
        }
    }
#ifdef ocpnUSE_GL    
    else { // opengl version
        glColor3ub(col.Red(), col.Green(), col.Blue());
        glLineWidth( wxMax( g_GLMinSymbolLineWidth, width ) );
        if( g_GLOptions.m_GLLineSmoothing )
            glEnable( GL_LINE_SMOOTH );
        glEnable( GL_BLEND );
        
        int size = 0;
        // convert from linked list to array, allocate array just once
        for(std::list< std::list<wxPoint> >::iterator lines = pointlists.begin();
            lines != pointlists.end(); lines++)
            size = wxMax(size, lines->size());
        int *points = new int[2*size];
        glVertexPointer(2, GL_INT, 0, points);

        glEnableClientState(GL_VERTEX_ARRAY);
        for(std::list< std::list<wxPoint> >::iterator lines = pointlists.begin();
            lines != pointlists.end(); lines++) {

            // convert from linked list to array
            int i = 0;
            for(std::list<wxPoint>::iterator line = lines->begin();
                line != lines->end(); line++) {
                points[i+0] = line->x;
                points[i+1] = line->y;
                i+=2;
            }

            glDrawArrays(GL_LINE_STRIP, 0, i >> 1);
        }
        glDisableClientState(GL_VERTEX_ARRAY);

        delete [] points;
        glDisable( GL_LINE_SMOOTH );
        glDisable( GL_BLEND );
        
    }
#endif

    if(m_HighlightedTrackPoint >= 0)
        TrackPoints[m_HighlightedTrackPoint]->Draw(dc);
}