Якщо ви створюєте користувацький шар, є можливість навіть додати до нього власні пресети керування. Це може стати у пригоді, якщо ваш шар має кнопки, які керують поведінкою шару під час роботи.
Структура даних
Наступна структура даних є прикладом виводу, який має бути присутнім у вашій композиції під ключем виводу структури `tvOut_ControlRepresentations`:
{
"tvOut_ControlRepresentations": [
{
"title": "Compact Cut's",
"buttons": [
{
"actions": [
{
"layerId": "03627C25-CC8A-474F-A738-C4DEB3353FA4",
"variantId": "F6F52194-06DE-462E-983A-8D505C533A69",
"type": "signal",
"signalKey": "tvGroup_Control__Cut_1_TypeSignal",
"signalName": "Cut 1"
}
],
"liveState": {
"layerId": "03627C25-CC8A-474F-A738-C4DEB3353FA4",
"variantId": "F6F52194-06DE-462E-983A-8D505C533A69",
"dynamicSourceId": "tvIn_VideoSourceAImage"
},
"sourcePreview": {
"layerId": "03627C25-CC8A-474F-A738-C4DEB3353FA4",
"variantId": "F6F52194-06DE-462E-983A-8D505C533A69",
"dynamicSourceId": "tvIn_VideoSourceAImage"
},
"color": "#BBBBBB",
"width": 1,
"height": 1,
"x": 0,
"y": 0,
"icon": "facetime-video",
"dynamicText": {
"template": "{{inputputValues.tvIn_VideoSourceAName}}",
"layerId": "03627C25-CC8A-474F-A738-C4DEB3353FA4",
"variantId": "F6F52194-06DE-462E-983A-8D505C533A69"
}
}
]
}
]
}
Пресет має "заголовок" і масив "кнопок", але можна обійтися і однією кнопкою.
Ключі `layerId` та `variantId` потрібно динамічно заповнювати рядковими даними з ключів введення композиції `tvIn_LayerIdentifier` та `tvIn_RuntimeIdentifier`.
Використання попереднього налаштування пульта дистанційного керування API у Quartz Composer
Вбудовані шари mimoLive використовують LUA щоб динамічно згенерувати цю структуру даних, оскільки Quartz Composer не підтримує створення структур даних самостійно. Для цього слід скористатися скриптом LUA містить складну функцію addButton(), за допомогою якої можна створити структуру для однієї кнопки. Зазвичай ви можете просто використовувати цю функцію, не змінюючи її. Таким чином, досить легко створити нові налаштування пульта дистанційного керування за замовчуванням для вашого власного шару.
Наприклад, це LUA скрипт для генерації пультів дистанційного керування для шару секундоміра. Зверніть увагу, що ви можете адаптувати цей код, просто змінивши рядки з 15 по 29.
inLayerIdentifier = QC_STRING
inVariantIdentifier = QC_STRING
outControlRepresentations = QC_STRUCT
main = function()
controlRepresentations = {}
-- first representation
controlRepresenation = {}
-- {
controlRepresenation["Title"] = "Stop Watch"
buttons = {}
-- {
-- addButton(buttonsTable, buttonTitle, subTitle, positionX, positionY, width, height, color, icon, actionTarget, liveStateSource, previewSource)
-- first row
addButton(buttons, "{{outputValues.tvOut_TimeString}}", "", 0, 0, 2, 1, "#333333", "", "", "", "")
addButton(buttons, "Live", "{\{name\}}", 2, 0, 1, 1, "#333333", "", "toggleLive", "layerVariant", "")
-- second row
addButton(buttons, "Start", "", 0, 1, 1, 1, "#33cc33", "play", "tvGroup_Control__Start_TypeSignal", "", "")
addButton(buttons, "Stop", "", 1, 1, 1, 1, "#cc3333", "pause", "tvGroup_Control__Stop_TypeSignal", "", "")
addButton(buttons, "Reset", "", 2, 1, 1, 1, "#cccc33", "stop", "tvGroup_Control__Reset_TypeSignal", "", "")
-- }
controlRepresenation["buttons"] = buttons
-- }
table.insert(controlRepresentations , controlRepresenation)
outControlRepresentations = controlRepresentations
end
function addButton(buttonsTable, buttonTitle, buttonSubTitle, positionX, positionY, width, height, color, icon, actionTarget, liveStateSource, previewSource)
local button = {}
-- {
if #buttonTitle > 0 then
if string.find(buttonTitle, "{{") then
-- dynamic titel
local dynamicText = {}
-- {
dynamicText["layerId"] = inLayerIdentifier
dynamicText["variantId"] = inVariantIdentifier
dynamicText["template"] = buttonTitle
-- }
button["dynamicText"] = dynamicText
else
-- static title
button["text"] = buttonTitle
end -- if dynamic
end -- if buttonTitle
if #buttonSubTitle > 0 then
if string.find(buttonSubTitle, "{{") then
-- dynamic titel
local dynamicSubText = {}
-- {
dynamicSubText["layerId"] = inLayerIdentifier
dynamicSubText["variantId"] = inVariantIdentifier
dynamicSubText["template"] = buttonSubTitle
-- }
button["dynamicSubText"] = dynamicSubText
else
-- static title
button["subtext"] = buttonSubTitle
end -- if dynamic
end -- if buttonSubTitle
button["x"] = positionX
button["y"] = positionY
button["width"] = width
button["height"] = height
if #color > 0 then
button["color"] = color
end -- if
if #actionTarget > 0 then
local actions = {}
-- {
local action = {}
-- {
action["layerId"] = inLayerIdentifier
action["variantId"] = inVariantIdentifier
if string.ends(actionTarget, "_TypeSignal") then
action["type"] = "signal"
action["signalKey"] = actionTarget
action["signalName"] = buttonTitle
elseif actionTarget == "toggleLive" then
action["type"] = "toggleLive"
else
action["type"] = "toggleSwitch"
action["toggleSwitchKey"] = actionTarget
action["toggleSwitchName"] = buttonTitle
end -- if
-- }
table.insert(actions , action)
-- }
button["actions"] = actions
end -- if actionTarget
if #liveStateSource > 0 then
local liveState = {}
-- {
liveState["layerId"] = inLayerIdentifier
liveState["variantId"] = inVariantIdentifier
if string.starts(liveStateSource,"tvIn_VideoSource") then
-- get the live state from a dynamic video source
liveState["dynamicSourceId"] = liveStateSource
elseif liveStateSource == "layerVariant" then
-- nor more information needed
else
liveState["propertyPath"] = liveStateSource end -- if
-- }
button["liveState"] = liveState
end -- if liveState Source
if #previewSource > 0 then
local sourcePreview = {}
-- {
sourcePreview["layerId"] = inLayerIdentifier
sourcePreview["variantId"] = inVariantIdentifier
sourcePreview["dynamicSourceId"] = previewSource
-- }
button["sourcePreview"] = sourcePreview
end -- if
if #icon > 0 then
-- See bottom of documentation page for list of avaiable icon names
button["icon"] = icon
end -- if
-- }
table.insert(buttonsTable, button)
end -- func
function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start
end
function string.ends(String,End)
return End=='' or string.sub(String,-string.len(End))==End
end
Позиціонування Button
При використанні декількох кнопок, розташуванням кнопок доводиться керувати вручну. Це означає, що кнопки позиціонуються на сітці за допомогою атрибутів "x" і "y", які, так само як і атрибути "width" і "height", задаються в кратних клітинках сітки. Позиції вказано відносно верхньої лівої комірки сітки, до якої було перетягнуто групу кнопок.
Button Дії
Buttons може мати декілька дій, одну дію або взагалі не мати жодної. Існують різні допустимі комбінації цілей дій та типів дій.
Зверніть увагу, що дії "textInput" та "numericInput" мають бути окремими, оскільки послідовна робота користувача з пультом дистанційного керування не гарантується.
Цілі дій
Цілі дій - це елементи всередині документа mimoLive. Вони адресуються в ієрархічному порядку:
"Ідентифікатор документа" завжди створюється під час виконання, тому він не повинен бути присутнім у попередньому налаштуванні.
- Якщо не вказано ні "layerId", ні "variantId", дію буде застосовано до самого документа.
- Якщо задано "layerId", дія буде виконана на вказаному шарі.
- Якщо "layerId" і "variantId", дія спрацює на вказаному варіанті. Тільки в цьому випадку можна вказати додатково "toggleSwitchKey" або "signalKey" (див. Типи дій нижче).
Типи дій
Тип дії | Пояснення | Додаткові атрибути | Дійсні цілі |
---|---|---|---|
toggleLive | Переключити стан в реальному часі | ні | Документ (Початок/зупинка показу), Шар, Варіант |
setLive | Встановіть стан "живий" на "живий" | ні | Документ (Початок показу), Шар, Варіант |
setOff | Встановіть стан "живий" на "вимкнено" | ні | Документ (Зупинити показ), Шар, Варіант |
сигнал | Запустити сигнал | signalKey, signalName (рекомендовано) | Варіант |
toggleSwitch | Перемикання логічного вхідного значення | toggleSwitchKey, toggleSwitchName (рекомендовано) | Варіант |
textInput | Відкриває текстове поле введення, яке після надсилання оновлює значення на inputKey. | inputKey, inputName (рекомендовано) | Шар, Варіант, Джерело |
numericInput | Повзунок, який керує числовим значенням на inputKey. | inputKey, inputDescription (об'єкт з мінімальним та максимальним значенням), inputName (рекомендовано) | Шар, Варіант, Джерело |
Типи дій "textInput" та "numericInput" доступні починаючи з mimoLive 5.2.
Button Live State
Об'єкт "liveState" можна використовувати для налаштування стану індикатора підрахунку, який може бути увімкненим (червоне підсвічування), перехідним (жовте підсвічування) або вимкненим (без підсвічування).
Живі державні джерела
Подібно до цілей дії кнопки, стан в реальному часі можна отримати з декількох джерел:
- "Ідентифікатор документа" завжди створюється під час виконання, тому він не повинен бути присутнім у попередньому налаштуванні.
- Якщо не вказано ні "layerId", ні "variantId", використовується поточний стан документа (показ розпочато чи ні).
- Якщо задано "layerId", використовується поточний стан шару.
- Якщо вказано "layerId" та "variantId", використовується поточний стан варіанту.
- Тільки в цьому випадку можна вказати додатковий параметр "propertyPath", щоб вказати, що має бути використана булева властивість на вхідних або вихідних значеннях варіанта.
- Інша можливість (взаємовиключна з propertyPath!) - вказати властивість "dynamicSourceId", яка перенаправляє пошук стану в реальному часі на джерело (отримане за ID), що враховує динамічні зміни вибраного джерела (наприклад, у відеокомутаторі). Значення "dynamicSourceId" шукається у вхідних значеннях варіанта.
Вкажіть повний шлях до властивості, починаючи з варіанту як кореневого, наприклад, "inputValues.some_Boolean_Property" або "outputValues.other_Property".
- Якщо вказано "sourceId", використовується поточний стан джерела.
Button Text
Кнопки дій можуть відображати основні та додаткові рядки тексту, обидва можуть бути статичними або динамічними.
Основний текст
Цей текст буде основним індикатором того, що кнопка буде робити для користувача. Якщо пресет кнопки містить властивість text, це буде статичний текст, який буде показано як є.
Крім того, можна вказати динамічний текст (dynamicText), який уможливлює включення властивостей шару або варіанта mimoLive за допомогою простого синтаксису шаблону. У рядку шаблону звичайні символи можна комбінувати зі шляхами до властивостей, укладеними у фігурні дужки:
"template": "{\{propertyPath\}}"
Шляхи властивостей оцінюються відносно об'єкта, який розпізнається за допомогою "layerId", "variantId", "sourceId" та "filterId". Розв'язування об'єктів відбувається за цими правилами:
- "Ідентифікатор документа" завжди створюється під час виконання, тому він не повинен бути присутнім у попередньому налаштуванні.
- Якщо не вказано ні "layerId", ні "variantId", шляхи властивостей оцінюються відносно документа
- Якщо вказано "layerId" (і необов'язково "variantId"), шляхи властивостей обчислюються відносно шару/варіанту.
- Доступ до батьківського шару варіанта можна отримати, почавши шлях з "layer", наприклад, "aslayer.name".
Перший сегмент шляху вхідних та вихідних значень має бути у форматі camelCase ("inputValues.tvIn..."), а не kebab-case ("input-values.tvIn..."), як у документах API.
- Статичний текст завжди матиме перевагу над динамічним, оскільки це дозволяє користувачам замінити динамічний текст користувацьким текстом, який може бути більш корисним у їхній ситуації.
Вторинний текст
Щоб надати користувачеві більше інформації про кнопку, наприклад, ім'я її батьківського шару, можна додати додатковий текст за допомогою властивостей "subtext" або "dynamicSubText".
Синтаксис шаблону та роздільна здатність об'єктів відповідають тим самим правилам, що й основний текст.
1TP7Тонний розмір тексту та піктограм
Текст та іконки на кнопках можуть змінюватись за розміром залежно від контексту. За допомогою опції "fontScale" ви можете вказати відносний масштаб до розміру за замовчуванням, розрахований для поточного розміру екрану. "1" буде розміром за замовчуванням. Менше 1 (наприклад, 0.8) зменшить розмір шрифту, а більше 1 (наприклад, 1.5) - збільшить.
Button Попередній перегляд
Кнопки дій можуть відображати зображення попереднього перегляду джерела, яким вони керують, або будь-якого іншого джерела, доступного в документі.
Залежно від того, чи є джерело статичним (лише зображення, які було перетягнуто до mimoLive), статичне ПАПУА-НОВА ГВІНЕЯ завантажується лише один раз, якщо джерело підтримує альфа-канал. Для будь-якого іншого джерела JPEG представлення джерела регулярно оновлюється. Цільова частота оновлення для динамічних джерел - 5 кадрів на секунду, але вона зменшується, коли швидкість мережевого з'єднання виявляється недостатньою для багаторазового завантаження кадрів попереднього перегляду.
Наразі не підтримується відображення результатів роботи програми документа на кнопці дії. Зображення шарів за замовчуванням, хоча їх і не видно у списку джерел, доступні для попереднього перегляду.
Щоб задати попередній перегляд джерела, використовується механізм роздільної здатності об'єктів:
- "Ідентифікатор документа" завжди створюється під час виконання, тому він не повинен бути присутнім у попередньому налаштуванні.
- Якщо вказано "sourceId", для попереднього перегляду буде використано джерело з цим ідентифікатором.
- Якщо вказано всі "layerId", "variantId" і "dynamicSourceId", ідентифікатор джерела буде шукатися у варіанті вказаного шару за ключем у "dynamicSourceId". Це може бути використано для посилання на такі джерела, як джерело A-G відеокомутатора, навіть якщо їх було змінено у документі.
1TP7Тоновий колір
Використовуючи атрибут "color", кнопки можна забарвити будь-яким кодом кольору, який можна представити в HTML (наприклад, "#f80", "#ff0088", "orange" або "rgb(255, 66, 88)").
Button Icon
1TP7Тони можуть відображати піктограму для позначення їхньої функціональності. Щоб переглянути список усіх доступних піктограм, відкрийте http://localhost:8989/icons/demo.html під час роботи mimoLive та увімкненого пульта дистанційного керування.
Використовуйте просту назву піктограми, наприклад, "назад" або "стрілка вниз".