Applied #9011: Native wxListCtrl::HitTest on OS X

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@62113 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
2009-09-25 09:06:07 +00:00
parent f0bd165e49
commit f3fc0413d6
3 changed files with 124 additions and 46 deletions

View File

@@ -802,6 +802,8 @@ public :
OSStatus SetHeaderDesc( DataBrowserPropertyID property, DataBrowserListViewHeaderDesc *desc ); OSStatus SetHeaderDesc( DataBrowserPropertyID property, DataBrowserListViewHeaderDesc *desc );
OSStatus SetDisclosureColumn( DataBrowserPropertyID property , Boolean expandableRows ); OSStatus SetDisclosureColumn( DataBrowserPropertyID property , Boolean expandableRows );
OSStatus GetItemPartBounds( DataBrowserItemID item, DataBrowserPropertyID property, DataBrowserPropertyPart part, Rect * bounds );
protected : protected :
static pascal void DataBrowserItemNotificationProc( static pascal void DataBrowserItemNotificationProc(

View File

@@ -103,7 +103,7 @@ wxEND_HANDLERS_TABLE()
wxCONSTRUCTOR_5( wxListCtrl , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle ) wxCONSTRUCTOR_5( wxListCtrl , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle )
/* /*
TODO : Expose more information of a list's layout etc. via appropriate objects (<EFBFBD> la NotebookPageInfo) TODO : Expose more information of a list's layout etc. via appropriate objects (a la NotebookPageInfo)
*/ */
#else #else
IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl) IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl)
@@ -619,7 +619,7 @@ void wxListCtrl::OnLeftDown(wxMouseEvent& event)
int hitResult; int hitResult;
long current = HitTest(event.GetPosition(), hitResult); long current = HitTest(event.GetPosition(), hitResult);
if ((current == m_current) && if ((current == m_current) &&
(hitResult == wxLIST_HITTEST_ONITEM) && (hitResult & wxLIST_HITTEST_ONITEMLABEL) &&
HasFlag(wxLC_EDIT_LABELS) ) HasFlag(wxLC_EDIT_LABELS) )
{ {
m_renameTimer->Start( 100, true ); m_renameTimer->Start( 100, true );
@@ -2019,11 +2019,16 @@ long wxListCtrl::FindItem(long start, const wxPoint& pt, int direction)
return -1; return -1;
} }
static void calculateCGDrawingBounds(CGRect inItemRect, CGRect *outIconRect, CGRect *outTextRect, bool hasIcon = false);
// Determines which item (if any) is at the specified point, // Determines which item (if any) is at the specified point,
// giving details in 'flags' (see wxLIST_HITTEST_... flags above) // giving details in 'flags' (see wxLIST_HITTEST_... flags above)
long long
wxListCtrl::HitTest(const wxPoint& point, int& flags, long *ptrSubItem) const wxListCtrl::HitTest(const wxPoint& point, int& flags, long *ptrSubItem) const
{ {
if (ptrSubItem)
*ptrSubItem = -1;
if (m_genericImpl) if (m_genericImpl)
return m_genericImpl->HitTest(point, flags, ptrSubItem); return m_genericImpl->HitTest(point, flags, ptrSubItem);
@@ -2050,26 +2055,93 @@ wxListCtrl::HitTest(const wxPoint& point, int& flags, long *ptrSubItem) const
DataBrowserItemID id; DataBrowserItemID id;
m_dbImpl->GetItemID( (DataBrowserTableViewRowIndex) row, &id ); m_dbImpl->GetItemID( (DataBrowserTableViewRowIndex) row, &id );
// TODO: Use GetDataBrowserItemPartBounds to return if we are in icon or label CGPoint click_point = CGPointMake( point.x, point.y );
if ( !(GetWindowStyleFlag() & wxLC_VIRTUAL ) && row < GetItemCount() ) if (row < GetItemCount() )
{
short column;
for( column = 0; column < GetColumnCount(); column++ )
{
Rect enclosingRect;
CGRect enclosingCGRect, iconCGRect, textCGRect;
int imgIndex = -1;
wxMacListCtrlItem* lcItem;
WXUNUSED_UNLESS_DEBUG( OSStatus status = ) m_dbImpl->GetItemPartBounds( id, kMinColumnId + column, kDataBrowserPropertyEnclosingPart, &enclosingRect );
wxASSERT( status == noErr );
enclosingCGRect = CGRectMake(enclosingRect.left,
enclosingRect.top,
enclosingRect.right - enclosingRect.left,
enclosingRect.bottom - enclosingRect.top);
if (column >= 0)
{
if ( !(GetWindowStyleFlag() & wxLC_VIRTUAL ) )
{
lcItem = (wxMacListCtrlItem*) id;
if (lcItem->HasColumnInfo(column))
{
wxListItem* item = lcItem->GetColumnInfo(column);
if (item->GetMask() & wxLIST_MASK_IMAGE)
{
imgIndex = item->GetImage();
}
}
}
else
{
long itemNum = (long)id-1;
if (itemNum >= 0 && itemNum < GetItemCount())
{
imgIndex = OnGetItemColumnImage( itemNum, column );
}
}
}
calculateCGDrawingBounds(enclosingCGRect, &iconCGRect, &textCGRect, (imgIndex != -1) );
if ( CGRectContainsPoint( iconCGRect, click_point ) )
{
flags = wxLIST_HITTEST_ONITEMICON;
if (ptrSubItem)
*ptrSubItem = column;
return row;
}
else if ( CGRectContainsPoint( textCGRect, click_point ) )
{
flags = wxLIST_HITTEST_ONITEMLABEL;
if (ptrSubItem)
*ptrSubItem = column;
return row;
}
}
if ( !(GetWindowStyleFlag() & wxLC_VIRTUAL ) )
{ {
wxMacListCtrlItem* lcItem; wxMacListCtrlItem* lcItem;
lcItem = (wxMacListCtrlItem*) id; lcItem = (wxMacListCtrlItem*) id;
if (lcItem) if (lcItem)
{ {
flags = wxLIST_HITTEST_ONITEM; flags = wxLIST_HITTEST_ONITEM;
if (ptrSubItem)
*ptrSubItem = column;
return row; return row;
} }
} }
else else
{
if (row < GetItemCount() )
{ {
flags = wxLIST_HITTEST_ONITEM; flags = wxLIST_HITTEST_ONITEM;
if (ptrSubItem)
*ptrSubItem = column;
return row; return row;
} }
} }
else
{
if ( wxControl::HitTest( point ) )
flags = wxLIST_HITTEST_NOWHERE;
}
} }
return -1; return -1;
} }
@@ -2698,7 +2770,7 @@ enum
kContentHeight = kIconHeight + kTextBoxHeight + kIconTextSpacingV kContentHeight = kIconHeight + kTextBoxHeight + kIconTextSpacingV
}; };
static void calculateCGDrawingBounds(CGRect inItemRect, CGRect *outIconRect, CGRect *outTextRect, bool hasIcon = false) static void calculateCGDrawingBounds(CGRect inItemRect, CGRect *outIconRect, CGRect *outTextRect, bool hasIcon)
{ {
float textBottom; float textBottom;
float iconH, iconW = 0; float iconH, iconW = 0;
@@ -2801,6 +2873,8 @@ void wxMacDataBrowserListCtrlControl::DrawItem(
ThemeDrawingState savedState = NULL; ThemeDrawingState savedState = NULL;
#endif #endif
CGContextRef context = (CGContextRef)list->MacGetDrawingContext(); CGContextRef context = (CGContextRef)list->MacGetDrawingContext();
wxMacCGContextStateSaver top_saver_cg( context );
RGBColor labelColor; RGBColor labelColor;
labelColor.red = 0; labelColor.red = 0;
labelColor.green = 0; labelColor.green = 0;
@@ -2844,14 +2918,13 @@ void wxMacDataBrowserListCtrlControl::DrawItem(
GetThemeBrushAsColor(kThemeBrushSecondaryHighlightColor, 32, true, &backgroundColor); GetThemeBrushAsColor(kThemeBrushSecondaryHighlightColor, 32, true, &backgroundColor);
GetThemeTextColor(kThemeTextColorBlack, gdDepth, colorDevice, &labelColor); GetThemeTextColor(kThemeTextColorBlack, gdDepth, colorDevice, &labelColor);
} }
CGContextSaveGState(context); wxMacCGContextStateSaver cg( context );
CGContextSetRGBFillColor(context, (float)backgroundColor.red / (float)USHRT_MAX, CGContextSetRGBFillColor(context,
(float)backgroundColor.red / (float)USHRT_MAX,
(float)backgroundColor.green / (float)USHRT_MAX, (float)backgroundColor.green / (float)USHRT_MAX,
(float)backgroundColor.blue / (float)USHRT_MAX, 1.0); (float)backgroundColor.blue / (float)USHRT_MAX, 1.0);
CGContextFillRect(context, enclosingCGRect); CGContextFillRect(context, enclosingCGRect);
CGContextRestoreGState(context);
} }
else else
{ {
@@ -2864,14 +2937,13 @@ void wxMacDataBrowserListCtrlControl::DrawItem(
if (bgColor.Ok()) if (bgColor.Ok())
{ {
backgroundColor = MAC_WXCOLORREF( bgColor.GetPixel() ); backgroundColor = MAC_WXCOLORREF( bgColor.GetPixel() );
CGContextSaveGState(context); wxMacCGContextStateSaver cg( context );
CGContextSetRGBFillColor(context, (float)backgroundColor.red / (float)USHRT_MAX, CGContextSetRGBFillColor(context,
(float)backgroundColor.red / (float)USHRT_MAX,
(float)backgroundColor.green / (float)USHRT_MAX, (float)backgroundColor.green / (float)USHRT_MAX,
(float)backgroundColor.blue / (float)USHRT_MAX, 1.0); (float)backgroundColor.blue / (float)USHRT_MAX, 1.0);
CGContextFillRect(context, enclosingCGRect); CGContextFillRect(context, enclosingCGRect);
CGContextRestoreGState(context);
} }
} }
@@ -2884,14 +2956,13 @@ void wxMacDataBrowserListCtrlControl::DrawItem(
wxBitmap bmp = imageList->GetBitmap(imgIndex); wxBitmap bmp = imageList->GetBitmap(imgIndex);
IconRef icon = bmp.GetBitmapData()->GetIconRef(); IconRef icon = bmp.GetBitmapData()->GetIconRef();
CGContextSaveGState(context); wxMacCGContextStateSaver cg( context );
CGContextTranslateCTM(context, 0,iconCGRect.origin.y + CGRectGetMaxY(iconCGRect)); CGContextTranslateCTM(context, 0,iconCGRect.origin.y + CGRectGetMaxY(iconCGRect));
CGContextScaleCTM(context,1.0f,-1.0f); CGContextScaleCTM(context,1.0f,-1.0f);
PlotIconRefInContext(context, &iconCGRect, kAlignNone, PlotIconRefInContext(context, &iconCGRect, kAlignNone,
active ? kTransformNone : kTransformDisabled, NULL, active ? kTransformNone : kTransformDisabled, NULL,
kPlotIconRefNormalFlags, icon); kPlotIconRefNormalFlags, icon);
CGContextRestoreGState(context);
} }
} }
@@ -2941,14 +3012,14 @@ void wxMacDataBrowserListCtrlControl::DrawItem(
info.truncationPosition = kHIThemeTextTruncationEnd; info.truncationPosition = kHIThemeTextTruncationEnd;
info.truncationMaxLines = 1; info.truncationMaxLines = 1;
CGContextSaveGState(context); {
wxMacCGContextStateSaver cg( context );
CGContextSetRGBFillColor (context, (float)labelColor.red / (float)USHRT_MAX, CGContextSetRGBFillColor (context, (float)labelColor.red / (float)USHRT_MAX,
(float)labelColor.green / (float)USHRT_MAX, (float)labelColor.green / (float)USHRT_MAX,
(float)labelColor.blue / (float)USHRT_MAX, 1.0); (float)labelColor.blue / (float)USHRT_MAX, 1.0);
HIThemeDrawTextBox(cfString, &textCGRect, &info, context, kHIThemeOrientationNormal); HIThemeDrawTextBox(cfString, &textCGRect, &info, context, kHIThemeOrientationNormal);
}
CGContextRestoreGState(context);
#ifndef __LP64__ #ifndef __LP64__
if (savedState != NULL) if (savedState != NULL)

View File

@@ -1644,6 +1644,11 @@ OSStatus wxMacDataBrowserControl::SetDisclosureColumn( DataBrowserPropertyID pro
return SetDataBrowserListViewDisclosureColumn( m_controlRef, property, expandableRows); return SetDataBrowserListViewDisclosureColumn( m_controlRef, property, expandableRows);
} }
OSStatus wxMacDataBrowserControl::GetItemPartBounds( DataBrowserItemID item, DataBrowserPropertyID property, DataBrowserPropertyPart part, Rect * bounds )
{
return GetDataBrowserItemPartBounds( m_controlRef, item, property, part, bounds);
}
// ============================================================================ // ============================================================================
// Higher-level Databrowser // Higher-level Databrowser
// ============================================================================ // ============================================================================