// but requires updating the texture if the piano changes which is slower (although still quite fast) // the other problem is the code is difficult to follow and maintain // can remove this when we know we aren't going to ever be using it void Piano::UpdateGLTexture() { extern GLenum g_texture_rectangle_format; int w = cc1->GetClientSize().x, h = GetHeight(), tex_w, tex_h; if(g_texture_rectangle_format == GL_TEXTURE_2D) tex_w = w, tex_h = h; else tex_w = NextPow2(w), tex_h = NextPow2(h); m_texcoords[0] = (float)w / tex_w; m_texcoords[1] = (float)h / tex_h; // this isn't very pretty but should at least be fast enough unsigned char bgcolor[4], tbgcolor[4]; SetColor(bgcolor, m_backBrush); SetColor(tbgcolor, m_backBrush); wxColour b = GetGlobalColor( _T("CHBLK") ); unsigned char bcolor[4] = {b.Red(), b.Green(), b.Blue(), 255}; ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle(); if(style->chartStatusWindowTransparent) tbgcolor[3] = 0; unsigned char *data = new unsigned char[4*w*h]; // fill to background color for(int x = 0; x < w; x++) { unsigned char *pos = data + 4*x; memcpy(pos, tbgcolor, 4); } for(int y = 1; y < 8; y++) { unsigned char *pos = data + 4*(y*w); memcpy(pos, data, 4*w); } int nKeys = m_key_array.GetCount(); // draw the keys 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); unsigned char color[4]; if( ChartData->GetDBChartType( key_db_index ) == CHART_TYPE_CM93 || ChartData->GetDBChartType( key_db_index ) == CHART_TYPE_CM93COMP ) { if(selected) SetColor(color, m_scBrush ); else SetColor(color, m_cBrush ); } else if( ChartData->GetDBChartFamily( key_db_index ) == CHART_FAMILY_VECTOR ) { if(selected) SetColor(color, m_svBrush ); else SetColor(color, m_vBrush ); } else { // Raster Chart if(selected) SetColor(color, m_slBrush ); else SetColor(color, 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) SetColor(color, m_uvBrush ); wxRect box = KeyRect.Item( i ); bool eclipsed = InArray(m_eclipsed_index_array, key_db_index); int sympoint = m_brounded ? (eclipsed ? 5 : 3) : 1; for(int y = 0; y < 6; y++) { unsigned char *pos = data + 4*((box.y+y)*w + box.x); if(y > sympoint) { int line; if(y < box.height - sympoint) line = sympoint; else line = box.height-y-1; // shouldn't hit memcpy(pos, data + 4*((box.y+line)*w + box.x), 4*box.width); continue; } for(int x = 0; x < box.width; x++, pos+=4) { if(y == 0) { if( m_brounded && (x <= 2 || x >= box.width - 3) ) memcpy(pos, tbgcolor, 4); else memcpy(pos, bcolor, 4); } else if(m_brounded) { if(y == 1) { if(x == 0 || x == box.width - 1) memcpy(pos, tbgcolor, 4); else if(x == 1 || x == 2 || x == box.width - 3 || x == box.width - 2) memcpy(pos, bcolor, 4); else memcpy(pos, color, 4); } else if(y == 2) { if(x == 0 || x == box.width - 1) memcpy(pos, tbgcolor, 4); else if(x == 1 || x == box.width - 2) memcpy(pos, bcolor, 4); else memcpy(pos, color, 4); } else if(eclipsed) { if(x == 0 || x == box.width - 1) memcpy(pos, bcolor, 4); else { if(y == 3) { if(x <= 4 || x >= box.width - 5) memcpy(pos, color, 4); else memcpy(pos, bcolor, 4); } else if(y == 4) { if(x <= 3 || x >= box.width - 4) memcpy(pos, color, 4); else if(x == 4 || x == box.width - 5) memcpy(pos, bcolor, 4); else memcpy(pos, bgcolor, 4); } else { if(x <= 2 || x >= box.width - 3) memcpy(pos, color, 4); else if(x == 3 || x == box.width - 4) memcpy(pos, bcolor, 4); else memcpy(pos, bgcolor, 4); } } } else goto def; } else { def: if(x == 0 || x == box.width - 1) memcpy(pos, bcolor, 4); else memcpy(pos, color, 4); } } } } // quickly fill the rest via symmetry for(int y = 8; y < h; y++) { int line; if(y < h - 7) line = 7; else line = h-y-1; memcpy(data + 4*(y*w), data + 4*(line*w), 4*w); } if(!m_tex) glGenTextures( 1, &m_tex ); glBindTexture(GL_TEXTURE_2D, m_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if(g_texture_rectangle_format == GL_TEXTURE_2D) glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); else { glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 ); glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data ); } delete [] data; }
void PianoWin::OnPaint(wxPaintEvent& event) { int width, height; GetClientSize(&width, &height ); wxPaintDC dc(this); dc.SetBackground(m_backBrush); dc.Clear(); // Create the Piano Keys int nKeys = m_key_array.GetCount(); // assert(nKeys <= KEY_REGIONS_MAX); if(nKeys) { wxPen ppPen(GetGlobalColor(_T("CHBLK")), 1, wxSOLID); dc.SetPen(ppPen); dc.SetBrush(m_tBrush); for(int i=0 ; i<nKeys ; i++) { int key_db_index = m_key_array.Item(i); if(-1 == key_db_index) continue; if(ChartData->GetDBChartType(m_key_array.Item(i)) == CHART_TYPE_S57) { dc.SetBrush(m_vBrush); for(unsigned int ino=0 ; ino < m_active_index_array.GetCount() ; ino++) { if(m_active_index_array.Item(ino) == key_db_index) // chart is in the active list dc.SetBrush(m_svBrush); } } else if(ChartData->GetDBChartType(m_key_array.Item(i)) == CHART_TYPE_CM93) { dc.SetBrush(m_cBrush); for(unsigned int ino=0 ; ino < m_active_index_array.GetCount() ; ino++) { if(m_active_index_array.Item(ino) == key_db_index) // chart is in the active list dc.SetBrush(m_scBrush); } } else if(ChartData->GetDBChartType(m_key_array.Item(i)) == CHART_TYPE_CM93COMP) { dc.SetBrush(m_cBrush); for(unsigned int ino=0 ; ino < m_active_index_array.GetCount() ; ino++) { if(m_active_index_array.Item(ino) == key_db_index) // chart is in the active list dc.SetBrush(m_scBrush); } } else { dc.SetBrush(m_tBrush); for(unsigned int ino=0 ; ino < m_active_index_array.GetCount() ; ino++) { if(m_active_index_array.Item(ino) == key_db_index) // chart is in the active list dc.SetBrush(m_slBrush); } } // Check to see if this box appears in the sub_light array // If so, add a crosshatch pattern to the brush for(unsigned int ino=0 ; ino < m_sublite_index_array.GetCount() ; ino++) { if(m_sublite_index_array.Item(ino) == key_db_index) // chart is in the sublite list { wxBrush ebrush(dc.GetBrush().GetColour(), wxCROSSDIAG_HATCH); // dc.SetBrush(ebrush); } } wxRect box = KeyRegion[i].GetBox(); if(m_brounded) dc.DrawRoundedRectangle(box.x, box.y, box.width, box.height, 4); else dc.DrawRectangle(box); for(unsigned int ino=0 ; ino < m_sublite_index_array.GetCount() ; ino++) { if(m_sublite_index_array.Item(ino) == key_db_index) // chart is in the sublite list { dc.SetBrush(dc.GetBackground()); 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 for(unsigned int ino=0 ; ino < m_noshow_index_array.GetCount() ; ino++) { if(m_noshow_index_array.Item(ino) == key_db_index) // chart is in the noshow list { if(m_pInVizIconBmp && m_pInVizIconBmp->IsOk()) dc.DrawBitmap(*m_pInVizIconBmp, box.x + 4, box.y + 3, true); break; } } // Look in the current skew array for this index for(unsigned int ino=0 ; ino < m_skew_index_array.GetCount() ; ino++) { if(m_skew_index_array.Item(ino) == key_db_index) // chart is in the list { if(m_pSkewIconBmp && m_pSkewIconBmp->IsOk()) dc.DrawBitmap(*m_pSkewIconBmp, box.x + box.width - m_pSkewIconBmp->GetWidth(), box.y, true); break; } } // Look in the current tmerc array for this index for(unsigned int ino=0 ; ino < m_tmerc_index_array.GetCount() ; ino++) { if(m_tmerc_index_array.Item(ino) == key_db_index) // chart is in the list { if(m_pTmercIconBmp && m_pTmercIconBmp->IsOk()) dc.DrawBitmap(*m_pTmercIconBmp,box.x + box.width - m_pTmercIconBmp->GetWidth(), box.y, true); break; } } // Look in the current poly array for this index for(unsigned int ino=0 ; ino < m_poly_index_array.GetCount() ; ino++) { if(m_poly_index_array.Item(ino) == key_db_index) // chart is in the list { if(m_pPolyIconBmp && m_pPolyIconBmp->IsOk()) dc.DrawBitmap(*m_pPolyIconBmp,box.x + box.width - m_pPolyIconBmp->GetWidth(), box.y, true); break; } } } } }
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 ); } }
void PianoWin::OnPaint( wxPaintEvent& event ) { ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle(); int width, height; GetClientSize( &width, &height ); wxPaintDC dc( this ); wxBitmap shape = wxBitmap( width, height ); wxMemoryDC shapeDc( shape ); shapeDc.SetBackground( *wxBLACK_BRUSH); shapeDc.SetBrush( *wxWHITE_BRUSH); shapeDc.SetPen( *wxWHITE_PEN); shapeDc.Clear(); dc.SetBackground( m_backBrush ); dc.Clear(); // Create the Piano Keys int nKeys = m_key_array.GetCount(); if( nKeys ) { wxPen ppPen( GetGlobalColor( _T("CHBLK") ), 1, wxSOLID ); dc.SetPen( ppPen ); dc.SetBrush( m_tBrush ); for( int i = 0; i < nKeys; i++ ) { int key_db_index = m_key_array.Item( i ); if( -1 == key_db_index ) continue; if( ChartData->GetDBChartType( m_key_array.Item( i ) ) == CHART_TYPE_S57 ) { dc.SetBrush( m_vBrush ); for( unsigned int ino = 0; ino < m_active_index_array.GetCount(); ino++ ) { if( m_active_index_array.Item( ino ) == key_db_index ) // chart is in the active list dc.SetBrush( m_svBrush ); } } else if( ChartData->GetDBChartType( m_key_array.Item( i ) ) == CHART_TYPE_CM93 ) { dc.SetBrush( m_cBrush ); for( unsigned int ino = 0; ino < m_active_index_array.GetCount(); ino++ ) { if( m_active_index_array.Item( ino ) == key_db_index ) // chart is in the active list dc.SetBrush( m_scBrush ); } } else if( ChartData->GetDBChartType( m_key_array.Item( i ) ) == CHART_TYPE_CM93COMP ) { dc.SetBrush( m_cBrush ); for( unsigned int ino = 0; ino < m_active_index_array.GetCount(); ino++ ) { if( m_active_index_array.Item( ino ) == key_db_index ) // chart is in the active list dc.SetBrush( m_scBrush ); } } else { dc.SetBrush( m_tBrush ); for( unsigned int ino = 0; ino < m_active_index_array.GetCount(); ino++ ) { if( m_active_index_array.Item( ino ) == key_db_index ) // chart is in the active list dc.SetBrush( m_slBrush ); } } // Check to see if this box appears in the sub_light array // If so, add a crosshatch pattern to the brush for( unsigned int ino = 0; ino < m_sublite_index_array.GetCount(); ino++ ) { if( m_sublite_index_array.Item( ino ) == key_db_index ) // chart is in the sublite list { wxBrush ebrush( dc.GetBrush().GetColour(), wxCROSSDIAG_HATCH ); // dc.SetBrush(ebrush); } } wxRect box = KeyRegion.Item( i ).GetBox(); if( m_brounded ) { dc.DrawRoundedRectangle( box.x, box.y, box.width, box.height, 4 ); shapeDc.DrawRoundedRectangle( box.x, box.y, box.width, box.height, 4 ); } else { dc.DrawRectangle( box ); shapeDc.DrawRectangle( box ); } for( unsigned int ino = 0; ino < m_sublite_index_array.GetCount(); ino++ ) { if( m_sublite_index_array.Item( ino ) == key_db_index ) { // chart is in the sublite list dc.SetBrush( dc.GetBackground() ); 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 for( unsigned int ino = 0; ino < m_noshow_index_array.GetCount(); ino++ ) { if( m_noshow_index_array.Item( ino ) == key_db_index ) { // chart is in the noshow list if( m_pInVizIconBmp && m_pInVizIconBmp->IsOk() ) dc.DrawBitmap( ConvertTo24Bit( dc.GetBrush().GetColour(), *m_pInVizIconBmp ), box.x + 4, box.y + 3, false ); break; } } // Look in the current skew array for this index for( unsigned int ino = 0; ino < m_skew_index_array.GetCount(); ino++ ) { if( m_skew_index_array.Item( ino ) == key_db_index ) { // chart is in the list if( 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 ); break; } } // Look in the current tmerc array for this index for( unsigned int ino = 0; ino < m_tmerc_index_array.GetCount(); ino++ ) { if( m_tmerc_index_array.Item( ino ) == key_db_index ) { // chart is in the list if( 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 ); break; } } // Look in the current poly array for this index for( unsigned int ino = 0; ino < m_poly_index_array.GetCount(); ino++ ) { if( m_poly_index_array.Item( ino ) == key_db_index ) { // chart is in the list if( 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 ); break; } } } #ifndef __WXMAC__ if( style->chartStatusWindowTransparent ) ((wxDialog*) GetParent())->SetShape( wxRegion( shape, *wxBLACK, 0 ) ); } else { // SetShape() with a completely empty shape doesn't work, and leaving the shape // but hiding the window causes artifacts when dragging in GL mode on MSW. // The best solution found so far is to show just a single pixel, this is less // disturbing than flashing piano keys when dragging. (wxWidgets 2.8) if( style->chartStatusWindowTransparent ) ((wxDialog*) GetParent())->SetShape( wxRegion( wxRect(0,0,1,1) ) ); } #else }