private void CheckMenuOpenerStart(DataGridView dgv, int rowIndex) { if (rowIndex > -1 && dgv.Rows.Count > rowIndex) { RowData trigger = (RowData)dgv.Rows[rowIndex].Cells[2].Value; trigger.IsSelected = true; dgv.Rows[rowIndex].Selected = true; Menu menuFromTrigger = (Menu)dgv.FindForm(); Menu menuTriggered = trigger.SubMenu; int level = menuFromTrigger.Level + 1; if (trigger.ContainsMenu && level < MenuDefines.MenusMax && menus[0].IsUsable && (menus[level] == null || menus[level] != menuTriggered)) { trigger.StopLoadMenuAndStartWaitToOpenIt(); trigger.StartMenuOpener(); if (trigger.Reading.IsBusy) { trigger.RestartLoading = true; } else { LoadStarted(this, false); trigger.Reading.RunWorkerAsync(level); } } } }
private void OpenSubMenu(object sender, RowData trigger) { Menu menuTriggered = trigger.SubMenu; Menu menuFromTrigger = menus[menuTriggered.Level - 1]; for (int level = menuTriggered.Level; level < MenuDefines.MenusMax; level++) { if (menus[level] != null) { Menu menuToClose = menus[level]; RowData oldTrigger = (RowData)menuToClose.Tag; DataGridView dgv = menuFromTrigger.GetDataGridView(); foreach (DataGridViewRow row in dgv.Rows) { RowData rowData = (RowData)row.Cells[2].Value; rowData.IsSelected = false; } trigger.IsSelected = true; dgv.ClearSelection(); dgv.Rows[trigger.RowIndex].Selected = true; menuToClose.HideWithFade(); menuToClose.VisibleChanged += MenuVisibleChanged; menus[level] = null; } } DisposeMenu(menus[menuTriggered.Level]); menus[menuTriggered.Level] = menuTriggered; AdjustMenusSizeAndLocation(); menus[menuTriggered.Level].ShowWithFadeOrTransparent(IsActive()); }
private bool IsAnyMenuSelectedByKey( ref DataGridView dgv, ref Menu menuFromSelected, ref string textselected) { Menu menu = menus[iMenuKey]; bool isStillSelected = false; if (menu != null && iRowKey > -1) { dgv = menu.GetDataGridView(); if (dgv.Rows.Count > iRowKey) { RowData rowData = (RowData)dgv. Rows[iRowKey].Cells[2].Value; if (rowData.IsSelected) { isStillSelected = true; menuFromSelected = rowData.SubMenu; textselected = dgv.Rows[iRowKey]. Cells[1].Value.ToString(); } } } return(isStillSelected); }
void StartLoadMenu(RowData rowData) { if (menus[0].IsUsable && loadingRowData != rowData && (menus[rowData.MenuLevel + 1] == null || menus[rowData.MenuLevel + 1].Tag as RowData != rowData)) { loadingRowData = rowData; LoadStarted(); BackgroundWorker workerSubMenu = workersSubMenu. Where(w => !w.IsBusy).FirstOrDefault(); if (workerSubMenu == null) { workerSubMenu = new BackgroundWorker { WorkerSupportsCancellation = true, }; workerSubMenu.DoWork += LoadMenu; workerSubMenu.RunWorkerCompleted += LoadSubMenuCompleted; workersSubMenu.Add(workerSubMenu); } workerSubMenu.RunWorkerAsync(rowData); } void LoadSubMenuCompleted(object senderCompleted, RunWorkerCompletedEventArgs e) { LoadStopped(); MenuData menuData = (MenuData)e.Result; if (menus[0].IsUsable && menuData.Validity != MenuDataValidity.AbortedOrUnknown) { Menu menu = Create(menuData); switch (menuData.Validity) { case MenuDataValidity.Valid: menu.SetTypeSub(); break; case MenuDataValidity.Empty: menu.SetTypeEmpty(); break; case MenuDataValidity.NoAccess: menu.SetTypeNoAccess(); break; } menu.Tag = menuData.RowDataParent; menuData.RowDataParent.SubMenu = menu; if (menus[0].IsUsable) { ShowSubMenu(menu); } } loadingRowData = null; } }
private void Dgv_CellMouseLeave(object sender, DataGridViewCellEventArgs e) { if (!keyboardInput.InUse) { DataGridView dgv = (DataGridView)sender; Menu menu = (Menu)dgv.FindForm(); CheckMenuOpenerStop(menu.Level, e.RowIndex, dgv); } }
internal void SearchTextChanged(object sender, EventArgs e) { Menu menu = (Menu)sender; DataGridView dgv = menu.GetDataGridView(); if (dgv.Rows.Count > 0) { Select(dgv, 0, true); } }
private void CreateMenuRow(RowData rowData, Menu menu, DataTable dataTable) { rowData.SetData(rowData, dataTable); rowData.OpenMenu += OpenSubMenu; rowData.Reading.WorkerSupportsCancellation = true; rowData.Reading.DoWork += ReadMenu_DoWork; void ReadMenu_DoWork(object senderDoWork, DoWorkEventArgs eDoWork) { int level = (int)eDoWork.Argument; BackgroundWorker worker = (BackgroundWorker)senderDoWork; eDoWork.Result = Business.Menus.GetData(worker, rowData.TargetFilePath, level); } rowData.Reading.RunWorkerCompleted += ReadMenu_RunWorkerCompleted; void ReadMenu_RunWorkerCompleted(object senderCompleted, RunWorkerCompletedEventArgs e) { MenuData menuData = (MenuData)e.Result; if (rowData.RestartLoading) { rowData.RestartLoading = false; rowData.Reading.RunWorkerAsync(menuData.Level); } else { LoadStopped(); if (menuData.Validity != MenuDataValidity.Invalid) { menu = Create(menuData); if (menuData.RowDatas.Count > 0) { menu.SetTypeSub(); } else if (menuData.Validity == MenuDataValidity.NoAccess) { menu.SetTypeNoAccess(); } else { menu.SetTypeEmpty(); } menu.Tag = rowData; rowData.SubMenu = menu; rowData.MenuLoaded(); } } } }
private void AddItemsToMenu(List <RowData> data, Menu menu) { DataGridView dgv = menu.GetDataGridView(); DataTable dataTable = new DataTable(); dataTable.Columns.Add(dgv.Columns[0].Name, typeof(Icon)); dataTable.Columns.Add(dgv.Columns[1].Name, typeof(string)); dataTable.Columns.Add("data", typeof(RowData)); foreach (RowData rowData in data) { CreateMenuRow(rowData, menu, dataTable); } dgv.DataSource = dataTable; }
internal void DisposeMenu(Menu menuToDispose) { if (menuToDispose != null) { DataGridView dgv = menuToDispose.GetDataGridView(); foreach (DataGridViewRow row in dgv.Rows) { RowData rowData = (RowData)row.Cells[2].Value; rowData.Dispose(); DisposeMenu(rowData.SubMenu); } dgv.ClearSelection(); menuToDispose.Dispose(); } }
/// <summary> /// While menu is open user presses a key to search for specific entries. /// </summary> /// <param name="sender">not used.</param> /// <param name="e">Key data of the pressed key.</param> internal void KeyPress(object sender, KeyPressEventArgs e) { if (char.IsLetterOrDigit(e.KeyChar) || char.IsPunctuation(e.KeyChar) || char.IsWhiteSpace(e.KeyChar) || char.IsSeparator(e.KeyChar)) { string letter = e.KeyChar.ToString(CultureInfo.InvariantCulture); Menu menu = menus[iMenuKey]; menu.KeyPressedSearch(letter); e.Handled = true; } }
private void ClearIsSelectedByKey(int menuIndex, int rowIndex) { Menu menu = menus[menuIndex]; if (menu != null && rowIndex > -1) { DataGridView dgv = menu.GetDataGridView(); if (dgv.Rows.Count > rowIndex) { DataGridViewRow row = dgv.Rows[rowIndex]; RowData rowData = (RowData)row.Cells[2].Value; rowData.IsSelected = false; row.Selected = false; } } }
private void CheckMenuOpenerStop(int menuIndex, int rowIndex, DataGridView dgv = null) { Menu menu = menus[menuIndex]; if (menu != null && rowIndex > -1) { if (dgv == null) { dgv = menu.GetDataGridView(); } if (dgv.Rows.Count > rowIndex) { RowData trigger = (RowData)dgv.Rows[rowIndex].Cells[2].Value; if (trigger.Reading.IsBusy) { if (!trigger.IsContextMenuOpen) { trigger.IsSelected = false; dgv.Rows[rowIndex].Selected = false; } trigger.Reading.CancelAsync(); } else if (trigger.ContainsMenu && !trigger.IsLoading) { trigger.IsSelected = true; dgv.Rows[rowIndex].Selected = true; } else { if (!trigger.IsContextMenuOpen) { trigger.IsSelected = false; dgv.Rows[rowIndex].Selected = false; } } if (trigger.IsLoading) { trigger.StopLoadMenuAndStartWaitToOpenIt(); trigger.IsLoading = false; } } } }
private void MenuVisibleChanged(object sender, EventArgs e) { Menu menu = (Menu)sender; if (menu.IsUsable) { AdjustMenusSizeAndLocation(); if (menu.Level == 0) { menus[0].AdjustSizeAndLocation(); } } if (!menu.Visible) { DisposeMenu(menu); } if (!AsEnumerable.Any(m => m.Visible)) { openCloseState = OpenCloseState.Default; } }
private void AdjustMenusSizeAndLocation() { Menu menuPredecessor = menus[0]; int widthPredecessors = -1; // -1 padding bool directionToRight = false; menus[0].AdjustSizeAndLocation(); foreach (Menu menu in AsEnumerable.Where(m => m.Level > 0)) { int newWith = (menu.Width - menu.Padding.Horizontal + menuPredecessor.Width); if (directionToRight) { if (widthPredecessors - menu.Width <= -menu.Padding.Horizontal) { directionToRight = false; } else { widthPredecessors -= newWith; } } else if (Statics.ScreenWidth < widthPredecessors + menuPredecessor.Width + menu.Width) { directionToRight = true; widthPredecessors -= newWith; } menu.AdjustSizeAndLocation(menuPredecessor, directionToRight); widthPredecessors += menu.Width - menu.Padding.Left; menuPredecessor = menu; } }
private void SelectByKey(Keys keys, string keyInput = "", bool keepSelection = false) { int iRowBefore = iRowKey; int iMenuBefore = iMenuKey; Menu menu = menus[iMenuKey]; DataGridView dgv = null; DataGridView dgvBefore = null; Menu menuFromSelected = null; string textselected = string.Empty; bool isStillSelected = IsAnyMenuSelectedByKey(ref dgv, ref menuFromSelected, ref textselected); if (isStillSelected) { if (keepSelection) { // If current selection is still valid for this search then skip selecting different item if (textselected.StartsWith(keyInput, true, CultureInfo.InvariantCulture)) { return; } } dgvBefore = dgv; } else { ResetSelectedByKey(); menu = menus[iMenuKey]; dgv = menu.GetDataGridView(); } bool toClear = false; switch (keys) { case Keys.Enter: if (iRowKey > -1 && dgv.Rows.Count > iRowKey) { RowData trigger = (RowData)dgv.Rows[iRowKey].Cells[2].Value; if (trigger.IsMenuOpen || !trigger.ContainsMenu) { trigger.MouseDown(dgv, null); trigger.DoubleClick( new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0)); } else { RowDeselected(iRowBefore, dgvBefore); SelectRow(dgv, iRowKey); EnterPressed.Invoke(dgv, iRowKey); } } break; case Keys.Up: if (SelectMatchedReverse(dgv, iRowKey) || SelectMatchedReverse(dgv, dgv.Rows.Count - 1)) { RowDeselected(iRowBefore, dgvBefore); SelectRow(dgv, iRowKey); toClear = true; } break; case Keys.Down: if (SelectMatched(dgv, iRowKey) || SelectMatched(dgv, 0)) { RowDeselected(iRowBefore, dgvBefore); SelectRow(dgv, iRowKey); toClear = true; } break; case Keys.Left: int iMenuKeyNext = iMenuKey + 1; if (isStillSelected) { if (menuFromSelected != null && menuFromSelected == menus[iMenuKeyNext]) { dgv = menuFromSelected.GetDataGridView(); if (dgv.Rows.Count > 0) { iMenuKey += 1; iRowKey = -1; if (SelectMatched(dgv, iRowKey) || SelectMatched(dgv, 0)) { RowDeselected(iRowBefore, dgvBefore); SelectRow(dgv, iRowKey); toClear = true; } } } } else { iRowKey = -1; iMenuKey = menus.Where(m => m != null).Count() - 1; if (menus[iMenuKey] != null) { dgv = menus[iMenuKey].GetDataGridView(); if (SelectMatched(dgv, iRowKey) || SelectMatched(dgv, 0)) { RowDeselected(iRowBefore, dgvBefore); SelectRow(dgv, iRowKey); toClear = true; } } } break; case Keys.Right: if (iMenuKey > 0) { if (menus[iMenuKey - 1] != null) { iMenuKey -= 1; iRowKey = -1; menu = menus[iMenuKey]; dgv = menu.GetDataGridView(); if (SelectMatched(dgv, dgv.SelectedRows[0].Index) || SelectMatched(dgv, 0)) { RowDeselected(iRowBefore, dgvBefore); SelectRow(dgv, iRowKey); toClear = true; } } } else { RowDeselected(iRowBefore, dgvBefore); iMenuKey = 0; iRowKey = -1; toClear = true; Cleared?.Invoke(); } break; case Keys.Escape: RowDeselected(iRowBefore, dgvBefore); iMenuKey = 0; iRowKey = -1; toClear = true; ClosePressed?.Invoke(); break; default: if (!string.IsNullOrEmpty(keyInput)) { if (SelectMatched(dgv, iRowKey, keyInput) || SelectMatched(dgv, 0, keyInput)) { RowDeselected(iRowBefore, null); SelectRow(dgv, iRowKey); toClear = true; } else if (isStillSelected) { iRowKey = iRowBefore - 1; if (SelectMatched(dgv, iRowKey, keyInput) || SelectMatched(dgv, 0, keyInput)) { RowDeselected(iRowBefore, null); SelectRow(dgv, iRowKey); } else { iRowKey = iRowBefore; } } } break; } if (isStillSelected && toClear) { ClearIsSelectedByKey(iMenuBefore, iRowBefore); } }
internal void CmdKeyProcessed(object sender, Keys keys) { switch (keys) { case Keys.Enter: case Keys.Up: case Keys.Down: case Keys.Left: case Keys.Right: case Keys.Escape: SelectByKey(keys); break; case Keys.Control | Keys.F: Menu menu = menus[iMenuKey]; menu.FocusTextBox(); break; case Keys.Tab: { Menu currentMenu = (Menu)sender; int indexOfTheCurrentMenu = GetMenuIndex(currentMenu); int indexMax = menus.Where(m => m != null).Count() - 1; int indexNew = 0; if (indexOfTheCurrentMenu > 0) { indexNew = indexOfTheCurrentMenu - 1; } else { indexNew = indexMax; } menus[indexNew].FocusTextBox(); } break; case Keys.Tab | Keys.Shift: { Menu currentMenu = (Menu)sender; int indexOfTheCurrentMenu = GetMenuIndex(currentMenu); int indexMax = menus.Where(m => m != null).Count() - 1; int indexNew = 0; if (indexOfTheCurrentMenu < indexMax) { indexNew = indexOfTheCurrentMenu + 1; } else { indexNew = 0; } menus[indexNew].FocusTextBox(); } break; case Keys.Apps: { DataGridView dgv = menus[iMenuKey].GetDataGridView(); if (iRowKey > -1 && dgv.Rows.Count > iRowKey) { Point pt = dgv.GetCellDisplayRectangle(2, iRowKey, false).Location; RowData trigger = (RowData)dgv.Rows[iRowKey].Cells[2].Value; MouseEventArgs mea = new MouseEventArgs(MouseButtons.Right, 1, pt.X, pt.Y, 0); trigger.MouseDown(dgv, mea); } } break; default: break; } int GetMenuIndex(in Menu currentMenu) { int index = 0; foreach (Menu menuFindIndex in menus.Where(m => m != null)) { if (currentMenu == menuFindIndex) { break; } index++; } return(index); } }
private Menu Create(MenuData menuData, string title = null) { Menu menu = new Menu(); if (title != null) { if (string.IsNullOrEmpty(title)) { title = Path.GetPathRoot(Config.Path); } menu.SetTitle(title); menu.UserClickedOpenFolder += OpenFolder; void OpenFolder() { Log.ProcessStart("explorer.exe", Config.Path); } } menu.Level = menuData.Level; menu.MouseWheel += AdjustMenusSizeAndLocation; menu.MouseLeave += waitLeave.Start; menu.MouseEnter += waitLeave.Stop; menu.KeyPress += keyboardInput.KeyPress; menu.CmdKeyProcessed += keyboardInput.CmdKeyProcessed; menu.SearchTextChanging += keyboardInput.SearchTextChanging; menu.SearchTextChanged += Menu_SearchTextChanged; void Menu_SearchTextChanged(object sender, EventArgs e) { keyboardInput.SearchTextChanged(sender, e); AdjustMenusSizeAndLocation(); } menu.Deactivate += Deactivate; void Deactivate(object sender, EventArgs e) { FadeHalfOrOutIfNeeded(); if (!IsActive()) { deactivatedTime = DateTime.Now; } } menu.Activated += Activated; void Activated(object sender, EventArgs e) { if (IsActive() && menus[0].IsUsable) { menus[0].SetTitleColorActive(); AsList.ForEach(m => m.ShowWithFade()); } CheckIfWindowsStartStoleFocusNoDeactivateInRareCase(); void CheckIfWindowsStartStoleFocusNoDeactivateInRareCase() { timerStillActiveCheck.Interval = 1000; timerStillActiveCheck.Tick += StillActiveTick; void StillActiveTick(object senderTimer, EventArgs eTimer) { if (!waitLeave.IsRunning) { FadeHalfOrOutIfNeeded(); if (!IsActive()) { timerStillActiveCheck.Stop(); } } } timerStillActiveCheck.Start(); } } menu.VisibleChanged += MenuVisibleChanged; AddItemsToMenu(menuData.RowDatas, menu); DataGridView dgv = menu.GetDataGridView(); dgv.CellMouseEnter += Dgv_CellMouseEnter; dgv.CellMouseLeave += Dgv_CellMouseLeave; dgv.MouseDown += Dgv_MouseDown; dgv.MouseDoubleClick += Dgv_MouseDoubleClick; dgv.SelectionChanged += Dgv_SelectionChanged; return(menu); }