/// <summary> /// Handles selection and caret changes due to mouse clicks. /// </summary> private void DoSelectionChangeFromMouse( ref VirtualTreeHitInfo hitInfo, bool shiftPressed, bool controlPressed, MouseButtons mouseButton) { var fireEvent = false; var columnSwitch = RequireColumnSwitchForSelection(ref hitInfo); if (columnSwitch) { SetSelectionColumn(myMouseDownHitInfo.DisplayColumn, false); fireEvent = true; } if (hitInfo.Row != VirtualTreeConstant.NullIndex) { if (mouseButton == MouseButtons.Right && IsSelected(hitInfo.Row)) { // if right button is clicked, and the index is already selected, // we'll just change the caret. if (CaretIndex != hitInfo.Row) { CaretIndex = hitInfo.Row; } } else { if (GetStyleFlag(VTCStyleFlags.ExtendedMultiSelect)) { var action = controlPressed ? ModifySelectionAction.Toggle : ModifySelectionAction.Select; SetCurrentExtendedMultiSelectIndex(hitInfo.Row, shiftPressed, controlPressed, action); // SetCurrentExtendedMultiSelectIndex fires SelectionChanged event. fireEvent = false; } else if (GetStyleFlag(VTCStyleFlags.MultiSelect)) { SetSelected(hitInfo.Row, !IsSelected(hitInfo.Row) || columnSwitch); CurrentIndex = hitInfo.Row; // CurrentIndex setter fires SelectionChanged event. fireEvent = false; } else if (!IsSelected(hitInfo.Row)) { CurrentIndex = hitInfo.Row; // CurrentIndex setter fires SelectionChanged event. fireEvent = false; } } } if (fireEvent) { DoSelectionChanged(); } }
internal VirtualTreeExtendedHitInfo(ref VirtualTreeHitInfo hitInfo, ref ExtraHitInfo extraHitInfo) { myHitInfo = hitInfo; myExtraHitInfo = extraHitInfo; }
public static bool Compare(VirtualTreeHitInfo operand1, VirtualTreeHitInfo operand2) { Debug.Assert(false); // There is no need to compare these return(false); }
public void Activate(ref VirtualTreeHitInfo hit, ref ExtraHitInfo extraInfo, ref Point mousePos, bool immediateActivation) { var hWnd = Handle.ToInt32(); if (hWnd == 0) { return; } var ctrlhWnd = Handle; NativeMethods.SendMessage(ctrlhWnd, NativeMethods.TTM_ACTIVATE, 0, hWnd); if (hit.Row != VirtualTreeConstant.NullIndex) { var ti = new NativeMethods.TOOLINFO(); ti.SetSize(); ti.uId = hWnd; ti.uFlags = NativeMethods.TTF_IDISHWND; ti.rect = NativeMethods.RECT.FromXYWH( extraInfo.ClippedItemRectangle.X, extraInfo.ClippedItemRectangle.Y, extraInfo.ClippedItemRectangle.Width, extraInfo.ClippedItemRectangle.Height); NativeMethods.SendMessage( ctrlhWnd, NativeMethods.TTM_SETDELAYTIME, NativeMethods.TTDT_INITIAL, immediateActivation ? 0 : 250); NativeMethods.SendMessage(ctrlhWnd, NativeMethods.TTM_NEWTOOLRECT, 0, ref ti); NativeMethods.SendMessage(ctrlhWnd, NativeMethods.TTM_ACTIVATE, 1, hWnd); Font = extraInfo.LabelFont; myFormat = extraInfo.LabelFormat; myFullLabelRectangle = extraInfo.FullLabelRectangle; myActivatingMousePos = mousePos; } }
/// <summary> /// Helper routine to determine if the column needs to be switched to /// correctly display the selection of an item. /// </summary> /// <param name="hitInfo">The hitInfo to test</param> /// <returns>true if a column change is required to honor the selection request</returns> private bool RequireColumnSwitchForSelection(ref VirtualTreeHitInfo hitInfo) { var retVal = false; var selColumn = mySelectionColumn; if (hitInfo.DisplayColumn != selColumn) { if (GetStyleFlag(VTCStyleFlags.MultiSelect) && ExtendSelectionToAnchors) { if (hitInfo.DisplayColumn == hitInfo.RawColumn) { // Single width column, must switch retVal = true; } else if (!((selColumn >= hitInfo.DisplayColumn && selColumn <= hitInfo.RawColumn) || (selColumn <= hitInfo.DisplayColumn && selColumn >= hitInfo.RawColumn))) { // The selection column is between the hit columns // Note that the only time this does not work is with a blank expansion // that has an offset anchor. However, even in this case, you have to click // on the column, or on opposite sides of the column to make the column switch, // which is still a reasonable behavior. retVal = true; } } else { retVal = true; } } return retVal; }
/// <summary> /// Control.OnMouseDown override. Handles tree-specific mouse gestures and events. /// </summary> /// <param name="e">MouseEventArgs</param> protected override void OnMouseDown(MouseEventArgs e) { if (e.Clicks == 2) { var doubleClickArgs = new DoubleClickEventArgs(this, e.Button, e.X, e.Y); OnDoubleClick(doubleClickArgs); if (doubleClickArgs.Handled) { SetStateFlag(VTCStateFlags.CallDefWndProc, false); } } else { var hitInfo = myMouseDownHitInfo = HitInfo(e.X, e.Y); // == OnItemButton is correct here. Ignore OnItemButton if OnBlankItem is also set if (e.Button == MouseButtons.Left && 0 != (hitInfo.HitTarget & VirtualTreeHitTargets.OnItemButton)) { if (myTree.IsExpandable(hitInfo.Row, hitInfo.NativeColumn)) { myTree.ToggleExpansion(hitInfo.Row, hitInfo.NativeColumn); SetStateFlag(VTCStateFlags.CallDefWndProc, false); return; } } if (e.Button == MouseButtons.Left && 0 != (hitInfo.HitTarget & VirtualTreeHitTargets.OnItemStateIcon)) { // the state icon was clicked ToggleAndSynchronizeState(myMouseDownHitInfo.Row, myMouseDownHitInfo.NativeColumn); SetStateFlag(VTCStateFlags.CallDefWndProc, false); return; } if (0 != (hitInfo.HitTarget & VirtualTreeHitTargets.OnBlankItem) && e.Button != MouseButtons.Right) { if (hitInfo.HitTarget != VirtualTreeHitTargets.OnBlankItem) { // This is an anchored blank item, handle it specially. // Hold off on shifting anchor columns until we need to. if (RequireColumnSwitchForSelection(ref hitInfo)) { SetSelectionColumn(hitInfo.DisplayColumn, false); } if (GetStyleFlag(VTCStyleFlags.ExtendedMultiSelect)) { var isControlPressed = GetStateFlag(VTCStateFlags.MouseButtonDownCtrl); SetCurrentExtendedMultiSelectIndex( hitInfo.Row, GetStateFlag(VTCStateFlags.MouseButtonDownShift), isControlPressed, isControlPressed ? ModifySelectionAction.Toggle : ModifySelectionAction.Select); } else { CurrentIndex = hitInfo.Row; } } SetStateFlag(VTCStateFlags.CallDefWndProc, false); SetStateFlag(VTCStateFlags.StandardLButtonDownProcessing, true); } // special handling for right-clicks. These don't select in a standard list box, we want // them to select here else if (e.Button == MouseButtons.Right) { if (myMouseDownHitInfo.Row != -1) { DoSelectionChangeFromMouse( ref hitInfo, GetStateFlag(VTCStateFlags.MouseButtonDownShift), GetStateFlag(VTCStateFlags.MouseButtonDownCtrl), MouseButtons.Right); } } } base.OnMouseDown(e); }
public static bool Compare(VirtualTreeHitInfo operand1, VirtualTreeHitInfo operand2) { Debug.Assert(false); // There is no need to compare these return false; }