ok, thanks sorry for no
Thanks for the comment, I forgot to post the solution in case anyone decides to use it. I'm still working on improving the implementation
of the buttons, icons, and actions. Here's the code of dynamic menu from DB:
procedure TfrmPrincipal.Button2Click(Sender: TObject);
var
TabItem: TRibbonTabItem;
Group: TRibbonGroup; // This will act as our TCustomActionBar
BarAction: TActionClientItem;
PadreIDTab: Integer;
PadreIDGrupo: Integer;
Action: TAction;
i: Integer;
GroupCaption: string;
CurrentActionBarItem: TActionBarItem;
Bg: TRibbonLargeButtonControl;
Bs: TRibbonSmallButtonControl;
begin
ribMenu.Tabs.Clear;
QryMenu.Close;
QryMenu.SQL.Clear;
QryMenu.SQL.Add('SELECT * ');
QryMenu.SQL.Add('FROM Menu ');
QryMenu.SQL.Add('WHERE (padre_id IS NULL OR padre_id = 0) AND activo = 1 ');
QryMenu.SQL.Add('ORDER BY orden ASC');
QryMenu.Open;
QryMenu.First;
// Limpiar las actionbars antes de empezar el proceso
amMenu.ActionBars.Clear; // Importante: limpiar las action bars existentes
while not QryMenu.Eof do // Crear las pestañas principales
begin
TabItem := ribMenu.Tabs.Add;
TabItem.Caption := Trim(QryMenu.FieldByName('titulo').Value);
PadreIDTab := QryMenu.FieldByName('menu_item_id').Value;
QrySubMenu.Close;
QrySubMenu.SQL.Clear;
QrySubMenu.SQL.Add('SELECT * ');
QrySubMenu.SQL.Add('FROM Menu ');
QrySubMenu.SQL.Add('WHERE padre_id = :PadreIDTab AND activo = 1 '); // Obtener los grupos de la pestaña
QrySubMenu.SQL.Add('ORDER BY orden ASC');
QrySubMenu.Parameters.ParamByName('PadreIDTab').Value := PadreIDTab;
QrySubMenu.Open;
QrySubMenu.First;
while not QrySubMenu.Eof do // Crear los grupos dentro de la pestaña
begin
if UpperCase(QrySubMenu.FieldByName('tipo').Value) = 'GRUPO' then
begin
GroupCaption := Trim(QrySubMenu.FieldByName('titulo').AsString);
Group := nil; // Inicializamos Group a nil
// Buscar si ya existe un grupo con este Caption en la pestaña actual
for i := 0 to TabItem.Page.ControlCount - 1 do
begin
if (TabItem.Page.Controls[i] is TRibbonGroup) and (TRibbonGroup(TabItem.Page.Controls[i]).Caption = GroupCaption) then
begin
Group := TRibbonGroup(TabItem.Page.Controls[i]);
Break; // Se encontró el grupo existente, salir del bucle
end;
end;
// Si no se encontró el grupo, crear uno nuevo
if not Assigned(Group) then
begin
Group := TRibbonGroup.Create(ribMenu);
Group.Parent := TabItem.Page;
Group.Caption := GroupCaption;
end;
PadreIDGrupo := QrySubMenu.FieldByName('menu_item_id').Value; // Capturar el ID del grupo
// Find or create the TActionBarItem associated with this TRibbonGroup
CurrentActionBarItem := nil;
for i := 0 to amMenu.ActionBars.Count - 1 do
begin
// A TRibbonGroup can be assigned to an ActionManager through an ActionBarItem
// We can use the Group itself as the identifier, or set the ActionBarItem.Tag
if amMenu.ActionBars[i].ActionBar = Group then
begin
CurrentActionBarItem := amMenu.ActionBars[i];
Break;
end;
// Alternatively, if you prefer to use Tag (and ensure Tag is set for the ActionBarItem)
// if (amMenu.ActionBars[i].Tag = PadreIDGrupo) then
// begin
// CurrentActionBarItem := amMenu.ActionBars[i];
// Break;
// end;
end;
if not Assigned(CurrentActionBarItem) then // If ActionBarItem for this group doesn't exist, create it
begin
CurrentActionBarItem := amMenu.ActionBars.Add; // Add creates a new TActionBarItem
CurrentActionBarItem.ActionBar := Group; // Assign the TRibbonGroup to the ActionBarItem
CurrentActionBarItem.Tag := PadreIDGrupo; // Store the group's ID in the ActionBarItem's Tag for lookup
end;
QryItems.Close;
QryItems.SQL.Clear;
QryItems.SQL.Add('SELECT * ');
QryItems.SQL.Add('FROM Menu ');
QryItems.SQL.Add('WHERE padre_id = :PadreIDGrupo AND activo = 1 '); // Obtener los ítems del grupo
QryItems.SQL.Add('ORDER BY orden');
QryItems.Parameters.ParamByName('PadreIDGrupo').Value := PadreIDGrupo;
QryItems.Open;
QryItems.First;
while not QryItems.Eof do // Crear los ítems dentro del grupo
begin
if UpperCase(QryItems.FieldByName('tipo').Value) = 'ITEM' then
begin
OutputDebugString(PWideChar('Creando ítem: "' + Trim(QryItems.FieldByName('titulo').Value) + '" para el grupo "' + Group.Caption + '"'));
Action := TAction.Create(Self); // Action owner is the form
Action.Caption := Trim(QryItems.FieldByName('titulo').Value);
Action.OnExecute := ItemClick;
Action.Tag := QryItems.FieldByName('menu_item_id').AsInteger;
BarAction := CurrentActionBarItem.Items.Add as TActionClientItem;
BarAction.Action := Action;
BarAction.Caption := Trim(QryItems.FieldByName('titulo').Value);
// Add the correct control to the group, linked to the ActionClientItem
if QryItems.FieldByName('tipo_control').AsString = 'LARGEBUTTON' then
begin
Bg := TRibbonLargeButtonControl.Create(Group); // Group as owner
Bg.ActionClient := BarAction;
end
else if QryItems.FieldByName('tipo_control').AsString = 'SMALLBUTTON' then
begin
Bs := TRibbonSmallButtonControl.Create(Group); // Group as owner
Bs.ActionClient := BarAction;
end;
end;
QryItems.Next;
end;
QryItems.Close; // Close the query for items
end; // End of if tipo = 'GRUPO'
QrySubMenu.Next;
end;
QrySubMenu.Close; // Cerrar la consulta de grupos
QryMenu.Next;
end;
if ribMenu.Tabs.Count >= 2 then
begin
// Simular click en la segunda pestaña (índice 1)
ribMenu.TabIndex := 1;
ribMenu.TabIndex := 0;
end;
ribMenu.Refresh;
QryMenu.Close; // Cerrar la consulta de pestañas
end;