Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   [FMX] Splitter in einem bestimmten Bereich verschieben (https://www.delphipraxis.net/175665-%5Bfmx%5D-splitter-einem-bestimmten-bereich-verschieben.html)

RWarnecke 8. Jul 2013 18:03

[FMX] Splitter in einem bestimmten Bereich verschieben
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

ich habe den Splitter in dem Beispiel Programm dazu gebracht, dass er nur in einem bestimmten Bereich zu verschieben ist. Das funktioniert auch soweit sehr gut.

Jetzt stellt sich mir nur die Frage, wie ich den Splitter dazu bewege auf der Endposition zu bleiben, auch dann, wenn die Maus noch weiter nach rechts geht ?

Die zweite Frage wäre noch, das nur das OnMouseMove-Ergeignis ausgeführt wird, wenn die linke Maustaste gedrückt ist ?

Ich habe das Projekt unter Delphi XE4 erstellt.

RWarnecke 9. Jul 2013 20:47

AW: [FMX] Splitter in einem bestimmten Bereich verschieben
 
Hat denn keiner eine Idee, wie ich das Verschieben des Splitters in einem bestimmten Bereich noch verbessern kann ?

stahli 9. Jul 2013 23:07

AW: [FMX] Splitter in einem bestimmten Bereich verschieben
 
Oh, ich kann Dein Formular mit XE3 gar nicht öffnen. Da ist offenbar noch einiges geschraubt worden.

Für die erste Frage kannst Du vielleicht TSplitter überschreiben und Grenzwerte für X+Y festlegen.
Die sind natürlich evtl. etwas schwierig zu ermitteln.
Alternativ könntest Du eine Ereignisbehandlung OnIsSplitterInRange ausführen und wenn False zurückgeliefert wird Veränderungen verweigern.
Delphi-Quellcode:
procedure TSplitter.MouseMove(Shift: TShiftState; X, Y: Single);
var
  NewSize, Split: Single;
  RangeResult: Boolean;
begin
  inherited;
  if FPressed and Assigned(FControl) then
  begin
// X und Y "korrigieren"
// if Assigned(fOnIsSplitterInRange) then
// begin
//   fOnIsSplitterInRange(Self, RangeResult);
//   if not RangeResult then Exit;
// end; ... irgendwie sowas
    CalcSplitSize(X, Y, NewSize, Split);
    if DoCanResize(NewSize) then
    begin
      FNewSize := NewSize;
      FSplit := Split;
      UpdateControlSize;
    end;
  end;
end;
Constraints für Deine Panels gibt es noch nicht - oder?
Evtl. deren Breite immer wieder auf einen Maximalwert setzen?

So ganz verstehe ich Deine Fragen aber noch nicht. Kann morgen Abend das mal unter XE3 nachbauen...

Volker Z. 9. Jul 2013 23:12

AW: [FMX] Splitter in einem bestimmten Bereich verschieben
 
Hallo,

ich würde mal die Eventhandler
Delphi-Quellcode:
Splitter1MouseLeave
und
Delphi-Quellcode:
Splitter1MouseMove
löschen, und es mit
Delphi-Quellcode:
procedure TForm1.Panel2Resize(Sender: TObject);
begin
  if Panel2.Width > LeftClientWidth then
    Panel2.Width := LeftClientWidth
end;
versuchen

Gruß

RWarnecke 9. Jul 2013 23:19

AW: [FMX] Splitter in einem bestimmten Bereich verschieben
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Andre,

danke erstmal für Deine Antwort.

Zitat:

Zitat von stahli (Beitrag 1221300)
Für die erste Frage kannst Du vielleicht TSplitter überschreiben und Grenzwerte für X+Y festlegen.
Die sind natürlich evtl. etwas schwierig zu ermitteln.

Die X und Y Werte ist nur die Position der Maus innerhalb des Splitters.

Zitat:

Zitat von stahli (Beitrag 1221300)
Alternativ könntest Du eine Ereignisbehandlung OnIsSplitterInRange ausführen und wenn False zurückgeliefert wird Veränderungen verweigern.

Das habe ich ja schon mit meinen beiden Procedure's erreicht.

Zitat:

Zitat von stahli (Beitrag 1221300)
Constraints für Deine Panels gibt es noch nicht - oder?

Nein, ein Contraints gibt es für keine Komponente.

Ich habe mal eine EXE angehängt, die mein Problem vielleicht etwas verdeutlicht.

RWarnecke 9. Jul 2013 23:49

AW: [FMX] Splitter in einem bestimmten Bereich verschieben
 
Hallo Volker,

danke für Deinen Tipp. Ich habe das ganze mal ausprobiert und Dein Ansatz war völlig richtig. Hier mein Endergebnis :
Delphi-Quellcode:
var
  HalfClientWidth : Single;
  LeftClientWidth : Single;

procedure TForm1.FormResize(Sender: TObject);
begin
  HalfClientWidth := Round(self.ClientWidth / 2);
  LeftClientWidth := 300;
end;

procedure TForm1.Panel2Resize(Sender: TObject);
begin
  if LeftClientWidth > Panel2.Width then
    Panel2.Width := LeftClientWidth
  else
    if Panel2.Width > HalfClientWidth then
      Panel2.Width := HalfClientWidth - Splitter1.Width;
end;
Nun kann ich das Panel2 in der Breite nicht kleiner als 300 Pixel machen und das Panel 3 nicht kleiner als die Hälfte der Breite vom Fenster. Ich habe auch jetzt nichtmehr das Zittern des Splitters, wenn ich über die Grenze des Bereiches gehe. Damit bin ich wieder einen Schritt weiter.

Edit:
Ich habe auch einen entsprechenden Eintrag in meine Code-Orakel Online Datenbank gemacht.

Volker Z. 10. Jul 2013 00:37

AW: [FMX] Splitter in einem bestimmten Bereich verschieben
 
Hallo,

ich würde eher auf etwas in dieser Richtung setzen:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  // kannst Du natürlich auch im Objectinspector setzen
  Splitter1.MinSize := 300;
  Panel2.Width     := Splitter1.MinSize
end;

procedure TForm1.FormResize(Sender: TObject);
var
  w : Integer;
begin
  w := Round (ClientWidth / 2);
  if w <= Splitter1.MinSize then
    Panel2.Width := Splitter1.MinSize
  else
    Panel2.Width := w
end;

procedure TForm1.Panel2Resize(Sender: TObject);
var
  w : Integer;
begin
   w := Round (ClientWidth / 2);
   if Panel2.Width > w then
     Panel2.Width := Splitter1.MinSize + w - Splitter1.MinSize
end;

procedure TForm1.FormCreate(Sender: TObject);
Denn das funktioniert auch noch nach einer Größenänderung des Fensters.

Gruß

stahli 10. Jul 2013 08:02

AW: [FMX] Splitter in einem bestimmten Bereich verschieben
 
Ok, schön wenn es jetzt passt.

Bei meiner Lösung (innerhalb von TSplitter) hätte man noch mit ClientToParent arbeiten müssen.
Aber das wäre schon sehr umständlich geworden (mindestens ;-)).

RWarnecke 10. Jul 2013 08:30

AW: [FMX] Splitter in einem bestimmten Bereich verschieben
 
Danke für Deinen Vorschlag Volker, aber der hat einen Nachteil. Bei jeder Größenänderung des Fensters springt der Splitter immer in die Mitte des Fensters. Dieses finde ich einen unschönen Effekt. Bei meiner Version bleibt der Splitter an der Stelle, wo ich ihn zuletzt abgesetzt habe.

So wäre es jetzt aus meiner Sicht perfekt :
Delphi-Quellcode:
var
  HalfClientWidth : Single;
  LeftClientWidth : Single;

procedure TForm1.FormResize(Sender: TObject);
begin
  HalfClientWidth := Round(self.ClientWidth / 2);
  LeftClientWidth := 300;
  Panel2Resize(nil);
end;

procedure TForm1.Panel2Resize(Sender: TObject);
begin
  if LeftClientWidth > Panel2.Width then
    Panel2.Width := LeftClientWidth
  else
    if Panel2.Width > HalfClientWidth then
      Panel2.Width := HalfClientWidth - Splitter1.Width;
end;
Bei dieser Version bleibt der Splitter immer an der gleichen Position stehen, wenn der Splitter innerhalb des Bereichs ist. Wenn der Splitter beim Verändern der Größe außerhalb des Bereichs ist, dann springt er immer in die Mitte des Fensters.

Volker Z. 10. Jul 2013 15:01

AW: [FMX] Splitter in einem bestimmten Bereich verschieben
 
Hallo,

Zitat:

[...] Bei jeder Größenänderung des Fensters springt der Splitter immer in die Mitte des Fensters. Dieses finde ich einen unschönen Effekt. [...]
Sorry, da habe ich dann wohl zu viel hineininterpretiert.

Bei Deiner Lösung scheppert es aber mit einem Stackoverflow. Ich meine es müsste heißen:
Delphi-Quellcode:
if LeftClientWidth >= Panel2.Width then


Gruß


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:47 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz