Delphi-PRAXiS

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] Image mit Scrollfunktion (https://www.delphipraxis.net/188529-%5Bfmx%5D-image-mit-scrollfunktion.html)

Peter666 13. Mär 2016 09:53

[FMX] Image mit Scrollfunktion
 
Hi,

es ist mir etwas peinlich nur mit Fragen hier beizusteuern, aber auch diesmal hab ich eine ebensolche. Mein Konkretes Problem ist dass ich sowas wie ein Gantt Diagramm erstelle und die dahinter liegenden Datensätze gigantisch sind. Wunsch ist das auch auf mobilen Geräten zu erstellen. Meine Idee war also folgende: Ich erstelle eine Komponente die ein Bitmap mit dem Bildausschnitt beinhaltet. Ich möchte nun eine virtuelle Scrollbox erstellen und mit den relativen Koordinaten die der horizontale und vertikale Scroller liefert den Ausschnitt neu rendern. Das geht zwar mit der Maus, wenn man auf die Scrollbars klickt, aber mit Touchpad oder Touchdisplay geht das nicht. Hat jemand schon so etwas in der Art gemacht?

Peter

CHackbart 14. Mär 2016 11:03

AW: [FMX] Image mit Scrollfunktion
 
Uff, die sauberste Variante ist wahrscheinlich wenn Du TAniCalculations zu verwenden. Da bin ich aber ehrlich gesagt dran verzweifelt. Ich hab dann für mein Problem einfach folgendes gemacht:

Delphi-Quellcode:
const
 BOUNDS_WIDTH = 10000;
 BOUNDS_HEIGHT = 10000;

TMyClass = class(TCustomScrollBox)
protected
 ..
function DoCalcContentBounds: TRectF; override;
    procedure ViewportPositionChange(const OldViewportPosition,
      NewViewportPosition: TPointF; const ContentSizeChanged: Boolean);
      override;
    function GetDefaultStyleLookupName: string; override;
..

function TMyClass.GetDefaultStyleLookupName: string;
begin
  result := 'framedscrollboxstyle';
end;

function TMyClass.DoCalcContentBounds: TRectF;
begin
  result := RectF(0, 0, BOUNDS_WIDTH, BOUNDS_HEIGHT);
end;

procedure TMyClass.ViewportPositionChange(const OldViewportPosition,
  NewViewportPosition: TPointF; const ContentSizeChanged: Boolean);
begin
  FImage.Position.Point := NewViewportPosition; //FImage ist mein Bild mit den Maßen der TMyClass (ohne Scrollbars)
  //virtual_x = NewViewportPosition.x/BOUNDS_WIDTH*RealXVal <- damit kannst du dann die Werte virtualisieren
...
Glücklich bin ich mit der Lösung nicht. Vielleicht hat jemand ja eine bessere Idee. :Wub:

Christian

Rollo62 16. Mär 2016 11:51

AW: [FMX] Image mit Scrollfunktion
 
Ich benutze ein TImageView (basiert auf TScrollBox), mit einem Hintergrundbild und lege
ein Layout darein in das ich die Elemente in OnPaint selber zeichne.

Das funktioniert ganz gut, allerdings ist es schon sehr tricky das ans Laufen zu bekommen.
Die Koordinaten, die TAniCalculations, die Mouse/TouchEvents um jeweils Pan/Zoom als auch Drag and Drop
schön sauber zu selektieren (auf Phones/Tablets) ist eine Herausforderung.

Was ich vermute ist das es bei vielen Objekten sehr oft komplett neugezeichnet wird, deshalb müsstest
du wahrscheinlich deine eigene ViewPort Filterung einbauen, und nur das zeichnen was gerade sichtbar ist.

Wenn du alles in einem Bitmap vorzeichen willst solltest du daran denken das die Bitmaps nicht unendlich groß werden können, und je nach Platform anders sein werden. Ich hatte schon des öfteren Probleme damit, insbesondere bei Screenshots.

Rollo

CHackbart 17. Mär 2016 18:57

AW: [FMX] Image mit Scrollfunktion
 
Ich poste mal eine etwas aufgeräumte Variante von meinem Ansatz:

Delphi-Quellcode:
type
  TVirtualScrollBox = class(TCustomScrollBox)
  private
    FContentSize: TPointF;
  protected
    procedure DoPaint; override;
    function DoCalcContentBounds: TRectF; override;
    function GetDefaultStyleLookupName: string; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

constructor TVirtualScrollBox.Create(AOwner: TComponent);
begin
  inherited;
  FContentSize := PointF(10000, 10000);
end;

procedure TVirtualScrollBox.DoPaint;
begin
  inherited;
  canvas.Fill.Color := $FF000000;
  canvas.FillText(ClipRect, format('%0.2f/%0.2f',
    [HScrollBarValue / FContentSize.X, VScrollBarValue / FContentSize.Y]),
    false, 1, [], TTextAlign.Center, TTextAlign.Center);
end;

function TVirtualScrollBox.DoCalcContentBounds: TRectF;
begin
  result := RectF(0, 0, FContentSize.X, FContentSize.Y);
end;

function TVirtualScrollBox.GetDefaultStyleLookupName: string;
begin
  result := 'framedscrollboxstyle';
end;
Im Prinzip muss man nur DoPaint überschreiben mit seiner eigenen Logik. Mir gefällt das Basiskonstrukt in der Form nicht wirklich, aber es läuft recht passabel. Eventuell kann das ja jemand auch nutzen ;)

Christian


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:03 Uhr.

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