+ if (item_x-view_x < 5)
+ Scroll( (item_x-5)/m_xScroll, -1 );
+ if (item_x+item_w-5 > view_x+client_w)
+ Scroll( (item_x+item_w-client_w+15)/m_xScroll, -1 );
+ }
+}
+
+void wxListMainWindow::OnArrowChar( wxListLineData *newCurrent, bool shiftDown )
+{
+ if ((m_mode & wxLC_SINGLE_SEL) || (m_usedKeys == FALSE)) m_current->Hilight( FALSE );
+ wxListLineData *oldCurrent = m_current;
+ m_current = newCurrent;
+ if (shiftDown || (m_mode & wxLC_SINGLE_SEL)) m_current->Hilight( TRUE );
+ RefreshLine( m_current );
+ RefreshLine( oldCurrent );
+ FocusLine( m_current );
+ UnfocusLine( oldCurrent );
+ MoveToFocus();
+}
+
+void wxListMainWindow::OnKeyDown( wxKeyEvent &event )
+{
+ wxWindow *parent = GetParent();
+
+ /* we propagate the key event up */
+ wxKeyEvent ke( wxEVT_KEY_DOWN );
+ ke.m_shiftDown = event.m_shiftDown;
+ ke.m_controlDown = event.m_controlDown;
+ ke.m_altDown = event.m_altDown;
+ ke.m_metaDown = event.m_metaDown;
+ ke.m_keyCode = event.m_keyCode;
+ ke.m_x = event.m_x;
+ ke.m_y = event.m_y;
+ ke.SetEventObject( parent );
+ if (parent->GetEventHandler()->ProcessEvent( ke )) return;
+
+ event.Skip();
+}
+
+void wxListMainWindow::OnChar( wxKeyEvent &event )
+{
+ wxWindow *parent = GetParent();
+
+ /* we send a list_key event up */
+ if ( m_current )
+ {
+ wxListEvent le( wxEVT_COMMAND_LIST_KEY_DOWN, GetParent()->GetId() );
+ le.m_itemIndex = GetIndexOfLine( m_current );
+ m_current->GetItem( 0, le.m_item );
+ le.m_code = (int)event.KeyCode();
+ le.SetEventObject( parent );
+ parent->GetEventHandler()->ProcessEvent( le );
+ }
+
+ /* we propagate the char event up */
+ wxKeyEvent ke( wxEVT_CHAR );
+ ke.m_shiftDown = event.m_shiftDown;
+ ke.m_controlDown = event.m_controlDown;
+ ke.m_altDown = event.m_altDown;
+ ke.m_metaDown = event.m_metaDown;
+ ke.m_keyCode = event.m_keyCode;
+ ke.m_x = event.m_x;
+ ke.m_y = event.m_y;
+ ke.SetEventObject( parent );
+ if (parent->GetEventHandler()->ProcessEvent( ke )) return;
+
+ if (event.KeyCode() == WXK_TAB)
+ {
+ wxNavigationKeyEvent nevent;
+ nevent.SetWindowChange( event.ControlDown() );
+ nevent.SetDirection( !event.ShiftDown() );
+ nevent.SetEventObject( GetParent()->GetParent() );
+ nevent.SetCurrentFocus( m_parent );
+ if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent )) return;
+ }
+
+ /* no item -> nothing to do */
+ if (!m_current)
+ {
+ event.Skip();
+ return;
+ }
+
+ switch (event.KeyCode())
+ {
+ case WXK_UP:
+ {
+ int index = m_lines.Index(*m_current);
+ if (index != wxNOT_FOUND && index > 0)
+ OnArrowChar( &m_lines[index-1], event.ShiftDown() );
+ break;
+ }
+ case WXK_DOWN:
+ {
+ int index = m_lines.Index(*m_current);
+ if (index != wxNOT_FOUND && (size_t)index < m_lines.GetCount()-1)
+ OnArrowChar( &m_lines[index+1], event.ShiftDown() );
+ break;
+ }
+ case WXK_END:
+ {
+ if (!m_lines.IsEmpty())
+ OnArrowChar( &m_lines.Last(), event.ShiftDown() );
+ break;
+ }
+ case WXK_HOME:
+ {
+ if (!m_lines.IsEmpty())
+ OnArrowChar( &m_lines[0], event.ShiftDown() );
+ break;
+ }
+ case WXK_PRIOR:
+ {
+ int steps = 0;
+ int index = m_lines.Index(*m_current);
+ if (m_mode & wxLC_REPORT)
+ {
+ steps = m_visibleLines-1;
+ }
+ else
+ {
+ steps = index % m_visibleLines;
+ }
+ if (index != wxNOT_FOUND)
+ {
+ index -= steps;
+ if (index < 0) index = 0;
+ OnArrowChar( &m_lines[index], event.ShiftDown() );
+ }
+ break;
+ }
+ case WXK_NEXT:
+ {
+ int steps = 0;
+ int index = m_lines.Index(*m_current);
+ if (m_mode & wxLC_REPORT)
+ {
+ steps = m_visibleLines-1;
+ }
+ else
+ {
+ steps = m_visibleLines-(index % m_visibleLines)-1;
+ }
+
+ if (index != wxNOT_FOUND)
+ {
+ index += steps;
+ if ((size_t)index >= m_lines.GetCount())
+ index = m_lines.GetCount()-1;
+ OnArrowChar( &m_lines[index], event.ShiftDown() );
+ }
+ break;
+ }
+ case WXK_LEFT:
+ {
+ if (!(m_mode & wxLC_REPORT))
+ {
+ int index = m_lines.Index(*m_current);
+ if (index != wxNOT_FOUND)
+ {
+ index -= m_visibleLines;
+ if (index < 0) index = 0;
+ OnArrowChar( &m_lines[index], event.ShiftDown() );
+ }
+ }
+ break;
+ }
+ case WXK_RIGHT:
+ {
+ if (!(m_mode & wxLC_REPORT))
+ {
+ int index = m_lines.Index(*m_current);
+ if (index != wxNOT_FOUND)
+ {
+ index += m_visibleLines;
+ if ((size_t)index >= m_lines.GetCount())
+ index = m_lines.GetCount()-1;
+ OnArrowChar( &m_lines[index], event.ShiftDown() );
+ }
+ }
+ break;
+ }
+ case WXK_SPACE:
+ {
+ if (m_mode & wxLC_SINGLE_SEL)
+ {
+ wxListEvent le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, GetParent()->GetId() );
+ le.SetEventObject( GetParent() );
+ le.m_itemIndex = GetIndexOfLine( m_current );
+ m_current->GetItem( 0, le.m_item );
+ GetParent()->GetEventHandler()->ProcessEvent( le );
+ }
+ else
+ {
+ m_current->ReverseHilight();
+ RefreshLine( m_current );
+ }
+ break;
+ }
+ case WXK_INSERT:
+ {
+ if (!(m_mode & wxLC_SINGLE_SEL))
+ {
+ wxListLineData *oldCurrent = m_current;
+ m_current->ReverseHilight();
+ int index = m_lines.Index( *m_current ) + 1;
+ if ( (size_t)index < m_lines.GetCount() )
+ m_current = &m_lines[index];
+ RefreshLine( oldCurrent );
+ RefreshLine( m_current );
+ UnfocusLine( oldCurrent );
+ FocusLine( m_current );
+ MoveToFocus();
+ }
+ break;
+ }
+ case WXK_RETURN:
+ case WXK_EXECUTE:
+ {
+ wxListEvent le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, GetParent()->GetId() );
+ le.SetEventObject( GetParent() );
+ le.m_itemIndex = GetIndexOfLine( m_current );
+ m_current->GetItem( 0, le.m_item );
+ GetParent()->GetEventHandler()->ProcessEvent( le );
+ break;
+ }
+ default:
+ {
+ event.Skip();
+ return;
+ }
+ }
+ m_usedKeys = TRUE;
+}
+
+#ifdef __WXGTK__
+extern wxWindow *g_focusWindow;
+#endif