O Studio dá a você a possibilidade de criar widgets personalizados e usá-los como ferramentas e extensões do Studio. Esses widgets funcionam como janelas/painéis personalizados no Studio e você pode incorporá-los na sua interface ou deixá-los flutuando como janelas separadas.
Criação de UIs do Widget
Todos os widgets do Studio começam como objetos Class. DockWidgetPluginGui que você pode preencher com Class. GuiObject|GuiObjects, como etiquetas textuais e botões. Para criar uma interface gráfica do Widget vazia, use a função Class. Plugin:CreateDockWidgetPluginGui()|CreateDockWidgetPluginGui(), passando em uma ID e um objeto Datatype.
Observe que o Datatype. DockWidgetPluginGuiInfo.new() construtor espera seus parâmetros em uma ordem específica, da seguinte forma:
# | Propriedade | Tipo | Descrição |
---|---|---|---|
1 | Enum. InitialDockState | Enumeração | Uma das enumerações Enum. InitialDockState. |
2 | InitialEnabled | Booleano | O estado habilitado (visível) inicial da interface gráfica do widget. |
3 | InitialEnabledShouldOverrideRestore | Booleano | Se for verdadeiro, o valor de InitialEnabled substitui o estado habilitado salvo anteriormente. |
4 | FloatingXSize | Inteiro | A largura inicial da interface gráfica quando InitialDockState está definido como Enum. InitialDockState. Float. |
5 | FloatingYSize | Inteiro | A altura inicial da interface gráfica quando InitialDockState está definido como Enum. InitialDockState. Float. |
6 | MinWidth | Inteiro | A largura mínima da interface gráfica com algumas variações específicas da plataforma. |
7 | MinHeight | Inteiro | A altura mínima da interface gráfica com algumas variações específicas da plataforma. |
-- Create new "DockWidgetPluginGuiInfo" objectlocal widgetInfo = DockWidgetPluginGuiInfo.new(Enum. InitialDockState. Float, -- Widget will be initialized in floating paneltrue, -- Widget will be initially enabledfalse, -- Don't override the previous enabled state200, -- Default width of the floating window300, -- Default height of the floating window150, -- Minimum width of the floating window150 -- Minimum height of the floating window)-- Create new widget GUIlocal testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget. Title = "Test Widget" -- Optional widget title
Personalização da UI do Widget
Depois de criar o Widget, você pode personalizar a interface do usuário com Class. GuiObject|GuiObjects, como Class. TextLabel|TextLabels informativo ou Class. ImageButton|ImageButtons interativo. Por exemplo, o seguinte código adiciona uma Class. TextButton básica à janela da interface gráfica:
-- Create new widget GUIlocal testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget. Title = "Test Widget" -- Optional widget titlelocal testButton = Instance.new("TextButton")testButton. BorderSizePixel = 0testButton. TextSize = 20testButton. TextColor3 = Color3.new(1,0.2,0.4)testButton. AnchorPoint = Vector2.new(0.5,0.5)testButton. Size = UDim2.new(1,0,1,0)testButton. Position = UDim2.new(0.5,0,0.5,0)testButton. SizeConstraint = Enum. SizeConstraint. RelativeYYtestButton. Text = "Click Me"testButton. Parent = testWidget
Alteração de temas de cor do Studio
Os widgets do Studio eficazes normalmente combinam com a configuração do tema do Studio e se ajustam dinamicamente quando o tema é alterado. Por exemplo, se um desenvolvedor estiver usando um tema escuro, a cor de fundo do widget, as imagens e as etiquetas textuais devem ser agradáveis junto com as cores temáticas padrão do Studio.
A seguinte adição de código usa uma função syncGuiColors() que inicialmente é usada junto com uma tabela de objetos de interface gráfica para sincronizar. Dentro da função, uma função setColors() aninhada faz o ciclo sucessivo de objetos e sincroniza aspectos específicos deles usando Class. StudioTheme:GetColor()|GetColor() com enumerações Enum. StudioStyleGuideColor. Essa função setColors() é imediatamente executada para sincronizar o tema do Studio, então ela é conectada ao evento Class. Studio. ThemeChanged|ThemeChanged para detectar futuras alterações de tema.
testButton. Parent = testWidget
local function syncGuiColors(objects)
local function setColors()
for _, guiObject in pairs(objects) do
-- Sync background color
guiObject. BackgroundColor3 = settings(). Studio. Theme:GetColor(Enum. StudioStyleGuideColor. MainBackground)
-- Sync text color
guiObject. TextColor3 = settings(). Studio. Theme:GetColor(Enum. StudioStyleGuideColor. MainText)
end
end
-- Run 'setColors()' function to initially sync colors
setColors()
-- Connect 'ThemeChanged' event to the 'setColors()' function
settings(). Studio. ThemeChanged:Connect(setColors)
end
-- Run 'syncGuiColors()' function to sync colors of provided objects
syncGuiColors({testButton})
Personalização de cursores de mouse
Para melhorar a interação esperada com elementos widget, você pode definir cursores de mouse específicos do sistema para eventos de interface gráfica, como Class. GuiObject. MouseEnter|MouseEnter e Class. GuiObject. MouseLeave|MouseLeave. O seguinte código demonstra como conectar uma função aos eventos Class. GuiObject. MouseEnter|MouseEnter e Class. GuiObject. MouseLeave|MouseLeave do testButton para alterar o cursor de mouse:
local function setCursor(cursorAsset)
plugin:GetMouse(). Icon = cursorAsset
end
testButton. MouseEnter:Connect(function()
setCursor("rbxasset://SystemCursors/PointingHand")
end)
testButton. MouseLeave:Connect(function()
setCursor("")
end)
Consulte a tabela a seguir para uma lista de cursores de mouse e seus casos potenciais de uso:
Ícone do cursor de mouse | Ativo | Caso de uso |
---|---|---|
rbxasset://SystemCursors/Arrow | Clique e seleção padrão. | |
rbxasset://SystemCursors/PointingHand | Passar o mouse sobre um link/botão ativo. | |
rbxasset://SystemCursors/OpenHand | Passar o mouse sobre um item arrastável. | |
rbxasset://SystemCursors/ClosedHand | Arrastar um item. | |
rbxasset://SystemCursors/IBeam | Passar o mouse sobre o campo de texto. | |
rbxasset://SystemCursors/SizeNS | Passar o mouse sobre um manipulador de redimensionamento vertical. | |
rbxasset://SystemCursors/SizeEW | Passar o mouse sobre um manipulador de redimensionamento horizontal. | |
rbxasset://SystemCursors/SizeNESW | Passar o mouse sobre um manipulador de redimensionamento de canto. | |
rbxasset://SystemCursors/SizeNWSE | Passar o mouse sobre um manipulador de redimensionamento de canto. | |
rbxasset://SystemCursors/SizeAll | Passar o mouse sobre um manipulador de redimensionamento multi-direções. | |
rbxasset://SystemCursors/SplitNS | Passar o mouse sobre um manipulador vertical de "divisão". | |
rbxasset://SystemCursors/SplitEW | Passar o mouse sobre um manipulador horizontal de "divisão". | |
rbxasset://SystemCursors/Forbidden | Passar o mouse sobre um item bloqueado/proibido. | |
rbxasset://SystemCursors/Wait | Indicar uma ação em andamento. | |
rbxasset://SystemCursors/Busy | Indicar que o sistema está ocupado. | |
rbxasset://SystemCursors/Cross | Passar o mouse sobre uma área de seleção de identificação. |
Acumular entradas do usuário
Elementos de interface do usuário, como TextBox e TextButton funcionam normalmente em widgets do Studio e você pode construir interfaces normalmente na Roblox. No entanto, Class. UserInputService e Class. ContextActionService não funcionam, já que esses serviços esperam que a janela de jogo principal esteja em foco.
Uma solução alternativa para eventos de entrada genéricos é criar um Class. Frame transparente e sobrepôr sobre a tela inteira. O exemplo de código a seguir cria um quadro e quando o usuário clicar no quadro, o evento Class. GuiObject. InputBegan captura a entrada do teclado no quadro até o usuário clicar fora:
local frame = Instance.new("Frame")
frame. BackgroundTransparency = 1 -- Hide the frame
frame. Size = UDim2.new(1, 0, 1, 0) -- Cover the screen
frame. Position = UDim2.new(0, 0, 0, 0)
frame. Parent = testWidget
local function onInputBegan(inputObject)
-- Process the input object here, for example detect key presses
end
frame. InputBegan:Connect(onInputBegan)
Interação de arrastar e soltar
Usar interações de arrastar e soltar para os seus widgets é uma maneira simples de melhorar o fluxo de dados. Para criar essa interação, você deve definir o elemento para arrastar, iniciar o arrastar, criar um alvo para soltar e processar a ação de soltar.
Criar uma fonte de arrasto
Você pode iniciar uma ação de arrastar chamando Class. Plugin:StartDrag()quando o usuário pressionar um botão do mouse em algum elemento da interface de usuário, normalmente um Class. TextButtonou Class. ImageButtondentro de um widget. O exemplo de código a seguir cria um único widget de janela com um botão de texto dentro dele.
-- Create the widget firstlocal widgetInfo = DockWidgetPluginGuiInfo.new(Enum. InitialDockState. Float, true, true, 300, 200)local dragSourceWidget = plugin:CreateDockWidgetPluginGui("Drag Source", widgetInfo)dragSourceWidget. Title = "Drag Source"-- Create a TextButton that will initiate the draglocal dragButton = Instance.new("TextButton")dragButton. Size = UDim2.new(1, 0, 1, 0)dragButton. Text = "Drag me!"dragButton. Parent = dragSourceWidget
Iniciar o arrastar
Quando o usuário clica em Class. TextButton, você pode iniciar o arrastar por meio do evento Class. GuiButton. MouseButton1Down|MouseButton1Down() que é disparado assim que o usuário pressionar o botão do mouse.
Dentro da função conectada, determine os dados para arrastar. O tipo de dado deve ser refletivo na chave MimeType, o conteúdo do arrastar deve ser refletido na Data chave e o remetente deve se descrever na chave Sender. Consulte a página Class. Plugin:StartDrag() para mais detalhes.
local function onButton1Down()
local dragInfo = {
Data = "Hello, world", -- The data being dragged
MimeType = "text/plain", -- Describes the MIME type of the data
Sender = "SomeDragSource", -- Describes from where the data originated
MouseIcon = "", -- Image content to use for the cursor
DragIcon = "", -- Image content to render under the cursor during drag
HotSpot = Vector2.new(0, 0) -- Where on the DragIcon to center the cursor
}
plugin:StartDrag(dragInfo)
end
dragButton. MouseButton1Down:Connect(onButton1Down)
Criar um alvo de suspensão
O evento Class. PluginGui. PluginDragDropped é acionado quando o usuário libera o mouse em uma janela durante o arrastar. Quando isso acontece, você precisa definir um alvo de suspensão, como um segundo widget com um Class. TextLabel para detectar suspensões.
local dragTargetWidget = plugin:CreateDockWidgetPluginGui("Drop Target", widgetInfo)dragTargetWidget. Title = "Drop Target"-- This TextLabel will display what was droppedlocal textLabel = Instance.new("TextLabel")textLabel. Size = UDim2.new(1, 0, 1, 0)textLabel. Text = "Drop here..."textLabel. Parent = dragTargetWidget
Processamento da ação de suspensão
Depois de criar um alvo de suspensão, conecte o evento Class. PluginGui. PluginDragDropped com o widget do alvo de suspensão:
local function onDragDrop(dragData)
print("PluginDragDropped")
if dragData. MimeType == "text/plain" then
textLabel. Text = dragData. Data
else
textLabel. Text = dragData. MimeType
end
end
dragTargetWidget. PluginDragDropped:Connect(onDragDrop)
Enquanto o arrastar estiver em andamento, esses três eventos são acionados conforme o usuário movimenta o mouse sobre o widget:
- Class. PluginGui. PluginDragEntered|PluginDragEntered– é acionado quando o usuário passa o mouse sobre uma janela
- Class. PluginGui. PluginDragMoved|PluginDragMoved– é acionado repetidamente conforme o usuário movimenta o mouse sobre uma janela. Isso é útil para exibir uma mensagem "Solte aqui!" .
- Class. PluginGui. PluginDragLeft|PluginDragLeft– é acionado quando o cursor do usuário sair de uma janela. Isso é útil para ocultar uma mensagem de "Solte aqui!" .