Ir al contenido



Foto

Vcl/FMX: Resaltar texto parcialmente

VCL FMX Multiplataforma Canvas Negrita Resaltar Parcial Parcialmente Busquedas

  • Por favor identifícate para responder
3 respuestas en este tema

#1 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 27 julio 2016 - 09:25

Hola a todos
 
Este truco sirve cuando por ejemplo mostramos datos en un Grid y queremos resaltar parte del texto (color, negrita, etc). Esta muy bueno cuando hacemos una busqueda parcial, y queda resaltado que parte del string es la que coincide con la busqueda. 
 
El efecto buscado seria, si busco Juan que me resalte asi:
 
Juan
Juan Carlos
Pedro Juan
AlgoJuanOtraCosa
 
El codigo en realidad es obra de ecfisa, lo interesante es que el algoritmo es aplicable facilmente a casi cualquier clase, porque todo se basa en codigo RTL para manipulacion de strings, y luego el pintado es usando TCanvas. Es cierto que hay algunas pequeñas diferencias entre el manejo de Canvas Vcl y el de FMX
 
Si yo no he entendido mal, lo que hace Daniel es ir dibujando con el canvas de a "trocitos" el string, dividiendo el mismo en tres partes. 
 
En el codigo que voy a usar de ejemplo, simplemente voy a resaltar usando negrita para la parte que coincide y normal para el resto
 
El codigo para Vcl lo pueden encontrar en el hilo original
 
Para FMX, las pruebas las hice con un componente TStringGrid. Es necesario que tengamos TStringGrid.DefaultDrawing a False
 
Luego simplemente metemos un hook para el evento TStringGrid.OnDrawColumnCell
 
Solo hay unas cosas mas que se deben notar:
 
  • SearchString es una propiedad de lectura/funcion que devuelve un string. Vendria a ser el string por el cual estamos buscando

  • IsColumnTextHighlightable es una funcion que como se puede ver, devuelve un Boolean que indica si la columna que recibe el evento debe implementar el pintado por defecto o el pintado custom

  • He renombrado algunas variables del codigo original de ecfisa, ya que a mi me confunde mucho los nombres cortos y simples como a, b, c

  • El procedimiento anidado DrawText esta en la version para FMX porque el metodo TCanvas.FillText es bastante "aburrido", ya que requiere de varios parametros que son siempre los mismos. Lo unico que me interesa variar son el Bounds y el Text. La forma mas purista de resolverlo es con un ayudante de clase (class helper) para TCanvas


delphi
  1. procedure TForm1.OnCreate(Sender: TObject);
  2. begin
  3. StringGrid1.DefaultDrawing := False;
  4. end;
  5.  
  6. procedure TForm1.StringGrid1DrawColumnCell(Sender: TObject; const Canvas: TCanvas;
  7. const Column: TColumn; const [Ref] Bounds: TRectF; const Row: Integer; const [Ref] Value: TValue;
  8. const State: TGridDrawStates);
  9.  
  10. procedure DrawText(Bounds: TRectF; const LeftDelta: Single; const Text: string);
  11. begin
  12. Bounds := RectF(LeftDelta, Bounds.Top, Bounds.Right, Bounds.Bottom);
  13. Canvas.FillText(Bounds, Text, False, 1, [], TTextAlign.Leading);
  14. end;
  15. var
  16. Handled: Boolean;
  17. StringLeft, StringMiddle, StringRight, CellStringValue: string;
  18. p: Integer;
  19. LeftBoundDelta: Single;
  20. FontStyles: TFontStyles;
  21. begin
  22. Handled := False;
  23. try
  24. if not IsColumnTextHighlightable(Column) then
  25. Exit;
  26.  
  27. CellStringValue := Value.AsString;
  28.  
  29. if not AnsiStartsText(SearchString, CellStringValue) then
  30. Exit;
  31.  
  32. p := AnsiPos(AnsiUpperCase(SearchString), AnsiUpperCase(CellStringValue));
  33. if p <> 0 then
  34. begin
  35. StringLeft := Copy(CellStringValue, 1, p - 1);
  36. StringMiddle := Copy(CellStringValue, p, Length(SearchString));
  37. StringRight := Copy(CellStringValue, p + Length(SearchString), MaxInt);
  38.  
  39. Canvas.Font.Assign(StringGrid1.TextSettings.Font);
  40. Canvas.Fill.Color := TAlphaColorRec.Black;
  41. FontStyles := StringGrid1.TextSettings.Font.Style;
  42.  
  43. LeftBoundDelta := Bounds.Left + 2;
  44. Canvas.Font.Style := FontStyles;
  45. DrawText(Bounds, LeftBoundDelta, StringLeft);
  46.  
  47. LeftBoundDelta := LeftBoundDelta + Canvas.TextWidth(StringLeft);
  48. Canvas.Font.Style := [TFontStyle.fsBold];
  49. DrawText(Bounds, LeftBoundDelta, StringMiddle);
  50.  
  51. LeftBoundDelta := LeftBoundDelta + Canvas.TextWidth(StringMiddle);
  52. Canvas.Font.Style := FontStyles;
  53. DrawText(Bounds, LeftBoundDelta, StringRight);
  54. Handled := True;
  55. end;
  56. finally
  57. if not Handled then
  58. StringGrid1.DefaultDrawColumnCell(Canvas, Column, Bounds, Row, Value, State);
  59. end;
  60. end;

 
Efecto conseguido en un TGrid FMX:
 
186711a0e10967a11f8ab324a792964do.jpg
 
 
Efecto conseguido en un TDBGrid Vcl
 
4a069c3fb557d71e9a68d4296075aed5o.jpg
 
 

  • 2

#2 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 516 mensajes
  • LocationCali, Colombia

Escrito 28 julio 2016 - 06:26

Excelente, muchas gracias por el aporte.


  • 0

#3 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.962 mensajes
  • LocationMéxico

Escrito 28 julio 2016 - 08:57

Muy interesante, gracias amigo Agustín

 

Saludos


  • 0

#4 jmonfor

jmonfor

    Member

  • Miembros
  • PipPip
  • 20 mensajes

Escrito 29 julio 2016 - 10:42

Muy interesante. Gracias por el aporte!!
  • 0





Etiquetado también con una o más de estas palabras: VCL, FMX, Multiplataforma, Canvas, Negrita, Resaltar, Parcial, Parcialmente, Busquedas