Jump to content
Sign in to follow this  
Stano

Dynamic creation of TActionManager with Actions

Recommended Posts

Hi,

I want to create a component based on TActionToolBar. I want to dynamically create a TActionManager in it. TActionManager to populate TAction.
I have this code

procedure TjstVstDBNavigator.NewActions;
var
  ItemIndex: Cardinal;
  ActionBarItem: TActionBarItem;
  ActionClientItem: TActionClientItem;
begin
  // My code
  if Assigned(FAcnMan) then
    FreeAndNil(FAcnMan);

  FAcnMan := TAcTionManager.Create(Self);
  FAcnMan.SetSubComponent(True);
  Self.ActionManager := FAcnMan;
  FActions.Clear;

// Copied code
  ActionBarItem := FAcnMan.ActionBars.Add;

  for var IdxActn in FRequiredIdxActn do
  begin
    ItemIndex := Ord(TIndexAction(IdxActn));

    // Create new action for a menu/ActionToolBar item
    FActions.Add(TAction.Create(Self));
    FActions.Last.Category := 'PopupMenuItems';
    ....
     // Add this action to the Action Manager
    FActions.Last.ActionList := FAcnMan;

    // Also add this action to the Action Bar ???
    actionClientItem := ActionBarItem.Items.Add;
    actionClientItem.Action := FActions.Last;
  end;

  // My code
  Self.ActionClient := FAcnMan.ActionBars[0];
end;

The buttons are displayed. But only Caption.
I want to set the TAction properties as follows (copied from Embt):

procedure TjstVstDBNavigator.ApplyShowOnAction;
const
  NoActionToolBar = -1;
var
  Action: TAction;
  BarItem: TActionBarItem;
  Client: TActionClientItem;
  K: Integer;
begin
  for var J := 0 to FAcnMan.ActionBars.Count -1 do  // OK
  begin
    BarItem := FAcnMan.ActionBars.ActionBars[J];  // I'm done here

    if BarItem.ActionBar <> nil then
    begin
      for K := 0 to BarItem.Items.Count -1 do
      begin
        Client := BarItem.Items[K];

        if Client.Action <> nil then
        begin
          Action := (Client.Action as TAction);

          if Action <> nil then
          begin
            Client.ShowShortCut ...;
...
end;

I don't have the whole structure in ActionManager.  
The figure shows the structure created by the ActionManager. I need that.
I have no idea how to do it.

ActionManager Structure.png

Share this post


Link to post

If I throw this condition

if BarItem.ActionBar <> nil then

then I'll get it right

Edited by Stano

Share this post


Link to post

I just pushed the problem. I'll open a test project. I'll run it. I will close the app and the appropriate pas unit. I open the pas unit. I'm getting an error while loading. The reason is that I miss the part in the frame. See picture. I can't do it.
Can anyone help me?

  acttb1.ActionManager := actmgr1;
  ActionBarItem := actmgr1.ActionBars.Add;

  for var ItemIndex := 0 to 4 do
  begin
    // Create new action for a ActionToolBar item
    Action := TAction.Create(Self);
    Action.Category := 'Database';
    // Add this action to the Action Manager
    Action.ActionList := actmgr1;
    // Also add this action to the ActionBar
    actionClientItem := ActionBarItem.Items.Add;
    actionClientItem.Action := Action;
  end;

  acttb1.ActionClient := ActionBarItem;
  acttb1.ActionManager := actmgr1

 

ActionManager + ActionToolBar + Action v ATB.png

Share this post


Link to post

Use ActionManager as in design window and its property editors and sub editors adding stubs to be used like this to connect the events at runtime. 

 

procedure TForm1.Button2Click(Sender: TObject);
const
  popupmenuitemCaptions: array[0..1] of String=('Action4','frameAction1');
var
  popupFrameCaption: string;
  I: Integer;
  A: TContainedAction;
begin
  for popupFrameCaption in popupmenuitemCaptions do

    for I := 0 to ActionManager1.ActionCount - 1 do
    begin
      A := ActionManager1.Actions[I];
      if A.caption = popupFrameCaption then
      begin
        A.OnExecute := Frame11.PopupActionBar1.Items[0].OnClick;
        A.Execute;
        Break;
      end;
    end;

end;
object ActionManager1: TActionManager
  ActionBars = <
    item
      Items.CaptionOptions = coAll
      Items = <>
      ActionBar = ActionToolBar3
    end>
  LinkedActionLists = <
    item
      Caption = '(No Name)'
    end>
  Images = ImageList1 
  Left = 722
  Top = 172
  StyleName = 'Platform Default'
  object Action4: TAction
    Category = 'Frame'
    Caption = 'Action4'
    ImageIndex = 1
    OnExecute = Action4Execute
  end
  object DatasetFirst1: TDataSetFirst
    Category = 'Dataset'
    Caption = '&First'
    Hint = 'First'
    ImageIndex = 0
  end
end

Inspecting the object in design by copying it to notepad shows Images property to possibly set at runtime.  

 

Share this post


Link to post

The problem is gone. Don't know why / how yet. Keep the topic closed.

Share this post


Link to post

The solution, as always, is simple:

    FAcnMan.ActionBars[0].ActionBar := Self;  /// - TActionToolBar

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×