Capítulo 3. Criando entradas no menu

Ao criar um novo plugin, você precisa informá-lo ao RKWard. Portanto, a primeira coisa a fazer é escrever um arquivo .pluginmap (ou modificar um existente). O formato do .pluginmap é XML. Vou mostrar um exemplo (e, claro, certifique-se de ter configurado o RKWard para carregar seu .pluginmap -- ConfiguraçõesConfigurar RKWardPlugins):

Dica

Após ler este capítulo, dê uma olhada também no pacote rkwarddev. Ele fornece algumas funções R para criar a maioria das tags XML do RKWard para você.

<!DOCTYPE rkpluginmap>
        

O doctype não é realmente interpretado, mas defina-o como "rkpluginmap" mesmo assim.

<document base_prefix="" namespace="meusplugins" id="meupluginmap">
        

O atributo base_prefix pode ser usado se todos os seus plugins estiverem em um diretório comum. Basicamente, você pode omitir esse diretório dos nomes de arquivo especificados abaixo. É seguro deixá-lo como "".

Como você verá abaixo, todos os plugins recebem um identificador único, id. O namespace é uma forma de organizar esses IDs e reduzir a probabilidade de criar identificadores duplicados acidentalmente. Internamente, basicamente o namespace e, em seguida, uma :: são adicionados a todos os identificadores que você especificar neste .pluginmap. Em geral, se você pretende distribuir seus plugins em um pacote R, é uma boa prática usar o nome do pacote como parâmetro namespace. Os plugins distribuídos com a distribuição oficial RKWard têm namespace="rkward".

O atributo id é opcional, mas especificar um id para o seu .pluginmap permite que outras pessoas façam com que seus .pluginmaps carreguem o seu .pluginmap automaticamente (consulte a seção sobre dependências).

<componentes>
        

Componentes? Não estamos falando de plugins? Sim, mas no futuro, os plugins serão apenas uma classe especial de componentes. O que fazemos aqui, então, é registrar todos os componentes/plugins com RKWard. Vejamos um exemplo de entrada:

<component type="standard" id="t_test_duas_vars" file="t_test_duas_vars.xml" label="t-Test com duas variáveis" />
        

Primeiro, o atributo type: Deixe-o com "standard" por enquanto. Outros tipos ainda não foram implementados. O id já foi mencionado. Cada componente precisa de um identificador único (em seu namespace). Escolha um que seja facilmente reconhecível. Evite espaços e caracteres especiais. Eles não são proibidos, até o momento, mas podem ter significados especiais. Com o atributo file, você especifica onde a descrição do próprio plugin está localizada. Isso é relativo ao diretório onde o arquivo .pluginmap está localizado e ao base_prefix acima. Finalmente, dê ao componente um rótulo. Este rótulo será exibido onde quer que o plugin seja colocado no menu (ou, no futuro, talvez em outros lugares também).

Normalmente, um arquivo .pluginmap contém vários componentes, então aqui estão mais alguns:

<component type="standard" id="teste_nao_implementado" file="means/nao_implementado.xml" />
                <component type="standard" id="t_test_ficticio" file="means/ttests/ficticio.xml" label="Este é um t-test fictício" />
                <component type="standard" id="descritivo" file="descritivo.xml" label="Estatísticas descritivas" />
                <component type="standard" id="corr_matriz" file="corr_matriz.xml" label="Correlação da matriz" />
                <component type="standard" id="simples_anova" file="simples_anova.xml" label="Simples Anova" />
        </components>
        

OK, este foi o primeiro passo. O RKWard agora sabe que esses plugins existem. Mas como invocá-los? Eles precisam ser colocados em uma hierarquia de menus:

<hierarchy>
                <menu id="analysis" label="Análise">
        

Logo abaixo da tag <hierarchy>, você começa a descrição de em qual <menu> seus plugins devem estar. Com a linha acima, você basicamente diz que seu plugin deve estar no menu Análise (não necessariamente diretamente lá, mas em um submenu). O menu Análise é padrão no RKWard, então ele não precisa ser criado do zero. No entanto, se ele ainda não existir, você pode usar o atributo label para dar um nome a ele. Finalmente, o id identifica novamente este <menu>. Isso é necessário para que vários arquivos .pluginmap possam colocar seus plugins nos mesmos menus. Eles fazem isso procurando por um <menu> com o id fornecido. Se o ID ainda não existir, um novo menu será criado. Caso contrário, as entradas serão adicionadas ao menu existente.

<menu id="means" label="Métodos">
        

Basicamente a mesma coisa aqui: Agora definimos um submenu para o menu Análise. Ele será chamado Métodos.

<menu id="ttests" label="Testes-t">
        

E um nível final na hierarquia do menu: Um submenu do submenu Métodos.

<entry component="teste_t_duas_vars" />
        

Agora, finalmente, este é o menu em que queremos colocar o plugin. A tag <entry> indica que este é realmente o item, e não outro submenu. O atributo component refere-se ao id que você atribuiu ao plugin/componente acima.

<entry component="teste_t_ficticio" />
                                </menu>
                                <entry component="teste_t_ficticio" />
                        </menu>
                        <menu id="frequency" label="Frequência" index="2"/>
        

Caso você tenha se perdido: Este é outro submenu do menu Análise. Veja a captura de tela abaixo. Vamos pular algumas opções que não estão visíveis, marcadas com [...].

[...]
                        </menu>
                        <entry component="corr_matrix"/>
                        <entry component="descriptive"/>
                        <entry component="simple_anova"/>
                </menu>
        

Estas são as entradas finais visíveis nas capturas de tela abaixo.

<menu id="plots" label="Gráficos">
                        [...]
                </menu>
        

É claro que você também pode colocar seus plugins em menus diferentes de Análise.

<menu id="file" label="Arquivo">
                        [...]
                </menu>
        

Mesmo em menus padrão como Arquivo. Tudo o que você precisa é do id correto.

</hierarchy>        
</document>
        

É assim que se faz. E esta captura de tela mostra o resultado:

Hierarquia de menus criada pelo código mostrado acima

Confuso? A maneira mais fácil de começar provavelmente é pegar alguns dos arquivos .pluginmap existentes que acompanham a distribuição e modificá-los de acordo com suas necessidades. Além disso, se precisar de ajuda, não hesite em escrever para a lista de discussão de desenvolvimento.

Controlar a ordem dos itens do menu

Por padrão, todos os itens (entradas/submenus) dentro de um menu serão classificados alfabeticamente, automaticamente. Em alguns casos, você pode querer ter mais controle. Nesse caso, você pode agrupar os elementos da seguinte forma:

  • Você pode definir grupos dentro de qualquer menu desta forma. Todos os elementos pertencentes ao mesmo grupo serão agrupados:

    <group id="algumgrupo"/>
                                    
  • Se você deseja que o grupo seja visualmente separado das outras entradas, use:

    <group id="algumgrupo" separated="true"/>
                                    
  • Entradas, menus e grupos podem ser adicionados a um grupo específico, usando:

    <entry component="..." group="algumgrupo"/>
                                    
  • Na verdade, também é possível definir grupos (sem linhas separadoras) implicitamente:

    <entry component="primeiro" group="a"/>
                    <entry component="terceiro"/>
                    <entry component="segundo" group="a"/>
                                    
  • Os nomes dos grupos são específicos para cada menu. O grupo "a" no menu "Dados" não entra em conflito com o grupo "a" no menu "Análise", por exemplo.

  • O caso de uso mais comum é a definição de grupos na parte superior ou inferior de um menu. Para isso, existem grupos predefinidos "superior" e "inferior" em cada menu.

  • As entradas dentro de cada grupo são classificadas em ordem alfabética. Os grupos aparecem na ordem de declaração (a menos que sejam anexados a outro grupo, é claro).

  • Menus e entradas sem especificação de grupo formam logicamente um grupo (""), também.