From 001a50bf149b781632e2e25e37d33d4db2146e5c Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 6 May 2020 18:55:07 +0100 Subject: [PATCH] Moved PANEL_COLOR_SETTINGS from buttons to swatches. This allows us to correctly display non-100%-opacity colors (ie: over the correct background color). --- common/dialogs/panel_color_settings.cpp | 114 +++++++----------- common/dialogs/panel_color_settings.h | 13 +- common/settings/color_settings.cpp | 17 ++- common/widgets/color_swatch.cpp | 10 +- .../dialogs/panel_eeschema_color_settings.cpp | 16 +-- .../dialogs/panel_eeschema_color_settings.h | 2 +- include/widgets/color_swatch.h | 2 +- .../dialogs/panel_modedit_color_settings.cpp | 8 +- pcbnew/dialogs/panel_modedit_color_settings.h | 2 +- .../dialogs/panel_pcbnew_color_settings.cpp | 8 +- pcbnew/dialogs/panel_pcbnew_color_settings.h | 2 +- pcbnew/layer_widget.cpp | 12 +- 12 files changed, 91 insertions(+), 115 deletions(-) diff --git a/common/dialogs/panel_color_settings.cpp b/common/dialogs/panel_color_settings.cpp index aa81de0b40..73d799518a 100644 --- a/common/dialogs/panel_color_settings.cpp +++ b/common/dialogs/panel_color_settings.cpp @@ -29,12 +29,9 @@ #include #include #include +#include -// Width and height of every (color-displaying / bitmap) button in dialog units -const wxSize BUTTON_SIZE( 24, 12 ); -const wxSize BUTTON_BORDER( 4, 4 ); - // Button ID starting point constexpr int FIRST_BUTTON_ID = 1800; @@ -42,7 +39,7 @@ constexpr int FIRST_BUTTON_ID = 1800; PANEL_COLOR_SETTINGS::PANEL_COLOR_SETTINGS( wxWindow* aParent ) : PANEL_COLOR_SETTINGS_BASE( aParent ), m_currentSettings( nullptr ), - m_buttons(), + m_swatches(), m_copied( COLOR4D::UNSPECIFIED ), m_validLayers(), m_colorNamespace() @@ -53,8 +50,6 @@ PANEL_COLOR_SETTINGS::PANEL_COLOR_SETTINGS( wxWindow* aParent ) : // Simple border is too dark on OSX m_colorsListWindow->SetWindowStyle( wxBORDER_SUNKEN|wxVSCROLL ); #endif - - m_buttonSizePx = ConvertDialogToPixels( BUTTON_SIZE ); } @@ -70,15 +65,15 @@ void PANEL_COLOR_SETTINGS::OnBtnResetClicked( wxCommandEvent& event ) if( !m_currentSettings ) return; - for( const auto& pair : m_buttons ) + for( const std::pair& pair : m_swatches ) { - int layer = pair.first; - wxBitmapButton* button = pair.second; + int layer = pair.first; + COLOR_SWATCH* button = pair.second; COLOR4D defaultColor = m_currentSettings->GetDefaultColor( layer ); m_currentSettings->SetColor( layer, defaultColor ); - drawButton( button, defaultColor ); + button->SetSwatchColor( defaultColor, false ); } } @@ -149,9 +144,12 @@ void PANEL_COLOR_SETTINGS::OnThemeChanged( wxCommandEvent& event ) *m_currentSettings = *selected; onNewThemeSelected(); - for( auto pair : m_buttons ) + COLOR4D background = m_currentSettings->GetColor( m_backgroundLayer ); + + for( std::pair pair : m_swatches ) { - drawButton( pair.second, m_currentSettings->GetColor( pair.first ) ); + pair.second->SetSwatchBackground( background ); + pair.second->SetSwatchColor( m_currentSettings->GetColor( pair.first ), false ); if( pair.first == LAYER_SHEET || pair.first == LAYER_SHEET_BACKGROUND ) pair.second->Show( selected->GetOverrideSchItemColors() ); @@ -189,44 +187,33 @@ void PANEL_COLOR_SETTINGS::createThemeList( const wxString& aCurrent ) } -void PANEL_COLOR_SETTINGS::createButton( int aLayer, const KIGFX::COLOR4D& aColor, - const wxString& aName ) +void PANEL_COLOR_SETTINGS::createSwatch( int aLayer, const wxString& aName ) { - const wxSize border = ConvertDialogToPixels( BUTTON_BORDER ); - wxStaticText* label = new wxStaticText( m_colorsListWindow, wxID_ANY, aName ); - wxMemoryDC iconDC; - wxBitmap bitmap( m_buttonSizePx ); + void* clientData = m_cbTheme->GetClientData( m_cbTheme->GetSelection() ); + COLOR_SETTINGS* selected = static_cast( clientData ); + int id = FIRST_BUTTON_ID + aLayer; + COLOR4D defaultColor = selected->GetDefaultColor( aLayer ); + COLOR4D color = m_currentSettings->GetColor( aLayer ); + COLOR4D backgroundColor = m_currentSettings->GetColor( m_backgroundLayer ); - iconDC.SelectObject( bitmap ); - iconDC.SetPen( *wxBLACK_PEN ); - - wxBrush brush; - brush.SetColour( aColor.ToColour() ); - brush.SetStyle( wxBRUSHSTYLE_SOLID ); - iconDC.SetBrush( brush ); - iconDC.DrawRectangle( 0, 0, m_buttonSizePx.x, m_buttonSizePx.y ); - - int id = FIRST_BUTTON_ID + aLayer; - - auto button = new wxBitmapButton( m_colorsListWindow, id, bitmap, wxDefaultPosition, - m_buttonSizePx + border + wxSize( 1, 1 ) ); - button->SetToolTip( _( "Edit color (right click for options)" ) ); + COLOR_SWATCH* swatch = new COLOR_SWATCH( m_colorsListWindow, color, id, backgroundColor, + defaultColor, true ); + swatch->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); m_colorsGridSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxLEFT, 5 ); - m_colorsGridSizer->Add( button, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5 ); + m_colorsGridSizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3 ); - m_labels[aLayer] = label; - m_buttons[aLayer] = button; + m_labels[aLayer] = label; + m_swatches[aLayer] = swatch; - button->Bind( wxEVT_RIGHT_DOWN, + swatch->Bind( wxEVT_RIGHT_DOWN, [&, aLayer]( wxMouseEvent& aEvent ) { ShowColorContextMenu( aEvent, aLayer ); } ); - - button->Bind( wxEVT_COMMAND_BUTTON_CLICKED, &PANEL_COLOR_SETTINGS::SetColor, this ); + swatch->Bind( COLOR_SWATCH_CHANGED, &PANEL_COLOR_SETTINGS::OnColorChanged, this ); } @@ -249,7 +236,8 @@ void PANEL_COLOR_SETTINGS::ShowColorContextMenu( wxMouseEvent& aEvent, int aLaye AddMenuItem( &menu, ID_REVERT, _( "Revert to saved color" ), KiBitmap( undo_xpm ) ); menu.Bind( wxEVT_COMMAND_MENU_SELECTED, - [&]( wxCommandEvent& aCmd ) { + [&]( wxCommandEvent& aCmd ) + { switch( aCmd.GetId() ) { case ID_COPY: @@ -273,50 +261,30 @@ void PANEL_COLOR_SETTINGS::ShowColorContextMenu( wxMouseEvent& aEvent, int aLaye } -void PANEL_COLOR_SETTINGS::SetColor( wxCommandEvent& event ) +void PANEL_COLOR_SETTINGS::OnColorChanged( wxCommandEvent& aEvent ) { - auto button = static_cast( event.GetEventObject() ); - auto layer = static_cast( button->GetId() - FIRST_BUTTON_ID ); - - COLOR4D oldColor = m_currentSettings->GetColor( layer ); - COLOR4D newColor = COLOR4D::UNSPECIFIED; - DIALOG_COLOR_PICKER dialog( this, oldColor, false ); - - if( dialog.ShowModal() == wxID_OK ) - newColor = dialog.GetColor(); - - if( newColor == COLOR4D::UNSPECIFIED || oldColor == newColor ) - return; + COLOR_SWATCH* swatch = static_cast( aEvent.GetEventObject() ); + COLOR4D newColor = swatch->GetSwatchColor(); + LAYER_NUM layer = static_cast( swatch->GetId() - FIRST_BUTTON_ID ); updateColor( layer, newColor ); } -void PANEL_COLOR_SETTINGS::drawButton( wxBitmapButton* aButton, const COLOR4D& aColor ) const -{ - wxMemoryDC iconDC; - - wxBitmap bitmap = aButton->GetBitmapLabel(); - iconDC.SelectObject( bitmap ); - iconDC.SetPen( *wxBLACK_PEN ); - - wxBrush brush; - brush.SetColour( aColor.ToColour() ); - brush.SetStyle( wxBRUSHSTYLE_SOLID ); - - iconDC.SetBrush( brush ); - iconDC.DrawRectangle( 0, 0, m_buttonSizePx.x, m_buttonSizePx.y ); - aButton->SetBitmapLabel( bitmap ); - aButton->Refresh(); -} - - void PANEL_COLOR_SETTINGS::updateColor( int aLayer, const KIGFX::COLOR4D& aColor ) { if( m_currentSettings ) m_currentSettings->SetColor( aLayer, aColor ); - drawButton( m_buttons[aLayer], aColor ); + m_swatches[aLayer]->SetSwatchColor( aColor, false ); + + if( aLayer == m_backgroundLayer ) + { + COLOR4D background = m_currentSettings->GetColor( m_backgroundLayer ); + + for( std::pair pair : m_swatches ) + pair.second->SetSwatchBackground( background ); + } onColorChanged(); } diff --git a/common/dialogs/panel_color_settings.h b/common/dialogs/panel_color_settings.h index aede3532f6..cd60f5ff03 100644 --- a/common/dialogs/panel_color_settings.h +++ b/common/dialogs/panel_color_settings.h @@ -26,6 +26,7 @@ class COLOR_SETTINGS; +class COLOR_SWATCH; class PANEL_COLOR_SETTINGS : public PANEL_COLOR_SETTINGS_BASE @@ -51,16 +52,14 @@ protected: void ShowColorContextMenu( wxMouseEvent& aEvent, int aLayer ); - void SetColor( wxCommandEvent& aEvent ); + void OnColorChanged( wxCommandEvent& aEvent ); void createThemeList( const wxString& aCurrent ); - void createButton( int aLayer, const KIGFX::COLOR4D& aColor, const wxString& aName ); + void createSwatch( int aLayer, const wxString& aName ); void updateColor( int aLayer, const KIGFX::COLOR4D& aColor ); - void drawButton( wxBitmapButton* aButton, const KIGFX::COLOR4D& aColor ) const; - virtual bool saveCurrentTheme( bool aValidate ); /** @@ -85,11 +84,8 @@ protected: COLOR_SETTINGS* m_currentSettings; - wxSize m_buttonSizePx; - std::map m_labels; - - std::map m_buttons; + std::map m_swatches; KIGFX::COLOR4D m_copied; @@ -102,6 +98,7 @@ protected: * This list must be filled in the application-specific color settings panel constructors. */ std::vector m_validLayers; + int m_backgroundLayer; /** * A namespace that will be passed to SETTINGS_MANAGER::SaveColorSettings diff --git a/common/settings/color_settings.cpp b/common/settings/color_settings.cpp index f65c09e669..40d540cae0 100644 --- a/common/settings/color_settings.cpp +++ b/common/settings/color_settings.cpp @@ -299,13 +299,18 @@ COLOR4D COLOR_SETTINGS::GetDefaultColor( int aLayer ) { COLOR_MAP_PARAM* p = nullptr; - for( auto param : m_params ) - if( auto cmp = dynamic_cast( param ) ) - if( cmp->GetKey() == aLayer ) - p = cmp; + for( PARAM_BASE* param : m_params ) + { + COLOR_MAP_PARAM* cmp = dynamic_cast( param ); - wxASSERT( p ); - m_defaultColors[aLayer] = p->GetDefault(); + if( cmp && cmp->GetKey() == aLayer ) + p = cmp; + } + + if( p ) + m_defaultColors[aLayer] = p->GetDefault(); + else + m_defaultColors[aLayer] = COLOR4D::UNSPECIFIED; } return m_defaultColors.at( aLayer );; diff --git a/common/widgets/color_swatch.cpp b/common/widgets/color_swatch.cpp index aa78783700..4a3a4e137f 100644 --- a/common/widgets/color_swatch.cpp +++ b/common/widgets/color_swatch.cpp @@ -65,13 +65,16 @@ wxBitmap COLOR_SWATCH::MakeBitmap( COLOR4D aColor, COLOR4D aBackground, wxSize a COLOR_SWATCH::COLOR_SWATCH( wxWindow* aParent, COLOR4D aColor, int aID, COLOR4D aBackground, - const COLOR4D aDefault ) : + const COLOR4D aDefault, bool aForDialog ) : wxPanel( aParent, aID ), m_color( aColor ), m_background( aBackground ), m_default( aDefault ) { - m_size = ConvertDialogToPixels( PALETTE_SWATCH_SIZE_DU ); + if( aForDialog ) + m_size = ConvertDialogToPixels( DIALOG_SWATCH_SIZE_DU ); + else + m_size = ConvertDialogToPixels( PALETTE_SWATCH_SIZE_DU ); auto sizer = new wxBoxSizer( wxHORIZONTAL ); SetSizer( sizer ); @@ -128,7 +131,6 @@ void COLOR_SWATCH::setupEvents() { // forward click to any other listeners, since we don't want them m_swatch->Bind( wxEVT_LEFT_DOWN, &COLOR_SWATCH::rePostEvent, this ); - m_swatch->Bind( wxEVT_RIGHT_DOWN, &COLOR_SWATCH::rePostEvent, this ); // bind the events that trigger the dialog m_swatch->Bind( wxEVT_LEFT_DCLICK, @@ -143,6 +145,8 @@ void COLOR_SWATCH::setupEvents() { GetNewSwatchColor(); } ); + + m_swatch->Bind( wxEVT_RIGHT_DOWN, &COLOR_SWATCH::rePostEvent, this ); } diff --git a/eeschema/dialogs/panel_eeschema_color_settings.cpp b/eeschema/dialogs/panel_eeschema_color_settings.cpp index b918fa900b..66e35f8bf5 100644 --- a/eeschema/dialogs/panel_eeschema_color_settings.cpp +++ b/eeschema/dialogs/panel_eeschema_color_settings.cpp @@ -21,13 +21,11 @@ #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -45,7 +43,7 @@ #include #include #include -#include +#include // Width and height of every (color-displaying / bitmap) button in dialog units const wxSize BUTTON_SIZE( 24, 12 ); @@ -84,7 +82,9 @@ PANEL_EESCHEMA_COLOR_SETTINGS::PANEL_EESCHEMA_COLOR_SETTINGS( SCH_BASE_FRAME* aF for( int id = SCH_LAYER_ID_START; id < SCH_LAYER_ID_END; id++ ) m_validLayers.push_back( id ); - createButtons(); + m_backgroundLayer = LAYER_SCHEMATIC_BACKGROUND; + + createSwatches(); KIGFX::GAL_DISPLAY_OPTIONS options; options.ReadConfig( *common_settings, app_settings->m_Window, this ); @@ -187,7 +187,7 @@ bool PANEL_EESCHEMA_COLOR_SETTINGS::saveCurrentTheme( bool aValidate) } -void PANEL_EESCHEMA_COLOR_SETTINGS::createButtons() +void PANEL_EESCHEMA_COLOR_SETTINGS::createSwatches() { std::vector layers; @@ -201,7 +201,7 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createButtons() } ); for( int layer : layers ) - createButton( layer, m_currentSettings->GetColor( layer ), LayerName( layer ) ); + createSwatch( layer, LayerName( layer ) ); } @@ -389,10 +389,10 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::OnOverrideItemColorsClicked( wxCommandEvent& // If the theme is not overriding individual item colors then don't show them so that // the user doesn't get seduced into thinking they'll have some effect. m_labels[ LAYER_SHEET ]->Show( m_currentSettings->GetOverrideSchItemColors() ); - m_buttons[ LAYER_SHEET ]->Show( m_currentSettings->GetOverrideSchItemColors() ); + m_swatches[ LAYER_SHEET ]->Show( m_currentSettings->GetOverrideSchItemColors() ); m_labels[ LAYER_SHEET_BACKGROUND ]->Show( m_currentSettings->GetOverrideSchItemColors() ); - m_buttons[ LAYER_SHEET_BACKGROUND ]->Show( m_currentSettings->GetOverrideSchItemColors() ); + m_swatches[ LAYER_SHEET_BACKGROUND ]->Show( m_currentSettings->GetOverrideSchItemColors() ); m_colorsGridSizer->Layout(); m_colorsListWindow->Layout(); diff --git a/eeschema/dialogs/panel_eeschema_color_settings.h b/eeschema/dialogs/panel_eeschema_color_settings.h index 72902277c8..9a9b1fc29b 100644 --- a/eeschema/dialogs/panel_eeschema_color_settings.h +++ b/eeschema/dialogs/panel_eeschema_color_settings.h @@ -78,7 +78,7 @@ private: void createPreviewItems(); - void createButtons(); + void createSwatches(); void updatePreview(); diff --git a/include/widgets/color_swatch.h b/include/widgets/color_swatch.h index 6392a26b56..9bb4b7871a 100644 --- a/include/widgets/color_swatch.h +++ b/include/widgets/color_swatch.h @@ -47,7 +47,7 @@ public: * @param aID id to use when sending swatch events */ COLOR_SWATCH( wxWindow* aParent, KIGFX::COLOR4D aColor, int aID, KIGFX::COLOR4D aBackground, - const KIGFX::COLOR4D aDefault = KIGFX::COLOR4D::UNSPECIFIED ); + const KIGFX::COLOR4D aDefault, bool aForDialog ); /** * constructor for wxFormBuilder diff --git a/pcbnew/dialogs/panel_modedit_color_settings.cpp b/pcbnew/dialogs/panel_modedit_color_settings.cpp index cb14415def..3cf504bae8 100644 --- a/pcbnew/dialogs/panel_modedit_color_settings.cpp +++ b/pcbnew/dialogs/panel_modedit_color_settings.cpp @@ -73,9 +73,11 @@ PANEL_MODEDIT_COLOR_SETTINGS::PANEL_MODEDIT_COLOR_SETTINGS( FOOTPRINT_EDIT_FRAME m_validLayers.push_back( id ); } + m_backgroundLayer = LAYER_PCB_BACKGROUND; + m_colorsMainSizer->Insert( 0, 10, 0, 0, wxEXPAND, 5 ); - createButtons(); + createSwatches(); } @@ -111,7 +113,7 @@ bool PANEL_MODEDIT_COLOR_SETTINGS::TransferDataToWindow() } -void PANEL_MODEDIT_COLOR_SETTINGS::createButtons() +void PANEL_MODEDIT_COLOR_SETTINGS::createSwatches() { std::vector layers; @@ -140,6 +142,6 @@ void PANEL_MODEDIT_COLOR_SETTINGS::createButtons() if( board && layer >= PCBNEW_LAYER_ID_START && layer < PCB_LAYER_ID_COUNT ) name = board->GetLayerName( static_cast( layer ) ); - createButton( layer, m_currentSettings->GetColor( layer ), name ); + createSwatch( layer, name ); } } diff --git a/pcbnew/dialogs/panel_modedit_color_settings.h b/pcbnew/dialogs/panel_modedit_color_settings.h index 25b0bf8614..46d0ff03e2 100644 --- a/pcbnew/dialogs/panel_modedit_color_settings.h +++ b/pcbnew/dialogs/panel_modedit_color_settings.h @@ -63,7 +63,7 @@ private: KIGFX::WS_PROXY_VIEW_ITEM* m_ws; - void createButtons(); + void createSwatches(); }; diff --git a/pcbnew/dialogs/panel_pcbnew_color_settings.cpp b/pcbnew/dialogs/panel_pcbnew_color_settings.cpp index 928b583be8..1281d9029b 100644 --- a/pcbnew/dialogs/panel_pcbnew_color_settings.cpp +++ b/pcbnew/dialogs/panel_pcbnew_color_settings.cpp @@ -73,9 +73,11 @@ PANEL_PCBNEW_COLOR_SETTINGS::PANEL_PCBNEW_COLOR_SETTINGS( PCB_EDIT_FRAME* aFrame m_validLayers.push_back( id ); } + m_backgroundLayer = LAYER_PCB_BACKGROUND; + m_colorsMainSizer->Insert( 0, 10, 0, 0, wxEXPAND, 5 ); - createButtons(); + createSwatches(); } @@ -112,7 +114,7 @@ bool PANEL_PCBNEW_COLOR_SETTINGS::TransferDataToWindow() } -void PANEL_PCBNEW_COLOR_SETTINGS::createButtons() +void PANEL_PCBNEW_COLOR_SETTINGS::createSwatches() { std::vector layers; @@ -141,6 +143,6 @@ void PANEL_PCBNEW_COLOR_SETTINGS::createButtons() if( board && layer >= PCBNEW_LAYER_ID_START && layer < PCB_LAYER_ID_COUNT ) name = board->GetLayerName( static_cast( layer ) ); - createButton( layer, m_currentSettings->GetColor( layer ), name ); + createSwatch( layer, name ); } } diff --git a/pcbnew/dialogs/panel_pcbnew_color_settings.h b/pcbnew/dialogs/panel_pcbnew_color_settings.h index 7de8355a04..f23d159a1a 100644 --- a/pcbnew/dialogs/panel_pcbnew_color_settings.h +++ b/pcbnew/dialogs/panel_pcbnew_color_settings.h @@ -63,7 +63,7 @@ private: KIGFX::WS_PROXY_VIEW_ITEM* m_ws; - void createButtons(); + void createSwatches(); }; diff --git a/pcbnew/layer_widget.cpp b/pcbnew/layer_widget.cpp index b5b3b23e3b..40fb7fc854 100644 --- a/pcbnew/layer_widget.cpp +++ b/pcbnew/layer_widget.cpp @@ -148,11 +148,9 @@ void LAYER_WIDGET::OnRightDownLayer( wxMouseEvent& aEvent, COLOR_SWATCH* aColorS void LAYER_WIDGET::OnLayerSwatchChanged( wxCommandEvent& aEvent ) { - auto eventSource = static_cast( aEvent.GetEventObject() ); - - COLOR4D newColor = eventSource->GetSwatchColor(); - - LAYER_NUM layer = getDecodedId( eventSource->GetId() ); + COLOR_SWATCH* eventSource = static_cast( aEvent.GetEventObject() ); + COLOR4D newColor = eventSource->GetSwatchColor(); + LAYER_NUM layer = getDecodedId( eventSource->GetId() ); // tell the client code. OnLayerColorChange( layer, newColor ); @@ -333,7 +331,7 @@ void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec ) col = COLUMN_COLORBM; auto bmb = new COLOR_SWATCH( m_LayerScrolledWindow, aSpec.color, encodeId( col, aSpec.id ), - getBackgroundLayerColor(), aSpec.defaultColor ); + getBackgroundLayerColor(), aSpec.defaultColor, false ); bmb->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this ); bmb->Bind( COLOR_SWATCH_CHANGED, &LAYER_WIDGET::OnLayerSwatchChanged, this ); bmb->SetToolTip( _("Left double click or middle click for color change, right click for menu" ) ); @@ -433,7 +431,7 @@ void LAYER_WIDGET::insertRenderRow( int aRow, const ROW& aSpec ) if( aSpec.color != COLOR4D::UNSPECIFIED ) { auto bmb = new COLOR_SWATCH( m_RenderScrolledWindow, aSpec.color, encodeId( col, aSpec.id ), - getBackgroundLayerColor(), aSpec.defaultColor ); + getBackgroundLayerColor(), aSpec.defaultColor, false ); bmb->Bind( COLOR_SWATCH_CHANGED, &LAYER_WIDGET::OnRenderSwatchChanged, this ); bmb->SetToolTip( _( "Left double click or middle click for color change" ) ); m_RenderFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags );