![]() |
FireMonkey Erfahrungen
Liste der Anhänge anzeigen (Anzahl: 2)
... gibt es ja keine offiziellen. Und so sehr ich den Delphi-Mitarbeitern ihre Einführungsshow gönne, umso ärgerlicher machen mich diese albernen und substanzlosen "Blog-Posts" zum Thema wie zuletzt
![]() Als bekennender UX-Anhänger möchte ich meinen Programmen immer bestmögliche GUI spendieren. So habe ich zuletzt die SmoothComponents von TMS geprüft und deren letzte Version enthält ja auch eine sehr interessante ![]() Ich habe mich vor 2-3 Jahren schon mit vgScene und DxScene beschäftigt und bin seinerzeit mit der etwas eigenwilligen IDE- Integration und zahlreichen Bugs nicht zurecht gekommen. Nachdem nun (Achtung: Gaanz!Neue!Info!) FireMonkey darauf basiert, habe ich mir die letzte Version unter XE installiert und mich nochmals intensiv damit beschäftigt. Fazit: Klasse. Was aber allem die Krone aufsetzt: Ich habe eine vgScene-Demo auf meinem ca. 12 Jahren alten 1GHz, 256 MB, 14" Siemens-Notebook getestet und bin begeistert, wie smooth (nicht im Sinne von TMS) das alles selbst dort läuft. Das ist wirklich eine gute Basis für eine auch aufwändige GUI. Die IDE-Integration von vgScene ist nach wie vor sehr gewöhnungsbedürftig, aber nachdem ich mir angewöhnt habe, nur noch abgeleitete Komponenten und Controls zu benutzen, passiert bei mir ohnehin alles "zu Fuß" und abseits des Delphi-IDE-Form-Designers. Das Konzept von FireMonkey/vgScene ist - verglichen mit der VCL - sehr vielversprechend. Man kann hier nicht nur wild Elemente (Controls, Animationen, Effekte etc.) im XML-Style komponieren, sondern auch die Eigenschaften ganz simpel überladen, indem man eine beliebige Definition zuweist. Das bedeutet praktisch, das man im Inspektor oder Code nur eine (1!) Eigenschaft (Name der Definition) zuweist, und damit das komplette Verhalten eines Controls umstellt. Als Beispiel poste ich hier den Source zur im Anhang verfügbaren Exe-Demo. Dort erzeuge ich zur Laufzeit die 4 animierten Buttons, indem ich dem statischen
Delphi-Quellcode:
noch 3 Animationen unterordne, die in vorgegebener Zeit (Duration) eine Parent-Eigenschaft (PropertyName) von einem auf den anderen Wert verändert (Start-, StopValue).
TvgBitmapButton
Diese 3 Animationen werden in
Delphi-Quellcode:
gestartet und laufen gleichzeitig ab (im Gegensatz z.B. zu den Transitions von Billenium Effects):
DoHoover
Die PNGs sind nur einmal in einer
Delphi-Quellcode:
abelegt und werden durch die BitmapSize-Animation
TvgImageList
Delphi-Quellcode:
von 64 auf 120 px (und zurück) in 200 ms gezoomed, wobei der Button vergrößert
FBmpSizeOut
Delphi-Quellcode:
und gleichzeitig auch die Größe des Container-Controls verändert wird (4. Animation definiert im DFM), was die LeftAligned-Buttons animiert bewegen lässt.
FWidthOut, FPaddingOut
Das alles ist zwar eine neue Dimension bei der Gestaltung und Programmierung, aber wirklich leicht zu durchschauen und anzupassen. Man kann praktisch im VCL-Style beginnen und je nach Befarf beliebig komplexer werden. (Von den "Dreingaben" MacOs, iOs etc. ganz zu schweigen.)
Delphi-Quellcode:
Die Begeisterung der Delphi-Mannen ist für mich unbedingt nachvollziehbar.
unit Unit8;
interface uses SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, vg_scene, vg_objects, vg_effects, vg_layouts, vg_ani, vg_controls, ImgList, vg_actions; type TSelectedEvent = procedure (aHoover : Boolean = True) of object; TMySelectBtn = class(TvgBitmapButton) private FSelecting : Boolean; FSelected : Boolean; FSelectEvent : TSelectedEvent; FResetEvent : TNotifyEvent; FPaddingOut : TvgRectAnimation; FWidthOut : TvgFloatAnimation; FBmpSizeOut : TvgFloatAnimation; procedure DoOnClick(aSender : TObject); procedure DoPaddingAnimation; procedure DoWidthAnimation; procedure DoBmpSizeAnimation; procedure SetHoover(const Value: Boolean); procedure DoSelect; public constructor Create(aOwner : TComponent; aParent : TvgObject); reintroduce; property SelectEvent : TSelectedEvent read FSelectEvent write FSelectEvent; property ResetEvent : TNotifyEvent read FResetEvent write FResetEvent; property Selected : Boolean read FSelected write SetHoover; end; TForm8 = class(TForm) vgScene1 : TvgScene; Root1 : TvgBackground; Rectangle1 : TvgRectangle; Rectangle2 : TvgRectangle; Rectangle3 : TvgRectangle; Image1 : TvgImage; Text1 : TvgText; Text2 : TvgText; Layout1 : TvgLayout; Layout2 : TvgLayout; Layout3 : TvgLayout; Rectangle5 : TvgRectangle; Text3 : TvgText; Text4 : TvgText; Text5 : TvgText; Text6 : TvgText; vgResources1 : TvgResources; Container : TvgLayout; containerOut : TvgFloatAnimation; Resources1 : TvgResources; BitmapButton1 : TvgBitmapButton; vgImageList2 : TvgImageList; procedure DoContainerAnimation(aIsButtonSelected : Boolean = True); procedure DoReset(aSender : TObject); private BtnYellow : TMySelectBtn; BtnBlue : TMySelectBtn; BtnGreen : TMySelectBtn; BtnRed : TMySelectBtn; public constructor Create(aOwner : TComponent); override; procedure ResetAllButtons; end; var Form8: TForm8; implementation {$R *.dfm} procedure TForm8.ResetAllButtons; /// Im Setter der Property wird die Animation ausgelöst. begin BtnGreen.Selected := False; BtnRed.Selected := False; BtnBlue.Selected := False; BtnYellow.Selected := False; Container.Width := 450; end; procedure TForm8.DoContainerAnimation(aIsButtonSelected: Boolean); /// Diese Animation macht den Container breiter, so das ein /// (breiter) Selected-Button hineipasst. Da alle Nuttons Left-Aligned sind /// gibt es einen schönen Verschiebe- Effekt. begin containerOut.Inverse := not aIsButtonSelected; containerOut.Start; end; constructor TForm8.Create(aOwner : TComponent); /// 4 Buttons für unseren Container, denen mitgegeben wird /// welche Prozedur beim Resetten und Selected aufzurufen ist. begin inherited; BtnYellow := TMySelectBtn.Create(Self, Container); if vgImageList2.Count > 0 then BtnYellow.Bitmap := vgImageList2.Images[0]; BtnYellow.Text := 'Yellow'; BtnYellow.SelectEvent := DoContainerAnimation; BtnYellow.ResetEvent := DoReset; BtnBlue := TMySelectBtn.Create(Self, Container); if vgImageList2.Count > 1 then BtnBlue.Bitmap := vgImageList2.Images[1]; BtnBlue.Text := 'Blue'; BtnBlue.SelectEvent := DoContainerAnimation; BtnBlue.ResetEvent := DoReset; BtnGreen := TMySelectBtn.Create(Self, Container); if vgImageList2.Count > 2 then BtnGreen.Bitmap := vgImageList2.Images[2]; BtnGreen.Text := 'Green'; BtnGreen.SelectEvent := DoContainerAnimation; BtnGreen.ResetEvent := DoReset; BtnRed := TMySelectBtn.Create(Self, Container); if vgImageList2.Count > 3 then BtnRed.Bitmap := vgImageList2.Images[3]; BtnRed.Text := 'Red'; BtnRed.SelectEvent := DoContainerAnimation; BtnRed.ResetEvent := DoReset; end; procedure TForm8.DoReset(aSender: TObject); /// Zurück auf Anfang. begin ResetAllButtons; end; { TMySelectBtn } constructor TMySelectBtn.Create(aOwner : TComponent; aParent : TvgObject); begin inherited Create(aOwner); FSelected := False; Parent := aParent; Position.X := 1000; // entspricht Left Align := vaLeft; Resource := 'acroButton'; // Definition im DFM Width := 110; BitmapLayout := vgGlyphTop; BitmapSize := 64; BitmapPadding := 13; Font.Size := 14; OnClick := DoOnClick; // 1. Animation für das "Oversizen" FPaddingOut := TvgRectAnimation.Create(aOwner); FPaddingOut.Parent := Self; FPaddingOut.PropertyName := 'Padding'; FPaddingOut.Duration := 0.2; FPaddingOut.StartValue := TvgBounds.Create(vgRect(0, 0, 0, 0)); FPaddingOut.StopValue := TvgBounds.Create(vgRect(0, -60, 0, -30)); // 2. Animation für das Vergrößern/Verkleiner beim Selektieren/Klicken FWidthOut := TvgFloatAnimation.Create(aOwner); FWidthOut.Parent := Self; FWidthOut.PropertyName := 'Width'; FWidthOut.Duration := 0.2; FWidthOut.StartValue := 110; FWidthOut.StopValue := 260; // 3. Animation für das Zoomen der Button-Grafik FBmpSizeOut := TvgFloatAnimation.Create(aOwner); FBmpSizeOut.Parent := Self; FBmpSizeOut.PropertyName := 'BitmapSize'; FBmpSizeOut.Duration := 0.2; FBmpSizeOut.StartValue := 64; FBmpSizeOut.StopValue := 120; end; procedure TMySelectBtn.DoSelect; /// Gleichzeitiges Starten der Animationen, dadurch ist die Reihenfolge egal. begin if FSelecting then Exit; FSelecting := True; try FSelected := not FSelected; if Assigned(FResetEvent) then FResetEvent(Self); DoPaddingAnimation; DoWidthAnimation; DoBmpSizeAnimation; if Assigned(FSelectEvent) then FSelectEvent(FSelected); finally FSelecting := False; end; end; procedure TMySelectBtn.DoOnClick(aSender: TObject); begin DoSelect; end; procedure TMySelectBtn.DoPaddingAnimation; begin FPaddingOut.Inverse := not FSelected; FPaddingOut.Start; end; procedure TMySelectBtn.SetHoover(const Value: Boolean); begin if FSelected <> Value then DoSelect; end; procedure TMySelectBtn.DoWidthAnimation; begin FWidthOut.Inverse := not FSelected; FWidthOut.Start; end; procedure TMySelectBtn.DoBmpSizeAnimation; begin FBmpSizeOut.Inverse := not FSelected; FBmpSizeOut.Start; end; end. |
AW: FireMonkey Erfahrungen
Zitat:
|
AW: FireMonkey Erfahrungen
Zitat:
BTW, hätte ich nur meine Anhänge gepostet, wäre auch mein Beitrag aus meiner Sicht substanzlos - sieht man einmal davon ab, dass man mit der Exe die Performance- Aussagen leicht selbst nachprüfen kann. |
AW: FireMonkey Erfahrungen
Liste der Anhänge anzeigen (Anzahl: 2)
Vielleicht geht es nur mir so: obwohl die Monitore immer größer werden, wird die Schrift der Programme immer kleiner. Das Zooming in den Office-Programmen oder aber auch das Firefox-Plugin
![]() In einer meiner älteren Apps habe ich einmal die Komponente TFormResizer dahingehend customized, dass sie auch mit Grids und dergleichen funktionierte. Das Ergebnis war hilfreich, aber optisch eher mäßig. Bei meiner Früherkundung von FireMonkey per vgScene nun habe ich mir die Zoom-Funktion angeschaut. Fazit: Klasse. Das Zoomen der Maske passiert in einer beeindruckenden Qualität und umfasst alles (Size, Schriftgrad, Position und selbst die Scrollbars und Grafiken). Dazu muss nur das Parent-Control per Scale-Faktoren gezoomed werden - die Child-Controls machen alles mit. Einfacher geht's wohl nicht. Ich habe die Demo aus dem 1. Beitrag dahingehend erweitert, dass nun die Zoom-Funktion benutzbar ist. Dazu wurden die Buttons und das Memo-Feld in eine TvgScrollBox verschoben, die bei Bedarf Scrollbars zeigt (hier in der schmalen Version). Sobald die Scrollbars sichtbar sind, kann man die Maske mit der Maus oder dem Mausrad verschieben. Wenn die Zoom-Stufe groß genug ist, kommt beim Verschieben mit der Maus das Touch'n'Feel vom iPad auf, da das auf Wunsch/Option animiert erfolgt. Die von mir hinzugefügte Auto-Funktion ermöglicht es, eine Maske für unterschiedliche Auflösungen (oder Fenstergrößen) zu verwenden. Da Win8 ja dann auch auf Tablets läuft und FireMonkey-Apps demnächst neben iOS auch Android "können" sollen, ist das ziemlich hilfreich. Der Klick auf die Weltkugel macht folgendes:
Delphi-Quellcode:
Damit wird die Animation und die Farbe umgestellt. (Was hinter der Resource 'acroButton' alles abgelegt wird, ist von der Komplexität ziemlich beliebig.)
procedure TForm8.BitmapButton1Click(Sender: TObject);
begin if BitmapButton1.Resource = '' then BitmapButton1.Resource := 'acroButton' else BitmapButton1.Resource := ''; end; |
AW: FireMonkey Erfahrungen
Uhm...ich bin ziemlich beeindruckt. Toll sieht das aus, und "smooth" ist das wirklich :-)
Nur schade, dass man das nicht mehr selbst testen kann mit vgScene, wenn mans damals nicht geladen / gekauft hat :( Was mir aber gerade bzgl. der Touch-Bedienung der Demo auffällt: Es lässt sich leider nur innerhalb des Panels srollen, wenn man den Finger über der Maske / Hintergrund / Panel hat und kein Control darüber liegt, wenn z.B. die Zoomstufe sehr hoch gewählt ist, so dass z.B. ein gezoomtet Button die gesamte Fläche ausfüllt, lässt sich mit dem Finger nicht mehr scrollen, nur noch über die Scrolleiste. Ja, ich weiss, ist nur ne Demo :-D Aber das sind meist in der Realität dann so Kleinigkeiten, die einem dann das Genick brechen, weil genau sowas dann nicht geht oder nur sehr umständlich. Lässt sich das leicht beheben? Getestet habe ich das gerade mit meinem Iiyama ProLite T2250MTS Multitouch-Bildschirm-Viech ("Der Bildschirm, auf dem Mücken und Fliegen Programme aktivieren...."). Edit: Jetzt mal genau, für einen unwissenden, der sich mit XE2 / Firemonkey noch nicht so beschäftigt hat: FireMonkey ist die Weiterentwicklung von genau DEM hier? |
AW: FireMonkey Erfahrungen
Warum heisst das Teil eigentlich so unsäglich "FireMonkey"?
Soll das eine Anspielung auf "Mono" sein, die Cross-Platform-Lösung für .NET? :-) Würde ja von dem her passen... Oder haben Framework-Entwickler generell eine Affinität zu Affen? :lol: Ich weiss nicht, aber der Name wirkt irgendwie unprofessionell...wenn ich meinem Chef sagen würde "Hey, machen wir das in FireMonkey" hat er sicher erstmal den Eindruck, das ist irgend so ein bugverseuchtes Nerd-Tool von einem Einzelentwickler der Demoszene, das nach 1 Jahr wieder in der Versenkung verschwindet, nachdem das "Proof of Concept" da war.... |
AW: FireMonkey Erfahrungen
Zitat:
|
AW: FireMonkey Erfahrungen
Allerdings ist FireMonkey <> VGScene. Es basiert darauf. Es wird imho trotzdem nicht möglich sein, ein Programm mit VGScene zu Starten und dann einfach mit FireMonkey weiter zu entwickeln.
|
AW: FireMonkey Erfahrungen
Zitat:
Zitat:
Zitat:
![]() |
AW: FireMonkey Erfahrungen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:31 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz