BBCode em RichTextLabel

Introdução

Os nós de rótulo são ótimos para exibir texto básico, mas têm limites. Se você quiser alterar a cor do texto ou seu alinhamento, essa alteração afetará todo o texto no nó Label. Você não pode ter apenas uma parte do texto com uma cor ou apenas uma parte do texto centralizada. Para contornar essa limitação, você usaria um RichTextLabel.

RichTextLabel permite a exibição de marcações de texto complexas em um Control. Ele possui uma API embutida para gerar a marcação, mas também pode analisar um BBCode.

Observe que as tags BBCode também podem ser usadas, até certo ponto, na fonte XML da referência de classe.

Usando BBCode

Para texto formatado uniformemente, você pode escrever na propriedade "Texto", mas se quiser usar a marcação BBCode, deve usar a propriedade "Texto" na seção "Bb Code" (bbcode_text). Gravar nessa propriedade acionará a análise de sua marcação para formatar o texto conforme solicitado. Antes que isso aconteça, você precisa alternar a caixa de seleção "Enabled" na seção "Bb Code" (bbcode_enabled).

../../_images/bbcodeText.png

Por exemplo, BBCode [color=blue]azul[/color] renderizaria a palavra "azul" com uma cor azul.

../../_images/bbcodeDemo.png

Você notará que depois de escrever na propriedade "Texto" do BBCode, a propriedade "Texto" normal agora tem o texto sem o BBCode. Embora a propriedade text seja atualizada pela propriedade BBCode, você não pode editar a propriedade text ou perderá a marcação BBCode. Todas as alterações no texto devem ser feitas no parâmetro BBCode.

Nota

Para que tags BBCode como [b] (negrito), [i] (itálico) ou [code] funcionem, primeiro você deve configurar fontes personalizadas para o nó RichTextLabel.

Ainda não há tags BBCode para controlar a centralização vertical do texto.

Referência

Comando

Etiqueta

Descrição

negrito

[b]{text}[/b]

Torna {text} negrito.

itálico

[i]{text}[/i]

Coloca {text} em itálico.

sublinhado

[u]{text}[/u]

Torna {texto} sublinhado.

riscado

[s]{text}[/s]

Torna {text} riscado.

código

[code]{text}[/code]

Faz com que {text} use a fonte do código (que normalmente é monoespaçada).

centralizado

[center]{text}[/center]

Faz com que {text} seja centralizado horizontalmente.

direita

[right]{text}[/right]

Faz com que {text} seja alinhado horizontalmente à direita.

preencher

[fill]{text}[/fill]

Faz com que {text} preencha a largura do RichTextLabel.

recuo

[indent]{text}[/indent]

Aumenta o nível de recuo de {text}.

url

[url]{url}[/url]

Mostre {url} como tal, sublinhe-o e torne-o clicável. Deve ser tratado com o sinal "meta_clicked" para ter efeito. Veja Lidando com cliques de tags [url].

url (ref)

[url=<url>]{text}[/url]

Faz {text} ser um link para <url> (sublinhado e clicável). Deve ser tratado com o sinal "meta_clicked" para ter efeito. Veja Lidando com cliques de tags [url].

imagem

[img]{caminho}[/img]

Insira a imagem no recurso {caminho}.

imagem redimensionada

[img=<width>]{caminho}[/img]

Insira a imagem no recurso {caminho} usando <width> (mantém a proporção).

imagem redimensionada

[img=<largura>x<altura>]{caminho}[/img]

Insira a imagem no recurso {caminho} usando <largura>×<height>.

fonte

[font=<caminho>]{texto}[/font]

Use fonte personalizada em <caminho> para {text}.

cor

[color=<código/nome>]{texto}[/color]

Mude a cor do {texto}; use o nome ou o formato #, como #ff00ff.

tabela

[table=<number>]{cells}[/table]

Cria uma tabela com <number> colunas.

célula

[cell]{texto}[/cell]

Adiciona células com o {texto} à tabela.

Nomes de cores embutidas

Lista de nomes de cores válidos para a tag [color=<name>]:

  • aqua

  • black

  • blue

  • fuchsia

  • gray

  • green

  • lime

  • maroon

  • navy

  • purple

  • red

  • silver

  • teal

  • white

  • yellow

Códigos de cores hexadecimais

Para cores RGB opacas, qualquer código hexadecimal válido de 6 dígitos é suportado, por ex. [color=#ffffff]branco[/color]. Códigos de cores RGB curtos como #6f2 (equivalente a #66ff22) também são suportados.

For transparent RGB colors, any 8-digit hexadecimal code can be used, e.g. [color=#88ffffff]translucent white[/color]. In this case, note that the alpha channel is the first component of the color code, not the last one. Short RGBA color codes such as #86f2 (equivalent to #8866ff22) are also supported.

Lidando com cliques de tags [url]

Por padrão, as tags [url] não fazem nada quando clicadas. Isso é para permitir o uso flexível de tags [url] em vez de limitá-los a abrir URLs em um navegador da web.

Para lidar com tags [url] clicadas, conecte o sinal meta_clicked do nó RichTextLabel a uma função de script.

Por exemplo, o seguinte método pode ser conectado a meta_clicked para abrir URLs clicados usando o navegador padrão do usuário:

# This assumes RichTextLabel's `meta_clicked` signal was connected to
# the function below using the signal connection dialog.
func _richtextlabel_on_meta_clicked(meta):
    # `meta` is not guaranteed to be a String, so convert it to a String
    # to avoid script errors at run-time.
    OS.shell_open(str(meta))

Para casos de uso mais avançados, também é possível armazenar JSON em uma opção de tag [url] e analisá-lo na função que trata o sinal meta_clicked. Por exemplo: [url={"exemplo": "valor"}]JSON[/url]

Deslocamento vertical da imagem

Use uma fonte personalizada para sua imagem para alinhá-la verticalmente.

  1. Criar um recurso ``BitmapFont`

  2. Defina esta fonte de bitmap com um valor positivo para a propriedade ascent, esse é o seu deslocamento de altura

  3. Defina a tag BBCode desta forma: [font=<caminho-da-fonte>][img]{caminho-da-imagem}[/img][/font]

Efeitos de animação

BBCode também pode ser usado para criar diferentes efeitos de animação de texto. Cinco efeitos personalizáveis são fornecidos por padrão, e você pode facilmente criar o seu próprio.

Onda

../../_images/wave.png

A Onda faz o texto subir e descer. Seu formato de tag é [wave amp=50 freq=2][/wave]. amp controla quão alto e baixo o efeito vai, e freq controla quão rápido o texto sobe e desce.

Tornado

../../_images/tornado.png

Tornao faz o texto se mover em um círculo. Seu formato de tag é [tornado radius=5 freq=2][/tornado]. radius é o raio do círculo que controla o deslocamento, freq é a velocidade com que o texto se move em um círculo.

Tremendo

../../_images/shake.png

Shake faz o texto tremer. Seu formato de tag é [shake rate=5 level=10][/shake]. rate controla a rapidez com que o texto treme, level controla o quanto o texto é deslocado da origem.

Desaparecer

../../_images/fade.png

Fade cria um efeito de fade sobre o texto que não é animado. Seu formato de tag é [fade start=4 length=14][/fade]. start controla a posição inicial do falloff em relação a onde o comando fade é inserido, length controla em quantos caracteres o desaparecer gradualmente deve ocorrer.

Arco-íris

../../_images/rainbow.png

Arco-íris dá ao texto uma cor de arco-íris que muda com o tempo. Seu formato de tag é [rainbow freq=0.2 sat=10 val=20][/rainbow]. freq é o número de ciclos de arco-íris completos por segundo, sat é a saturação do arco-íris, val é o valor do arco-íris.

Tags BBCode personalizadas e efeitos de texto

You can extend the RichTextEffect resource type to create your own custom BBCode tags. You begin by extending the RichTextEffect resource type. Add the tool prefix to your GDScript file if you wish to have these custom effects run within the editor itself. The RichTextLabel does not need to have a script attached, nor does it need to be running in tool mode. The new effect will be activable in the Inspector through the Custom Effects property.

Aviso

If the custom effect is not registered within the RichTextLabel's Custom Effects property, no effect will be visible and the original tag will be left as-is.

There is only one function that you need to extend: _process_custom_fx(char_fx). Optionally, you can also provide a custom BBCode identifier simply by adding a member name bbcode. The code will check the bbcode property automatically or will use the name of the file to determine what the BBCode tag should be.

_process_custom_fx

This is where the logic of each effect takes place and is called once per character during the draw phase of text rendering. This passes in a CharFXTransform object, which holds a few variables to control how the associated character is rendered:

  • identity specifies which custom effect is being processed. You should use that for code flow control.

  • relative_index tells you how far into a given custom effect block you are in as an index.

  • absolute_index tells you how far into the entire text you are as an index.

  • elapsed_time is the total amount of time the text effect has been running.

  • visible will tell you whether the character is visible or not and will also allow you to hide a given portion of text.

  • offset is an offset position relative to where the given character should render under normal circumstances.

  • color is the color of a given character.

  • Finally, env is a Dictionary of parameters assigned to a given custom effect. You can use get() with an optional default value to retrieve each parameter, if specified by the user. For example [custom_fx spread=0.5 color=#FFFF00]test[/custom_fx] would have a float spread and Color color parameters in its ` env` Dictionary. See below for more usage examples.

The last thing to note about this function is that it is necessary to return a boolean true value to verify that the effect processed correctly. This way, if there's a problem with rendering a given character, it will back out of rendering custom effects entirely until the user fixes whatever error cropped up in their custom effect logic.

Aqui estão alguns exemplos de efeitos personalizados:

Fantasma

tool
extends RichTextEffect
class_name RichTextGhost

# Syntax: [ghost freq=5.0 span=10.0][/ghost]

# Define the tag name.
var bbcode = "ghost"

func _process_custom_fx(char_fx):
    # Get parameters, or use the provided default value if missing.
    var speed = char_fx.env.get("freq", 5.0)
    var span = char_fx.env.get("span", 10.0)

    var alpha = sin(char_fx.elapsed_time * speed + (char_fx.absolute_index / span)) * 0.5 + 0.5
    char_fx.color.a = alpha
    return true

Pulso

tool
extends RichTextEffect
class_name RichTextPulse

# Syntax: [pulse color=#00FFAA height=0.0 freq=2.0][/pulse]

# Define the tag name.
var bbcode = "pulse"

func _process_custom_fx(char_fx):
    # Get parameters, or use the provided default value if missing.
    var color = char_fx.env.get("color", char_fx.color)
    var height = char_fx.env.get("height", 0.0)
    var freq = char_fx.env.get("freq", 2.0)

    var sined_time = (sin(char_fx.elapsed_time * freq) + 1.0) / 2.0
    var y_off = sined_time * height
    color.a = 1.0
    char_fx.color = char_fx.color.linear_interpolate(color, sined_time)
    char_fx.offset = Vector2(0, -1) * y_off
    return true

Matriz

tool
extends RichTextEffect
class_name RichTextMatrix

# Syntax: [matrix clean=2.0 dirty=1.0 span=50][/matrix]

# Define the tag name.
var bbcode = "matrix"

func _process_custom_fx(char_fx):
    # Get parameters, or use the provided default value if missing.
    var clear_time = char_fx.env.get("clean", 2.0)
    var dirty_time = char_fx.env.get("dirty", 1.0)
    var text_span = char_fx.env.get("span", 50)

    var value = char_fx.character

    var matrix_time = fmod(char_fx.elapsed_time + (char_fx.absolute_index / float(text_span)), \
                           clear_time + dirty_time)

    matrix_time = 0.0 if matrix_time < clear_time else \
                  (matrix_time - clear_time) / dirty_time

    if value >= 65 && value < 126 && matrix_time > 0.0:
        value -= 65
        value = value + int(1 * matrix_time * (126 - 65))
        value %= (126 - 65)
        value += 65
    char_fx.character = value
    return true

Isso adicionará alguns novos comandos BBCode, que podem ser usados assim:

[center][ghost]This is a custom [matrix]effect[/matrix][/ghost] made in
[pulse freq=5.0 height=2.0][pulse color=#00FFAA freq=2.0]GDScript[/pulse][/pulse].[/center]