Add support for stretchable spaces to wxToolBar.
Stretchable spaces consume all extra toolbar space not allocated to the fixed size items. They can in particular be used to right-align (some) toolbar tools. Add and document the new API, change the sample to show it and implement it for MSW, GTK and OS X/Cocoa. Also refactor MSW background erasing/repainting code to avoid duplicated calls to DrawThemeBackground(), call it from a new helper MSWEraseRect() function. Note that we may want to add support for "invisible" separators, IOW non-stretchable spaces. This could be easily done for MSW after the changes in this commit and is supported natively by GTK+ and Cocoa so implementing this would be trivial if there is any interest. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62850 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -445,6 +445,7 @@ All (GUI):
|
|||||||
|
|
||||||
- Added support for showing bitmaps in wxButton.
|
- Added support for showing bitmaps in wxButton.
|
||||||
- Added wxInfoBar.
|
- Added wxInfoBar.
|
||||||
|
- Added stretchable spaces support to wxToolBar.
|
||||||
- Added support for corner, row and column headers renderers to wxGrid.
|
- Added support for corner, row and column headers renderers to wxGrid.
|
||||||
- wxWindow::SetAutoLayout() now works for all windows, not just panels.
|
- wxWindow::SetAutoLayout() now works for all windows, not just panels.
|
||||||
- Support wxListCtrl columns, items and image lists in XRC (Kinaou Hervé).
|
- Support wxListCtrl columns, items and image lists in XRC (Kinaou Hervé).
|
||||||
|
@@ -142,6 +142,10 @@ protected:
|
|||||||
// the total number of toolbar elements
|
// the total number of toolbar elements
|
||||||
size_t m_nButtons;
|
size_t m_nButtons;
|
||||||
|
|
||||||
|
// the sum of the sizes of the fixed items (i.e. excluding stretchable
|
||||||
|
// spaces) in the toolbar direction
|
||||||
|
int m_totalFixedSize;
|
||||||
|
|
||||||
// the tool the cursor is in
|
// the tool the cursor is in
|
||||||
wxToolBarToolBase *m_pInTool;
|
wxToolBarToolBase *m_pInTool;
|
||||||
|
|
||||||
@@ -149,6 +153,17 @@ private:
|
|||||||
// makes sure tool bitmap size is sufficient for all tools
|
// makes sure tool bitmap size is sufficient for all tools
|
||||||
void AdjustToolBitmapSize();
|
void AdjustToolBitmapSize();
|
||||||
|
|
||||||
|
// update the sizes of stretchable spacers to consume all extra space we
|
||||||
|
// have
|
||||||
|
void UpdateStretchableSpacersSize();
|
||||||
|
|
||||||
|
// redraw the background of the given part of the window (or entire window
|
||||||
|
// if the parameter is NULL) to erase separator drawn in it
|
||||||
|
//
|
||||||
|
// return true if the background was erased using DrawThemeBackground()
|
||||||
|
bool MSWEraseRect(wxDC& dc, const wxRect *rectItem = NULL);
|
||||||
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
DECLARE_DYNAMIC_CLASS(wxToolBar)
|
DECLARE_DYNAMIC_CLASS(wxToolBar)
|
||||||
wxDECLARE_NO_COPY_CLASS(wxToolBar);
|
wxDECLARE_NO_COPY_CLASS(wxToolBar);
|
||||||
|
@@ -101,11 +101,6 @@ public:
|
|||||||
m_control = control;
|
m_control = control;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_toolStyle = wxTOOL_STYLE_CONTROL;
|
|
||||||
|
|
||||||
m_dropdownMenu = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~wxToolBarToolBase();
|
virtual ~wxToolBarToolBase();
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
@@ -123,10 +118,12 @@ public:
|
|||||||
|
|
||||||
wxToolBarBase *GetToolBar() const { return m_tbar; }
|
wxToolBarBase *GetToolBar() const { return m_tbar; }
|
||||||
|
|
||||||
// style
|
// style/kind
|
||||||
|
bool IsStretchable() const { return m_stretchable; }
|
||||||
bool IsButton() const { return m_toolStyle == wxTOOL_STYLE_BUTTON; }
|
bool IsButton() const { return m_toolStyle == wxTOOL_STYLE_BUTTON; }
|
||||||
bool IsControl() const { return m_toolStyle == wxTOOL_STYLE_CONTROL; }
|
bool IsControl() const { return m_toolStyle == wxTOOL_STYLE_CONTROL; }
|
||||||
bool IsSeparator() const { return m_toolStyle == wxTOOL_STYLE_SEPARATOR; }
|
bool IsSeparator() const { return m_toolStyle == wxTOOL_STYLE_SEPARATOR; }
|
||||||
|
bool IsStretchableSpace() const { return IsSeparator() && IsStretchable(); }
|
||||||
int GetStyle() const { return m_toolStyle; }
|
int GetStyle() const { return m_toolStyle; }
|
||||||
wxItemKind GetKind() const
|
wxItemKind GetKind() const
|
||||||
{
|
{
|
||||||
@@ -135,6 +132,13 @@ public:
|
|||||||
return m_kind;
|
return m_kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MakeStretchable()
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( IsSeparator(), "only separators can be stretchable" );
|
||||||
|
|
||||||
|
m_stretchable = true;
|
||||||
|
}
|
||||||
|
|
||||||
// state
|
// state
|
||||||
bool IsEnabled() const { return m_enabled; }
|
bool IsEnabled() const { return m_enabled; }
|
||||||
bool IsToggled() const { return m_toggled; }
|
bool IsToggled() const { return m_toggled; }
|
||||||
@@ -214,6 +218,7 @@ protected:
|
|||||||
|
|
||||||
m_clientData = NULL;
|
m_clientData = NULL;
|
||||||
|
|
||||||
|
m_stretchable = false;
|
||||||
m_toggled = false;
|
m_toggled = false;
|
||||||
m_enabled = true;
|
m_enabled = true;
|
||||||
|
|
||||||
@@ -223,7 +228,7 @@ protected:
|
|||||||
wxToolBarBase *m_tbar; // the toolbar to which we belong (may be NULL)
|
wxToolBarBase *m_tbar; // the toolbar to which we belong (may be NULL)
|
||||||
|
|
||||||
// tool parameters
|
// tool parameters
|
||||||
int m_toolStyle; // see enum wxToolBarToolStyle
|
wxToolBarToolStyle m_toolStyle;
|
||||||
wxWindowIDRef m_id; // the tool id, wxID_SEPARATOR for separator
|
wxWindowIDRef m_id; // the tool id, wxID_SEPARATOR for separator
|
||||||
wxItemKind m_kind; // for normal buttons may be wxITEM_NORMAL/CHECK/RADIO
|
wxItemKind m_kind; // for normal buttons may be wxITEM_NORMAL/CHECK/RADIO
|
||||||
|
|
||||||
@@ -234,6 +239,9 @@ protected:
|
|||||||
wxControl *m_control;
|
wxControl *m_control;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// true if this tool is stretchable: currently is only value for separators
|
||||||
|
bool m_stretchable;
|
||||||
|
|
||||||
// tool state
|
// tool state
|
||||||
bool m_toggled;
|
bool m_toggled;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
@@ -362,6 +370,12 @@ public:
|
|||||||
virtual wxToolBarToolBase *AddSeparator();
|
virtual wxToolBarToolBase *AddSeparator();
|
||||||
virtual wxToolBarToolBase *InsertSeparator(size_t pos);
|
virtual wxToolBarToolBase *InsertSeparator(size_t pos);
|
||||||
|
|
||||||
|
// add a stretchable space to the toolbar: this is similar to a separator
|
||||||
|
// except that it's always blank and that all the extra space the toolbar
|
||||||
|
// has is [equally] distributed among the stretchable spaces in it
|
||||||
|
virtual wxToolBarToolBase *AddStretchableSpace();
|
||||||
|
virtual wxToolBarToolBase *InsertStretchableSpace(size_t pos);
|
||||||
|
|
||||||
// remove the tool from the toolbar: the caller is responsible for actually
|
// remove the tool from the toolbar: the caller is responsible for actually
|
||||||
// deleting the pointer
|
// deleting the pointer
|
||||||
virtual wxToolBarToolBase *RemoveTool(int toolid);
|
virtual wxToolBarToolBase *RemoveTool(int toolid);
|
||||||
@@ -606,6 +620,17 @@ protected:
|
|||||||
virtual wxToolBarToolBase *CreateTool(wxControl *control,
|
virtual wxToolBarToolBase *CreateTool(wxControl *control,
|
||||||
const wxString& label) = 0;
|
const wxString& label) = 0;
|
||||||
|
|
||||||
|
// this one is not virtual but just a simple helper/wrapper around
|
||||||
|
// CreateTool() for separators
|
||||||
|
wxToolBarToolBase *CreateSeparator()
|
||||||
|
{
|
||||||
|
return CreateTool(wxID_SEPARATOR,
|
||||||
|
wxEmptyString,
|
||||||
|
wxNullBitmap, wxNullBitmap,
|
||||||
|
wxITEM_SEPARATOR, NULL,
|
||||||
|
wxEmptyString, wxEmptyString);
|
||||||
|
}
|
||||||
|
|
||||||
// helper functions
|
// helper functions
|
||||||
// ----------------
|
// ----------------
|
||||||
|
|
||||||
|
@@ -228,10 +228,27 @@ public:
|
|||||||
platform so it can be a vertical line (MSW, some versions of GTK) or
|
platform so it can be a vertical line (MSW, some versions of GTK) or
|
||||||
just an empty space or something else.
|
just an empty space or something else.
|
||||||
|
|
||||||
@see AddTool(), SetToolSeparation()
|
@see AddTool(), SetToolSeparation(), AddStretchableSpace()
|
||||||
*/
|
*/
|
||||||
virtual wxToolBarToolBase* AddSeparator();
|
virtual wxToolBarToolBase* AddSeparator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds a stretchable space to the toolbar.
|
||||||
|
|
||||||
|
Any space not taken up by the fixed items (all items except for
|
||||||
|
stretchable spaces) is distributed in equal measure between the
|
||||||
|
stretchable spaces in the toolbar. The most common use for this method
|
||||||
|
is to add a single stretchable space before the items which should be
|
||||||
|
right-aligned in the toolbar, but more exotic possibilities are
|
||||||
|
possible, e.g. a stretchable space may be added in the beginning and
|
||||||
|
the end of the toolbar to centre all toolbar items.
|
||||||
|
|
||||||
|
@see AddTool(), AddSeparator(), InsertStretchableSpace()
|
||||||
|
|
||||||
|
@since 2.9.1
|
||||||
|
*/
|
||||||
|
wxToolBarToolBase *AddStretchableSpace();
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/**
|
/**
|
||||||
Adds a tool to the toolbar.
|
Adds a tool to the toolbar.
|
||||||
@@ -525,6 +542,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual wxToolBarToolBase* InsertSeparator(size_t pos);
|
virtual wxToolBarToolBase* InsertSeparator(size_t pos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Inserts a stretchable space at the given position.
|
||||||
|
|
||||||
|
See AddStretchableSpace() for details about stretchable spaces.
|
||||||
|
|
||||||
|
@see InsertTool(), InsertSeparator()
|
||||||
|
|
||||||
|
@since 2.9.1
|
||||||
|
*/
|
||||||
|
wxToolBarToolBase *InsertStretchableSpace(size_t pos);
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/**
|
/**
|
||||||
Inserts the tool with the specified attributes into the toolbar at the
|
Inserts the tool with the specified attributes into the toolbar at the
|
||||||
|
@@ -310,7 +310,7 @@ bool MyApp::OnInit()
|
|||||||
// Create the main frame window
|
// Create the main frame window
|
||||||
MyFrame* frame = new MyFrame((wxFrame *) NULL, wxID_ANY,
|
MyFrame* frame = new MyFrame((wxFrame *) NULL, wxID_ANY,
|
||||||
wxT("wxToolBar Sample"),
|
wxT("wxToolBar Sample"),
|
||||||
wxPoint(100, 100), wxSize(550, 300));
|
wxPoint(100, 100), wxSize(650, 300));
|
||||||
|
|
||||||
frame->Show(true);
|
frame->Show(true);
|
||||||
|
|
||||||
@@ -474,9 +474,12 @@ void MyFrame::PopulateToolbar(wxToolBarBase* toolBar)
|
|||||||
#endif // USE_CONTROLS_IN_TOOLBAR
|
#endif // USE_CONTROLS_IN_TOOLBAR
|
||||||
|
|
||||||
toolBar->AddTool(wxID_SAVE, wxT("Save"), toolBarBitmaps[Tool_save], wxT("Toggle button 1"), wxITEM_CHECK);
|
toolBar->AddTool(wxID_SAVE, wxT("Save"), toolBarBitmaps[Tool_save], wxT("Toggle button 1"), wxITEM_CHECK);
|
||||||
|
|
||||||
|
toolBar->AddSeparator();
|
||||||
toolBar->AddTool(wxID_COPY, wxT("Copy"), toolBarBitmaps[Tool_copy], wxT("Toggle button 2"), wxITEM_CHECK);
|
toolBar->AddTool(wxID_COPY, wxT("Copy"), toolBarBitmaps[Tool_copy], wxT("Toggle button 2"), wxITEM_CHECK);
|
||||||
toolBar->AddTool(wxID_CUT, wxT("Cut"), toolBarBitmaps[Tool_cut], wxT("Toggle/Untoggle help button"));
|
toolBar->AddTool(wxID_CUT, wxT("Cut"), toolBarBitmaps[Tool_cut], wxT("Toggle/Untoggle help button"));
|
||||||
toolBar->AddTool(wxID_PASTE, wxT("Paste"), toolBarBitmaps[Tool_paste], wxT("Paste"));
|
toolBar->AddTool(wxID_PASTE, wxT("Paste"), toolBarBitmaps[Tool_paste], wxT("Paste"));
|
||||||
|
toolBar->AddSeparator();
|
||||||
|
|
||||||
if ( m_useCustomDisabled )
|
if ( m_useCustomDisabled )
|
||||||
{
|
{
|
||||||
@@ -500,7 +503,9 @@ void MyFrame::PopulateToolbar(wxToolBarBase* toolBar)
|
|||||||
wxT("Delete this tool. This is a very long tooltip to test whether it does the right thing when the tooltip is more than Windows can cope with."));
|
wxT("Delete this tool. This is a very long tooltip to test whether it does the right thing when the tooltip is more than Windows can cope with."));
|
||||||
}
|
}
|
||||||
|
|
||||||
toolBar->AddSeparator();
|
// add a stretchable space before the "Help" button to make it
|
||||||
|
// right-aligned
|
||||||
|
toolBar->AddStretchableSpace();
|
||||||
toolBar->AddTool(wxID_HELP, wxT("Help"), toolBarBitmaps[Tool_help], wxT("Help button"), wxITEM_CHECK);
|
toolBar->AddTool(wxID_HELP, wxT("Help"), toolBarBitmaps[Tool_help], wxT("Help button"), wxITEM_CHECK);
|
||||||
|
|
||||||
if ( !m_pathBmp.empty() )
|
if ( !m_pathBmp.empty() )
|
||||||
@@ -899,14 +904,12 @@ void MyFrame::DoToggleHelp()
|
|||||||
|
|
||||||
void MyFrame::OnToggleSearch(wxCommandEvent& WXUNUSED(event))
|
void MyFrame::OnToggleSearch(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
static const int searchPos = 3;
|
|
||||||
|
|
||||||
wxToolBarBase * const tb = GetToolBar();
|
wxToolBarBase * const tb = GetToolBar();
|
||||||
if ( !m_searchTool )
|
if ( !m_searchTool )
|
||||||
{
|
{
|
||||||
wxSearchCtrl * const srch = new wxSearchCtrl(tb, wxID_ANY, "needle");
|
wxSearchCtrl * const srch = new wxSearchCtrl(tb, wxID_ANY, "needle");
|
||||||
srch->SetMinSize(wxSize(80, -1));
|
srch->SetMinSize(wxSize(80, -1));
|
||||||
m_searchTool = tb->InsertControl(searchPos, srch);
|
m_searchTool = tb->AddControl(srch);
|
||||||
}
|
}
|
||||||
else // tool already exists
|
else // tool already exists
|
||||||
{
|
{
|
||||||
@@ -919,7 +922,7 @@ void MyFrame::OnToggleSearch(wxCommandEvent& WXUNUSED(event))
|
|||||||
}
|
}
|
||||||
else // tool exists in detached state, attach it back
|
else // tool exists in detached state, attach it back
|
||||||
{
|
{
|
||||||
tb->InsertTool(searchPos, m_searchTool);
|
tb->AddTool(m_searchTool);
|
||||||
win->Show();
|
win->Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -259,11 +259,29 @@ wxToolBarToolBase *wxToolBarBase::AddSeparator()
|
|||||||
|
|
||||||
wxToolBarToolBase *wxToolBarBase::InsertSeparator(size_t pos)
|
wxToolBarToolBase *wxToolBarBase::InsertSeparator(size_t pos)
|
||||||
{
|
{
|
||||||
return DoInsertNewTool(pos, CreateTool(wxID_SEPARATOR,
|
return DoInsertNewTool(pos, CreateSeparator());
|
||||||
wxEmptyString,
|
}
|
||||||
wxNullBitmap, wxNullBitmap,
|
|
||||||
wxITEM_SEPARATOR, NULL,
|
wxToolBarToolBase *wxToolBarBase::AddStretchableSpace()
|
||||||
wxEmptyString, wxEmptyString));
|
{
|
||||||
|
return InsertStretchableSpace(GetToolsCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
wxToolBarToolBase *wxToolBarBase::InsertStretchableSpace(size_t pos)
|
||||||
|
{
|
||||||
|
wxToolBarToolBase * const tool = CreateSeparator();
|
||||||
|
if ( tool )
|
||||||
|
{
|
||||||
|
// this is a hack but we know that all the current implementations
|
||||||
|
// don't really use the tool when it's created, they will do it
|
||||||
|
// InsertTool() at earliest and maybe even in Realize() much later
|
||||||
|
//
|
||||||
|
// so we can create the tool as a plain separator and mark it as being
|
||||||
|
// a stretchable space later
|
||||||
|
tool->MakeStretchable();
|
||||||
|
}
|
||||||
|
|
||||||
|
return DoInsertNewTool(pos, tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxToolBarToolBase *wxToolBarBase::RemoveTool(int id)
|
wxToolBarToolBase *wxToolBarBase::RemoveTool(int id)
|
||||||
|
@@ -519,6 +519,15 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
|
|||||||
|
|
||||||
case wxTOOL_STYLE_SEPARATOR:
|
case wxTOOL_STYLE_SEPARATOR:
|
||||||
tool->m_item = gtk_separator_tool_item_new();
|
tool->m_item = gtk_separator_tool_item_new();
|
||||||
|
if ( tool->IsStretchable() )
|
||||||
|
{
|
||||||
|
gtk_separator_tool_item_set_draw
|
||||||
|
(
|
||||||
|
GTK_SEPARATOR_TOOL_ITEM(tool->m_item),
|
||||||
|
FALSE
|
||||||
|
);
|
||||||
|
gtk_tool_item_set_expand(tool->m_item, TRUE);
|
||||||
|
}
|
||||||
gtk_toolbar_insert(m_toolbar, tool->m_item, int(pos));
|
gtk_toolbar_insert(m_toolbar, tool->m_item, int(pos));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -149,7 +149,7 @@ public:
|
|||||||
clientData, shortHelp, longHelp)
|
clientData, shortHelp, longHelp)
|
||||||
{
|
{
|
||||||
m_nSepCount = 0;
|
m_nSepCount = 0;
|
||||||
m_staticText = 0;
|
m_staticText = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxToolBarTool(wxToolBar *tbar, wxControl *control, const wxString& label)
|
wxToolBarTool(wxToolBar *tbar, wxControl *control, const wxString& label)
|
||||||
@@ -210,6 +210,29 @@ public:
|
|||||||
void SetSeparatorsCount(size_t count) { m_nSepCount = count; }
|
void SetSeparatorsCount(size_t count) { m_nSepCount = count; }
|
||||||
size_t GetSeparatorsCount() const { return m_nSepCount; }
|
size_t GetSeparatorsCount() const { return m_nSepCount; }
|
||||||
|
|
||||||
|
// we need ids for the spacers which we want to modify later on, this
|
||||||
|
// function will allocate a valid/unique id for a spacer if not done yet
|
||||||
|
void AllocSpacerId()
|
||||||
|
{
|
||||||
|
if ( m_id == wxID_SEPARATOR )
|
||||||
|
m_id = wxWindow::NewControlId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// this method is used for controls only and offsets the control by the
|
||||||
|
// given amount (in pixels) in horizontal direction
|
||||||
|
void MoveBy(int offset)
|
||||||
|
{
|
||||||
|
wxControl * const control = GetControl();
|
||||||
|
|
||||||
|
control->Move(control->GetPosition().x + offset, wxDefaultCoord);
|
||||||
|
|
||||||
|
if ( m_staticText )
|
||||||
|
{
|
||||||
|
m_staticText->Move(m_staticText->GetPosition().x + offset,
|
||||||
|
wxDefaultCoord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t m_nSepCount;
|
size_t m_nSepCount;
|
||||||
wxStaticText *m_staticText;
|
wxStaticText *m_staticText;
|
||||||
@@ -281,6 +304,7 @@ void wxToolBar::Init()
|
|||||||
m_disabledImgList = NULL;
|
m_disabledImgList = NULL;
|
||||||
|
|
||||||
m_nButtons = 0;
|
m_nButtons = 0;
|
||||||
|
m_totalFixedSize = 0;
|
||||||
|
|
||||||
// even though modern Windows applications typically use 24*24 (or even
|
// even though modern Windows applications typically use 24*24 (or even
|
||||||
// 32*32) size for their bitmaps, the native control itself still uses the
|
// 32*32) size for their bitmaps, the native control itself still uses the
|
||||||
@@ -582,15 +606,7 @@ bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool)
|
|||||||
wxToolBarTool *tool2 = (wxToolBarTool*)node->GetData();
|
wxToolBarTool *tool2 = (wxToolBarTool*)node->GetData();
|
||||||
if ( tool2->IsControl() )
|
if ( tool2->IsControl() )
|
||||||
{
|
{
|
||||||
wxControl * const control = tool2->GetControl();
|
tool2->MoveBy(-width);
|
||||||
|
|
||||||
int x;
|
|
||||||
control->GetPosition(&x, NULL);
|
|
||||||
control->Move(x - width, wxDefaultCoord);
|
|
||||||
|
|
||||||
wxStaticText * const staticText = tool2->GetStaticText();
|
|
||||||
if ( staticText )
|
|
||||||
staticText->Move(x - width, wxDefaultCoord);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -900,7 +916,7 @@ bool wxToolBar::Realize()
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
|
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
|
||||||
{
|
{
|
||||||
wxToolBarToolBase *tool = node->GetData();
|
wxToolBarTool *tool = static_cast<wxToolBarTool *>(node->GetData());
|
||||||
|
|
||||||
// don't add separators to the vertical toolbar with old comctl32.dll
|
// don't add separators to the vertical toolbar with old comctl32.dll
|
||||||
// versions as they didn't handle this properly
|
// versions as they didn't handle this properly
|
||||||
@@ -918,10 +934,16 @@ bool wxToolBar::Realize()
|
|||||||
switch ( tool->GetStyle() )
|
switch ( tool->GetStyle() )
|
||||||
{
|
{
|
||||||
case wxTOOL_STYLE_CONTROL:
|
case wxTOOL_STYLE_CONTROL:
|
||||||
button.idCommand = tool->GetId();
|
|
||||||
// fall through: create just a separator too
|
|
||||||
|
|
||||||
case wxTOOL_STYLE_SEPARATOR:
|
case wxTOOL_STYLE_SEPARATOR:
|
||||||
|
if ( tool->IsStretchableSpace() )
|
||||||
|
{
|
||||||
|
// we're going to modify the size of this button later and
|
||||||
|
// so we need a valid id for it and not wxID_SEPARATOR
|
||||||
|
// which is used by spacers by default
|
||||||
|
tool->AllocSpacerId();
|
||||||
|
}
|
||||||
|
|
||||||
|
button.idCommand = tool->GetId();
|
||||||
button.fsState = TBSTATE_ENABLED;
|
button.fsState = TBSTATE_ENABLED;
|
||||||
button.fsStyle = TBSTYLE_SEP;
|
button.fsStyle = TBSTYLE_SEP;
|
||||||
break;
|
break;
|
||||||
@@ -1017,33 +1039,38 @@ bool wxToolBar::Realize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Deal with the controls finally
|
// Adjust controls and stretchable spaces
|
||||||
// ------------------------------
|
// --------------------------------------
|
||||||
|
|
||||||
// adjust the controls size to fit nicely in the toolbar
|
// adjust the controls size to fit nicely in the toolbar and compute its
|
||||||
int y = 0;
|
// total size while doing it
|
||||||
size_t index = 0;
|
m_totalFixedSize = 0;
|
||||||
for ( node = m_tools.GetFirst(); node; node = node->GetNext(), index++ )
|
int toolIndex = 0;
|
||||||
|
for ( node = m_tools.GetFirst(); node; node = node->GetNext(), toolIndex++ )
|
||||||
{
|
{
|
||||||
wxToolBarTool *tool = (wxToolBarTool*)node->GetData();
|
wxToolBarTool * const tool = (wxToolBarTool*)node->GetData();
|
||||||
|
|
||||||
// we calculate the running y coord for vertical toolbars so we need to
|
const RECT r = wxGetTBItemRect(GetHwnd(), toolIndex);
|
||||||
// get the items size for all items but for the horizontal ones we
|
|
||||||
// don't need to deal with the non controls
|
|
||||||
bool isControl = tool->IsControl();
|
|
||||||
if ( !isControl && !IsVertical() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const RECT r = wxGetTBItemRect(GetHwnd(), index);
|
if ( !tool->IsControl() )
|
||||||
if ( !isControl )
|
|
||||||
{
|
{
|
||||||
// can only be control if isVertical
|
if ( IsVertical() )
|
||||||
y += r.bottom - r.top;
|
m_totalFixedSize += r.bottom - r.top;
|
||||||
|
else
|
||||||
|
m_totalFixedSize += r.right - r.left;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControl *control = tool->GetControl();
|
if ( IsVertical() )
|
||||||
|
{
|
||||||
|
// don't embed controls in the vertical toolbar, this doesn't look
|
||||||
|
// good and wxGTK doesn't do it neither (and the code below can't
|
||||||
|
// deal with this case)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxControl * const control = tool->GetControl();
|
||||||
wxStaticText * const staticText = tool->GetStaticText();
|
wxStaticText * const staticText = tool->GetStaticText();
|
||||||
|
|
||||||
wxSize size = control->GetSize();
|
wxSize size = control->GetSize();
|
||||||
@@ -1054,9 +1081,6 @@ bool wxToolBar::Realize()
|
|||||||
staticTextSize.y += 3; // margin between control and its label
|
staticTextSize.y += 3; // margin between control and its label
|
||||||
}
|
}
|
||||||
|
|
||||||
// the position of the leftmost controls corner
|
|
||||||
int left = wxDefaultCoord;
|
|
||||||
|
|
||||||
// TB_SETBUTTONINFO message is only supported by comctl32.dll 4.71+
|
// TB_SETBUTTONINFO message is only supported by comctl32.dll 4.71+
|
||||||
#ifdef TB_SETBUTTONINFO
|
#ifdef TB_SETBUTTONINFO
|
||||||
// available in headers, now check whether it is available now
|
// available in headers, now check whether it is available now
|
||||||
@@ -1082,7 +1106,6 @@ bool wxToolBar::Realize()
|
|||||||
{
|
{
|
||||||
// try adding several separators to fit the controls width
|
// try adding several separators to fit the controls width
|
||||||
int widthSep = r.right - r.left;
|
int widthSep = r.right - r.left;
|
||||||
left = r.left;
|
|
||||||
|
|
||||||
TBBUTTON tbb;
|
TBBUTTON tbb;
|
||||||
wxZeroMemory(tbb);
|
wxZeroMemory(tbb);
|
||||||
@@ -1094,17 +1117,17 @@ bool wxToolBar::Realize()
|
|||||||
for ( size_t nSep = 0; nSep < nSeparators; nSep++ )
|
for ( size_t nSep = 0; nSep < nSeparators; nSep++ )
|
||||||
{
|
{
|
||||||
if ( !::SendMessage(GetHwnd(), TB_INSERTBUTTON,
|
if ( !::SendMessage(GetHwnd(), TB_INSERTBUTTON,
|
||||||
index, (LPARAM)&tbb) )
|
toolIndex, (LPARAM)&tbb) )
|
||||||
{
|
{
|
||||||
wxLogLastError(wxT("TB_INSERTBUTTON"));
|
wxLogLastError(wxT("TB_INSERTBUTTON"));
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
toolIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remember the number of separators we used - we'd have to
|
// remember the number of separators we used - we'd have to
|
||||||
// delete all of them later
|
// delete all of them later
|
||||||
((wxToolBarTool *)tool)->SetSeparatorsCount(nSeparators);
|
tool->SetSeparatorsCount(nSeparators);
|
||||||
|
|
||||||
// adjust the controls width to exactly cover the separators
|
// adjust the controls width to exactly cover the separators
|
||||||
size.x = (nSeparators + 1)*widthSep;
|
size.x = (nSeparators + 1)*widthSep;
|
||||||
@@ -1139,33 +1162,19 @@ bool wxToolBar::Realize()
|
|||||||
staticText->Show();
|
staticText->Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
int top;
|
control->Move(r.left, r.top + (diff + 1) / 2);
|
||||||
if ( IsVertical() )
|
|
||||||
{
|
|
||||||
left = 0;
|
|
||||||
top = y;
|
|
||||||
|
|
||||||
y += height + 2 * GetMargins().y;
|
|
||||||
}
|
|
||||||
else // horizontal toolbar
|
|
||||||
{
|
|
||||||
if ( left == wxDefaultCoord )
|
|
||||||
left = r.left;
|
|
||||||
|
|
||||||
top = r.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
control->Move(left, top + (diff + 1) / 2);
|
|
||||||
if ( staticText )
|
if ( staticText )
|
||||||
{
|
{
|
||||||
staticText->Move(left + (size.x - staticTextSize.x)/2,
|
staticText->Move(r.left + (size.x - staticTextSize.x)/2,
|
||||||
r.bottom - staticTextSize.y);
|
r.bottom - staticTextSize.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_totalFixedSize += size.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the max index is the "real" number of buttons - i.e. counting even the
|
// the max index is the "real" number of buttons - i.e. counting even the
|
||||||
// separators which we added just for aligning the controls
|
// separators which we added just for aligning the controls
|
||||||
m_nButtons = index;
|
m_nButtons = toolIndex;
|
||||||
|
|
||||||
if ( !IsVertical() )
|
if ( !IsVertical() )
|
||||||
{
|
{
|
||||||
@@ -1186,6 +1195,77 @@ bool wxToolBar::Realize()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxToolBar::UpdateStretchableSpacersSize()
|
||||||
|
{
|
||||||
|
// we can't resize the spacers if TB_SETBUTTONINFO is not supported
|
||||||
|
if ( wxApp::GetComCtl32Version() < 471 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check if we have any stretchable spacers in the first place
|
||||||
|
unsigned numSpaces = 0;
|
||||||
|
wxToolBarToolsList::compatibility_iterator node;
|
||||||
|
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
|
||||||
|
{
|
||||||
|
wxToolBarTool * const tool = (wxToolBarTool*)node->GetData();
|
||||||
|
if ( tool->IsStretchableSpace() )
|
||||||
|
numSpaces++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !numSpaces )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// we do, adjust their size: either distribute the extra size among them or
|
||||||
|
// reduce their size if there is not enough place for all tools
|
||||||
|
const int totalSize = IsVertical() ? GetClientSize().y : GetClientSize().x;
|
||||||
|
const int extraSize = totalSize - m_totalFixedSize;
|
||||||
|
const int sizeSpacer = extraSize > 0 ? extraSize / numSpaces : 0;
|
||||||
|
|
||||||
|
// the last spacer should consume all remaining space if we have too much
|
||||||
|
// of it (which can be greater than sizeSpacer because of the rounding)
|
||||||
|
const int sizeLastSpacer = extraSize > 0
|
||||||
|
? extraSize - (numSpaces - 1)*sizeSpacer
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
// cumulated offset by which we need to move all the following controls to
|
||||||
|
// the right: while the toolbar takes care of the normal items, we must
|
||||||
|
// move the controls manually ourselves to ensure they remain at the
|
||||||
|
// correct place
|
||||||
|
int offset = 0;
|
||||||
|
int toolIndex = 0;
|
||||||
|
for ( node = m_tools.GetFirst(); node; node = node->GetNext(), toolIndex++ )
|
||||||
|
{
|
||||||
|
wxToolBarTool * const tool = (wxToolBarTool*)node->GetData();
|
||||||
|
|
||||||
|
if ( tool->IsControl() && offset )
|
||||||
|
{
|
||||||
|
tool->MoveBy(offset);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !tool->IsStretchableSpace() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const RECT rcOld = wxGetTBItemRect(GetHwnd(), toolIndex);
|
||||||
|
|
||||||
|
WinStruct<TBBUTTONINFO> tbbi;
|
||||||
|
tbbi.dwMask = TBIF_SIZE;
|
||||||
|
tbbi.cx = --numSpaces ? sizeSpacer : sizeLastSpacer;
|
||||||
|
|
||||||
|
if ( !::SendMessage(GetHwnd(), TB_SETBUTTONINFO,
|
||||||
|
tool->GetId(), (LPARAM)&tbbi) )
|
||||||
|
{
|
||||||
|
wxLogLastError(wxT("TB_SETBUTTONINFO"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we successfully resized this one, move all the controls after it
|
||||||
|
// by the corresponding amount (may be positive or negative)
|
||||||
|
offset += tbbi.cx - (rcOld.right - rcOld.left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// message handlers
|
// message handlers
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -1576,12 +1656,7 @@ void wxToolBar::OnEraseBackground(wxEraseEvent& event)
|
|||||||
RECT rect = wxGetClientRect(GetHwnd());
|
RECT rect = wxGetClientRect(GetHwnd());
|
||||||
|
|
||||||
wxDC *dc = event.GetDC();
|
wxDC *dc = event.GetDC();
|
||||||
if (!dc) return;
|
HDC hdc = GetHdcOf(*dc);
|
||||||
wxMSWDCImpl *impl = (wxMSWDCImpl*) dc->GetImpl();
|
|
||||||
HDC hdc = GetHdcOf(*impl);
|
|
||||||
|
|
||||||
int majorVersion, minorVersion;
|
|
||||||
wxGetOsVersion(& majorVersion, & minorVersion);
|
|
||||||
|
|
||||||
#if wxUSE_UXTHEME
|
#if wxUSE_UXTHEME
|
||||||
// we may need to draw themed colour so that we appear correctly on
|
// we may need to draw themed colour so that we appear correctly on
|
||||||
@@ -1606,36 +1681,13 @@ void wxToolBar::OnEraseBackground(wxEraseEvent& event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only draw a rebar theme on Vista, since it doesn't jive so well with XP
|
if ( MSWEraseRect(*dc) )
|
||||||
if ( !UseBgCol() && majorVersion >= 6 )
|
return;
|
||||||
{
|
|
||||||
wxUxThemeEngine *theme = wxUxThemeEngine::GetIfActive();
|
|
||||||
if ( theme )
|
|
||||||
{
|
|
||||||
wxUxThemeHandle hTheme(this, L"REBAR");
|
|
||||||
|
|
||||||
RECT r;
|
|
||||||
wxRect rect = GetClientRect();
|
|
||||||
wxCopyRectToRECT(rect, r);
|
|
||||||
|
|
||||||
HRESULT hr = theme->DrawThemeBackground(hTheme, hdc, 0, 0, & r, NULL);
|
|
||||||
if ( hr == S_OK )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// it can also return S_FALSE which seems to simply say that it
|
|
||||||
// didn't draw anything but no error really occurred
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
{
|
|
||||||
wxLogApiError(wxT("DrawThemeParentBackground(toolbar)"), hr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // wxUSE_UXTHEME
|
#endif // wxUSE_UXTHEME
|
||||||
|
|
||||||
// we need to always draw our background under XP, as otherwise it doesn't
|
// we need to always draw our background under XP, as otherwise it doesn't
|
||||||
// appear correctly with some themes (e.g. Zune one)
|
// appear correctly with some themes (e.g. Zune one)
|
||||||
if ( majorVersion == 5 ||
|
if ( wxGetWinVersion() == wxWinVersion_XP ||
|
||||||
UseBgCol() || (GetMSWToolbarStyle() & TBSTYLE_TRANSPARENT) )
|
UseBgCol() || (GetMSWToolbarStyle() & TBSTYLE_TRANSPARENT) )
|
||||||
{
|
{
|
||||||
// do draw our background
|
// do draw our background
|
||||||
@@ -1648,7 +1700,7 @@ void wxToolBar::OnEraseBackground(wxEraseEvent& event)
|
|||||||
wxCHANGE_HDC_MAP_MODE(hdc, MM_TEXT);
|
wxCHANGE_HDC_MAP_MODE(hdc, MM_TEXT);
|
||||||
::FillRect(hdc, &rect, hBrush);
|
::FillRect(hdc, &rect, hBrush);
|
||||||
}
|
}
|
||||||
else // we have no non default background colour
|
else // we have no non-default background colour
|
||||||
{
|
{
|
||||||
// let the system do it for us
|
// let the system do it for us
|
||||||
event.Skip();
|
event.Skip();
|
||||||
@@ -1699,45 +1751,100 @@ bool wxToolBar::HandleSize(WXWPARAM WXUNUSED(wParam), WXLPARAM lParam)
|
|||||||
SetSize(w, h);
|
SetSize(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateStretchableSpacersSize();
|
||||||
|
|
||||||
// message processed
|
// message processed
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __WXWINCE__
|
#ifndef __WXWINCE__
|
||||||
|
|
||||||
|
bool wxToolBar::MSWEraseRect(wxDC& dc, const wxRect *rectItem)
|
||||||
|
{
|
||||||
|
// erase the given rectangle to hide the separator
|
||||||
|
#if wxUSE_UXTHEME
|
||||||
|
// themed background doesn't look well under XP so only draw it for Vista
|
||||||
|
// and later
|
||||||
|
if ( !UseBgCol() && wxGetWinVersion() >= wxWinVersion_Vista )
|
||||||
|
{
|
||||||
|
wxUxThemeEngine *theme = wxUxThemeEngine::GetIfActive();
|
||||||
|
if ( theme )
|
||||||
|
{
|
||||||
|
wxUxThemeHandle hTheme(this, L"REBAR");
|
||||||
|
|
||||||
|
// Draw the whole background since the pattern may be position
|
||||||
|
// sensitive; but clip it to the area of interest.
|
||||||
|
RECT rcTotal;
|
||||||
|
wxCopyRectToRECT(GetClientSize(), rcTotal);
|
||||||
|
|
||||||
|
RECT rcItem;
|
||||||
|
if ( rectItem )
|
||||||
|
wxCopyRectToRECT(*rectItem, rcItem);
|
||||||
|
|
||||||
|
HRESULT hr = theme->DrawThemeBackground
|
||||||
|
(
|
||||||
|
hTheme,
|
||||||
|
GetHdcOf(dc),
|
||||||
|
0, 0,
|
||||||
|
&rcTotal,
|
||||||
|
rectItem ? &rcItem : NULL
|
||||||
|
);
|
||||||
|
if ( hr == S_OK )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// it can also return S_FALSE which seems to simply say that it
|
||||||
|
// didn't draw anything but no error really occurred
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
{
|
||||||
|
wxLogApiError(wxT("DrawThemeBackground(toolbar)"), hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // wxUSE_UXTHEME
|
||||||
|
|
||||||
|
// this is a bit peculiar but we may simply do nothing here if no rectItem
|
||||||
|
// is specified (and hence we need to erase everything) as this only
|
||||||
|
// happens when we're called from OnEraseBackground() and in this case we
|
||||||
|
// may simply return false to let the systems default background erasing to
|
||||||
|
// take place
|
||||||
|
if ( rectItem )
|
||||||
|
dc.DrawRectangle(*rectItem);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool wxToolBar::HandlePaint(WXWPARAM wParam, WXLPARAM lParam)
|
bool wxToolBar::HandlePaint(WXWPARAM wParam, WXLPARAM lParam)
|
||||||
{
|
{
|
||||||
// erase any dummy separators which were used
|
// erase any dummy separators which were used only for reserving space in
|
||||||
// for aligning the controls if any here
|
// the toolbar (either for a control or just for a stretchable space)
|
||||||
|
|
||||||
// first of all, are there any controls at all?
|
// first of all, are there any controls at all?
|
||||||
wxToolBarToolsList::compatibility_iterator node;
|
wxToolBarToolsList::compatibility_iterator node;
|
||||||
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
|
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
|
||||||
{
|
{
|
||||||
if ( node->GetData()->IsControl() )
|
wxToolBarToolBase * const tool = node->GetData();
|
||||||
|
if ( tool->IsControl() || tool->IsStretchableSpace() )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !node )
|
if ( !node )
|
||||||
|
{
|
||||||
// no controls, nothing to erase
|
// no controls, nothing to erase
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
wxSize clientSize = GetClientSize();
|
|
||||||
int majorVersion, minorVersion;
|
|
||||||
wxGetOsVersion(& majorVersion, & minorVersion);
|
|
||||||
|
|
||||||
// prepare the DC on which we'll be drawing
|
// prepare the DC on which we'll be drawing
|
||||||
wxClientDC dc(this);
|
wxClientDC dc(this);
|
||||||
dc.SetBrush(wxBrush(GetBackgroundColour(), wxSOLID));
|
|
||||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||||
|
|
||||||
RECT r;
|
RECT rcUpdate;
|
||||||
if ( !::GetUpdateRect(GetHwnd(), &r, FALSE) )
|
if ( !::GetUpdateRect(GetHwnd(), &rcUpdate, FALSE) )
|
||||||
|
{
|
||||||
// nothing to redraw anyhow
|
// nothing to redraw anyhow
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
wxRect rectUpdate;
|
const wxRect rectUpdate = wxRectFromRECT(rcUpdate);
|
||||||
wxCopyRECTToRect(r, rectUpdate);
|
|
||||||
|
|
||||||
dc.SetClippingRegion(rectUpdate);
|
dc.SetClippingRegion(rectUpdate);
|
||||||
|
|
||||||
// draw the toolbar tools, separators &c normally
|
// draw the toolbar tools, separators &c normally
|
||||||
@@ -1749,7 +1856,8 @@ bool wxToolBar::HandlePaint(WXWPARAM wParam, WXLPARAM lParam)
|
|||||||
// NB: this is really the only way to do it as we don't know if a separator
|
// NB: this is really the only way to do it as we don't know if a separator
|
||||||
// corresponds to a control (i.e. is a dummy one) or a real one
|
// corresponds to a control (i.e. is a dummy one) or a real one
|
||||||
// otherwise
|
// otherwise
|
||||||
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
|
int toolIndex = 0;
|
||||||
|
for ( node = m_tools.GetFirst(); node; node = node->GetNext(), toolIndex++ )
|
||||||
{
|
{
|
||||||
wxToolBarTool *tool = (wxToolBarTool*)node->GetData();
|
wxToolBarTool *tool = (wxToolBarTool*)node->GetData();
|
||||||
if ( tool->IsControl() )
|
if ( tool->IsControl() )
|
||||||
@@ -1758,13 +1866,16 @@ bool wxToolBar::HandlePaint(WXWPARAM wParam, WXLPARAM lParam)
|
|||||||
wxControl *control = tool->GetControl();
|
wxControl *control = tool->GetControl();
|
||||||
wxStaticText *staticText = tool->GetStaticText();
|
wxStaticText *staticText = tool->GetStaticText();
|
||||||
wxRect rectCtrl = control->GetRect();
|
wxRect rectCtrl = control->GetRect();
|
||||||
wxRect rectStaticText(0,0,0,0);
|
wxRect rectStaticText;
|
||||||
if ( staticText )
|
if ( staticText )
|
||||||
{
|
|
||||||
rectStaticText = staticText->GetRect();
|
rectStaticText = staticText->GetRect();
|
||||||
}
|
|
||||||
|
|
||||||
// iterate over all buttons
|
if ( !rectCtrl.Intersects(rectUpdate) &&
|
||||||
|
(!staticText || !rectStaticText.Intersects(rectUpdate)) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// iterate over all buttons to find all separators intersecting
|
||||||
|
// this control
|
||||||
TBBUTTON tbb;
|
TBBUTTON tbb;
|
||||||
int count = ::SendMessage(GetHwnd(), TB_BUTTONCOUNT, 0, 0);
|
int count = ::SendMessage(GetHwnd(), TB_BUTTONCOUNT, 0, 0);
|
||||||
for ( int n = 0; n < count; n++ )
|
for ( int n = 0; n < count; n++ )
|
||||||
@@ -1786,63 +1897,34 @@ bool wxToolBar::HandlePaint(WXWPARAM wParam, WXLPARAM lParam)
|
|||||||
if ( !r.right )
|
if ( !r.right )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// does it intersect the control?
|
const wxRect rectItem = wxRectFromRECT(r);
|
||||||
wxRect rectItem;
|
|
||||||
wxCopyRECTToRect(r, rectItem);
|
|
||||||
if ( rectCtrl.Intersects(rectItem) || (staticText && rectStaticText.Intersects(rectItem)))
|
|
||||||
{
|
|
||||||
// yes, do erase it!
|
|
||||||
|
|
||||||
bool haveRefreshed = false;
|
// does it intersect the update region at all?
|
||||||
|
if ( !rectUpdate.Intersects(rectItem) )
|
||||||
#if wxUSE_UXTHEME
|
continue;
|
||||||
if ( !UseBgCol() && !GetParent()->UseBgCol() )
|
|
||||||
{
|
|
||||||
// Don't use DrawThemeBackground
|
|
||||||
}
|
|
||||||
else if ( !UseBgCol() && majorVersion >= 6 )
|
|
||||||
{
|
|
||||||
wxUxThemeEngine *theme = wxUxThemeEngine::GetIfActive();
|
|
||||||
if ( theme )
|
|
||||||
{
|
|
||||||
wxUxThemeHandle hTheme(this, L"REBAR");
|
|
||||||
|
|
||||||
RECT clipRect = r;
|
|
||||||
|
|
||||||
// Draw the whole background since the pattern may be position sensitive;
|
|
||||||
// but clip it to the area of interest.
|
|
||||||
r.left = 0;
|
|
||||||
r.right = clientSize.x;
|
|
||||||
r.top = 0;
|
|
||||||
r.bottom = clientSize.y;
|
|
||||||
|
|
||||||
wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
|
|
||||||
HRESULT hr = theme->DrawThemeBackground(hTheme, GetHdcOf(*impl), 0, 0, & r, & clipRect);
|
|
||||||
if ( hr == S_OK )
|
|
||||||
haveRefreshed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // wxUSE_UXTHEME
|
|
||||||
|
|
||||||
if (!haveRefreshed)
|
|
||||||
dc.DrawRectangle(rectItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// does it intersect the control itself or its label?
|
||||||
|
//
|
||||||
|
// if it does, refresh it so it's redrawn on top of the
|
||||||
|
// background
|
||||||
if ( rectCtrl.Intersects(rectItem) )
|
if ( rectCtrl.Intersects(rectItem) )
|
||||||
{
|
|
||||||
// Necessary in case we use a no-paint-on-size
|
|
||||||
// style in the parent: the controls can disappear
|
|
||||||
control->Refresh(false);
|
control->Refresh(false);
|
||||||
}
|
else if ( staticText && rectStaticText.Intersects(rectItem) )
|
||||||
|
|
||||||
if ( staticText && rectStaticText.Intersects(rectItem) )
|
|
||||||
{
|
|
||||||
// Necessary in case we use a no-paint-on-size
|
|
||||||
// style in the parent: the controls can disappear
|
|
||||||
staticText->Refresh(false);
|
staticText->Refresh(false);
|
||||||
}
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MSWEraseRect(dc, &rectItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( tool->IsStretchableSpace() )
|
||||||
|
{
|
||||||
|
const wxRect
|
||||||
|
rectItem = wxRectFromRECT(wxGetTBItemRect(GetHwnd(), toolIndex));
|
||||||
|
|
||||||
|
if ( rectUpdate.Intersects(rectItem) )
|
||||||
|
MSWEraseRect(dc, &rectItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@@ -960,16 +960,21 @@ bool wxToolBar::Realize()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxCFStringRef cfidentifier;
|
||||||
|
const NSString *nsItemId;
|
||||||
if (tool->GetStyle() == wxTOOL_STYLE_SEPARATOR)
|
if (tool->GetStyle() == wxTOOL_STYLE_SEPARATOR)
|
||||||
[refTB insertItemWithItemIdentifier:NSToolbarSeparatorItemIdentifier atIndex:currentPosition];
|
{
|
||||||
|
nsItemId = tool->IsStretchable() ? NSToolbarFlexibleSpaceItemIdentifier
|
||||||
|
: NSToolbarSeparatorItemIdentifier;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
cfidentifier = wxCFStringRef(wxString::Format("%ld", (long)tool));
|
||||||
wxString identifier = wxString::Format( wxT("%ld"), (long) tool );
|
nsItemId = cfidentifier.AsNSString();
|
||||||
wxCFStringRef cfidentifier(identifier);
|
|
||||||
|
|
||||||
[refTB insertItemWithItemIdentifier:cfidentifier.AsNSString() atIndex:currentPosition];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[refTB insertItemWithItemIdentifier:nsItemId atIndex:currentPosition];
|
||||||
tool->SetIndex( currentPosition );
|
tool->SetIndex( currentPosition );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1220,7 +1225,10 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
|
|||||||
#if wxOSX_USE_NATIVE_TOOLBAR
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
||||||
if (m_macToolbar != NULL)
|
if (m_macToolbar != NULL)
|
||||||
{
|
{
|
||||||
NSToolbarItem* item = [[NSToolbarItem alloc] initWithItemIdentifier:NSToolbarSeparatorItemIdentifier];
|
const NSString * const
|
||||||
|
nsItemId = tool->IsStretchable() ? NSToolbarFlexibleSpaceItemIdentifier
|
||||||
|
: NSToolbarSeparatorItemIdentifier;
|
||||||
|
NSToolbarItem* item = [[NSToolbarItem alloc] initWithItemIdentifier:nsItemId];
|
||||||
tool->SetToolbarItemRef( item );
|
tool->SetToolbarItemRef( item );
|
||||||
}
|
}
|
||||||
#endif // wxOSX_USE_NATIVE_TOOLBAR
|
#endif // wxOSX_USE_NATIVE_TOOLBAR
|
||||||
|
Reference in New Issue
Block a user