// --------------------------------------------------------------------------------------
pascal void DrawIconDataBrowserItem86CB(ControlRef browser, DataBrowserItemID item, 
										DataBrowserPropertyID property, 
										DataBrowserItemState itemState, const Rect *theRect, 
										SInt16 gdDepth, Boolean colorDevice)
{
#pragma unused (theRect)
	Rect enclosingRect, iconRect, textRect;
	Boolean active;
	IconDBItemDataRec *itemData;
	
		/* The data browser currently gives us the content part bounds in the theRect 
		   parameter but we want the enclosing part bounds to draw in so that we can 
		   draw a fill style highlight. */
	GetDataBrowserItemPartBounds(browser, item, property, kDataBrowserPropertyEnclosingPart, 
									&enclosingRect);
	
	active = IsControlActive(browser);
	
	if ((itemState & kDataBrowserItemIsSelected) != 0)
	{
		ThemeDrawingState savedState;
		
		GetThemeDrawingState(&savedState);
		
		SetThemePen(active ? kThemeBrushPrimaryHighlightColor : kThemeBrushSecondaryHighlightColor, 
					gdDepth, colorDevice);
		PaintRect(&enclosingRect);
		
		SetThemeDrawingState(savedState, true);
	}
	
	calculateDrawingBounds(&enclosingRect, &iconRect, &textRect);
	itemData = (IconDBItemDataRec *)item;
	
	PlotIconRef(&iconRect, kAlignNone, active ? kTransformNone : kTransformDisabled, 
				kIconServicesNormalUsageFlag, itemData->icon);
	DrawThemeTextBox(itemData->name, kThemeViewsFont, 
						active ? kThemeStateActive : kThemeStateInactive, true, 
						&textRect, teCenter, NULL);
}
Example #2
0
int wxMacDataBrowserListControl::DoListHitTest(const wxPoint& inpoint) const
{
    OSStatus err;

    // There are few reasons why this is complicated:
    // 1) There is no native HitTest function for Mac
    // 2) GetDataBrowserItemPartBounds only works on visible items
    // 3) We can't do it through GetDataBrowserTableView[Item]RowHeight
    //    because what it returns is basically inaccurate in the context
    //    of the coordinates we want here, but we use this as a guess
    //    for where the first visible item lies

    wxPoint point = inpoint;

    // get column property ID (req. for call to itempartbounds)
    DataBrowserTableViewColumnID colId = 0;
    err = GetDataBrowserTableViewColumnProperty(GetControlRef(), 0, &colId);
    wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserTableViewColumnProperty"));

    // OK, first we need to find the first visible item we have -
    // this will be the "low" for our binary search. There is no real
    // easy way around this, as we will need to do a SLOW linear search
    // until we find a visible item, but we can do a cheap calculation
    // via the row height to speed things up a bit
    UInt32 scrollx, scrolly;
    err = GetDataBrowserScrollPosition(GetControlRef(), &scrollx, &scrolly);
    wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserScrollPosition"));

    UInt16 height;
    err = GetDataBrowserTableViewRowHeight(GetControlRef(), &height);
    wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserTableViewRowHeight"));

    wxListBox *list = wxDynamicCast( GetWXPeer() , wxListBox );

    // these indices are 0-based, as usual, so we need to add 1 to them when
    // passing them to data browser functions which use 1-based indices
    int low = scrolly / height,
        high = list->GetCount() - 1;

    // search for the first visible item (note that the scroll guess above
    // is the low bounds of where the item might lie so we only use that as a
    // starting point - we should reach it within 1 or 2 iterations of the loop)
    while ( low <= high )
    {
        Rect bounds;
        err = GetDataBrowserItemPartBounds(
            GetControlRef(), low + 1, colId,
            kDataBrowserPropertyEnclosingPart,
            &bounds); // note +1 to translate to Mac ID
        if ( err == noErr )
            break;

        // errDataBrowserItemNotFound is expected as it simply means that the
        // item is not currently visible -- but other errors are not
        wxCHECK_MSG( err == errDataBrowserItemNotFound, wxNOT_FOUND,
                     wxT("Unexpected error from GetDataBrowserItemPartBounds") );

        low++;
    }

    // NOW do a binary search for where the item lies, searching low again if
    // we hit an item that isn't visible
    while ( low <= high )
    {
        int mid = (low + high) / 2;

        Rect bounds;
        err = GetDataBrowserItemPartBounds(
            GetControlRef(), mid + 1, colId,
            kDataBrowserPropertyEnclosingPart,
            &bounds); //note +1 to trans to mac id
        wxCHECK_MSG( err == noErr || err == errDataBrowserItemNotFound,
                     wxNOT_FOUND,
                     wxT("Unexpected error from GetDataBrowserItemPartBounds") );

        if ( err == errDataBrowserItemNotFound )
        {
            // item not visible, attempt to find a visible one
            // search lower
            high = mid - 1;
        }
        else // visible item, do actual hitttest
        {
            // if point is within the bounds, return this item (since we assume
            // all x coords of items are equal we only test the x coord in
            // equality)
            if ((point.x >= bounds.left && point.x <= bounds.right) &&
                (point.y >= bounds.top && point.y <= bounds.bottom) )
            {
                // found!
                return mid;
            }

            if ( point.y < bounds.top )
                // index(bounds) greater than key(point)
                high = mid - 1;
            else
                // index(bounds) less than key(point)
                low = mid + 1;
        }
    }

    return wxNOT_FOUND;
}
Example #3
0
OSStatus wxMacDataBrowserControl::GetItemPartBounds( DataBrowserItemID item, DataBrowserPropertyID property, DataBrowserPropertyPart part, Rect * bounds )
{
    return GetDataBrowserItemPartBounds( m_controlRef, item, property, part, bounds);
}
// --------------------------------------------------------------------------------------
pascal void DrawIconDataBrowserItem104CB(ControlRef browser, DataBrowserItemID item, 
											DataBrowserPropertyID property, 
											DataBrowserItemState itemState, 
											const Rect *theRect, SInt16 gdDepth, 
											Boolean colorDevice)
{
#pragma unused (theRect, gdDepth, colorDevice)
	Rect enclosingRect, portBounds;
	GrafPtr port;
	CGRect enclosingCGRect, iconCGRect, textCGRect;
	Boolean active;
	CGContextRef context;
	IconDBItemDataRec *itemData;
	RGBColor labelColor;
	HIThemeTextInfo textInfo;
	
		/* The data browser currently gives us the content part bounds in the theRect 
		   parameter but we want the enclosing part bounds to draw in so that we can 
		   draw a fill style highlight. */
	GetDataBrowserItemPartBounds(browser, item, property, kDataBrowserPropertyEnclosingPart, 
									&enclosingRect);
	
		/* In Mac OS X we're going to use Quartz 2D/Core Graphics for the drawing, so we 
		   need to convert the enclosing part bounds to a CGRect */
	GetPort(&port);		// the data browser sets the port up for us so we just need to get it
	GetPortBounds(port, &portBounds);
	enclosingCGRect = CGRectMake(enclosingRect.left, 
									portBounds.bottom - portBounds.top - 
									enclosingRect.bottom, 
									enclosingRect.right - enclosingRect.left, 
									enclosingRect.bottom - enclosingRect.top);
	calculateCGDrawingBounds(enclosingCGRect, &iconCGRect, &textCGRect);
	
	active = IsControlActive(browser);
	
	if ((itemState & kDataBrowserItemIsSelected) != 0)
	{
		CGRect clipRect;
		
		clipRect = getClipCGRect(&portBounds);	// call this before beginning the context
		
		QDBeginCGContext(port, &context);
		CGContextClipToRect(context, clipRect);
		CGContextSaveGState(context);
		
		HIThemeSetFill(active ? kThemeBrushPrimaryHighlightColor : kThemeBrushSecondaryHighlightColor, 
						NULL, context, kHIThemeOrientationInverted);
		CGContextFillRect(context, enclosingCGRect);
		
		CGContextRestoreGState(context);
	}
	else
	{
			/* The data browser will redraw items on the edge of its content view.  
			   Because HIThemeDrawTextBox does not erase the drawing rectangle before 
			   it draws, the text becomes thicker with every draw due to anti-aliasing.  
			   As a workaround, this section erases the text rectangle (if the item was 
			   selected then the enclosing rectangle was erased above). */
		CGRect clipRect;
		RGBColor backgroundColor;
		
		clipRect = getClipCGRect(&portBounds);	// call these before beginning the context
		GetBackColor(&backgroundColor);
		
		QDBeginCGContext(port, &context);
		CGContextClipToRect(context, clipRect);
		CGContextSaveGState(context);
		
		CGContextSetRGBFillColor(context, (float)backgroundColor.red / (float)USHRT_MAX, 
									(float)backgroundColor.green / (float)USHRT_MAX, 
									(float)backgroundColor.blue / (float)USHRT_MAX, 1.0);
		CGContextFillRect(context, textCGRect);
		
		CGContextRestoreGState(context);
	}
	
	itemData = (IconDBItemDataRec *)item;
	
	labelColor.red = 0;
	labelColor.green = 0;
	labelColor.blue = 0;
	PlotIconRefInContext(context, &iconCGRect, kAlignNone, 
							active ? kTransformNone : kTransformDisabled, &labelColor, 
							kPlotIconRefNormalFlags, itemData->icon);
	
	textInfo.version = kHIThemeTextInfoVersionZero;
	textInfo.state = active ? kThemeStateActive : kThemeStateInactive;
	textInfo.fontID = kThemeViewsFont;
	textInfo.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
	textInfo.verticalFlushness = kHIThemeTextVerticalFlushTop;
	textInfo.options = kHIThemeTextBoxOptionNone;
	textInfo.truncationPosition = kHIThemeTextTruncationNone;
	HIThemeDrawTextBox(itemData->name, &textCGRect, &textInfo, context, 
						kHIThemeOrientationInverted);
	
	QDEndCGContext(port, &context);
} // DrawIconDataBrowserItem104CB
// --------------------------------------------------------------------------------------
pascal void DrawIconDataBrowserItem101CB(ControlRef browser, DataBrowserItemID item, 
											DataBrowserPropertyID property, 
											DataBrowserItemState itemState, 
											const Rect *theRect, SInt16 gdDepth, 
											Boolean colorDevice)
{
#pragma unused (theRect)
	Rect enclosingRect, portBounds, iconRect, textRect;
	GrafPtr port;
	CGRect enclosingCGRect, iconCGRect, textCGRect;
	Boolean active;
	ThemeDrawingState savedState = NULL;
	CGContextRef context;
	IconDBItemDataRec *itemData;
	RGBColor labelColor;
	
		/* The data browser currently gives us the content part bounds in the theRect 
		   parameter but we want the enclosing part bounds to draw in so that we can 
		   draw a fill style highlight. */
	GetDataBrowserItemPartBounds(browser, item, property, kDataBrowserPropertyEnclosingPart, 
									&enclosingRect);
	
		/* In Mac OS X we're going to use Quartz 2D/Core Graphics for the drawing, so we 
		   need to convert the enclosing part bounds to a CGRect */
	GetPort(&port);		// the data browser sets the port up for us so we just need to get it
	GetPortBounds(port, &portBounds);
	enclosingCGRect = CGRectMake(enclosingRect.left, 
									portBounds.bottom - portBounds.top - 
									enclosingRect.bottom, 
									enclosingRect.right - enclosingRect.left, 
									enclosingRect.bottom - enclosingRect.top);
	
	active = IsControlActive(browser);
	
	if ((itemState & kDataBrowserItemIsSelected) != 0)
	{
		CGRect clipRect;
		RGBColor foregroundColor;
		
		GetThemeDrawingState(&savedState);
		
		SetThemePen(active ? kThemeBrushPrimaryHighlightColor : kThemeBrushSecondaryHighlightColor, 
					gdDepth, colorDevice);

		clipRect = getClipCGRect(&portBounds);	// call these before beginning the context
		GetForeColor(&foregroundColor);
		
		QDBeginCGContext(port, &context);
		CGContextClipToRect(context, clipRect);
		CGContextSaveGState(context);
		
		CGContextSetRGBFillColor(context, (float)foregroundColor.red / (float)USHRT_MAX, 
									(float)foregroundColor.green / (float)USHRT_MAX, 
									(float)foregroundColor.blue / (float)USHRT_MAX, 1.0);
		CGContextFillRect(context, enclosingCGRect);
		
		CGContextRestoreGState(context);
	}
	else
	{
		CGRect clipRect;
		
		clipRect = getClipCGRect(&portBounds);	// call this before beginning the context
		
		QDBeginCGContext(port, &context);
		CGContextClipToRect(context, clipRect);
	}

	calculateCGDrawingBounds(enclosingCGRect, &iconCGRect, &textCGRect);
		/* DrawThemeTextBox wants the bounding rectangle to be QuickDraw coordinates 
		   relative to the current port, not Core Graphics coordinates relative to the 
		   passed context. */
	calculateDrawingBounds(&enclosingRect, &iconRect, &textRect);
	itemData = (IconDBItemDataRec *)item;
	
	labelColor.red = 0;
	labelColor.green = 0;
	labelColor.blue = 0;
	PlotIconRefInContext(context, &iconCGRect, kAlignNone, 
							active ? kTransformNone : kTransformDisabled, &labelColor, 
							kPlotIconRefNormalFlags, itemData->icon);
	
	DrawThemeTextBox(itemData->name, kThemeViewsFont, 
						active ? kThemeStateActive : kThemeStateInactive, true, 
						&textRect, teCenter, context);
	
	QDEndCGContext(port, &context);
	if (savedState != NULL)
		SetThemeDrawingState(savedState, true);
} // DrawIconDataBrowserItem101CB