X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e9a0cc4b727ed06da1a776a1b6c4ba66ed4bde3c..7564225f8bff6e6c2ed27695836035fa85a81189:/src/mac/carbon/listctrl_mac.cpp diff --git a/src/mac/carbon/listctrl_mac.cpp b/src/mac/carbon/listctrl_mac.cpp index 1c2878f868..5450de5164 100644 --- a/src/mac/carbon/listctrl_mac.cpp +++ b/src/mac/carbon/listctrl_mac.cpp @@ -36,6 +36,7 @@ #include "wx/imaglist.h" #include "wx/sysopt.h" +#include "wx/timer.h" #define wxMAC_ALWAYS_USE_GENERIC_LISTCTRL wxT("mac.listctrl.always_use_generic") @@ -136,7 +137,7 @@ static pascal OSStatus wxMacListCtrlEventHandler( EventHandlerCallRef handler , wxListCtrl *window = (wxListCtrl*) data ; wxListEvent le( wxEVT_COMMAND_LIST_COL_CLICK, window->GetId() ); le.SetEventObject( window ); - + switch ( GetEventKind( event ) ) { // check if the column was clicked on and fire an event if so @@ -151,18 +152,21 @@ static pascal OSStatus wxMacListCtrlEventHandler( EventHandlerCallRef handler , window->GetEventHandler()->ProcessEvent( le ); } result = CallNextEventHandler(handler, event); - break; + break; } case kEventControlDraw: - CGContextRef context = cEvent.GetParameter(kEventParamCGContextRef, typeCGContextRef) ; - window->MacSetDrawingContext(context); - result = CallNextEventHandler(handler, event); - window->MacSetDrawingContext(NULL); + { + CGContextRef context = cEvent.GetParameter(kEventParamCGContextRef, typeCGContextRef) ; + window->MacSetDrawingContext(context); + result = CallNextEventHandler(handler, event); + window->MacSetDrawingContext(NULL); + break; + } default : break ; } - + return result ; } @@ -235,7 +239,7 @@ protected: const Rect *theRect, SInt16 gdDepth, Boolean colorDevice); - + virtual void DrawItem(DataBrowserItemID itemID, DataBrowserPropertyID property, DataBrowserItemState itemState, @@ -250,7 +254,7 @@ protected: Rect *maxEditTextRect, Boolean *shrinkToFit); - static pascal Boolean DataBrowserHitTestProc(ControlRef browser, + static pascal Boolean DataBrowserHitTestProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, const Rect *theRect, @@ -262,19 +266,19 @@ protected: Rect *maxEditTextRect, Boolean *shrinkToFit); - + wxClientDataType m_clientDataItemsType; bool m_isVirtual; }; -class wxMacListCtrlEventDelegate : public wxEvtHandler +class wxMacListCtrlEventDelegate : public wxEvtHandler { public: wxMacListCtrlEventDelegate( wxListCtrl* list, int id ); virtual bool ProcessEvent( wxEvent& event ); - + private: wxListCtrl* m_list; int m_id; @@ -292,10 +296,212 @@ bool wxMacListCtrlEventDelegate::ProcessEvent( wxEvent& event ) // we present ourselves as wxListCtrl. event.SetEventObject( m_list ); event.SetId( m_id ); - + + if ( !event.IsKindOf( CLASSINFO( wxCommandEvent ) ) ) + { + if (m_list->GetEventHandler()->ProcessEvent( event )) + return true; + } return wxEvtHandler::ProcessEvent(event); } +//----------------------------------------------------------------------------- +// wxListCtrlRenameTimer (internal) +//----------------------------------------------------------------------------- + +class wxListCtrlRenameTimer: public wxTimer +{ +private: + wxListCtrl *m_owner; + +public: + wxListCtrlRenameTimer( wxListCtrl *owner ); + void Notify(); +}; + +//----------------------------------------------------------------------------- +// wxListCtrlTextCtrlWrapper: wraps a wxTextCtrl to make it work for inline editing +//----------------------------------------------------------------------------- + +class wxListCtrlTextCtrlWrapper : public wxEvtHandler +{ +public: + // NB: text must be a valid object but not Create()d yet + wxListCtrlTextCtrlWrapper(wxListCtrl *owner, + wxTextCtrl *text, + long itemEdit); + + wxTextCtrl *GetText() const { return m_text; } + + void AcceptChangesAndFinish(); + +protected: + void OnChar( wxKeyEvent &event ); + void OnKeyUp( wxKeyEvent &event ); + void OnKillFocus( wxFocusEvent &event ); + + bool AcceptChanges(); + void Finish(); + +private: + wxListCtrl *m_owner; + wxTextCtrl *m_text; + wxString m_startValue; + long m_itemEdited; + bool m_finished; + bool m_aboutToFinish; + + DECLARE_EVENT_TABLE() +}; + +//----------------------------------------------------------------------------- +// wxListCtrlRenameTimer (internal) +//----------------------------------------------------------------------------- + +wxListCtrlRenameTimer::wxListCtrlRenameTimer( wxListCtrl *owner ) +{ + m_owner = owner; +} + +void wxListCtrlRenameTimer::Notify() +{ + m_owner->OnRenameTimer(); +} + +//----------------------------------------------------------------------------- +// wxListCtrlTextCtrlWrapper (internal) +//----------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(wxListCtrlTextCtrlWrapper, wxEvtHandler) + EVT_CHAR (wxListCtrlTextCtrlWrapper::OnChar) + EVT_KEY_UP (wxListCtrlTextCtrlWrapper::OnKeyUp) + EVT_KILL_FOCUS (wxListCtrlTextCtrlWrapper::OnKillFocus) +END_EVENT_TABLE() + +wxListCtrlTextCtrlWrapper::wxListCtrlTextCtrlWrapper(wxListCtrl *owner, + wxTextCtrl *text, + long itemEdit) + : m_startValue(owner->GetItemText(itemEdit)), + m_itemEdited(itemEdit) +{ + m_owner = owner; + m_text = text; + m_finished = false; + m_aboutToFinish = false; + + wxRect rectLabel; + owner->GetItemRect(itemEdit, rectLabel); + + m_text->Create(owner, wxID_ANY, m_startValue, + wxPoint(rectLabel.x+8,rectLabel.y), + wxSize(rectLabel.width,rectLabel.height)); + m_text->SetFocus(); + + m_text->PushEventHandler(this); +} + +void wxListCtrlTextCtrlWrapper::Finish() +{ + if ( !m_finished ) + { + m_finished = true; + + m_text->RemoveEventHandler(this); + m_owner->FinishEditing(m_text); + + wxPendingDelete.Append( this ); + } +} + +bool wxListCtrlTextCtrlWrapper::AcceptChanges() +{ + const wxString value = m_text->GetValue(); + + if ( value == m_startValue ) + // nothing changed, always accept + return true; + + if ( !m_owner->OnRenameAccept(m_itemEdited, value) ) + // vetoed by the user + return false; + + // accepted, do rename the item + m_owner->SetItemText(m_itemEdited, value); + + return true; +} + +void wxListCtrlTextCtrlWrapper::AcceptChangesAndFinish() +{ + m_aboutToFinish = true; + + // Notify the owner about the changes + AcceptChanges(); + + // Even if vetoed, close the control (consistent with MSW) + Finish(); +} + +void wxListCtrlTextCtrlWrapper::OnChar( wxKeyEvent &event ) +{ + switch ( event.m_keyCode ) + { + case WXK_RETURN: + AcceptChangesAndFinish(); + break; + + case WXK_ESCAPE: + m_owner->OnRenameCancelled( m_itemEdited ); + Finish(); + break; + + default: + event.Skip(); + } +} + +void wxListCtrlTextCtrlWrapper::OnKeyUp( wxKeyEvent &event ) +{ + if (m_finished) + { + event.Skip(); + return; + } + + // auto-grow the textctrl: + wxSize parentSize = m_owner->GetSize(); + wxPoint myPos = m_text->GetPosition(); + wxSize mySize = m_text->GetSize(); + int sx, sy; + m_text->GetTextExtent(m_text->GetValue() + _T("MM"), &sx, &sy); + if (myPos.x + sx > parentSize.x) + sx = parentSize.x - myPos.x; + if (mySize.x > sx) + sx = mySize.x; + m_text->SetSize(sx, wxDefaultCoord); + + event.Skip(); +} + +void wxListCtrlTextCtrlWrapper::OnKillFocus( wxFocusEvent &event ) +{ + if ( !m_finished && !m_aboutToFinish ) + { + if ( !AcceptChanges() ) + m_owner->OnRenameCancelled( m_itemEdited ); + + Finish(); + } + + // We must let the native text control handle focus + event.Skip(); +} + +BEGIN_EVENT_TABLE(wxListCtrl, wxControl) + EVT_LEFT_DOWN(wxListCtrl::OnLeftDown) + EVT_LEFT_DCLICK(wxListCtrl::OnDblClick) +END_EVENT_TABLE() + // ============================================================================ // implementation // ============================================================================ @@ -328,6 +534,9 @@ void wxListCtrl::Init() m_colsInfo = wxColumnList(); m_textColor = wxNullColour; m_bgColor = wxNullColour; + m_textctrlWrapper = NULL; + m_current = -1; + m_renameTimer = new wxListCtrlRenameTimer( this ); } class wxGenericListCtrlHook : public wxGenericListCtrl @@ -370,6 +579,35 @@ protected: }; +void wxListCtrl::OnLeftDown(wxMouseEvent& event) +{ + if ( m_textctrlWrapper ) + { + m_current = -1; + m_textctrlWrapper->AcceptChangesAndFinish(); + } + + int hitResult; + long current = HitTest(event.GetPosition(), hitResult); + if ((current == m_current) && + (hitResult == wxLIST_HITTEST_ONITEM) && + HasFlag(wxLC_EDIT_LABELS) ) + { + m_renameTimer->Start( 100, true ); + } + else + { + m_current = current; + } + event.Skip(); +} + +void wxListCtrl::OnDblClick(wxMouseEvent& event) +{ + m_current = -1; + event.Skip(); +} + bool wxListCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, @@ -385,13 +623,15 @@ bool wxListCtrl::Create(wxWindow *parent, // Also, use generic list control in VIRTUAL mode. if ( (wxSystemOptions::HasOption( wxMAC_ALWAYS_USE_GENERIC_LISTCTRL ) && (wxSystemOptions::GetOptionInt( wxMAC_ALWAYS_USE_GENERIC_LISTCTRL ) == 1)) || - (style & wxLC_ICON) || (style & wxLC_SMALL_ICON) || (style & wxLC_LIST) || (style & wxLC_EDIT_LABELS) ) + (style & wxLC_ICON) || (style & wxLC_SMALL_ICON) || (style & wxLC_LIST) ) { m_macIsUserPane = true; - if ( !wxWindow::Create(parent, id, pos, size, style, name) ) + if ( !wxWindow::Create(parent, id, pos, size, style & wxNO_BORDER, name) ) return false; - m_genericImpl = new wxGenericListCtrlHook(this, id, pos, size, style, validator, name); + + // since the generic control is a child, make sure we position it at 0, 0 + m_genericImpl = new wxGenericListCtrlHook(this, id, wxPoint(0, 0), size, style, validator, name); m_genericImpl->PushEventHandler( new wxMacListCtrlEventDelegate( this, GetId() ) ); return true; } @@ -404,9 +644,9 @@ bool wxListCtrl::Create(wxWindow *parent, return false; m_dbImpl = new wxMacDataBrowserListCtrlControl( this, pos, size, style ); m_peer = m_dbImpl; - + MacPostControlCreate( pos, size ); - + InstallControlEventHandler( m_peer->GetControlRef() , GetwxMacListCtrlEventHandlerUPP(), GetEventTypeCount(eventList), eventList, this, (EventHandlerRef *)&m_macListCtrlEventHandler); @@ -419,15 +659,17 @@ wxListCtrl::~wxListCtrl() { if (m_genericImpl) { - m_genericImpl->PopEventHandler(/* deleteHandler = */ true); + m_genericImpl->PopEventHandler(/* deleteHandler = */ true); } - + if (m_ownsImageListNormal) delete m_imageListNormal; if (m_ownsImageListSmall) delete m_imageListSmall; if (m_ownsImageListState) delete m_imageListState; + + delete m_renameTimer; } // ---------------------------------------------------------------------------- @@ -479,7 +721,12 @@ void wxListCtrl::DoSetSize( int x, int y, int width, int height, int sizeFlags ) wxControl::DoSetSize(x, y, width, height, sizeFlags); if (m_genericImpl) - m_genericImpl->SetSize(x, y, width, height, sizeFlags); + m_genericImpl->SetSize(0, 0, width, height, sizeFlags); +} + +wxSize wxListCtrl::DoGetBestSize() const +{ + return wxWindow::DoGetBestSize(); } bool wxListCtrl::SetFont(const wxFont& font) @@ -517,7 +764,7 @@ wxColour wxListCtrl::GetBackgroundColour() return m_genericImpl->GetBackgroundColour(); if (m_dbImpl) return m_bgColor; - + return wxNullColour; } @@ -535,11 +782,11 @@ bool wxListCtrl::GetColumn(int col, wxListItem& item) const if (m_dbImpl) { - + wxColumnList::compatibility_iterator node = m_colsInfo.Item( col ); wxASSERT_MSG( node, _T("invalid column index in wxMacListCtrlItem") ); wxListItem* column = node->GetData(); - + long mask = column->GetMask(); if (mask & wxLIST_MASK_TEXT) item.SetText(column->GetText()); @@ -589,12 +836,12 @@ bool wxListCtrl::SetColumn(int col, wxListItem& item) if (mask & wxLIST_MASK_WIDTH) listItem.SetWidth(item.GetWidth()); } - + // change the appearance in the databrowser. DataBrowserListViewHeaderDesc columnDesc; columnDesc.version=kDataBrowserListViewLatestHeaderDesc; verify_noerr( m_dbImpl->GetHeaderDesc( kMinColumnId + col, &columnDesc ) ); - + /* if (item.GetMask() & wxLIST_MASK_TEXT) { @@ -605,12 +852,12 @@ bool wxListCtrl::SetColumn(int col, wxListItem& item) enc = wxLocale::GetSystemEncoding(); wxMacCFStringHolder cfTitle; cfTitle.Assign( item.GetText() , enc ); - if(columnDesc.titleString) + if(columnDesc.titleString) CFRelease(columnDesc.titleString); - columnDesc.titleString = cfTitle; + columnDesc.titleString = cfTitle; } */ - + if (item.GetMask() & wxLIST_MASK_IMAGE && item.GetImage() != -1 ) { columnDesc.btnContentInfo.contentType = kControlContentIconRef; @@ -622,7 +869,7 @@ bool wxListCtrl::SetColumn(int col, wxListItem& item) columnDesc.btnContentInfo.u.iconRef = icon; } } - + verify_noerr( m_dbImpl->SetHeaderDesc( kMinColumnId + col, &columnDesc ) ); } @@ -718,7 +965,22 @@ bool wxListCtrl::GetItem(wxListItem& info) const return m_genericImpl->GetItem(info); if (m_dbImpl) - m_dbImpl->MacGetColumnInfo(info.m_itemId, info.m_col, info); + { + if (!IsVirtual()) + m_dbImpl->MacGetColumnInfo(info.m_itemId, info.m_col, info); + else + { + info.SetText( OnGetItemText(info.m_itemId, info.m_col) ); + info.SetImage( OnGetItemColumnImage(info.m_itemId, info.m_col) ); + wxListItemAttr* attrs = OnGetItemAttr( info.m_itemId ); + if (attrs) + { + info.SetFont( attrs->GetFont() ); + info.SetBackgroundColour( attrs->GetBackgroundColour() ); + info.SetTextColour( attrs->GetTextColour() ); + } + } + } bool success = true; return success; } @@ -888,6 +1150,34 @@ bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const if (m_genericImpl) return m_genericImpl->GetItemRect(item, rect, code); + + if (m_dbImpl) + { + DataBrowserItemID id; + DataBrowserPropertyID col = kMinColumnId; + Rect bounds; + DataBrowserPropertyPart part = kDataBrowserPropertyEnclosingPart; + if ( code == wxLIST_RECT_LABEL ) + part = kDataBrowserPropertyTextPart; + else if ( code == wxLIST_RECT_ICON ) + part = kDataBrowserPropertyIconPart; + + if ( !(GetWindowStyleFlag() & wxLC_VIRTUAL) ) + { + wxMacDataItem* thisItem = m_dbImpl->GetItemFromLine(item); + id = (DataBrowserItemID) thisItem; + } + else + id = item; + + GetDataBrowserItemPartBounds( m_dbImpl->GetControlRef(), id, col, part, &bounds ); + + rect.x = bounds.left; + rect.y = bounds.top; + rect.width = bounds.right - bounds.left; //GetClientSize().x; // we need the width of the whole row, not just the item. + rect.height = bounds.bottom - bounds.top; + //fprintf("id = %d, bounds = %d, %d, %d, %d\n", id, rect.x, rect.y, rect.width, rect.height); + } return true; } @@ -899,6 +1189,14 @@ bool wxListCtrl::GetItemPosition(long item, wxPoint& pos) const bool success = false; + if (m_dbImpl) + { + wxRect itemRect; + GetItemRect(item, itemRect); + pos = itemRect.GetPosition(); + success = true; + } + return success; } @@ -1267,8 +1565,27 @@ wxTextCtrl* wxListCtrl::EditLabel(long item, wxClassInfo* textControlClass) if (m_dbImpl) { - wxMacDataItem* id = m_dbImpl->GetItemFromLine(item); - verify_noerr( SetDataBrowserEditItem(m_dbImpl->GetControlRef(), (DataBrowserItemID)id, kMinColumnId) ); + wxCHECK_MSG( (item >= 0) && ((long)item < GetItemCount()), NULL, + wxT("wrong index in wxListCtrl::EditLabel()") ); + + wxASSERT_MSG( textControlClass->IsKindOf(CLASSINFO(wxTextCtrl)), + wxT("EditLabel() needs a text control") ); + + wxListEvent le( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT, GetParent()->GetId() ); + le.SetEventObject( this ); + le.m_itemIndex = item; + le.m_col = 0; + GetItem( le.m_item ); + + if ( GetParent()->GetEventHandler()->ProcessEvent( le ) && !le.IsAllowed() ) + { + // vetoed by user code + return NULL; + } + + wxTextCtrl * const text = (wxTextCtrl *)textControlClass->CreateObject(); + m_textctrlWrapper = new wxListCtrlTextCtrlWrapper(this, text, item); + return m_textctrlWrapper->GetText(); } return NULL; } @@ -1347,6 +1664,47 @@ wxListCtrl::HitTest(const wxPoint& point, int& flags, long *ptrSubItem) const if (m_genericImpl) return m_genericImpl->HitTest(point, flags, ptrSubItem); + flags = wxLIST_HITTEST_NOWHERE; + if (m_dbImpl) + { + int colHeaderHeight = 22; // TODO: Find a way to get this value from the db control? + UInt16 rowHeight = 0; + m_dbImpl->GetDefaultRowHeight(&rowHeight); + + int y = point.y; + // get the actual row by taking scroll position into account + UInt32 offsetX, offsetY; + m_dbImpl->GetScrollPosition( &offsetY, &offsetX ); + y += offsetY; + + if ( !(GetWindowStyleFlag() & wxLC_NO_HEADER) ) + y -= colHeaderHeight; + + int row = y / rowHeight; + DataBrowserItemID id; + m_dbImpl->GetItemID( (DataBrowserTableViewRowIndex) row, &id ); + + // TODO: Use GetDataBrowserItemPartBounds to return if we are in icon or label + if ( !(GetWindowStyleFlag() & wxLC_VIRTUAL ) ) + { + wxMacListCtrlItem* lcItem; + lcItem = (wxMacListCtrlItem*) id; + if (lcItem) + { + flags = wxLIST_HITTEST_ONITEM; + return row; + } + } + else + { + if (row < GetItemCount() ) + { + flags = wxLIST_HITTEST_ONITEM; + return row; + } + } + + } return -1; } @@ -1507,7 +1865,7 @@ bool wxListCtrl::SortItems(wxListCtrlCompare fn, long data) { if (m_genericImpl) return m_genericImpl->SortItems(fn, data); - + if (m_dbImpl) { m_compareFunc = fn; @@ -1517,6 +1875,39 @@ bool wxListCtrl::SortItems(wxListCtrlCompare fn, long data) return true; } +void wxListCtrl::OnRenameTimer() +{ + wxCHECK_RET( HasCurrent(), wxT("unexpected rename timer") ); + + EditLabel( m_current ); +} + +bool wxListCtrl::OnRenameAccept(long itemEdit, const wxString& value) +{ + wxListEvent le( wxEVT_COMMAND_LIST_END_LABEL_EDIT, GetId() ); + le.SetEventObject( this ); + le.m_itemIndex = itemEdit; + + GetItem( le.m_item ); + le.m_item.m_text = value; + return !GetEventHandler()->ProcessEvent( le ) || + le.IsAllowed(); +} + +void wxListCtrl::OnRenameCancelled(long itemEdit) +{ + // let owner know that the edit was cancelled + wxListEvent le( wxEVT_COMMAND_LIST_END_LABEL_EDIT, GetParent()->GetId() ); + + le.SetEditCanceled(true); + + le.SetEventObject( this ); + le.m_itemIndex = itemEdit; + + GetItem( le.m_item ); + GetEventHandler()->ProcessEvent( le ); +} + // ---------------------------------------------------------------------------- // virtual list controls // ---------------------------------------------------------------------------- @@ -1727,7 +2118,7 @@ wxMacDataBrowserListCtrlControl::wxMacDataBrowserListCtrlControl( wxWindow *peer err = SetSelectionFlags( options ); verify_noerr( err ); - + DataBrowserCustomCallbacks callbacks; InitializeDataBrowserCustomCallbacks( &callbacks, kDataBrowserLatestCustomCallbacks ); @@ -1739,11 +2130,11 @@ wxMacDataBrowserListCtrlControl::wxMacDataBrowserListCtrlControl( wxWindow *peer if ( gDataBrowserHitTestUPP == NULL ) gDataBrowserHitTestUPP = NewDataBrowserHitTestUPP(DataBrowserHitTestProc); - + callbacks.u.v1.drawItemCallback = gDataBrowserDrawItemUPP; // callbacks.u.v1.editTextCallback = gDataBrowserEditItemUPP; callbacks.u.v1.hitTestCallback = gDataBrowserHitTestUPP; - + SetDataBrowserCustomCallbacks( GetControlRef(), &callbacks ); if ( style & wxLC_LIST ) @@ -1837,7 +2228,7 @@ enum kIconHeight = 16, kTextBoxHeight = 14, kIconTextSpacingV = 2, - kItemPadding = 4, + kItemPadding = 4, kContentHeight = kIconHeight + kTextBoxHeight + kIconTextSpacingV }; @@ -1852,15 +2243,15 @@ static void calculateCGDrawingBounds(CGRect inItemRect, CGRect *outIconRect, CGR iconW = kIconWidth; padding = padding*2; } - + textBottom = inItemRect.origin.y; - - *outIconRect = CGRectMake(inItemRect.origin.x + kItemPadding, - textBottom + kIconTextSpacingV, kIconWidth, + + *outIconRect = CGRectMake(inItemRect.origin.x + kItemPadding, + textBottom + kIconTextSpacingV, kIconWidth, kIconHeight); - - *outTextRect = CGRectMake(inItemRect.origin.x + padding + iconW, - textBottom + kIconTextSpacingV, inItemRect.size.width - padding - iconW, + + *outTextRect = CGRectMake(inItemRect.origin.x + padding + iconW, + textBottom + kIconTextSpacingV, inItemRect.size.width - padding - iconW, inItemRect.size.height - kIconTextSpacingV); } @@ -1889,7 +2280,7 @@ void wxMacDataBrowserListCtrlControl::DrawItem( lcItem = (wxMacListCtrlItem*) itemID; if (lcItem->HasColumnInfo(listColumn)){ wxListItem* item = lcItem->GetColumnInfo(listColumn); - + // we always use the 0 column to get font and text/background colors. if (lcItem->HasColumnInfo(0)) { @@ -1898,13 +2289,13 @@ void wxMacDataBrowserListCtrlControl::DrawItem( bgColor = firstItem->GetBackgroundColour(); font = firstItem->GetFont(); } - + if (item->GetMask() & wxLIST_MASK_TEXT) text = item->GetText(); if (item->GetMask() & wxLIST_MASK_IMAGE) imgIndex = item->GetImage(); } - + } else { @@ -1922,31 +2313,31 @@ void wxMacDataBrowserListCtrlControl::DrawItem( } } } - + wxColour listBgColor = list->GetBackgroundColour(); if (bgColor == wxNullColour) bgColor = listBgColor; - + wxFont listFont = list->GetFont(); if (font == wxNullFont) font = listFont; - + wxMacCFStringHolder cfString; cfString.Assign( text, wxLocale::GetSystemEncoding() ); - + Rect enclosingRect; CGRect enclosingCGRect, iconCGRect, textCGRect; Boolean active; ThemeDrawingState savedState = NULL; CGContextRef context = (CGContextRef)list->MacGetDrawingContext(); RGBColor labelColor; - - GetDataBrowserItemPartBounds(GetControlRef(), itemID, property, kDataBrowserPropertyEnclosingPart, + + GetDataBrowserItemPartBounds(GetControlRef(), itemID, property, kDataBrowserPropertyEnclosingPart, &enclosingRect); - - enclosingCGRect = CGRectMake(enclosingRect.left, - enclosingRect.top, - enclosingRect.right - enclosingRect.left, + + enclosingCGRect = CGRectMake(enclosingRect.left, + enclosingRect.top, + enclosingRect.right - enclosingRect.left, enclosingRect.bottom - enclosingRect.top); active = IsControlActive(GetControlRef()); @@ -1954,24 +2345,24 @@ void wxMacDataBrowserListCtrlControl::DrawItem( if (itemState == kDataBrowserItemIsSelected) { RGBColor foregroundColor; - + GetThemeDrawingState(&savedState); GetThemeBrushAsColor(kThemeBrushAlternatePrimaryHighlightColor, 32, true, &foregroundColor); GetThemeTextColor(kThemeTextColorWhite, gdDepth, colorDevice, &labelColor); CGContextSaveGState(context); - - CGContextSetRGBFillColor(context, (float)foregroundColor.red / (float)USHRT_MAX, - (float)foregroundColor.green / (float)USHRT_MAX, + + 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 - { - + { + if (color.Ok()) labelColor = MAC_WXCOLORREF( color.GetPixel() ); else if (list->GetTextColour().Ok()) @@ -1982,71 +2373,76 @@ void wxMacDataBrowserListCtrlControl::DrawItem( labelColor.green = 0; labelColor.blue = 0; } - + if (bgColor.Ok()) { RGBColor foregroundColor = MAC_WXCOLORREF( bgColor.GetPixel() ); CGContextSaveGState(context); - - CGContextSetRGBFillColor(context, (float)foregroundColor.red / (float)USHRT_MAX, - (float)foregroundColor.green / (float)USHRT_MAX, + + 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); } } - + calculateCGDrawingBounds(enclosingCGRect, &iconCGRect, &textCGRect, (imgIndex != -1) ); - + if (imgIndex != -1) { wxImageList* imageList = list->GetImageList(wxIMAGE_LIST_SMALL); if (imageList && imageList->GetImageCount() > 0){ wxBitmap bmp = imageList->GetBitmap(imgIndex); IconRef icon = bmp.GetBitmapData()->GetIconRef(); - + RGBColor iconLabel; iconLabel.red = 0; iconLabel.green = 0; iconLabel.blue = 0; - - PlotIconRefInContext(context, &iconCGRect, kAlignNone, - active ? kTransformNone : kTransformDisabled, &iconLabel, + + CGContextSaveGState(context); + CGContextTranslateCTM(context, 0,iconCGRect.origin.y + CGRectGetMaxY(iconCGRect)); + CGContextScaleCTM(context,1.0f,-1.0f); + PlotIconRefInContext(context, &iconCGRect, kAlignNone, + active ? kTransformNone : kTransformDisabled, &iconLabel, kPlotIconRefNormalFlags, icon); + + CGContextRestoreGState(context); } } - + HIThemeTextHorizontalFlush hFlush = kHIThemeTextHorizontalFlushLeft; UInt16 fontID = kThemeViewsFont; - + if (font.Ok()) { if (font.GetFamily() != wxFONTFAMILY_DEFAULT) fontID = font.MacGetThemeFontID(); - + // FIXME: replace these with CG or ATSUI calls so we can remove this #ifndef. #ifndef __LP64__ ::TextSize( (short)(font.MacGetFontSize()) ) ; ::TextFace( font.MacGetFontStyle() ) ; #endif } - + wxListItem item; list->GetColumn(listColumn, item); if (item.GetMask() & wxLIST_MASK_FORMAT) { if (item.GetAlign() == wxLIST_FORMAT_LEFT) - hFlush = kHIThemeTextHorizontalFlushLeft; + hFlush = kHIThemeTextHorizontalFlushLeft; else if (item.GetAlign() == wxLIST_FORMAT_CENTER) - hFlush = kHIThemeTextHorizontalFlushCenter; + hFlush = kHIThemeTextHorizontalFlushCenter; else if (item.GetAlign() == wxLIST_FORMAT_RIGHT) { hFlush = kHIThemeTextHorizontalFlushRight; textCGRect.origin.x -= kItemPadding; // give a little extra paddding } } - + HIThemeTextInfo info; info.version = kHIThemeTextInfoVersionZero; info.state = active ? kThemeStateActive : kThemeStateInactive; @@ -2058,14 +2454,14 @@ void wxMacDataBrowserListCtrlControl::DrawItem( info.truncationMaxLines = 1; CGContextSaveGState(context); - CGContextSetRGBFillColor (context, (float)labelColor.red / (float)USHRT_MAX, - (float)labelColor.green / (float)USHRT_MAX, + CGContextSetRGBFillColor (context, (float)labelColor.red / (float)USHRT_MAX, + (float)labelColor.green / (float)USHRT_MAX, (float)labelColor.blue / (float)USHRT_MAX, 1.0); - - HIThemeDrawTextBox(cfString, &textCGRect, &info, context, kHIThemeOrientationNormal); - + + HIThemeDrawTextBox(cfString, &textCGRect, &info, context, kHIThemeOrientationNormal); + CGContextRestoreGState(context); - + if (savedState != NULL) SetThemeDrawingState(savedState, true); } @@ -2221,7 +2617,7 @@ void wxMacDataBrowserListCtrlControl::ItemNotification(DataBrowserItemID itemID, case kDataBrowserItemSelected: trigger = !IsSelectionSuppressed(); - + break; case kDataBrowserItemDoubleClicked: @@ -2461,7 +2857,7 @@ void wxMacListCtrlItem::SetColumnInfo( unsigned int column, wxListItem* item ) listItem->SetAlign(item->GetAlign()); if (mask & wxLIST_MASK_WIDTH) listItem->SetWidth(item->GetWidth()); - + listItem->SetTextColour(item->GetTextColour()); listItem->SetBackgroundColour(item->GetBackgroundColour()); listItem->SetFont(item->GetFont());