#18138 closed defect (fixed)

wxToolbar managed by wxAui: the bottom edge of the toolbar are not drawn correctly

Reported by: ollydbg Owned by: VZ <vz-github@…>
Priority: normal Milestone:
Component: wxAui Version: 3.1.1
Keywords: toolbar Cc: asmwarrior@…
Blocked By: Blocking:
Patch: no

Description

Under Windows, with wxWidgets 3.0+, I found the that wxToolbar was not shown correct if the toolbar button image size is smaller than the standard size.

Here is the test code

#include <wx/wx.h>
#include <wx/frame.h>
#include <wx/artprov.h>
#include <wx/aui/aui.h>

/*---------------------------------------------------------------------------------------------------------*/
// HEADER

enum
{
	ID_ShowNormal = wxID_HIGHEST,
    ID_ShowBug,
    ID_ShowWorkaround,
};

class MyApp : public wxApp
{
public:
	bool OnInit();
};

class MyFrame : public wxFrame
{
public:
	MyFrame(wxFrame *parent,
		wxWindowID id = wxID_ANY,
		const wxString& title = _T("wxToolBar Bug Demo"),
		const wxPoint& pos = wxDefaultPosition,
		const wxSize& size = wxDefaultSize,
		long style = wxDEFAULT_FRAME_STYLE|wxCLIP_CHILDREN|wxNO_FULL_REPAINT_ON_RESIZE);
	virtual ~MyFrame();

	wxToolBar *m_tb;
	wxToolBar *m_tb2;
    wxToolBar *m_tb3;
	wxAuiManager m_mngr;

	DECLARE_EVENT_TABLE()
};

/*---------------------------------------------------------------------------------------------------------*/
// SOURCE

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
	MyFrame* frame = new MyFrame((wxFrame *) NULL, wxID_ANY,
		_T("wxToolbar Bug Demo"),
		wxPoint(100, 100), wxSize(550, 300));

	frame->Show(true);

	wxInitAllImageHandlers();

	SetTopWindow(frame);

	return true;
}

BEGIN_EVENT_TABLE(MyFrame,wxFrame)
END_EVENT_TABLE()

MyFrame::MyFrame(wxFrame* parent,
				 wxWindowID id,
				 const wxString& title,
				 const wxPoint& pos,
				 const wxSize& size,
				 long style)
				 : wxFrame(parent, id, title, pos, size, style)
				 ,m_tb(0), m_tb2(0),m_tb3(0)
{
	m_mngr.SetManagedWindow(this);
	wxMenu *menuFile=new wxMenu;
	menuFile->Append(ID_ShowNormal,wxT("Show Normal"));
	menuFile->Append(ID_ShowBug,wxT("Show Bug"));
	menuFile->Append(ID_ShowWorkaround,wxT("Show Workaround"));
	wxMenuBar *menuBar = new wxMenuBar();
	menuBar->Append(menuFile,wxT("Mode"));
	SetMenuBar(menuBar);
	//m_mngr.Update();



	m_tb=new wxToolBar(this,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxTB_FLAT|wxTB_NODIVIDER);
	//m_tb->AddTool(wxID_ANY,wxT("tool1"),wxArtProvider::GetBitmap(wxART_FILE_OPEN,wxART_TOOLBAR));
	//m_tb->AddTool(wxID_ANY,wxT("tool2"),wxArtProvider::GetBitmap(wxART_FILE_SAVE,wxART_TOOLBAR));
    m_tb->AddTool(wxID_ANY,wxT("tool1"),wxBitmap(16,15));
	m_tb->AddTool(wxID_ANY,wxT("tool2"),wxBitmap(16,15));

	m_tb->Realize();
	wxAuiPaneInfo pi = wxAuiPaneInfo()	.Name(wxT("toolbar"))
										.Caption(wxT("toolbar"))
										.ToolbarPane()
										.Floatable()
										.Direction(wxAUI_DOCK_TOP) // see also ticket #9722
										.LeftDockable(false)
										.RightDockable(false);
	m_mngr.AddPane(m_tb,pi);

    m_tb2=new wxToolBar(this,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxTB_FLAT|wxTB_NODIVIDER);
	//m_tb2->AddTool(wxID_ANY,wxT("tool1"),wxArtProvider::GetBitmap(wxART_FILE_OPEN,wxART_TOOLBAR));
	//m_tb2->AddTool(wxID_ANY,wxT("tool2"),wxArtProvider::GetBitmap(wxART_FILE_SAVE,wxART_TOOLBAR));
	m_tb2->AddTool(wxID_ANY,wxT("tool1"),wxBitmap(16,15));
	m_tb2->AddTool(wxID_ANY,wxT("tool2"),wxBitmap(16,15));
	m_tb2->Realize();
	wxAuiPaneInfo pi2 = wxAuiPaneInfo()	.Name(wxT("toolbar2"))
										.Caption(wxT("toolbar2"))
										.ToolbarPane()
										.Floatable()
										.Direction(wxAUI_DOCK_TOP) // see also ticket #9722
										.LeftDockable(false)
										.RightDockable(false);
	m_mngr.AddPane(m_tb2,pi2);


    m_tb3=new wxToolBar(this,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxTB_FLAT|wxTB_NODIVIDER);
	//m_tb3->AddTool(wxID_ANY,wxT("tool1"),wxArtProvider::GetBitmap(wxART_FILE_OPEN,wxART_TOOLBAR));
	//m_tb3->AddTool(wxID_ANY,wxT("tool2"),wxArtProvider::GetBitmap(wxART_FILE_SAVE,wxART_TOOLBAR));
	m_tb3->AddTool(wxID_ANY,wxT("tool1"),wxBitmap(16,15));
	m_tb3->AddTool(wxID_ANY,wxT("tool2"),wxBitmap(16,15));
	wxChoice* choice = new wxChoice(m_tb3, wxID_ANY);
    choice->AppendString(wxT("One choice"));
    choice->AppendString(wxT("Another choice"));
    m_tb3->AddControl(choice);
	m_tb3->Realize();
	wxAuiPaneInfo pi3 = wxAuiPaneInfo()	.Name(wxT("toolbar3"))
										.Caption(wxT("toolbar3"))
										.ToolbarPane()
										.Floatable()
										.Direction(wxAUI_DOCK_TOP) // see also ticket #9722
										.LeftDockable(false)
										.RightDockable(false);
	m_mngr.AddPane(m_tb3,pi3);

	m_mngr.Update();
}

MyFrame::~MyFrame()
{
	m_mngr.UnInit();
}

When the toolbar button is small, such as "16*15", then you drag the toolbar to move horizontally, you see the screen shot as attachment.

If you use the standard toolbar size, such as the commented line, you don't have such issue.

I have already report this issue under wx user maillist here several years ago but with no response there:
wxToolbar managed by wxAui: why the bottom edge of the toolbar are not drawn correctly - Google Groups

Also, I first found this issue when I build Code::Blocks against wx3.0, see my report on the C::B forum here:toolbar bottom edge is not shown corectly under C::B build with wx git master

Attachments (1)

wxtoolbar_bug.png download (31.6 KB) - added by ollydbg 18 months ago.

Download all attachments as: .zip

Change History (8)

Changed 18 months ago by ollydbg

comment:1 Changed 18 months ago by ollydbg

  • Cc asmwarrior@… added

I have upload a screen shot of the sample program to demonstrate this bug.

comment:2 Changed 18 months ago by vadz

  • Status changed from new to confirmed

FWIW I see this under MSW but not with wxGTK3. I don't have time to debug this further and if the problem can be worked around by using bigger images, it's probably better to just do this for now.

Of course, if you can debug what's going on here, it would be very welcome, as usual.

comment:3 Changed 18 months ago by ollydbg

  • Cc asmwarrior@… removed

Hi, VZ, I debugged this issue about two years ago, see my report here:

[wxToolbar managed by wxAui: why the bottom edge of the toolbar are not drawn correctly - Google Groups](https://groups.google.com/forum/#!topic/wx-users/2riQ9W_vcOs)

I even located which commit caused this issue. Can you have a look at my thread on the wx-user?

Thanks.

comment:4 Changed 18 months ago by MaartenB

Hi, I found a fix/workaround by modifying wxToolBar::HandleSize. I haven't tested extensively for side-effects in the toolbar sample.

bool wxToolBar::HandleSize(WXWPARAM WXUNUSED(wParam), WXLPARAM lParam)
{
    wxSize s(DoGetBestSize());
    int w = s.GetWidth();
    int h = s.GetHeight();

    int w2 = LOWORD(lParam);
    int h2 = HIWORD(lParam);

    if (w2 > w)
        w = w2;
    if (h2 > h)
        h = h2;

    if ( MAKELPARAM(w, h) != lParam )
    {
        // size really changed
        SetSize(w, h);
    }

    UpdateStretchableSpacersSize();

    // message processed
    return true;
}

Update:
First of all, this doesn't work when moving the toolbar to a different size of the screen (without AUI). Second, it should probably be fixed in AUI code, not in wxToolbar code. E.g. repainting/refreshing the background of the AUI ToolbarPane.

Last edited 18 months ago by MaartenB (previous) (diff)

comment:5 follow-up: Changed 18 months ago by MaartenB

The patch below fixes the issue for me.
It uses the background colour from the ArtProvider, without it will be the default dark-gray wxFrame colour.
(try m_mngr.GetArtProvider()->SetColor(wxAUI_DOCKART_BACKGROUND_COLOUR, *wxRED); to see the effect).

Please confirm it works, and wether it should be _WIN32 only (mac already uses Clear() in OnRender).

@@ -3937,6 +3937,8 @@ void wxAuiManager::Repaint(wxDC* dc)
 void wxAuiManager::OnPaint(wxPaintEvent& WXUNUSED(event))
 {
     wxPaintDC dc(m_frame);
+    dc.SetBackground(GetArtProvider()->GetColor(wxAUI_DOCKART_BACKGROUND_COLOUR));
+    dc.Clear();
     Repaint(&dc);
 }

comment:6 in reply to: ↑ 5 Changed 18 months ago by ollydbg

  • Cc asmwarrior@… added

Replying to MaartenB:

The patch below fixes the issue for me.
It uses the background colour from the ArtProvider, without it will be the default dark-gray wxFrame colour.
(try m_mngr.GetArtProvider()->SetColor(wxAUI_DOCKART_BACKGROUND_COLOUR, *wxRED); to see the effect).

Please confirm it works, and wether it should be _WIN32 only (mac already uses Clear() in OnRender).

@@ -3937,6 +3937,8 @@ void wxAuiManager::Repaint(wxDC* dc)
 void wxAuiManager::OnPaint(wxPaintEvent& WXUNUSED(event))
 {
     wxPaintDC dc(m_frame);
+    dc.SetBackground(GetArtProvider()->GetColor(wxAUI_DOCKART_BACKGROUND_COLOUR));
+    dc.Clear();
     Repaint(&dc);
 }

Hi, MaartenB, thanks for the patch.
I can confirm it fix my reported issue. (I'm testing under wx3.1.1 under Windows 7)

comment:7 Changed 17 months ago by VZ <vz-github@…>

  • Owner set to VZ <vz-github@…>
  • Resolution set to fixed
  • Status changed from confirmed to closed

In ce903da79/git-wxWidgets:

Fix glitch in AUI frame with standard wxToolbar

When the height of the AUI toolbar pane is higher than the wxToolbar, the extra
area shows a glitch. This happens because the paint handler never draws on this
area. Clearing the DC of the frame with the AUI background colour fixes this.

See https://github.com/wxWidgets/wxWidgets/pull/829

Closes #18138

Note: See TracTickets for help on using tickets.