Конструктор меню из кнопок

Готовые скрипты, модули расширений, динамические библиотеки и вспомогательные утилиты.
Аватара пользователя
Владимир
Администратор
Сообщения: 587
Зарегистрирован: 10 фев 2018, 18:27
Откуда: Белгород
Контактная информация:

Конструктор меню из кнопок

Сообщение Владимир » 08 авг 2019, 10:31

Действие формы: "Конструктор меню". Создает меню из кнопок расположенных в указанной "Группе".

Изображение Изображение

Настраиваемые опции:

[Кнопка вызова меню] (обязательная) - любая из кнопок формы, при нажатии на которую будет открываться создаваемое меню.
[Группа кнопок для создания пунктов меню]
(обязательная) - "Группа", внутри которой будут расположены кнопки (пункты меню). При открытии формы в рабочем режиме группа будет программно скрыта а из находящихся в ней кнопок будет создано меню, раскрывающееся по нажатию "Кнопки вызова меню".

В создаваемые пункты меню из кнопок "переезжают": заголовки, иконки, свойства "доступность" и "видимость", событие клика (действия/скрипты, завязанные на кнопки вызываются при нажатии на соответствующий пункт меню).

Для создания горизонтального разделителя меню достаточно добавить отдельную кнопку между пунктами и указать текст кнопки "-" (дефис).

Порядок пунктов меню определяет вертикальное расположение кнопок (в расчет берется верхний край кнопки - свойство "top"). Для изменения порядка достаточно в дизайнере передвинуть кнопки выше/ниже относительно друг друга и пункты меню будут выстроены соответственно.

Рецепт видимости/доступности пунктов меню по условию:
1). Скачиваем и устанавливаем расширение "Управление видимостью/доступностью компонентов" отсюда.
2). В него прописываем условие скрытия и ниже в таблице компонентов добавляем требуемые кнопки из группы, участвующие в построении меню. В настройках расширения "Управление видимостью/доступностью компонентов" можно указать любое свойство (Видимость, Доступность) - реакция меню будет соответсвующей.

Примечание:
На одной форме может быть неограниченное подключение действия (по одному на кнопку со связанной группой кнопок)
Вторичное меню (субменю) не поддерживается (и не планируется)

Код расширенияПоказать

Код: Выделить всё

{@module
author=Develop-Soft [ https://forum.develop-soft.ru ]
version=1.2
description=Меню
Действия:
1. Конструктор меню из кнопок

Изменения:
v 1 от 08.08.2019 - выход первой версии
v 1.1 от 08.08.2019 - добавлено скрытие/доступность пунктов меню
v 1.2 от 08.08.2019 - исправлено скрытие/доступность пунктов меню при
первом нажатии правой кнопкой мыши
...
@}

{@action
Id=7EB55F4C-C8E3-41CD-B744-A2CF2422A3CF
Target=form
OrigName=MenuFromGroupButtons
Name=Конструктор меню из кнопок
Group=Меню
UI=
<ui>
<component name="mbn" filter="TdxButton" caption="Кнопка вызова меню:" required=1/>
<component name="buttons_group" caption="Группа кнопок для создания пунктов меню:"
filter="TdxGroupBox" required=1/>
</ui>
Description=
<b>Действие формы: "Конструктор меню". Создает меню из кнопок
расположенных в указанной "Группе". </b><br><br>
<b>Настраиваемые опции:</b><br><br>
<b>[Кнопка вызова меню] <i>(обязательная)</i> </b> - любая из кнопок формы,
при нажатии на которую будет открываться создаваемое меню.<br><br>
<b>[Группа кнопок для создания пунктов меню] <i>(обязательная)</i></b> -
"Группа", внутри которой будут расположены кнопки (пункты меню).
При открытии формы в рабочем режиме группа будет программно скрыта а из
находящихся в ней кнопок будет создано меню, раскрывающееся по нажатию
<b>"Кнопки вызова меню"</b>.<br><br>
В создаваемые пункты меню из кнопок "переезжают": заголовки, иконки, событие
клика (действия/скрипты, завязанные на кнопки вызываются при нажатии на
соответствующий пункт меню).<br> Для создания горизонтального разделителя меню
достаточно добавить отдельную кнопку между пунктами и указать текст кнопки "-"
(дефис). <br> Порядок пунктов меню определяет вертикальное расположение кнопок
(в расчет берется верхний край кнопки - свойство "top"). Для изменения порядка
достаточно в дизайнере передвинуть кнопки выше/ниже относительно друг друга и
пункты меню будут выстроены соответственно.
<br><br>
<i><b>Примечание: </b><br><br>
На одной форме может быть неограниченное подключение действия (по одному на
кнопку со связанной группой кнопок)<br>Вторичное меню (субменю) не поддерживается
(и не планируется) </i>
@}

procedure OnClick(Sender:TObject);
var Fm:TdxForm;
    Mi:TMenuItem;
    Bn:TdxButton;
begin
  Mi := TMenuItem(Sender);
  Fm:=TdxForm(TComponent(Sender).Owner.Owner);
  Bn:=TdxButton(Fm.FindComponent(Mi.Name));
  Bn.Click;
  Mi:=nil;
  Fm:=nil
  Bn:=nil;
end;

// var Bn_PopupMenu_OnPopup_Old:TNotifyEvent;

procedure PopupMenu(Sender:TObject);
var Bn,SBn:TdxButton;
    Fm:TdxForm;
    i:integer;
    Bn_PopupMenu_OnPopup_Old:TNotifyEvent;
begin
  if Sender.ClassName = 'TdxButton' then
  begin
    Bn:=TdxButton(Sender);
    Bn_PopupMenu_OnPopup_Old := Bn.PopupMenu.OnPopup;
    Bn.PopupMenu.OnPopup:=nil;
  end
  else
  if Sender.ClassName = 'TPopupMenu' then
    Bn := TdxButton(TPopupMenu(Sender).PopupComponent);
    Fm:=TdxForm(Bn.Owner);
  for i:=0 to Bn.PopupMenu.Items.Count-1 do
  begin
    SBn:=TdxButton(Fm.FindComponent(Bn.PopupMenu.Items[i].Name))
    if SBn.Visible = false then
    Bn.PopupMenu.Items[i].Visible:=false else
    Bn.PopupMenu.Items[i].Visible:=true;
    if SBn.Enabled = false then
    Bn.PopupMenu.Items[i].Enabled:=false else
    Bn.PopupMenu.Items[i].Enabled:=true;
  end;
    if Sender.ClassName = 'TdxButton' then
    begin
      Bn.PopupMenu.Popup;
      Bn.PopupMenu.OnPopup := Bn_PopupMenu_OnPopup_Old;
      Bn_PopupMenu_OnPopup_Old:=nil;
    end;
    Fm:=nil;
    Bn:=nil;
end;

procedure MenuFromGroupButtons(MasterButton,BnGroupBox:string);
var i,j,cr:integer;
  MBn,TmpBn:TdxButton;
  SBn:array of TdxButton;
  GB:TdxGroupBox;
  BnsMenu:TPopupMenu;
  BnsItems:array of TMenuItem;
begin
  MBn:=TdxButton(Self.FindComponent(MasterButton));
  GB := TdxGroupBox(Self.FindComponent(BnGroupBox));
    for i:=0 to Self.ComponentCount-1 do
    begin
      if (Self.Components[i].ClassName = 'TdxButton') then
      if TControl(Self.Components[i]).Parent=GB
      then
        begin
          SetArrayLength(SBn,GetArrayLength(SBn)+1);
          SBn[GetArrayLength(SBn)-1]:=TdxButton(Self.Components[i]);
        end
      else
      Continue;
    end;
j := GetArrayLength(SBn);
repeat
  cr := 0;
for i:=0 to j-1 do
  begin
  if (i+1=j) then Continue;
  if SBn[i].Top < SBn[i+1].Top then Continue;
  if SBn[i].Top > SBn[i+1].Top then
      begin
        TmpBn:=SBn[i];
        SBn[i] := SBn[i+1];
        SBn[i+1] := TmpBn;
        TmpBn := nil;
        inc(cr);
      end;
  end;
until
  cr = 0;
  BnsMenu:=TPopupMenu.Create(Self);
    for i:=0 to length(SBn)-1 do
    begin
      SetArrayLength(BnsItems,GetArrayLength(BnsItems)+1);
      BnsItems[i]:=TMenuItem.Create(BnsMenu);
      SetArrayLength(BnsItems,GetArrayLength(BnsItems)+1);
      BnsItems[i].Name:=SBn[i].Name;
      BnsItems[i].Caption:=SBn[i].Caption;
      BnsItems[i].Bitmap:=SBn[i].Glyph;
      BnsItems[i].Hint:=SBn[i].Hint;
      BnsItems[i].OnClick:= @OnClick;
      BnsMenu.Items.Add(BnsItems[i]);
    end;
  MBn.PopupMenu:=BnsMenu;
  MBn.OnClick :=  @PopupMenu;
  MBn.PopupMenu.OnPopup := @PopupMenu;
  if trim(MBn.Caption)='' then
  MBn.Caption := #9660 else
  MBn.Caption := MBn.Caption + #32#9660;
  GB.Hide;
end;


демо

Скачать:
Конструктор меню из кнопок v1.2.epas
v1.2 - исправлено: не срабатывала установка видимости/доступности при первом нажатии ПКМ
(6.5 КБ) 17 скачиваний

Поддержка проекта



Теги:

Быстрый ответ

Смайлики
:-) ;-) :-( :-[ :-D :-P O_O :bye: :good: :help: :lol: :ok: :pardon: :sorry: :yes:
Ещё смайлики…
Загрузить изображение