📄 listctrl.cpp
字号:
// and the width of the icon, if any int ix = 0, iy = 0; // init them just to suppress the compiler warnings const int image = item.m_image; wxImageList *imageList; if ( image != -1 ) { imageList = m_owner->m_small_image_list; if ( imageList ) { imageList->GetSize(image, ix, iy); wLabel += ix + HEADER_IMAGE_MARGIN_IN_REPORT_MODE; } } else { imageList = NULL; } // ignore alignment if there is not enough space anyhow int xAligned; switch ( wLabel < cw ? item.GetAlign() : wxLIST_FORMAT_LEFT ) { default: wxFAIL_MSG( _T("unknown list item format") ); // fall through case wxLIST_FORMAT_LEFT: xAligned = x; break; case wxLIST_FORMAT_RIGHT: xAligned = x + cw - wLabel; break; case wxLIST_FORMAT_CENTER: xAligned = x + (cw - wLabel) / 2; break; } // draw the text and image clipping them so that they // don't overwrite the column boundary wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h ); // if we have an image, draw it on the right of the label if ( imageList ) { imageList->Draw ( image, dc, xAligned + wLabel - ix - HEADER_IMAGE_MARGIN_IN_REPORT_MODE, HEADER_OFFSET_Y + (h - 4 - iy)/2, wxIMAGELIST_DRAW_TRANSPARENT ); } dc.DrawText( item.GetText(), xAligned + EXTRA_WIDTH, h / 2 - hLabel / 2 ); //HEADER_OFFSET_Y + EXTRA_HEIGHT ); x += wCol; }}void wxListHeaderWindow::DrawCurrent(){#if 1 m_owner->SetColumnWidth( m_column, m_currentX - m_minX );#else int x1 = m_currentX; int y1 = 0; m_owner->ClientToScreen( &x1, &y1 ); int x2 = m_currentX; int y2 = 0; m_owner->GetClientSize( NULL, &y2 ); m_owner->ClientToScreen( &x2, &y2 ); wxScreenDC dc; dc.SetLogicalFunction( wxINVERT ); dc.SetPen( wxPen( *wxBLACK, 2, wxSOLID ) ); dc.SetBrush( *wxTRANSPARENT_BRUSH ); AdjustDC(dc); dc.DrawLine( x1, y1, x2, y2 ); dc.SetLogicalFunction( wxCOPY ); dc.SetPen( wxNullPen ); dc.SetBrush( wxNullBrush );#endif}void wxListHeaderWindow::OnMouse( wxMouseEvent &event ){ // we want to work with logical coords int x; m_owner->CalcUnscrolledPosition(event.GetX(), 0, &x, NULL); int y = event.GetY(); if (m_isDragging) { SendListEvent(wxEVT_COMMAND_LIST_COL_DRAGGING, event.GetPosition()); // we don't draw the line beyond our window, but we allow dragging it // there int w = 0; GetClientSize( &w, NULL ); m_owner->CalcUnscrolledPosition(w, 0, &w, NULL); w -= 6; // erase the line if it was drawn if ( m_currentX < w ) DrawCurrent(); if (event.ButtonUp()) { ReleaseMouse(); m_isDragging = false; m_dirty = true; m_owner->SetColumnWidth( m_column, m_currentX - m_minX ); SendListEvent(wxEVT_COMMAND_LIST_COL_END_DRAG, event.GetPosition()); } else { if (x > m_minX + 7) m_currentX = x; else m_currentX = m_minX + 7; // draw in the new location if ( m_currentX < w ) DrawCurrent(); } } else // not dragging { m_minX = 0; bool hit_border = false; // end of the current column int xpos = 0; // find the column where this event occurred int col, countCol = m_owner->GetColumnCount(); for (col = 0; col < countCol; col++) { xpos += m_owner->GetColumnWidth( col ); m_column = col; if ( (abs(x-xpos) < 3) && (y < 22) ) { // near the column border hit_border = true; break; } if ( x < xpos ) { // inside the column break; } m_minX = xpos; } if ( col == countCol ) m_column = -1; if (event.LeftDown() || event.RightUp()) { if (hit_border && event.LeftDown()) { if ( SendListEvent(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, event.GetPosition()) ) { m_isDragging = true; m_currentX = x; CaptureMouse(); DrawCurrent(); } //else: column resizing was vetoed by the user code } else // click on a column { // record the selected state of the columns if (event.LeftDown()) { for (int i=0; i < m_owner->GetColumnCount(); i++) { wxListItem colItem; m_owner->GetColumn(i, colItem); long state = colItem.GetState(); if (i == m_column) colItem.SetState(state | wxLIST_STATE_SELECTED); else colItem.SetState(state & ~wxLIST_STATE_SELECTED); m_owner->SetColumn(i, colItem); } } SendListEvent( event.LeftDown() ? wxEVT_COMMAND_LIST_COL_CLICK : wxEVT_COMMAND_LIST_COL_RIGHT_CLICK, event.GetPosition()); } } else if (event.Moving()) { bool setCursor; if (hit_border) { setCursor = m_currentCursor == wxSTANDARD_CURSOR; m_currentCursor = m_resizeCursor; } else { setCursor = m_currentCursor != wxSTANDARD_CURSOR; m_currentCursor = wxSTANDARD_CURSOR; } if ( setCursor ) SetCursor(*m_currentCursor); } }}void wxListHeaderWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) ){ m_owner->SetFocus(); m_owner->Update();}bool wxListHeaderWindow::SendListEvent(wxEventType type, const wxPoint& pos){ wxWindow *parent = GetParent(); wxListEvent le( type, parent->GetId() ); le.SetEventObject( parent ); le.m_pointDrag = pos; // the position should be relative to the parent window, not // this one for compatibility with MSW and common sense: the // user code doesn't know anything at all about this header // window, so why should it get positions relative to it? le.m_pointDrag.y -= GetSize().y; le.m_col = m_column; return !parent->GetEventHandler()->ProcessEvent( le ) || le.IsAllowed();}//-----------------------------------------------------------------------------// wxListRenameTimer (internal)//-----------------------------------------------------------------------------wxListRenameTimer::wxListRenameTimer( wxListMainWindow *owner ){ m_owner = owner;}void wxListRenameTimer::Notify(){ m_owner->OnRenameTimer();}//-----------------------------------------------------------------------------// wxListTextCtrlWrapper (internal)//-----------------------------------------------------------------------------BEGIN_EVENT_TABLE(wxListTextCtrlWrapper, wxEvtHandler) EVT_CHAR (wxListTextCtrlWrapper::OnChar) EVT_KEY_UP (wxListTextCtrlWrapper::OnKeyUp) EVT_KILL_FOCUS (wxListTextCtrlWrapper::OnKillFocus)END_EVENT_TABLE()wxListTextCtrlWrapper::wxListTextCtrlWrapper(wxListMainWindow *owner, wxTextCtrl *text, size_t itemEdit) : m_startValue(owner->GetItemText(itemEdit)), m_itemEdited(itemEdit){ m_owner = owner; m_text = text; m_finished = false; m_aboutToFinish = false; wxRect rectLabel = owner->GetLineLabelRect(itemEdit); m_owner->CalcScrolledPosition(rectLabel.x, rectLabel.y, &rectLabel.x, &rectLabel.y); m_text->Create(owner, wxID_ANY, m_startValue, wxPoint(rectLabel.x-4,rectLabel.y-4), wxSize(rectLabel.width+11,rectLabel.height+8)); m_text->SetFocus(); m_text->PushEventHandler(this);}void wxListTextCtrlWrapper::Finish(){ if ( !m_finished ) { m_finished = true; m_text->RemoveEventHandler(this); m_owner->FinishEditing(m_text); wxPendingDelete.Append( this ); }}bool wxListTextCtrlWrapper::AcceptChanges(){ const wxString value = m_text->GetValue(); // notice that we should always call OnRenameAccept() to generate the "end // label editing" event, even if the user hasn't really changed anything if ( !m_owner->OnRenameAccept(m_itemEdited, value) ) { // vetoed by the user return false; } // accepted, do rename the item (unless nothing changed) if ( value != m_startValue ) m_owner->SetItemText(m_itemEdited, value); return true;}void wxListTextCtrlWrapper::AcceptChangesAndFinish(){ m_aboutToFinish = true; // Notify the owner about the changes AcceptChanges(); // Even if vetoed, close the control (consistent with MSW) Finish();}void wxListTextCtrlWrapper::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 wxListTextCtrlWrapper::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 wxListTextCtrlWrapper::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();}//-----------------------------------------------------------------------------// wxListMainWindow//-----------------------------------------------------------------------------BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledWindow) EVT_PAINT (wxListMainWindow::OnPaint) EVT_ERASE_BACKGROUND (wxListMainWindow::OnErase) EVT_MOUSE_EVENTS (wxListMainWindow::OnMouse) EVT_CHAR (wxListMainWindow::OnChar) EVT_KEY_DOWN (wxListMainWindow::OnKeyDown) EVT_KEY_UP (wxListMainWindow::OnKeyUp) EVT_SET_FOCUS (wxListMainWindow::OnSetFocus) EVT_KILL_FOCUS (wxListMainWindow::OnKillFocus) EVT_SCROLLWIN (wxListMainWindow::OnScroll)END_EVENT_TABLE()void wxListMainWindow::Init(){ m_dirty = true; m_countVirt = 0; m_lineFrom = m_lineTo = (size_t)-1; m_linesPerPage = 0; m_headerWidth = m_lineHeight = 0; m_small_image_list = (wxImageList *) NULL; m_normal_image_list = (wxImageList *) NULL; m_small_spacing = 30; m_normal_spacing = 40; m_hasFocus = false; m_dragCount = 0; m_isCreated = false; m_lastOnSame = false; m_renameTimer = new wxListRenameTimer( this ); m_textctrlWrapper = NULL; m_current = m_lineLastClicked = m_lineSelectSingleOnUp = m_lineBeforeLastClicked = (size_t)-1; m_freezeCount = 0;}wxListMainWindow::wxListMainWindow(){ Init(); m_highlightBrush = m_highlightUnfocusedBrush = (wxBrush *) NULL;}wxListMainWindow::wxListMainWindow( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -