Se estiver a criar uma camada personalizada, existe a possibilidade de incluir predefinições de controlo personalizadas na sua camada. Isto é útil se a sua camada tiver botões de pressão que controlam o comportamento da sua camada quando está ativa.
Estrutura de dados
A estrutura de dados seguinte é um exemplo de saída que tem de estar presente na composição, sob a chave de saída da estrutura `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"
}
}
]
}
]
}
Uma predefinição tem um "título" e um conjunto de "botões", mas um único botão também é aceitável.
As chaves `layerId` e `variantId` têm de ser preenchidas dinamicamente com os dados de cadeia das chaves de entrada de composição `tvIn_LayerIdentifier` e `tvIn_RuntimeIdentifier`.
Utilizar a predefinição do controlo remoto API em Quartz Composer
As camadas de construção do mimoLive estão a utilizar um LUA para gerar dinamicamente esta estrutura de dados porque o Quartz Composer não suporta a geração de estruturas de dados por si só. O LUA O script contém uma função complexa addButton() que pode ser utilizada para criar a estrutura de um único botão. Normalmente, basta utilizar esta função e não é necessário modificá-la. Por isso, é muito fácil criar novas predefinições de controlo remoto para a sua própria camada.
Por exemplo, este é o LUA para gerar os controlos remotos para a camada Stop Watch. Tenha em atenção que pode adotar este código alterando apenas as linhas 15 a 29 do código.
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 Posicionamento
Quando se utilizam vários botões, a disposição dos botões tem de ser controlada manualmente. Isto significa que os botões são posicionados na grelha utilizando os atributos "x" e "y", que, tal como os atributos "largura" e "altura", são dados em múltiplos de células da grelha. As posições são relativas à célula superior esquerda da grelha para a qual o grupo de botões foi arrastado.
Button Acções
Buttons podem ter várias acções, uma única ação ou nenhuma. Existem várias combinações válidas de alvos de ação e tipos de ação.
Note que as acções "textInput" e "numericInput" devem ser isoladas, uma vez que não é garantida uma experiência de utilizador consistente no controlo remoto.
Objectivos de ação
Os objectivos de ação são elementos dentro do documento mimoLive. São abordados de forma hierárquica:
O "ID do documento" é sempre desenhado em tempo de execução, pelo que não tem de estar presente na predefinição.
- Se nem "layerId" nem "variantId" forem indicados, a ação será desencadeada no próprio documento.
- Se for indicado "layerId", a ação será desencadeada na camada especificada.
- Se "layerId" e "variantId" são fornecidos, a ação será desencadeada na variante especificada. Apenas neste caso, podem ser especificados os adicionais "toggleSwitchKey" ou "signalKey" (ver Tipos de ação abaixo).
Tipos de ação
Tipo de ação | Explicação | Atributos adicionais | Objectivos válidos |
---|---|---|---|
toggleLive | Alternar estado em direto | nenhum | Documento (Iniciar/Parar exibição), Camada, Variante |
setLive | Definir o estado em direto para "em direto" | nenhum | Documento (Start Show), Camada, Variante |
setOff | Definir o estado ativo para "desligado" | nenhum | Documento (Stop Show), Camada, Variante |
sinal | Acionar um sinal | signalKey, signalName (recomendado) | Variante |
toggleSwitch | Alternar um valor de entrada booleano | toggleSwitchKey, toggleSwitchName (recomendado) | Variante |
textInput | Abre um campo de entrada de texto que, ao ser enviado, actualiza o valor em inputKey. | inputKey, inputName (recomendado) | Camada, Variante, Fonte |
numéricoEntrada | Controlo deslizante que controla um valor numérico em inputKey. | inputKey, inputDescription (objeto com valores mínimos e máximos), inputName (recomendado) | Camada, Variante, Fonte |
Os tipos de ação "textInput" e "numericInput" estão disponíveis desde o mimoLive 5.2.
Button Live State
O objeto "liveState" pode ser utilizado para configurar o estado da luz de contagem do botão, que pode estar ligado (marcação vermelha), em transição (marcação amarela) ou desligado (sem marcação).
Fontes do Estado em direto
À semelhança dos alvos de acções de botão, o estado em direto pode ser obtido a partir de várias fontes:
- O "ID do documento" é sempre desenhado em tempo de execução, pelo que não tem de estar presente na predefinição.
- Se nem "layerId" nem "variantId" forem indicados, é utilizado o estado ativo do documento (a apresentação começou ou não).
- Se for indicado "layerId", é utilizado o estado ativo da camada.
- Se forem indicados "layerId" e "variantId", é utilizado o estado ativo da variante.
- Apenas neste caso, o adicional "propertyPath" pode ser especificado para indicar que deve ser utilizada uma propriedade booleana nos valores de entrada ou de saída da variante.
- Outra possibilidade (mutuamente exclusiva de propertyPath!) é especificar uma propriedade "dynamicSourceId" que redirecciona a pesquisa de estado real para uma fonte (obtida por ID), que respeita as alterações dinâmicas da fonte selecionada (por exemplo, no comutador de vídeo). O valor de "dynamicSourceId" é procurado nos valores de entrada da variante.
Indique o caminho completo para a propriedade, começando na variante como raiz, por exemplo, "inputValues.some_Boolean_Property" ou "outputValues.other_Property".
- Se for indicado "sourceId", é utilizado o estado ativo da fonte.
Button Texto
Os botões de ação podem apresentar linhas de texto primárias e secundárias, podendo ambas ser de natureza estática ou dinâmica.
Texto primário
Este texto será o principal indicador do que o botão fará para o utilizador. Se a predefinição do botão contiver uma propriedade de texto, trata-se de um texto estático que será apresentado tal como está.
Em alternativa, pode ser fornecido um dynamicText que permite a inclusão da camada mimoLive ou propriedades variantes utilizando uma sintaxe de modelo simples. Na cadeia de modelos, os caracteres regulares podem ser combinados com caminhos de propriedades entre parênteses rectos:
"template": "{\{propertyPath\}}"
Os caminhos de propriedade são avaliados relativamente ao objeto que é resolvido utilizando "layerId", "variantId", "sourceId" e "filterId". A resolução de objectivos segue estas regras:
- O "ID do documento" é sempre desenhado em tempo de execução, pelo que não tem de estar presente na predefinição.
- Se nem "layerId" nem "variantId" forem indicados, os caminhos das propriedades são avaliados relativamente ao documento
- Se for dado "layerId" (e opcionalmente "variantId"), os caminhos das propriedades são avaliados relativamente a uma camada/variante.
- É possível aceder à camada-mãe de uma variante iniciando um caminho com "camada", como "aslayer.name".
O primeiro segmento de caminho dos valores de entrada e saída tem de ser em maiúsculas ("inputValues.tvIn...") e não em minúsculas ("input-values.tvIn...") como nos documentos API.
- O texto estático terá sempre precedência sobre o texto dinâmico, porque isto permite aos utilizadores substituir o texto dinâmico por algum texto personalizado que possa ser mais útil na sua situação.
Texto secundário
Para dar ao utilizador mais informações sobre um botão, como o nome da sua camada principal, pode ser fornecido um texto secundário utilizando as propriedades "subtext" ou "dynamicSubText".
A sintaxe do modelo e a resolução de objectos seguem exatamente as mesmas regras que o texto principal.
Button Tamanho do texto e do ícone
O texto e os ícones nos botões podem variar de tamanho consoante o contexto. Com a opção "fontScale", pode especificar uma escala relativa a um tamanho predefinido calculado para o tamanho atual do ecrã. "1" será o tamanho predefinido. Menos de 1 (por exemplo, 0,8) reduzirá o tamanho da fonte e mais de 1 (por exemplo, 1,5) aumentá-lo-á.
Button Pré-visualização
Os botões de ação podem apresentar uma imagem de pré-visualização da fonte que estão a controlar, ou de qualquer outra fonte disponível no documento.
Dependendo do facto de a fonte ser estática (apenas imagens que foram arrastadas para o mimoLive), uma imagem estática PNG da fonte é carregada uma vez que suporta um canal alfa. Para qualquer outra fonte, um JPEG A representação da fonte é actualizada regularmente. A taxa de atualização pretendida para fontes dinâmicas é de 5 fotogramas por segundo, mas esta taxa é reduzida quando a velocidade de ligação à rede é insuficiente para o carregamento repetido de fotogramas de pré-visualização.
Atualmente, não é suportado apresentar a saída do programa do documento num botão de ação. As imagens predefinidas da camada, embora não sejam visíveis na lista de origens, estão disponíveis para pré-visualização.
Para especificar uma pré-visualização de origem, é utilizado um mecanismo de resolução de objectos:
- O "ID do documento" é sempre desenhado em tempo de execução, pelo que não tem de estar presente na predefinição.
- Se for indicado "sourceId", a fonte com esse ID é utilizada para a pré-visualização.
- Se todos os campos "layerId", "variantId" e "dynamicSourceId" forem fornecidos, o ID da fonte será procurado na variante da camada especificada sob a chave em "dynamicSourceId". Isto pode ser utilizado para referenciar fontes como a fonte A-G do comutador de vídeo, mesmo quando estas são alteradas no documento.
Button Cor
Ao utilizar o atributo "color", os botões podem ser coloridos com qualquer código de cor que seja representável em HTML (por exemplo, "#f80", "#ff0088", "orange", ou "rgb(255, 66, 88)").
Button Ícone
Buttons podem exibir um ícone para indicar a sua funcionalidade. Para ver uma lista de todos os ícones disponíveis, abra http://localhost:8989/icons/demo.html enquanto o mimoLive estiver em execução e os controlos remotos estiverem activados.
Utilize o nome simples do ícone, por exemplo, "para trás" ou "seta para baixo".