Páginas

terça-feira, 29 de setembro de 2020

Toast Notification Android no Delphi


Olá novamente, recruta!

Hoje vamos falar sobre notificações Toast no Android utilizando Delphi FireMonkey .

Rapidamente para quem não está familiarizado com o assunto, Toast Notidication se refere a pequenas mensagens pop-up que aparecem na tela do mobile quando efetuamos algumas operações em certos Apps, como enviar um e-mail ou o concluir um download.

Essas notificações permanecem por um tempo na tela e depois somem, elas não impedem ou bloqueiam a execução da tela atual, ou seja, não são janelas modais, inclusive, mesmo que nossa aplicação seja finalizada elas permanecerão na tela pelo tempo que foi configurado.

Existem algumas formas de emular um Toast Notification, algumas bem difundidas na internet, o que de certa forma é bem interessante, ao ponto que não ficamos preso a uma plataforma específica, mas não é tão eficiente quanto usar o Toast nativo da plataforma. A forma  que nós iremos utilizar será com a própria API do Toast Notification do Android, consequentemente você não poderá utilizar no Windows nem no IOS.

quarta-feira, 19 de agosto de 2020

Criando um ListBox Delphi com a usabilidade da lista de contatos do WhatsApp

Olá, recruta

Neste post iremos dar algumas dicas de usabilidade criando um Listbox estilo WhatsApp.

Mas o que exatamente queremos dizer isso?

Muitas vezes desenvolvedores colocam botões de excluir, editar e outras funcionalidades em cada um dos itens do Listbox, desse forma repetindo cada um deles em cada registro da lista. Se repararmos no WhatsApp as únicas opções de um item é clicarmos nele para irmos para a tela de mensagens do contato, e a seleção do item ao manter-lo pressionado, que é justamente quando as demais opções aparecem. E é exatamente isso que iremos fazer, ao clicar em um item da nossa lista ir para uma aba de detalhe do item e habilitar botões como excluir ou alguma outra opção apenas quando houver um ou mais itens selecionados.

segunda-feira, 24 de junho de 2013

Alterando a cor de palavras em um editor de texto.

Olá galerinha, segue uma dica rápida.
Se você precisar criar um editor de texto onde alguma palavras do seu texto devem aparecer com alguma cor ou fonte diferente, sua saída, sem apelar para uma editor de texto de terceiro é o TRichEdit. O TMemo e o TEdit não possuem suporte a edição de fonte parcial do texto. É como comparar o NotePad com o WordPad.

Abaixo segue a receita de bolo de como fazer isso: 

function TForm1.AlterarCorDoTexto(pRichEdit: TRichEdit;
  pTexto: string; pColor: TColor): Boolean;
var
  lStartPos, lPosition, lEndpos, lPosIni: Integer;
begin
  lStartPos := 0;
  lEndpos := Length(pRichEdit.Text);
  lPosIni := pRichEdit.SelStart;

  pRichEdit.Lines.BeginUpdate;
  // Coloca tudo na fonte padrão
  pRichEdit.SelStart  := 0;
  pRichEdit.SelLength := lEndpos;
  pRichEdit.SelAttributes.Color := pRichEdit.Font.Color;

  // Localiza o texto de coloca ele na fonte desejada
  while pRichEdit.FindText(pTexto, lStartPos, lEndpos,
    [stMatchCase])<>-1 do
  begin
    lEndpos   := Length(pRichEdit.Text) - lStartPos;
    lPosition := pRichEdit.FindText(pTexto, lStartPos, 
      lEndpos, [stMatchCase]);
    Inc(lStartPos, Length(pTexto));
    pRichEdit.SelStart  := lPosition;
    pRichEdit.SelLength := Length(pTexto);
    pRichEdit.SelAttributes.Color := pColor;
  end;

  // Posiciona o cursor na posição originar e
  // atribui o texto para o definido no componente
  pRichEdit.SelStart  := lPosIni;
  pRichEdit.SelLength := 0;
  pRichEdit.SelAttributes.Color := pRichEdit.Font.Color;
  pRichEdit.Lines.EndUpdate;

end;

Bom agora é só fazer a chamada do método. Um lugar bom para fazer isso é o evento OnKeyDowm do seu RichEdit:

function TForm1.RichEdit1KeyDown(Sender: TObject; 
  var Key: Word; Shift: TShiftState);
begin
  AlterarCorDoTexto(RichEdit1,'muka',clBlue);
end;

Abraço a todos!

terça-feira, 21 de maio de 2013

Tutorial de desenvolvimento para iOS com Delphi XE4

Olá Delpheiros, super dica na área!
Como a grande sensação do Delphi XE4 é o desenvolvimento para iOS a Embarcadero publicou um manual detalhado (em inglês) sobre desenvolvimento para iOS. 
O documento abrange configuração do Mac, instalação do certificado de desenvolvedor Apple, configuração de profile no Delphi para comunicação com o Mac, componentes e estilos, banco de dados e mais uma monte de coisa muito interessante.
O Tutorial está excelente, parabéns para equipe Embarcadero.

Link para donwload:

segunda-feira, 20 de maio de 2013

Portal de Treinamento Embarcadero


Olá Pessoal,
Nesse post quero falar um pouco do Portal de Treinamento Embarcadero. Já no ar a algum tempo mas ainda pouco divulgado.
Se você anda meio desanimado, não vendo a carreira deslanchar, sem vontade de cantar uma bela canção...
Como diz aquela canção do Raul e Marcelo Nova, "Chegou a luz no fim do seu túnel meu filho...", hehehe.
E essa luz nada mais é que o Portal de Treinamento Embarcadero,
www.embarcaderobr.com.br/treinamentos/
Nele você pode ter informações sobre os Centros de Treinamentos Oficiais Embarcadero, ondo você conta com toda assistência para se tornar um Jedi no desenvolvimento de Sistemas em Delphi. Também é possível cadastrar seu currículo ou no caso esteja procurando um desenvolvedor, pesquisar por profissionais de todo Brasil. O Site ainda traz informações sobre certificação e treinamentos oficiais.

Evento DUG-RS
Desenvolvimento para iOS

Salve Delpheiros!
Dia 21-05-13 apartir das 19h, teremos 4 dos MVPs Embarcaderos, Newton Oliveira, Carlos "Tatu" Agnes, Luciano Pimenta e Eu reunidos na  Faculdade Dom Bosco para colocar as novas ferramentas de desenvolvimento para iOS e o recém adquirido FireDAC a toda prova.
Vamos discutir, desenvolver, testar e rever a galera!

Incrições: http://www.sucesurs.org.br/evento/novidades-do-mobile-stduio-dugrs

Vejo vocês la.

quinta-feira, 16 de maio de 2013

Criando campos data e calculado em tempo de execução

Essa semana tive que implementar uma tela que mostrasse um grid com a listagem de produtos, e ao lado uma coluna para cada tabela de preço com seu respectivo preço, além de uma coluna que tivesse um campo InternalCalc booleano para que fosse possível selecionar os produtos através de um checkbox no meu grid (utilizo o cxGrid da DevExpress, então os campos booleanos podem ser exibidos com um checkbox na coluna). 
O drama começa na geração do Sql. Como eu posso ter quantas tabelas de preço eu quiser, logo as colunas deverão ser dinâmicas, cada tabela deverá gerar um campo novo no meu select. Eu estou utilizando Firebird, então não tenho nenhum recurso de Olap ou Pivot, então meu Sql teve que ser gerado por um método no Delphi, onde eu faço um loop para cada uma das tabelas de preço gerar uma coluna coluna correspondente, isso ficou mais ou menos assim (mudei a nomenclatura dos meus campos para ficar mais didático):

procedure TdmdCadAlteraPreco.MontarConsulta;
var
  lSql : TStringList;
  lCod, lCampo : String;
  lField : TField;
begin
  lSql := TStringList.Create;
  try
    lSql.Add('SELECT P.PROD_ID, P.PROD_CODIGO, P.PROD_DESC ');

    cdsTabPreco.Close;
    cdsTabPreco.Open;
    cdsTabPreco.First;
    while not cdsTabPreco.Eof do
    begin
      lCod := IntToStr(cdsTabPreco.FieldByName('TPRE_ID').AsInteger);
      lCampo := 'TABELAPRECO_'+lCod;
      lSql.Add(',(SELECT F.PRECO FROM PRECOPRODUTO F ');
      lSql.Add('   WHERE F.PROD_ID = P.PROD_ID ');
      lSql.Add(    AND F.TPRE_ID = '+lCod+') as 'lCampo);
  
      cdsTabPreco.Next;
    end;
    cdsTabPreco.Close;

    lSql.Add('FROM PRODUTO P');
    sqlPesquisa.CommandText := lSql.Text;
    finally
      lSql.Free;
    end;
end;

Como meu velho pai costumava dizer, "para bom programador meio código basta". Então, a unica coisa que não está visível aqui é o Sql do cdsTabPreco, que tem a lista das tabelas de preço cadastradas no sistema. Gerar Sql geralmente não é mistério pra ninguém, o problema está em colocar estes campos no CDS de pesquisa, para que possamos usar por exemplo o DisplayFormat, o DisplayName e também adicionar  campos InteralCal.

Confesso que até o momento nunca tinha passado por tal situação, minhas Sqls são todas colocadas diretamente nos datasets, e tenho um framework de pesquisa que apenas trabalha o where das Sqls, as colunas nunca são alteradas.
Na primeira tentativa fui direto para o FieldDefs do CdsPesquisa, já que estou acostumado a criar CDSs temporários utilizando esses comandos:

cdsPesquisa.FieldDefs.Add('PROD_ID',ftInteger);
cdsPesquisa.FieldDefs.Add('PROD_CODIGO',ftString,15);
...

Essa técnica foi frustrante, por que eu não tenho aqui como dizer se meu campo é calculado ou não. 

A próxima lógica ao meu ver seria criar um objeto do tipo TField e adiciona-lo ao CDS. Algo dessa forma:

lField := TIntegerField.Create(Self);
lField.FieldName := 'PROD_ID';
lField.FieldKind := fkData;
cdsPesquisa.Fields.Add(lField);

Aqui eu consigo definir o tipo do campo, se é data, calculado ou InternalCal, mas na hora de abrir o CDS...
Não é que o "chato do pato", ou melhor do CDS ficou reclamando que o campo não existia no dataset!
Ai fiquei matutando, qual será a mandinga para adicionar meu campo no CDS?
Foi então que dando um pesquisada por ai descubro que não devemos adicionar o TField a lista de TFields do CDS, e sim atribuir para a propriedade DataSet do TField o DataSet onde ele será adicionado. Dessa forma:

lField := TIntegerField.Create(Self);
lField.FieldName := 'PROD_ID';
lField.FieldKind := fkData;
lField.DataSet   := cdsPesquisa;

Facil né?
Claro, depois que sabemos o que fazer.

Nosso código completo fica assim:

procedure TdmdCadAlteraPreco.MontarConsulta;
var
  lSql : TStringList;
  lCod, lCampo : String;
  lField : TField;
begin
  lSql := TStringList.Create;
  try
    lSql.Add('SELECT P.PROD_ID, P.PROD_CODIGO, P.PROD_DESC ');


    lField := TBooleanField.Create(Self);

    lField.FieldName := 'SELECAO';
    lField.FieldKind := fkInternalCalc;
    lField.DisplayLabel := 'Sel';
    lField.DataSet   := cdsPesquisa;

    lField := TIntegerField.Create(Self);
    lField.FieldName := 'PROD_ID';
    lField.FieldKind := fkData;
    lField.Visible   := False;
    lField.DataSet   := cdsPesquisa;

    lField := TStringField.Create(Self);
    lField.FieldName := 'PROD_CODIGO';
    lField.FieldKind := fkData;
    lField.Size      := 15;
    lField.DisplayLabel := 'Código';
    lField.DataSet   := cdsPesquisa;

    lField := TStringField.Create(Self);
    lField.FieldName := 'PROD_DESC';
    lField.FieldKind := fkData;
    lField.Size := 50;
    lField.DisplayLabel := 'Descrição';
    lField.DataSet   := cdsPesquisa;

    cdsTabPreco.Close;
    cdsTabPreco.Open;
    cdsTabPreco.First;
    while not cdsTabPreco.Eof do
    begin
      lCod := IntToStr(cdsTabPreco.FieldByName('TPRE_ID').AsInteger);
      lCampo := 'TABELAPRECO_'+lCod;
      lSql.Add(',(SELECT F.PRECO FROM PRECOPRODUTO F ');
      lSql.Add('   WHERE F.PROD_ID = P.PROD_ID ');
      lSql.Add(    AND F.TPRE_ID = '+lCod+') as 'lCampo);
  

      lField := TFMTBCDField.Create(Self);

      lField.FieldName := lCampo;

      lField.FieldKind := fkData;

      lField.DataSet   := cdsPesquisa;

      TFMTBCDField(lField).DisplayFormat := '0.,00';

      lField.DisplayLabel :=
        cdsTabPreco.FieldByName('TPRE_DESC').AsString;    

      cdsTabPreco.Next;
    end;
    cdsTabPreco.Close;

    lSql.Add('FROM PRODUTO P');
    sqlPesquisa.CommandText := lSql.Text;
  finally
    lSql.Free;
  end;
end;

Observe que cada Field e instanciado usando a classe correspondente ao seu tipo no banco, TIntegerField, TFMTBCDField, TStringField ...

Galerinha, fica a dica e até a próxima!