AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia TLine - Canvas an Line ausrichten
Thema durchsuchen
Ansicht
Themen-Optionen

TLine - Canvas an Line ausrichten

Ein Thema von Bjoerk · begonnen am 6. Mär 2013 · letzter Beitrag vom 9. Mär 2013
Antwort Antwort
Seite 1 von 2  1 2      
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#1

TLine - Canvas an Line ausrichten

  Alt 6. Mär 2013, 18:52
Ich erstelle z.Z eine TLine Klasse (Shape).

Dabei habe Ich folgendes Problem: Damit die Line vollständig in das Canvas hineinpasst, muß man beim Zeichnen der Linie Offsets abziehen. Wenn man das aber tut, wird die Linie zwar schön dargestellt (Siehe Paint), aber sie stimmt nicht mehr, weder Start- noch Endpunkt. Man sieht auch, daß der Winkel falsch ist (Siehe Anlage).

Ich müßte die ganze Komponente andersrum aufziehen. Zwei Eckpunkte vorgeben und die Komponentengröße wird dann entsprechend berechnet (statt die Linie einzupassen). Es wäre auch schön, wenn das auch schon zur Designzeit so angezeigt werden könnte.

Da ich von Grafikprogrammierung nur wenig Ahnung habe, wolle ich mal fragen, wie könnte man denn so was machen? TLine ist z.Z. von TGraphicControl abgeleitet?

Edit: Crosspost vergessen

http://forum.delphi-treff.de/showthr...Sets-erstellen

Delphi-Quellcode:
function TLine.OffSet1: integer;
begin
  Result := FPen.Width div 2;
end;

function TLine.OffSet2: integer;
begin
  Result := OffSet1 + FPen.Width mod 2;
end;

procedure TLine.Paint;
var
  X1, Y1, X2, Y2: Integer;
begin
  with Canvas do
  begin
    Pen := FPen;
    X1 := 0;
    Y1 := 0;
    X2 := Width;
    Y2 := Height;
    if X2 < 0 then
    begin
      Dec(X1, OffSet2);
      Inc(X2, OffSet1);
    end
    else
    begin
      Inc(X1, OffSet1);
      Dec(X2, OffSet2);
    end;
    if Y2 < 0 then
    begin
      Dec(Y1, OffSet2);
      Inc(Y2, OffSet1);
    end
    else
    begin
      Inc(Y1, OffSet1);
      Dec(Y2, OffSet2);
    end;
    MoveTo(X1, Y1);
    LineTo(X2, Y2);
  end;
end;
Zum besseren Verständnis hab ich einem Image die korrekte Line mal gezeichnet.
Angehängte Dateien
Dateityp: pdf TLine.pdf (62,3 KB, 28x aufgerufen)

Geändert von Bjoerk ( 6. Mär 2013 um 18:55 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

AW: TLine - Canvas an Line ausrichten

  Alt 6. Mär 2013, 19:27
Deine Linien Komponente bräuchte ein Property mit dem angegeben wird wie die Linie im umgebenden "Kasten" ausgerichtet sein soll.
Delphi-Quellcode:
TLineAlign = (
  laLeft, // links anliegend
  laRight, // rechts anliegend
  laTop, // oben anliegend
  laBottom, // unten anliegen
  laDiagUp, // diagonal "abwärts"
  laDiagDown // diagonal "aufwärts"
  )
Bei laLeft und laRight kann die Linie nur gerade von oben nach unten verlaufen.
Der x-Offset beträgt dann 0.5 * Linienbreite.
Bei laTop und laBottom kann die Linie nur waagerecht verlaufen.
Der y-Offset beträgt dann 0.5 * Linienbreite.
Bei laDiagUp und laDiagDown läuft die Linie von Ecke zu Ecke.
Dein Beispiel wäre laDiagDown weil die Linie von links oben nach rechts unten verläuft.
Bei den diagonalen Linien muss man die Endpunkte der Linie jeweils in x- und y-Richtung
um die halbe Linienbreite verschieben.

Es ist sinnvoll sich diese 6 Fälle grafisch aufzuzeichnen (so wie du das im Anhang schon für einen Fall gemacht hast).

Delphi-Quellcode:
procedure CalcOffsets(la:TLineAlign; Linewidth:integer; var offsetX, offsetY:Integer);
begin
  offsetX = 0;
  offsetY = 0;

  case la of
    laLeft : offsetX := Linewidth div 2;
    laRight: offsetX := -(Linewidth div 2);
    laTop : offsetY := Linewidth div 2;
    laBottom : offsetY := -(Linewidth div 2);
    laDiagUp, laDiagDown :
      begin
        offsetX := Linewidth div 2;
         offsetY := Linewidth div 2;
      end;
  end;
end;
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: TLine - Canvas an Line ausrichten

  Alt 6. Mär 2013, 19:55
Ja, das ist klar (Siehe OffSet1 und OffSet2). Typen hab ich auch schon (hab ich in der Paint jetzt weggelassen).
Delphi-Quellcode:
  TLineStyle = (lsTop, lsBottom, lsLeft, lsRight,
    lsTopLeft, lsTopRight, lsBottomLeft, lsBottomRight,
    lsTopLeftBottomRight, lsTopRightBottomLeft);

procedure TLine.Paint;
var
  X1, Y1, X2, Y2: Integer;
begin
  with Canvas do
  begin
    Pen := FPen;
    X1 := 0;
    Y1 := 0;
    X2 := Width;
    Y2 := Height;
    if X2 < 0 then
    begin
      Dec(X1, OffSet2);
      Inc(X2, OffSet1);
    end
    else
    begin
      Inc(X1, OffSet1);
      Dec(X2, OffSet2);
    end;
    if Y2 < 0 then
    begin
      Dec(Y1, OffSet2);
      Inc(Y2, OffSet1);
    end
    else
    begin
      Inc(Y1, OffSet1);
      Dec(Y2, OffSet2);
    end;
    case FStyle of
      lsTop, lsLeft, lsTopRight, lsBottomLeft, lsTopLeftBottomRight:
        MoveTo(X1, Y1);
      lsRight, lsTopLeft, lsBottomRight, lsTopRightBottomLeft:
        MoveTo(X2, Y1);
      lsBottom:
        MoveTo(X1, Y2);
    end;
    case FStyle of
      lsTopLeft:
        LineTo(X1, Y1);
      lsTopRight:
        LineTo(X2, Y1);
      lsBottomLeft:
        LineTo(X1, Y2);
      lsBottomRight:
        LineTo(X2, Y2);
    end;
    case FStyle of
      lsTop:
        LineTo(X2, Y1);
      lsLeft, lsTopLeft, lsBottomRight, lsTopRightBottomLeft:
        LineTo(X1, Y2);
      lsBottom, lsRight, lsTopRight, lsBottomLeft, lsTopLeftBottomRight:
        LineTo(X2, Y2);
    end;
  end;
end;
Das Problem ist aber ein anderes. Ich mu0 hier genau zeichen. Ich will ja eine Line von z.B. P1 nach P2 haben und nicht von P1 + Offset nach P2 - Offset?
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: TLine - Canvas an Line ausrichten

  Alt 6. Mär 2013, 20:35
Vielleicht nochmal zur Erläuterung. Man gibt die roten Koordinaten (Siehe 2. Anlage) vor und die Komponente wird dann so dargestellt (möglichst schon zur Designzeit auf der Form, Offset nach außen, also so wie MoveTo/LineTo das eigentlich machen würde). Das krieg ich aber nicht hin?
Angehängte Dateien
Dateityp: pdf TLine2.pdf (21,3 KB, 6x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#5

AW: TLine - Canvas an Line ausrichten

  Alt 6. Mär 2013, 20:41
Das Problem ist aber ein anderes. Ich mu0 hier genau zeichen. Ich will ja eine Line von z.B. P1 nach P2 haben und nicht von P1 + Offset nach P2 - Offset?
Wenn die Linien dicker werden, dann geht das aber nicht so einfach.
Das Rechteck, dass von der Komponente mit Top, Left, Height und Width aufgespannt wird, darf auf keinen Fall überschritten werden. (das blaue Rechteck)
Die beiden Endpunkte einer Linie spannen ebenfalls ein Rechteck auf. (das rote Rechteck)
Dieses Rechteck muss bei diagonalen Linien jeweils um die halbe Linienbreite kleiner sein als das umgebende Rechteck der Komponente.
Du könntest der Komponente eine Methode spendieren, die das Rechteck der Komponente entsprechend vergrössert:
Delphi-Quellcode:
procedure TLine.InflateBoundingRect;
var
  lw2 : integer;
begin
   lw2 := LineWidth div 2;

   // TODO: Fallunterscheidung bzgl. TLineAline bzw.TLineStyle
   SetBounds(Left-lw2, Top-lw2, Width+lw2, Height+lw2);
end;

Geändert von sx2008 ( 6. Mär 2013 um 20:44 Uhr)
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: TLine - Canvas an Line ausrichten

  Alt 6. Mär 2013, 20:46
Zitat:
Wenn die Linien dicker werden, dann geht das aber nicht so einfach.
Genau!!

Zitat:
Du könntest der Komponente eine Methode spendieren, die das Rechteck der Komponente entsprechend vergrössert:
Also, wenns so einfach geht wäre natürlich super. Probier ich sofort aus. Thanx! Hoffe Paint spielt dann nicht verrückt...
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: TLine - Canvas an Line ausrichten

  Alt 6. Mär 2013, 21:06
Nee, das geht nicht. Wo sollte ich das auch hinschreiben? In Paint geht ja nicht. Da würde ja bei jedem Paint With und Height der Komponente vergrößert. Width und Height sind ja die von TGraphicControl geerbten. Deshalb meinte ich, man sollte die Komponente vielleicht von was ganz anderem ableiten, nur von welcher? wobei ich die Mauseereignisse schon bräuchte..
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: TLine - Canvas an Line ausrichten

  Alt 7. Mär 2013, 13:09
Was mir gestern abend noch eingefallen ist, was ich brauch' nennt man wohl Autosize.

Deshalb schau ich mir gerade die TCustomLabel an, weil die auch von TGraphicControl ebgeleitet ist und ein Autosize hat (die Komponentenhöhe wird da ja auch anhand der Fontgröße gesetzt, falls Autosize true ist).

In diesem Zusammenhang ist bei mir folgende Frage aufgetaucht:
Delphi-Quellcode:
  TCustomLabel = class(TGraphicControl)
    ..
  public
    ..
    property Caption;
    property Canvas;
  end;
Die beiden Properties. Diese Syntax ist mir nicht bekannt.
Wieso weiß denn Delphi, von welchem Typ die sind?
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#9

AW: TLine - Canvas an Line ausrichten

  Alt 7. Mär 2013, 13:19
Die Property ist in TControl als protected implementiert und wird in TCustomLabel sichtbar gesetzt (public)

TCustomLabel/TGraphicControl/TControl
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: TLine - Canvas an Line ausrichten

  Alt 7. Mär 2013, 14:02
Ok. Thanx.

Die Methode Loaded war mir auch nicht bekannt. Es geht so, wie sx2008 vorgeschlagen hat. Hab aber nicht gewußt, daß das nach Loaded rein muß. Was aber immer noch nicht geht, daß es zur Designzeit angezeigt wird.

Delphi-Quellcode:
procedure TLine.Loaded;
begin
  inherited Loaded;
  AdjustBounds;
end;

Geändert von Bjoerk ( 7. Mär 2013 um 14:06 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es 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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:12 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