При переходе с обычного приложения на управляемые формы многие разработчики сталкиваются с вопросом гибкой настройки интерфейса. В обычном приложении можно было легко создать произвольное дерево в справочнике или обработке, прикрепить форму к левой границе рабочего пространства и получить полностью динамическое меню. Выясним, возможно ли повторить такое поведение в управляемом интерфейсе (включая интерфейс «Такси»), с какими ограничениями платформы придется столкнуться и как реализовать удобную альтернативу.
Проанализируем, как устроен командный интерфейс в управляемом приложении. Главное меню, панель разделов, панель навигации и панель действий формируются платформой строго декларативно на этапе инициализации конфигурации. Состав элементов рассчитывается автоматически на основе трех составляющих:
В объектной модели встроенного языка 1С нет методов для прямого программного добавления кнопок или изменения порядка разделов в главном меню. Мы не можем вызвать объект вроде «ПанельРазделов.Элементы.Добавить()» в рантайме. Кроме того, в управляемых формах отсутствует программный механизм жесткого прикрепления (докинга) произвольной формы к границе окна, как это было в обычном интерфейсе.
Если требуется динамически скрывать или показывать стандартные разделы и команды без создания десятков отдельных ролей, рассмотрим штатный механизм платформы — функциональные опции, привязанные к параметрам.
Разберем по шагам, как это реализовать:
ПараметрФункциональныхОпций (например, ТекущийПрофильИнтерфейса).ФункциональнаяОпция, указываем в качестве параметра наш параметр, а в составе опции отмечаем подсистемы, документы, справочники или отчеты, видимость которых должна переключаться.Посмотрим на пример кода, выполняемого на клиенте при изменении настроек пользователя:
ПараметрыОпций = Новый Структура;
ПараметрыОпций.Вставить("ТекущийПрофильИнтерфейса", ИдентификаторПрофиля);
УстановитьПараметрыФункциональныхОпций(ПараметрыОпций);
// Принудительно перестраиваем командный интерфейс текущего сеанса
ОбновитьИнтерфейс();
Этот способ позволяет динамически менять доступность целых разделов и отдельных команд, оставаясь в рамках типового интерфейса 1С.
Если стандартного командного интерфейса недостаточно и требуется иерархическое меню произвольной структуры с сортировкой и расчетом статусов, лучшим решением будет вынос навигации в отдельную форму. Рассмотрим два основных варианта компоновки:
Чтобы стандартное меню не дублировало элементы и не перегружало экран, стандартные панели можно скрыть программно. Для этого используется объект НастройкиИнтерфейсаКлиентскогоПриложения с сохранением в системное хранилище настроек:
// Программная настройка состава панелей интерфейса
НастройкиИнтерфейса = Новый НастройкиИнтерфейсаКлиентскогоПриложения;
// Отключаем лишние стандартные панели
НастройкиИнтерфейса.ПанельРазделов.Видимость = Ложь;
НастройкиИнтерфейса.ПанельФункцийТекущегоРаздела.Видимость = Ложь;
ХранилищеСистемныхНастроек.Сохранить(
"Общее/НастройкиИнтерфейсаКлиентскогоПриложения",
"",
НастройкиИнтерфейса
);
ОбновитьИнтерфейс();
После создания формы-навигатора выберем механизм динамического вывода элементов:
Вариант А: Иерархическое дерево значений или таблица формы
Создаем реквизит формы с типом ДеревоЗначений. В него загружаются разделы из справочника, регистра сведений или структуры прав. В событии таблицы Выбор вызываем нужный объект:
&НаКлиенте
Процедура МенюВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ТекущиеДанные = Элемент.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено И ЗначениеЗаполнено(ТекущиеДанные.ИмяФормы) Тогда
ОткрытьФорму(ТекущиеДанные.ИмяФормы);
ИначеЕсли ЗначениеЗаполнено(ТекущиеДанные.НавигационнаяСсылка) Тогда
ПерейтиПоНавигационнойСсылке(ТекущиеДанные.НавигационнаяСсылка);
КонецЕсли;
КонецПроцедуры
Вариант Б: Программная генерация кнопок и групп формы
В событии ПриСозданииНаСервере мы можем полностью программно заполнить форму кнопками на основе прав или персональных настроек текущего пользователя:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Создаем команду формы
ИмяКоманды = "КомандаОткрытьНакладные";
НоваяКоманда = Команды.Добавить(ИмяКоманды);
НоваяКоманда.Заголовок = "Расходные накладные";
НоваяКоманда.Действие = "Подключаемый_ВыполнитьКомандуМеню";
// Создаем визуальную кнопку
НоваяКнопка = Элементы.Добавить("КнопкаНакладные", Тип("КнопкаФормы"), Элементы.ГруппаМеню);
НоваяКнопка.ИмяКоманды = ИмяКоманды;
НоваяКнопка.Вид = ВидКнопкиФормы.ОбычнаяКнопка;
КонецПроцедуры
Вариант В: Поле HTML-документа
Для создания современного интерфейса с анимациями, раскрывающимися списками и нестандартной версткой разместим на форме элемент с видом ПолеHTMLДокумента. В него генерируется готовая HTML/CSS-разметка. При клике по пунктам меню навигация перехватывается стандартными ссылками вида e1c: либо через событие ПриНажатии поля HTML.
Таким образом, прямое изменение глобального меню платформы невозможно из-за декларативной архитектуры управляемого приложения. Однако поставленная задача легко решается скрытием стандартных панелей и созданием собственной навигационной формы на начальной странице или в виде отдельного АРМ.