CanvasGadget

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: CanvasGadget

Beitrag von NicTheQuick »

Ich würde einfach nur die Funktion DrawCanvas() kopieren, dann PrintCanvas() nennen und diese so anpassen, dass sie sich automatisch an die Papiergröße anpasst und das Bild passend darauf malt. Also nicht das Bild aus dem Canvas nehmen und drucken, sondern es extra für den Druckvorgang neu malen, sodass es für die eingestellt DPI-Zahl passt.
derschutzhund
Beiträge: 328
Registriert: 06.06.2013 20:37
Computerausstattung: Satellite A210-19Z, Samsung Netbook N130, VPAD10

Re: CanvasGadget

Beitrag von derschutzhund »

NicTheQuick hat geschrieben:Ich würde einfach nur die Funktion DrawCanvas() kopieren, dann PrintCanvas() nennen und diese so anpassen, dass sie sich automatisch an die Papiergröße anpasst und das Bild passend darauf malt. Also nicht das Bild aus dem Canvas nehmen und drucken, sondern es extra für den Druckvorgang neu malen, sodass es für die eingestellt DPI-Zahl passt.
Bekommt ihr unter Linux bei dieser Druckroutine die Auflösung des Druckers angezeigt und könnt ihr sie umstellen???
Satellite A210-19Z, Samsung N130, VPAD10, WinXP, Win7, PuppyLinux, PB 5.24, 5.31. 5.70
Elektronik, Mikrocontroller, CNC-Technik, 3D-Druck
derschutzhund
Beiträge: 328
Registriert: 06.06.2013 20:37
Computerausstattung: Satellite A210-19Z, Samsung Netbook N130, VPAD10

Re: CanvasGadget

Beitrag von derschutzhund »

Gebe es jetzt auf das Canvas unter Linux auszudrucken! Ist Müll und unter Mac ist es möglicherweise auch nicht toll oder es gibt neue Probleme.
Da muss bei PB doch wohl noch einiges gemacht werden!!!

Erzeuge dann halt, wie bisher auch, html-Dateien!

Schade, ich dachte es geht unter PB über die Druckfunktion! :twisted:
Satellite A210-19Z, Samsung N130, VPAD10, WinXP, Win7, PuppyLinux, PB 5.24, 5.31. 5.70
Elektronik, Mikrocontroller, CNC-Technik, 3D-Druck
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: CanvasGadget

Beitrag von NicTheQuick »

Das liegt wohl kaum an PB, sondern an fehlenden Treibern für den Drucker, wenn man keine DPI einstellen kann. Nicht mal die fehlende Zoomfunktion des CanvasGadgets ist Schuld an dem Problem. Du solltest dich lieber mal in kleinen Schritten an die ganzen Befehle heran tasten anstatt hier direkt herum zu meckern.
Das, was hier tatsächlich fehlt, ist eine Funktion, die die eingestellte DPI-Zahl ausgibt. Aber dass die PB-Druck-Funktionen nicht ausgereift sind, wissen wir schon Jahre lang. Ich glaube seit Version 2.6 und noch früher hat sich da nichts mehr daran geändert...
derschutzhund
Beiträge: 328
Registriert: 06.06.2013 20:37
Computerausstattung: Satellite A210-19Z, Samsung Netbook N130, VPAD10

Re: CanvasGadget

Beitrag von derschutzhund »

Das liegt wohl kaum an PB, sondern an fehlenden Treibern für den Drucker, wenn man keine DPI einstellen kann.
Wohl eher nicht denn bei allen anderen Linuxprogrammen wird die Auflösung angezeigt und kann eingestellt werden!
Du solltest dich lieber mal in kleinen Schritten an die ganzen Befehle heran tasten anstatt hier direkt herum zu meckern.
Ich habe mich nun drei Tage mit der Druckfunktion beschäftigt und wenn sich dann zeigt, dass es hier und da klemmt kann man das auch ruhig mal sagen oder?
Aber dass die PB-Druck-Funktionen nicht ausgereift sind, wissen wir schon Jahre lang. Ich glaube seit Version 2.6 und noch früher hat sich da nichts mehr daran geändert...
Jetzt also doch PB :mrgreen:

Wenn es legitim ist PB für bestimmte Stärken zu loben ist es ebenso erlaubt sich mal über die Schwächen, so man sie findet, auszulassen.
Auch bin ich der Meinung, dass es die Programmentwicklung weiterbringt wenn man mehr über bestimmte Schwächen redet.
Nachdem ich PB käuflich erworben habe, macht es für mich schon einen Unterschied zur Freeware oder gar open source! Bei einer kommerziellen Software erwarte ich die Behebung von bekannten Fehlern nach vertretbarer Zeit sonst sollte man auf den Status von Freeware zurückgehen!
Nochmal, es nützt einem Entwickler nichts, wenn man ihm ständig nur sagt, wie toll alles ist!

Was wirklich toll ist, ist dieses Forum. Die Reaktionszeiten sind echt genial kurz!

LG

Wolfgang
Satellite A210-19Z, Samsung N130, VPAD10, WinXP, Win7, PuppyLinux, PB 5.24, 5.31. 5.70
Elektronik, Mikrocontroller, CNC-Technik, 3D-Druck
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: CanvasGadget

Beitrag von CSHW89 »

Wenn du Ideen hast, PB weiterzuführen, bzw. für neue Befehle ect.., kann ihr dir den Wünschthread im englischen Forum empfehlen:
http://www.purebasic.fr/english/viewforum.php?f=3

Allerdings muss man auch immer dran denken, dass PB von einem wirklich kleinen Team entwickelt wird. Das geht dann nicht so schnell, wie man es gern hätte. Aber dass es zumindest die Möglichkeit gibt, solche Wünsche zu äußern, ist ja schon aller Ehren wert.

lg Kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
derschutzhund
Beiträge: 328
Registriert: 06.06.2013 20:37
Computerausstattung: Satellite A210-19Z, Samsung Netbook N130, VPAD10

Re: CanvasGadget

Beitrag von derschutzhund »

Hallo Kevin,
Wenn du Ideen hast, PB weiterzuführen, bzw. für neue Befehle ect.., kann ihr dir den Wünschthread im englischen Forum empfehlen:
das ist ein guter Tipp!

LG

Wolfgang
Satellite A210-19Z, Samsung N130, VPAD10, WinXP, Win7, PuppyLinux, PB 5.24, 5.31. 5.70
Elektronik, Mikrocontroller, CNC-Technik, 3D-Druck
derschutzhund
Beiträge: 328
Registriert: 06.06.2013 20:37
Computerausstattung: Satellite A210-19Z, Samsung Netbook N130, VPAD10

Re: CanvasGadget

Beitrag von derschutzhund »

Kann mir jemand sagen, wie ich diesen Code so erweitern kann, dass die Elemente mit der linken Maus-Taste auch vergrößert werden können?
Habe dazu schon mal unten Rechts jeweils eine kleine Fläche "angebaut" die man dafür nutzen kann.

EDIT: Habe es jetzt erst mal über Schieberegler gemacht aber super gut ist das nicht!

Code: Alles auswählen

EnableExplicit

Structure canvasitem
    img.i
    x.i
    y.i
    width.i
    height.i
    alphatest.i
    name.s
EndStructure

Enumeration
    #MyCanvas = 1   ; just to test whether a number different from 0 works now
EndEnumeration

Enumeration 10
    #ImagePopup
EndEnumeration

Enumeration 10
  #RemoveImage
  #ChangeImage
EndEnumeration

Define isCurrentItem=#False
Define currentItemXOffset.i, currentItemYOffset.i
Define Event.i, x.i, y.i, drag.i, hole.i
NewList Images.canvasitem()


Procedure AddImage (List Images.canvasitem(), name.s, x, y, img, alphatest=0)
    If AddElement(Images())
        Images()\img    = img
        Images()\x      = x
        Images()\y      = y
        Images()\width  = ImageWidth(img)
        Images()\height = ImageHeight(img)
        Images()\alphatest = alphatest
        images()\name = name.s
    EndIf
EndProcedure

Procedure DrawCanvas (canvas.i, List Images.canvasitem())
    If StartDrawing(CanvasOutput(canvas))
        Box(0, 0, GadgetWidth(canvas), GadgetHeight(canvas), RGB(255,255,255))
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        ForEach Images()
            DrawImage(ImageID(Images()\img),Images()\x,Images()\y,images()\width,images()\height) ; draw all images with z-order
            DrawImage(ImageID(Images()\img),(Images()\x)+images()\width,(Images()\y)+images()\height,6,6)
         Next
        StopDrawing()
    EndIf
EndProcedure

Procedure.i HitTest (List Images.canvasitem(), x, y)
    Shared currentItemXOffset.i, currentItemYOffset.i
    Protected alpha.i, isCurrentItem.i = #False
   
    If LastElement(Images()) ; search for hit, starting from end (z-order)
        Repeat
            If x >= Images()\x And x < Images()\x + Images()\width
                If y >= Images()\y And y < Images()\y + Images()\height
                    alpha = 255
                    If Images()\alphatest And ImageDepth(Images()\img)>31
                        If StartDrawing(ImageOutput(Images()\img))
                            DrawingMode(#PB_2DDrawing_AlphaChannel)
                            alpha = Alpha(Point(x-Images()\x,y-Images()\y)) ; get alpha
                            StopDrawing()
                        EndIf
                    EndIf
                    If alpha
                        MoveElement(Images(), #PB_List_Last)
                        isCurrentItem = #True
                        currentItemXOffset = x - Images()\x
                        currentItemYOffset = y - Images()\y
                        Break
                    EndIf
                EndIf
            EndIf
        Until PreviousElement(Images()) = 0
    EndIf
   
    ProcedureReturn isCurrentItem
EndProcedure


AddImage(Images(),"PureBasic.bmp",  10, 10, LoadImage(#PB_Any, #PB_Compiler_Home + "/examples/sources/Data/PureBasic.bmp"))
AddImage(Images(),"AlphaChannel.bmp", 100,100, LoadImage(#PB_Any, #PB_Compiler_Home + "/examples/sources/Data/AlphaChannel.bmp"))
AddImage(Images(),"Geebee2.bmp",  50,200, LoadImage(#PB_Any, #PB_Compiler_Home + "/examples/sources/Data/Geebee2.bmp"))

hole = CreateImage(#PB_Any,100,100,32)
If StartDrawing(ImageOutput(hole))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Box(0,0,100,100,RGBA($00,$00,$00,$00))
    Circle(50,50,48,RGBA($00,$FF,$FF,$FF))
    Circle(50,50,30,RGBA($00,$00,$00,$00))
    StopDrawing()
EndIf
AddImage(Images(),"Loch",170,70,hole,1)

If OpenWindow(0, 0, 0, 420, 420, "Move/Drag Canvas Image", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) = 0
    MessageRequester("Fatal error", "Program terminated.")
    End
EndIf

CanvasGadget(#MyCanvas, 10, 10, 400, 400)
DrawCanvas(#MyCanvas, Images())

CreatePopupMenu(#ImagePopup)
MenuItem(#RemoveImage,"Remove")
MenuItem(#ChangeImage,"Change")

Repeat
    Event = WaitWindowEvent()
   
    If Event = #PB_Event_Gadget And EventGadget() = #MyCanvas
        Select EventType()
            Case #PB_EventType_LeftButtonDown
                x = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseX)
                y = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseY)
                isCurrentItem = HitTest(Images(), x, y)
                If isCurrentItem
                    DrawCanvas(#MyCanvas, Images())
                EndIf
                Drag = #True
            Case #PB_EventType_LeftButtonUp
                Drag = #False
            Case #PB_EventType_MouseMove
                If Drag = #True
                    If isCurrentItem
                        x = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseX)
                        y = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseY)
                        If LastElement(Images())
                            Images()\x = x - currentItemXOffset
                            Images()\y = y - currentItemYOffset
                            DrawCanvas(#MyCanvas, Images())
                        EndIf
                    EndIf
                EndIf
            Case #PB_EventType_RightButtonUp
                x = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseX)
                y = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseY)
                isCurrentItem = HitTest(Images(), x, y)
                If isCurrentItem
                    DrawCanvas(#MyCanvas, Images())
                    DisplayPopupMenu(10,WindowID(0))
                EndIf
        EndSelect
    ElseIf Event = #PB_Event_Menu
        Select EventMenu()
            Case #RemoveImage
              If LastElement(Images())                
                    DeleteElement(Images())
                    DrawCanvas(#MyCanvas, Images())
                EndIf
           Case #ChangeImage
              If LastElement(Images())                
                
                images()\height = 50
                images()\width = 50
                
                   DrawCanvas(#MyCanvas, Images())
                EndIf
        EndSelect
    EndIf   
Until Event = #PB_Event_CloseWindow
Weiterhin würde ich gerne wissen, wie man ein Element in den Vordergrund bringt ohne es mit der Maus zu markieren.
Also wenn ich ein beliebiges Element aus der Liste Images() im Vordergrund zeichnen möchte!

EDIT: ist erledigt!
Satellite A210-19Z, Samsung N130, VPAD10, WinXP, Win7, PuppyLinux, PB 5.24, 5.31. 5.70
Elektronik, Mikrocontroller, CNC-Technik, 3D-Druck
Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: CanvasGadget

Beitrag von Regenduft »

Du könntest vielleicht die HitTest()-Prozedur aufbohren und das kleine 6*6-Image (dessen sonstiger Sinn mir sich gerade nicht offenbart) als Griffpunkt zur Größenveränderung nutzen.
Habe gerade keine Zeit für einen ordentlichen Code, aber um die Idee zu verdeutlichen:

Code: Alles auswählen

Procedure.i HitTest (List Images.canvasitem(), x, y)
    ; ...
    
    If LastElement(Images()) ; search for hit, starting from end (z-order)
        Repeat
            If x >= Images()\x And x < Images()\x + Images()\width
                ; ...
                isCurrentItem = #HIT_Image
                ; ...
            ElseIf x >= Images()\x + Images()\width And x < Images()\x + Images()\width + 6
                If y >= Images()\y + Images()\height And y < Images()\y + Images()\height + 6
                    ; ...
                    isCurrentItem = #HIT_Resize
                    ; ...
                EndIf
            EndIf
        Until PreviousElement(Images()) = 0
    EndIf
   
    ProcedureReturn isCurrentItem
EndProcedure
Alternativ gäbe es noch #PB_EventType_MouseWheel...

Nebenbei: Schöner Code! :allright:

EDIT: Wer lesen kann ist klar im Vorteil... Du hast ja geschrieben, dass Du das 6*6 Image extra dafür eingebaut hast... :oops:
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: CanvasGadget

Beitrag von NicTheQuick »

Hier mal mein Lösungsvorschlag.

Code: Alles auswählen

EnableExplicit

Structure canvasitem
	img.i
	x.i
	y.i
	width.i
	height.i
	alphatest.i
	name.s
EndStructure

Enumeration
	#MyCanvas = 1   ; just to test whether a number different from 0 works now
EndEnumeration

Enumeration 10
	#ImagePopup
EndEnumeration

Enumeration 10
	#RemoveImage
	#ChangeImage
EndEnumeration

Define isCurrentItem=#False
Define currentItemXOffset.i, currentItemYOffset.i
Define Event.i, x.i, y.i, drag.i, hole.i
NewList Images.canvasitem()


Procedure AddImage (List Images.canvasitem(), name.s, x, y, img, alphatest=0)
	If AddElement(Images())
		Images()\img    = img
		Images()\x      = x
		Images()\y      = y
		Images()\width  = ImageWidth(img)
		Images()\height = ImageHeight(img)
		Images()\alphatest = alphatest
		images()\name = name.s
	EndIf
EndProcedure

Procedure DrawCanvas (canvas.i, List Images.canvasitem())
	If StartDrawing(CanvasOutput(canvas))
		Box(0, 0, GadgetWidth(canvas), GadgetHeight(canvas), RGB(255,255,255))
		DrawingMode(#PB_2DDrawing_AlphaBlend)
		ForEach Images()
			DrawImage(ImageID(Images()\img),Images()\x,Images()\y,images()\width,images()\height) ; draw all images with z-order
			DrawImage(ImageID(Images()\img),(Images()\x)+images()\width,(Images()\y)+images()\height,6,6)
		Next
		StopDrawing()
	EndIf
EndProcedure

Procedure.i HitTest (List Images.canvasitem(), x, y, *sizing.Integer = 0)
	Shared currentItemXOffset.i, currentItemYOffset.i
	Protected alpha.i, isCurrentItem.i = #False
	If (*sizing)
		*sizing\i = #False
	EndIf
	
	If LastElement(Images()) ; search for hit, starting from end (z-order)
		Repeat
			If (*sizing)
				If x >= Images()\x + images()\width And x < Images()\x + Images()\width + 6 And y >= Images()\y + Images()\height And y < Images()\y + Images()\height + 6
					*sizing\i = #True
					MoveElement(Images(), #PB_List_Last)
					isCurrentItem = #True
					currentItemXOffset = x - Images()\x - Images()\width
					currentItemYOffset = y - Images()\y - Images()\height
				EndIf
			EndIf
			If x >= Images()\x And x < Images()\x + Images()\width
				If y >= Images()\y And y < Images()\y + Images()\height
					alpha = 255
					If Images()\alphatest And ImageDepth(Images()\img)>31
						If StartDrawing(ImageOutput(Images()\img))
							DrawingMode(#PB_2DDrawing_AlphaChannel)
							alpha = Alpha(Point(x-Images()\x,y-Images()\y)) ; get alpha
							StopDrawing()
						EndIf
					EndIf
					If alpha
						MoveElement(Images(), #PB_List_Last)
						isCurrentItem = #True
						currentItemXOffset = x - Images()\x
						currentItemYOffset = y - Images()\y
						Break
					EndIf
				EndIf
			EndIf
		Until PreviousElement(Images()) = 0
	EndIf
	
	ProcedureReturn isCurrentItem
EndProcedure


AddImage(Images(),"PureBasic.bmp",  10, 10, LoadImage(#PB_Any, #PB_Compiler_Home + "/examples/sources/Data/PureBasic.bmp"))
AddImage(Images(),"AlphaChannel.bmp", 100,100, LoadImage(#PB_Any, #PB_Compiler_Home + "/examples/sources/Data/AlphaChannel.bmp"))
AddImage(Images(),"Geebee2.bmp",  50,200, LoadImage(#PB_Any, #PB_Compiler_Home + "/examples/sources/Data/Geebee2.bmp"))

hole = CreateImage(#PB_Any,100,100,32)
If StartDrawing(ImageOutput(hole))
	DrawingMode(#PB_2DDrawing_AllChannels)
	Box(0,0,100,100,RGBA($00,$00,$00,$00))
	Circle(50,50,48,RGBA($00,$FF,$FF,$FF))
	Circle(50,50,30,RGBA($00,$00,$00,$00))
	StopDrawing()
EndIf
AddImage(Images(),"Loch",170,70,hole,1)

If OpenWindow(0, 0, 0, 420, 420, "Move/Drag Canvas Image", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) = 0
	MessageRequester("Fatal error", "Program terminated.")
	End
EndIf

CanvasGadget(#MyCanvas, 10, 10, 400, 400)
DrawCanvas(#MyCanvas, Images())

CreatePopupMenu(#ImagePopup)
MenuItem(#RemoveImage,"Remove")
MenuItem(#ChangeImage,"Change")

Define sizing = #False

Repeat
	Event = WaitWindowEvent()
	
	If Event = #PB_Event_Gadget And EventGadget() = #MyCanvas
		Select EventType()
			Case #PB_EventType_LeftButtonDown
				x = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseX)
				y = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseY)
				isCurrentItem = HitTest(Images(), x, y, @sizing)
				If isCurrentItem
					DrawCanvas(#MyCanvas, Images())
				EndIf
				Drag = #True
			Case #PB_EventType_LeftButtonUp
				Drag = #False
			Case #PB_EventType_MouseMove
				If Drag = #True
					If isCurrentItem
						x = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseX)
						y = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseY)
						If LastElement(Images())
							If (sizing)
								Images()\width = x - currentItemXOffset - Images()\x
								Images()\height = y - currentItemYOffset - Images()\y
							Else
								Images()\x = x - currentItemXOffset
								Images()\y = y - currentItemYOffset
							EndIf
							DrawCanvas(#MyCanvas, Images())
						EndIf
					EndIf
				EndIf
			Case #PB_EventType_RightButtonUp
				x = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseX)
				y = GetGadgetAttribute(#MyCanvas, #PB_Canvas_MouseY)
				isCurrentItem = HitTest(Images(), x, y)
				If isCurrentItem
					DrawCanvas(#MyCanvas, Images())
					DisplayPopupMenu(10,WindowID(0))
				EndIf
		EndSelect
	ElseIf Event = #PB_Event_Menu
		Select EventMenu()
			Case #RemoveImage
				If LastElement(Images())               
					DeleteElement(Images())
					DrawCanvas(#MyCanvas, Images())
				EndIf
			Case #ChangeImage
				If LastElement(Images())               
					
					images()\height = 50
					images()\width = 50
					
					DrawCanvas(#MyCanvas, Images())
				EndIf
		EndSelect
	EndIf   
Until Event = #PB_Event_CloseWindow 
Ich hab mich mal versucht an deine Variablenkonventionen zu halten. Aber etwas verwirrend sind manche Sachen schon. Dennoch gut geschrieben. :)
Antworten