Как установить фон wxAuiToolBar?

На wxWidgets3.0.0 я хочу изменить фон wxAuiToolBar, поэтому я создаю wxAuiToolBar, используя стиль wxAUI_TB_PLAIN_BACKGROUND. Однако не достигли ожидаемых результатов. Пример:

// create some toolbars
wxAuiToolBar* tb1 = new wxAuiToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_PLAIN_BACKGROUND);
tb1->SetToolBitmapSize(wxSize(48,48));
tb1->AddTool(ID_SampleItem+1, wxT("Test"), wxArtProvider::GetBitmap(wxART_ERROR));
tb1->AddSeparator();
tb1->AddTool(ID_SampleItem+2, wxT("Test"), wxArtProvider::GetBitmap(wxART_QUESTION));
tb1->AddTool(ID_SampleItem+3, wxT("Test"), wxArtProvider::GetBitmap(wxART_INFORMATION));
tb1->AddTool(ID_SampleItem+4, wxT("Test"), wxArtProvider::GetBitmap(wxART_WARNING));
tb1->AddTool(ID_SampleItem+5, wxT("Test"), wxArtProvider::GetBitmap(wxART_MISSING_IMAGE));
tb1->SetCustomOverflowItems(prepend_items, append_items);
tb1->Realize();

1 ответ

Первый, wxAUI_TB_PLAIN_BACKGROUND не делает ничего другого, кроме просто изменения того, будет ли фон нарисован с каким-то причудливым градиентом или, ну, в общем, простым. Это не имеет ничего общего с прозрачностью, несмотря на то, что написано в документации.

Как можно сделать панель инструментов AUI нарисованной иначе? Используйте пользовательский "инструмент провайдера панели инструментов". wxAuiToolBar есть метод SetArtProvider(), который позволяет вам установить экземпляр любого класса, производного от wxAuiToolBarArt, Как вы можете видеть из его документации, у него есть много методов для рисования различных частей панели инструментов. Вы можете создать собственный поставщик искусства и делать что-то по-другому.

Это не совсем то, что вы хотите, вы хотите изменить только то, как окрашивается фон (чтобы не рисовать его вообще и оставить прозрачным). Так что создайте собственный класс, который наследует от wxAuiDefaultToolBarArt, который используется по умолчанию, когда вы не устанавливаете пользовательский художественный поставщик и переопределяете только необходимый метод DrawPlainBackground() (или же DrawBackground() - какая из этих функций вызывается, это единственное, на что может повлиять "простой фоновый флаг"):

class MyToolBarArt : public wxAuiDefaultToolBarArt {
  public:
    virtual wxAuiToolBarArt* Clone()
    {
        return new MyToolBarArt(*this);
    }

    virtual void DrawPlainBackground(wxDC& dc, wxWindow* wnd, const wxRect& rect)
    {
        // TODO
    }
};

...

tb1->SetArtProvider(new MyToolBarArtProvider);

Если вы попробуете это так, вы заметите, что серый фон больше не окрашен - но элемент управления имеет черный фон вместо прозрачного! Черный фон по умолчанию остается там. Нам нужно использовать хитрость - чтобы сделать фон прозрачным, мы просим родительское окно нарисовать его содержимое для нас, а затем позволить панели инструментов продолжить работу с остальной частью чертежа.

Теперь это то, где это становится безобразным. Я не смог найти никакого способа в wxWidgets попросить родительское окно нарисовать себя в пользовательском DC. Так что вам нужно будет реализовать это самостоятельно.

Если родительский фон состоит из какого-то простого цвета, вы можете просто закрасить прямоугольник тем же цветом. Если фон, например, какое-то изображение, вы можете нарисовать его там же. Точно так же с еще более сложным фоном.

В более поздних случаях, вероятно, лучше всего выполнить это с помощью пользовательского метода в родительском окне (которое в любом случае знает, как оно себя рисует):

class MyParentWindowWithBackground : public wxWindow ... {
  ...
  public:
    void DrawBackground(wxDC& dc, wxRect& rect)
    {
        // TODO: Perform the drawing here...
    }
};

...

    virtual void DrawPlainBackground(wxDC& dc, wxWindow* wnd, const wxRect& rect)
    {
        wxWindow* parent = wnd->GetParent();
        if (parent)
            static_cast<MyParentWindowWithBackground*>(parent)->DrawBackground(dc, rect);
    }
Другие вопросы по тегам