Все статьи цикла: Введение Расширяем структуру файлов надстройки и удалённая отладка Автозаполнение для API и знакомимся с контролами (эта статья) Разбираем структуру   Напомню, что поскольку, худо ли - бедно, я добился удалённой отладки для надстроек (напомню, так почему-то  назвали разработчики «МойОфис» макросы с возможностью использовать пусть и примитивный, но набор контролов и форм). Тем самым, в критических ситуациях можно теперь пошагово отследить, в чём проблема.  Так же напоминаю, что работа сейчас ведётся не в самом пакете «МойОфис», так как там штатно для надстроек вообще пока ничего нет, а в самой последней версии (1.40 на момент написания статьи) IDE для Lua – LuaRT. Который в свою очередь, является заточенной под Windows форк версией, от самой известной IDE - ZeroBrane Studio (иногда в дальнейшем для краткости - ZBS) с разными дополнительными плюшками, которые я надеюсь,  смогу использовать чуть позже (если смогу, то напишу об этом отдельную статью). А сам же ZeroBrane Studio имеет то преимущество, что кроссплатформенная, а значит ею можно пользоваться для аналогичной работы под Linux версией офиса, благодаря тому, что все базовые принципы, которые я здесь излагаю, должны без проблем подойти и в эту программу.    Теперь передо мной встал вопрос об отсутствии банальной в XXI веке «фишке», к которой я привык, как программист о-о-очень избалованный современными IDE, и без наличия которой программирование меня быстро приводит в ярость, а именно – автозаполнение вводимого кода. Как упоминал в первой ещё статье цикла, его нет даже во «встроенном редакторе» «МойОФис» (в кавычках, ибо на редактор это тянет слабо) для того, что там назвали макросами. То есть, хочешь писать макросы, открывай справочник по Lua API для макросов, и ищи там! Бесит, честно говоря. Но поскольку речь не о нём, то что же  мне предлагает  LuaRT (тоже самое есть и в ZeroBrane Studio, поэтому описанное далее подойдёт как родное и туда)? ZeroBrane Studio, а следовательно и LuaRT, предлагает много  интересных «фишек» для программирования. Часть из них есть и «из коробки», а часть можно догрузить из набора дополнений к самой программы ZeroBrane Studio (они опять же, почти все без проблем становятся и в LuaRT). В частности, поддерживает довольно обширный набор различных фреймворков, в которых активно используется или которые сами построены на Lua (LÖVE, Corona, Moai, Gideros, Marmalade Quick, Cocos2d-x,  и ряд других). В основном это касается отладки и такой интересной возможности, как «интерпретация на лету», но так же можно добавить и функционал по автодополнению кода при его написании, в соответствии с используемым фреймворком.  Включается такого рода либо загрузкой уже готового бесплатного расширения, либо самостоятельно - путём создания собственного файла описания требуемого API. Итак, приступим! Перво-наперво, надо в файле настроек (user.lua) добавить следующий пункт:    на самом деле можно внести ещё много дополнительных пунктов в настройки (расписанных в документации), чтобы конфигурация IDE была более адекватной для работы с API «под себя», но это сильно отклонит от текущих задачи, поэтому как-нибудь в другой раз. Хотя эта тема и весьма интересная.    Данный пункт «api» -  включит при открытии IDE загрузку специализированных файлов написанных как таблицы lua, в которых и хранится информация, используемая при программировании. Далее перечисляются названия файлов без расширения «.lua», которые в свою очередь должны быть расположены в специальной подпапке ( /api/lua ) внутри папки самого IDE: Само - собой, что на момент написания я уже более-менее заполнил созданный файл myofficeapi.lua, используя справочник по API надстроек от самих разработчиков, который лежит в свободном доступе на их сайте.    Поскольку у меня нет на момент написания статьи полного описания этого самого API, да и буду ли я его делать – большой вопрос, то я внёс туда только то, что мне нужно было для облегчения моих экспериментов, а именно - описание (и то неполное) двух базовых «классов» для работы с формами: «Forms»  и «ui». Немного подробнее о них я расскажу ниже, а пока распишу, как можно заполнять самостоятельно файлы для автодополнения.    Формат подобных файлов расписан в документации к ZeroBrane Studio: «foo» - это описываемый «класс», или модуль, или вообще любая первая в написании структура которую мы набираем, по типу foo:function(). А далее, в таблицах lua мы заполняем различные атрибуты – описатели для foo. Если имеются  дочерние структуры (переменные, классы и т.п.), то аналогичным способом внутри таблицы «childs» описываем и их. Это например: foo.bar.f(). Можно (и нужно!) описать так же тип, аргументы и возвращаемый тип, если описывается функция. Вот ниже я привожу перевод из документации:    «type»: одно из следующих значений:           «keyword»: для описания ключевых слов языка, таких как «do» и «end»;        «class» и «lib»: для описания групп функций, методов, значений и других классов и библиотек;        «value»: для описания конкретных значений (например, констант);        «function»: для описания функции, которая принимает параметры («args») и возвращает значения («returns»), возможно, определенного типа («valuetype»);        «method»: описывать вызовы методов; методы описываются аналогично функциям, а также принимают аргументы, возвращаемые значения и типы значений. Единственное отличие состоит в том, что методы предлагаются только после «:» в автозаполнении, а функции предлагаются после «.» и «:». «description»: текст, описывающий элемент указанного типа. Описание может включать новые строки, которые включаются в отображаемый текст. Длинные описания будут сокращены, чтобы они поместились на экране. «args»: (необязательно) строка с аргументами; например, (file: file) «returns»: (необязательная) строка с возвращаемыми значениями; например, (boolean|nil [, string, number]) «childs»: (необязательно) таблица с подэлементами текущего элемента; например, методы в классе или функции/значения в библиотеке. «valuetype»: (необязательная) строка со значением типа, которая действует как подсказка для обработки типа в автозаполнении. Например, использование valuetype = "f" указывает, что текущий элемент возвращает значение типа f. Значение может быть сложным именем; например, foo.bar. «inherits»: (необязательная) строка для указания цепочки наследования для текущего класса. Может включать несколько классов, разделенных пробелами. Теперь запасаемся терпением, открываем в одном окне скачанный pdf файл с описанием API, в другом начинаем мучаться с переносом данных, согласно описанию формата. Приведу здесь кусок с кодом для Forms (соджержит в основном вспомогательные константы и типы данных для создания контролов, описанных классом ui), который у меня получился:  Если всё прошло пучком (а мне пришлось чтобы убедиться, после каждого нового внесённого объекта проверять, что всё работает, через сохранение файла и перезагрузку всего IDE), то теперь при наборе в LuaRT (или в ZBS) появляются в автозаполнение внесённые данные: И больше того, как и положено во "взрослой" IDE, если мы сохраняем вводимое значение как переменную, то «тип» запоминается, и автодополнение корректно работает и с переменной:   В общем: «то что доктор прописал»! Так можно по идее заполнить всё API «МойОфис», но как говорится, мне за это никто не платит, потому и как-нибудь  «без меня». Главное что возможности для этого есть! Теперь, давайте наконец начнём уже ковыряться в возможностях надстроек, в плане построения на них хоть какого то GUI! Итак, открываем справочный файл по надстройкам от разработчиков, и смотрим что у нас есть для создания интерактивного взаимодействия между программой «МойОфис»  (и увы и ах, но и это  доступно только для текстового и табличного процессора) и пользователем, через надстройки (раздел 2.9 справочника): Пользовательский интерфейс в надстройках Для описания пользовательского интерфейса в надстройках редакторов МойОфис разработчик использует виджеты (widgets) и компоновки (layouts). Виджеты представляют собой элементы пользовательского интерфейса, такие как кнопки, выпадающие списки, флажки и т. д. Виджеты используются для отображения данных в диалоговом окне и для получения ввода от пользователя. Компоновки предоставляют инструмент для автоматического размещения виджетов внутри диалогового окна. Для создания пользовательского интерфейса надстроек доступны следующие виджеты: – Label (Надпись ui:Label) – элемент для отображения неизменяемого текста, например, пояснительная надпись для поля ввода; – Button (Кнопка ui:Button) – элемент для отображения кнопки, требующей нажатия; – CheckBox (Флажок ui:CheckBox) – элемент для отображения флажка; – RadioButton (Радио кнопка ui:RadioButton) – элемент для отображения переключателя; – GroupBox (Рамка группы ui:GroupBox) – элемент для отображения группы элементов Радиокнопка; – ListBox (Список элементов ui:ListBox) – элемент для отображения окна списка; – ComboBox (Поле с выпадающим списком ui:ComboBox) – элемент для отображения поля с выпадающим списком; – TextBox (Текстовое поле ui:TextBox) – элемент для ввода небольшого объема текста.   Для размещения виджетов в пространстве диалогового окна используются следующие виды компоновок: – Row (ui:Row )– располагает виджеты по горизонтали слева направо по ширине диалогового окна; – Column (ui:Column) – располагает виджеты по вертикали сверху вниз по высоте диалогового окна; – Spacer(ui:Spacer) – используется для выравнивания позиции виджета относительно ширины или высоты диалогового окна. Так же имеются ещё и возможности вызова встроенных диалоговых окон для задания параметров печати, самой печати, поиска папок и файлов (но опять, не напрямую как контрол,  а через нажатия скажем на кнопку). Кроме того, можно в некоторых контролах менять цвет текста и его расположение внутри (надпись и кнопка). Можно задать размеры контрола, и его доступность. Как выяснилось случайно, есть и недокументированная почему-то возможность сделать контролы невидимыми. Вот навскидку наверное и всё, что нам разрешили на текущий момент разработчкики!  Нет крайне необходимых для визуального разделения фреймов (Frame в терминах VBA). Нет разбиения групп контролов по отельным страницам (MulipageControl и Page). Нельзя поменять шрифт надписей, его размер и начертание. Нельзя визуализировать и изменить стиль границ контролов. Короче, почти ничего нельзя! Почему? Да – хз! Честно говоря, я когда первый раз ознакомился, был мягко говоря удивлён, от скудости возможностей предоставленных разработчиками "МойОФис" программистам. Тем не менее, «на безрыбье и рак – рыба», посему кое-то я вам смогу показать, в плане изготовления из имеющегося г..на и палок  набора, чего то более-менее похожего хотя бы по функционалу, на формы в офисе от майкрософта. Но, чудес не ждите! Так как без подключения сторонних модулей для GUI в Lua «МойОфис», ничего не выйдет, пока не расщедрятся разработчкики! А заниматься этим мне как то пока без особого смысла.  Итак, посмотрим как выглядят контролы на форме. Для этого внесём в /cmd/forms.lua (или в /forms/init.lua – почему так см. предыдущую статью) следующие изменения (листинг я скрою под спойлер)  Я намеренно не стал нагружать этот пример обработчиками событий для каждого контрола, так как они для цели сегодняшнего разбора не особо важны. Части касающиеся расположения я немного прокомментировал, но более подробно «кухню всего этого», и главное, каким образом можно сделать в рамках одной надстройки что-то более-менее сложное, в плане наполнения формы, я покажу в следующей части. Она скорее всего будет заключительной для вводного курса. А на сегодня – всё!  Программист широкого профиля