pwseo Posted March 25, 2012 at 11:06 AM Report #445559 Posted March 25, 2012 at 11:06 AM Pois é, Numa tentativa de adiar ainda mais o estudo para o meu exame, comecei a fazer (há 2 dias) uma espécie de framework para criação de menus em programas feitos em Pascal. Então, o meu objectivo inicial era utilizar objectos (obviamente), mas como estava a pensar direccionar isto para os iniciados, abandonei essa ideia (são muitos conceitos novos) e optei por utilizar uma abordagem procedural semi-orientada a objectos. Através da utilização de callbacks (conceito muuuito à frente 😛 ) o menu pode ser facilmente personalizado, basta definir procedimentos que "façam o render" do título e de cada opção (ou seja, existe efectivamente uma separação do conteúdo e da aparência). O facto de cada item saber qual o procedimento que lhe corresponde obriga à boa prática de separar os programas em fragmentos mais facilmente compreendidos e estruturados. O único senão aqui é ter que dizer aos novatos que precisam de colocar um @ antes do nome do procedimento (tem a ver com pointers). No entanto, nunca mais toquei nisto xD De qualquer forma, aqui fica o código, caso alguém queira dar-lhe continuidade. Também estou aberto a sugestões, nunca se sabe quando voltarei a pegar nisto 🙂 Talvez um dia mova tudo para o github Aqui fica o módulo da framework: http://pastebin.com/KszMyBev E já agora, um exemplo da sua utilização: {$MODE OBJFPC} program test; uses SysUtils, PasMenu; procedure Foo; begin writeln('foo'); end; procedure Bar; begin writeln('bar'); end; var m: TMenu; begin MenuSetup(m, 'This is a menu'); MenuAddItem(m, 'Foo', @Foo); MenuAddItem(m, 'Bar', @Bar); MenuRender(m); MenuChoose(m); end.
pwseo Posted March 25, 2012 at 11:07 AM Author Report #445560 Posted March 25, 2012 at 11:07 AM E aqui um exemplo que faz uso dos tais callbacks para mudar o aspecto do menu: {$MODE OBJFPC} program test; uses SysUtils, PasMenu; procedure Foo; begin writeln('foo'); end; procedure Bar; begin writeln('bar'); end; procedure myrenderer(t: string; i: integer); var s, d: string; j: integer; begin s := inttostr(i); d := ''; for j := 1 to length(s) do d := d + '-'; writeln(''); writeln('+-', d, '-+'); writeln('| ', i, ' | ', t); writeln('+-', d, '-+'); end; procedure mytitle(t: string); var i: integer; s: string; begin s := ''; for i := 1 to length(t) do s := s + '*'; writeln('**', s, '**'); writeln('* ', t, ' *'); writeln('**', s, '**'); end; var m: TMenu; begin MenuSetup(m, 'This is a menu'); MenuAddItem(m, 'Foo', @Foo); MenuAddItem(m, 'Bar', @Bar); MenuSetTitleRenderer(m, @mytitle); MenuSetItemRenderer(m, @myrenderer); MenuRender(m); // back to the default renderers MenuSetTitleRenderer(m, nil); MenuSetItemRenderer(m, nil); writeln; MenuRender(m); MenuChoose(m); end. 1 Report
nunopicado Posted March 25, 2012 at 12:07 PM Report #445564 Posted March 25, 2012 at 12:07 PM 😄 Muito bem Pedro. De uma forma razoavelmente simples, consegues facilitar imenso a contrução de um menu, e ainda mostras conceitos avançados como os Procedural Types. Curiosamente, o Thoga ainda "agora" perguntou sobre isso... 😞 "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.
pwseo Posted March 25, 2012 at 06:50 PM Author Report #445604 Posted March 25, 2012 at 06:50 PM Pois, a utilização de tipos de dados procedurais é uma consequência do design da "API". Aqui fica o projecto no github: https://github.com/pwseo/pascal-simple-menus Sei que está mais incompleto que a versão que coloquei acima, mas deve-se ao facto de ter refeito isto... com outros nomes, essencialmente. Bem, aguardo críticas 🙂
thoga31 Posted March 30, 2012 at 03:28 PM Report #446622 Posted March 30, 2012 at 03:28 PM Documento na Wiki 🙂 Knowledge is free!
nunopicado Posted March 30, 2012 at 03:31 PM Report #446624 Posted March 30, 2012 at 03:31 PM Quase me esquecia do tópico! 😕 Não tenho grandes criticas a fazer. Quando muito, seria interessante criar MenuItems automáticos (por opção), do tipo, Terminar ou Voltar. Mas também não é nada que quem está a usar não possa fazer facilmente... "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.
thoga31 Posted March 30, 2012 at 03:37 PM Report #446627 Posted March 30, 2012 at 03:37 PM Mas também não é nada que quem está a usar não possa fazer facilmente... Explicando o princípio do módulo criado, sim. Para quem olha de fora, não. O módulo nem comentários tem - nada de mal, mas dificulta a vida a quem não está habituado a ver este nível de programação. @pedro-kun, continua com o bom trabalho. 😕 Mas só deixo uma crítica/sugestão: para este nível de programação, comenta e escreve algo mais sobre o assunto. Isto fica melhor num tutorial do que num simples snippet. Tal completa mais e melhor a Wiki e não faz dela um github do P@P. 😄 Knowledge is free!
pwseo Posted March 30, 2012 at 06:52 PM Author Report #446687 Posted March 30, 2012 at 06:52 PM Vou apenas clarificar algumas coisas. Não era pretendido que isto fosse uma snippet, nem sequer uma página da Wiki. Utilizei o github porque pretendia (e ainda pretendo) desenvolver isto ao longo do tempo (daí a escassez de comentários, além do facto de estar nos seus primeiros passos). Quanto ao nível de programação utilizado - é suposto isto ser utilizado por iniciados sem ter conhecimento do que vai dentro do módulo 🙂 Os que quiserem aventurar-se e ler, tudo bem... Mas não se preocupem, eventualmente haverá comentários no código. Porque isto é um "projecto" com uma evolução prevista, a utilização do github faz mais sentido, para controlo de versões, etc etc
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now