bool KeyboardScroll(Gdk.ModifierType modifier, int relative_row, bool align_y) { if (Model == null) { return(true); } int row_limit; if (relative_row < 0) { if (Selection.FocusedIndex == -1) { return(false); } row_limit = 0; } else { row_limit = Model.Count - 1; } if (Selection.FocusedIndex == row_limit) { return(true); } int scroll_target_item_index = Math.Min(Model.Count - 1, Math.Max(0, Selection.FocusedIndex + relative_row)); if (Selection != null) { if ((modifier & Gdk.ModifierType.ControlMask) != 0) { // Don't change the selection } else if ((modifier & Gdk.ModifierType.ShiftMask) != 0) { // Behave like nautilus: if and arrow key + shift is pressed and the currently focused item // is not selected, select it and don't move the focus or vadjustment. // Otherwise, select the new row and scroll etc as necessary. if (relative_row * relative_row != 1) { Selection.SelectFromFirst(scroll_target_item_index, true, false); } else if (Selection.Contains(Selection.FocusedIndex)) { Selection.SelectFromFirst(scroll_target_item_index, true, false); } else { Selection.Select(Selection.FocusedIndex, false); return(true); } } else { Selection.Clear(false); Selection.Select(scroll_target_item_index, false); } } // Scroll if needed double y_at_row = GetViewPointForModelRow(scroll_target_item_index).Y; if (align_y) { if (y_at_row < VadjustmentValue) { ScrollToY(y_at_row); } else if (vadjustment != null) { var bottom_of_item = y_at_row + ChildSize.Height; var bottom_of_view = vadjustment.Value + vadjustment.PageSize; if (bottom_of_item > bottom_of_view) { // Scroll down just enough to put the item fully into view ScrollToY(bottom_of_item - (vadjustment.PageSize)); } } } else if (vadjustment != null) { ScrollToY(vadjustment.Value + y_at_row - GetViewPointForModelRow(Selection.FocusedIndex).Y); } Selection.FocusedIndex = scroll_target_item_index; InvalidateList(); return(true); }
bool OnListButtonPressEvent(Gdk.EventButton evnt) { if (Model == null) { return(true); } int x = (int)evnt.X - list_interaction_alloc.X; int y = (int)evnt.Y - list_interaction_alloc.Y; GrabFocus(); int row_index = GetModelRowAt(x, y); if (row_index < 0 || row_index >= Model.Count) { Gtk.Drag.SourceUnset(this); return(true); } if (LayoutChildHandlesEvent(evnt, true)) { return(true); } ProxyEventToCell(evnt, true); object item = model[row_index]; if (item == null) { return(true); } if (evnt.Button == 1 && evnt.Type == Gdk.EventType.TwoButtonPress) { // Double clicked OnRowActivated(); } else if (Selection != null) { if ((evnt.State & Gdk.ModifierType.ControlMask) != 0) { if (evnt.Button == 3) { // Right clicked with ctrl pressed, so make sure row selected if (!Selection.Contains(row_index)) { Selection.Select(row_index); } } else { // Normal ctrl-click, so toggle Selection.ToggleSelect(row_index); } } else if ((evnt.State & Gdk.ModifierType.ShiftMask) != 0) { // Shift-click, so select from first-row-selected (if any) to the current row Selection.SelectFromFirst(row_index, true); } else { if (evnt.Button == 3) { // Normal right-click, make sure row is only row selected if (!Selection.Contains(row_index)) { Selection.Clear(false); Selection.Select(row_index); } } else { // Normal click, if row not already selected, select only it right now, // but if it's already selected, wait until the Release to unselect any others so that // drag and drop of 2+ items works. if (!Selection.Contains(row_index)) { Selection.Clear(false); Selection.Select(row_index); } } } FocusModelRow(row_index); // Now that we've worked out the selections, open the context menu if (evnt.Button == 3) { OnPopupMenu(); } } InvalidateList(); return(true); }
private bool KeyboardScroll(Gdk.ModifierType modifier, int relative_row, bool align_y) { if (Model == null) { return(true); } int row_limit; if (relative_row < 0) { if (Selection.FocusedIndex == -1) { return(false); } row_limit = 0; } else { row_limit = Model.Count - 1; } if (Selection.FocusedIndex == row_limit) { return(true); } int row_index = Math.Min(Model.Count - 1, Math.Max(0, Selection.FocusedIndex + relative_row)); if (Selection != null) { if ((modifier & Gdk.ModifierType.ControlMask) != 0) { // Don't change the selection } else if ((modifier & Gdk.ModifierType.ShiftMask) != 0) { // Behave like nautilus: if and arrow key + shift is pressed and the currently focused item // is not selected, select it and don't move the focus or vadjustment. // Otherwise, select the new row and scroll etc as necessary. if (relative_row * relative_row != 1) { Selection.SelectFromFirst(row_index, true); } else if (Selection.Contains(Selection.FocusedIndex)) { Selection.SelectFromFirst(row_index, true); } else { Selection.Select(Selection.FocusedIndex); return(true); } } else { Selection.Clear(false); Selection.Select(row_index); } } // Scroll if needed double y_at_row = GetYAtRow(row_index); if (align_y) { if (y_at_row < VadjustmentValue) { ScrollTo(y_at_row); } else if (vadjustment != null && (y_at_row + RowHeight) > (vadjustment.Value + vadjustment.PageSize)) { ScrollTo(y_at_row + RowHeight - (vadjustment.PageSize)); } } else if (vadjustment != null) { ScrollTo(vadjustment.Value + ((row_index - Selection.FocusedIndex) * RowHeight)); } Selection.FocusedIndex = row_index; InvalidateList(); return(true); }