예제 #1
0
wxBitmap ocpnFloatingCompassWindow::CreateBmp()
{
    wxString gpsIconName;
    ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();

    // In order to draw a horizontal compass window when the toolbar is vertical, we
    // need to save away the sizes and backgrounds for the two icons.

    static wxBitmap compassBg, gpsBg;
    static wxSize toolsize;
    static int topmargin, leftmargin, radius;

    if( ! compassBg.IsOk() ) {
        int orient = style->GetOrientation();
        style->SetOrientation( wxTB_HORIZONTAL );
        if( style->HasBackground() ) {
            compassBg = style->GetNormalBG();
            style->DrawToolbarLineStart( compassBg );
            gpsBg = style->GetNormalBG();
            style->DrawToolbarLineEnd( gpsBg );
        }

        leftmargin = style->GetLeftMargin();
        topmargin = style->GetTopMargin();
        toolsize = style->GetToolSize();
        toolsize.x *= 2;
        radius = style->GetToolbarCornerRadius();

        if( orient ) style->SetOrientation( wxTB_VERTICAL );
    }

    bool b_need_refresh = false;

    if( bGPSValid ) {
        if( g_bSatValid ) {
            gpsIconName = _T("gps3Bar");
            if( g_SatsInView <= 8 ) gpsIconName = _T("gps2Bar");
            if( g_SatsInView <= 4 ) gpsIconName = _T("gps1Bar");
            if( g_SatsInView < 0 ) gpsIconName = _T("gpsGry");

        } else
            gpsIconName = _T("gpsGrn");
    } else
        gpsIconName = _T("gpsRed");

    if( m_lastgpsIconName != gpsIconName ) b_need_refresh = true;

    double rose_angle = -999.;

    if( ( fabs( cc1->GetVPRotation() ) > .01 ) || ( fabs( cc1->GetVPSkew() ) > .01 ) ) {
        rose_angle = -cc1->GetVPRotation();

        if( !g_bCourseUp && !g_bskew_comp ) rose_angle = -cc1->GetVPRotation() - cc1->GetVPSkew();

        b_need_refresh = true;
    } else
        rose_angle = 0.;

    if( fabs( m_rose_angle - rose_angle ) > .001 ) b_need_refresh = true;

    if( b_need_refresh ) {
        wxBitmap StatBmp;

        StatBmp.Create(
                ( _img_compass.GetWidth() + _img_gpsRed.GetWidth() ) + style->GetLeftMargin() * 2
                        + style->GetToolSeparation(),
                _img_compass.GetHeight() + style->GetTopMargin() + style->GetBottomMargin() );

        if( StatBmp.IsOk() ) {

            wxMemoryDC mdc;
            mdc.SelectObject( StatBmp );
            mdc.SetBackground( wxBrush( GetGlobalColor( _T("GREY2") ), wxSOLID ) );
            mdc.Clear();

            mdc.SetPen( wxPen( GetGlobalColor( _T("UITX1") ), 1 ) );
            mdc.SetBrush( wxBrush( GetGlobalColor( _T("UITX1") ), wxTRANSPARENT ) );

            mdc.DrawRoundedRectangle( 0, 0, StatBmp.GetWidth(), StatBmp.GetHeight(),
                    style->GetToolbarCornerRadius() );

            wxPoint offset( style->GetLeftMargin(), style->GetTopMargin() );

            //    Build Compass Rose, rotated...
            wxBitmap BMPRose;
            wxPoint after_rotate;

            if( g_bCourseUp ) BMPRose = style->GetIcon( _T("CompassRose") );
            else
                BMPRose = style->GetIcon( _T("CompassRoseBlue") );
            if( ( fabs( cc1->GetVPRotation() ) > .01 ) || ( fabs( cc1->GetVPSkew() ) > .01 ) ) {
                wxPoint rot_ctr( BMPRose.GetWidth() / 2, BMPRose.GetHeight() / 2 );
                wxImage rose_img = BMPRose.ConvertToImage();

                wxImage rot_image = rose_img.Rotate( rose_angle, rot_ctr, true, &after_rotate );
                BMPRose = wxBitmap( rot_image ).GetSubBitmap( wxRect( -after_rotate.x, -after_rotate.y, BMPRose.GetWidth(), BMPRose.GetHeight()) );
            }

            wxBitmap iconBm;

            if( style->HasBackground() ) {
                iconBm = MergeBitmaps( compassBg, BMPRose, wxSize( 0, 0 ) );
            } else {
                iconBm = BMPRose;
            }

            mdc.DrawBitmap( iconBm, offset );
            offset.x += iconBm.GetWidth();

            m_rose_angle = rose_angle;

            if( style->HasBackground() ) {
                iconBm = MergeBitmaps( gpsBg, style->GetIcon( gpsIconName ), wxSize( 0, 0 ) );
            } else {
                iconBm = style->GetIcon( gpsIconName );
            }
            mdc.DrawBitmap( iconBm, offset );
            mdc.SelectObject( wxNullBitmap );
            m_lastgpsIconName = gpsIconName;
        }

        if( style->marginsInvisible ) {
            m_MaskBmp = wxBitmap( StatBmp.GetWidth(), StatBmp.GetHeight() );
            wxMemoryDC sdc( m_MaskBmp );
            sdc.SetBackground( *wxWHITE_BRUSH );
            sdc.Clear();
            sdc.SetBrush( *wxBLACK_BRUSH );
            sdc.SetPen( *wxBLACK_PEN );
            sdc.DrawRoundedRectangle( wxPoint( leftmargin, topmargin ), toolsize, radius );
            sdc.SelectObject( wxNullBitmap );
            SetShape( wxRegion( m_MaskBmp, *wxWHITE, 0 ) );
        }

        return StatBmp;
    }

    else
        return wxNullBitmap;
}
예제 #2
0
void ocpnCompass::CreateBmp( bool newColorScheme )
{
    if(!m_shown)
        return;

    wxString gpsIconName;
    ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();

    // In order to draw a horizontal compass window when the toolbar is vertical, we
    // need to save away the sizes and backgrounds for the two icons.

    static wxBitmap compassBg, gpsBg;
    static wxSize toolsize;
    static int topmargin, leftmargin, radius;

    if( ! compassBg.IsOk() || newColorScheme ) {
        int orient = style->GetOrientation();
        style->SetOrientation( wxTB_HORIZONTAL );
        if( style->HasBackground() ) {
            compassBg = style->GetNormalBG();
            style->DrawToolbarLineStart( compassBg );
            compassBg = style->SetBitmapBrightness( compassBg );
            gpsBg = style->GetNormalBG();
            style->DrawToolbarLineEnd( gpsBg );
            gpsBg = style->SetBitmapBrightness( gpsBg );
        }

        if(fabs(m_scale-1.0) > 0.1){
            wxImage bg_img = compassBg.ConvertToImage();
            bg_img.Rescale(compassBg.GetWidth() * m_scale, compassBg.GetHeight() *m_scale, wxIMAGE_QUALITY_NORMAL);
            compassBg = wxBitmap( bg_img );
            
            bg_img = gpsBg.ConvertToImage();
            bg_img.Rescale(gpsBg.GetWidth() * m_scale, gpsBg.GetHeight() *m_scale, wxIMAGE_QUALITY_NORMAL);
            gpsBg = wxBitmap( bg_img );
        }
    
        leftmargin = style->GetCompassLeftMargin();
        topmargin = style->GetCompassTopMargin();
        radius = style->GetCompassCornerRadius();

        if( orient ) style->SetOrientation( wxTB_VERTICAL );
    }

    bool b_need_refresh = false;

    if( bGPSValid ) {
        if( g_bSatValid ) {
            gpsIconName = _T("gps3Bar");
            if( g_SatsInView <= 8 ) gpsIconName = _T("gps2Bar");
            if( g_SatsInView <= 4 ) gpsIconName = _T("gps1Bar");
            if( g_SatsInView < 0 ) gpsIconName = _T("gpsGry");

        } else
            gpsIconName = _T("gpsGrn");
    } else
        gpsIconName = _T("gpsRed");

    if( m_lastgpsIconName != gpsIconName ) b_need_refresh = true;

    double rose_angle = -999.;

    if( ( fabs( cc1->GetVPRotation() ) > .01 ) || ( fabs( cc1->GetVPSkew() ) > .01 ) ) {
        rose_angle = -cc1->GetVPRotation();
    } else
        rose_angle = 0.;

    if( fabs( m_rose_angle - rose_angle ) > .1 ) b_need_refresh = true;

    if( !b_need_refresh )
        return;

    int width = compassBg.GetWidth() + gpsBg.GetWidth() + leftmargin;
    if( !style->marginsInvisible ) 
        width += leftmargin + style->GetToolSeparation();
        
    m_StatBmp.Create( width, compassBg.GetHeight() + topmargin + style->GetCompassBottomMargin() );

    m_rect.width = m_StatBmp.GetWidth();
    m_rect.height = m_StatBmp.GetHeight();
    
    if( !m_StatBmp.IsOk() )
        return;

    m_MaskBmp = wxBitmap( m_StatBmp.GetWidth(), m_StatBmp.GetHeight() );
    if( style->marginsInvisible ) {
        wxMemoryDC sdc( m_MaskBmp );
        sdc.SetBackground( *wxWHITE_BRUSH );
        sdc.Clear();
        sdc.SetBrush( *wxBLACK_BRUSH );
        sdc.SetPen( *wxBLACK_PEN );
        wxSize maskSize = wxSize(m_MaskBmp.GetWidth() - leftmargin,
                                 m_MaskBmp.GetHeight() - (2 * topmargin));
        sdc.DrawRoundedRectangle( wxPoint( leftmargin, topmargin ), maskSize, radius );
        sdc.SelectObject( wxNullBitmap );
    } else if(radius) {
        wxMemoryDC sdc( m_MaskBmp );
        sdc.SetBackground( *wxWHITE_BRUSH );
        sdc.Clear();
        sdc.SetBrush( *wxBLACK_BRUSH );
        sdc.SetPen( *wxBLACK_PEN );
        sdc.DrawRoundedRectangle( 0, 0, m_MaskBmp.GetWidth(), m_MaskBmp.GetHeight(), radius );
        sdc.SelectObject( wxNullBitmap );
    }
    m_StatBmp.SetMask(new wxMask(m_MaskBmp, *wxWHITE));

    wxMemoryDC mdc;
    mdc.SelectObject( m_StatBmp );
    mdc.SetBackground( wxBrush( GetGlobalColor( _T("COMP1") ), wxSOLID ) );
    mdc.Clear();

    mdc.SetPen( wxPen( GetGlobalColor( _T("UITX1") ), 1 ) );
    mdc.SetBrush( wxBrush( GetGlobalColor( _T("UITX1") ), wxTRANSPARENT ) );
    
    if( !style->marginsInvisible )
        mdc.DrawRoundedRectangle( 0, 0, m_StatBmp.GetWidth(), m_StatBmp.GetHeight(),radius );

    wxPoint offset(leftmargin, topmargin);

    //    Build Compass Rose, rotated...
    wxBitmap BMPRose;
    wxPoint after_rotate;

    int cwidth = style->GetToolSize().x * m_scale;
    int cheight = style->GetToolSize().y * m_scale;
    cheight = wxMin(cheight, compassBg.GetHeight());
    cwidth = wxMin( cwidth, cheight );
    cheight = cwidth;
    
    if( g_bCourseUp )
        BMPRose = style->GetIcon( _T("CompassRose"), cwidth, cheight );
    else
        BMPRose = style->GetIcon( _T("CompassRoseBlue"), cwidth, cheight );
    if( ( fabs( cc1->GetVPRotation() ) > .01 ) || ( fabs( cc1->GetVPSkew() ) > .01 ) ) {
        
        wxImage rose_img = BMPRose.ConvertToImage();
        wxPoint rot_ctr( cwidth / 2, cheight / 2  );
        wxImage rot_image = rose_img.Rotate( rose_angle, rot_ctr, true, &after_rotate );
        BMPRose = wxBitmap( rot_image ).GetSubBitmap( wxRect( -after_rotate.x, -after_rotate.y, cwidth, cheight ));
    }

    wxBitmap iconBm;

    if( style->HasBackground() ) {
        iconBm = MergeBitmaps( compassBg, BMPRose, wxSize( 0, 0 ) );
    } else {
        iconBm = BMPRose;
    }
    
    iconBm = ConvertTo24Bit( wxColor(0,0,0), iconBm);
        
    mdc.DrawBitmap( iconBm, offset );
    offset.x += iconBm.GetWidth();
    offset.x += style->GetToolSeparation();

    m_rose_angle = rose_angle;

    //  GPS Icon
    int twidth = style->GetToolSize().x * m_scale;
    int theight = style->GetToolSize().y * m_scale;
    theight = wxMin(cheight, compassBg.GetHeight());
    int swidth = wxMax( twidth, theight );
    int sheight = wxMin( twidth, theight );
    
    //  Sometimes, the SVG renderer gets the size wrong due to some internal rounding error.
    //  If so found, it seems to work OK by just reducing the requested size by one pixel....
    wxBitmap gicon = style->GetIcon( gpsIconName, swidth, sheight );
    if( gicon.GetHeight() != sheight )
        gicon = style->GetIcon( gpsIconName, swidth-1, sheight-1, true );

    if( style->HasBackground() ) {
        iconBm = MergeBitmaps( gpsBg, gicon, wxSize( 0, 0 ) );
    } else {
        iconBm = gicon;
    }
    
    iconBm = ConvertTo24Bit( wxColor(0,0,0), iconBm);
    mdc.DrawBitmap( iconBm, offset );
    mdc.SelectObject( wxNullBitmap );
    
    m_lastgpsIconName = gpsIconName;

#if defined(ocpnUSE_GLES)   // GLES does not do ocpnDC::DrawBitmap(), so use texture
    if(g_bopengl){
        wxImage image = m_StatBmp.ConvertToImage(); 
        unsigned char *imgdata = image.GetData();
        unsigned char *imgalpha = image.GetAlpha();
        int tex_w = image.GetWidth();
        int tex_h = image.GetHeight();
        
        GLuint format = GL_RGBA;
        GLuint internalformat = format;
        int stride = 4;
        
        if(imgdata){
            unsigned char *teximage = (unsigned char *) malloc( stride * tex_w * tex_h );
        
            for( int j = 0; j < tex_w*tex_h; j++ ){
                for( int k = 0; k < 3; k++ )
                    teximage[j * stride + k] = imgdata[3*j + k];
                teximage[j * stride + 3] = imgalpha ? imgalpha[j] : 255;      // alpha
            }
                
            if(texobj){
                glDeleteTextures(1, &texobj);
                texobj = 0;
            }
                
            glGenTextures( 1, &texobj );
            glBindTexture( GL_TEXTURE_2D, texobj );
            
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST/*GL_LINEAR*/ );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
            
            glTexImage2D( GL_TEXTURE_2D, 0, internalformat, tex_w, tex_h, 0,
                        format, GL_UNSIGNED_BYTE, teximage );
                            
            free(teximage);
        }
   }
#endif
       
}