bonjour
dans mon application je voudrais tenir compte des dimensions
des écrans des portables
et savoir comment vous faites pour mieux placer les composants
moi ils sont souvent sur None
mais je vois que c'est une très mauvaise décision
merci
bonjour
dans mon application je voudrais tenir compte des dimensions
des écrans des portables
et savoir comment vous faites pour mieux placer les composants
moi ils sont souvent sur None
mais je vois que c'est une très mauvaise décision
merci
bonjour
j'ai trouvé sa
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 uses FMX.Platform; var clientScreenScale : Single; clientScreenSize : TSize; clientScreenService : IFMXScreenService; begin if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(clientScreenService)) then begin clientScreenScale := clientScreenService.GetScreenScale; end else clientScreenScale := 1; // The display device's width: clientScreenSize.CX := Round(clientScreenService.GetScreenSize.X*clientScreenScale); // The display device's height: clientScreenSize.CY := Round(clientScreenService.GetScreenSize.Y*clientScreenScale); end;
sa peux correspondre a ce que je cherche ?
merci
C'est quoi None ?
Si c'est Align, cela arrive mais il reste les Anchors, ... personnellement, cela fait parmi des premières choses que je change quand je pose un contrôle, comment il va s'aligner au reste.
En VCL, on ne calcule quasiment jamais manuellement les tailles des controles, la taille d'une fenêtre étant indéterminée (on peut la redimensionner à volonté) même à l'époque ou l'on avait du 1024x768je suis un partisan des TPanel imbriqués
En FMX, il ne faut surtout pas calculer, je crois que le mieux c'est les Layout
Les valeurs FMX.Forms.TForm.ClientWidth et FMX.Forms.TForm.ClientHeight ne te conviennent pas ?
Si tu as un écran généré dynamiquement, les contrôles crées au RunTime, là cela se complique mais si tu peux utiliser une grille, ça serait surement plus simple, ou un équivalent d'un FlowPanel par exemple
Il y a aussi le Screen Family, je ne sais pas si c'est encore d'actualité, selon la résolution différente disposition
Enfin, pense à l'orientation, on peut changer radicalement l'aspect selon portrait, paysage ... et encore, les téléphones Android proposent du Multi-Screen avec des résolutions différentes (genre les Fold)
Aide via F1 - Utilisez l'I.A. - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !![]()
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité ! Sachez-le : l'IA remplace la très grande majorité des développeurs, pas seulement les ignares ...
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
bonjour
merci ShaiLeTroll
oui je mettait align sur None
viens de modifier avec un panel avec align sur bottom
pour que le menu reste en bas dessus il auras ma grille
suivant la largeur du portable
mais je ne sais comment faire pour donner a une grille la largeur
de l' écran du portable
peut être en mettant Windowstate de la forme a WsMaximized
et ensuite récupérer la largeur de la forme
mais je pense qu'il doit avoir un autre moyen
merci d'avance a tous pour votre aide
bonjour
je vais essayer d'être un peu plus clair
tous les composants posés sur la fiche ont étés
défini avec Anchors suggéré par ShaiLeTroll
mais ma grille est créés dans le programme
voici un aperçue de la grille
la largeur des cases devrait être ( largeur écran divisé par 4)
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 for r := 1 to 28 do begin rectang[r] := Trectangle.Create(layout1); with rectang[r] do begin Parent := Layout1; Width := largeur_cadre; Height := largeur_cadre; Position.X := pas + 20; Position.y := pasy; Fill.Color := Talphacolorrec.white; Stroke.Color := Talphacolorrec.red; Stroke.Thickness := 1; xradius := 3; yradius := 3; end; with TText.Create(Self) do begin Align := TAlignLayout.Client; Text := inttostr(r); Font.Size := 10; Parent := rectang[r]; textsettings.FontColor := TAlphaColors.red; end; pas := pas + largeur_cadre + 2; if r mod 4 = 0 then begin pas := 8; pasy := pasy + largeur_cadre + 2; end; end;
que si on est sur un portable autrement sous Windows c'est
différent
merci
Bonjour,
Dans le cas de FMX mon premier conseil est d'oublier le TPanel lui préférer un TLayout ou un dérivé de TLayout (TGridLayout, TScaledLayout, TGridPanelLayout, TFlowLayout) ou un simple TRectangle.
La vue Grille telle qu'indiquée, je la verrai bien en utilisant un TGridPanelLayout. Cela étant un TlistView pourrait aussi faire l'affaire (en utilisant DynamicApparence) j'ai du faire ce genre de chose et l'exposer dans un de mes billets blogs ou lors de posts dans le foreum FMX.
Une video de Pprem montre comment utiliser TGridPanelLayout
utiliser les tailles en pourcentages fera le nécessaire en cas de changements d'écran (suivre l'astuce exposée pour mettre 25% en largeur et 14.285714... pour la hauteur
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes), D13 (Florence)
SGBD : Firebird 2.5, 3, 5 et SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
FMX.Layouts.TGridLayout ne fait cela tout seul ?
Edit : Grillé
Aide via F1 - Utilisez l'I.A. - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !![]()
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité ! Sachez-le : l'IA remplace la très grande majorité des développeurs, pas seulement les ignares ...
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
Bonjour,
Je ne sais ps si le problème est réglé ou pas encore ..il est possible d’utiliser, evenment OnResized de Layout1 pour ajuster les dimension automatiquement
L'Align de Layout1 doit être Client pour couvrir toute la 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
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 procedure TForm1.FormCreate(Sender: TObject); var r: integer; rec: Trectangle; begin for r := 0 to 27 do begin rec := Trectangle.Create(layout1); with rec do begin Parent := Layout1; Fill.Color := Talphacolorrec.white; Stroke.Color := Talphacolorrec.red; Stroke.Thickness := 1; xradius := 3; yradius := 3; end; with TText.Create(Self) do begin Align := TAlignLayout.Client; Text := inttostr(r+1); Font.Size := 10; Parent := rec ; textsettings.FontColor := TAlphaColors.red; end; end; Layout1.RecalcSize; end; procedure TForm1.Layout1Resized(Sender: TObject); const Spacing = 2; var r: integer; rec: Trectangle; W, H, pas, pasy: single; begin W := (Layout1.LocalRect.Width - Spacing) / 4; H := (Layout1.LocalRect.Height - Spacing) / 7; Layout1.BeginUpdate; for r := 0 to Layout1.ControlsCount-1 do begin pas := r mod 4 * W + Spacing; pasy := r div 4 * H + Spacing; with Layout1.Controls[r] as TRectangle do begin SetBounds( pas, pasy, W - Spacing, H - Spacing); end; end; Layout1.EndUpdate; end;
bonjour
et merci a vous tous
vous me répondez pas a la question primaire
largeur de écran
et si on faisait les fonctions suivante
on peux ou pas
merci
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 uses FMX.Platform; private FScreenService: IFMXScreenService; function tScreenScale: Single; var ScreenService: IFMXScreenService; begin Result := 1; if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) then Result := ScreenService.GetScreenScale; end; function tScreenX: Single; var ScreenService: IFMXScreenService; begin Result := 1; if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) then Result := ScreenService.GetScreenSize.X; end; function tScreenY: Single; var ScreenService: IFMXScreenService; begin Result := 1; if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) then Result := ScreenService.GetScreenSize.Y; end; var largeur:integer; largeur:=round(tscreenX);
Pour afficher le Layout sur tout l'ecran d'un mobile :
et puis tu peux lire ses dimensionsL'Align de Layout1 doit être Client pour couvrir toute la forme.
Mais pourquoi utiliser la taille de l'écran alors que vous serez limité à la taille de la fenêtre ou du layout conteneur, il faut utiliser la dimension dans la zone cliente.
Avez vous tenter le TGridLayout ou TGridPanelLayout pour gérer cela sans calcul de dimension ?
Aide via F1 - Utilisez l'I.A. - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !![]()
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité ! Sachez-le : l'IA remplace la très grande majorité des développeurs, pas seulement les ignares ...
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
J'ignore pourquoi mon rappel sur la bonne utilisation du TGridLayout a reçu un
Si l'on utilise TGridLayout, il faut profiter de ItemWidth et ItemHeight, ne pas calculer les positions manuellement
Idem, pour le spacing, suffit d'utiliser un TLayout parent pour ajouter un Padding
Code évoqué, il n'y a aucun code compliqué à faire pour gérer le Resize
Suffit de laisser faire le TGridLayout qui fait cela tout seul
Je suis reparti du code simplifié de tintin62 et Informt2025, comme je ne fais jamais de FMX, cela m'a pris un peu de temps, soit 20 minutes et 20 de plus pour ajouter le padding.
Si la grille s'affiche automatiquement sans bouton, je conseille de créer la grille après le OnShow, je ne connais pas en FMX,
il faut de préférence que cela soit hors du FormCreate pour que la taille de la fenêtre soit correctement calculée (plein écran forcément en mobile), un OnActivate avec un flag FirstActivate par exemple comme à l'époque de Delphi 3
Sur Windows, avec WindowState à wsMaximized + FormCreate crée la grille, cela fonctionne, sur mobile, c'est à tester !
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 unit GridLayoutRectangle_MainForm; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Edit, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, FMX.Objects; type TForm1 = class(TForm) GridLayoutOfRectangle: TGridLayout; btnFillLayout: TButton; edCol: TEdit; edRow: TEdit; ckbKeepColRow: TCheckBox; edSpacing: TEdit; RectangleParent: TRectangle; procedure btnFillLayoutClick(Sender: TObject); procedure GridLayoutOfRectangleResize(Sender: TObject); private { Déclarations privées } public { Déclarations publiques } end; var Form1: TForm1; implementation {$R *.fmx} uses System.Math; procedure TForm1.btnFillLayoutClick(Sender: TObject); var I: Integer; L: TLayout; R: TRectangle; begin for I := GridLayoutOfRectangle.ComponentCount - 1 downto 0 do GridLayoutOfRectangle.Components[I].Free(); RectangleParent.Padding.Left := Max(StrToIntDef(edSpacing.Text, 0), 0); RectangleParent.Padding.Right := Max(StrToIntDef(edSpacing.Text, 0), 0); RectangleParent.Padding.Top := Max(StrToIntDef(edSpacing.Text, 0), 0); RectangleParent.Padding.Bottom := Max(StrToIntDef(edSpacing.Text, 0), 0); for I := 1 to StrToIntDef(edCol.Text, 1) * StrToIntDef(edRow.Text, 1) do begin L := TLayout.Create(GridLayoutOfRectangle); with L do begin Parent := GridLayoutOfRectangle; Align := TAlignLayout.Client; Padding.Left := Max(StrToIntDef(edSpacing.Text, 0), 0); Padding.Right := Max(StrToIntDef(edSpacing.Text, 0), 0); Padding.Top := Max(StrToIntDef(edSpacing.Text, 0), 0); Padding.Bottom := Max(StrToIntDef(edSpacing.Text, 0), 0); end; R := TRectangle.Create(L); with R do begin Parent := L; Align := TAlignLayout.Client; Fill.Color := TAlphaColorRec.White; Stroke.Color := TAlphaColorRec.Red; Stroke.Thickness := 1; end; with TText.Create(R) do begin Parent := R; Align := TAlignLayout.Client; Text := I.ToString(); Font.Size := 10; TextSettings.FontColor := TAlphaColors.red; end; end; GridLayoutOfRectangle.ItemWidth := Trunc(GridLayoutOfRectangle.Width / Max(StrToIntDef(edCol.Text, 1), 1)); GridLayoutOfRectangle.ItemHeight := Trunc(GridLayoutOfRectangle.Height / Max(StrToIntDef(edRow.Text, 1), 1)); end; procedure TForm1.GridLayoutOfRectangleResize(Sender: TObject); begin if ckbKeepColRow.IsChecked then begin GridLayoutOfRectangle.ItemWidth := Trunc(GridLayoutOfRectangle.Width / Max(StrToIntDef(edCol.Text, 1), 1)); GridLayoutOfRectangle.ItemHeight := Trunc(GridLayoutOfRectangle.Height / Max(StrToIntDef(edRow.Text, 1), 1)); end; end; end.
Code dfm : 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 object Form1: TForm1 Left = 0 Top = 0 Caption = 'Form1' ClientHeight = 621 ClientWidth = 512 FormFactor.Width = 320 FormFactor.Height = 480 FormFactor.Devices = [Desktop] DesignerMasterStyle = 0 object btnFillLayout: TButton Position.X = 8.000000000000000000 Position.Y = 16.000000000000000000 TabOrder = 0 Text = 'Fill Layout' OnClick = btnFillLayoutClick end object edCol: TEdit Touch.InteractiveGestures = [LongTap, DoubleTap] TabOrder = 1 Text = '4' Position.X = 96.000000000000000000 Position.Y = 16.000000000000000000 OnChange = btnFillLayoutClick end object edRow: TEdit Touch.InteractiveGestures = [LongTap, DoubleTap] TabOrder = 2 Text = '7' Position.X = 200.000000000000000000 Position.Y = 16.000000000000000000 OnChange = btnFillLayoutClick end object ckbKeepColRow: TCheckBox Position.X = 312.000000000000000000 Position.Y = 16.000000000000000000 Size.Width = 81.000000000000000000 Size.Height = 19.000000000000000000 Size.PlatformDefault = False TabOrder = 3 Text = 'Reponsive' OnChange = GridLayoutOfRectangleResize end object edSpacing: TEdit Touch.InteractiveGestures = [LongTap, DoubleTap] TabOrder = 4 Text = '2' Position.X = 400.000000000000000000 Position.Y = 16.000000000000000000 OnChange = btnFillLayoutClick end object RectangleParent: TRectangle Anchors = [akLeft, akTop, akRight, akBottom] Fill.Color = claWhite Position.X = 8.000000000000000000 Position.Y = 48.000000000000000000 Size.Width = 497.000000000000000000 Size.Height = 566.000000000000000000 Size.PlatformDefault = False Stroke.Color = claRed object GridLayoutOfRectangle: TGridLayout Align = Client ItemHeight = 64.000000000000000000 ItemWidth = 64.000000000000000000 Orientation = Horizontal Size.Width = 497.000000000000000000 Size.Height = 566.000000000000000000 Size.PlatformDefault = False TabOrder = 0 OnResize = GridLayoutOfRectangleResize end end end
![]()
Aide via F1 - Utilisez l'I.A. - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !![]()
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité ! Sachez-le : l'IA remplace la très grande majorité des développeurs, pas seulement les ignares ...
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
Bonjour,
Reste à voir quel et le bon choix un Resize ou une mise en échelle (scale) et comme il a posté beaucoup de code sur les puzzles j'ai un doute
L'exemple fourni n'est donc pas au top dans ce cas si c'est un pour un Puzzle
Si ce n'est pas une forme rectangulaire comme une pièce de Puzzle, l'approche par la TGridLayout n'est pas possible, cela ne va pas gérer des formes qui débordent et il faut conserver les proportions inialies, c'est plus une gestion de Sprite donc plutôt un Scale, avec si possible des images multi-résolution, car le Scale a ses limites.
Mais l'utilisation d'un Layout parent conteneur du Puzzle et utiliser le OnResize reste une bonne approche, on connait la taille cliente (le cadre), on connait la taille source (l'image), il faut calculer le ratio de proportion pour effectuer le Scale approprié.
Je ne connais pas le Scale en FMX, je ne connais que celui du Zoom Windows, généralement, on n'a pas grand chose à faire, en dehors d'ajuster les largeurs de colonne ou de StatusPanel, en mobile, je suppose que c'est assez différent, rien que la transition Portrait Paysage à gérer.
Et là, ci c'est un Puzzle, faut tout faire à la main, mais j'utiliserais dans ce cas une approche POO, ce n'est pas le conteneur qui dessine les pièces, c'est chaque pièce qui sait se dessiner elle-même dans un super conteneur, dans la boite, sur le bord du puzzle, à une mauvaise position et à sa juste position.
Je n'ai pas lu les autres sujets mais je suppose qu'une Pièce de Puzzle c'est juste un TPath, et l'ensemble d'un Puzzle c'est une Image d'origine, N pièce Produit en TPath et l'intérieur le Sprite de l'image correspondant, éventuellement un second TPath pour un effet 3D de la pièce.
En Windows, je l'aurais fait avec des régions pour créer des formes complexe découpé d'un Panel, pour ne pas devoir gérer le click manuellement.
Aide via F1 - Utilisez l'I.A. - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !![]()
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité ! Sachez-le : l'IA remplace la très grande majorité des développeurs, pas seulement les ignares ...
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
Bonsoir a tous
une petite question pour ShaiLeTroll
j'ai fait comme vous m'aviez dit de mettre un
TGridPanelLayout mais j'arrive pas a centrer le texte du haut
et celui du bas
vous joint fichier
merci
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 object Form1: TForm1 Left = 0 Top = 0 Caption = 'Form1' ClientHeight = 542 ClientWidth = 201 Fill.Color = xFFD8F4F5 Fill.Kind = Solid FormFactor.Width = 320 FormFactor.Height = 480 FormFactor.Devices = [Desktop] OnCreate = FormCreate OnClose = FormClose DesignerMasterStyle = 3 object PathAnimation1: TPathAnimation Duration = 0.200000002980232200 end object Layout1: TLayout Align = Client Size.Width = 201.000000000000000000 Size.Height = 429.000000000000000000 Size.PlatformDefault = False TabOrder = 1 end object GridPanelLayout1: TGridPanelLayout Align = Bottom Position.Y = 429.000000000000000000 Size.Width = 201.000000000000000000 Size.Height = 113.000000000000000000 Size.PlatformDefault = False TabOrder = 0 ColumnCollection = < item Value = 50.000000000000000000 end item Value = 50.000000000000000000 end> ControlCollection = < item Column = 0 ColumnSpan = 2 Control = text1 Row = 0 end item Column = 0 Control = Button2 Row = 1 end item Column = 1 Control = Button3 Row = 1 end item Column = 0 ColumnSpan = 2 Control = Text2 Row = 2 RowSpan = 2 end> RowCollection = < item Value = 25.000000000000000000 end item Value = 25.000000000000000000 end item Value = 50.000000000000000000 end item SizeStyle = Auto end> object text1: TLabel Align = Center StyledSettings = [Family, Size, Style] Size.Width = 630.000000000000000000 Size.Height = 40.000000000000000000 Size.PlatformDefault = False TextSettings.FontColor = claBlue TextSettings.HorzAlign = Center Text = '****************************' TabOrder = 0 end object Button2: TButton Anchors = [] StyledSettings = [Family, Size, Style] Position.X = 13.750000000000000000 Position.Y = 28.375000000000000000 Size.Width = 73.000000000000000000 Size.Height = 28.000000000000000000 Size.PlatformDefault = False TabOrder = 1 Text = 'Lancer' TextSettings.FontColor = claBlue TextSettings.Trimming = None OnClick = Button1Click end object Button3: TButton Anchors = [] Position.X = 114.250000000000000000 Position.Y = 28.250000000000000000 Size.Width = 73.000000000000000000 Size.Height = 28.250000000000000000 Size.PlatformDefault = False TabOrder = 2 Text = 'Quitter' TextSettings.Trimming = None OnClick = Button2Click end object Text2: TText Anchors = [] Position.X = 52.000000000000000000 Position.Y = 64.750000000000000000 Size.Width = 97.000000000000000000 Size.Height = 40.000000000000000000 Size.PlatformDefault = False Text = 'Amigo' TextSettings.FontColor = claCrimson end end end
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351 unit amig; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects, FMX.Controls.Presentation, FMX.StdCtrls,FMX.Ani, FMX.Layouts; type TForm1 = class(TForm) PathAnimation1: TPathAnimation; Layout1: TLayout; GridPanelLayout1: TGridPanelLayout; text1: TLabel; Button2: TButton; Button3: TButton; Text2: TText; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormDestroy(Sender: TObject); private { Déclarations privées } public { Déclarations publiques } procedure cre_boule(a: integer; var tr: TRectangle; n: integer); procedure boule_blanche; procedure grille; procedure ballearrivéFinish(Sender: TObject); procedure trajet; end; var Form1: TForm1; rectang: array [1 .. 28] of TRectangle; pas: integer; pasy: integer; num: integer; uneboule: array [1 .. 7] of Tcircle; largeur_cadre: integer; boule_blanc: Tcircle; PathAnimation1: TPathAnimation; bal: integer; Tableau: array of integer; // le tableau Anim: TFloatAnimation; largeur: integer; info: string; decalx:integer; implementation {$R *.fmx} {$R *.Windows.fmx MSWINDOWS} {$R *.iPhone55in.fmx IOS} {$R *.iPhone.fmx IOS} {$R *.iPhone47in.fmx IOS} {$R *.iPhone4in.fmx IOS} {$R *.XLgXhdpiTb.fmx ANDROID} function FloatS(const aValue: single): string; var Buf: TFormatSettings; begin Buf := FormatSettings; Buf.DecimalSeparator := '.'; Result := FloatToStr(aValue, Buf); end; procedure TForm1.ballearrivéFinish(Sender: TObject); var numero: integer; begin PathAnimation1.Stop; boule_blanc.Visible := false; numero := Tableau[bal]; cre_boule(bal, rectang[numero], numero); if (PathAnimation1.Running = false) and (bal < 7) then begin bal := bal + 1; trajet; end; if (PathAnimation1.Running = false) and (bal = 7) then begin text1.Text := inttostr(Tableau[1]) + ' ' + inttostr(Tableau[2]) + ' ' + inttostr(Tableau[3]) + ' ' + inttostr(Tableau[4]) + ' ' + inttostr(Tableau[5]) + ' ' + inttostr(Tableau[6]) + ' ' + inttostr(Tableau[7]); Button2.Enabled := true; Anim.Loop := false; Text2.RotationAngle := 0; end; end; procedure TForm1.trajet; var xpo, ypo: single; nu: integer; begin nu := Tableau[bal]; xpo := rectang[nu].Position.X + 2; ypo := rectang[nu].Position.y + 2; boule_blanc.Visible := true; PathAnimation1.Path.ClosePath; PathAnimation1.Path.Clear; boule_blanc.Position.X := xpo + 20; boule_blanc.Position.y := ypo + 20; { pathanimation1.Path.Data := 'M 0,0 l 100,50 l 200,200 l 0,10 l0,400 '+'l '+ floattostr(xpo)+','+ floattostr(ypo); } PathAnimation1.Path.MoveTo(PointF(0, 0)); PathAnimation1.Path.LineTo(PointF(10, 150)); PathAnimation1.Path.LineTo(PointF(20, 200)); PathAnimation1.Path.LineTo(PointF(90, 150)); PathAnimation1.Path.LineTo(PointF(xpo + 10, ypo + 10)); PathAnimation1.Path.ClosePath; PathAnimation1.OnFinish := Form1.ballearrivéFinish; PathAnimation1.Start; end; procedure TForm1.boule_blanche; begin boule_blanc := Tcircle.Create(Form1); { tr ou form1 ???? } boule_blanc.Parent := Form1; boule_blanc.Fill.Kind := TBrushKind.Gradient; boule_blanc.Fill.Gradient.Style := TGradientStyle.Radial; boule_blanc.Fill.Gradient.Color := $FFE2E7B3; boule_blanc.Stroke.Color := TAlphaColors.Blue; boule_blanc.Height := largeur_cadre; boule_blanc.Width := largeur_cadre; boule_blanc.Position.X := random(40) + 2; boule_blanc.Position.y := random(40) + 2; boule_blanc.Visible := false; PathAnimation1 := TPathAnimation.Create(Self); PathAnimation1.Parent := boule_blanc; PathAnimation1.Path.Clear; PathAnimation1.Loop := false; PathAnimation1.Duration := 2; end; procedure TForm1.grille; var r: integer; begin pas:=decalx; for r := 1 to 28 do begin rectang[r] := TRectangle.Create(Form1); with rectang[r] do begin Parent := Layout1; Width := largeur_cadre; Height := largeur_cadre; Position.X := pas; Position.y := pasy; Fill.Color := Talphacolorrec.white; Stroke.Color := Talphacolorrec.red; Stroke.Thickness := 1; xradius := 3; yradius := 3; end; with TText.Create(Self) do begin Align := TAlignLayout.Client; Text := inttostr(r); Font.Size := 10; Parent := rectang[r]; textsettings.FontColor := TAlphaColors.red; end; pas := pas + largeur_cadre + 2; if r mod 4 = 0 then begin pas := decalx; pasy := pasy + largeur_cadre + 2; end; end; end; procedure TForm1.Button1Click(Sender: TObject); var I, C, r, t, a: integer; begin Anim.Enabled := false; Text2.RotationAngle := 0; Anim.Enabled := true; Anim.Loop := true; bal := 1; Form1.Button2.Enabled := false; Form1.text1.Text := '***************'; for a := 1 to 7 do begin if uneboule[a] <> nil then begin freeandnil(uneboule[a]); end; end; randomize; for t := 1 to 50 do begin for I := 1 to 28 do Tableau[I] := I; for I := 1 to 28 do begin r := random(28) + 1; C := Tableau[I]; { if c>28 then showmessage(inttostr(c)); } Tableau[I] := Tableau[r]; Tableau[r] := C; end; end; for a := 1 to 7 do begin num := Tableau[a]; end; trajet; end; procedure TForm1.Button2Click(Sender: TObject); begin application.Terminate; end; procedure TForm1.cre_boule(a: integer; var tr: TRectangle; n: integer); begin uneboule[a] := Tcircle.Create(tr); { tr ou form1 ???? } uneboule[a].Parent := tr; uneboule[a].Fill.Kind := TBrushKind.Gradient; uneboule[a].Fill.Gradient.Style := TGradientStyle.Radial; uneboule[a].Fill.Gradient.Color := $FFE2E7B3; uneboule[a].Stroke.Color := TAlphaColors.Blue; uneboule[a].Width := largeur_cadre - 2; uneboule[a].Height := largeur_cadre - 2; uneboule[a].Align := TAlignLayout.Center; with TText.Create(Self) do begin Align := TAlignLayout.Client; Text := inttostr(n); Font.Size := 24; Parent := uneboule[a]; textsettings.FontColor := TAlphaColors.Blue; end; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if boule_blanc <> nil then begin boule_blanc.Free; boule_blanc := nil; end; end; procedure TForm1.FormCreate(Sender: TObject); begin {$IFDEF MSWINDOWS} largeur_cadre := round(Layout1.Width / 5); {$ENDIF} {$IFDEF ANDROID} largeur_cadre := round(Layout1.Width / 5); {$ENDIF} setlength(tableau,28); largeur := round((largeur_cadre * 5)) + 20; decalx:=28; pas := 0; pasy := 4; // dessine la grille grille; // create boule pour simulation de la boule boule_blanche; Text2.RotationAngle := 0; Anim := TFloatAnimation.Create(Self); Anim.Parent := Text2; Anim.Duration := 5; Anim.StartValue := 0; Anim.StopValue := 360; Anim.Loop := true; Anim.PropertyName := 'Text2.RotationAngle'; Anim.Enabled := false; end; procedure TForm1.FormDestroy(Sender: TObject); var a: integer; begin Tableau := []; for a := 1 to 7 do freeandnil(uneboule[a]); for a := 1 to 28 do freeandnil(rectang[a]); if boule_blanc <> nil then freeandnil(boule_blanc); end; end.
bonsoir
c bon j'ai trouvé
je crois
faut mettre le texte en align center et
mettre a Margins Left une valeur décalage
++
je ne sais pas si TPanel gère correctement la transparence complexe des images en arrière plan et même TCustomTransparentControl cafouille avec les formes complexes je pense que TGraphicControl fait un bon travaille sans alourdir le code juste implémenter le HitTest pour les tests de region et Paint pour dessiner:En Windows, je l'aurais fait avec des régions pour créer des formes complexe découpé d'un Panel, pour ne pas devoir gérer le click manuellement.
![]()
J'ai testé ton dernier code voila quelques remarques;j'ai fait comme vous m'aviez dit de mettre un
TGridPanelLayout mais j'arrive pas a centrer le texte du haut
et celui du bas
La marge gauche de la grille est définie manuellement decalx:=28; ce qui interfère avec l'alignment automatique.
Pour ajuster la grille au centre de l'écran garder layout1 tel quel avec Align = Client et ajoute dans Layout1 un TScaledLayout avec Align = Fit ce dernier contrôle devient le parent de la grille et gère le redimensionnement .
Les modifications à apporter à TForm1.grille:
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 procedure TForm1.grille; var r, w: integer; begin decalx := 2; pas:=decalx; for r := 1 to 28 do begin rectang[r] := TRectangle.Create(Form1); with rectang[r] do begin Parent := ScaledLayout1; Width := largeur_cadre; Height := largeur_cadre; Position.X := pas; Position.y := pasy; Fill.Color := Talphacolorrec.white; Stroke.Color := Talphacolorrec.red; Stroke.Thickness := 1; xradius := 3; yradius := 3; end; with TText.Create(Self) do begin Align := TAlignLayout.Client; Text := inttostr(r); Font.Size := 10; Parent := rectang[r]; textsettings.FontColor := TAlphaColors.red; end; pas := pas + largeur_cadre + 2; if r mod 4 = 0 then begin w := pas +2; pas := decalx; pasy := pasy + largeur_cadre + 2; end; end; with ScaledLayout1 do begin Align := TAlignLayout.None; OriginalWidth:= w; OriginalHeight:= pasy; // si tu ne veux pas garder les proportions désactive cette ligne Width := Height *( w / pasy); Align := TAlignLayout.fit; end; end;
Probablement il est aussi nécessaire de remplacer Layout1 par ScaledLayout1
largeur_cadre := round(Layout1.Width / 5);
Partager