Toujours dans mes délires de composants FMX (maintenant que j'ai trouvé comment faire des liens) je suis parti sur la création d'un compas "numérique" Pièce jointe 610929
Cependant je n'arrive pas à maitriser ArcDial. Sur l'image, le bouton pointe au Nord (en fait le 0, obtenu au Nord grâce à une rotation de -90) Pièce jointe 610930
cependant quand je tourne le bouton vers la droite (vers l'Est donc en théorie) je me retouve avec des valeurs négatives et donc vers l'Ouest !
je m'en suis sorti en multipliant ArcDial.Value par -1 mais est-ce la seule solution ?
// dans ce code test, c'est avant la liaison par livebindings
// en fait c'est pour l'instant sans unité spéciale pour écrire le composant,
// l'objet étant de tester l'affichage (graduations)
procedure TForm1.ArcDial1Change(Sender: TObject);
var i,ng,s : integer;
Angle : single;
begin
GridLayout1.BeginUpdate;
GridLayout1.DeleteChildren;
Angle:=Trunc(ArcDial1.Value)*-1;
ng:=Trunc(GridLayout1.Width/10);
s:=Trunc(Angle)-(ng div2);
for i:= s to Trunc(Angle)+(ng div2)do DrawGraduation(GridLayout1,round(degnormalize(i)));
GridLayout1.EndUpdate;
end;
procedure TForm1.drawgraduation(const P : TGridLayout; d : integer);
var PRectangle : TRectangle;
begin
PRectangle:= TRectangle.Create(P);
with PRectangle dobegin
Width:=4;
with TText.Create(PRectangle)dobegin
Height:=20;
Width:=30;
Align:=TAlignLayout.Center;
Parent:=PRectangle;
Margins.Top:=50;
Font.Style:=[TFontStyle.fsBold];
case d of0 : Text:=North;
45 : Text:=NorthEast;
90 : Text:=East;
135: Text:=SouthEast;
180: Text:=South;
225: Text:=SouthWest;
270: Text:=West;
315: Text:=NorthWest;
elsebeginif(d mod10)=0thenbegin
Text:=Format('%d°',[d]);
Margins.Top:=30;
Font.Style:=[TFontStyle.fsItalic];
end;
end;
end;
end;
Margins.Bottom:=8;
if(d mod10)=0then Margins.Bottom:=0elseif(d mod5)=0then Margins.Bottom:=5;
margins.left:=3;
margins.Right:=4;
Stroke.Kind:=TBrushKind.None;
Fill.Color:=TAlphaColors.Black;
Align:=TAlignLayout.Top;
end;
P.AddObject(pRectangle);
end;
29/12/2021, 10h02
Paul TOTH
hello, je ne sais pas pour ta question, mais ton code me pique les yeux :)
pourquoi détruire et reconstruire tous les éléments à chaque fois ? à vu de nez tu as toujours le même nombre de composants, il suffit donc d'ajuster leurs propriétés non ?
29/12/2021, 10h16
SergioMaster
Citation:
Envoyé par Paul TOTH
pourquoi détruire et reconstruire tous les éléments à chaque fois ? à vue de nez tu as toujours le même nombre de composants, il suffit donc d'ajuster leurs propriétés non ?
Comme je l'ai écrit un premier essai, il a l'avantage d'avoir une sensation de défilement horizontal.
Ton nez n'est pas tout à fait assez long, le nombre de composants dépend de la largeur du compas donc en cas de resize c'est à refaire, ne pas oublier que mon objectif est un futur composant (donc une procedure Paint quelque part)
Mais je n'ai pas encore testé en changeant simplement les propriétés lors d'un changement de valeur, pas sûr que l'effet soit identique, wait and see !
29/12/2021, 13h31
_alx_
Citation:
Envoyé par SergioMaster
je m'en suis sorti en multipliant ArcDial.Value par -1 mais est-ce la seule solution ?
J'ai regardé le code de TArcDial dans l'unité FMX.StdCtrls. Ce sont bien les conventions mathématiques standards qui sont utilisées:
1) les angles sont comptés dans le sens direct, c'est-à-dire dans le sens inverse de celui des aiguilles d'une montre.
2) l'origine des angles (quand on a juste posé le composant sur la fiche) est sur l'axe horizontal dans le sens positif.
Donc, dans l'exemple de SergioMaster, le point "Est" correspond à 0° (Arcdial.Value) et l'angle de "Est" à "Nord" vaut +90°.
Mais ce qui est trompeur et peut faire penser que les angles seraient comptés dans le sens des aiguilles d'une montre, c'est que l'orientation du bouton (Arcdial.RotationAngle) est mesurée par l'angle de la rotation d'ensemble du bouton (matérialisée par le point qu'on entraîne avec la souris). Mais ici intervient un résultat mathématique (contre intuitif mais facile à montrer) : la transformation des coordonnées d'un point dans un repère tournant est la rotation inverse (c'est-à-dire d'angle opposé) de la rotation qui change ce point dans le repère initial. D'où la valeur Arcdial.RotationAngle = - 90° pour faire passer l'origine du bouton de "Est" à "Nord".
(Accessoirement, le code qui donne la valeur de l'angle entre deux points (fonction AngleBetween) me semble inutilement compliqué: il utilise seulement la fonction ArcCos de System.Math en oubliant la fonction AcrTan2 plus adaptée et présente dans la même unité)
29/12/2021, 21h45
pprem
Citation:
Envoyé par SergioMaster
Mais je n'ai pas encore testé en changeant simplement les propriétés lors d'un changement de valeur, pas sûr que l'effet soit identique, wait and see !
tu es en FMX, amuse toi aussi avec les TFloatAnimation ;) (bon, ok, ça peut foutre le bordel quand on en fout partout, mais sont sympa des fois)
Et, pour re-répondre @Paul, effectivement si mon nombre de graduation restait toujours identique (une propriété de mon composant) il serait envisageable de jouer sur la propriété des rectangles enfants. Je vais faire un essai.
OK, ce n'est pas encore, loin d'être, une panacée : des composants aboutis.
Seul mon "Thermometre" est dans une unité séparée et dans un dpk. Il y a beaucoup d'amélioration à y apporter :
- des graduations
- un réservoir en bas
- un maximum/minimum de température et bien entendu la prise en compte de ceux-ci
Mon seul objectif de départ était de trouver un moyen de faire des liens LinkPropertyToField plutôt que LinkControlToField entre composants et données
(toute la différence entre Field1 vers Progress des "thermomètres" et Field1 ver SelectedValue) de fil en aiguille j'en ai concoté plusieurs.
La documentation de base ne proposait que le LinkControlToField (bidirectionnel) en utilisant Data.Bind.Components.RegisterObservableMember. J'ai longtemps pensé q'une option aurait permis de changer (autrement que dans le code) le type de liaison. Après m'être acharné sur cette idée, et une fouille approfondie des sources, j'ai découvert qu'il fallait utiliser un autre type "d'enregistrement" (terme à trouver) : Data.Bind.Components.RegisterValuePropertyName.
Ceci pourrait faire l'objet d'une FAQ, quoique je ne soit pas sûr que ce soit une Question Fréquente :lol:
30/12/2021, 09h46
Paul TOTH
1 pièce(s) jointe(s)
tient, j'ai fait un test rapide
c'est un mélange de canvas et de composants qui peut s'adapter facilement en tout canvas
le principe est de dessiner sur un bitmap tout le cadran, puis de l'afficher dans deux TImage qui scroll dans un layout en clipping :)
le principe est de dessiner sur un bitmap tout le cadran, puis de l'afficher dans deux TImage qui scroll dans un layout en clipping :)
Merci, cette technique servirait très bien dans le cadre d'une utilisation de style (FMX) dans un composant. Une piste que je n'ai pas encore creusée n'en étant pour l'instant qu'aux liaisons
03/01/2022, 08h54
Gouyon
Bonjour à tous et bonne année
C'est amusant mais je pensais compléter ma collection de composant avec un truc dans ce genre.
Ce qu'il faut savoir avec les angles c'est que c'est un peu chiant à gérer en général il faut se fixer un domaine (0-360 ou -180 +180) et quelque soit la valeur entrée la remettre dans ce domaine. Après il faut gérer le problème des angles situés à proximité des limites extérieures du domaine.
Ensuite pour ce qui est de l'affichage j’essaie dans la mesure du possible de paramétrer au maximum pour que l'utilisateur puisse adapter au mieux l'affichage en fonction de son usage.
Par exemple combien de degrés sont affiché dans ton rectangle, combien de degré représente une graduation...
Ensuite pour ce qui est de l'affichage je dessine tout dans une bitmap que j'affiche ensuite dans mon rectangle.
03/01/2022, 10h07
SergioMaster
Citation:
Envoyé par Gouyon
Bonjour à tous et bonne année
Meilleurs vœux
Citation:
C'est amusant mais je pensais compléter ma collection de composant avec un truc dans ce genre.
en fait c'est parce-que la liaison que je t'avais proposé aux départ pour tes composants était bidirectionnelle que je me suis lancé le défi de fin d'année
Citation:
Ensuite pour ce qui est de l'affichage j’essaie dans la mesure du possible de paramétrer au maximum pour que l'utilisateur puisse adapter au mieux l'affichage en fonction de son usage.
Par exemple combien de degrés sont affiché dans ton rectangle, combien de degré représente une graduation...
ça, c'est une étape que je n'avais bien sûr pas encore franchie : les propriétés, bien sûr que je le ferai quand il s'agira d'écrire l'unité composant. La question était plus sur la gestion des angles (chiante) d'ArcDial qu'autre chose
Citation:
Ensuite pour ce qui est de l'affichage je dessine tout dans une bitmap que j'affiche ensuite dans mon rectangle.
Oui, j'ai regardé tes sources ;) la technique proposée par Paul est une solution, envisageable même en tant que style (juste avant le réveillon j'ai même entraperçu comment faire :yaisse2:)