lcl: toolbutton: when clicked on button part of tbsDropDown, do not paint arrow as down. It's native appearance on Win&Linux.

Further info: This is different from Delphi. Delphi paints the arrow as down in this case, but other applications (MS Office, Adobe, Thunderbird) don't do it. Linux applications don't do it either.

git-svn-id: trunk@50957 -
This commit is contained in:
ondrej 2015-12-20 17:31:34 +00:00
parent 0d604bed83
commit fda56cd53f
2 changed files with 56 additions and 7 deletions

View File

@ -1956,7 +1956,8 @@ type
TToolButtonFlag = TToolButtonFlag =
( (
tbfPressed, // set while mouse is pressed on button tbfPressed, // set while mouse is pressed on button
tbfArrowPressed // set while mouse is pressed on arrow button tbfArrowPressed,// set while mouse is pressed on arrow button
tbfMouseInArrow // set while mouse is on arrow button
); );
TToolButtonFlags = set of TToolButtonFlag; TToolButtonFlags = set of TToolButtonFlag;
@ -1993,6 +1994,7 @@ type
FUpdateCount: Integer; FUpdateCount: Integer;
FWrap: Boolean; FWrap: Boolean;
FLastDropDownTick: QWord; FLastDropDownTick: QWord;
FLastDown: Boolean;
procedure GetGroupBounds(var StartIndex, EndIndex: integer); procedure GetGroupBounds(var StartIndex, EndIndex: integer);
function GetIndex: Integer; function GetIndex: Integer;
function GetTextSize: TSize; function GetTextSize: TSize;
@ -2027,6 +2029,7 @@ type
procedure AssignTo(Dest: TPersistent); override; procedure AssignTo(Dest: TPersistent); override;
procedure BeginUpdate; virtual; procedure BeginUpdate; virtual;
procedure EndUpdate; virtual; procedure EndUpdate; virtual;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseEnter; override; procedure MouseEnter; override;
@ -2059,6 +2062,7 @@ type
Raw: boolean = false; Raw: boolean = false;
WithThemeSpace: boolean = true); override; WithThemeSpace: boolean = true); override;
property Index: Integer read GetIndex; property Index: Integer read GetIndex;
function PointInArrow(const X, Y: Integer): Boolean;
published published
property Action; property Action;
property AllowAllUp: Boolean read FAllowAllUp write FAllowAllUp default False; property AllowAllUp: Boolean read FAllowAllUp write FAllowAllUp default False;

View File

@ -84,7 +84,7 @@ begin
// therefore the condition is always met. // therefore the condition is always met.
if Enabled and not(GetTickCount64 < FLastDropDownTick + 100) then if Enabled and not(GetTickCount64 < FLastDropDownTick + 100) then
begin begin
if (Style = tbsDropDown) and (FToolBar <> nil) and (X > ClientWidth - FToolBar.GetRealDropDownWidth) then if PointInArrow(X, Y) then
Include(NewFlags, tbfArrowPressed) Include(NewFlags, tbfArrowPressed)
else else
Include(NewFlags, tbfPressed); Include(NewFlags, tbfPressed);
@ -96,6 +96,8 @@ begin
end; end;
end; end;
FLastDown := Down;
inherited MouseDown(Button, Shift, X, Y); inherited MouseDown(Button, Shift, X, Y);
FLastDropDownTick := 0; FLastDropDownTick := 0;
@ -127,13 +129,23 @@ procedure TToolButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
var var
Pressed: Boolean; Pressed: Boolean;
Pt: TPoint; Pt: TPoint;
NewFlags: TToolButtonFlags;
begin begin
//DebugLn(['TToolButton.MouseUp ',Name,':',ClassName,' ',dbgs(ord(Button)),' ',X,',',Y]); //DebugLn(['TToolButton.MouseUp ',Name,':',ClassName,' ',dbgs(ord(Button)),' ',X,',',Y]);
Pressed := (Button = mbLeft) and ([tbfArrowPressed, tbfPressed] * FToolButtonFlags <> []); FLastDown := False;
NewFlags := FToolButtonFlags;
Pressed := (Button = mbLeft) and ([tbfArrowPressed, tbfPressed] * NewFlags <> []);
if Pressed then if Pressed then
begin begin
Exclude(FToolButtonFlags, tbfPressed); Exclude(NewFlags, tbfPressed);
Exclude(FToolButtonFlags, tbfArrowPressed); Exclude(NewFlags, tbfArrowPressed);
end;
if (tbfMouseInArrow in NewFlags) and PointInArrow(X, Y) then
Exclude(NewFlags, tbfMouseInArrow);
if NewFlags <> FToolButtonFlags then
begin
FToolButtonFlags := NewFlags;
Invalidate; Invalidate;
end; end;
@ -191,7 +203,10 @@ procedure TToolButton.Paint;
begin begin
ArrowState := TThemedToolBar(ord(ttbSplitButtonDropDownNormal) + OwnerDetails.State - 1); ArrowState := TThemedToolBar(ord(ttbSplitButtonDropDownNormal) + OwnerDetails.State - 1);
if (tbfArrowPressed in FToolButtonFlags) and FMouseInControl and Enabled then if (tbfArrowPressed in FToolButtonFlags) and FMouseInControl and Enabled then
ArrowState := ttbSplitButtonDropDownPressed; ArrowState := ttbSplitButtonDropDownPressed
else
if (FToolButtonFlags*[tbfMouseInArrow,tbfPressed] = [tbfPressed]) and not FLastDown then
ArrowState := ttbSplitButtonDropDownHot;
end; end;
Details := ThemeServices.GetElementDetails(ArrowState); Details := ThemeServices.GetElementDetails(ArrowState);
if (FToolBar <> nil) and (not FToolBar.Flat) if (FToolBar <> nil) and (not FToolBar.Flat)
@ -445,6 +460,13 @@ begin
inherited Paint; inherited Paint;
end; end;
function TToolButton.PointInArrow(const X, Y: Integer): Boolean;
begin
Result := (Style = tbsDropDown) and (FToolBar <> nil)
and (Y >= 0) and (Y <= ClientHeight)
and (X > ClientWidth - FToolBar.GetRealDropDownWidth) and (X <= ClientWidth);
end;
procedure TToolButton.Loaded; procedure TToolButton.Loaded;
begin begin
inherited Loaded; inherited Loaded;
@ -535,14 +557,37 @@ procedure TToolButton.MouseLeave;
begin begin
// DebugLn('TToolButton.MouseLeave ',Name); // DebugLn('TToolButton.MouseLeave ',Name);
inherited MouseLeave; inherited MouseLeave;
if (not MouseCapture) and ([tbfPressed, tbfArrowPressed] * FToolButtonFlags <> []) then if (not MouseCapture) and ([tbfPressed, tbfArrowPressed, tbfMouseInArrow] * FToolButtonFlags <> []) then
begin begin
Exclude(FToolButtonFlags, tbfPressed); Exclude(FToolButtonFlags, tbfPressed);
Exclude(FToolButtonFlags, tbfArrowPressed); Exclude(FToolButtonFlags, tbfArrowPressed);
Exclude(FToolButtonFlags, tbfMouseInArrow);
end; end;
SetMouseInControl(false); SetMouseInControl(false);
end; end;
procedure TToolButton.MouseMove(Shift: TShiftState; X, Y: Integer);
var
NewFlags: TToolButtonFlags;
begin
inherited MouseMove(Shift, X, Y);
if (not MouseCapture) and (Style = tbsDropDown) and (FToolBar <> nil) then
begin
NewFlags := FToolButtonFlags;
if PointInArrow(X, Y) then
Include(NewFlags, tbfMouseInArrow)
else
Exclude(NewFlags, tbfMouseInArrow);
if NewFlags <> FToolButtonFlags then
begin
FToolButtonFlags := NewFlags;
Invalidate;
end;
end;
end;
procedure TToolButton.SetDown(Value: Boolean); procedure TToolButton.SetDown(Value: Boolean);
var var
StartIndex, EndIndex: integer; StartIndex, EndIndex: integer;