private void FocusMod(string key, bool exactMatch, bool showAsFirst = false) { DataGridViewRow current_row = ModList.CurrentRow; int currentIndex = current_row != null ? current_row.Index : 0; DataGridViewRow first_match = null; var does_name_begin_with_key = new Func <DataGridViewRow, bool>(row => { GUIMod mod = row.Tag as GUIMod; bool row_match = false; if (exactMatch) { row_match = mod.Name == key || mod.Identifier == key; } else { row_match = mod.Name.StartsWith(key, StringComparison.OrdinalIgnoreCase) || mod.Abbrevation.StartsWith(key, StringComparison.OrdinalIgnoreCase) || mod.Identifier.StartsWith(key, StringComparison.OrdinalIgnoreCase); } if (row_match && first_match == null) { // Remember the first match to allow cycling back to it if necessary first_match = row; } if (key.Length == 1 && row_match && row.Index <= currentIndex) { // Keep going forward if it's a single key match and not ahead of the current row return(false); } return(row_match); }); ModList.ClearSelection(); var rows = ModList.Rows.Cast <DataGridViewRow>().Where(row => row.Visible); DataGridViewRow match = rows.FirstOrDefault(does_name_begin_with_key); if (match == null && first_match != null) { // If there were no matches after the first match, cycle over to the beginning match = first_match; } if (match != null) { match.Selected = true; // Setting this to the Name cell prevents the checkbox from being toggled // by pressing Space while the row is not indicated as active ModList.CurrentCell = match.Cells[2]; if (showAsFirst) { ModList.FirstDisplayedScrollingRowIndex = match.Index; } } else { this.AddStatusMessage("Not found"); } }
/// <summary> /// Called on key press when the mod is focused. Scrolls to the first mod /// with name begining with the key pressed. /// </summary> private void ModList_KeyPress(object sender, KeyPressEventArgs e) { var rows = ModList.Rows.Cast <DataGridViewRow>().Where(row => row.Visible); var does_name_begin_with_char = new Func <DataGridViewRow, bool>(row => { var modname = ((CkanModule)row.Tag).name; var key = e.KeyChar.ToString(); return(modname.StartsWith(key, StringComparison.OrdinalIgnoreCase)); }); ModList.ClearSelection(); DataGridViewRow match = rows.FirstOrDefault(does_name_begin_with_char); if (match != null) { match.Selected = true; if (Util.IsLinux) { try { var first_row_index = ModList.GetType().GetField("first_row_index", BindingFlags.NonPublic | BindingFlags.Instance); var vertical_scroll_bar = ModList.GetType().GetField("verticalScrollBar", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(ModList); var safe_set_method = vertical_scroll_bar.GetType().GetMethod("SafeValueSet", BindingFlags.NonPublic | BindingFlags.Instance); first_row_index.SetValue(ModList, match.Index); safe_set_method.Invoke(vertical_scroll_bar, new object[] { match.Index *match.Height }); } catch { //Compared to crashing ignoring the keypress is fine. } ModList.FirstDisplayedScrollingRowIndex = match.Index; ModList.Refresh(); } else { //Not the best of names. Why not FirstVisableRowIndex? ModList.FirstDisplayedScrollingRowIndex = match.Index; } } }
private void ModList_MouseDown(object sender, MouseEventArgs e) { var rowIndex = ModList.HitTest(e.X, e.Y).RowIndex; // Ignore header column to prevent errors. if (rowIndex != -1 && e.Button == MouseButtons.Right) { // Detect the clicked cell and select the row. ModList.ClearSelection(); ModList.Rows[rowIndex].Selected = true; // Show the context menu. ModListContextMenuStrip.Show(ModList, new Point(e.X, e.Y)); // Set the menu options. var guiMod = (GUIMod)ModList.Rows[rowIndex].Tag; downloadContentsToolStripMenuItem.Enabled = !guiMod.IsCached; reinstallToolStripMenuItem.Enabled = guiMod.IsInstalled; } }
/// <summary> /// Called on key press when the mod is focused. Scrolls to the first mod /// with name begining with the key pressed. If space is pressed, the checkbox /// at the current row is toggled. /// </summary> private void ModList_KeyPress(object sender, KeyPressEventArgs e) { // Check the key. If it is space, mark the current mod as selected. if (e.KeyChar.ToString() == " ") { var selected_row = ModList.CurrentRow; if (selected_row != null) { // Get the checkbox. var selected_row_check_box = selected_row.Cells["Installed"] as DataGridViewCheckBoxCell; // Invert the value. if (selected_row_check_box != null) { bool selected_value = (bool)selected_row_check_box.Value; selected_row_check_box.Value = !selected_value; } } e.Handled = true; return; } var rows = ModList.Rows.Cast <DataGridViewRow>().Where(row => row.Visible); var does_name_begin_with_char = new Func <DataGridViewRow, bool>(row => { var modname = ((GUIMod)row.Tag).ToCkanModule().name; var key = e.KeyChar.ToString(); return(modname.StartsWith(key, StringComparison.OrdinalIgnoreCase)); }); ModList.ClearSelection(); DataGridViewRow match = rows.FirstOrDefault(does_name_begin_with_char); if (match != null) { match.Selected = true; ModList.CurrentCell = match.Cells[0]; } }
/// <summary> /// Called on key press when the mod is focused. Scrolls to the first mod /// with name begining with the key pressed. If more than one unique keys are pressed /// in under a second, it searches for the combination of the keys pressed. /// If the same key is being pressed repeatedly, it cycles through mods names /// beginnng with that key. If space is pressed, the checkbox at the current row is toggled. /// </summary> private void ModList_KeyPress(object sender, KeyPressEventArgs e) { var current_row = ModList.CurrentRow; var key = e.KeyChar.ToString(); // Check the key. If it is space and the current row is selected, mark the current mod as selected. if (key == " ") { if (current_row != null && current_row.Selected) { // Get the checkbox. var selected_row_check_box = current_row.Cells["Installed"] as DataGridViewCheckBoxCell; // Invert the value. if (selected_row_check_box != null) { bool selected_value = (bool)selected_row_check_box.Value; selected_row_check_box.Value = !selected_value; } } e.Handled = true; return; } if (e.KeyChar == (char)Keys.Enter) { // Don't try to search for newlines return; } var rows = ModList.Rows.Cast <DataGridViewRow>().Where(row => row.Visible); // Determine time passed since last key press TimeSpan interval = DateTime.Now - this.lastSearchTime; if (interval.TotalSeconds < 1) { // Last keypress was < 1 sec ago, so combine the last and current keys key = this.lastSearchKey + key; } // Remember the current time and key this.lastSearchTime = DateTime.Now; this.lastSearchKey = key; if (key.Distinct().Count() == 1) { // Treat repeating and single keypresses the same key = key.Substring(0, 1); } var current_name = ((GUIMod)current_row.Tag).ToCkanModule().name; var current_match = current_name.StartsWith(key, StringComparison.OrdinalIgnoreCase); DataGridViewRow first_match = null; var does_name_begin_with_key = new Func <DataGridViewRow, bool>(row => { var modname = ((GUIMod)row.Tag).ToCkanModule().name; var row_match = modname.StartsWith(key, StringComparison.OrdinalIgnoreCase); if (row_match && first_match == null) { // Remember the first match to allow cycling back to it if necessary first_match = row; } if (key.Length == 1 && row_match && row.Index <= current_row.Index) { // Keep going forward if it's a single key match and not ahead of the current row return(false); } return(row_match); }); ModList.ClearSelection(); DataGridViewRow match = rows.FirstOrDefault(does_name_begin_with_key); if (match == null && first_match != null) { // If there were no matches after the first match, cycle over to the beginning match = first_match; } if (match != null) { match.Selected = true; // Setting this to the Name cell prevents the checkbox from being toggled // by pressing Space while the row is not indicated as active ModList.CurrentCell = match.Cells[2]; } else { this.AddStatusMessage("Not found"); } e.Handled = true; }