mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-28 10:02:14 +00:00
ADD: The possibility to use a concept of "Tree View Menu" where the possible actions offered to the user are placed into a tree view. There is above an edit box where user might enter a few letters to eliminate the non-matching choices from the visual field so only the matching ones are remaining visible. User might use arrows keys to move up and down through possible selectable items from the three. He might even use ALT+KEY shorcut to select item. This way, user might choose quicker when list are long without having to give much attention. ADD: The "Tree View Menu" are not offered by default so it won't impact on user by default. User needs to activate the "Tree View Menu" presentation from "Tree View Menu" configuration page. ADD: "Tree View Menu" may be activated for selection from hot directories configured independently if it was called from internal command "cm_DirHotList" or from a double click for the top of the panel. ADD: "Tree View Menu" may be activated for selection from favorite tabs configured independently if it was called from internal command "cm_LoadFavoriteTabs" or from a double click on a tabs. ADD: "Tree View Menu" may be activated for selection from directories in dir history. ADD: "Tree View Menu" may be activated for selection from directories in fileview history, ADD: "Tree View Menu" may be activated for selection of commands when looking at the command line history. UPD: The internal commands "cm_ShowMainMenu" may now supports the parameter "treeview" with boolean possible values to offer the possibility to choose item from main menu items through a "Tree View Menu" look. UPD: Put back in action the internal command "cm_ShowButtonMenu" to make visible or not the toolbar with the parameter "toolbar" with boolean possible values. UPD: The internal commands "cm_ShowButtonMenu" may now supports the parameter "treeview" with boolean possible values to offer the possibility to choose item from toolbar items through a "Tree View Menu" look. ADD: In the TKASToolBar, add a "PublicExecuteToolItem" function so given a "TKASToolItem", we may call its execution directly from it. ADD: Two new configuration pages related with the "Tree View Menus" which are a page for basic settings "fOptionsTreeViewMenu" and one for colors "fOptionsTreeViewMenuColor". ADD: Add new 32x32 icon for the commands "cm_configtreeviewmenus" and "cm_configtreeviewmenuscolors". UPD: Change 32x32 icon for the "cm_showbuttonmenu" so it looks like a little more to a DC toolbar. UPD: New parameter "position=" for the internal command "cm_DirHotList" with possible values "panel" or "cursor" to determine where it will be shown. Previous one was not documented and use only internally so no need to respect legacy here.
1094 lines
32 KiB
ObjectPascal
1094 lines
32 KiB
ObjectPascal
{
|
|
Double Commander components
|
|
-------------------------------------------------------------------------
|
|
Toolbar panel class
|
|
|
|
Copyright (C) 2006-2016 Koblov Alexander (Alexx2000@mail.ru)
|
|
|
|
contributors:
|
|
2012 Przemyslaw Nagay (cobines@gmail.com)
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
in a file called COPYING along with this program; if not, write to
|
|
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
|
|
02139, USA.
|
|
}
|
|
|
|
unit KASToolBar;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, LResources, Forms, Controls, ComCtrls,
|
|
Graphics, Dialogs, ExtCtrls, Buttons, FileUtil, Menus,
|
|
DCXmlConfig, KASToolItems, LCLVersion;
|
|
|
|
type
|
|
TOnToolButtonClick = procedure (Sender: TObject) of object;
|
|
TOnToolButtonMouseUpDown = procedure (Sender: TObject; Button: TMouseButton; Shift:TShiftState; X,Y:Integer) of object;
|
|
TOnToolButtonMouseMove = procedure (Sender: TObject; Shift:TShiftState; X,Y:Integer; NumberOfButton: Integer) of object;
|
|
TOnToolButtonDragOver = procedure(Sender, Source: TObject; X,Y: Integer;
|
|
State: TDragState; var Accept: Boolean; NumberOfButton: Integer) of object;
|
|
TOnToolButtonDragDrop = procedure(Sender, Source: TObject; X, Y: Integer) of object;
|
|
TOnToolButtonEndDrag = procedure(Sender, Target: TObject; X,Y: Integer) of object;
|
|
TOnLoadButtonGlyph = function (ToolItem: TKASToolItem; iIconSize: Integer; clBackColor: TColor): TBitmap of object;
|
|
TOnToolItemExecute = procedure (ToolItem: TKASToolItem) of object;
|
|
TOnConfigLoadItem = function (Config: TXmlConfig; Node: TXmlNode): TKASToolItem of object;
|
|
TOnToolItemShortcutsHint = function (ToolItem: TKASNormalItem): String of object;
|
|
TTypeOfConfigurationLoad = (tocl_FlushCurrentToolbarContent, tocl_AddToCurrentToolbarContent);
|
|
|
|
TKASToolBar = class;
|
|
|
|
{ TKASToolButton }
|
|
|
|
TKASToolButton = class(TSpeedButton)
|
|
private
|
|
FToolItem: TKASToolItem;
|
|
function GetToolBar: TKASToolBar;
|
|
protected
|
|
procedure CalculatePreferredSize(var PreferredWidth,
|
|
PreferredHeight: integer; WithThemeSpace: Boolean); override;
|
|
public
|
|
constructor Create(AOwner: TComponent; Item: TKASToolItem); reintroduce;
|
|
property ToolBar: TKASToolBar read GetToolBar;
|
|
property ToolItem: TKASToolItem read FToolItem;
|
|
end;
|
|
|
|
{ TKASToolDivider }
|
|
|
|
TKASToolDivider = class(TKASToolButton)
|
|
protected
|
|
procedure CalculatePreferredSize(var PreferredWidth,
|
|
PreferredHeight: integer; WithThemeSpace: Boolean); override;
|
|
procedure Paint; override;
|
|
end;
|
|
|
|
{ TKASToolBar }
|
|
|
|
TKASToolBar = class(TToolBar, IToolOwner)
|
|
private
|
|
FButtonHeight: Integer;
|
|
FButtonWidth: Integer;
|
|
FFlat: Boolean;
|
|
FGlyphSize: Integer;
|
|
FRadioToolBar: Boolean;
|
|
FRowHeight: Integer;
|
|
FShowDividerAsButton: Boolean;
|
|
FToolItemExecutors: TFPList;
|
|
FToolItems: TKASToolBarItems;
|
|
FToolPopupMenu: TPopupMenu;
|
|
FOwnsToolItems: Boolean;
|
|
{$if lcl_fullversion < 1010000}
|
|
FUpdateCount: Integer;
|
|
{$endif}
|
|
FOnToolButtonClick: TOnToolButtonClick;
|
|
FOnToolButtonMouseDown: TOnToolButtonMouseUpDown;
|
|
FOnToolButtonMouseUp: TOnToolButtonMouseUpDown;
|
|
FOnToolButtonMouseMove: TOnToolButtonMouseMove;
|
|
FOnToolButtonDragOver: TOnToolButtonDragOver;
|
|
FOnToolButtonDragDrop: TOnToolButtonDragDrop;
|
|
FOnToolButtonEndDrag: TOnToolButtonEndDrag;
|
|
FOnLoadButtonGlyph: TOnLoadButtonGlyph;
|
|
FOnToolItemExecute: TOnToolItemExecute;
|
|
FOnToolItemShortcutsHint: TOnToolItemShortcutsHint;
|
|
FKASToolBarFlags: TToolBarFlags;
|
|
FResizeButtonsNeeded: Boolean;
|
|
procedure AssignToolButtonProperties(ToolButton: TKASToolButton);
|
|
procedure ClearExecutors;
|
|
function CreateButton(Item: TKASToolItem): TKASToolButton;
|
|
function ExecuteToolItem(Item: TKASToolItem): Boolean;
|
|
function FindButton(Button: TKASToolButton): Integer;
|
|
function GetChangePath: String;
|
|
function GetEnvVar: String;
|
|
function GetToolItemShortcutsHint(Item: TKASToolItem): String;
|
|
function LoadBtnIcon(IconPath: String): TBitMap;
|
|
procedure DrawLinkIcon(Image: TBitMap);
|
|
function GetButton(Index: Integer): TKASToolButton;
|
|
procedure InsertButton(InsertAt: Integer; ToolButton: TKASToolButton);
|
|
procedure SetButtonHeight(const AValue: Integer);
|
|
procedure SetButtonWidth(const AValue: Integer);
|
|
procedure SetChangePath(const {%H-}AValue: String);
|
|
procedure SetEnvVar(const {%H-}AValue: String);
|
|
procedure SetFlat(const AValue: Boolean);
|
|
procedure SetGlyphSize(const AValue: Integer);
|
|
procedure ShowMenu(ToolButton: TKASToolButton);
|
|
procedure ToolButtonClick(Sender: TObject);
|
|
procedure ToolButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift:TShiftState; X,Y:Integer);
|
|
procedure ToolButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift:TShiftState; X,Y:Integer);
|
|
procedure ToolButtonMouseMove(Sender: TObject; Shift:TShiftState; X,Y:Integer);
|
|
procedure ToolButtonDragOver(Sender, Source: TObject; X,Y: Integer; State: TDragState; var Accept: Boolean);
|
|
procedure ToolButtonDragDrop(Sender, Source: TObject; X,Y: Integer);
|
|
procedure ToolButtonEndDrag(Sender, Target: TObject; X, Y: Integer);
|
|
procedure ToolItemLoaded(Item: TKASToolItem);
|
|
procedure ToolMenuClicked(Sender: TObject);
|
|
procedure UpdateButtonsTags;
|
|
protected
|
|
procedure CalculatePreferredSize(var PreferredWidth,
|
|
PreferredHeight: Integer; WithThemeSpace: Boolean); override;
|
|
procedure ControlsAligned; override;
|
|
procedure FontChanged(Sender: TObject); override;
|
|
function WrapButtons(UseWidth: integer;
|
|
out NewWidth, NewHeight: Integer; Simulate: boolean): Boolean;
|
|
procedure ResizeButtons;
|
|
public
|
|
constructor Create(TheOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
function AddButton(Item: TKASToolItem): TKASToolButton;
|
|
procedure AddToolItemExecutor(ToolItemClass: TKASToolItemClass;
|
|
ExecuteFunction: TOnToolItemExecute);
|
|
procedure Clear;
|
|
procedure ClickItem(ToolItemID: String); overload;
|
|
function InsertButton(InsertAt: Integer; Item: TKASToolItem): TKASToolButton;
|
|
function InsertButton(InsertAt: TKASToolButton; Item: TKASToolItem): TKASToolButton;
|
|
procedure MoveButton(ButtonIndex, MovePosition: Integer);
|
|
procedure MoveButton(SourceButton: TKASToolButton; TargetToolBar: TKASToolBar; InsertAt: TKASToolButton);
|
|
procedure RemoveButton(Index: Integer);
|
|
procedure RemoveButton(Button: TKASToolButton);
|
|
procedure RemoveToolItemExecutor(ExecuteFunction: TOnToolItemExecute);
|
|
procedure UncheckAllButtons;
|
|
procedure UpdateIcon(ToolButton: TKASToolButton);
|
|
procedure UseItems(AItems: TKASToolBarItems);
|
|
|
|
procedure LoadConfiguration(Config: TXmlConfig; RootNode: TXmlNode;
|
|
Loader: TKASToolBarLoader; ConfigurationLoadType:TTypeOfConfigurationLoad);
|
|
procedure SaveConfiguration(Config: TXmlConfig; RootNode: TXmlNode);
|
|
|
|
procedure BeginUpdate; override;
|
|
procedure EndUpdate; override;
|
|
procedure SetButtonSize(NewButtonWidth, NewButtonHeight: Integer);
|
|
function PublicExecuteToolItem(Item: TKASToolItem): Boolean;
|
|
|
|
property Buttons[Index: Integer]: TKASToolButton read GetButton;
|
|
property RowHeight: Integer read FRowHeight;
|
|
|
|
published
|
|
property OnLoadButtonGlyph : TOnLoadButtonGlyph read FOnLoadButtonGlyph write FOnLoadButtonGlyph;
|
|
property OnToolButtonClick: TOnToolButtonClick read FOnToolButtonClick write FOnToolButtonClick;
|
|
property OnToolButtonMouseDown: TOnToolButtonMouseUpDown read FOnToolButtonMouseDown write FOnToolButtonMouseDown;
|
|
property OnToolButtonMouseUp: TOnToolButtonMouseUpDown read FOnToolButtonMouseUp write FOnToolButtonMouseUp;
|
|
property OnToolButtonMouseMove: TOnToolButtonMouseMove read FOnToolButtonMouseMove write FOnToolButtonMouseMove;
|
|
property OnToolButtonDragDrop: TOnToolButtonDragDrop read FOnToolButtonDragDrop write FOnToolButtonDragDrop;
|
|
property OnToolButtonEndDrag: TOnToolButtonEndDrag read FOnToolButtonEndDrag write FOnToolButtonEndDrag;
|
|
property OnToolButtonDragOver: TOnToolButtonDragOver read FOnToolButtonDragOver write FOnToolButtonDragOver;
|
|
property OnToolItemExecute: TOnToolItemExecute read FOnToolItemExecute write FOnToolItemExecute;
|
|
property OnToolItemShortcutsHint: TOnToolItemShortcutsHint read FOnToolItemShortcutsHint write FOnToolItemShortcutsHint;
|
|
property RadioToolBar: Boolean read FRadioToolBar write FRadioToolBar default False;
|
|
property Flat: Boolean read FFlat write SetFlat default False;
|
|
property GlyphSize: Integer read FGlyphSize write SetGlyphSize;
|
|
property ButtonHeight: Integer read FButtonHeight write SetButtonHeight default 22;
|
|
property ButtonWidth: Integer read FButtonWidth write SetButtonWidth default 23;
|
|
property ShowDividerAsButton: Boolean read FShowDividerAsButton write FShowDividerAsButton default False;
|
|
|
|
property ChangePath: String read GetChangePath write SetChangePath;
|
|
property EnvVar: String read GetEnvVar write SetEnvVar;
|
|
end;
|
|
|
|
procedure Register;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Themes, types, math, DCOSUtils;
|
|
|
|
type
|
|
PToolItemExecutor = ^TToolItemExecutor;
|
|
TToolItemExecutor = record
|
|
ToolItemClass: TKASToolItemClass;
|
|
ToolItemExecute: TOnToolItemExecute;
|
|
end;
|
|
|
|
procedure Register;
|
|
begin
|
|
RegisterComponents('KASComponents',[TKASToolBar]);
|
|
end;
|
|
|
|
{ TKASToolBar }
|
|
|
|
procedure TKASToolBar.InsertButton(InsertAt: Integer; ToolButton: TKASToolButton);
|
|
begin
|
|
if InsertAt < 0 then
|
|
InsertAt:= 0;
|
|
if InsertAt > ButtonList.Count then
|
|
InsertAt:= ButtonList.Count;
|
|
|
|
ButtonList.Insert(InsertAt, ToolButton);
|
|
FToolItems.Insert(InsertAt, ToolButton.ToolItem);
|
|
|
|
UpdateButtonsTags;
|
|
ResizeButtons;
|
|
end;
|
|
|
|
function TKASToolBar.InsertButton(InsertAt: TKASToolButton; Item: TKASToolItem): TKASToolButton;
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Index := ButtonList.IndexOf(InsertAt);
|
|
if Index < 0 then
|
|
Index := ButtonCount;
|
|
Result := InsertButton(Index, Item);
|
|
end;
|
|
|
|
procedure TKASToolBar.CalculatePreferredSize(var PreferredWidth,
|
|
PreferredHeight: Integer; WithThemeSpace: Boolean);
|
|
begin
|
|
WrapButtons(Width, PreferredWidth, PreferredHeight, True);
|
|
end;
|
|
|
|
procedure TKASToolBar.ControlsAligned;
|
|
var
|
|
NewWidth, NewHeight: integer;
|
|
begin
|
|
if tbfPlacingControls in FKASToolBarFlags then exit;
|
|
Include(FKASToolBarFlags, tbfPlacingControls);
|
|
try
|
|
WrapButtons(Width, NewWidth, NewHeight, False);
|
|
finally
|
|
Exclude(FKASToolBarFlags, tbfPlacingControls);
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.FontChanged(Sender: TObject);
|
|
begin
|
|
inherited FontChanged(Sender);
|
|
ResizeButtons;
|
|
end;
|
|
|
|
function TKASToolBar.WrapButtons(UseWidth: integer;
|
|
out NewWidth, NewHeight: Integer; Simulate: boolean): Boolean;
|
|
var
|
|
ARect: TRect;
|
|
x: Integer;
|
|
y: Integer;
|
|
CurControl: TControl;
|
|
StartX: Integer;
|
|
|
|
procedure CalculatePosition;
|
|
var
|
|
NewBounds: TRect;
|
|
begin
|
|
NewBounds := Bounds(x, y, CurControl.Width, RowHeight);
|
|
repeat
|
|
if (not Wrapable) or
|
|
(NewBounds.Right <= ARect.Right) or
|
|
(NewBounds.Left = StartX) then
|
|
begin
|
|
// control fits into the row
|
|
x := NewBounds.Left;
|
|
y := NewBounds.Top;
|
|
break;
|
|
end;
|
|
|
|
// try next row
|
|
NewBounds.Left := StartX;
|
|
NewBounds.Right := NewBounds.Left + CurControl.Width;
|
|
inc(NewBounds.Top, RowHeight);
|
|
inc(NewBounds.Bottom, RowHeight);
|
|
until false;
|
|
end;
|
|
|
|
var
|
|
CurClientRect: TRect;
|
|
AdjustClientFrame: TRect;
|
|
i: Integer;
|
|
w, h: Longint;
|
|
begin
|
|
Result := True;
|
|
NewWidth := 0;
|
|
NewHeight := 0;
|
|
DisableAlign;
|
|
BeginUpdate;
|
|
try
|
|
CurClientRect := ClientRect;
|
|
inc(CurClientRect.Right, UseWidth - Width);
|
|
ARect := CurClientRect;
|
|
AdjustClientRect(ARect);
|
|
AdjustClientFrame.Left := ARect.Left - CurClientRect.Left;
|
|
AdjustClientFrame.Top := ARect.Top - CurClientRect.Top;
|
|
AdjustClientFrame.Right := CurClientRect.Right - ARect.Right;
|
|
AdjustClientFrame.Bottom := CurClientRect.Bottom - ARect.Bottom;
|
|
//DebugLn(['TToolBar.WrapButtons ',DbgSName(Self),' ARect=',dbgs(ARect)]);
|
|
// important: top, left button must start in the AdjustClientRect top, left
|
|
// otherwise Toolbar.AutoSize=true will create an endless loop
|
|
StartX := ARect.Left;
|
|
x := StartX;
|
|
y := ARect.Top;
|
|
for i := 0 to ButtonList.Count - 1 do
|
|
begin
|
|
CurControl := TControl(ButtonList[i]);
|
|
if not CurControl.IsControlVisible then
|
|
Continue;
|
|
CalculatePosition;
|
|
|
|
w := CurControl.Width;
|
|
h := CurControl.Height;
|
|
|
|
if (not Simulate) and ((CurControl.Left <> x) or (CurControl.Top <> y)) then
|
|
begin
|
|
CurControl.SetBounds(x,y,w,h); // Note: do not use SetBoundsKeepBase
|
|
end;
|
|
|
|
// adjust NewWidth, NewHeight
|
|
NewWidth := Max(NewWidth, x + w + AdjustClientFrame.Right);
|
|
NewHeight := Max(NewHeight, y + h + AdjustClientFrame.Bottom);
|
|
|
|
// step to next position
|
|
inc(x,w);
|
|
end;
|
|
finally
|
|
EndUpdate;
|
|
EnableAlign;
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.ResizeButtons;
|
|
var
|
|
w, h: LongInt;
|
|
i: Integer;
|
|
CurControl: TControl;
|
|
begin
|
|
if FUpdateCount > 0 then
|
|
begin
|
|
FResizeButtonsNeeded := True;
|
|
Exit;
|
|
end;
|
|
|
|
InvalidatePreferredChildSizes;
|
|
FRowHeight := ButtonHeight; // Row height is at least initial button height
|
|
|
|
// First recalculate RowHeight.
|
|
for i := 0 to ButtonList.Count - 1 do
|
|
begin
|
|
CurControl := TControl(ButtonList[i]);
|
|
w := ButtonWidth;
|
|
h := ButtonHeight;
|
|
CurControl.GetPreferredSize(w, h);
|
|
if FRowHeight < h then
|
|
FRowHeight := h;
|
|
end;
|
|
|
|
FResizeButtonsNeeded := False;
|
|
|
|
// Now resize buttons.
|
|
DisableAlign;
|
|
BeginUpdate;
|
|
try
|
|
for i := 0 to ButtonList.Count - 1 do
|
|
begin
|
|
CurControl := TControl(ButtonList[i]);
|
|
w := ButtonWidth;
|
|
h := RowHeight;
|
|
CurControl.GetPreferredSize(w, h);
|
|
if (CurControl.Width <> w) or (CurControl.Height <> h) then
|
|
CurControl.SetBounds(CurControl.Left, CurControl.Top, w, h);
|
|
end;
|
|
InvalidatePreferredSize;
|
|
AdjustSize;
|
|
finally
|
|
EndUpdate;
|
|
EnableAlign;
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.SaveConfiguration(Config: TXmlConfig; RootNode: TXmlNode);
|
|
var
|
|
Node: TXmlNode;
|
|
Item: TKASToolItem;
|
|
i: Integer;
|
|
begin
|
|
if ButtonCount > 0 then
|
|
begin
|
|
Node := Config.AddNode(RootNode, 'Row');
|
|
for i := 0 to ButtonCount - 1 do
|
|
begin
|
|
Item := TKASToolButton(Buttons[i]).ToolItem;
|
|
Item.Save(Config, Node);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.DrawLinkIcon(Image: TBitMap);
|
|
var
|
|
sizeLink : Integer;
|
|
bmLinkIcon : TBitmap;
|
|
{$IFDEF LCLGTK2}
|
|
bmTempIcon : TBitmap;
|
|
{$ENDIF}
|
|
ToolItem: TKASNormalItem;
|
|
begin
|
|
if (Image = nil) or (FOnLoadButtonGlyph = nil) then Exit;
|
|
sizeLink := FGlyphSize div 2;
|
|
ToolItem := TKASNormalItem.Create;
|
|
ToolItem.Icon := 'emblem-symbolic-link';
|
|
bmLinkIcon:= FOnLoadButtonGlyph(ToolItem, sizeLink, clBtnFace);
|
|
ToolItem.Free;
|
|
if Assigned(bmLinkIcon) then
|
|
begin
|
|
{$IFDEF LCLGTK2} // Under GTK2 can not draw over alpha transparent pixels
|
|
bmTempIcon := TBitmap.Create;
|
|
bmTempIcon.Assign(Image);
|
|
Image.FreeImage;
|
|
Image.SetSize(FGlyphSize, FGlyphSize);
|
|
Image.Canvas.Brush.Color := clBtnFace;
|
|
Image.Canvas.FillRect(0, 0, FGlyphSize, FGlyphSize);
|
|
Image.Canvas.Draw(0, 0, bmTempIcon);
|
|
bmTempIcon.Free;
|
|
{$ENDIF}
|
|
Image.Canvas.Draw(FGlyphSize-sizeLink+2,FGlyphSize-sizeLink+2, bmLinkIcon);
|
|
Image.TransparentColor:= clBtnFace;
|
|
Image.Transparent:= True;
|
|
bmLinkIcon.Free;
|
|
end;
|
|
end;
|
|
|
|
function TKASToolBar.LoadBtnIcon(IconPath: String): TBitMap;
|
|
var
|
|
picture: TPicture;
|
|
begin
|
|
if (IconPath = '') or (not mbFileExists(IconPath)) then Exit(nil);
|
|
|
|
Picture := TPicture.Create;
|
|
try
|
|
Picture.LoadFromFile(IconPath);
|
|
Result := TBitmap.Create;
|
|
Result.Assign(Picture.Bitmap);
|
|
finally
|
|
FreeAndNil(Picture);
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.LoadConfiguration(Config: TXmlConfig; RootNode: TXmlNode;
|
|
Loader: TKASToolBarLoader; ConfigurationLoadType:TTypeOfConfigurationLoad);
|
|
var
|
|
Node: TXmlNode;
|
|
begin
|
|
BeginUpdate;
|
|
if ConfigurationLoadType=tocl_FlushCurrentToolbarContent then
|
|
begin
|
|
Clear;
|
|
Application.ProcessMessages;
|
|
end;
|
|
try
|
|
Node := Config.FindNode(RootNode, 'Row', False);
|
|
if Assigned(Node) then
|
|
Loader.Load(Config, Node, @ToolItemLoaded);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.AssignToolButtonProperties(ToolButton: TKASToolButton);
|
|
begin
|
|
ToolButton.OnClick:= @ToolButtonClick;
|
|
ToolButton.OnMouseDown:= @ToolButtonMouseDown;
|
|
ToolButton.OnMouseUp:= @ToolButtonMouseUp;
|
|
ToolButton.OnMouseMove:= @ToolButtonMouseMove;
|
|
ToolButton.OnDragDrop:= @ToolButtonDragDrop;
|
|
ToolButton.OnDragOver:= @ToolButtonDragOver;
|
|
ToolButton.OnEndDrag:= @ToolButtonEndDrag;
|
|
end;
|
|
|
|
function TKASToolBar.GetChangePath: String;
|
|
begin
|
|
end;
|
|
|
|
function TKASToolBar.GetEnvVar: String;
|
|
begin
|
|
end;
|
|
|
|
function TKASToolBar.GetToolItemShortcutsHint(Item: TKASToolItem): String;
|
|
begin
|
|
Result := '';
|
|
if Assigned(FOnToolItemShortcutsHint) and (Item is TKASNormalItem) then
|
|
Result := FOnToolItemShortcutsHint(TKASNormalItem(Item));
|
|
end;
|
|
|
|
function TKASToolBar.GetButton(Index: Integer): TKASToolButton;
|
|
begin
|
|
Result:= TKASToolButton(ButtonList.Items[Index]);
|
|
end;
|
|
|
|
procedure TKASToolBar.SetChangePath(const AValue: String);
|
|
begin
|
|
end;
|
|
|
|
procedure TKASToolBar.SetEnvVar(const AValue: String);
|
|
begin
|
|
end;
|
|
|
|
procedure TKASToolBar.SetFlat(const AValue: Boolean);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
FFlat:= AValue;
|
|
for I:= 0 to ButtonList.Count - 1 do
|
|
TKASToolButton(ButtonList.Items[I]).Flat:= FFlat;
|
|
end;
|
|
|
|
procedure TKASToolBar.SetGlyphSize(const AValue: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if FGlyphSize = AValue then Exit;
|
|
FGlyphSize:= AValue;
|
|
|
|
BeginUpdate;
|
|
try
|
|
for I := 0 to ButtonList.Count - 1 do
|
|
UpdateIcon(TKASToolButton(ButtonList[i]));
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.ShowMenu(ToolButton: TKASToolButton);
|
|
procedure MakeMenu(PopupMenu: TMenuItem; MenuItem: TKASMenuItem);
|
|
var
|
|
I: Integer;
|
|
Item: TKASToolItem;
|
|
PopupMenuItem: TMenuItem;
|
|
BitmapTmp: TBitmap = nil;
|
|
sText: String;
|
|
begin
|
|
for I := 0 to MenuItem.SubItems.Count - 1 do
|
|
begin
|
|
Item := MenuItem.SubItems.Items[I];
|
|
if Item is TKASSeparatorItem then
|
|
begin
|
|
PopupMenu.AddSeparator;
|
|
end
|
|
else
|
|
begin
|
|
PopupMenuItem := TMenuItem.Create(PopupMenu);
|
|
sText := Item.GetEffectiveText;
|
|
if sText = '' then
|
|
sText := Item.GetEffectiveHint;
|
|
PopupMenuItem.Caption := StringReplace(StringReplace(sText, #$0A, ' | ', [rfReplaceAll]), ' | ----', '', [rfReplaceAll]);
|
|
|
|
if Item is TKASNormalItem then
|
|
begin
|
|
if Assigned(FOnLoadButtonGlyph) then
|
|
BitmapTmp := FOnLoadButtonGlyph(Item, 16, clMenu);
|
|
if not Assigned(BitmapTmp) then
|
|
BitmapTmp := LoadBtnIcon(TKASNormalItem(Item).Icon);
|
|
|
|
PopupMenuItem.Bitmap := BitmapTmp;
|
|
FreeAndNil(BitmapTmp);
|
|
end;
|
|
|
|
PopupMenuItem.Tag := PtrInt(Item);
|
|
PopupMenuItem.OnClick := TNotifyEvent(@ToolMenuClicked);
|
|
PopupMenu.Add(PopupMenuItem);
|
|
|
|
if Item is TKASMenuItem then
|
|
MakeMenu(PopupMenuItem, TKASMenuItem(Item));
|
|
end;
|
|
end;
|
|
end;
|
|
var
|
|
Point: TPoint;
|
|
begin
|
|
FToolPopupMenu.Free;
|
|
FToolPopupMenu := TPopupMenu.Create(Self);
|
|
MakeMenu(FToolPopupMenu.Items, ToolButton.ToolItem as TKASMenuItem);
|
|
Point.x := ToolButton.Left;
|
|
Point.y := ToolButton.Top + ToolButton.Height;
|
|
Point := Self.ClientToScreen(Point);
|
|
FToolPopupMenu.PopUp(Point.x, Point.y);
|
|
end;
|
|
|
|
procedure TKASToolBar.ToolButtonClick(Sender: TObject);
|
|
var
|
|
Button: TKASToolButton;
|
|
begin
|
|
Button := Sender as TKASToolButton;
|
|
|
|
// Do not allow depressing down buttons.
|
|
if FRadioToolBar and not Button.Down then
|
|
Button.Down := True;
|
|
|
|
if not ExecuteToolItem(Button.ToolItem) then
|
|
begin
|
|
if Assigned(FOnToolButtonClick) then
|
|
FOnToolButtonClick(Button)
|
|
else if Button.ToolItem is TKASMenuItem then
|
|
begin
|
|
ShowMenu(Button);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.ToolButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift:TShiftState; X,Y:Integer);
|
|
begin
|
|
if Assigned(FOnToolButtonMouseDown) then
|
|
FOnToolButtonMouseDown(Sender, Button, Shift, X,Y);
|
|
end;
|
|
|
|
procedure TKASToolBar.ToolButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift:TShiftState; X,Y:Integer);
|
|
begin
|
|
if Assigned(FOnToolButtonMouseUp) then
|
|
FOnToolButtonMouseUp(Sender, Button, Shift, X,Y);
|
|
end;
|
|
|
|
procedure TKASToolBar.ToolItemLoaded(Item: TKASToolItem);
|
|
begin
|
|
AddButton(Item);
|
|
end;
|
|
|
|
procedure TKASToolBar.ToolMenuClicked(Sender: TObject);
|
|
begin
|
|
ExecuteToolItem(TKASToolItem((Sender as TMenuItem).Tag));
|
|
end;
|
|
|
|
procedure TKASToolBar.ToolButtonMouseMove(Sender: TObject; Shift:TShiftState; X,Y:Integer);
|
|
begin
|
|
if Assigned(FOnToolButtonMouseMove) then
|
|
FOnToolButtonMouseMove(Sender, Shift, X,Y, (Sender as TSpeedButton).Tag);
|
|
end;
|
|
|
|
procedure TKASToolBar.ToolButtonDragOver(Sender, Source: TObject; X,Y: Integer; State: TDragState; var Accept: Boolean);
|
|
begin
|
|
if Assigned(FOnToolButtonDragOver) then
|
|
FOnToolButtonDragOver(Sender, Source, X,Y, State, Accept, (Sender as TSpeedButton).Tag);
|
|
end;
|
|
|
|
procedure TKASToolBar.ToolButtonDragDrop(Sender, Source: TObject; X,Y: Integer);
|
|
begin
|
|
if Assigned(FOnToolButtonDragDrop) then
|
|
FOnToolButtonDragDrop(Sender, Source, X, Y);
|
|
end;
|
|
|
|
procedure TKASToolBar.ToolButtonEndDrag(Sender, Target: TObject; X, Y: Integer);
|
|
begin
|
|
if Assigned(FOnToolButtonEndDrag) then
|
|
FOnToolButtonEndDrag(Sender, Target, X, Y);
|
|
end;
|
|
|
|
procedure TKASToolBar.MoveButton(ButtonIndex, MovePosition: Integer);
|
|
begin
|
|
ButtonList.Move(ButtonIndex, MovePosition);
|
|
FToolItems.Move(ButtonIndex, MovePosition);
|
|
UpdateButtonsTags;
|
|
ResizeButtons;
|
|
end;
|
|
|
|
procedure TKASToolBar.MoveButton(SourceButton: TKASToolButton; TargetToolBar: TKASToolBar; InsertAt: TKASToolButton);
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Index := FindButton(SourceButton);
|
|
if (Index <> -1) and (FToolItems[Index] = SourceButton.ToolItem) then
|
|
begin
|
|
SourceButton.FToolItem := nil;
|
|
TargetToolBar.InsertButton(InsertAt, FToolItems.ReleaseItem(Index));
|
|
ButtonList.Delete(Index);
|
|
Application.ReleaseComponent(SourceButton); // Free later
|
|
UpdateButtonsTags;
|
|
Resize;
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.UpdateButtonsTags;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I:= 0 to ButtonList.Count - 1 do
|
|
TKASToolButton(ButtonList.Items[I]).Tag:= I;
|
|
end;
|
|
|
|
procedure TKASToolBar.UpdateIcon(ToolButton: TKASToolButton);
|
|
var
|
|
Bitmap: TBitmap = nil;
|
|
begin
|
|
try
|
|
if Assigned(FOnLoadButtonGlyph) then
|
|
Bitmap := FOnLoadButtonGlyph(ToolButton.ToolItem, FGlyphSize, clBtnFace);
|
|
|
|
if not Assigned(Bitmap) and (ToolButton.ToolItem is TKASNormalItem) then
|
|
Bitmap := LoadBtnIcon(TKASNormalItem(ToolButton.ToolItem).Icon);
|
|
|
|
try
|
|
if (ToolButton.ToolItem is TKASMenuItem) and Assigned(Bitmap) then
|
|
DrawLinkIcon(Bitmap);
|
|
|
|
ToolButton.Glyph.Assign(Bitmap);
|
|
finally
|
|
Bitmap.Free;
|
|
end;
|
|
except
|
|
// Ignore
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.UseItems(AItems: TKASToolBarItems);
|
|
var
|
|
i: Integer;
|
|
Button: TKASToolButton;
|
|
begin
|
|
if Assigned(AItems) then
|
|
begin
|
|
BeginUpdate;
|
|
|
|
Clear;
|
|
if FOwnsToolItems then
|
|
FToolItems.Free;
|
|
FToolItems := AItems;
|
|
FOwnsToolItems := False;
|
|
|
|
// Insert the existing items as buttons.
|
|
for i := 0 to FToolItems.Count - 1 do
|
|
begin
|
|
Button := CreateButton(FToolItems.Items[i]);
|
|
if Assigned(Button) then
|
|
ButtonList.Insert(ButtonCount, Button);
|
|
end;
|
|
UpdateButtonsTags;
|
|
ResizeButtons;
|
|
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.Clear;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
BeginUpdate;
|
|
|
|
for I := 0 to ButtonList.Count - 1 do
|
|
TKASToolButton(ButtonList.Items[I]).Free;
|
|
ButtonList.Clear;
|
|
if Assigned(FToolItems) then
|
|
FToolItems.Clear;
|
|
|
|
EndUpdate;
|
|
end;
|
|
|
|
procedure TKASToolBar.ClearExecutors;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to FToolItemExecutors.Count - 1 do
|
|
Dispose(PToolItemExecutor(FToolItemExecutors[I]));
|
|
FToolItemExecutors.Clear;
|
|
end;
|
|
|
|
procedure TKASToolBar.ClickItem(ToolItemID: String);
|
|
var
|
|
I: Integer;
|
|
Button: TKASToolButton;
|
|
NormalItem: TKASNormalItem;
|
|
begin
|
|
for I := 0 to ButtonList.Count - 1 do
|
|
begin
|
|
Button := TKASToolButton(ButtonList.Items[I]);
|
|
if Button.ToolItem is TKASNormalItem then
|
|
begin
|
|
NormalItem := TKASNormalItem(Button.ToolItem);
|
|
if NormalItem.ID = ToolItemID then
|
|
begin
|
|
Button.Click;
|
|
Break;
|
|
end;
|
|
|
|
if Button.ToolItem.CheckExecute(ToolItemID) then
|
|
Break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.SetButtonHeight(const AValue: Integer);
|
|
begin
|
|
SetButtonSize(ButtonWidth, AValue);
|
|
end;
|
|
|
|
procedure TKASToolBar.SetButtonWidth(const AValue: Integer);
|
|
begin
|
|
SetButtonSize(AValue, ButtonHeight);
|
|
end;
|
|
|
|
constructor TKASToolBar.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
FGlyphSize:= 16; // by default
|
|
FUpdateCount:= 0;
|
|
FButtonWidth := 23;
|
|
FButtonHeight := 22;
|
|
FKASToolBarFlags := [];
|
|
FToolItemExecutors := TFPList.Create;
|
|
FToolItems := TKASToolBarItems.Create;
|
|
FOwnsToolItems := True;
|
|
end;
|
|
|
|
function TKASToolBar.CreateButton(Item: TKASToolItem): TKASToolButton;
|
|
begin
|
|
if Assigned(Item) then
|
|
begin
|
|
if FOwnsToolItems then
|
|
Item.SetToolOwner(Self);
|
|
|
|
if Item is TKASSeparatorItem then
|
|
begin
|
|
Result := TKASToolDivider.Create(Self, Item);
|
|
end
|
|
else
|
|
begin
|
|
Result := TKASToolButton.Create(Self, Item);
|
|
Result.ShowHint := True;
|
|
Result.Caption := Item.GetEffectiveText;
|
|
Result.Hint := Item.GetEffectiveHint;
|
|
end;
|
|
|
|
Result.Flat := FFlat;
|
|
if FRadioToolBar then
|
|
begin
|
|
Result.GroupIndex := 1;
|
|
Result.AllowAllUp := True;
|
|
end;
|
|
|
|
Result.ShowCaption := ShowCaptions;
|
|
UpdateIcon(Result);
|
|
AssignToolButtonProperties(Result);
|
|
|
|
Result.Parent := Self;
|
|
end
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
destructor TKASToolBar.Destroy;
|
|
begin
|
|
if not FOwnsToolItems then
|
|
FToolItems := nil; // Unassign before Clear so that items are not cleared.
|
|
Clear;
|
|
inherited Destroy;
|
|
ClearExecutors;
|
|
FToolItemExecutors.Free;
|
|
if FOwnsToolItems then
|
|
FToolItems.Free;
|
|
end;
|
|
|
|
function TKASToolBar.ExecuteToolItem(Item: TKASToolItem): Boolean;
|
|
var
|
|
I: Integer;
|
|
Executor: PToolItemExecutor;
|
|
BestMatch: PToolItemExecutor = nil;
|
|
begin
|
|
for I := 0 to FToolItemExecutors.Count - 1 do
|
|
begin
|
|
Executor := PToolItemExecutor(FToolItemExecutors[I]);
|
|
if Assigned(Executor^.ToolItemExecute) and
|
|
Item.InheritsFrom(Executor^.ToolItemClass) and
|
|
(not Assigned(BestMatch) or
|
|
(Executor^.ToolItemClass.InheritsFrom(BestMatch^.ToolItemClass))) then
|
|
begin
|
|
BestMatch := Executor;
|
|
end;
|
|
end;
|
|
Result := Assigned(BestMatch);
|
|
if Result then
|
|
BestMatch^.ToolItemExecute(Item);
|
|
end;
|
|
|
|
{ TKASToolBar.PublicExecuteToolItem }
|
|
function TKASToolBar.PublicExecuteToolItem(Item: TKASToolItem): Boolean;
|
|
begin
|
|
result:=ExecuteToolItem(Item);
|
|
end;
|
|
|
|
procedure TKASToolBar.BeginUpdate;
|
|
begin
|
|
{$if lcl_fullversion < 1010000}
|
|
Inc(FUpdateCount);
|
|
{$endif}
|
|
inherited BeginUpdate;
|
|
DisableAutoSizing;
|
|
end;
|
|
|
|
procedure TKASToolBar.EndUpdate;
|
|
begin
|
|
EnableAutoSizing;
|
|
inherited EndUpdate;
|
|
{$if lcl_fullversion < 1010000}
|
|
Dec(FUpdateCount);
|
|
{$endif}
|
|
if (FUpdateCount = 0) and FResizeButtonsNeeded then
|
|
ResizeButtons;
|
|
end;
|
|
|
|
function TKASToolBar.FindButton(Button: TKASToolButton): Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to ButtonList.Count - 1 do
|
|
if TKASToolButton(ButtonList[I]) = Button then
|
|
Exit(I);
|
|
Result := -1;
|
|
end;
|
|
|
|
procedure TKASToolBar.SetButtonSize(NewButtonWidth, NewButtonHeight: Integer);
|
|
begin
|
|
FButtonWidth := NewButtonWidth;
|
|
FButtonHeight := NewButtonHeight;
|
|
ResizeButtons;
|
|
end;
|
|
|
|
function TKASToolBar.AddButton(Item: TKASToolItem): TKASToolButton;
|
|
begin
|
|
Result := InsertButton(ButtonCount, Item);
|
|
end;
|
|
|
|
procedure TKASToolBar.AddToolItemExecutor(ToolItemClass: TKASToolItemClass; ExecuteFunction: TOnToolItemExecute);
|
|
var
|
|
Executor: PToolItemExecutor;
|
|
begin
|
|
New(Executor);
|
|
FToolItemExecutors.Add(Executor);
|
|
Executor^.ToolItemClass := ToolItemClass;
|
|
Executor^.ToolItemExecute := ExecuteFunction;
|
|
end;
|
|
|
|
function TKASToolBar.InsertButton(InsertAt: Integer; Item: TKASToolItem): TKASToolButton;
|
|
begin
|
|
Result := CreateButton(Item);
|
|
if Assigned(Result) then
|
|
InsertButton(InsertAt, Result);
|
|
end;
|
|
|
|
procedure TKASToolBar.RemoveButton(Index: Integer);
|
|
var
|
|
Button: TKASToolButton;
|
|
begin
|
|
Button := TKASToolButton(ButtonList.Items[Index]);
|
|
ButtonList.Delete(Index);
|
|
Button.Free;
|
|
FToolItems.Remove(Index);
|
|
UpdateButtonsTags;
|
|
Resize;
|
|
end;
|
|
|
|
procedure TKASToolBar.RemoveButton(Button: TKASToolButton);
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Index := FindButton(Button);
|
|
if Index <> -1 then
|
|
RemoveButton(Index);
|
|
end;
|
|
|
|
procedure TKASToolBar.RemoveToolItemExecutor(ExecuteFunction: TOnToolItemExecute);
|
|
var
|
|
Executor: PToolItemExecutor;
|
|
I: Integer;
|
|
begin
|
|
for I := FToolItemExecutors.Count - 1 downto 0 do
|
|
begin
|
|
Executor := PToolItemExecutor(FToolItemExecutors[I]);
|
|
if (TMethod(Executor^.ToolItemExecute).Code = TMethod(ExecuteFunction).Code) and
|
|
(TMethod(Executor^.ToolItemExecute).Data = TMethod(ExecuteFunction).Data) then
|
|
begin
|
|
Dispose(Executor);
|
|
FToolItemExecutors.Delete(I);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TKASToolBar.UncheckAllButtons;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I:= 0 to ButtonCount - 1 do
|
|
Buttons[I].Down:= False;
|
|
end;
|
|
|
|
{ TKASToolButton }
|
|
|
|
procedure TKASToolButton.CalculatePreferredSize(var PreferredWidth,
|
|
PreferredHeight: integer; WithThemeSpace: Boolean);
|
|
var
|
|
TextSize: TSize;
|
|
begin
|
|
if Assigned(Parent) then
|
|
begin
|
|
if ShowCaption and (Caption <> EmptyStr) then
|
|
begin
|
|
// Size to extent of the icon + caption.
|
|
// Minimum size is the ButtonWidth x RowHeight of the toolbar.
|
|
TextSize := Canvas.TextExtent(Caption);
|
|
PreferredWidth := Max(TextSize.cx + Glyph.Width + 16, ToolBar.ButtonWidth);
|
|
PreferredHeight := Max(TextSize.cy + 4, ToolBar.RowHeight);
|
|
end
|
|
else
|
|
begin
|
|
PreferredWidth := ToolBar.ButtonWidth;
|
|
PreferredHeight := ToolBar.RowHeight;
|
|
end;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
constructor TKASToolButton.Create(AOwner: TComponent; Item: TKASToolItem);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FToolItem := Item;
|
|
end;
|
|
|
|
function TKASToolButton.GetToolBar: TKASToolBar;
|
|
begin
|
|
Result := Parent as TKASToolBar;
|
|
end;
|
|
|
|
{ TKASToolDivider }
|
|
|
|
procedure TKASToolDivider.CalculatePreferredSize(var PreferredWidth,
|
|
PreferredHeight: integer; WithThemeSpace: Boolean);
|
|
begin
|
|
if Assigned(Parent) and (Parent is TKASToolBar) and
|
|
not TKASToolBar(Parent).FShowDividerAsButton then
|
|
begin
|
|
PreferredWidth := 5;
|
|
PreferredHeight := TKASToolBar(Parent).RowHeight;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TKASToolDivider.Paint;
|
|
var
|
|
DividerRect: TRect;
|
|
Details: TThemedElementDetails;
|
|
begin
|
|
if Assigned(Parent) and (Parent is TKASToolBar) and
|
|
not TKASToolBar(Parent).FShowDividerAsButton then
|
|
begin
|
|
DividerRect:= ClientRect;
|
|
Details:= ThemeServices.GetElementDetails(ttbSeparatorNormal);
|
|
// Theme services have no strict rule to draw divider in the center,
|
|
// so we should calculate rectangle here
|
|
// on windows 7 divider can't be less than 4 pixels
|
|
if (DividerRect.Right - DividerRect.Left) > 5 then
|
|
begin
|
|
DividerRect.Left := (DividerRect.Left + DividerRect.Right) div 2 - 3;
|
|
DividerRect.Right := DividerRect.Left + 5;
|
|
end;
|
|
ThemeServices.DrawElement(Canvas.GetUpdatedHandle([csBrushValid, csPenValid]), Details, DividerRect);
|
|
end
|
|
else
|
|
inherited Paint;
|
|
end;
|
|
|
|
end.
|
|
|