Revision: 0a555f3c833ab94c9ee3f9250778b113894e14e0
Author: Artur Wieczorek <artwik@wp.pl>
Date: 2016-2-13 3:06:47
Message:
Fix ToolsVersion value in minimal sample project file (VS 2010+).
Since minimal.vcxproj file is shared by VS 2010-15 solution files, ToolsVersion value should be set to the value supported by all VS versions since 2010 to avoid warning messages like "Project file contains ToolsVersion="14.0", which is not supported by this version of MSBuild.".
----
Modified: samples/minimal/minimal.vcxproj
<?xml version="1.0" encoding="utf-8" ?>
<resource xmlns="http://www.wxwidgets.org/wxxrc" version="2.5.3.0">
<object class="wxToolBarAddOn" name="compiler_toolbar">
<object class="tool" name="idCompilerMenuCompile">
<tooltip>Build</tooltip>
<longhelp>Build the active project</longhelp>
<bitmap>images/compile.png</bitmap>
</object>
<object class="tool" name="idCompilerMenuRun">
<tooltip>Run</tooltip>
<longhelp>Run the active project</longhelp>
<bitmap>images/run.png</bitmap>
</object>
<object class="tool" name="idCompilerMenuCompileAndRun">
<tooltip>Build and run</tooltip>
<longhelp>Build and run the active project</longhelp>
<bitmap>images/compilerun.png</bitmap>
</object>
<object class="tool" name="idCompilerMenuRebuild">
<tooltip>Rebuild</tooltip>
<longhelp>Rebuild all modules in the active project</longhelp>
<bitmap>images/rebuild.png</bitmap>
</object>
<object class="tool" name="idCompilerMenuKillProcess">
<tooltip>Abort</tooltip>
<longhelp>Abort the running build process</longhelp>
<bitmap>images/stop.png</bitmap>
<disabled>1</disabled>
</object>
<object class="wxChoice" name="idToolTarget">
<content/>
<size>136,-1</size>
<tooltip>Build target</tooltip>
<longhelp>Select the current build target</longhelp>
</object>
</object>
</resource>
class wxXmlResourceHandler;
class DLLIMPORT wxToolBarAddOnXmlHandler : public wxXmlResourceHandler
{
public:
wxToolBarAddOnXmlHandler();
virtual wxObject *DoCreateResource();
virtual bool CanHandle(wxXmlNode *node);
protected:
bool m_isInside;
bool m_isAddon;
wxToolBar *m_toolbar;
wxBitmap GetCenteredBitmap(const wxString& param = wxT("bitmap"),
const wxArtClient& defaultArtClient = wxART_OTHER,
wxSize size = wxDefaultSize);
};
#include <wx/xml/xml.h>
/////////////////////////////////////////////////////////////////////////////
// Name: xh_toolb.cpp
// Purpose: XRC resource for wxBoxSizer
// Author: Vaclav Slavik
// Created: 2000/08/11
// RCS-ID: $Id$
// Copyright: (c) 2000 Vaclav Slavik
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// Modified by Ricardo Garcia for Code::Blocks
// Comment: Things would've been much easier if field m_isInside had been
// protected instead of private! >:(
/////////////////////////////////////////////////////////////////////////////
wxToolBarAddOnXmlHandler::wxToolBarAddOnXmlHandler()
: wxXmlResourceHandler(), m_isInside(FALSE), m_isAddon(false), m_toolbar(NULL)
{
XRC_ADD_STYLE(wxTB_FLAT);
XRC_ADD_STYLE(wxTB_DOCKABLE);
XRC_ADD_STYLE(wxTB_VERTICAL);
XRC_ADD_STYLE(wxTB_HORIZONTAL);
XRC_ADD_STYLE(wxTB_3DBUTTONS);
XRC_ADD_STYLE(wxTB_TEXT);
XRC_ADD_STYLE(wxTB_NOICONS);
XRC_ADD_STYLE(wxTB_NODIVIDER);
XRC_ADD_STYLE(wxTB_NOALIGN);
}
wxBitmap wxToolBarAddOnXmlHandler::GetCenteredBitmap(const wxString& param,
const wxArtClient& defaultArtClient, wxSize size)
{
wxBitmap bitmap = GetBitmap(param, defaultArtClient, wxDefaultSize);
if (!bitmap.Ok()) // == wxNullBitmap
return bitmap;
int bw = bitmap.GetWidth();
int bh = bitmap.GetHeight();
if (size == wxSize(bw, bh))
return bitmap;
wxImage image = bitmap.ConvertToImage();
int w = size.GetWidth();
int h = size.GetHeight();
int x = (w - bw) / 2;
int y = (h - bh) / 2;
if (image.HasAlpha()) // Resize doesn't handle Alpha... :-(
{
const unsigned char *data = image.GetData();
const unsigned char *alpha = image.GetAlpha();
unsigned char *rgb = (unsigned char *) calloc(w * h, 3);
unsigned char *a = (unsigned char *) calloc(w * h, 1);
// copy Data/Alpha from smaller bitmap to larger bitmap
for (int row = 0; row < bh; row++)
{
memcpy(rgb + ((row + y) * w + x) * 3, data + (row * bw) * 3, bw * 3);
memcpy(a + ((row + y) * w + x), alpha + (row * bw), bw);
}
image = wxImage(w, h, rgb, a);
}
else
image.Resize(size, wxPoint(x,y));
return wxBitmap(image);
}
wxObject *wxToolBarAddOnXmlHandler::DoCreateResource()
{
wxToolBar* toolbar=NULL;
if (m_class == _T("tool"))
{
wxCHECK_MSG(m_toolbar, NULL, _("Incorrect syntax of XRC resource: tool not within a toolbar!"));
wxSize bitmapSize = m_toolbar->GetToolBitmapSize();
if (GetPosition() != wxDefaultPosition)
{
m_toolbar->AddTool(GetID(),
#if wxCHECK_VERSION(3, 0, 0)
wxEmptyString,
#endif
GetCenteredBitmap(_T("bitmap"), wxART_TOOLBAR, bitmapSize),
GetCenteredBitmap(_T("bitmap2"), wxART_TOOLBAR, bitmapSize),
#if !wxCHECK_VERSION(3, 0, 0)
GetBool(_T("toggle")),
GetPosition().x,
GetPosition().y,
NULL,
#else
wxITEM_NORMAL,
#endif
GetText(_T("tooltip")),
GetText(_T("longhelp")));
if (GetBool(_T("disabled")))
{
m_toolbar->Realize();
m_toolbar->EnableTool(GetID(),false);
}
}
else
{
wxItemKind kind = wxITEM_NORMAL;
if (GetBool(_T("radio")))
kind = wxITEM_RADIO;
if (GetBool(_T("toggle")))
{
wxASSERT_MSG( kind == wxITEM_NORMAL,
_("can't have both toggleable and radion button at once") );
kind = wxITEM_CHECK;
}
m_toolbar->AddTool(GetID(),
GetText(_T("label")),
GetCenteredBitmap(_T("bitmap"), wxART_TOOLBAR, bitmapSize),
GetCenteredBitmap(_T("bitmap2"), wxART_TOOLBAR, bitmapSize),
kind,
GetText(_T("tooltip")),
GetText(_T("longhelp")));
if (GetBool(_T("disabled")))
{
m_toolbar->Realize();
m_toolbar->EnableTool(GetID(),false);
}
}
return m_toolbar; // must return non-NULL
}
else if (m_class == _T("separator"))
{
wxCHECK_MSG(m_toolbar, NULL, _("Incorrect syntax of XRC resource: separator not within a toolbar!"));
m_toolbar->AddSeparator();
return m_toolbar; // must return non-NULL
}
else /*<object class="wxToolBar">*/
{
m_isAddon=(m_class == _T("wxToolBarAddOn"));
if(m_isAddon)
{ // special case: Only add items to toolbar
toolbar=(wxToolBar*)m_instance;
// XRC_MAKE_INSTANCE(toolbar, wxToolBar);
}
else
{
int style = GetStyle(_T("style"), wxNO_BORDER | wxTB_HORIZONTAL);
#ifdef __WXMSW__
if (!(style & wxNO_BORDER)) style |= wxNO_BORDER;
#endif
// XRC_MAKE_INSTANCE(toolbar, wxToolBar)
if (m_instance)
toolbar = wxStaticCast(m_instance, wxToolBar);
if (!toolbar)
toolbar = new wxToolBar;
toolbar->Create(m_parentAsWindow,
GetID(),
GetPosition(),
GetSize(),
style,
GetName());
wxSize bmpsize = GetSize(_T("bitmapsize"));
if (!(bmpsize == wxDefaultSize))
toolbar->SetToolBitmapSize(bmpsize);
wxSize margins = GetSize(_T("margins"));
if (!(margins == wxDefaultSize))
toolbar->SetMargins(margins.x, margins.y);
long packing = GetLong(_T("packing"), -1);
if (packing != -1)
toolbar->SetToolPacking(packing);
long separation = GetLong(_T("separation"), -1);
if (separation != -1)
toolbar->SetToolSeparation(separation);
}
wxXmlNode *children_node = GetParamNode(_T("object"));
if (!children_node)
children_node = GetParamNode(_T("object_ref"));
if (children_node == NULL) return toolbar;
m_isInside = TRUE;
m_toolbar = toolbar;
wxXmlNode *n = children_node;
while (n)
{
if ((n->GetType() == wxXML_ELEMENT_NODE) &&
(n->GetName() == _T("object") || n->GetName() == _T("object_ref")))
{
wxObject *created = CreateResFromNode(n, toolbar, NULL);
wxControl *control = wxDynamicCast(created, wxControl);
if (!IsOfClass(n, _T("tool")) &&
!IsOfClass(n, _T("separator")) &&
control != NULL &&
control != toolbar)
{
//Manager::Get()->GetLogManager()->DebugLog(F(_T("control=%p, parent=%p, toolbar=%p"), control, control->GetParent(), toolbar));
toolbar->AddControl(control);
}
}
n = n->GetNext();
}
toolbar->Realize();
m_isInside = FALSE;
m_toolbar = NULL;
if(!m_isAddon)
{
if (m_parentAsWindow && !GetBool(_T("dontattachtoframe")))
{
wxFrame *parentFrame = wxDynamicCast(m_parent, wxFrame);
if (parentFrame)
parentFrame->SetToolBar(toolbar);
}
}
m_isAddon=false;
return toolbar;
}
}
bool wxToolBarAddOnXmlHandler::CanHandle(wxXmlNode *node)
{
// NOTE (mandrav#1#): wxXmlResourceHandler::IsOfClass() doesn't work in unicode (2.6.2)
// Don't ask why. It does this and doesn't work for our custom handler:
// return node->GetPropVal(wxT("class"), wxEmptyString) == classname;
//
// This works though:
// return node->GetPropVal(wxT("class"), wxEmptyString).Matches(classname);
//
// Don't ask me why... >:-|
#if wxCHECK_VERSION(3, 0, 0)
bool istbar = node->GetAttribute(wxT("class"), wxEmptyString).Matches(_T("wxToolBarAddOn"));
bool istool = node->GetAttribute(wxT("class"), wxEmptyString).Matches(_T("tool"));
bool issep = node->GetAttribute(wxT("class"), wxEmptyString).Matches(_T("separator"));
#else
bool istbar = node->GetPropVal(wxT("class"), wxEmptyString).Matches(_T("wxToolBarAddOn"));
bool istool = node->GetPropVal(wxT("class"), wxEmptyString).Matches(_T("tool"));
bool issep = node->GetPropVal(wxT("class"), wxEmptyString).Matches(_T("separator"));
#endif
return ((!m_isInside && istbar) ||
(m_isInside && istool) ||
(m_isInside && issep));
}
...
while (n)
{
if ((n->GetType() == wxXML_ELEMENT_NODE) &&
(n->GetName() == _T("object") || n->GetName() == _T("object_ref")))
{
wxObject *created = CreateResFromNode(n, toolbar, NULL);
wxControl *control = wxDynamicCast(created, wxControl);
if (!IsOfClass(n, _T("tool")) &&
!IsOfClass(n, _T("separator")) &&
control != NULL &&
control != toolbar)
{
//Manager::Get()->GetLogManager()->DebugLog(F(_T("control=%p, parent=%p, toolbar=%p"), control, control->GetParent(), toolbar));
toolbar->AddControl(control);
}
}
n = n->GetNext();
}
...
wxSize wxToolBar::DoGetBestSize() const
{
wxSize sizeBest;
SIZE size;
if ( !::SendMessage(GetHwnd(), TB_GETMAXSIZE, 0, (LPARAM)&size) )
{
// maybe an old (< 0x400) Windows version? try to approximate the
// toolbar size ourselves
sizeBest = GetToolSize();
sizeBest.y += 2 * ::GetSystemMetrics(SM_CYBORDER); // Add borders
sizeBest.x *= GetToolsCount();
// reverse horz and vertical components if necessary
if ( IsVertical() )
{
wxSwap(sizeBest.x, sizeBest.y);
}
}
else // TB_GETMAXSIZE succeeded
{
// but it could still return an incorrect result due to what appears to
// be a bug in old comctl32.dll versions which don't handle controls in
// the toolbar correctly, so work around it (see SF patch 1902358)
if ( !IsVertical() && wxApp::GetComCtl32Version() < 600 )
{
// calculate the toolbar width in alternative way
const RECT rcFirst = wxGetTBItemRect(GetHwnd(), 0);
const RECT rcLast = wxGetTBItemRect(GetHwnd(), GetToolsCount() - 1);
const int widthAlt = rcLast.right - rcFirst.left;
if ( widthAlt > size.cx )
size.cx = widthAlt;
}
sizeBest.x = size.cx;
sizeBest.y = size.cy;
}
if ( !IsVertical() )
{
wxToolBarToolsList::compatibility_iterator node;
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
{
wxToolBarTool * const
tool = static_cast<wxToolBarTool *>(node->GetData());
if (tool->IsControl())
{
int y = tool->GetControl()->GetSize().y;
// Approximate border size
if (y > (sizeBest.y - 4))
sizeBest.y = y + 4;
}
}
// Without the extra height, DoGetBestSize can report a size that's
// smaller than the actual window, causing windows to overlap slightly
// in some circumstances, leading to missing borders (especially noticeable
// in AUI layouts).
if (!(GetWindowStyle() & wxTB_NODIVIDER))
sizeBest.y += 2;
sizeBest.y ++;
}
CacheBestSize(sizeBest);
return sizeBest;
}
Revision: 0185d61a2c6f91cf47932fce0d68d70b7e578b17
Author: JulianSmart <julian@anthemion.co.uk>
Date: 2015-11-25 5:28:09
Message:
Ensure toolbar fits controls that are taller than the buttons in wxMSW toolbar
----
Modified: src/msw/toolbar.cpp
The workaround is that we can explicitly reduce the toolbar size if it contains a wxChoice.
From my point of view, I think the old way is quite compact( so I like the compact toolbar :) ), and save a lot of spaces for other windows(such as the notebook window)
Or, wx's source code need to be changed, I see it is introduced by this commit:CodeRevision: 0185d61a2c6f91cf47932fce0d68d70b7e578b17
Author: JulianSmart <julian@anthemion.co.uk>
Date: 2015-11-25 5:28:09
Message:
Ensure toolbar fits controls that are taller than the buttons in wxMSW toolbar
----
Modified: src/msw/toolbar.cpp
What gtk are you using?
My toolbars look perfectly fine and slim with both wxgtk2.8 and wxgtk3.0.
Comparing wxmsw and wxgtk build is not a good idea - they use totally different rendering engines underneath.
Can you also try the auidemo sample or some other wxwidgets sample to verify that the problem happens there, too?The wx demo's should not have such issue(I have tested under Windows about one year before), because this issue is caused by our customized xrc loader, see discussion in this thread before(you can see the previous posts).
So, the toolbar have both spaces in the top and bottom edges, you expect those edges should be smaller, right?Yes, that is correct. This becomes problematic when there is also extra space used left & right of each toolbar item, making the toolbars extra wide. Because they are extra wide, you really need two rows of toolbars, but then you lose twice as much vertical space. So it really adds up.
@cacb: Sorry, I've asked the wrong question - it should have been - "What gtk theme are you using?"
This is what affects drawing of such controls.
Can you also try the auidemo sample or some other wxwidgets sample to verify that the problem happens there, too?
I'm sure it will happen.
Edit: What is the resolution of you display?
It is just the default KDE desktop under Kubuntu 16.10, I think that is "plasma". Is that an answer? I don't have that computer available right now, will try to check tonight.
I will check this and get back to you. Btw, I have a couple of wx GUI applications I have written myself that is using AUI toolbars, and I do not see such issues there, the toolbars are ok. But I will try the auidemo also.
Edit: What is the resolution of you display?
I believe it is 1920x1200, will check later.
Can you try to modify C::B and test it with your theme? Then tell us if it makes a difference?
Search the wiki for tutorials about building. For experiments you can use autotools. Just set the --prefix to something in your home folder.
This method Manager::CreateEmptyToolbar is probably the place to start the investigation.
#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();
}