В nanoCAD существует возможность добавлять новые пункты меню, создавать собственные панели инструментов (Toolbar) — (рис. 1) и ленты (Ribbon) — (рис. 2). Все кнопки в меню, панелях инструментов и лентах связаны с командами. Можно добавлять свои команды, использующие API nanoCAD. Команды описываются в DLL-библиотеках, которые становятся доступны пользователю после загрузки в Платформу.

Создание пользовательского меню и панелей инструментов, а также изменение ленты может включать следующие шаги:

  • подготовка DLL-библиотеки с командами;
  • создание меню;
  • создание панели инструментов;
  • создание ленты;
  • добавление иконок в меню, панель инструментов и в ленту;
  • иконки для темной и светлой схемы;
  • создание ресурсной DLL с иконками;
  • отключение меню, панели инструментов, ленты.
Рис. 1 Рис. 1 Рис. 2 Рис. 2

Подготовка DLL-библиотеки с командами

За любой кнопкой интерфейса nanoCAD стоит команда, которая выполняет те или иные действия. Используя инструменты API nanoCAD, пользователь может разрабатывать собственные наборы команд. Как правило, разработка нацелена на взаимодействие с пользователем, поэтому DLL-библиотека содержит команды, которые станут доступны пользователю после загрузки в командной строке Платформы nanoCAD. Для удобства командам могут быть назначены свои кнопки в меню, панелях инструментов и в ленте.

Для этого код должен содержать название команды (атрибут CommandMethod).

Листинг MyApplication.dll (имена команд — HelloHost_Example1 и HelloHost_Example2):

...
public class HelloHost
{
[CommandMethod("HelloHost_Example1")]
public void Template1()
{
...
}
...
[CommandMethod("HelloHost_Example2")]
public void Template2()
{
...
}
}
...

Полный пример кода содержится в SDK:

\SDK\samples\Mgd\HelloHost\HelloHost.cs

Создание меню

Перейдите в настройки пользовательского интерфейса (НПИ): СервисИнтерфейсНастройка пользовательского интерфейса либо используйте команду INTERFACE в командной строке nanoCAD (рис. 3).

Рис. 3 Рис. 3

Для кастомизации меню используется отдельный файл, его нужно создать (рис. 4).

Рис. 4 Рис. 4

Переключитесь на созданный конфигурационный файл, выбрав его из выпадающего списка (рис. 5).

Рис. 5 Рис. 5

Создайте меню верхнего уровня (правая кнопка мыши (ПКМ) → вкладка Главное меню) в созданном конфигурационном файле (рис. 6).

Рис. 6 Рис. 6

Результат должен выглядеть так, как показано на рис. 7.

Рис. 7 Рис. 7

Создайте описание команд HelloHost_Example1 и HelloHost_Example2 (ПКМ → Создать команду). Команды будут вызываться в пунктах меню (рис. 8).

Рис. 8 Рис. 8

Поле Внутреннее имя должно содержать точное название команды, как в DLL-приложении (рис. 9, 10).

Команда HelloHost_Example1

Команда HelloHost_Example2

Рис. 9 Рис. 9
Рис. 10 Рис. 10

Добавьте пункты меню, вызывающие команды HelloHost_Example1 и HelloHost_Example2 (рис. 11).

Рис. 11 Рис. 11

Сохраните и подключите конфигурационный файл.

При подключении Платформа попросит выбрать файл — нужно указать созданный частичный файл меню: MyMenuConfig.cfg (рис. 12).

Для применения новых настроек перезагрузите Платформу nanoCAD полностью.

Рис. 12 Рис. 12

Результат должен быть таким, как показано на рис. 13.

Рис. 13 Рис. 13

Примечание. Так как созданное меню использует команды из DLL-библиотеки, ее загрузку следует автоматизировать, то есть добавить DLL в список автоматически загружаемых приложений.

Создание панели инструментов

Перейдите в настройки пользовательского интерфейса (НПИ): СервисИнтерфейсНастройка пользовательского интерфейса либо используйте команду INTERFACE в командной строке nanoCAD. Вкладка Панели инструментов.

В примере используется ранее созданный частичный конфигурационный файл.

Добавьте панель инструментов (щелчок ПКМ в окне вкладки Панели инструментов) и укажите нужные параметры в окне создания панели инструментов (рис. 14).

Рис. 14 Рис. 14

Для удобства первой настройки параметру Размещение можно назначить значение Сверху (рис. 15).

Рис. 15 Рис. 15

Добавьте кнопки на панель инструментов — они будут вызывать команды из DLL-приложения (рис. 16).

Рис. 16 Рис. 16

Полученный результат представлен на рис. 17.

Рис. 17 Рис. 17

Сохраните и подключите конфигурационный файл. Если конфигурационный файл уже был подключен ранее, пункт 2 (см. рис. 18) следует пропустить.

Рис. 18 Рис. 18

Для применения новых настроек перезагрузите Платформу nanoCAD полностью.

После создания и подключения панель инструментов отображается с системными иконками (рис. 19).

Рис. 19 Рис. 19

Созданный частичный конфигурационный файл располагается по следующему адресу:

C:\Users\nanoUser\AppData\Roaming\Nanosoft\nanoCAD x64 XX.x\Config\MyMenuConfig.cfg

При подключении конфигурационного файла в диалоге НПИ название файла будет добавлено в основной конфигурационный файл:

C:\Users\nanoUser\AppData\Roaming\Nanosoft\nanoCAD x64 XX.x\Config\nanoCAD.cfg

Листинг nanoCAD.cfg:

...
[\ribbon]
...
#include "MyMenuConfig.cfg"
...

Создание ленты (Ribbon)

Лента приложения описывается в файле CUIX, который представляет собой ZIP-архив, где расположены XML-файлы, поименованные определенным образом.

Частичные (пользовательские) файлы ленты поддерживаются Платформой, но не поддерживаются диалогом НПИ.

Диалог НПИ умеет редактировать лишь основную ленту приложения, поэтому его имеет смысл применять только в том случае, когда используется подход «настроить и распространить по всем компьютерам».

Для создания частичной (пользовательской) ленты требуется выполнить следующие действия:

  1. Создайте три файла: [Content_Types].xml, Menu_Package_Info.xml, RibbonRoot.cui.

    Листинг [Content_Types].xml:

    <?xml version="1.0" encoding="utf-8"?>
    <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
    <Default Extension="cui" ContentType="text/xml" />
    <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
    <Default Extension="xml" ContentType="text/xml" />
    </Types>
    

    Листинг Menu_Package_Info.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <MenuPackageParts>
    <PartData PartData_Name="/RibbonRoot.cui" PartData_Modified="2022-01-31T12:42:04.9848238+03:00" />
    <PartData PartData_Name="/Menu_Package_Info.xml" PartData_Modified="2022-01-31T12:42:05.0058294+03:00" />
    </MenuPackageParts>
    

    Листинг RibbonRoot.cui:

    <?xml version="1.0"?>
    <RibbonRoot>
    <RibbonPanelSourceCollection xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <RibbonPanelSource UID="RBNU_HelloHost_GroupA" Text="Команды A" HiddenInEditor="false">
    <RibbonRow UID="RBNUR_Sample_Ribbon_Row_Main_GroupA">
    <RibbonRowPanel UID="RBNURP_SDK_Samples_nano" ResizeStyle="None" ResizePriority="100" TopJustify="True">
    <RibbonRow UID="RBNURR_Samples_GroupA">
    <RibbonCommandButton UID="ID_RBN_GR_A_HELLOHOSTEX1" Id="AcRibbonCommandButton" Text="Команда 1" ButtonStyle="LargeWithText" MenuMacroID="HelloHost_Example1" KeyTip="">
    <TooltipTitle xlate="true" UID="XLS_HelloHost1">Выводит в командную строку сообщение</TooltipTitle>
    </RibbonCommandButton>
    <RibbonCommandButton UID="ID_RBN_GR_A_HELLOHOSTEX2" Id="AcRibbonCommandButton" Text="Команда 2" ButtonStyle="LargeWithText" MenuMacroID="HelloHost_Example2" KeyTip="">
    <TooltipTitle xlate="true" UID="XLS_HelloHost2">Выводит в командную строку информацию о первых 10 слоях</TooltipTitle>
    </RibbonCommandButton>
    </RibbonRow>
    </RibbonRowPanel>
    </RibbonRow>
    <RibbonPanelBreak Id="RibbonPanelBreak"/>
    <RibbonRow UID="RBNUR_Sample_Ribbon_Row_Additional_1" ResizeStyle="None" ResizePriority="100" TopJustify="True">
    <RibbonCommandButton UID="ID_RBN_GR_A_HELLOHOSTEX3" Id="RibbonCommandButton" Text="Команда 3" ButtonStyle="SmallWithText" MenuMacroID="HelloHost_Example3" resolved="1" KeyTip=""/>
    </RibbonRow>
    <RibbonRow UID="RBNUR_Sample_Ribbon_Row_Additional_2" ResizeStyle="None" ResizePriority="100" TopJustify="True">
    <RibbonCommandButton UID="ID_RBN_GR_A_HELLOHOSTEX4" Id="RibbonCommandButton" Text="Команда 4" ButtonStyle="SmallWithText" MenuMacroID="HelloHost_Example4" resolved="1" KeyTip=""/>
    </RibbonRow>
    <RibbonRow UID="RBNUR_Sample_Ribbon_Row_Additional_3" ResizeStyle="None" ResizePriority="100" TopJustify="True">
    <RibbonCommandButton UID="ID_RBN_GR_A_HELLOHOSTEX5" Id="RibbonCommandButton" Text="Команда 5" ButtonStyle="SmallWithText" MenuMacroID="HelloHost_Example5" resolved="1" KeyTip=""/>
    </RibbonRow>
    </RibbonPanelSource>
    <RibbonPanelSource UID="RBNU_HelloHost_GroupB" Text="Команды B" HiddenInEditor="false">
    <RibbonRowPanel UID="RBNUR_Sample_Ribbon_Row_Main_GroupB" ResizeStyle="None" ResizePriority="100" TopJustify="True">
    <RibbonRow UID="RBNUR_Sample_Ribbon_Row_1_Main_GroupB">
    <RibbonCommandButton UID="RBNU_HelloHost_Example1" Id="AcRibbonCommandButton" Text="Команда 1" ButtonStyle="SmallWithText" MenuMacroID="HelloHost_Example1" KeyTip="">
    <TooltipTitle xlate="true" UID="XLS_HelloHost_Example1">Выводит в командную строку сообщение</TooltipTitle>
    </RibbonCommandButton>
    </RibbonRow>
    <RibbonRow UID="RBNUR_Sample_Ribbon_Row_2_Main_GroupB">
    <RibbonCommandButton UID="RBNU_HelloHost_Example2" Id="AcRibbon CommandButton" Text="Команда 2" ButtonStyle="SmallWithText" MenuMacroID="HelloHost_Example2" KeyTip="">
    <TooltipTitle xlate="true" UID="XLS_HelloHost_Example2">Выводит в командную строку информацию о первых 10 слоях</TooltipTitle>
    </RibbonCommandButton>
    </RibbonRow>
    <RibbonRow UID="RBNUR_Sample_Ribbon_Row_3_Main_GroupB">
    <RibbonCommandButton UID="RBNU_HelloHost_Example3" Id="AcRibbonCommandButton" Text="Команда 3" ButtonStyle="SmallWithText" MenuMacroID="HelloHost_Example3" KeyTip="">
    <TooltipTitle xlate="true" UID="XLS_ListCrCr">Третья команда</TooltipTitle>
    </RibbonCommandButton>
    </RibbonRow>
    </RibbonRowPanel>
    <RibbonPanelBreak Id="RibbonPanelBreak"/>
    <RibbonRowPanel UID="" ResizeStyle="None" ResizePriority="100" TopJustify="True">
    <RibbonRow UID="RBNURR_SDK_MAPI">
    <RibbonSplitButton UID="ID_RBN_SPLITBTN_ADDCOMMANDS" Id="RibbonSplitButton" Text="Доп.команды" KeyTip="" Behavior="SplitFollowStaticText" ListStyle="IconText" ButtonStyle="LargeWithText" Grouping="false">
    <RibbonCommandButton UID="RBNU_AddCommand6" Id="AcRibbon CommandButton" Text="Команда 6" ButtonStyle="SmallWithText" MenuMacroID="TextInBox" KeyTip="" />
    </RibbonSplitButton>
    <RibbonSplitButton UID="ID_RBN_SPLITBTN_SOMECOMMANDS" Id="RibbonSplitButton" Text="Еще доп.команды" KeyTip="" Behavior="SplitFollowStaticText" ListStyle="IconText" ButtonStyle="LargeWithText" Grouping="false">
    <RibbonCommandButton UID="ID_RBN__AddCommand7" Id="RibbonCommandButton" Text="Команда 7" ButtonStyle="SmallWithText" MenuMacroID="testTable" resolved="1" KeyTip=""/>
    <RibbonCommandButton UID="ID_RBN__AddCommand8" Id="RibbonCommandButton" Text="Команда 8" ButtonStyle="SmallWithText" MenuMacroID="testSymbols" resolved="1" KeyTip=""/>
    </RibbonSplitButton>
    </RibbonRow>
    </RibbonRowPanel>
    </RibbonPanelSource>
    </RibbonPanelSourceCollection>
    <RibbonTabSourceCollection>
    <RibbonTabSource Text="Моя лента" UID="ID_MY_RIBBON">
    <RibbonPanelSourceReference UID="RBNU_LargeWithText_GroupA_Ref" PanelId="RBNU_HelloHost_GroupA" ResizeStyle="Default" />
    <RibbonPanelSourceReference UID="RBNU_SmallWithText_GroupC_Ref" PanelId="RBNU_HelloHost_GroupB" ResizeStyle="Default" />
    </RibbonTabSource>
    </RibbonTabSourceCollection>
    </RibbonRoot>
    
  2. Создайте архив MyRibbon.zip, содержащий указанные выше файлы (на одном уровне, без вложенности в папку) — рис. 20. Не рекомендуется использовать внешние архиваторы и дополнительные параметры сжатия.
    Рис. 20 Рис. 20
  3. Переименуйте файл MyRibbon.zip в MyRibbon.cuix. Например, в командной строке Windows:

    C:\Users\nanoUser\AppData\Roaming\Nanosoft\Config\>rename MyRibbon.zip MyRibbon.cuix

  4. Расположите MyRibbon.cuix в C:\Users\nanoUser\AppData\Roaming\Nanosoft\nanoCAD x64 XX.x\Config.
  5. Добавьте ссылку на MyRibbon.cuix в конец файла: C:\Users\nanoUser\AppData\Roaming\Nanosoft\nanoCAD x64 XX.x\Config\MyMenuConfig.cfg

    Листинг MyMenuConfig.cfg:

    [\Menu]
    [\Menu\MainMenu_2]
    Name=sMyMenu3">
    [\Menu\MainMenu_2\MenuItem_1]
    Intername=sHelloHost_Example1
    Name=sКоманда 1
    [\Menu\MainMenu_2\MenuItem_2]
    Intername=sHelloHost_Example2
    Name=sКоманда 2
    [\ConfigMan]
    [\ConfigMan\Commands]
    [\ConfigMan\Commands\Command_1]
    cmdtype=i1
    weight=i0
    Intername=sHelloHost_Example1
    LocalName=sHelloHostEx1
    DispName=sHelloHost (Пример 1)
    IsUserCommand=f1
    [\ConfigMan\Commands\Command_2]
    cmdtype=i1
    weight=i0
    DispName=sHelloHost (Пример 2)
    Intername=sHelloHost_Example2
    LocalName=sHelloHostEx2
    IsUserCommand=f1
    [\ribbon\MyRibbon]
    CUIX=s%CFG_PATH%\MyRibbon.cuix
    visible=f1
    

    Примечание. Вносить изменения в файл CUIX можно без перезапуска всей Платформы, достаточно воспользоваться командой RELOADRIBBON.

    Результат показан на рис. 21.

    Рис. 21 Рис. 21

    Примечание. Дополнительные (частные) ленты поддерживаются только в формате CUIX.

Добавление иконок в меню, панель инструментов и в ленту

Иконка команды — это свойство описания команды. Если она не указана, будет отображаться иконка по умолчанию.

Настроенная иконка выводится и в меню, и на панель инструментов, и в ленту.

Задать иконку можно в поле Ресурсная DLL (рис. 22). При этом принимаются форматы ICO, BMP и иконки в составе ресурсной DLL (рис. 23).

Рис. 22 Рис. 22 Рис. 23 Рис. 23

Примеры иконок входят в состав SDK: \SDK\samples\Menu\MenuRes\res.

Результат добавления иконок показан на рис. 24.

Рис. 24 Рис. 24

Иконки для темной и светлой схемы

Иконки для светлой и темной схемы разные, предусмотрен механизм автоматического переключения. Если в описании команд прописана иконка myicon.ico, то при переключении в темную схему будет использована иконка myicon_dark.ico (при ее наличии).

В случае использования изображений формата BMP файлы подбираются по следующим правилам:

myBitmap.bmp — светлая схема, 16×16;

myBitmap_large.bmp — светлая схема, 32×32;

myBitmap_dark.bmp — темная схема, 16×16;

myBitmap_dark_large.bmp — темная схема, 32×32.

Создание ресурсной DLL с иконками

Пример проекта Visual Studio, с помощью которого можно сформировать ресурсную DLL с иконками, входит в состав SDK:

\SDK\samples\Menu\MenuRes\MenuRes.vcxproj

Итоговый листинг MyMenuConfig.cfg:

[\Menu]
[\Menu\MainMenu_2]
Name=sМоеМеню
[\Menu\MainMenu_2\MenuItem_1]
Intername=sHelloHost_Example1
Name=sКоманда 1
[\Menu\MainMenu_2\MenuItem_2]
Intername=sHelloHost_Example2
Name=sКоманда 2
[\ConfigMan]
[\ConfigMan\Commands]
[\ConfigMan\Commands\Command_1]
cmdtype=i1
weight=i0
Intername=sHelloHost_Example1
LocalName=sHelloHostEx1
DispName=sКоманда 1
IsUserCommand=f1
BitmapDll=sG:\SDK\samples\Menu\MenuRes\res\a.ico
[\ConfigMan\Commands\Command_2]
cmdtype=i1
weight=i0
Intername=sHelloHost_Example2
LocalName=sHelloHostEx1
DispName=sКоманда 2
IsUserCommand=f1
BitmapDll=sG:\SDK\samples\Menu\MenuRes\res\n.ico
[\Toolbars]
[\Toolbars\Toolbar_1]
Name=sМояПанельИнстр
Intername=sMyToolbar
[\Toolbars\Toolbar_1\ToolbarButton_1]
Intername=sHelloHost_Example1
Name=sКоманда 1
[\Toolbars\Toolbar_1\ToolbarButton_2]
Intername=sHelloHost_Example2
Name=sКоманда 2
[\ToolbarsPos]
[\ToolbarsPos\Toolbar_1]
InitialVisible=i1
Row=i5">
Pos=i1
DockPosition=sTop
[\ribbon]
[\ribbon\MyRibbon]
CUIX=s%CFG_PATH%\MyRibbon.cuix
visible=f1

Отключение меню, панели инструментов, ленты

Для отключения ранее подключенного меню или панели инструментов нужно:

  1. перейти в настройки пользовательского интерфейса (НПИ): СервисИнтерфейсНастройки пользовательского интерфейса либо вызвать команду INTERFACE в командной строке nanoCAD;
  2. переключиться на конфигурационный файл меню, который следует отключить;
  3. ФайлОтключить текущий частичный файл.

Для отключения ленты достаточно убрать ссылку на файл CUIX из частичного конфигурационного файла.

Сергей Евсеев,
специалист группы поддержки API
ООО «Нанософт разработка»