Größe einer Kompo animiert verändern

Rund um die LCL und andere Komponenten
alexander
Beiträge: 423
Registriert: Di 5. Feb 2008, 12:45
OS, Lazarus, FPC: Linux, Lazarus svn, FPC svn
CPU-Target: 64Bit
Kontaktdaten:

Größe einer Kompo animiert verändern

Beitrag von alexander »

Hi,

also ich bekomme es einfach nicht hin, dass wenn ich die Höhe meiner Demo Komponente in einer Schleife verändere die Komponente neu gezeichnet wird.

der gesamte Code ist:

Code: Alles auswählen

%u7b TMyPanel %u7d
 
  TMyPanel=class%u28TPanel%u29
  private
    procedure AnimatedCollapse%u28var size%u3ainteger%u29;
    procedure Click; override;
 
  end;
 
var
  Form1%u3a TForm1; 
  mypanel%u3aTMyPanel;
 
implementation
 
%u7b TForm1 %u7d
 
 
 
procedure TForm1.FormCreate%u28Sender%u3a TObject%u29;
begin
  mypanel%u3a=TMyPanel.Create%u28self%u29;
  with mypanel do
    begin
    parent%u3a=self;
    Height%u3a=300;
    end;
end;
 
procedure TForm1.FormDestroy%u28Sender%u3a TObject%u29;
begin
  mypanel.free;
end;
 
 
 
%u7b TMyPanel %u7d
 
procedure TMyPanel.AnimatedCollapse%u28var size%u3ainteger%u29;
var step%u3areal;
    originalSize%u3ainteger;
begin
  originalSize%u3a=size;
  step%u3a=2;
 
  while size>0 do
    begin
    if size-round%u28step%u29 >= 0 then
      size%u3a=size-round%u28step%u29
    else
      size%u3a=0;
 
    Caption%u3a=IntToStr%u28size%u29;
    Update;
    Paint;
    Application.ProcessMessages;
    end;
end;
 
 
procedure TMyPanel.Click;
begin
  AnimatedCollapse%u28self.Height%u29;
 
  inherited Click;
end;
Ich sehe wie er in der Caption runterzählt, allerdings verändert sich die sichtbare Höhe des Panel garnicht.
Habt ihr eine Idee?

EDIT: Irgendwie liegt das an der Variablenübergabe.... kann ich keine Properties als var übergeben?

hmmm so klappt das auch nicht:



Gruß Alexander

Code: Alles auswählen

procedure TMyPanel.AnimatedCollapse%u28var size%u3aPInteger%u29;
var step%u3areal;
    originalSize%u3ainteger;
begin
  originalSize%u3a=size^;
  step%u3a=2;
 
  while size^>0 do
    begin
    if size^-round%u28step%u29 >= 0 then
      size^%u3a=size^-round%u28step%u29
    else
      size^%u3a=0;
 
    Caption%u3a=IntToStr%u28size^%u29;
    Update;
    Paint;
    Application.ProcessMessages;
    end;
end;
 
 
procedure TMyPanel.Click;
begin
  AnimatedCollapse%u28%u40Height%u29;  //Fehler
 
  inherited Click;
end;

Ich muss doch irgendwie die Properties so übergeben können, dass ich nicht nur height sondern auch width übergeben kann.
Es kann doch wohl nicht sein dass ich den Code 2 mal schreiben muss....
Zuletzt geändert von alexander am Mi 11. Jun 2008, 18:57, insgesamt 1-mal geändert.
Du magst Freiheit? Gönne es auch deinem Computer mit Linux!
www.alexanderroth.eu

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Ich versteh dein Problem überhaupt nicht.
Erstens kann man den oberen Code nicht enziffern, und dann kapier ich nicht was du da weshalb als var übergeben willst und dann auch noch mit Pointern.

Wieso willst du ein Property als Var übergeben?
Wieso willst du Height überhaupt übergeben? Das ist doch in TMyPanel.AnimatedCollapse genauso erreichbar wie in TMyPanel.Click ?

Kapiere nichts.

alexander
Beiträge: 423
Registriert: Di 5. Feb 2008, 12:45
OS, Lazarus, FPC: Linux, Lazarus svn, FPC svn
CPU-Target: 64Bit
Kontaktdaten:

Beitrag von alexander »

hmmm du hast recht, der Code ist komisch... seltsam.... (mal wieder das dumme Encoding) vorhin sah er gut aus...


Ich will in AnimatedCollapse verschiedene Parameter übergeben wie Height, Width
Schön wäre es wenn man einen Pointer auf die Property setzten könnte. Klappt aber anscheinend nicht...

Ich habe es jetzt so gelöst, dass ich halt für Width und Height getrennt mache.... na ja...

Aber schade dass es nicht geht....
Du magst Freiheit? Gönne es auch deinem Computer mit Linux!
www.alexanderroth.eu

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Was geht nicht?
Du kannst doch zwei Parameter übergeben. Wieso denn nicht? (Wenn ich auch nicht weiss wozu).

alexander
Beiträge: 423
Registriert: Di 5. Feb 2008, 12:45
OS, Lazarus, FPC: Linux, Lazarus svn, FPC svn
CPU-Target: 64Bit
Kontaktdaten:

Beitrag von alexander »

hmmm du hast recht, der Code ist komisch... seltsam....


Ich will in AnimatedCollapse verschiedene Parameter übergeben entweder Height oder Width

Ich habe es jetzt so gelöst, dass ich halt für Width und Height getrennt mache.... na ja...

Aber schade dass es nicht geht....


Hier mal zum Ausprobieren:

Code: Alles auswählen

{ TMyPanel }
 
  TMyPanel=class(TPanel)
  private
    procedure AnimatedCollapse;
    procedure Click; override;
 
  end;
 
var
  Form1: TForm1;
  mypanel:TMyPanel;
 
implementation
 
{ TForm1 }
 
 
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  mypanel:=TMyPanel.Create(self);
  with mypanel do
    begin
    parent:=self;
    Height:=300;
    end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var b:integer;
begin
  b:=ord(MyRollOut1.ButtonPosition)+1;
  if ord(MyRollOut1.ButtonPosition)+1 > ord(High(TAnchorKind)) then
    b:=0;
 
  MyRollOut1.ButtonPosition:=TAnchorKind(b );
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
  mypanel.free;
end;
 
 
 
{ TMyPanel }
 
procedure TMyPanel.AnimatedCollapse;
var step:real;
    originalSize:integer;
begin
  originalSize:=Height;
  step:=2;
 
  while Height>1 do
    begin
    if Height-round(step) >=1 then
      Height:=Height-round(step)
    else
      Height:=1;
 
    Paint;
    Update;
    end;
end;
 
 
procedure TMyPanel.Click;
begin
  AnimatedCollapse;
 
  inherited Click;
end;
Klappt.

Doch das klappt nicht:

Code: Alles auswählen

TMyPanel=class(TPanel)
  private
    procedure AnimatedCollapse(size:integer);
    procedure Click; override;
 
  end;
 
var
  Form1: TForm1;
  mypanel:TMyPanel;
 
implementation
 
{ TForm1 }
 
 
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  mypanel:=TMyPanel.Create(self);
  with mypanel do
    begin
    parent:=self;
    Height:=300;
    end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var b:integer;
begin
  b:=ord(MyRollOut1.ButtonPosition)+1;
  if ord(MyRollOut1.ButtonPosition)+1 > ord(High(TAnchorKind)) then
    b:=0;
 
  MyRollOut1.ButtonPosition:=TAnchorKind(b );
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
  mypanel.free;
end;
 
 
 
{ TMyPanel }
 
procedure TMyPanel.AnimatedCollapse(size:integer);
var step:real;
    originalSize:integer;
begin
  originalSize:=size;
  step:=2;
 
  while size>1 do
    begin
    if size-round(step) >=1 then
      size:=size-round(step)
    else
      size:=1;
 
    Paint;
    Update;
    end;
end;
 
 
procedure TMyPanel.Click;
begin
  AnimatedCollapse(Height);
 
  inherited Click;
end;

seltsamerweise
Du magst Freiheit? Gönne es auch deinem Computer mit Linux!
www.alexanderroth.eu

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

alexander hat geschrieben: seltsamerweise
Überhaupt nicht seltsam.
Du übergibst einen Integer Size mit dem Wert von Height.
Dass der nicht von selber TComponent.Height setzt ist doch wohl klar.

Du kannst Height in der Proc setzen oder eine Funktion daraus machen die Height berechnet.
Dann so aufrufen:

Height:=AnimatedCollapse(Height);
Paint;
Update;

Du machst da einfach ein bisschen ein durcheinander... ;-)

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

Das einfachste währe du würde eine Klasse übergeben, dann währe das mit dem Pointer kein Problem. Einfache variable geht zwar auch, aber ich meine das ist aufwendiger oder ?

ich mache das immer mit der Passenden Klasse.
MFG
Michael Springwald

alexander
Beiträge: 423
Registriert: Di 5. Feb 2008, 12:45
OS, Lazarus, FPC: Linux, Lazarus svn, FPC svn
CPU-Target: 64Bit
Kontaktdaten:

Beitrag von alexander »

theo hat geschrieben: Height:=AnimatedCollapse(Height);
Paint;
Update;
witzig. Ich will doch gerade die Animation haben und nicht den Endwert! Die Schleife ist nicht dazu da um was zu berechnen sondern um zu animieren!

Code: Alles auswählen

Das einfachste währe du würde eine Klasse übergeben, dann währe das mit dem Pointer kein Problem. Einfache variable geht zwar auch, aber ich meine das ist aufwendiger oder ?
 
ich mache das immer mit der Passenden Klasse.
hmm ich möchte ja self.Height (oder self.width) übergeben. Wie kriege ich das mit einer klasse hin?
Du magst Freiheit? Gönne es auch deinem Computer mit Linux!
www.alexanderroth.eu

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

Ich kenne jetzt leider deine Klassen Struktur nicht. Aber z.b. folgendes beispiel :

Code: Alles auswählen

TKlasseA ....
...
Data:TComponent
end:
 
TKlasseB = class(TKlasseA)
procedure Test:
end:
 
procedure TKlasseb.Test;
begin
  writeln(TKlasseA(Data).left)
end;
So in etwa könnte das gehen. Ich hoffe das hilft dir weiter. Aber ich verstehe dein Problem noch nicht ganz.
hast du mehrer Klassen ?
MFG
Michael Springwald

alexander
Beiträge: 423
Registriert: Di 5. Feb 2008, 12:45
OS, Lazarus, FPC: Linux, Lazarus svn, FPC svn
CPU-Target: 64Bit
Kontaktdaten:

Beitrag von alexander »

hmmm nein... wie schon oben der Code:
Einfach in ein leeres Projekt kopieren!

Code: Alles auswählen

TMyPanel=class(TPanel)
  private
    procedure AnimatedCollapse(size:integer);
    procedure Click; override;
 
  end;
 
var
  Form1: TForm1;
  mypanel:TMyPanel;
 
implementation
 
{ TForm1 }
 
 
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  mypanel:=TMyPanel.Create(self);
  with mypanel do
    begin
    parent:=self;
    Height:=300;
    end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var b:integer;
begin
  b:=ord(MyRollOut1.ButtonPosition)+1;
  if ord(MyRollOut1.ButtonPosition)+1 > ord(High(TAnchorKind)) then
    b:=0;
 
  MyRollOut1.ButtonPosition:=TAnchorKind(b );
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
  mypanel.free;
end;
 
 
 
{ TMyPanel }
 
procedure TMyPanel.AnimatedCollapse(size:integer);
var step:real;
    originalSize:integer;
begin
  originalSize:=size;
  step:=2;
 
  while size>1 do
    begin
    if size-round(step) >=1 then
      size:=size-round(step)
    else
      size:=1;
 
    Paint;
    Update;
    end;
end;
 
 
procedure TMyPanel.Click;
begin
  AnimatedCollapse(Height);
 
  inherited Click;
end;
Du magst Freiheit? Gönne es auch deinem Computer mit Linux!
www.alexanderroth.eu

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

Ich nehme jetzt folgendes einfach mal an:
Du möchtest das sich das Panel animiert auf und zu klappen kann, richtig ?
Wenn ja sollte die Lösung recht einfach sein:
Du musst dafür die Original Größe des Panels speichern wie du es schon machst. Aber Gobal d.h. du musst sie oben Definieren.

Eine while schleife geht zwar, aber du brauchst eine zeit schleife, ich könnte mir vorstellen das es zu schnell geht.
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

alexander hat geschrieben:witzig. Ich will doch gerade die Animation haben und nicht den Endwert! Die Schleife ist nicht dazu da um was zu berechnen sondern um zu animieren!
Ich hab dir ja gesagt, ich kapier nicht was das tun soll. ;-)
alexander hat geschrieben: hmm ich möchte ja self.Height (oder self.width) übergeben. Wie kriege ich das mit einer klasse hin?
Aber wieso?
AnimatedCollapse hat doch genauso Zugriff auf Width, Height wie Click. Wieso also übergeben?

Ausserdem hat Pluto schon recht. Das geht viel zu schnell. Du solltest das mit einem Timer machen.
Ein Application.Processmessages müsste wahrsch. auch noch dazwischen.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

Naja oder ein Sleep verwenden. Aber timer währe schon besser.
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Auf die Schnelle schlage ich sowas vor:

Einen Timer nehmen, Enabled auf False interval z.B. auf 100.
Und schon rattert's.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  Timer1.Enabled:=true;
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if Panel1.Height>2 then Panel1.Height:=Panel1.height-2 else Timer1.Enabled:=false;
end;

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

Du kannst auch einen Timer zur Laufzeit hinzufügen.Evlt, möchtest du ja auch das die Animation nur beim Schließen oder beim Öffnen es Panels aufgerufen wird, dann musst du den Timer halt aktivieren und deaktivieren. sonst währe es eine Endlosschleife.

Aber ich sehe gerade theo hat das schon eingebaut.
MFG
Michael Springwald

Antworten