artigo

wxPython: Tudo sobre menus

Se você não tem nada a ver com programação, nem tem interesse no assunto, simplesmente ignore este artigo.


Mike Driscoll tem um blog dedicado a Python chamado The Mouse vs. the Python e eventualmente há excelentes artigos por lá.

Esta é uma tradução livre do artigo wxPython: All about menus e modifiquei sutilmente algumas coisas, incluindo os exemplos. Agradeço ao Mike pelos excelentes artigos e me desculpo pelas liberdades que tomei na tradução (incluindo a mudança no nome do artigo). Vamos a ele!


Menus são onipresentes. Eles estão praticamente em quase os programas para desktop. Você os usa para editar preferências ou configurar seu programa. Em wxPython, há várias opções de menu para se escolher. A mais familiar é provavelmente wx.Menu. Mas há menus popup e uma implementação própria do Python conhecida como FlatMenu. Nós cobriremo aqui o wx.Menu e os menus popup porque ambos estão relacionados. FlatMenu inclui a API toolbar, assim você vai ter que esperar por um outro artigo que trate exclusivamente desses widgets. Então vamos começar a festa dos menus!

Um Exemplo Simples de Menu

Um exemplo simples de menu

Vamos começar com algo realmente simples. Um menu que só tem uma opção: Sair. Veja o código:

import wx
 
########################################################################
class MyForm(wx.Frame):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Tutorial wx.Menu")
 
        self.panel = wx.Panel(self, wx.ID_ANY)
 
        menuBar = wx.MenuBar()
        fileMenu = wx.Menu()
        exitMenuItem = fileMenu.Append(wx.NewId(), "Sair",
                                       "Sair do programa")
        menuBar.Append(fileMenu, "&Arquivo")
        self.Bind(wx.EVT_MENU, self.onExit, exitMenuItem)
        self.SetMenuBar(menuBar)
 
    #----------------------------------------------------------------------
    def onExit(self, event):
        """"""
        self.Close()
 
#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm().Show()
    app.MainLoop()

Vamos detalhar melhor isso mais adiante. Para criarmos a barra de menu, instanciamos wx.MenuBar. Então criamos uma instância de wx.Menu, che chamamos de filemenu. Finalmente, adicionamos o item "Sair". Em essência, nós empilhamos wx.MenuItem, mas isso foi um tipo de atalho, já que não chegamos a instanciar um wx.MenuItem primeiro. Nós mostraremos como fazer isso no nosso próximo exemplo. Note que ao adicionarmos um item, temos que passar um id, uma string de etiqueta e uma string de estado. Esta última será mostrada quando você posicionar o mouse sobre o item de menu, desde que você tenha uma barra de estado. Not que para anexar um manipulador de eventos ao item de menu, você precisa usar o evento EVT_MENU e vinculá-lo ao frame. A seguir adicione o Menu propriamente ao objeto MenuBar e passe uma string também, que é neste caso "Arquivo". Finalmente, chamamos o método SetMenuBar do frame para anexar a barra de menu ao frame.

Adicionando uma imagem ao menu

Isso é tudo o que é preciso para criarmos um menu! Agora vamos mostrar um exemplo mais complex! Nota: para seguir o exemplo abaixo, você precisará usar seu próprio arquivo de imagem.

wx.Menu Imagem

# coding: utf-8
import wx
 
########################################################################
class MyForm(wx.Frame):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Tutorial wx.Menu")
 
        self.panel = wx.Panel(self, wx.ID_ANY)
 
        # create the menubar
        menuBar = wx.MenuBar()
 
        # create the first menu (starting on left)
        carMenu = wx.Menu()
        carMenu.Append(101, "&Ford", "Fabricante estadunidense")
        carMenu.Append(102, "&Nissan", "")
        carMenu.Append(103, "&Toyota", "Japoneses!")
        carMenu.Append(104, "&Sair", "Fechar a aplicação")
 
        # add a picture to a menu
        picMenu = wx.Menu()
        item = wx.MenuItem(picMenu, wx.ID_ANY, "Cobra", "Este menu tem uma imagem!")
        img = wx.Image('snake32.png', wx.BITMAP_TYPE_ANY)
        item.SetBitmap(wx.BitmapFromImage(img))
        picMenu.AppendItem(item)
 
        # add menus to menubar
        menuBar.Append(carMenu, "&Veículos")
        menuBar.Append(picMenu, "&Imagens")
        self.SetMenuBar(menuBar)
 
    #----------------------------------------------------------------------
    def onExit(self, event):
        """"""
        self.Close()
 
#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm().Show()
    app.MainLoop()

Este exemplo é similar ao primeiro. A principal diferença é que nós adicionamos itens no lugar do menu File. Note que desta vez, especificamos nossos números ID explicitamente. Isso não é geralmente recomendado porque você pode terminar substituindo algum ID requerido pelo wx. Porém, você deve ter visto exemplos assim pela Internet. A próxima grande diferença não vem antes do picMenu. Aqui nós criamos um wx.MenuItem e adicionamos uma imagem a ele via wx.Image e o método SetBitmap do MenuItem. O resto é basicamente o mesmo.

Agora vamos investir algum tempo vendo como adicionar botões de marcar e selecionar (check e radio, respectivamente) ao nosso menu.

Adicionando Botões de Marcar e de Selecionar (Radio)

Tela demonstrando uso de radio e check boxes em menus com wxPython

Adicionar um botão de marcar ou selecionar ao seu menu é bastante simples. Vamos dar uma olhada em como isso é feito!

# coding: utf-8
# radiocheck.py
import wx
 
########################################################################
class MyForm(wx.Frame):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Tutorial wx.Menu")
 
        self.panel = wx.Panel(self, wx.ID_ANY)
 
        # Create menu bar
        menuBar = wx.MenuBar()
 
        # Create radio menu
        radioMenu = wx.Menu()
        idleItem = radioMenu.Append(wx.NewId(), "IDLE",
                                   "um shell para Python feito em Tcl/Tk",
                                   wx.ITEM_RADIO)
        pyCrustItem = radioMenu.Append(wx.NewId(),"PyCrust",
                                      "um shell para Python feito em wxPython",
                                      wx.ITEM_RADIO)
        psiItem = radioMenu.Append(wx.NewId(), "psi",
                                  "um shell simples para Python feito em wxPython",
                                  wx.ITEM_RADIO)
        menuBar.Append(radioMenu, "&Radio")
 
        # create check menu
        checkMenu = wx.Menu()
        wgItem = checkMenu.Append(wx.NewId(), "Wells Fargo", "", wx.ITEM_CHECK)
        citiItem = checkMenu.Append(wx.NewId(), "Citibank", "", wx.ITEM_CHECK)
        geItem = checkMenu.Append(wx.NewId(), "GE Money Bank", "", wx.ITEM_CHECK)
        menuBar.Append(checkMenu, "&Check")
 
        # Attach menu bar to frame
        self.SetMenuBar(menuBar)
 
#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm().Show()
    app.MainLoop()

Sim, como você pode ver, tudo o que você precisa fazer é adicionar uma flag wx.ITEM_RADIO ou wx.ITEM_CHECK como um tipo de parâmetro, que é o quarto parâmetro. Por que é chamado de "tipo" ao invés de "estilo" como nos outros componentes visuais? Bem, enquanto discutia sobre isso no canal de IRC do wxPython, Robin Dunn (criador do wxPython) disse que provavelmente é assim por se tratarem de tipos de itens de menu diferentes.

Sub-Menus

Tela de exemplo do uso de submenus

A biblioteca wxPython suporta sub-menus. Aqui está um exemplo realmente simples que nos mostra como se faz iso.

# coding: utf-8
# submenu.py
import wx
 
########################################################################
class MyForm(wx.Frame):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Tutorial wx.Menu")
 
        self.panel = wx.Panel(self, wx.ID_ANY)
 
        menuBar = wx.MenuBar()
        fileMenu = wx.Menu()
        openMenuItem = fileMenu.Append(wx.NewId(), "Abrir")
 
        # create a submenu
        subMenu = wx.Menu()
        historyMenuItem = subMenu.Append(wx.NewId(), "Mostrar Histórico")
        fileMenu.AppendMenu(wx.NewId(), "Histórico", subMenu)
 
        exitMenuItem = fileMenu.Append(wx.NewId(), "Sair",
                                       "Deixar a aplicação")
        menuBar.Append(fileMenu, "&Arquivo")
        self.Bind(wx.EVT_MENU, self.onExit, exitMenuItem)
        self.SetMenuBar(menuBar)
 
    #----------------------------------------------------------------------
    def onExit(self, event):
        """"""
        self.Close()
 
#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm().Show()
    app.MainLoop()

O segredo aqui é que ao invés de usarmos o método Append do filemenu, usamos o método AppendMenu. Como o novo sugere, ele permite ao programador acrescentar um menu ao invés de um item de menu. Yup, é isso aí!

Menus Flutuantes (ou Pop-up ou ContextMenus)

Tela de exemplo de uso dos menus flutuantes

Menus flutuantes são menus geralmente acessados através do botão direito do mouse em um navegador ou em um arquivo. Eles também são conhecidos como Menus de Contexto (ou menus pop-up). Aqui temos um exemplo bastante trivial para você estudar.

# coding: utf-8
# submenu.py
import wx
 
########################################################################
class MyForm(wx.Frame):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Tutorial de Menu Flutuante")
 
        panel = wx.Panel(self, wx.ID_ANY)
 
        lbl = wx.StaticText(panel, label="Clique com o botão direito em qualquer lugar por aqui!")
        self.Bind(wx.EVT_CONTEXT_MENU, self.onContext)
 
    #----------------------------------------------------------------------
    def onContext(self, event):
        """
        Create and show a Context Menu
        """
 
        # only do this part the first time so the events are only bound once 
        if not hasattr(self, "popupID1"):
            self.popupID1 = wx.NewId()
            self.itemTwoId = wx.NewId()
            self.itemThreeId = wx.NewId()
            self.Bind(wx.EVT_MENU, self.onPopup, id=self.popupID1)
            self.Bind(wx.EVT_MENU, self.onPopup, id=self.itemTwoId)
            self.Bind(wx.EVT_MENU, self.onExit, id=self.itemThreeId)
 
        # build the menu
        menu = wx.Menu()
        itemOne = menu.Append(self.popupID1, "ItemUm")
        itemTwo = menu.Append(self.itemTwoId, "ItemDois")
        itemThree = menu.Append(self.itemThreeId, "Sair")
 
        # show the popup menu
        self.PopupMenu(menu)
        menu.Destroy()
 
    #----------------------------------------------------------------------
    def onExit(self, event):
        """
        Exit program
        """
        self.Close()
 
    #----------------------------------------------------------------------
    def onPopup(self, event):
        """
        Print the label of the menu item selected
        """
        itemId = event.GetId()
        menu = event.GetEventObject()
        menuItem = menu.FindItemById(itemId)
        print menuItem.GetLabel()
 
#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm().Show()
    app.MainLoop()

Para começar, ligamos wx.EVT_CONTEXT_MENU ao frame. Isso nos permite clicar com o botão direito em qualquer lugar e acionar o evento de menu de contexto, que criará e mostrará o menu flutuante. O código no método onContext é baseado no demo do wxPython para menus flutuantes. Como você pode ver, usamos uma checagem condicional, testando s o evento de menu já foi ativado. Se ele já foi ativado, não o será novamente. Em seguida, criamos nosso menu de um modo bem parecido com os anteriores. Finalmente, chamamos o método PopupMenu do frame e passamos para ele o nosso novo menu. Ele então mostra o menu ao usuário. Quando o usuário clica em um item do menu, o evento associado ao item será ativado e o menu será destruído.

Os primeiros dois itens do menu estão ligados ao método onPopup. Isso nos permite ver como podemos acessar o Menu e os atributos de um MenuItem. Você pode obter o id do menu com o evento e do Menu em si com o método GetEventObject do evento. Assim você pode usar o método FindItemById do menu para pegar um controlador para o item de menu propriamente. Finalmente, imprimimos a etiqueta do item de menu.

E pra terminar

Now you should know most of the menu methods and how to create them, bind events and make different kinds of menu items. You even know how to create popup menus! Now you can make your applications have fancy menus too.

Agora você já conhece grande parte dos métodos de menu e como criar menus, controlar eventos e fazer diferentes tipos de itens de menu. Você também sabe como criar menus flutuantes! Agora você pode fazer suas aplicações também terem menus originais.

Foto do post: Black Rat Snake, de cotinis.

O Silmarillion, de J. R. R. Tolkien

O Silmarillion - Capa do livro

Para quem gosta do gênero de ficção conhecido como Fantasia Medieval, O Senhor dos Anéis é uma obra indispensável.

Ao tomar como base elementos do folclore regional, detalhando povos e seres, criando todo um novo mundo, J. R. R. Tolkien terminou escreveu essa maravilhosa obra, que é inegável influência para diversas histórias de hoje em dia. Histórias de cavaleiros, dragões, magia, espadas, monstros, princesas... Apesar de a obra de Tolkien não trazer todos esses elementos, toda a essência da Fantasia Medieval vem de lá.

Quem gosta de RPGs como Dungeons & Dragons e Tormenta; jogos como The Legend of Zelda, Final Fantasy e The Elder Scrolls; e até mesmo de jogos de estratégia, muito deve, direta ou indiretamente, a esse grande autor.  Escarlate não estaria de fora.

A saga do Senhor dos Anéis já é conhecida, tendo inclusive ótimos filmes a seu respeito. O Hobbit - história que antecedeu a saga em torno do Um Anel - não é tão conhecido, mas logo mais terá seu filme lançado.

Acontece que todos esses livros foram escritos e organizados por Tolkien, narrando aventuras. Em Silmarillion a coisa muda bastante. Primeiro que não existia o livro "O Silmarillion". O que existia era um conjunto de diversas histórias relacionadas à Terra Média, agrupados pelo filho de Tolkien em uma obra que nos apresenta melhor esse mundo fantástico. Se a Terra Média existisse, o Silmarillion não seria um Romance ou Novela, mas um livro de História.

Nele podemos ver desde a criação do mundo por Ilúvatar até eventos mais recentes. Nele temos resposta para perguntas e curiosidades como: por que os reis da linhagem de Isildur vivem tanto mais do que outros humanos? Como surgiram os humanos? Quem exatamente é Sauron? Como foram criados os anéis? Quem são os magos, que são tratados como uma espécie à parte das existentes? (esta última era uma curiosidade antiga minha. O livro parece não trazer resposta, mas não desista: quando vai se aproximando do final isso também é revelado). E várias outras perguntas além destas são respondidas.

Claro, tem o lado ruim: se você acha monótona a narrativa de Tolkien, quando ele para a história para entrar na Geografia, talvez não deva ler O Silmarillion. Se, por outro lado, você não se incomoda com isso, é mestre RPG, autor de Fantasia Medieval ou simplesmente adorou a história toda do Senhor dos Anéis, nem pense duas vezes antes de descolar o seu exemplar!

Special: 

UFAL + Presídio #2

Se houvesse um Monopoly Arapiraca, com o vermelho sendo as instituições de ensino, a UFAL não ficaria só pertinho do presídio, mas com o presídio dentro.

Como já disse em outro post, a UFAL está paralisada em Arapiraca devido ao sério problema de segurança enfrentado há anos e que só se agrava.

Na última quarta-feira a fuga que levou a uma "basta" por parte da comunidade acadêmica fez aniversário de um mês. O que temos? Muitos obstáculos já foram superados e novos obstáculos apareceram.

O problema das fugas do presídio (que estranhamente fica dentro do terreno da UFAL) é recorrente, assim como as promessas governamentais de ao menos amenizar o problema. Em 2011 o Governador prometeu a construção de um muro que supostamente melhoraria a segurança. No final do ano, nada feito ainda, prometeu que o recurso que seria destinado ao muro seria realocado para a reforma de celas em Maceió que estavam sem uso, para que os reeducandos fossem transferidos provisoriamente para Maceió.

Pois bem, uma das notícias que temos é de que as 100 celas (que receberiam provisoriamente nossos cerca de 200 detentos) já estão reformadas, mas estão sendo ocupadas. Alega-se que houve aumento de 400 detentos na capital nos últimos meses. O prazo que o Governador deu em dezembro foi de 90 dias, o que já venceu faz tempo. E aí? Como fica?

Agora vamos ao novo presídio. Depois de receber uma cobrança da Prefeitura de Arapiraca em resposta ao seu pedido de terreno para a construção do presídio ("não temos terreno adequado. Vocês nos devem X milhões. O que podemos fazer é autorizar que esse recurso que vocês nos devem seja usado para a compra do terreno"), tem-se dito que a prefeitura de Craíbas, que fica perto de Arapiraca, cedeu o terreno. Ok!

Em reunião em Brasília para tratar do assunto, nosso Diretor Geral foi informado de que há uma verba de R$ 14,5 milhões pronta para a construção do novo presídio. Segudo disseram, basta o Governo Estadual apresentar que tem o terreno com o destino e o projeto de construção, que a verba estará à disposição no dia seguinte. Ok 2.

Assim temos duas pendências: a situação provisória, que é a transferência dos detentos para a capital esbarrou em um juiz de lá, que alega que a capital não pode receber esses presos. A construção do presídio (que leva 2 meses se for em pré-moldado ou de 8 a 12 se for uma construção convencional - há projetos do Governo Federal já prontos para as duas modalidades, à disposição do Estado; e que pode ser pedida em licitação emergencial) espera não se sabe o quê.

Enquanto o Governo não toma atitude (duas apenas: cumprir com a promessa da remoção e iniciar logo os trâmites para a construção do novo presídio), a UFAL continua parada por tempo indeterminado; estudantes estão sem aula e em breve correrão riscos de perderem o semestre.

Enquanto isso vamos às ruas, e para esta sexta-feira 4 está programado um seminário sobre a Universidade e o Sistema Prisional. O seminário ocorrerá a partir das 8 horas na Casa da Cultura, tomará toda a manhã e está aberto à toda a sociedade.

Para acompanhar melhor as ações de mobilização, sigam o blog UFAL Segura.

Special: 

As Bases de um Poeta Completo

Camões falava de Saber, Engenho e Arte em suas poesias. Considero, ao menos em minha interpretação, estas como as três características fundamentais para um poeta completo. Aqui, falo um pouco de cada uma delas na forma como vejo (não há garantia de que seja a forma como Camões pensava, embora ache até possível que de repente tenha sido).

Saber

Um poeta tem que ter o conhecimento do que vai falar. Para poesias filosóficas, conhecer filosofia; para narrar casos acontecidos, traçar bem o que houve. Enfim, tem que ter o tema. Um poeta de muito saber tem jogo de cintura e conhece vários temas. Se for um repentista, tem uma boa desenvoltura temática.

Engenho

Um poeta que não tem noção de ritmo e métrica não é um poeta completo. Essa é a parte que pode "obscurecer" o que o poeta quer dizer, mas é o caminho mais longo o que nos fortalece.

É difícil eu me afeiçoar com poesias modernas, que são poesias para serem declamadas teatralmente e não seguindo um ritmo.

Todas as regras são convenções e podem ser quebradas, mas quem planeja quebrar regras tem que saber o que está fazendo. Regras devem ser seguidas à risca enquanto não as entendemos. Só quando dominamos as regras é que podemos quebrá-las, se quisermos. Nesse ponto, teremos plena ciência de que estamos quebrando onde queremos um efeito diferente do convencional e, para quem também conhecer as regras, isso ficará muito claro.

Um exemplo mais claro dessa postura de conhecimento é a famosa licença poética, que dá liberdade ao poeta para burlar as regras do Português. Erros vindos do desconhecimento nunca foram nem serão licença poética, ela existe para mudanças conscientes nas regras do Português, mudanças que vêm para atender algum interesse do poeta.

Aplique-se o mesmo a métrica, rima, ritmo...

Arte

Esse é o fundamental de um poeta. Isso porque o Saber pode ser adquirido com leitura e o Engenho desenvolvido com o estudo e a prática. Se você tem Saber e Engenho, mas não Arte, produzirá poesias perfeitas estruturalmente, bem organizadas, mas sem vida, incapazes de despertar emoções no leitor.

Por outro lado, é até comum algumas pessoas que têm Arte, mas não Engenho ou Saber. Muitos desses nem tentam fazer poesias, limitando-se a escrever textos muito bem escritos e de agradabilíssima leitura.

Poetas Perfeitos

Um bom caminho para poetas perfeitos é dos violeiros, que desenvolvem a desenvoltura no Saber e aprimoram de maneira sublime o Engenho, quando atentos a ele (pois às vezes forçam métrica esticando sílabas cá e atropelando sílabas acolá). Se o cabra tiver Arte, não há quem segure.

Se quiser aprender mais sobre o Engenho, pesquise os estilos populares. São dos mais ricos e complexos que encontrei.

Para finalizar, uma estrofe de um galope à beira-mar, de Dimas Batista, que demonstra bem a superioridade do violeiro e repentista diante de muitos ditos poetas por aí...

"Eu acho engraçado um poeta de praça
Que passa dois meses fazendo um quarteto
Com um ano de luta, é que finda um soneto
Depois que termina, ainda sem graça
Com tinta e papel, o esboço ele traça
Contando nos dedos pra metrificar
Que noites de sono ele perde a pensar
A fim de mostrar tão minguado produto
Pois desses, eu faço, dois, três, num minuto
Cantando galope na beira do mar."

Special: 

Kirby, um herói não convencional

Bolo de aniversário no formato do Kirby

Um monstro assola a população, que não tem como se defender. Uma profecia fala de um guerreiro valoroso e corajoso que virá das estrelas para salvar o povo sofrido. Todos esperam e surpresa! É um balão cor-de-rosa.

Kirby com o poder do fogoKirby em essência é uma piada com as expectativas de heróis. Ao invés de um corpo definido, é uma bola; ao invés de transmitir confiança e imponência, é "fofinho"; e ainda é cor-de-rosa. Mas não subestimem esse herói, que tem poderes fabulosos.

Primeiro, que ele pode inflar o próprio corpo como um balão e voar por aí (devagarinho, mas voa). Segundo que ele é resistente pra caramba, como se seu corpo fosse feito de uma borracha especial. E terceiro, claro, que ele tem o poder de absorver os poderes de inimigos que ele engula.

Boa parte da diversão de jogar com esse carismático personagem da Nintendo está nessa última habilidade. Você enfrenta um espadachim e o absorve, Kirby ganha uma espada; absorve um monstrinho de fogo e Kirby ganha poderes de fogo também. Sempre mudando o visual um pouco. Foram diversos e diversos poderes que Kirby já teve graças a essa habilidade (quer ver? dá uma olhada na edição 25 da Revista Nintendo Blast). Sem contar que, se alguém conseguir fatiá-lo, ele se torna uma multidão de Kirbies (como no jogo mais recente para Nintendo DS: Kirby Mass Attack).

Kirby com a espadaKirby estrelou no Game Boy e já passou por diversos consoles, incluindo os recentes Nintendo DS e Wii (haverá versão para 3DS?), mas sua presença não está restrita aos seus próprios jogos: ele participa desde a primeira edição do Super Smash Bros, ainda para Nintendo 64. E é um competidor de peso. Sua habilidade de absorver poderes funciona também nesse jogo de luta (com a diferença de que o inimigo não é exatamente engolido, mas devolvido). Isso rende Kirby vestido de Link, Kirby-Mario, dentre outros.

Kirby, que hoje completa 20 anos, tem representado no universo Nintendo inovação e criatividade. Seja com o Canvas Course do Nintendo DS, onde o controle sobre o herói é indireto; ou com o altamente premiado Kirby Epic Yarn, que faz do jogo uma tela viva de bordado.

Veja o trailer desse belo jogo para Wii:

É isso aí! Parabéns! Feliz aniversário Kirby das Estrelas!

Special: 

UFAL + Presídio

Semana passada aconteceu um incidente na UFAL.Mais uma fuga de presidiários e mais uma vez tiros são disparados em direção aos prédios do Campus Arapiraca, durante o dia e em momento de aulas.

O resultado é esperado: caos. Correria, gente se machucando. Felizmente ninguém da comunidade acadêmica se machucou com os tiros, mas se machucaram com o caos gerado. Sem contar que os fugitivos sequestraram a besta que traz os professores que moram em Maceió. A besta e o motorista.

Para quem não sabe como são as coisas por aqui, um resumo: o campus oferece hoje em Arapiraca 14 cursos, 3 dos quais são noturnos. Inaugurada em 2006, desde aquela época, temos um bloco extra. O presídio fica dentro do terreno que foi cedido para construção da UFAL (há quem diga que o terreno já estava destinado à UFAL antes mesmo de o presídio chegar). Dentro mesmo. Dos quatro lados do prédio que é o presídio, 3 fazem fronteira com o terreno da UFAL.

Havia uma promessa de que os presos seriam transferidos para Maceió. Devido a essa promessa, colocaram o carro na frente dos bois e transferiram parte dos funcionários antes de assegurarem que a reforma necessária para viabilizar a transferência dos presos estivesse concluída. Resultado? A situação só piorou. Não há previsão para a reforma de lá e há menos funcionários hoje do que havia antes.

Devido a toda essa problemática, o Campus Arapiraca da UFAL está paralisado, cobrando que sejam tomadas ações de fato para solucionar o problema da segurança em nosso ambiente de trabalho (e estudo).

O Governo do Estado (que parece ser o maior causador de todo esse problema) pede à Prefeitura um terreno para a construção do presídio. O prefeito diz que não tem um terreno que atenda às especificações necessárias para um presídio e que o Estado tem com o Município uma dívida de mais de 1 milhão de reais e que, se a dívida for paga, todo esse valor será empregado na aquisição de um terreno para esse fim.

Enquanto uma solução não aparece, a Direção do Campus não se responsabiliza por uma volta às atividades antes que uma solução seja iniciada (e não apenas prometida. Não é a primeira vez que acontece uma fuga e que acontecem tiros e promessas já recebemos muitas); o Conselho da UFAL em Maceió votou em apoio à paralização e estão sendo feitas cobranças.

Enquanto isso, alunos ficam sem aula (mas estão ativamente envolvidos nessa causa)...

Special: 

Preparando o ambiente RenPy

RenPy é um engine para a criação de Visual Novels, aqueles jogos que funcionam como narrações visuais interativas. Já falei dele rapidamente em outra ocasião e agora vamos ver como preparar o ambiente para usá-lo.

Para começar - e creio que não deve causar nenhum espanto - você vai precisar do Python instalado. Enquanto a maioria das distribuições GNU/Linux já vem com Python (mesmo as distribuições pequenas), no Windows você precisará instalá-lo. Para isso, pode baixá-lo de Python.Org. O CyanPack inclui a versão mais recente do Python para Windows e se você tiver o CyanPack poderá instalar o Python a partir dele.

Se você usa Trisquel, Ubuntu, Debian ou algo parecido ou derivado, para instalar o RenPy basta procurar o pacote renpy via Synaptic e instalá-lo. Ou executar o comando apt-get install renpy (ou sudo apt-get install renpy). É bom instalar também o renpy-demo e o renpy-thequestion. Assim você terá exemplos completos de uso da ferramenta.

Pois bem, uma vez instalado o RenPy, a principal ferramenta que você vai utilizar - o que fará interface entre você e o RenPy propriamente - é o Launcher. Ele é feito em Python e tem rotina para criar e configurar os projetos, o que já ajuda muito e evita que você tenha que se preocupar com a criação dos diretórios e arquivos iniciais. O Launcher tem o seguinte aspecto:

RenPy Launcher

Nesta tela, você vê um projeto já criado (Agenda Mundial). As opções para o projeto aberto são:

  • Launch - executar o projeto (jogar)
  • Edit Script - editar o arquivo principal do projeto (o arquivo em que você vai efetivamente trabalhar) com o editor de textos padrão do RenPy (veremos sobre isso mais adiante)
  • Game Directory - abre a pasta do jogo no gerenciador de arquivos
  • Check Script (Lint) - checar o código-fonte do jogo em busca de erros, validar
  • Choose Theme - escolher a paleta de cores do projeto
  • Delet Persistent - tarefa de manutenção - remoção de arquivos persistentes do projeto
  • Archive Files - cria um arquivo compactado com tudo o que se encontra dentro da pasta de projeto
  • Build Distributions - parecido com Archive Files, mas já adiciona o script necessário para o Sistema Operacional desejado

As opções globais ficam na sessão Ren'Py e são:

  • Select Project - permite ecolher um projeto que exista no diretório padrão do RenPy
  • New Project - cria um novo projeto no diretório padrão do RenPy
  • Ren'Py Games List - vai para o site do projeto RenPy listar os jogos que estão lá cadastrados
  • Quit - dar o fora
  • Options - permite definir qual o editor de textos padrão do RenPy e qual o diretório padrão (onde estão os seus projetos de jogos)
  • Ren'Py Help - abre a documentação do RenPy no navegador

Bom, agora você já sabe do básico, mas isso não é tudo, pelo menos aqui na minha instalação do Trisquel não foi tudo.

O problema basicamente foi que o editorde textos não funcionou. Indo na configuração, vi que havia duas opções: Debian e jEdit. O problema é que o editor padrão do Debian é um editor sem interface gráfica e, por isso, não funciona direito aqui. Tudo bem, podemos escolher o jEdit, mas isso também não é uma solução por si, já que o jEdit não vem com o RenPy.

Bem, então vou apresentar duas soluções de editor de textos que funcionam em GNU/Linux.

Usando o jEdit

Não importa em que Sistema Operacional você vai usar o jEdit. Para usá-lo, obviamente, você precisará de suporte Java instalado.

Em Windows, você pode baixar o Java diretamente do site Java.com. O jedit você baixa de jEdit.org e de preferência o coloca dentro do diretório onde ficou instalado o RenPy. Isso deve funcionar.

Agora, se estamos utilizando uma distribuição GNU/Linux que use pacotes .deb, certamente queremos as coisas mais organizadas. Por isso, devemos instalar o pacote jedit via Synaptic. Ou, como antes, simplesmente executar o comando apt-get install jedit. Isso por si só instalará o Java - caso não esteja insatlado - e o jEdit.

Tá, mas não acabou. Isso muito bem instala o jEdit, mas o RenPy não vai encontrá-lo. Para que o RenPy o encontre, execute esta linha no terminal:

ln -s /usr/share/jedit /usr/games/renpy

Isso criará um link simbólico para toda a pasta do jedit, como se ele tivesse sido instalado dentro do RenPy. Assim, o RenPy vai chamar o jEdit sem problemas.

Usando o Geany

Uma opção mais atrativa talvez seja usar o editor Geany, especialmente para quem utiliza o Trisquel que é distribuído junto com o CyanPack, já que o Geany já vem instalado nesse caso.

Se você ainda não tem o Geany instalado, instale o pacote geany.

Para usar o Geany, você vai precisar adicionar um arquivo de sintaxe e alterar outro, ambos da instalação do próprio Geany, além de um do próprio RenPy. Todas essas operações devem ser feitas com privilégios administrativos (como usuário root ou com sudo).

Comece baixando este arquivo. Você vai descompactá-lo e jogar o arquivo geany.editor.py no diretório /usr/share/games/renpy/launcher. Pronto, isso basta para que o RenPy possa reconhecer o Geany como um editor de textos (para usá-lo de fato, você deve alterar o editor de textos padrão via interface Launcher - em Options. Ao reabrir o RenPy depois de colocado o tal arquivo lá, o RenPy já vai listar o Geany como opção de editor, junto com o Debian e o jEdit).

Bem, agora o RenPy já abre o Geany com os arquivos que queremos editar, mas o Geany não colore. Para que o destaque sintático do Geany funcione, você precisa adicionar o arquivo filetypes.Ren'Py source.conf ao diretório /usr/share/geany. O arquivo está dentro deste arquivo compactado.

Ok, falta pouco. Agora abra o arquivo /usr/share/geany/filetype_extensions.conf e adicione a linha:

Ren'Py source=*.rpy;*.rpym;

Pronto! Está feito! Agora você já tem o ambiente RenPy funcional e pode criar suas próprias histórias interativas! Claro, numa sintaxe própria derivada do Python. Uma sintaxe da qual falarei em uma outra oportunidade...

Special: 

Kingdom Hearts: 10 anos entre Disney e Final Fantasy

Em 28 de março de 2002 era lançado no Japão o jogo Kingdom Hearts para Playstation 2. Um jogo inovador idealizado e projetado por duas grandes empresas do mercado de entretenimento, misturando conceitos e personagens: Square (atualmente Square Enix), produtora de jogos famosa com sua série Final Fantasy; Disney, nome indiscutivelmente famoso na área de desenhos e animações. O novo título era um mistério para o público e trazia uma só pergunta a todos: isso vai dar certo?

Deu certo. Hoje Kingdom Hearts completa 10 anos de vida e continua tendo títulos lançados e fazendo sucesso em vários consoles. Os títulos mais importantes (sim, ainda há outros) da série são:

  1. Kingdom Hearts, para Playstation 2 (2002)
  2. Kingdom Hearts: Chain of Memories, para Game Boy Advance (2004)
  3. Kingdom Hearts II, para Playstation 2 (2005)
  4. Kingdom Hearts 358/2 Days, para Nintendo DS (2009)
  5. Kingdom Hearts Birth by Sleep, para Playstation Portable (2010)

As aventuras acontecem em um universo criado especialmente para a série. Sora, o personagem principal de grande parte da série, tem que partir a procura de seus amigos, interagindo com personagens da Disney e do universo de Final Fantasy, vagando por cenários variados (como o mundo da Pequena Sereia, a terra do Rei Leão e o mundo digital de Tron). Usando uma curiosa espada em formato de chave, a Keyblade, objeto mágico fundamental em toda a história.

É uma série que certamente deve ser apreciada por quem gosta de RPG ou da Disney. RPGs com qualidade Square Enix e o carisma de Mickey, Donald e outros. Inclusive, com as vozes oficiais dos personagens.

Estão por vir Kingdom Hearts III (para Playstation 3 e sem data prevista) e, comemorando os 10 anos da franquia, Kingdom Hearts 3D: Dream Drop Distance (para Nintendo 3DS). Esse último será lançado amanhã no Japão, com direito a kit especial comemorativo, com um 3DS temático mais o jogo. Com a popularidade cada vez mais crescente do 3DS não duvido que será outro sucesso. Veja um trailer:

Apesar de ser lançado amanhã no Japão, a versão americana só deve vir no final do ano. De qualquer forma, já está disponível em pré-venda no eStarLand.

Special: 

União Livre (de quem?)

"O objetivo desse projeto é descontinuar as atuais distribuições Linux do Brasil." É com essas palavras que o site do projeto União Livre começa a anunciar sua intenção: que o Brasil tenha uma distribuição GNU/Linux só.

Essa ideia de que existe um excesso de distribuições e que uma distribuição única seria a solução parece genial a um novato na área, mas se você analisar bem o cenário percebe facilmente o quanto é falha.

O grande problema dessa ideia é que o fato de haver muitas distribuições não é o problema. O problema acontece quando uma distribuição é criada e se mantém sem uma razão sólida. São duas situações distintas e que devem ser separadas.

Uma ideia de "unificar" ignora que distribuições tem seus motivos de existirem, não se resumem a "juntar usuários". Há distribuição que existe para atender a necessidades de certo perfil de usuários, outras que focam a divulgação de certas ferramentas ou ideais e por aí vai. É também frequente que os motivos de uma conflitem diretamente com os motivos de outra. Um exemplo simples? Uma distribuição quer facilitar ao máximo para os usuários enquanto outra quer se alinhar ao máximo com os conceitos de Software Livre. O que temos? "Facilitar ao máximo" exige abrir mão de certas liberdades, levando a equipe a embutir Adobe Flash, drivers fechados, dentre outras "facilidades". Isso não é conciliável com a outra meta.

Foi apenas um exemplo. Se considerarmos outras guerras como KDE versus GNOME (versus Unity versus GNOME 2 versus MATE versus...), por si só já justificaria divisões. Não adianta argumentar que elas podem entrar em concenso, pois as razões muitas vezes são complexas. Um dirá que adora a API do GTK+ e de todo o GNOME, enquanto outro dirá que a identidade visual do KDE é mais sólida; outro dirá que prefere o GNOME antigo, enquanto outro entende e aceita as vantagens que a Canonical defende para justificar seu Unity. Entendem? Geralmente não é só uma questão estética (só no caso de algumas ditas distribuições, que não passam de seleção de pacotes e criação de papéis de parede).

Você pode dizer: "Beleza, então faz uma distribuição que junte tudo num pacote só e fica todo mundo feliz." Será? O tamanho da distribuição resultante também pode ser um objetivo de algumas distribuições. Outras podem estar muito presas a certas distribuições internacionais específicas. Se uma distribuição quer "a melhor performance possível", não vai abrir mão de ser derivada do seu Arch Linux (suposição).

A despeito disso, "uma distribuição única" costuma ser algo pedido pelos usuários, por terem a percepção de que há desperdício de forças em um cenário tão amplo. Há mesmo? Muitas vezes sim, mas há outras soluções para isso. Os projetos podem se ajudar mais, trocar informações e ferramentas menores entre si, publicar mais o que é feito (muitas vezes ferramentas interessantes são criadas por pequenas distribuições e mantidas como "diferencial" ao invés de serem amplamente divulgadas como ferramentas para serem incorporadas por outros projetos).

Percebem como a multiplicidade de distribuições é algo complexo? Se ainda quiserem ver mais sobre a ideia de unificar distribuições, leiam uma discussão antiga minha com Sergio Tucano. Pois bem, vamos voltar ao caso específico da União Livre. O que vemos aqui? Um chamado anônimo aos mantenedores das milhares (?) de distribuições nacionais. Ao invés de assinar embaixo (identificando-se o/os autor/es da proposta perante a sociedade), ele(s) cria(m) um abaixo-assinado.

Por que não, ao invés de querer unificar, fazer uma consulta a cada distribuição, fazendo um levantamento das razões de sua existência? E a partir daí se tentar um MMC das distribuições (o que provavelmente não significaria uma distribuição única)? Não é preciso uma fundação para isso, nem é preciso unificar todas em uma só (e uma nova, ainda mais).

O que vejo é uma distribuição relativamente antiga no Brasil e uma mais nova: respectivamente, Big Linux e SimbiOS. As duas parecem ter os mesmos objetivos de agradar usuários leigos, agregando facilidades, de modo que não duvido que a ideia tenha surgido entre eles. E é uma boa ideia as duas integrarem esforços (mudando ou não de nome), só acho que não havia necessidade desse auê todo. Toda prepotência.

E ainda adotando o pomposo nome de União Livre (que adota drivers, browsers e outros aplicativos privativos). Quem vai entrar nessa canoa?

Páginas