IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Blog de Serge Girard (aka SergioMaster)

[Actualité] [FMX] Des navigateurs de données (TBindNavigator) en couleur

Noter ce billet
par , 09/11/2024 à 12h09 (1145 Affichages)
Via ce billet, je vous propose d'égayer le composant FMX TBindNavigator.
On pourrait penser que toucher au style permettrait ce genre de chose, mais cet élément de style n'existe pas.
La couleur appliquée pour les glyphes est celle de la couleur d'un texte du style en cours. Pour les curieux le code d'obtention de cette couleur se trouve dans la procédure TBindNavButton.ApplyStyle de l'unité FMX.Bind.Navigator.
En n'utilisant "aucun" style on obtient ceci

Nom : Capture_2.PNG
Affichages : 533
Taille : 5,8 Ko

Alors qu'en VCL un navigator s'affiche ainsi

Nom : Capture_1.PNG
Affichages : 220
Taille : 4,8 Ko

Bien qu'en FMX je ne suis pas un fervent utilisateur du composant TBindNavigator ou alors uniquement de la partie concernant la navigation, je me suis mis au défi de customiser ce composant. Avant de passer à de grands travaux, l'écriture d'un composant, j'ai voulu tester la faisabilité via des Helpers.

Je vous propose donc cette unité
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
unit ColoredBindNavigator;

interface

 uses System.Classes, System.UIConsts,System.UITypes,
      FMX.Bind.Navigator, Data.Bind.Controls;

/// range TNavigateButton in three groups
const   NavigatorScrollings = [nbFirst, nbPrior, nbNext, nbLast,nbRefresh];
        NavigatorValidations = [nbInsert, nbDelete, nbEdit, nbPost, nbCancel,
                                nbApplyUpdates];
        NavigatorCancelations = [nbDelete,nbCancel,nbCancelUpdates];

type

  TNavigatorColors = record
    scroll : TAlphacolor;
    update : TAlphacolor;
    cancel : TAlphacolor;
    class operator initialize (out Dest: TNavigatorColors);
    class operator finalize (var Dest: TNavigatorColors);
  end;

  TColorNavButton = class helper for TBindNavButton
    /// set the color of the Tpath.fill.color property
    procedure setcolor(c : TAlphaColor);
    /// apply the custom colors corresponding to the TNavigateButton type
    /// Three groups NavigatorScrollings,NavigatorValidations,NavigatorCancelations
    /// see const part
    procedure ApplyColorStyle(customcolors : TNavigatorColors);
  end;

  TColorBindNavigator = class helper for TCustomBindNavigator
    /// initialize and apply custom colors
    function customcolors(scrollcolor, Updatecolor, cancelcolor : TAlphaColor) : TNavigatorColors; overload;
    function customcolors(colors : TNavigatorColors) : TNavigatorColors; overload;
  end;

implementation

{ TColorNavButton }
procedure TColorNavButton.ApplyColorStyle(customcolors : TNavigatorColors);
var defaultstylecolor : TAlphaColor;
begin
inherited;
with Self do
  DefaultStylecolor:=FPath.Fill.Color;
if (TNavigateButton(Self.index) in NavigatorScrollings)
    AND (customcolors.scroll<>TAlphacolors.Alpha)
// todo test    AND (customcolors.scroll<>DefaultStyleColor)
 then Setcolor(customcolors.scroll);
if (TNavigateButton(Self.index) in NavigatorValidations)
    AND (customcolors.update<>TAlphacolors.Alpha)
 then Setcolor(customcolors.update);
if (TNavigateButton(Self.index) in NavigatorCancelations)
    AND (customcolors.cancel<>TAlphacolors.Alpha)
 then Setcolor(customcolors.cancel);
end;

procedure TColorNavButton.setcolor(c: TAlphaColor);
begin
with Self do
   FPath.Fill.Color:=c;
end;

{ TNavigatorColors }
class operator TNavigatorColors.finalize(var Dest: TNavigatorColors);
begin
// nothing to do
end;

class operator TNavigatorColors.initialize(out Dest: TNavigatorColors);
begin
Dest.scroll:=TAlphaColors.Alpha;
Dest.update:=TAlphaColors.Alpha;
Dest.cancel:=TAlphaColors.Alpha;
end;


{ TColorBindNavigator }
function TColorBindNavigator.customcolors(scrollcolor, Updatecolor,
  cancelcolor: TAlphaColor) : TNavigatorColors;
begin
result.scroll:=scrollcolor;
result.update:=updatecolor;
result.cancel:=cancelcolor;
for var i := 0 to  self.ControlsCount-1 do
      TBindNavButton(Self.Controls[i]).ApplyColorStyle(result);
end;

function TColorBindNavigator.customcolors(
  colors: TNavigatorColors): TNavigatorColors;
begin
for var i := 0 to  self.ControlsCount-1 do
      TBindNavButton(Self.Controls[i]).ApplyColorStyle(colors);
end;

end.
L'utilisation en est assez simple :
  1. Ajoutez l'unité au projet.
  2. Dans la forme contenant le composant TBindNavigator que vous voulez "colorier", ajoutez l'unité à la clause uses dans la partie interface.Vous obtiendrez alors quelque chose de ce genre :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  Data.Bind.Controls, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts,
  Fmx.Bind.Navigator, FMX.Memo.Types, FMX.ScrollBox, FMX.Memo, FMX.Objects,
  FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
  FireDAC.Stan.StorageBin, Data.Bind.Components, Data.Bind.DBScope, Data.DB,
  FireDAC.Comp.DataSet, FireDAC.Comp.Client,
  ColoredBindNavigator;
  1. Déclarez une variable privée (à moins que vous ne vouliez la partager) au sein de votre forme.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type
  TForm1 = class(TForm)
    BindNavigator1: TBindNavigator;
    btnDark: TButton;
    Memo1: TMemo;
    FDMemTable1: TFDMemTable;
    BindSourceDB1: TBindSourceDB;
    Label1: TLabel;
    StyleBook1: TStyleBook;
    Button1: TButton;
    procedure btnDarkClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Déclarations privées }
     Colors : TNavigatorColors;
  public
    { Déclarations publiques }
  end;
  1. Utilisez ensuite les diverses fonctions proposées.

Deux exemples :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
procedure TForm1.FormCreate(Sender: TObject);
begin
CustomColorsNavigator :=true;
colors:=BindNavigator1.customcolors(Talphacolors.blue,Talphacolors.Green,Talphacolors.Red);
end;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
procedure TForm1.btnDarkClick(Sender: TObject);
begin
 colors.scroll:=Talphacolors.darkBlue;
 colors.update:=Talphacolors.darkGreen;
 colors.cancel:=TAlphacolors.darkRed;
 for var i := 0 to  BindNavigator1.ControlsCount-1 do
      TBindNavButton(BindNavigator1.Controls[i]).ApplyColorStyle(colors);
end;
Vous pourrez ainsi obtenir ce navigateur, qui sans être totalement identique à celui proposé en VCL, la technique des TPath utilisée empêchant un remplissage autre que monochrome les boutons nbApplyUpdates et nbCancelUpdates sont donc un peu pénalisés.

Nom : Capture_3.PNG
Affichages : 215
Taille : 5,3 Ko

CustomNavigator.zip contient les sources de mon programme test écrit en Delphi 12ֽ_1.
Note : L'utilisation d'un managed record limite aux versions supérieures ou égales à 10_4.

Que reste t-il à contrôler ? L'utilisation d'un style, mes essais m'ont imposé l'utilisation d'une variable et d'un évènement OnPainting (commentés dans le source proposé), vérifiez donc que les commentaires sur ce billet ne contienne pas un correctif car bien évidemment je ne veux pas rester sur cette constatation.

Envoyer le billet « [FMX] Des navigateurs de données (TBindNavigator) en couleur » dans le blog Viadeo Envoyer le billet « [FMX] Des navigateurs de données (TBindNavigator) en couleur » dans le blog Twitter Envoyer le billet « [FMX] Des navigateurs de données (TBindNavigator) en couleur » dans le blog Google Envoyer le billet « [FMX] Des navigateurs de données (TBindNavigator) en couleur » dans le blog Facebook Envoyer le billet « [FMX] Des navigateurs de données (TBindNavigator) en couleur » dans le blog Digg Envoyer le billet « [FMX] Des navigateurs de données (TBindNavigator) en couleur » dans le blog Delicious Envoyer le billet « [FMX] Des navigateurs de données (TBindNavigator) en couleur » dans le blog MySpace Envoyer le billet « [FMX] Des navigateurs de données (TBindNavigator) en couleur » dans le blog Yahoo

Catégories
Programmation , Delphi , FMX

Commentaires

  1. Avatar de SergioMaster
    • |
    • permalink
    Mon nouvel Helper
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    unit ColoredBindNavigator;
    
    interface
    
     uses System.Classes, System.UIConsts,System.UITypes,System.Types,System.SysUtils,
          FMX.Bind.Navigator, FMX.Graphics, FMX.Forms, FMX.Types,
          Data.Bind.Controls;
    
    /// range TNavigateButton in three groups
    const   NavigatorScrollings = [nbFirst, nbPrior, nbNext, nbLast,nbRefresh];
            NavigatorValidations = [nbInsert, nbDelete, nbEdit, nbPost, nbCancel,
                                    nbApplyUpdates];
            NavigatorCancelations = [nbDelete,nbCancel,nbCancelUpdates];
    
    type
    
      TNavigatorColors = record
        scroll : TAlphacolor;
        update : TAlphacolor;
        cancel : TAlphacolor;
        class operator initialize (out Dest: TNavigatorColors);
        class operator finalize (var Dest: TNavigatorColors);
      end;
    
      TColorNavButton = class helper for TBindNavButton
        /// set the color of the Tpath.fill.color property
        procedure setcolor(c : TAlphaColor);
        /// apply the custom colors corresponding to the TNavigateButton type
        /// Three groups NavigatorScrollings,NavigatorValidations,NavigatorCancelations
        /// see const part
        procedure ApplyColorStyle(customcolors : TNavigatorColors);
      end;
    
      TColorBindNavigator = class helper for TCustomBindNavigator
        /// initialize and apply custom colors
        function customcolors(scrollcolor, Updatecolor, cancelcolor : TAlphaColor) : TNavigatorColors; overload;
        function customcolors(colors : TNavigatorColors) : TNavigatorColors; overload;
      end;
    
    implementation
    
    
    { TColorNavButton }
    procedure TColorNavButton.ApplyColorStyle(customcolors : TNavigatorColors);
    var defaultstylecolor : TAlphaColor;
    begin
    inherited;
    with Self do
      DefaultStylecolor:=FPath.Fill.Color;
    if (TNavigateButton(Self.index) in NavigatorScrollings)
        AND (customcolors.scroll<>TAlphacolors.Alpha)
    //    AND (customcolors.scroll<>DefaultStyleColor)   // todo test
     then Setcolor(customcolors.scroll);
    if (TNavigateButton(Self.index) in NavigatorValidations)
        AND (customcolors.update<>TAlphacolors.Alpha)
     then Setcolor(customcolors.update);
    if (TNavigateButton(Self.index) in NavigatorCancelations)
        AND (customcolors.cancel<>TAlphacolors.Alpha)
     then Setcolor(customcolors.cancel);
    end;
    
    procedure TColorNavButton.setcolor(c: TAlphaColor);
    begin
    with Self do
       FPath.Fill.Color:=c;
    end;
    
    { TNavigatorColors }
    class operator TNavigatorColors.finalize(var Dest: TNavigatorColors);
    begin
    // nothing to do
    end;
    
    class operator TNavigatorColors.initialize(out Dest: TNavigatorColors);
    begin
    Dest.scroll:=TAlphaColors.Alpha;
    Dest.update:=TAlphaColors.Alpha;
    Dest.cancel:=TAlphaColors.Alpha;
    end;
    
    
    { TColorBindNavigator }
    function TColorBindNavigator.customcolors(scrollcolor, Updatecolor,
      cancelcolor: TAlphaColor) : TNavigatorColors;
    var colors : TNavigatorColors;
    begin
    Colors.scroll:=scrollcolor;
    Colors.update:=updatecolor;
    Colors.cancel:=cancelcolor;
    customcolors(Colors);
    Result:=Colors;
    end;
    
    function TColorBindNavigator.customcolors(
      colors: TNavigatorColors): TNavigatorColors;
    begin
    for var i := 0 to  self.ControlsCount-1 do
          TBindNavButton(Self.Controls[i]).ApplyColorStyle(colors);
    end;
    
    end.
    Le changement dans la fonction TColorBindNavigator.customcolors(scrollcolor, Updatecolor, cancelcolor: TAlphaColor)à savoir l'utilisation d'une variable colors : TNavigatorColors plutôt que d'utiliser result à fait la différence.

    Un seul reproche désormais , à mon avis, plutôt que d'utiliser un helper, appliquer cette recherche au sein d'un dérivé du TCustomGrid pour avoir un composant wyseewyg