diff --git a/lcl/comctrls.pp b/lcl/comctrls.pp index 3078eef122..27e7641aa6 100644 --- a/lcl/comctrls.pp +++ b/lcl/comctrls.pp @@ -3331,7 +3331,9 @@ type FLastVertScrollInfo: TScrollInfo; FMaxLvl: integer; // maximum level of all nodes FMaxRight: integer; // maximum text width of all nodes (needed for horizontal scrolling) - fMouseDownPos: TPoint; + FMouseDownPos: TPoint; + FMouseDownNodeSelected: Boolean; + FMouseDownOnFoldingSign: Boolean; FMultiSelectStyle: TMultiSelectStyle; FHotTrackColor: TColor; FOnAddition: TTVExpandedEvent; @@ -3414,6 +3416,7 @@ type function IsStoredBackgroundColor: Boolean; procedure HintMouseLeave(Sender: TObject); procedure ImageListChange(Sender: TObject); + function MouseDownNode(X, Y: Integer): TTreeNode; procedure OnChangeTimer(Sender: TObject); procedure SetAutoExpand(Value: Boolean); procedure SetBackgroundColor(Value: TColor); @@ -3507,6 +3510,10 @@ type procedure Change(Node: TTreeNode); virtual; procedure Collapse(Node: TTreeNode); virtual; procedure CreateWnd; override; + procedure Click; override; + procedure DblClick; override; + procedure TripleClick; override; + procedure QuadClick; override; procedure Delete(Node: TTreeNode); virtual; procedure DestroyWnd; override; procedure DoCreateNodeClass(var NewNodeClass: TTreeNodeClass); virtual; diff --git a/lcl/include/treeview.inc b/lcl/include/treeview.inc index 55abe1ed4c..3a135f8219 100644 --- a/lcl/include/treeview.inc +++ b/lcl/include/treeview.inc @@ -3310,6 +3310,30 @@ begin inherited CreateWnd; end; +procedure TCustomTreeView.Click; +begin + if not FMouseDownOnFoldingSign then + inherited; +end; + +procedure TCustomTreeView.DblClick; +begin + if not FMouseDownOnFoldingSign then + inherited; +end; + +procedure TCustomTreeView.TripleClick; +begin + if not FMouseDownOnFoldingSign then + inherited; +end; + +procedure TCustomTreeView.QuadClick; +begin + if not FMouseDownOnFoldingSign then + inherited; +end; + procedure TCustomTreeView.InitializeWnd; begin inherited InitializeWnd; @@ -5534,23 +5558,27 @@ begin Result := FIndent >= 0; end; +function TCustomTreeView.MouseDownNode(X, Y: Integer): TTreeNode; +begin + Result := GetNodeAt(X, Y); + // Update the NodeSelected flag. + FMouseDownNodeSelected := Assigned(Result) and + (Result.Selected or ((tvoAllowMultiselect in Options) and Result.MultiSelected)); +end; + procedure TCustomTreeView.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var CursorNode: TTreeNode; LogicalX: Integer; - CursorNodeSelected: Boolean; begin {$IFDEF VerboseDrag} DebugLn('TCustomTreeView.MouseDown A ',DbgSName(Self),' '); {$ENDIF} - fMouseDownPos := Point(X,Y); + FMouseDownPos := Point(X,Y); FStates:=FStates-[tvsEditOnMouseUp,tvsSingleSelectOnMouseUp]; - CursorNode := GetNodeAt(X, Y); - CursorNodeSelected := (CursorNode<>nil) - and (CursorNode.Selected - or ((tvoAllowMultiselect in Options) and CursorNode.MultiSelected)); + CursorNode := MouseDownNode(X, Y); LogicalX:=X; //change selection on right click @@ -5564,7 +5592,7 @@ begin if not (tvoAllowMultiselect in Options) then Selected := CursorNode else - if not CursorNodeSelected then + if not FMouseDownNodeSelected then Items.SelectOnlyThis(CursorNode); end; @@ -5574,27 +5602,25 @@ begin inherited MouseDown(Button, Shift, X, Y); //CursorNode must be reassigned again - e.g. in OnMouseDown the node can be deleted or moved. - CursorNode := GetNodeAt(X, Y); - CursorNodeSelected := (CursorNode<>nil) - and (CursorNode.Selected - or ((tvoAllowMultiselect in Options) and CursorNode.MultiSelected)); + CursorNode := MouseDownNode(X, Y); + + //Flag is used for DblClick/TripleClick/QuadClick, so set it before testing ShiftState + FMouseDownOnFoldingSign := + Assigned(CursorNode) and CursorNode.HasChildren and ShowButtons and + (LogicalX >= CursorNode.DisplayExpandSignLeft) and + (LogicalX < CursorNode.DisplayExpandSignRight); //change selection on left click if (Button = mbLeft) and//left click (([ssDouble, ssTriple, ssQuad] * Shift) = []) and//single or first of a multi click (CursorNode <> nil) then begin - if CursorNode.HasChildren and ShowButtons and - (LogicalX >= CursorNode.DisplayExpandSignLeft) and - (LogicalX < CursorNode.DisplayExpandSignRight) then - begin + if FMouseDownOnFoldingSign then // mousedown occured on expand sign -> expand/collapse - CursorNode.Expanded := not CursorNode.Expanded; - end + CursorNode.Expanded := not CursorNode.Expanded else if LogicalX >= CursorNode.DisplayStateIconLeft then begin - // mousedown occured in text or icon - // -> select node and begin drag operation + // mousedown occured in text or icon -> select node and begin drag operation {$IFDEF VerboseDrag} DebugLn(['TCustomTreeView.MouseDown In Text ',DbgSName(Self),' MouseCapture=',MouseCapture]); {$ENDIF} @@ -5623,7 +5649,7 @@ begin end else begin - if not CursorNodeSelected then + if not FMouseDownNodeSelected then Items.SelectOnlyThis(CursorNode) else Include(FStates, tvsSingleSelectOnMouseUp); @@ -5664,27 +5690,29 @@ procedure TCustomTreeView.MouseUp(Button: TMouseButton; Shift: TShiftState; var aMouseDownNode, aMouseUpNode: TTreeNode; begin - if (FHintWnd<>nil) and FHintWnd.Visible then // must hide hint window in mouse up to receive redirected mouse up messages + // must hide hint window in mouse up to receive redirected mouse up messages + if (FHintWnd<>nil) and FHintWnd.Visible then FHintWnd.Hide; inherited MouseUp(Button, Shift, X, Y); if (Button = mbRight) and (Shift = [ssRight]) and Assigned(PopupMenu) then exit; if Button=mbLeft then + begin MouseCapture := False; - if (Button=mbLeft) - and (FStates * [tvsDblClicked, tvsTripleClicked, tvsQuadClicked] = []) - then begin - //AquirePrimarySelection; - aMouseDownNode:=GetNodeAt(fMouseDownPos.X,fMouseDownPos.Y); - aMouseUpNode:=GetNodeAt(X,Y); - if (abs(fMouseDownPos.X-X)+abs(fMouseDownPos.Y-Y)<10) - and (aMouseDownNode=aMouseUpNode) then + if FStates * [tvsDblClicked, tvsTripleClicked, tvsQuadClicked] = [] then begin - // mouse up on mouse-down node - if (tvsEditOnMouseUp in FStates) and (not ReadOnly) then - BeginEditing(Selected) - else if (tvsSingleSelectOnMouseUp in FStates) then - Items.SelectOnlyThis(aMouseUpNode); + //AquirePrimarySelection; + aMouseDownNode:=GetNodeAt(FMouseDownPos.X,FMouseDownPos.Y); + aMouseUpNode:=GetNodeAt(X,Y); + if (abs(FMouseDownPos.X-X)+abs(FMouseDownPos.Y-Y)<10) + and (aMouseDownNode=aMouseUpNode) then + begin + // mouse up on mouse-down node + if (tvsEditOnMouseUp in FStates) and (not ReadOnly) then + BeginEditing(Selected) + else if (tvsSingleSelectOnMouseUp in FStates) then + Items.SelectOnlyThis(aMouseUpNode); + end; end; end; FStates:=FStates-[tvsDblClicked,tvsTripleClicked,tvsQuadClicked,