unit Vis2D_ObjMgr;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, TextEditor, Vcl.StdCtrls, VisCtl2D,
  UxPanel, Vcl.ExtCtrls, Vcl.ComCtrls, ListViewEx, System.Actions, Vcl.ActnList,
  Vcl.Menus;

type
  TVis2D_ObjMgrFrm = class(TDrawableOptionsFrm)
    ListView: TListViewEx;
    ActionList: TActionList;
    aShow: TAction;
    aHide: TAction;
    PopupMenu: TPopupMenu;
    Show1: TMenuItem;
    Hide1: TMenuItem;
    N1: TMenuItem;
    aDelete: TAction;
    Delete1: TMenuItem;
    aMeta: TAction;
    N2: TMenuItem;
    Setmetadata1: TMenuItem;
    aMoveUp: TAction;
    aMoveDown: TAction;
    N3: TMenuItem;
    Moveup1: TMenuItem;
    Movedown1: TMenuItem;
    procedure ListViewItemChecked(Sender: TObject; Item: TListItem);
    procedure aShowUpdate(Sender: TObject);
    procedure aShowExecute(Sender: TObject);
    procedure aHideExecute(Sender: TObject);
    procedure aHideUpdate(Sender: TObject);
    procedure aDeleteExecute(Sender: TObject);
    procedure aDeleteUpdate(Sender: TObject);
    procedure ListViewKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ListViewKeyPress(Sender: TObject; var Key: Char);
    procedure aMetaUpdate(Sender: TObject);
    procedure aMetaExecute(Sender: TObject);
    procedure ListViewDblClick(Sender: TObject);
    procedure aMoveUpUpdate(Sender: TObject);
    procedure aMoveDownUpdate(Sender: TObject);
    procedure aMoveUpExecute(Sender: TObject);
    procedure aMoveDownExecute(Sender: TObject);
  strict protected
    procedure Initialize; override;
  public
  end;

implementation

{$R *.dfm}

uses ObjectMetadataForm;

procedure TVis2D_ObjMgrFrm.aDeleteExecute(Sender: TObject);
begin
  for var i := 0 to ListView.Items.Count - 1 do
    if ListView.Items[i].Selected then
      (FDrawable as TDrawableList).List.Remove(TObject(ListView.Items[i].Data) as TDrawable);
  ListView.DeleteSelected;
end;

procedure TVis2D_ObjMgrFrm.aDeleteUpdate(Sender: TObject);
begin
  aDelete.Enabled := ListView.SelCount > 0;
end;

procedure TVis2D_ObjMgrFrm.aHideExecute(Sender: TObject);
begin
  for var i := 0 to ListView.Items.Count - 1 do
    if ListView.Items[i].Selected then
      ListView.Items[i].Checked := False;
end;

procedure TVis2D_ObjMgrFrm.aHideUpdate(Sender: TObject);
begin
  aHide.Enabled := ListView.SelCount > 0;
end;

procedure TVis2D_ObjMgrFrm.aMetaExecute(Sender: TObject);
begin
  if (ListView.SelCount = 1) and Assigned(ListView.Selected) then
    if SetMetadata(Self, TObject(ListView.Selected.Data) as TDrawable) then
      Initialize;
end;

procedure TVis2D_ObjMgrFrm.aMetaUpdate(Sender: TObject);
begin
  aMeta.Enabled := (ListView.SelCount = 1) and Assigned(ListView.Selected);
end;

procedure TVis2D_ObjMgrFrm.aMoveDownExecute(Sender: TObject);
begin
  if (ListView.SelCount = 1) and Assigned(ListView.Selected) and (ListView.ItemIndex < ListView.Items.Count - 1) then
  begin
    (FDrawable as TDrawableList).MoveDown(TObject(ListView.Selected.Data) as TDrawable);
    Initialize;
  end;
end;

procedure TVis2D_ObjMgrFrm.aMoveDownUpdate(Sender: TObject);
begin
  aMoveDown.Enabled := (ListView.SelCount = 1) and (ListView.ItemIndex < ListView.Items.Count - 1);
end;

procedure TVis2D_ObjMgrFrm.aMoveUpExecute(Sender: TObject);
begin
  if (ListView.SelCount = 1) and Assigned(ListView.Selected) and (ListView.ItemIndex > 0) then
  begin
    (FDrawable as TDrawableList).MoveUp(TObject(ListView.Selected.Data) as TDrawable);
    Initialize;
  end;
end;

procedure TVis2D_ObjMgrFrm.aMoveUpUpdate(Sender: TObject);
begin
  aMoveUp.Enabled := (ListView.SelCount = 1) and (ListView.ItemIndex > 0);
end;

procedure TVis2D_ObjMgrFrm.aShowExecute(Sender: TObject);
begin
  for var i := 0 to ListView.Items.Count - 1 do
    if ListView.Items[i].Selected then
      ListView.Items[i].Checked := True;
end;

procedure TVis2D_ObjMgrFrm.aShowUpdate(Sender: TObject);
begin
  aShow.Enabled := ListView.SelCount > 0;
end;

procedure TVis2D_ObjMgrFrm.Initialize;
var
  List: TDrawableList;
  PrevSel: TDrawable;
begin
  inherited;
  if (ListView.SelCount = 1) and Assigned(ListView.Selected) then
    PrevSel := TObject(ListView.Selected.Data) as TDrawable
  else
    PrevSel := nil;
  List := FDrawable as TDrawableList;
  ListView.Items.BeginUpdate;
  try
    ListView.Clear;
    for var obj in List.List do
      with ListView.Items.Add do
      begin
        Caption := obj.Name;
        SubItems.Add(obj.Title);
        SubItems.Add(obj.Description);
        Checked := obj.Visible;
        Data := obj;
      end;
  finally
    ListView.Items.EndUpdate;
  end;
  if Assigned(PrevSel) then
    for var i := 0 to ListView.Items.Count - 1 do
      if ListView.Items[i].Data = Pointer(PrevSel) then
      begin
        ListView.ItemIndex := i;
        Break;
      end;
end;

procedure TVis2D_ObjMgrFrm.ListViewDblClick(Sender: TObject);
begin
  if ListView.SelCount = 1 then
    aMeta.Execute;
end;

procedure TVis2D_ObjMgrFrm.ListViewItemChecked(Sender: TObject;
  Item: TListItem);
begin
  if Assigned(Item) and (TObject(Item.Data) is TDrawable) then
    TDrawable(Item.Data).Visible := Item.Checked;
end;

procedure TVis2D_ObjMgrFrm.ListViewKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
    VK_RETURN:
      if ListView.SelCount = 1 then
        aMeta.Execute;
    VK_DELETE:
      aDelete.Execute;
  end;
  if ssCtrl in Shift then
    case Key of
      VK_UP:
        begin
          aMoveUp.Execute;
          Key := 0;
        end;
      VK_DOWN:
        begin
          aMoveDown.Execute;
          Key := 0;
        end;
    end;
end;

procedure TVis2D_ObjMgrFrm.ListViewKeyPress(Sender: TObject; var Key: Char);
begin
  case Key of
    ^S:
      aShow.Execute;
    ^H:
      aHide.Execute;
  end;
end;

end.
