listctrl.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,239 行 · 第 1/5 页
CPP
2,239 行
// for this we need the width of the text
wxCoord wLabel;
wxCoord hLabel;
dc.GetTextExtent(item.GetText(), &wLabel, &hLabel);
wLabel += 2*EXTRA_WIDTH;
// and the width of the icon, if any
static const int MARGIN_BETWEEN_TEXT_AND_ICON = 2;
int ix = 0, // init them just to suppress the compiler warnings
iy = 0;
const int image = item.m_image;
wxImageListType *imageList;
if ( image != -1 )
{
imageList = m_owner->m_small_image_list;
if ( imageList )
{
imageList->GetSize(image, ix, iy);
wLabel += ix + MARGIN_BETWEEN_TEXT_AND_ICON;
}
}
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;
}
// if we have an image, draw it on the right of the label
if ( imageList )
{
imageList->Draw
(
image,
dc,
xAligned + wLabel - ix - MARGIN_BETWEEN_TEXT_AND_ICON,
HEADER_OFFSET_Y + (h - 4 - iy)/2,
wxIMAGELIST_DRAW_TRANSPARENT
);
cw -= ix + MARGIN_BETWEEN_TEXT_AND_ICON;
}
// draw the text clipping it so that it doesn't overwrite the column
// boundary
wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h - 4 );
dc.DrawText( item.GetText(),
xAligned + EXTRA_WIDTH, h / 2 - hLabel / 2 ); //HEADER_OFFSET_Y + EXTRA_HEIGHT );
x += wCol;
}
dc.EndDrawing();
}
void wxListHeaderWindow::DrawCurrent()
{
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 );
}
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
{
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, 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();
}
//-----------------------------------------------------------------------------
// wxListTextCtrl (internal)
//-----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxListTextCtrl,wxTextCtrl)
EVT_CHAR (wxListTextCtrl::OnChar)
EVT_KEY_UP (wxListTextCtrl::OnKeyUp)
EVT_KILL_FOCUS (wxListTextCtrl::OnKillFocus)
END_EVENT_TABLE()
wxListTextCtrl::wxListTextCtrl(wxListMainWindow *owner, size_t itemEdit)
: m_startValue(owner->GetItemText(itemEdit)),
m_itemEdited(itemEdit)
{
m_owner = owner;
m_finished = false;
m_aboutToFinish = false;
wxRect rectLabel = owner->GetLineLabelRect(itemEdit);
m_owner->CalcScrolledPosition(rectLabel.x, rectLabel.y,
&rectLabel.x, &rectLabel.y);
(void)Create(owner, wxID_ANY, m_startValue,
wxPoint(rectLabel.x-4,rectLabel.y-4),
wxSize(rectLabel.width+11,rectLabel.height+8));
}
void wxListTextCtrl::Finish()
{
if ( !m_finished )
{
wxPendingDelete.Append(this);
m_owner->m_textctrl = NULL;
m_finished = true;
m_owner->SetFocusIgnoringChildren();
}
}
bool wxListTextCtrl::AcceptChanges()
{
const wxString value = 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 wxListTextCtrl::AcceptChangesAndFinish()
{
m_aboutToFinish = true;
// Notify the owner about the changes
AcceptChanges();
// Even if vetoed, close the control (consistent with MSW)
Finish();
}
void wxListTextCtrl::OnChar( wxKeyEvent &event )
{
switch ( event.m_keyCode )
{
case WXK_RETURN:
AcceptChangesAndFinish();
break;
case WXK_ESCAPE:
Finish();
m_owner->OnRenameCancelled( m_itemEdited );
break;
default:
event.Skip();
}
}
void wxListTextCtrl::OnKeyUp( wxKeyEvent &event )
{
if (m_finished)
{
event.Skip();
return;
}
// auto-grow the textctrl:
wxSize parentSize = m_owner->GetSize();
wxPoint myPos = GetPosition();
wxSize mySize = GetSize();
int sx, sy;
GetTextExtent(GetValue() + _T("MM"), &sx, &sy);
if (myPos.x + sx > parentSize.x)
sx = parentSize.x - myPos.x;
if (mySize.x > sx)
sx = mySize.x;
SetSize(sx, wxDefaultCoord);
event.Skip();
}
void wxListTextCtrl::OnKillFocus( wxFocusEvent &event )
{
if ( !m_finished && !m_aboutToFinish )
{
// We must finish regardless of success, otherwise we'll get
// focus problems:
Finish();
if ( !AcceptChanges() )
m_owner->OnRenameCancelled( m_itemEdited );
}
// We must let the native text control handle focus, too, otherwise
// it could have problems with the cursor (e.g., in wxGTK).
event.Skip();
}
//-----------------------------------------------------------------------------
// wxListMainWindow
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxListMainWindow,wxScrolledWindow)
BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledWindow)
EVT_PAINT (wxListMainWindow::OnPaint)
EVT_MOUSE_EVENTS (wxListMainWindow::OnMouse)
EVT_CHAR (wxListMainWindow::OnChar)
EVT_KEY_DOWN (wxListMainWindow::OnKeyDown)
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 = (wxImageListType *) NULL;
m_normal_image_list = (wxImageListType *) 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_textctrl = 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::wxListMa
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?