Merge branch 'dvc-misc'

Several bug fixes to (mostly generic, but not only) wxDataViewCtrl.

See https://github.com/wxWidgets/wxWidgets/pull/715
This commit is contained in:
Vadim Zeitlin
2018-02-04 15:11:48 +01:00
13 changed files with 254 additions and 119 deletions

View File

@@ -181,6 +181,7 @@ All (GUI):
- Add wxEVT_SEARCH[_CANCEL] synonyms for wxSearchCtrl events.
- Generate wxEVT_SEARCH on Enter under all platforms.
- Extend wxRendererNative::DrawGauge() to work for vertical gauges too.
- Add wxHD_BITMAP_ON_RIGHT style to wxHeaderCtrl.
wxGTK:
@@ -249,6 +250,7 @@ wxMSW:
- Fix focus-related problems when using native wxProgressDialog.
- Fix crash when reparenting the currently focused window to another TLW.
- Fix sending wxEVT_TEXT_ENTER when using auto-completion (Dubby).
- Fix missing selection event on click in multiselection wxDataViewCtrl (mikek).
wxOSX:
@@ -281,6 +283,7 @@ wxOSX:
- Fix selecting RGB bitmaps (with no alpha channel) into wxMemoryDC.
- Fix updating radio groups when menu item is inserted/removed from wxMenu.
- Allow changing alignment styles after wxTextCtrl creation (Andreas Falkenhahn).
- Fix wxDataViewColumn::SetSortOrder() (hartwigw).
wxQt

View File

@@ -27,6 +27,7 @@
#include "wx/dataobj.h"
#include "wx/withimages.h"
#include "wx/systhemectrl.h"
#include "wx/vector.h"
class WXDLLIMPEXP_FWD_CORE wxImageList;
class wxItemAttr;
@@ -179,8 +180,7 @@ private:
// wxDataViewModel
// ---------------------------------------------------------
WX_DECLARE_LIST_WITH_DECL(wxDataViewModelNotifier, wxDataViewModelNotifiers,
class WXDLLIMPEXP_ADV);
typedef wxVector<wxDataViewModelNotifier*> wxDataViewModelNotifiers;
class WXDLLIMPEXP_ADV wxDataViewModel: public wxRefCounter
{
@@ -273,8 +273,9 @@ public:
virtual bool IsVirtualListModel() const { return false; }
protected:
// the user should not delete this class directly: he should use DecRef() instead!
virtual ~wxDataViewModel() { }
// Dtor is protected because the objects of this class must not be deleted,
// DecRef() must be used instead.
virtual ~wxDataViewModel();
// Helper function used by the default Compare() implementation to compare
// values of types it is not aware about. Can be overridden in the derived
@@ -285,7 +286,7 @@ protected:
return 0;
}
private:
wxDataViewModelNotifiers m_notifiers;
};
@@ -1211,8 +1212,7 @@ private:
wxClientData *m_data;
};
WX_DECLARE_LIST_WITH_DECL(wxDataViewTreeStoreNode, wxDataViewTreeStoreNodeList,
class WXDLLIMPEXP_ADV);
typedef wxVector<wxDataViewTreeStoreNode*> wxDataViewTreeStoreNodes;
class WXDLLIMPEXP_ADV wxDataViewTreeStoreContainerNode: public wxDataViewTreeStoreNode
{
@@ -1222,11 +1222,13 @@ public:
wxClientData *data = NULL );
virtual ~wxDataViewTreeStoreContainerNode();
const wxDataViewTreeStoreNodeList &GetChildren() const
const wxDataViewTreeStoreNodes &GetChildren() const
{ return m_children; }
wxDataViewTreeStoreNodeList &GetChildren()
wxDataViewTreeStoreNodes &GetChildren()
{ return m_children; }
wxDataViewTreeStoreNodes::iterator FindChild(wxDataViewTreeStoreNode* node);
void SetExpandedIcon( const wxIcon &icon )
{ m_iconExpanded = icon; }
const wxIcon &GetExpandedIcon() const
@@ -1240,8 +1242,10 @@ public:
virtual bool IsContainer() wxOVERRIDE
{ return true; }
void DestroyChildren();
private:
wxDataViewTreeStoreNodeList m_children;
wxDataViewTreeStoreNodes m_children;
wxIcon m_iconExpanded;
bool m_isExpanded;
};

View File

@@ -257,10 +257,10 @@ public:
#if wxUSE_ACCESSIBILITY
virtual bool Show(bool show = true) wxOVERRIDE;
virtual bool Enable(bool enable = true) wxOVERRIDE;
virtual void SetName(const wxString &name) wxOVERRIDE;
virtual bool Reparent(wxWindowBase *newParent) wxOVERRIDE;
#endif // wxUSE_ACCESSIBILITY
virtual bool Enable(bool enable = true) wxOVERRIDE;
virtual bool AllowMultiColumnSort(bool allow) wxOVERRIDE;
virtual bool IsMultiColumnSortAllowed() const wxOVERRIDE { return m_allowMultiColumnSort; }

View File

@@ -37,6 +37,9 @@ enum
// right clicking the header
wxHD_ALLOW_HIDE = 0x0002,
// force putting column images on right
wxHD_BITMAP_ON_RIGHT = 0x0004,
// style used by default when creating the control
wxHD_DEFAULT_STYLE = wxHD_ALLOW_REORDER
};

View File

@@ -155,7 +155,8 @@ public:
@param column
The column holding the items to be compared.
@param ascending
The sort is being peformed in ascending or descending order.
Indicates whether the sort is being performed in ascending or
descending order.
@return
For an ascending comparison: a negative value if the item1 is less
than (i.e. should appear above) item2, zero if the two items are
@@ -163,11 +164,12 @@ public:
appear below) the second one. The reverse for a descending
comparison.
@note If there can be multiple rows with the same value, consider
differentiating them form each other by their ID's rather than
differentiating them form each other by their IDs rather than
returning zero. This to prevent rows with the same value jumping
positions when items are added etc. For example:
@code
// Differentiate items with the same value.
// Note that we need to distinguish between items with the same
// value.
wxUIntPtr id1 = wxPtrToUInt(item1.GetID()),
id2 = wxPtrToUInt(item2.GetID());
@@ -1440,6 +1442,16 @@ public:
virtual wxRect GetItemRect(const wxDataViewItem& item,
const wxDataViewColumn* col = NULL) const;
/**
Returns the window corresponding to the main area of the control.
This is the window that actually shows the control items and may be
different from wxDataViewCtrl window itself in some ports (currently
this is only the case for the generic implementation used by default
under MSW).
*/
wxWindow* GetMainWindow();
/**
Returns pointer to the data model associated with the control (if any).
*/
@@ -1956,7 +1968,7 @@ public:
/**
Sets the alignment of the renderer's content.
The default value of @c wxDVR_DEFAULT_ALIGMENT indicates that the content
The default value of @c wxDVR_DEFAULT_ALIGNMENT indicates that the content
should have the same alignment as the column header.
The method is not implemented under OS X and the renderer always aligns
@@ -3403,6 +3415,13 @@ public:
without having to derive any class from it, but it is mostly used from within
wxDataViewTreeCtrl.
Notice that by default this class sorts all items with children before the
leaf items. If this behaviour is inappropriate, you need to derive a custom
class from this one and override either its HasDefaultCompare() method to
return false, which would result in items being sorted just in the order in
which they were added, or its Compare() function to compare the items using
some other criterion, e.g. alphabetically.
@library{wxadv}
@category{dvc}
*/

View File

@@ -17,6 +17,9 @@ enum
// right clicking the header
wxHD_ALLOW_HIDE = 0x0002,
// force putting column images on right
wxHD_BITMAP_ON_RIGHT = 0x0004,
// style used by default when creating the control
wxHD_DEFAULT_STYLE = wxHD_ALLOW_REORDER
};
@@ -76,6 +79,11 @@ enum
user to change the columns visibility on right mouse click. Notice that
the program can always hide or show the columns, this style only
affects the users capability to do it.
@style{wxHD_BITMAP_ON_RIGHT}
The column image, if any, will be shown on the right side if this style
is used. Note that this style is only implemented in wxMSW currently
and doesn't do anything under the other platforms. It is available
since wxWidgets 3.1.1.
@style{wxHD_DEFAULT_STYLE}
Symbolic name for the default control style, currently equal to
@c wxHD_ALLOW_REORDER.

View File

@@ -23,6 +23,7 @@
#include "wx/wx.h"
#endif
#include "wx/artprov.h"
#include "wx/dataview.h"
#include "wx/datetime.h"
#include "wx/splitter.h"
@@ -84,6 +85,7 @@ private:
void OnCustomHeaderHeight(wxCommandEvent& event);
#endif // wxHAS_GENERIC_DATAVIEWCTRL
void OnGetPageInfo(wxCommandEvent& event);
void OnDisable(wxCommandEvent& event);
void OnSetForegroundColour(wxCommandEvent& event);
void OnIncIndent(wxCommandEvent& event);
void OnDecIndent(wxCommandEvent& event);
@@ -307,6 +309,7 @@ enum
{
ID_CLEARLOG = wxID_HIGHEST+1,
ID_GET_PAGE_INFO,
ID_DISABLE,
ID_BACKGROUND_COLOUR,
ID_FOREGROUND_COLOUR,
ID_CUSTOM_HEADER_ATTR,
@@ -367,6 +370,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU( ID_CLEARLOG, MyFrame::OnClearLog )
EVT_MENU( ID_GET_PAGE_INFO, MyFrame::OnGetPageInfo )
EVT_MENU( ID_DISABLE, MyFrame::OnDisable )
EVT_MENU( ID_FOREGROUND_COLOUR, MyFrame::OnSetForegroundColour )
EVT_MENU( ID_BACKGROUND_COLOUR, MyFrame::OnSetBackgroundColour )
EVT_MENU( ID_CUSTOM_HEADER_ATTR, MyFrame::OnCustomHeaderAttr )
@@ -460,6 +464,7 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
wxMenu *file_menu = new wxMenu;
file_menu->Append(ID_CLEARLOG, "&Clear log\tCtrl-L");
file_menu->Append(ID_GET_PAGE_INFO, "Show current &page info");
file_menu->AppendCheckItem(ID_DISABLE, "&Disable\tCtrl-D");
file_menu->Append(ID_FOREGROUND_COLOUR, "Set &foreground colour...\tCtrl-S");
file_menu->Append(ID_BACKGROUND_COLOUR, "Set &background colour...\tCtrl-B");
file_menu->AppendCheckItem(ID_CUSTOM_HEADER_ATTR, "C&ustom header attributes");
@@ -685,6 +690,7 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
wxDataViewColumn *column5 =
new wxDataViewColumn( "custom", cr, 5, -1, wxALIGN_LEFT,
wxDATAVIEW_COL_RESIZABLE );
column5->SetBitmap(wxArtProvider::GetBitmap(wxART_INFORMATION, wxART_MENU));
m_ctrl[0]->AppendColumn( column5 );
@@ -830,6 +836,11 @@ void MyFrame::OnGetPageInfo(wxCommandEvent& WXUNUSED(event))
dvc->GetCountPerPage());
}
void MyFrame::OnDisable(wxCommandEvent& event)
{
m_ctrl[m_notebook->GetSelection()]->Enable(!event.IsChecked());
}
void MyFrame::OnSetForegroundColour(wxCommandEvent& WXUNUSED(event))
{
wxDataViewCtrl * const dvc = m_ctrl[m_notebook->GetSelection()];
@@ -934,6 +945,8 @@ void MyFrame::OnPageChanged( wxBookCtrlEvent& WXUNUSED(event) )
GetMenuBar()->FindItem(id)->Check( m_ctrl[nPanel]->HasFlag(style) );
}
GetMenuBar()->FindItem(ID_DISABLE)->Check(!m_ctrl[nPanel]->IsEnabled());
}
void MyFrame::OnStyleChange( wxCommandEvent& WXUNUSED(event) )

View File

@@ -95,9 +95,6 @@ wxFont wxDataViewItemAttr::GetEffectiveFont(const wxFont& font) const
// wxDataViewModelNotifier
// ---------------------------------------------------------
#include "wx/listimpl.cpp"
WX_DEFINE_LIST(wxDataViewModelNotifiers)
bool wxDataViewModelNotifier::ItemsAdded( const wxDataViewItem &parent, const wxDataViewItemArray &items )
{
size_t count = items.GetCount();
@@ -134,7 +131,15 @@ bool wxDataViewModelNotifier::ItemsChanged( const wxDataViewItemArray &items )
wxDataViewModel::wxDataViewModel()
{
m_notifiers.DeleteContents( true );
}
wxDataViewModel::~wxDataViewModel()
{
wxDataViewModelNotifiers::const_iterator iter;
for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
{
delete *iter;
}
}
bool wxDataViewModel::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item )
@@ -305,7 +310,20 @@ void wxDataViewModel::AddNotifier( wxDataViewModelNotifier *notifier )
void wxDataViewModel::RemoveNotifier( wxDataViewModelNotifier *notifier )
{
m_notifiers.DeleteObject( notifier );
wxDataViewModelNotifiers::iterator iter;
for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
{
if ( *iter == notifier )
{
delete notifier;
m_notifiers.erase(iter);
// Skip the assert below.
return;
}
}
wxFAIL_MSG(wxS("Removing non-registered notifier"));
}
int wxDataViewModel::Compare( const wxDataViewItem &item1, const wxDataViewItem &item2,
@@ -2408,9 +2426,6 @@ wxDataViewTreeStoreNode::~wxDataViewTreeStoreNode()
delete m_data;
}
#include "wx/listimpl.cpp"
WX_DEFINE_LIST(wxDataViewTreeStoreNodeList)
wxDataViewTreeStoreContainerNode::wxDataViewTreeStoreContainerNode(
wxDataViewTreeStoreNode *parent, const wxString &text,
const wxIcon &icon, const wxIcon &expanded, wxClientData *data )
@@ -2418,11 +2433,35 @@ wxDataViewTreeStoreContainerNode::wxDataViewTreeStoreContainerNode(
, m_iconExpanded(expanded)
{
m_isExpanded = false;
m_children.DeleteContents(true);
}
wxDataViewTreeStoreContainerNode::~wxDataViewTreeStoreContainerNode()
{
DestroyChildren();
}
wxDataViewTreeStoreNodes::iterator
wxDataViewTreeStoreContainerNode::FindChild(wxDataViewTreeStoreNode* node)
{
wxDataViewTreeStoreNodes::iterator iter;
for (iter = m_children.begin(); iter != m_children.end(); ++iter)
{
if ( *iter == node )
break;
}
return iter;
}
void wxDataViewTreeStoreContainerNode::DestroyChildren()
{
wxDataViewTreeStoreNodes::const_iterator iter;
for (iter = m_children.begin(); iter != m_children.end(); ++iter)
{
delete *iter;
}
m_children.clear();
}
//-----------------------------------------------------------------------------
@@ -2445,7 +2484,7 @@ wxDataViewItem wxDataViewTreeStore::AppendItem( const wxDataViewItem& parent,
wxDataViewTreeStoreNode *node =
new wxDataViewTreeStoreNode( parent_node, text, icon, data );
parent_node->GetChildren().Append( node );
parent_node->GetChildren().push_back( node );
return node->GetItem();
}
@@ -2458,7 +2497,8 @@ wxDataViewItem wxDataViewTreeStore::PrependItem( const wxDataViewItem& parent,
wxDataViewTreeStoreNode *node =
new wxDataViewTreeStoreNode( parent_node, text, icon, data );
parent_node->GetChildren().Insert( node );
wxDataViewTreeStoreNodes& children = parent_node->GetChildren();
children.insert(children.begin(), node);
return node->GetItem();
}
@@ -2474,12 +2514,13 @@ wxDataViewTreeStore::InsertItem(const wxDataViewItem& parent,
if (!parent_node) return wxDataViewItem(0);
wxDataViewTreeStoreNode *previous_node = FindNode( previous );
int pos = parent_node->GetChildren().IndexOf( previous_node );
if (pos == wxNOT_FOUND) return wxDataViewItem(0);
wxDataViewTreeStoreNodes& children = parent_node->GetChildren();
const wxDataViewTreeStoreNodes::iterator iter = parent_node->FindChild( previous_node );
if (iter == children.end()) return wxDataViewItem(0);
wxDataViewTreeStoreNode *node =
new wxDataViewTreeStoreNode( parent_node, text, icon, data );
parent_node->GetChildren().Insert( (size_t) pos, node );
children.insert(iter, node);
return node->GetItem();
}
@@ -2493,7 +2534,8 @@ wxDataViewItem wxDataViewTreeStore::PrependContainer( const wxDataViewItem& pare
wxDataViewTreeStoreContainerNode *node =
new wxDataViewTreeStoreContainerNode( parent_node, text, icon, expanded, data );
parent_node->GetChildren().Insert( node );
wxDataViewTreeStoreNodes& children = parent_node->GetChildren();
children.insert(children.begin(), node);
return node->GetItem();
}
@@ -2510,7 +2552,7 @@ wxDataViewTreeStore::AppendContainer(const wxDataViewItem& parent,
wxDataViewTreeStoreContainerNode *node =
new wxDataViewTreeStoreContainerNode( parent_node, text, icon, expanded, data );
parent_node->GetChildren().Append( node );
parent_node->GetChildren().push_back( node );
return node->GetItem();
}
@@ -2527,12 +2569,13 @@ wxDataViewTreeStore::InsertContainer(const wxDataViewItem& parent,
if (!parent_node) return wxDataViewItem(0);
wxDataViewTreeStoreNode *previous_node = FindNode( previous );
int pos = parent_node->GetChildren().IndexOf( previous_node );
if (pos == wxNOT_FOUND) return wxDataViewItem(0);
wxDataViewTreeStoreNodes& children = parent_node->GetChildren();
const wxDataViewTreeStoreNodes::iterator iter = parent_node->FindChild( previous_node );
if (iter == children.end()) return wxDataViewItem(0);
wxDataViewTreeStoreContainerNode *node =
new wxDataViewTreeStoreContainerNode( parent_node, text, icon, expanded, data );
parent_node->GetChildren().Insert( (size_t) pos, node );
children.insert(iter, node);
return node->GetItem();
}
@@ -2550,7 +2593,7 @@ wxDataViewItem wxDataViewTreeStore::GetNthChild( const wxDataViewItem& parent, u
wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent );
if (!parent_node) return wxDataViewItem(0);
wxDataViewTreeStoreNodeList::compatibility_iterator node = parent_node->GetChildren().Item( pos );
wxDataViewTreeStoreNode* const node = parent_node->GetChildren()[pos];
if (node)
return wxDataViewItem(node->GetData());
@@ -2566,7 +2609,7 @@ int wxDataViewTreeStore::GetChildCount( const wxDataViewItem& parent ) const
return 0;
wxDataViewTreeStoreContainerNode *container_node = (wxDataViewTreeStoreContainerNode*) node;
return (int) container_node->GetChildren().GetCount();
return (int) container_node->GetChildren().size();
}
void wxDataViewTreeStore::SetItemText( const wxDataViewItem& item, const wxString &text )
@@ -2642,7 +2685,13 @@ void wxDataViewTreeStore::DeleteItem( const wxDataViewItem& item )
wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent_item );
if (!parent_node) return;
parent_node->GetChildren().DeleteObject( FindNode(item) );
const wxDataViewTreeStoreNodes::iterator
iter = parent_node->FindChild(FindNode(item));
if ( iter != parent_node->GetChildren().end() )
{
delete *iter;
parent_node->GetChildren().erase(iter);
}
}
void wxDataViewTreeStore::DeleteChildren( const wxDataViewItem& item )
@@ -2650,7 +2699,7 @@ void wxDataViewTreeStore::DeleteChildren( const wxDataViewItem& item )
wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
if (!node) return;
node->GetChildren().clear();
node->DestroyChildren();
}
void wxDataViewTreeStore::DeleteAllItems()
@@ -2720,14 +2769,14 @@ unsigned int wxDataViewTreeStore::GetChildren( const wxDataViewItem &item, wxDat
wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
if (!node) return 0;
wxDataViewTreeStoreNodeList::iterator iter;
wxDataViewTreeStoreNodes::iterator iter;
for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); ++iter)
{
wxDataViewTreeStoreNode* child = *iter;
children.Add( child->GetItem() );
}
return node->GetChildren().GetCount();
return node->GetChildren().size();
}
int wxDataViewTreeStore::Compare( const wxDataViewItem &item1, const wxDataViewItem &item2,
@@ -2736,19 +2785,14 @@ int wxDataViewTreeStore::Compare( const wxDataViewItem &item1, const wxDataViewI
wxDataViewTreeStoreNode *node1 = FindNode( item1 );
wxDataViewTreeStoreNode *node2 = FindNode( item2 );
if (!node1 || !node2)
if (!node1 || !node2 || (node1 == node2))
return 0;
wxDataViewTreeStoreContainerNode* parent1 =
wxDataViewTreeStoreContainerNode* const parent =
(wxDataViewTreeStoreContainerNode*) node1->GetParent();
wxDataViewTreeStoreContainerNode* parent2 =
(wxDataViewTreeStoreContainerNode*) node2->GetParent();
if (parent1 != parent2)
{
wxLogError( wxT("Comparing items with different parent.") );
return 0;
}
wxCHECK_MSG( node2->GetParent() == parent, 0,
wxS("Comparing items with different parent.") );
if (node1->IsContainer() && !node2->IsContainer())
return -1;
@@ -2756,7 +2800,18 @@ int wxDataViewTreeStore::Compare( const wxDataViewItem &item1, const wxDataViewI
if (node2->IsContainer() && !node1->IsContainer())
return 1;
return parent1->GetChildren().IndexOf( node1 ) - parent2->GetChildren().IndexOf( node2 );
wxDataViewTreeStoreNodes::const_iterator iter;
for (iter = parent->GetChildren().begin(); iter != parent->GetChildren().end(); ++iter)
{
if ( *iter == node1 )
return -1;
if ( *iter == node2 )
return 1;
}
wxFAIL_MSG(wxS("Unreachable"));
return 0;
}
wxDataViewTreeStoreNode *wxDataViewTreeStore::FindNode( const wxDataViewItem &item ) const
@@ -2925,7 +2980,7 @@ void wxDataViewTreeCtrl::DeleteChildren( const wxDataViewItem& item )
if (!node) return;
wxDataViewItemArray array;
wxDataViewTreeStoreNodeList::iterator iter;
wxDataViewTreeStoreNodes::iterator iter;
for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); ++iter)
{
wxDataViewTreeStoreNode* child = *iter;

View File

@@ -75,15 +75,6 @@ static const int SCROLL_UNIT_X = 15;
// the cell padding on the left/right
static const int PADDING_RIGHTLEFT = 3;
// the expander space margin
static const int EXPANDER_MARGIN = 4;
#ifdef __WXMSW__
static const int EXPANDER_OFFSET = 4;
#else
static const int EXPANDER_OFFSET = 1;
#endif
namespace
{
@@ -273,7 +264,9 @@ class wxDataViewHeaderWindow : public wxHeaderCtrl
{
public:
wxDataViewHeaderWindow(wxDataViewCtrl *parent)
: wxHeaderCtrl(parent)
: wxHeaderCtrl(parent, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxHD_DEFAULT_STYLE | wxHD_BITMAP_ON_RIGHT)
{
}
@@ -939,9 +932,6 @@ private:
// the pen used to draw horiz/vertical rules
wxPen m_penRule;
// the pen used to draw the expander and the lines
wxPen m_penExpander;
// This is the tree structure of the model
wxDataViewTreeNode * m_root;
int m_count;
@@ -1383,7 +1373,18 @@ wxString wxDataViewProgressRenderer::GetAccessibleDescription() const
bool
wxDataViewProgressRenderer::Render(wxRect rect, wxDC *dc, int WXUNUSED(state))
{
wxRendererNative::Get().DrawGauge(
const wxDataViewItemAttr& attr = GetAttr();
if ( attr.HasColour() )
dc->SetBackground(attr.GetColour());
// This is a hack, but native renderers don't support using custom colours,
// but typically gauge colour is important (e.g. it's commonly green/red to
// indicate some qualitative difference), so we fall back to the generic
// implementation which looks ugly but does support using custom colour.
wxRendererNative& renderer = attr.HasColour()
? wxRendererNative::GetGeneric()
: wxRendererNative::Get();
renderer.DrawGauge(
GetOwner()->GetOwner(),
*dc,
rect,
@@ -1966,10 +1967,6 @@ wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID i
m_penRule = wxPen(GetRuleColour());
// compose a pen whichcan draw black lines
// TODO: maybe there is something system colour to use
m_penExpander = wxPen(wxColour(0,0,0));
m_root = wxDataViewTreeNode::CreateRootNode();
// Make m_count = -1 will cause the class recaculate the real displaying number of rows.
@@ -2540,23 +2537,17 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
// Calculate the indent first
indent = GetOwner()->GetIndent() * node->GetIndentLevel();
// we reserve m_lineHeight of horizontal space for the expander
// but leave EXPANDER_MARGIN around the expander itself
int exp_x = cell_rect.x + indent + EXPANDER_MARGIN;
// We don't have any method to return the size of the expander
// button currently (TODO: add one to wxRendererNative), so
// just guesstimate it.
const int expWidth = 3*dc.GetCharWidth();
indent += m_lineHeight;
// draw expander if needed and visible
if ( node->HasChildren() && exp_x < cell_rect.GetRight() )
// draw expander if needed
if ( node->HasChildren() )
{
dc.SetPen( m_penExpander );
dc.SetBrush( wxNullBrush );
int exp_size = m_lineHeight - 2*EXPANDER_MARGIN;
int exp_y = cell_rect.y + (cell_rect.height - exp_size)/2
+ EXPANDER_MARGIN - EXPANDER_OFFSET;
const wxRect rect(exp_x, exp_y, exp_size, exp_size);
wxRect rect = cell_rect;
rect.x += indent;
rect.width = expWidth;
int flag = 0;
if ( m_underMouse == node )
@@ -2571,6 +2562,8 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag);
}
indent += expWidth;
// force the expander column to left-center align
cell->SetAlignment( wxALIGN_CENTER_VERTICAL );
}
@@ -4728,9 +4721,9 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
if ( UnselectAllRows(m_lineSelectSingleOnUp) )
{
SelectRow( m_lineSelectSingleOnUp, true );
SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) );
}
//else: it was already selected, nothing to do
SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) );
}
// If the user click the expander, we do not do editing even if the column
@@ -5228,17 +5221,6 @@ bool wxDataViewCtrl::Show(bool show)
return changed;
}
bool wxDataViewCtrl::Enable(bool enable)
{
bool changed = wxControl::Enable(enable);
if ( changed )
{
wxAccessible::NotifyEvent(wxACC_EVENT_OBJECT_STATECHANGE, this, wxOBJID_CLIENT, wxACC_SELF);
}
return changed;
}
void wxDataViewCtrl::SetName(const wxString &name)
{
wxControl::SetName(name);
@@ -5257,6 +5239,20 @@ bool wxDataViewCtrl::Reparent(wxWindowBase *newParent)
}
#endif // wxUSE_ACCESIBILITY
bool wxDataViewCtrl::Enable(bool enable)
{
bool changed = wxControl::Enable(enable);
if ( changed )
{
#if wxUSE_ACCESSIBILITY
wxAccessible::NotifyEvent(wxACC_EVENT_OBJECT_STATECHANGE, this, wxOBJID_CLIENT, wxACC_SELF);
#endif // wxUSE_ACCESIBILITY
Refresh();
}
return changed;
}
bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model )
{
if (!wxDataViewCtrlBase::AssociateModel( model ))

View File

@@ -912,6 +912,18 @@ void wxRendererGeneric::DrawGauge(wxWindow* win,
int max,
int flags)
{
// This is a hack, but we want to allow customizing the colour used for the
// gauge body, as this is important for the generic wxDataViewCtrl
// implementation which uses this method. So we assume that if the caller
// had set up a brush using background colour different from the default,
// it should be used. Otherwise we use the default one.
const wxBrush& bg = dc.GetBackground();
wxColour colBar;
if ( bg.IsOk() && bg.GetColour() != win->GetBackgroundColour() )
colBar = bg.GetColour();
else
colBar = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
// Use same background as text controls.
DrawTextCtrl(win, dc, rect);
@@ -929,7 +941,7 @@ void wxRendererGeneric::DrawGauge(wxWindow* win,
progRect.width = wxMulDivInt32(progRect.width, value, max);
}
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
dc.SetBrush(colBar);
dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawRectangle(progRect);
}

View File

@@ -314,6 +314,9 @@ void wxHeaderCtrl::DoInsertItem(const wxHeaderColumn& col, unsigned int idx)
{
hdi.mask |= HDI_IMAGE;
if ( HasFlag(wxHD_BITMAP_ON_RIGHT) )
hdi.fmt |= HDF_BITMAP_ON_RIGHT;
if ( bmp.IsOk() )
{
const int bmpWidth = bmp.GetWidth(),

View File

@@ -4169,6 +4169,14 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
return false;
}
if ( ContainsHWND(hwnd) )
{
// If another subwindow of this window already had focus before, this
// window should already have focus at wx level, no need for another
// event.
return false;
}
// notify the parent keeping track of focus for the kbd navigation
// purposes that we got it
wxChildFocusEvent eventFocus((wxWindow *)this);
@@ -4193,6 +4201,20 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
{
// Don't send the event when in the process of being deleted. This can
// only cause problems if the event handler tries to access the object.
if ( m_isBeingDeleted )
{
return false;
}
if ( ContainsHWND(hwnd) )
{
// If the focus switches to another HWND which is part of the same
// wxWindow, we must not generate a wxEVT_KILL_FOCUS.
return false;
}
#if wxUSE_CARET
// Deal with caret
if ( m_caret )
@@ -4201,13 +4223,6 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
}
#endif // wxUSE_CARET
// Don't send the event when in the process of being deleted. This can
// only cause problems if the event handler tries to access the object.
if ( m_isBeingDeleted )
{
return false;
}
wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
event.SetEventObject(this);

View File

@@ -3507,25 +3507,29 @@ void wxDataViewColumn::SetSortable(bool sortable)
void wxDataViewColumn::SetSortOrder(bool ascending)
{
if (m_ascending != ascending)
NSTableColumn* const tableColumn = m_NativeDataPtr->GetNativeColumnPtr();
NSTableView* tableView = [tableColumn tableView];
wxCHECK_RET( tableView, wxS("Column has to be associated with a table view when the sorting order is set") );
if ( (m_ascending != ascending) || ([tableColumn sortDescriptorPrototype] == nil) )
{
m_ascending = ascending;
if (IsSortKey())
{
// change sorting order:
NSArray* sortDescriptors;
NSSortDescriptor* sortDescriptor;
NSTableColumn* tableColumn;
tableColumn = m_NativeDataPtr->GetNativeColumnPtr();
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:[[tableColumn sortDescriptorPrototype] key] ascending:m_ascending];
sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
// change sorting order for the native implementation (this will
// trigger a call to outlineView:sortDescriptorsDidChange: where the
// wxWidget's sort descriptors are going to be set):
NSSortDescriptor* const
sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:[NSString stringWithFormat:@"%ld",(long)[tableView columnWithIdentifier:[tableColumn identifier]]]
ascending:m_ascending];
NSArray* sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[tableColumn setSortDescriptorPrototype:sortDescriptor];
[[tableColumn tableView] setSortDescriptors:sortDescriptors];
[tableView setSortDescriptors:sortDescriptors];
[sortDescriptor release];
}
}
}
void wxDataViewColumn::SetTitle(const wxString& title)
{