Images mit Linien verbinden, Drag&Drop
-
Hallo,
zwei Fragen:
ich habe auf der Form verschiedene Images. Diese verbinde ich mit einer Linie, die ich per Canvas auf die Form male. Nun will ich bei Drag&Drop, dass die Linien mitwandern. Ich könnte sie auch beim MouseUp nach dem Drag&Drop alle neu zeichnen lassen, würde aber lieber die erste Variante nehmen. Hierfür ist mein Ansatz, dass ich bei jeder Mausbewegung die alte Linie durch die Hintergrundfarbe ersetze und zur aktuellen Position eine neue zeichne. Oder liege ich da falsch ?Das Problem ist auch, dass ich per Drag&Drop die bestehenden Linien "wegwischen" kann, wenn das Image-Objekt darüber gezogen wird. Kann ich das verhindern ?
Peter
-
So ein "rubber banding" lässt sich mit der pmXOR-Einstellung des Pen erreichen. Dazu sollte die Suchfunktion auch einige Threads liefern.
-
Danke. Mir ist eben aufgefallen, dass alle Linien, die ich auf der Form zeichne verschwunden sind, wenn ich in einen anderen Task wechsle und wieder zurück gehe, also die Anwendung durch ein anderes Fenster überlappt wird. Kann ich das umgehen ?
-
Hallo,
das ist mein Ansatz. Ich merke mir in einem Array zu jedem zur Laufzeit erzeugten Image die alten x/y Werte (Array Pos 2,3) und die aktuellen (0,1) an Pos. 4 steht die Verbindung zu einem anderen Image. Über das Kontextmenü wähle ich aus, dass eine Beziehung hergestellt werden soll und danach das Ziel-Image. Im Moment kommen alle Linien jeweils von oben links nach oben links. Will ich später in Abhängigkeit der Position jeweils in der Mitte der Außenseite plazieren.
Dann lasse ich es bei MouseUp neu zeichnen. Klappt halbwegs. Ist das denn ein Ansatz so ?
TImage *img[10]; int iPos[10][5]; void __fastcall TfrmMain::Image1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { scX = X; scY = Y; scDyn = 1; if (Button == mbRight) { int iX = dynamic_cast<TImage*>(Sender)->Left + dynamic_cast<TImage*>(Sender)->Width + X + 10; int iY = dynamic_cast<TImage*>(Sender)->Top + Y + 150; iValue = StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false)); objPopup->Popup(iX, iY); } if (Button == mbLeft) { if (bBeziehung == true) { bBeziehung = false; Label1->Visible = false; frmMain->Canvas->MoveTo(img[iVon]->Left, img[iVon]->Top); frmMain->Canvas->LineTo(dynamic_cast<TImage*>(Sender)->Left, dynamic_cast<TImage*>(Sender)->Top); int iValue2 = StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false)); iPos[iValue2][0] = img[iValue2]->Left; iPos[iValue2][1] = img[iValue2]->Top; iPos[iVon][4] = iValue; IsDrawing = true; } } } void __fastcall TfrmMain::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if (scDyn == 1 && scX - X < 0) { dynamic_cast<TImage*>(Sender)->Left = dynamic_cast<TImage*>(Sender)->Left + (X - scX); memo[StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false))]->Left = dynamic_cast<TImage*>(Sender)->Left + 16; memo[StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false))]->Top = dynamic_cast<TImage*>(Sender)->Top + 16; } if (scDyn == 1 && scX - X > 0) { dynamic_cast<TImage*>(Sender)->Left = dynamic_cast<TImage*>(Sender)->Left - (scX - X); memo[StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false))]->Left = dynamic_cast<TImage*>(Sender)->Left + 16; memo[StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false))]->Top = dynamic_cast<TImage*>(Sender)->Top + 16; } if (scDyn == 1 && scY - Y < 0) { dynamic_cast<TImage*>(Sender)->Top = dynamic_cast<TImage*>(Sender)->Top + (Y - scY); memo[StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false))]->Left = dynamic_cast<TImage*>(Sender)->Left + 16; memo[StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false))]->Top = dynamic_cast<TImage*>(Sender)->Top + 16; } if (scDyn == 1 && scY - Y > 0) { dynamic_cast<TImage*>(Sender)->Top = dynamic_cast<TImage*>(Sender)->Top - (scY - Y); memo[StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false))]->Left = dynamic_cast<TImage*>(Sender)->Left + 16; memo[StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false))]->Top = dynamic_cast<TImage*>(Sender)->Top + 16; } iPos[StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false))][0] = dynamic_cast<TImage*>(Sender)->Left; iPos[StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false))][1] = dynamic_cast<TImage*>(Sender)->Top; iValue = StrToInt(Separator(dynamic_cast<TImage*>(Sender)->Name, "T", 2, false)); frmMain->SetFocus(); } void __fastcall TfrmMain::Image1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { scDyn = 0; for (int i = 0; i < 10; i++) { if (iPos[i][4] != 0) { frmMain->Canvas->MoveTo(iPos[i][0], iPos[iVon][1]); frmMain->Canvas->LineTo(iPos[iPos[i][4]][2], iPos[iPos[i][4]][3]); frmMain->Canvas->MoveTo(iPos[i][0], iPos[iVon][1]); frmMain->Canvas->LineTo(iPos[iPos[i][4]][0], iPos[iPos[i][4]][1]); } } } void __fastcall TfrmMain::FesteBeziehung1Click(TObject *Sender) { Label1->Left = iMouseX - 30; Label1->Top = iMouseY + 30; Label1->Visible = true; bBeziehung = true; iVon = iValue; scDyn = 0; iPos[iValue][0] = img[iValue]->Left; iPos[iValue][1] = img[iValue]->Top; }
-
Bevor ich mir das im detail ansehe erstmal zwei Dinge.
1. Wenn TImage *img[10] und int iPos[10][5]; globale Variablen sind, nimm sie da raus und mache aus ihnen membervariablen deiner Form.
2. Ein dynamic_cast pro Funktion reicht. das macht das ganze deutlich lesbarer.
So etwavoid __fastcall TfrmMain::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { TImage* img = dynamic_cast<TImage*>(Sender); if( img ) { // dann mit img weiter arbeiten3. Verwende bitte die C++Tags, dann gibt es auch Syntax-coloring