Basketball Playbook erstellen
Re: Basketball Playbook erstellen
Moin Moin,
Das Programm läuft super, aber leider fehlt mir noch eine Funktion um die Dribblings darzustellen. Normalerweise wird dies mit gewellten Linien dargestellt, jedoch weiß ich leider nicht wie ich das umsetzen soll. Das ganze müsste zusätzlich auch bei der Bezierkurve implementiert werden.
Hier mal ein Beispielbild:
Hätte da jemand eine Idee wie ich das umsetzen kann?
Liebe Grüße
Das Programm läuft super, aber leider fehlt mir noch eine Funktion um die Dribblings darzustellen. Normalerweise wird dies mit gewellten Linien dargestellt, jedoch weiß ich leider nicht wie ich das umsetzen soll. Das ganze müsste zusätzlich auch bei der Bezierkurve implementiert werden.
Hier mal ein Beispielbild:

Hätte da jemand eine Idee wie ich das umsetzen kann?
Liebe Grüße

- Fluid Byte
- Beiträge: 3110
- Registriert: 27.09.2006 22:06
- Wohnort: Berlin, Mitte
Re: Basketball Playbook erstellen
Hör auf zu betteln, is' ja widerlich 

Windows 10 Pro, 64-Bit / Outtakes | Derek
- alter Mann
- Beiträge: 201
- Registriert: 29.08.2008 09:13
- Wohnort: hinterm Mond
Re: Basketball Playbook erstellen
siehe Schlangenlinie :
die From ist abhängig von dem Punktabstand der zu Grunde liegenden Bezierkurve
Code: Alles auswählen
EnableExplicit
Enumeration
#Window_0
EndEnumeration
Enumeration
#Image_0
#Tree_0
#Combo_0
#Combo_1
#Button_0
#Button_1
#Button_2
#Text_0
#Text_1
#Spin_0
#Option_0
#Option_1
#ImageID_0
#ImageID_1
EndEnumeration
Enumeration
#Typ_Pfeil_Gerade = 0
#Typ_Pfeil_Bezier
#Typ_Pfeil_Schlange
#Typ_Image
EndEnumeration
Structure Displayliste
iTyp.i ; Typ des Darstellungselementes
iStyle.i ; Darstellungstyp / ImageID
iAnz.i ; Anzahl Koordinaten
aiX.i[16]
aiY.i[16]
iBreite.i
iColor.i
EndStructure
#Text_Gerade = "Gerader Pfeil :"+Chr(13)+Chr(10)+"linke Maustaste drücken und halten, beim Loslassen ist der Pfeil fertig"
#Text_Kurve = "Krummer Pfeil :"+Chr(13)+Chr(10)+"4mal linke Maustaste drücken, dann wird der Pfeil dargestellt"
#Text_Schlange = "Schlangenlinie:"+Chr(13)+Chr(10)+"4mal linke Maustaste drücken, dann wird der Pfeil dargestellt"
#Text_Bild = "Bild :"+Chr(13)+Chr(10)+"Bild auswählen, mit linker Maustaste setzen, mit rechter Maustaste beenden"
Global gfOldImageProc ; alte Fensterprocedure des Imagegadgets
Global glColor
Global giImage = -1
Global NewList gViewList.Displayliste()
Procedure Win_ColorsInit (hDC, pColorLine, pLineWidth, pLineType, pColorFill, pFillMode, *hPen, *hBrush)
; F: Farbe und Stil für Stift und Pinsel definieren
; E: hDC Windows Device Context
; pColorLine LinienFarbe
; pLineType #PS_SOLID/#PS_DASH/#PS_DOT/#PS_DASHDOT/#PS_DASHDOTDOT | #PS_ENDCAP_ROUND/#PS_ENDCAP_SQUARE/#PS_ENDCAP_FLAT | #PS_JOIN_ROUND/#PS_JOIN_BEVEL/#PS_JOIN_MITER
; pColorFill Füllfarbe
; pFillMode #ALTERNATE / #WINDING
; A: hPen Windows Pen
; hBrush Windows Brush
Protected tLBrush.LOGBRUSH ; Füllstil definieren
tLBrush\lbStyle = #BS_SOLID
tLBrush\lbColor = pColorFill
tLBrush\lbHatch = 0 ; nicht benötigt, wenn #BS_SOLID definiert
Protected hPen = ExtCreatePen_(pLineType|#PS_GEOMETRIC,pLineWidth,@tLBrush,0,#Null) ; Linienstift definieren
SetPolyFillMode_(hDC,pFillMode) ; Füllmodus bei sich überschneidenden Linien
Protected hBrush = CreateSolidBrush_(pColorFill)
PokeI (*hPen,hPen) ; Stift und Pinsel ausgeben
PokeI (*hBrush,hBrush) ;
hPen = SelectObject_(hDC,hPen) ; Stift und Pinsel zum Zeichnen auswählen
DeleteObject_(hPen)
hBrush = SelectObject_(hDC,hBrush)
DeleteObject_(hBrush)
EndProcedure
Procedure Win_ColorsDel (hPen,hBrush)
; F: Stift und Pinsel löschen
; E: hPen,hBrush Stift und Pinsel
DeleteObject_(hPen)
DeleteObject_(hBrush)
EndProcedure
Procedure Win_Polygon (hDC, iAnz.i, *iX.i, *iY.i)
; F: geschlossenes Polygon zeichnen
; E: hDC Windows Device Context
; iAnz Anzahl Koordinaten
; iX(),iY() Koordinaten
Protected *tPoints.POINT = AllocateMemory(iAnz*SizeOf(POINT)), *tP ; Speicher für Punkte holen
Protected i.i
*tP = *tPoints
For i = 0 To iAnz-1 Step 1 ; Punktkoordinaten zuweisen
*tPoints\x = PeekI(*iX)
*tPoints\y = PeekI(*iY)
*tPoints + SizeOf(POINT)
*iX + SizeOf(Integer)
*iY + SizeOf(Integer)
Next i
Polygon_(hDC,*tP,iAnz) ; Polygon zeichnen
FreeMemory(*tP) ; Speicher freigeben
EndProcedure
Procedure Win_PolyBezier (hDC, iAnz.i, *iX.i, *iY.i)
; F: Bezierkurve zeichnen, die Anzahl der Koordinaten muss durch 4 teilbar sein
; E: hDC Windows Device Context
; iAnz Anzahl Koordinaten
; iX(),iY() Koordinaten
Protected *tPoints.POINT = AllocateMemory(iAnz*SizeOf(POINT)), *tP ; Punktspeicher holen
Protected i.i
*tP = *tPoints
For i = 0 To iAnz-1 Step 1 ; Punktkoordinaten zuweisen
*tPoints\x = PeekI(*iX)
*tPoints\y = PeekI(*iY)
*tPoints + SizeOf(POINT)
*iX + SizeOf(Integer)
*iY + SizeOf(Integer)
Next i
PolyBezier_(hDC,*tP,iAnz) ; Bezierkurve zeichnen
FreeMemory(*tP) ; Speicher freigeben
EndProcedure
Procedure Win_PolyLine (hDC, iAnz.i, *iX.i, *iY.i)
; F: offenes Polygon zeichnen
; E: hDC Windows Device Context
; iAnz Anzahl Koordinaten
; iX(),iY() Koordinaten
Protected i.i
MoveToEx_(hDC,PeekI(*iX),PeekI(*iY),#Null) ; ersten Punkt anfahren
*iX + SizeOf(Integer)
*iY + SizeOf(Integer)
For i = 1 To iAnz-1 Step 1
LineTo_(hDC,PeekI(*iX),PeekI(*iY)) ; Linie vom Vorgängerpunkt zum aktuellen Punkt zeichnen
*iX + SizeOf(Integer)
*iY + SizeOf(Integer)
Next i
EndProcedure
Procedure.d Win_PolyLaenge(iAnz.i, *iX.i, *iY.i)
Protected dL.d=0.0
Protected iX1.i,iY1.i,iX2.i,iY2.i,i.i
iX1 = PeekI(*iX)
iY1 = PeekI(*iY)
For i=0 To iAnz-2
*iX + SizeOf(Integer)
*iY + SizeOf(Integer)
iX2 = PeekI(*iX)
iY2 = PeekI(*iY)
dL + Sqr((iX2-iX1)*(iX2-iX1)+(iY2-iY1)*(iY2-iY1))
iX1 = iX2
iY1 = iY2
Next i
ProcedureReturn dL
EndProcedure
Procedure.d NueberR(iN.i,iR.i)
If iN<iR
ProcedureReturn 0.0
ElseIf iN = iR Or iR = 0
ProcedureReturn 1.0
ElseIf iR = 1 Or iN = iR+2
ProcedureReturn iN
EndIf
Protected i.i
Protected dErg.d = iN
For i=2 To iR
iN - 1
dErg * iN
dErg / iR
Next i
ProcedureReturn dErg
EndProcedure
Procedure.d BezierNRT (iN.i,iR.i,dT.d)
Protected dErg.d
dErg = Pow(dT,iR)
dErg * Pow(1.0-dT,iN-iR)
dErg * NueberR(iN,iR)
ProcedureReturn dErg
EndProcedure
Procedure.i BezierPunkt(iA.i,*iP.i,dT.d)
Protected i.i
Protected dErg.d=0
For i=0 To iA-1
dErg + PeekI(*iP) * BezierNRT(iA-1,i,dT)
*iP + SizeOf(Integer)
Next i
i = Int(dErg)
ProcedureReturn i
EndProcedure
Procedure.i BezierTangente(iA.i,*iP.i,dT.d)
Protected i.i,iP1.i,iP2.i
Protected dErg.d=0
iP1 = PeekI(*iP)
*iP + SizeOf(Integer)
For i=0 To iA-2
iP2 = PeekI(*iP)
*iP + SizeOf(Integer)
dErg + (iP2-iP1)*BezierNRT(iA-2,i,dT)
iP1 = iP2
Next i
dErg * (iA-1)
i = Int(dErg)
ProcedureReturn i
EndProcedure
Procedure Win_BezierTangente ( dPos.d, iAnz.i, *iX.i, *iY.i ,*piTX.i, *piTY.i)
; F: Tangente am Ende einer Bezierkurve berechnen
; E: iPos 0 Tangente am Anfang, sonst am Ende
; iAnz Anzahl Koordinaten
; iX(),iY() Koordinaten
; A: *piTX,*piTY Tangente
If dPos = 0
Protected iX0.i = PeekI(*iX), iY0.i = PeekI(*iY)
Protected iTX.i = PeekI(*iX+SizeOf(Integer))-iX0, iTY.i = PeekI(*iY+SizeOf(Integer))-iY0
If iTX = 0 And iTY = 0
iTX = PeekI(*iX+2*SizeOf(Integer))-iX0
iTY = PeekI(*iY+2*SizeOf(Integer))-iY0
If iTX = 0 And iTY = 0
iTX = PeekI(*iX+3*SizeOf(Integer))-iX0
iTY = PeekI(*iY+3*SizeOf(Integer))-iY0
EndIf
EndIf
ElseIf dPos = 1.0
iX0 = PeekI(*iX+(iAnz-1)*SizeOf(Integer))
iY0 = PeekI(*iY+(iAnz-1)*SizeOf(Integer))
iTX = iX0-PeekI(*iX+(iAnz-2)*SizeOf(Integer))
iTY = iY0-PeekI(*iY+(iAnz-2)*SizeOf(Integer))
If iTX = 0 And iTY = 0
iTX = iX0-PeekI(*iX+(iAnz-3)*SizeOf(Integer))
iTY = iY0-PeekI(*iY+(iAnz-3)*SizeOf(Integer))
If iTX = 0 And iTY = 0
iTX = iX0-PeekI(*iX+(iAnz-4)*SizeOf(Integer))
iTY = iY0-PeekI(*iY+(iAnz-4)*SizeOf(Integer))
EndIf
EndIf
Else
iTX = BezierTangente(iAnz,*iX,dPos)
iTY = BezierTangente(iAnz,*iY,dPos)
EndIf
PokeI(*piTX,iTX)
PokeI(*piTY,iTY)
EndProcedure
Procedure Win_PolySchlange (hDC, iAnz.i, *iX.i, *iY.i, iAbst.i, iAnzS.i, iAnzP.i)
Protected i.i,j.i,iXP.i,iYP.i,iXT.i,iYT.i
Protected dT.d,dL.d,dW.d
For i=0 To iAnzS-1
For j=0 To iAnzP
dT = j+i*(iAnzP+1)
dT / (iAnzS*(iAnzP+1)-1)
;Debug "i="+Str(i)+" j="+Str(j)+" T="+StrD(dT,6)
iXP = BezierPunkt(iAnz,*iX,dT)
iYP = BezierPunkt(iAnz,*iY,dT)
iXT = BezierTangente(iAnz,*iX,dT)
iYT = BezierTangente(iAnz,*iY,dT)
;Debug "T:"+StrD(dT,6)+" X:"+Str(iXT)+" Y:"+Str(iYT)
dL = Sqr(iXT*iXT+iYT*iYT)
dW = iAnzS*2*#PI*dT/0.97
If dT<0.97
iXP + Int(-Sin(dW) * iYT / dL * iAbst)
iYP + Int( Sin(dW) * iXT / dL * iAbst)
EndIf
If i=0 And j=0
MoveToEx_(hDC,iXP,iYP,#Null)
Else
LineTo_(hDC,iXP,iYP)
EndIf
Next j
Next i
EndProcedure
Procedure Win_DrawPfeil (hDC, iTyp, iForm.i, iAnz.i, *iX.i, *iY.i, iBreite.i, iColor.i)
; F: Pfeil zeichnen
; E: hDC Windows Device Context
; iTyp #PS_SOLID durchgezogene Linie
; #PS_DASH gestrichelt
; #PS_DOT gepunktet
; #PS_DASHDOT ,#PS_DASHDOTDOT ...
; iAnz Anzahl Koordinaten
; iForm 2 Linie 4 Bezier 6 Schlange
; iX(),iY() Koordinaten
; iBreite Strichbreite
; iColor Farbe
Protected hPen,hBrush
Win_ColorsInit (hDC, iColor, iBreite, iTyp|#PS_ENDCAP_FLAT|#PS_JOIN_ROUND, iColor, #WINDING, @hPen, @hBrush) ; Farbe und Stil definieren
If iForm = 2
Win_PolyLine (hDC, iAnz, *iX, *iY) ; Pfeillinie zeichnen
ElseIf iForm = 4
Win_PolyBezier (hDC, iAnz, *iX, *iY)
Else
Protected dL.d
Protected iAnzS.i
dL = Win_PolyLaenge(iAnz, *iX, *iY)
iAnzS = Int( dL / iBreite * 0.05)
If iAnzS = 0
iAnzS = 1
EndIf
Win_PolySchlange(hDC, iAnz, *iX, *iY, iBreite*5, iAnzS, 10)
EndIf
Win_ColorsDel(hPen,hBrush) ; Stift und Pinsel freigeben
Protected iTX.i, iTY.i, iNX.i, iNY.i, iL.i
Win_BezierTangente ( 1.0, iAnz, *iX, *iY ,@iTX, @iTY) ; Tangente...
iNX = -iTY ; ... und Senkrechte berechnen
iNY = iTX
iL = Int(Sqr(iTX*iTX+iTY*iTY)) ; Tangentenlänge
Protected Dim iXS.i(4)
Protected Dim iYS.i(4)
iXS(0) = PeekI(*iX+SizeOf(Integer)*(iAnz-1)) ; Punkte für die Pfeilspitze berechnen
iYS(0) = PeekI(*iY+SizeOf(Integer)*(iAnz-1))
iXS(1) = iXS(0) + (2*iBreite*iNX)/iL
iYS(1) = iYS(0) + (2*iBreite*iNY)/iL
iXS(2) = iXS(0) + (4*iBreite*iTX)/iL
iYS(2) = iYS(0) + (4*iBreite*iTY)/iL
iXS(3) = iXS(0) - (2*iBreite*iNX)/iL
iYS(3) = iYS(0) - (2*iBreite*iNY)/iL
Win_ColorsInit (hDC, iColor, 1, #PS_GEOMETRIC|#PS_SOLID|#PS_ENDCAP_FLAT|#PS_JOIN_BEVEL, iColor, #WINDING, @hPen, @hBrush) ; Farbe und Stil für die Pfeilspitze
Win_Polygon (hDC, 4, @iXS(), @iYS()) ; Pfeilspitze zeichnen
Win_ColorsDel(hPen,hBrush) ; Stift und Pinsel freigeben
EndProcedure
Procedure Draw (iAnz.i, Array iX.i(1), Array iY.i(1) )
; F: Pfeil zeichnen vorbereiten
; E: hDC Windows Device Context
; iAnz Anzahl Koordinaten
; iX(),iY() Koordinaten
Protected iTyp = GetGadgetState(#Combo_0) ; Pfeillinientyp aus Combobox auslesen
If iTyp = -1
iTyp = #PS_SOLID
Else
iTyp = GetGadgetItemData(#Combo_0,iTyp)
EndIf
Protected hDC = StartDrawing(ImageOutput(#ImageID_0)) ; Device Context des Imagegadgets
Box(0,0,GadgetWidth(#Image_0),GadgetHeight(#Image_0),RGB(50,50,50)) ; Hintergrund
If GetGadgetState(#Option_0) = 1 And iAnz > -1 ; Option einfügen und Punkte vorhanden
If GetGadgetState(#Combo_1) = 3 ; im Image-Modus
DrawImage(ImageID(giImage),iX(0),iY(0))
ElseIf GetGadgetState(#Combo_1) = 2
Win_DrawPfeil (hDC, iTyp, 6, iAnz, @iX(), @iY(), GetGadgetState(#Spin_0), glColor) ; Pfeil zeichnen, bei mehr als einer Koordinate
ElseIf iAnz > 1 ; gerader Pfeil
Win_DrawPfeil (hDC, iTyp, iAnz, iAnz, @iX(), @iY(), GetGadgetState(#Spin_0), glColor) ; Pfeil zeichnen, bei mehr als einer Koordinate
EndIf
EndIf
ResetList(gViewList()) ; gesamte Element-Liste zeichnen
While NextElement(gViewList())
If gViewList()\iTyp = #Typ_Pfeil_Gerade
Win_DrawPfeil (hDC, gViewList()\iStyle, 2, gViewList()\iAnz, @gViewList()+OffsetOf(Displayliste\aiX), @gViewList()+OffsetOf(Displayliste\aiY), gViewList()\iBreite, gViewList()\iColor)
ElseIf gViewList()\iTyp = #Typ_Pfeil_Bezier
Win_DrawPfeil (hDC, gViewList()\iStyle, 4, gViewList()\iAnz, @gViewList()+OffsetOf(Displayliste\aiX), @gViewList()+OffsetOf(Displayliste\aiY), gViewList()\iBreite, gViewList()\iColor)
ElseIf gViewList()\iTyp = #Typ_Pfeil_Schlange
Win_DrawPfeil (hDC, gViewList()\iStyle, 6, gViewList()\iAnz, @gViewList()+OffsetOf(Displayliste\aiX), @gViewList()+OffsetOf(Displayliste\aiY), gViewList()\iBreite, gViewList()\iColor)
ElseIf gViewList()\iTyp = #Typ_Image
DrawImage(ImageID(gViewList()\iStyle),gViewList()\aiX[0],gViewList()\aiY[0])
EndIf
Wend
If GetGadgetState(#Option_1) = 1 And iAnz > -1 ; Option ändern -> Punkte darstellen
SelectElement(gViewList(),iAnz)
Protected i.i
For i=0 To gViewList()\iAnz-1 Step 1
Circle(gViewList()\aiX[i],gViewList()\aiY[i],5,RGB(250,0,0))
Circle(gViewList()\aiX[i],gViewList()\aiY[i],3,RGB(0,250,0))
Next i
EndIf
StopDrawing()
SetGadgetState(#Image_0,ImageID(#ImageID_0)) ; System auf die Änderung des Imagegadgets aufmerksam machen
EndProcedure
Procedure.i TreeFindLastItem (iTree.i, sName.s)
; F: Index für einen neuen Eintrag finden
; E: iTree Gadgetnummer
; sName Name des Eintrags, von dem die Nummer des letzten Untereintrags gefunden werden soll
Protected iAnz.i = CountGadgetItems(iTree), i.i, iFind.i = -2
For i=0 To iAnz-1 Step 1
If iFind = -2 And GetGadgetItemText(iTree,i) = sName And GetGadgetItemAttribute(iTree,i,#PB_Tree_SubLevel) = 0
iFind = i
ElseIf iFind > -1 And GetGadgetItemAttribute(iTree,i,#PB_Tree_SubLevel) > 0
iFind = i
ElseIf iFind > -1
Break
EndIf
Next i
ProcedureReturn iFind
EndProcedure
Procedure Win_CallBackImage(hWnd, Msg, wParam, lParam)
; F: Meldungen für das Imagegadget abfangen
Protected iResult.i = 0, iFind.i
Protected iMausX.i= lParam & $FFFF
Protected iMausY.i= lParam>>16 & $FFFF
Static Dim siX.i(4)
Static Dim siY.i(4)
Static siDraw.i = 0
Static siElem.i = -1
If GetGadgetState(#Combo_1) = 0 And GetGadgetState(#Option_0) = 1 ; gerader Pfeil
Select Msg
Case #WM_LBUTTONDOWN ; linke Maustaste gedrückt
If iMausX > 0 And iMausY > 0 And iMausX < GadgetWidth(#Image_0) And iMausY < GadgetHeight(#Image_0)
DisableGadget(#Combo_1,1)
siX(0) = iMausX
siY(0) = iMausY
siDraw = 1
EndIf
Case #WM_LBUTTONUP ; linke Maustaste losgelassen -> Element eintragen
If iMausX > 0 And iMausY > 0 And iMausX < GadgetWidth(#Image_0) And iMausY < GadgetHeight(#Image_0)
siX(1) = iMausX
siY(1) = iMausY
siDraw = 0
If siX(1)<>siX(0) Or siY(1)<>siY(0)
AddElement(gViewList())
gViewList()\iBreite = GetGadgetState(#Spin_0)
gViewList()\iColor = glColor
gViewList()\iTyp = #Typ_Pfeil_Gerade
gViewList()\aiX[0] = siX(0) : gViewList()\aiX[1] = siX(1)
gViewList()\aiY[0] = siY(0) : gViewList()\aiY[1] = siY(1)
gViewList()\iAnz = 2
gViewList()\iStyle = GetGadgetState(#Combo_0) ; Pfeillinientyp aus Combobox auslesen
If gViewList()\iStyle = -1
gViewList()\iStyle = #PS_SOLID
Else
gViewList()\iStyle = GetGadgetItemData(#Combo_0,gViewList()\iStyle)
EndIf
iFind = TreeFindLastItem(#Tree_0,"gerade Pfeile")
If iFind > -1
AddGadgetItem(#Tree_0,iFind+1,"Linie"+Str(ListSize(gViewList())-1),0,1)
SetGadgetItemData(#Tree_0,iFind+1,ListSize(gViewList())-1)
EndIf
Draw(2,siX(),siY())
DisableGadget(#Combo_1,0)
EndIf
EndIf
Case #WM_MOUSEMOVE ; Maus wird bewegt
If siDraw <> 0 And iMausX > 0 And iMausY > 0 And iMausX < GadgetWidth(#Image_0) And iMausY < GadgetHeight(#Image_0)
siX(1) = iMausX
siY(1) = iMausY
If siX(1)<>siX(0) Or siY(1)<>siY(0)
Draw(2,siX(),siY())
EndIf
EndIf
EndSelect
ElseIf (GetGadgetState(#Combo_1) = 1 Or GetGadgetState(#Combo_1) = 2) And GetGadgetState(#Option_0) = 1 ; krummer Pfeil / Schlangenlinie
Select Msg
Case #WM_LBUTTONDOWN ; linke Maustaste gedrückt
If iMausX > 0 And iMausY > 0 And iMausX < GadgetWidth(#Image_0) And iMausY < GadgetHeight(#Image_0)
If siDraw = 0
DisableGadget(#Combo_1,1)
EndIf
siX(siDraw) = iMausX
siY(siDraw) = iMausY
siDraw + 1
If siDraw = 4 ; 4mal geklickt -> Krummer Pfeil ist fertig
AddElement(gViewList())
gViewList()\iBreite = GetGadgetState(#Spin_0)
gViewList()\iColor = glColor
If GetGadgetState(#Combo_1) = 1
gViewList()\iTyp = #Typ_Pfeil_Bezier
Else
gViewList()\iTyp = #Typ_Pfeil_Schlange
EndIf
gViewList()\aiX[0] = siX(0) : gViewList()\aiX[1] = siX(1) : gViewList()\aiX[2] = siX(2) : gViewList()\aiX[3] = siX(3)
gViewList()\aiY[0] = siY(0) : gViewList()\aiY[1] = siY(1) : gViewList()\aiY[2] = siY(2) : gViewList()\aiY[3] = siY(3)
gViewList()\iAnz = 4
gViewList()\iStyle = GetGadgetState(#Combo_0) ; Pfeillinientyp aus Combobox auslesen
If gViewList()\iStyle = -1
gViewList()\iStyle = #PS_SOLID
Else
gViewList()\iStyle = GetGadgetItemData(#Combo_0,gViewList()\iStyle)
EndIf
Draw(4,siX(),siY())
DisableGadget(#Combo_1,0)
If GetGadgetState(#Combo_1) = 1
iFind = TreeFindLastItem(#Tree_0,"krumme Pfeile")
If iFind > -1
AddGadgetItem(#Tree_0,iFind+1,"Bezier"+Str(ListSize(gViewList())-1),0,1)
SetGadgetItemData(#Tree_0,iFind+1,ListSize(gViewList())-1)
EndIf
Else
iFind = TreeFindLastItem(#Tree_0,"Schlangenlinie")
If iFind > -1
AddGadgetItem(#Tree_0,iFind+1,"Sinus"+Str(ListSize(gViewList())-1),0,1)
SetGadgetItemData(#Tree_0,iFind+1,ListSize(gViewList())-1)
EndIf
EndIf
siDraw = 0
EndIf
EndIf
EndSelect
ElseIf GetGadgetState(#Option_0) = 1
Select Msg
Case #WM_LBUTTONDOWN ; linke Maustaste gedrückt -> Bild wird an der aktuellen Stelle eingefügt
If giImage > -1
AddElement(gViewList())
gViewList()\iBreite = 0
gViewList()\iColor = 0
gViewList()\iTyp = #Typ_Image
gViewList()\aiX[0] = siX(0)
gViewList()\aiY[0] = siY(0)
gViewList()\iAnz = 1
gViewList()\iStyle = giImage ; Imagenummer merken
Draw(1,siX(),siY())
DisableGadget(#Combo_1,0)
siDraw = 0
iFind = TreeFindLastItem(#Tree_0,"Bilder")
If iFind > -1
AddGadgetItem(#Tree_0,iFind+1,"Bild"+Str(ListSize(gViewList())-1),0,1)
SetGadgetItemData(#Tree_0,iFind+1,ListSize(gViewList())-1)
EndIf
EndIf
Case #WM_MOUSEMOVE ; Maus wird bewegt
If giImage > -1
siX(0) = iMausX-ImageWidth(giImage)/2
siY(0) = iMausY-ImageHeight(giImage)/2
Draw(1,siX(),siY())
EndIf
Case #WM_RBUTTONDOWN ; rechte Maustaste -> Beenden
giImage = -1
EndSelect
ElseIf GetGadgetState(#Option_1) = 1 ; Ändern-Option
Select Msg
Case #WM_LBUTTONDOWN ; linke Maustaste gedrückt
siElem = GetGadgetState(#Tree_0) ; aktuelles Element bestimmen
If siElem > -1
siElem = GetGadgetItemData(#Tree_0,siElem)
If siElem > -1
SelectElement(gViewList(),siElem) ; nächstliegenden Punkt bestimmen
Protected i.i
Protected dAbst.d = (iMausX-gViewList()\aiX[0])*(iMausX-gViewList()\aiX[0])+(iMausY-gViewList()\aiY[0])*(iMausY-gViewList()\aiY[0]), dAbstNeu.d
siDraw = 0
For i=1 To gViewList()\iAnz-1 Step 1
dAbstNeu = (iMausX-gViewList()\aiX[i])*(iMausX-gViewList()\aiX[i])+(iMausY-gViewList()\aiY[i])*(iMausY-gViewList()\aiY[i])
If dAbstNeu < dAbst
siDraw = i
dAbst = dAbstNeu
EndIf
Next i
gViewList()\aiX[siDraw] = iMausX
gViewList()\aiY[siDraw] = iMausY
Draw(siElem,siX(),siY())
EndIf
EndIf
Case #WM_MOUSEMOVE ; Maus wird bewegt
If siElem > -1
SelectElement(gViewList(),siElem)
gViewList()\aiX[siDraw] = iMausX
gViewList()\aiY[siDraw] = iMausY
Draw(siElem,siX(),siY())
EndIf
Case #WM_LBUTTONUP ; linke Maustaste losgelassen
siDraw = 0
siElem = -1
EndSelect
EndIf
iResult = CallWindowProc_(gfOldImageProc, hWnd, Msg, wParam, lParam) ; Meldung an die ursprüngliche Messageloop weiterleiten
ProcedureReturn iResult
EndProcedure
Procedure.i Open_WindowMain()
; F: Fenster definieren
If OpenWindow(#Window_0, 50, 50, 750, 750, "Pfeile malen und Images positionieren", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
ImageGadget(#Image_0, 145, 5, 600, 600, #ImageID_0)
TreeGadget(#Tree_0, 0, 5, 130, 600)
AddGadgetItem(#Tree_0,0,"gerade Pfeile",0,0)
SetGadgetItemData(#Tree_0,0,-1)
AddGadgetItem(#Tree_0,1,"krumme Pfeile",0,0)
SetGadgetItemData(#Tree_0,1,-1)
AddGadgetItem(#Tree_0,2,"Schlangenlinie",0,0)
SetGadgetItemData(#Tree_0,2,-1)
AddGadgetItem(#Tree_0,3,"Bilder",0,0)
SetGadgetItemData(#Tree_0,3,-1)
ComboBoxGadget(#Combo_0, 5, 610, 130, 20)
AddGadgetItem(#Combo_0,0,"durchgehend")
SetGadgetItemData(#Combo_0,0,#PS_SOLID)
AddGadgetItem(#Combo_0,1,"gestrichelt")
SetGadgetItemData(#Combo_0,1,#PS_DASH)
AddGadgetItem(#Combo_0,2,"gepunkted")
SetGadgetItemData(#Combo_0,2,#PS_DOT)
AddGadgetItem(#Combo_0,3,"Strich-Punkt")
SetGadgetItemData(#Combo_0,3,#PS_DASHDOT)
AddGadgetItem(#Combo_0,4,"Strich-Punkt-Punkt")
SetGadgetItemData(#Combo_0,4,#PS_DASHDOTDOT)
SetGadgetState(#Combo_0,0)
ComboBoxGadget(#Combo_1,145,650,130,20)
AddGadgetItem(#Combo_1,0,"gerade Linie")
AddGadgetItem(#Combo_1,1,"Bezierkurve")
AddGadgetItem(#Combo_1,2,"Schlangenlinie")
AddGadgetItem(#Combo_1,3,"Image")
SetGadgetState(#Combo_1,0)
ButtonGadget(#Button_0, 625, 720, 120, 25, "Beenden")
ButtonImageGadget(#Button_1, 500, 720, 120, 25, ImageID(#ImageID_1))
ButtonGadget(#Button_2, 375, 720, 120, 25, "neues Bild")
TextGadget(#Text_0,145,610,100,30,"Liniendicke :")
SpinGadget(#Spin_0,250,610,50,20,1,20,#PB_Spin_Numeric)
SetGadgetState(#Spin_0,5)
OptionGadget(#Option_0,350,610,100,30,"Erstellen")
OptionGadget(#Option_1,350,640,100,30,"Ändern")
SetGadgetState(#Option_0,1)
TextGadget(#Text_1,480,610,260,100,#Text_Gerade)
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure Main()
; F: Hauptfunktion
Protected Dim aiX.i(4)
Protected Dim aiY.i(4)
If CreateImage(#ImageID_0,600,600) = 0
MessageRequester("Achtung!","Kann Image nicht erstellen")
End
EndIf
If CreateImage(#ImageID_1,110,20) = 0
MessageRequester("Achtung!","Kann Image nicht erstellen")
End
EndIf
StartDrawing(ImageOutput(#ImageID_1)) ; Farbe des Images-Button zeichnen
glColor = RGB(255,255,255)
Box(0,0,109,19,glColor)
StopDrawing()
If Open_WindowMain() = 0
MessageRequester("Achtung!","Kann Fenster nicht öffnen")
End
EndIf
StartDrawing(ImageOutput(#ImageID_0)) ; Hintergrund des Images zeichnen
Box(0,0,ImageWidth(#ImageID_0),ImageHeight(#ImageID_0),RGB(50,50,50))
StopDrawing()
SetGadgetState(#Image_0,ImageID(#ImageID_0))
gfOldImageProc = SetWindowLongPtr_(GadgetID(#Image_0), #GWL_WNDPROC, @Win_CallBackImage()) ; Meldungen für das Imagegadget abfangen
Repeat
Protected iEvent.i = WaitWindowEvent()
Select iEvent
Case #PB_Event_Gadget
Select EventGadget()
Case #Button_0
iEvent = #PB_Event_CloseWindow
Case #Button_1 ; neue Farbe für Pfeile
glColor = ColorRequester(glColor)
StartDrawing(ImageOutput(#ImageID_1))
Box(0,0,109,19,glColor)
StopDrawing()
SetGadgetAttribute(#Button_1, #PB_Button_Image, ImageID(#ImageID_1))
If GetGadgetState(#Option_1) = 1
Protected iElem.i = -1
iElem = GetGadgetState(#Tree_0)
If iElem > -1
iElem = GetGadgetItemData(#Tree_0,iElem)
If iElem > -1
SelectElement(gViewList(),iElem)
gViewList()\iColor = glColor
EndIf
EndIf
Draw(iElem,aiX(),aiY())
EndIf
Case #Button_2 ; neues Bild auswählen
If GetGadgetState(#Combo_1) = 3
Protected sFile.s = GetPathPart(ProgramFilename())
Protected sPattern.s = "Bitmap (*.bmp)|*.bmp|JPEG (*.jpg)|*.jpg;*.jpeg|PNG (*.png)|*.png|Alle Dateien (*.*)|*.*"
Protected iPattern.i = 0
sFile = OpenFileRequester("Bitte Datei zum Laden auswählen", sFile, sPattern, iPattern)
If sFile
iPattern = SelectedFilePattern()
If iPattern = 0
ElseIf iPattern = 1
UseJPEGImageDecoder()
ElseIf iPattern = 2
UsePNGImageDecoder()
EndIf
giImage = LoadImage(#PB_Any,sFile)
DisableGadget(#Combo_1,1)
EndIf
EndIf
Case #Tree_0 ; Element auswählen
If GetGadgetState(#Option_1) = 1
iElem = GetGadgetState(#Tree_0)
If iElem > -1
iElem = GetGadgetItemData(#Tree_0,iElem)
EndIf
Draw(iElem,aiX(),aiY())
EndIf
Case #Option_1 ; Option Ändern
iElem = GetGadgetState(#Tree_0)
If iElem > -1
iElem = GetGadgetItemData(#Tree_0,iElem)
EndIf
Draw(iElem,aiX(),aiY())
Case #Option_0 ; Option Einfügen
Draw(-1,aiX(),aiY())
Case #Combo_1 ; Hilfetexte setzen
iElem = GetGadgetState(#Combo_1)
Select iElem
Case -1 : SetGadgetText(#Text_1,"")
Case 0 : SetGadgetText(#Text_1,#Text_Gerade)
Case 1 : SetGadgetText(#Text_1,#Text_Kurve)
Case 2 : SetGadgetText(#Text_1,#Text_Schlange)
Case 3 : SetGadgetText(#Text_1,#Text_Bild)
EndSelect
Case #Combo_0
If GetGadgetState(#Option_1) = 1
iElem = GetGadgetState(#Tree_0)
If iElem > -1
iElem = GetGadgetItemData(#Tree_0,iElem)
If iElem > -1
SelectElement(gViewList(),iElem)
gViewList()\iStyle = GetGadgetState(#Combo_0)
EndIf
EndIf
Draw(iElem,aiX(),aiY())
EndIf
Case #Spin_0
If GetGadgetState(#Option_1) = 1
iElem = GetGadgetState(#Tree_0)
If iElem > -1
iElem = GetGadgetItemData(#Tree_0,iElem)
If iElem > -1
SelectElement(gViewList(),iElem)
gViewList()\iBreite = GetGadgetState(#Spin_0)
EndIf
EndIf
Draw(iElem,aiX(),aiY())
EndIf
EndSelect
EndSelect
Until iEvent = #PB_Event_CloseWindow
CloseWindow(#Window_0)
EndProcedure
Main()
Win11 64Bit / PB 6.0