Skip to content

Commit

Permalink
Some further improvements related to Virtual TreeView issue #740:
Browse files Browse the repository at this point in the history
* TVTMenuItem now has an overloaded constructor that takes the most important values
* poResizeToFitItem is now set by default in TVTHeaderPopupMenu.Options
* Separator menu items created by TVTHeaderPopupMenu are now properly deleted too when re-filling the menu
* TVTHeaderPopupMenu.PopupComponent is now set properly
* Added own event handler for the "Resize all Columns to fit" menu item
  • Loading branch information
Joachim Marder committed Nov 21, 2017
1 parent 1b5ca56 commit 8727f2a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 30 deletions.
2 changes: 2 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ V7.0: (Under development)
- We do no longer test on Windows XP/2003
- We may accept pull request for XP support if the code quality is sufficient.
- We recommend to use the V6 branch on Windows XP
* Fixed issue #740: TVTHeaderPopupMenu should not delete menu items added at designtime
* Fixed issue #739: TVTHeader should use a popup menu if assigned
* Enhancement #735: Add event that is fired when a check state is needed
* Fixed issue #738: Deadlock on application close in ReleaseThreadReference
Expand All @@ -18,6 +19,7 @@ V7.0: (Under development)
* Fixed issue #467: Multi level checkboxes and BeginUpdate/EndUpdate issue
* Fixed issue #391: Change property HotNode: Add a setter
* Removed flag toDisableAutoscrollOnFocus from default configuration of a new Virtual TreeView to achieve a more common behavior with default properties.
* poResizeToFitItem is now set by default in TVTHeaderPopupMenu.Options

V6.7: (29 May 2017)
* Fixed issue #714: Integer overflow in TBaseVirtualTree's InternalAddFromStream
Expand Down
82 changes: 52 additions & 30 deletions Source/VTHeaderPopup.pas
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@
interface

uses
Vcl.Menus, VirtualTrees;
System.Classes,
Vcl.Menus,
VirtualTrees;

type
TVTHeaderPopupOption = (
Expand All @@ -86,22 +88,22 @@ interface
var Cmd: TAddPopupItemType) of object;
TColumnChangeEvent = procedure(const Sender: TBaseVirtualTree; const Column: TColumnIndex; Visible: Boolean) of object;

TVTMenuItem = TMenuItem;

TVTHeaderPopupMenu = class(TPopupMenu)
strict private
FOptions: TVTHeaderPopupOptions;

FOnAddHeaderPopupItem: TAddHeaderPopupItemEvent;
FOnColumnChange: TColumnChangeEvent;
procedure ResizeToFit(Sender: TObject);
strict protected
procedure DoAddHeaderPopupItem(const Column: TColumnIndex; out Cmd: TAddPopupItemType); virtual;
procedure DoColumnChange(Column: TColumnIndex; Visible: Boolean); virtual;
procedure OnMenuItemClick(Sender: TObject);
public
constructor Create(AOwner: TComponent); override;
procedure Popup(x, y: Integer); override;
published
property Options: TVTHeaderPopupOptions read FOptions write FOptions default [];
property Options: TVTHeaderPopupOptions read FOptions write FOptions default [poResizeToFitItem];

property OnAddHeaderPopupItem: TAddHeaderPopupItemEvent read FOnAddHeaderPopupItem write FOnAddHeaderPopupItem;
property OnColumnChange: TColumnChangeEvent read FOnColumnChange write FOnColumnChange;
Expand All @@ -112,13 +114,25 @@ TVTHeaderPopupMenu = class(TPopupMenu)
implementation

uses
Winapi.Windows, System.Classes;
Winapi.Windows;

resourcestring
sResizeToFit = '&Resize All Columns To Fit';

const
cResizeToFitMenuItemName = 'VT_ResizeToFitMenuItem';
type
TVTMenuItem = class(TMenuItem)
public
constructor Create(AOwner: TComponent; const ACaption: string; AClickHandler: TNotifyEvent = nil); reintroduce;
end;

//----------------- TVTHeaderPopupMenu ---------------------------------------------------------------------------------

constructor TVTHeaderPopupMenu.Create(AOwner: TComponent);
begin
inherited;
FOptions := [poResizeToFitItem];
end;

procedure TVTHeaderPopupMenu.DoAddHeaderPopupItem(const Column: TColumnIndex; out Cmd: TAddPopupItemType);

begin
Expand All @@ -142,29 +156,21 @@ procedure TVTHeaderPopupMenu.OnMenuItemClick(Sender: TObject);

begin
if Assigned(PopupComponent) and (PopupComponent is TBaseVirtualTree) then begin
if TVTMenuItem(Sender).Name = cResizeToFitMenuItemName then begin
TBaseVirtualTree(PopupComponent).Header.AutoFitColumns();
end
else begin
with TVTMenuItem(Sender),
TBaseVirtualTree(PopupComponent).Header.Columns.Items[Tag] do
begin
if Checked then
Options := Options - [coVisible]
else
Options := Options + [coVisible];
with TBaseVirtualTree(PopupComponent).Header.Columns.Items[Tag] do
begin
if TVTMenuItem(Sender).Checked then
Options := Options - [coVisible]
else
Options := Options + [coVisible];

DoColumnChange(TVTMenuItem(Sender).Tag, not Checked);
end;
end;//else
DoColumnChange(TVTMenuItem(Sender).Tag, not TVTMenuItem(Sender).Checked);
end;
end;
end;

//----------------------------------------------------------------------------------------------------------------------

procedure TVTHeaderPopupMenu.Popup(x, y: Integer);
resourcestring
sResizeToFit = '&Resize All Columns To Fit';
var
ColPos: TColumnPosition;
ColIdx: TColumnIndex;
Expand All @@ -175,17 +181,20 @@ procedure TVTHeaderPopupMenu.Popup(x, y: Integer);
VisibleCounter: Cardinal;
VisibleItem: TVTMenuItem;

i: Integer;

begin
if Assigned(PopupComponent) and (PopupComponent is TBaseVirtualTree) then
begin
// Delete existing menu items.
while Items.Count > 0 do
Items[0].Free;
for i := Items.Count -1 downto 0 do begin
if Items[i] is TVTMenuItem then
Items[i].Free;
end;//for i

if poResizeToFitItem in Self.Options then begin
NewMenuItem := NewItem(sResizeToFit, 0, False, True, OnMenuItemClick, 0, cResizeToFitMenuItemName);
Items.Add(NewMenuItem);
Items.Add(NewLine());
Items.Add(TVTMenuItem.Create(Self, sResizeToFit, ResizeToFit));
Items.Add(TVTMenuItem.Create(Self, cLineCaption));
end;//poResizeToFitItem

// Add column menu items.
Expand All @@ -212,13 +221,12 @@ procedure TVTHeaderPopupMenu.Popup(x, y: Integer);
DoAddHeaderPopupItem(ColIdx, Cmd);
if Cmd <> apHidden then
begin
NewMenuItem := TVTMenuItem.Create(Self);
NewMenuItem := TVTMenuItem.Create(Self, Text, OnMenuItemClick);
NewMenuItem.Tag := ColIdx;
NewMenuItem.Caption := Text;
NewMenuItem.Hint := Hint;
NewMenuItem.ImageIndex := ImageIndex;
NewMenuItem.Checked := coVisible in Options;
NewMenuItem.OnClick := OnMenuItemClick;
if Cmd = apDisabled then
NewMenuItem.Enabled := False
else
Expand All @@ -238,7 +246,21 @@ procedure TVTHeaderPopupMenu.Popup(x, y: Integer);
inherited;
end;

procedure TVTHeaderPopupMenu.ResizeToFit(Sender: TObject);
begin
TBaseVirtualTree(PopupComponent).Header.AutoFitColumns();
end;

//----------------------------------------------------------------------------------------------------------------------

{ TVTMenuItem }

constructor TVTMenuItem.Create(AOwner: TComponent; const ACaption: string; AClickHandler: TNotifyEvent);
begin
Inherited Create(AOwner);
Caption := ACaption;
OnClick := AClickHandler;
end;

end.

1 change: 1 addition & 0 deletions Source/VirtualTrees.pas
Original file line number Diff line number Diff line change
Expand Up @@ -8345,6 +8345,7 @@ procedure TVirtualTreeColumns.HandleClick(P: TPoint; Button: TMouseButton; Force
FreeAndNil(fColumnPopupMenu);// Attention: Do not free the TVTHeaderPopupMenu at the end of this method, otherwise the clikc events of the menu item will not be fired.
if Assigned(Header.PopupMenu) then
begin
Header.PopupMenu.PopupComponent := Header.Treeview;
With Header.Treeview.ClientToScreen(P) do
Header.PopupMenu.Popup(X, Y);
end // if hoAutoColumnPopupMenu
Expand Down

0 comments on commit 8727f2a

Please sign in to comment.