Вложенные МЕНЮ, описанные в отдельном файле

Здесь обсуждается всё, что касается макросов.
Post Reply
User avatar
buniak_a_h
Posts: 4234
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 642 times
Contact:

Вложенные МЕНЮ, описанные в отдельном файле

Post by buniak_a_h »

Навеяно этим:
SuperStainless wrote: Wed 22 Apr, 2020 16:19 I also meant menus in separate files: would be useful because you can compile the menu only one time and use it in different places.
Некоторые отвечали, что подменю, описанные в других файлах, ФАРом не поддерживаются. Как оказалось, поддерживается (функция mf.usermenu). Ниже привожу пункт "стандартного" меню, вызывающий "вложенное" пользовательское меню, описанное в другом файле, а также скрипт (ивент), "затеняющий" пункт стандартного меню в случае отсутствия такого файла.

Три замечания.
1. Хотя порядок не имеет значения, но лично мне удобно, чтоб этот пункт был первым. Ну, логично: локальное меню вызывается чаще…
2. Название этого пункта меню должно быть как-то формализовано, чтоб скрипт его "узнавал". Для себя я выбрал следующий стандарт: в заголовке пункта меню должно присутствовать имя файла в кавычках. Естественно, не должно быть пунктов, содержащих строку «File_name.ext».
3. Приведённый скрипт только дизейблит пункт меню; если заменить в нём LIF_DISABLE на LIF_HIDDEN, то такие пункты меню будут совсем скрыты. Но тогда надо бы пересчитать размеры рамки и всего диалога; я не стал париться.

Итак, скрипт:
  1. local F = far.Flags
  2.  
  3. Event {
  4.  
  5.   id = "5BC25193-48EE-42E7-8446-6125E4FBFAB0";
  6.  
  7.   group       = "DialogEvent"; -- export.ProcessDialogEvent
  8.  
  9.   description = "Сокрытие пункта вызова UserMenu из другого файла";
  10.  
  11. --  filemask    = "*.txt,*.cpp";                          -- string (опциональное поле)
  12.  
  13. --  priority    = 50;                                     -- number (опциональное поле)
  14.  
  15.   condition   = function(Event, Param)
  16.  
  17.    if Area.UserMenu and Event == F.DE_DEFDLGPROCINIT and Param.Msg == F.DN_INPUT then
  18.  
  19.     local Item = Param.hDlg:send(F.DM_GETDLGITEM, 1)
  20.  
  21.     if Item and type(Item) == 'table' and (Item[1]==F.DI_LISTBOX or Item[1]=='DI_LISTBOX') and
  22.  
  23.        (Item[12] or 0) == 0 then
  24.  
  25.      Item[12] = 1
  26.  
  27.      Param.hDlg:send(F.DM_SETDLGITEM,1, Item)
  28.  
  29.      return true
  30.  
  31.     end
  32.  
  33.    end
  34.  
  35.   end; -- condition
  36.  
  37.   action      = function(Event, Param)
  38.  
  39.    local hDlg = Param.hDlg
  40.  
  41.    local n = hDlg:send(F.DM_LISTINFO, 1).ItemsNumber
  42.  
  43.    for i=1,n do
  44.  
  45.     local Item = hDlg:send(F.DM_LISTGETITEM, 1, i)
  46.  
  47.     local FName = Item.Text:match"%b«»"
  48.  
  49.     if FName then
  50.  
  51.      FName = win.SearchPath( ( (APanel.Plugin and 'win.GetCurrentDir()' or APanel.Path) .. ';') ..
  52.  
  53.                              (win.GetEnv("FARHOME") .. ';') ..
  54.  
  55.                              (win.GetEnv("FARPROFILE") .. ';') ..
  56.  
  57.                              (win.GetEnv("FARLOCALPROFILE") .. ';') ..
  58.  
  59.                              (win.GetEnv("PATH") .. ';'), -- Path
  60.  
  61.                              FName:sub(2,-2)
  62.  
  63.                            )
  64.  
  65.      if not FName then
  66.  
  67.       Item.Flags = bor(Item.Flags, F.LIF_DISABLE)
  68.  
  69.       Item.Index = i
  70.  
  71.       hDlg:send(F.DM_LISTUPDATE, 1, Item)
  72.  
  73.      end
  74.  
  75.      break
  76.  
  77.     end
  78.  
  79.    end
  80.  
  81.   end; -- action
  82.  
  83. }
Post Reply

Return to “Обсуждение макросов”