|
Registriert seit: 22. Jan 2007 Ort: Ingolstadt 362 Beiträge Delphi XE2 Architect |
#1
... 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 TvgBitmapButton noch 3 Animationen unterordne, die in vorgegebener Zeit (Duration) eine Parent-Eigenschaft (PropertyName) von einem auf den anderen Wert verändert (Start-, StopValue). Diese 3 Animationen werden in DoHoover gestartet und laufen gleichzeitig ab (im Gegensatz z.B. zu den Transitions von Billenium Effects): Die PNGs sind nur einmal in einer TvgImageList abelegt und werden durch die BitmapSize-Animation FBmpSizeOut von 64 auf 120 px (und zurück) in 200 ms gezoomed, wobei der Button vergrößert FWidthOut, FPaddingOut 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. 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.
Andreas
Geändert von neo4a (25. Aug 2011 um 13:59 Uhr) Grund: Anhänge hinzugefügt, Refactoring |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |