CanvasGadget

Anfängerfragen zum Programmieren mit PureBasic.
derschutzhund
Beiträge: 328
Registriert: 06.06.2013 20:37
Computerausstattung: Satellite A210-19Z, Samsung Netbook N130, VPAD10

Re: CanvasGadget

Beitrag von derschutzhund »

STARGÅTE hat geschrieben:DrawImage() verlangt als ersten Parameter die ImageID, dass heißt, du musst dort:
DrawImage(ImageID(#Image),50,50,100,100) nutzen
Gut, dann werde ich mal etwas damit experimentieren!
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 »

Hallo Danilo,
Danilo hat geschrieben:Hier ein Code um Bilder im CanvasGadget mit der Mouse zu verschieben.
Neue Bilder einfach mit AddImage() hinzufügen. Getestet auf Win & Mac.
habe deinen Beispielcode in mein Programm eingebaut und es funktioniert nun wie gewünscht!
Super gut!

Jetzt müsste ich noch einzelne Bilder löschen können.
Also mit der Maus auf das Bild gehen und dann mit Rechtsklick löschen oder ein Menü einblenden und dann löschen.

Hast du dafür auch etwas code??
Satellite A210-19Z, Samsung N130, VPAD10, WinXP, Win7, PuppyLinux, PB 5.24, 5.31. 5.70
Elektronik, Mikrocontroller, CNC-Technik, 3D-Druck
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: CanvasGadget

Beitrag von Danilo »

derschutzhund hat geschrieben:Jetzt müsste ich noch einzelne Bilder löschen können.
Also mit der Maus auf das Bild gehen und dann mit Rechtsklick löschen oder ein Menü einblenden und dann löschen.

Hast du dafür auch etwas code??
Mit Menu:

Code: Alles auswählen

EnableExplicit

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

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

Enumeration 10
    #ImagePopup
EndEnumeration

Enumeration 10
    #RemoveImage
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(), 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
    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) ; draw all images with z-order
        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(),  10, 10, LoadImage(#PB_Any, #PB_Compiler_Home + "Examples/Sources/Data/PureBasic.bmp"))
AddImage(Images(), 100,100, LoadImage(#PB_Any, #PB_Compiler_Home + "Examples/Sources/Data/GeeBee2.bmp"))
AddImage(Images(),  50,200, LoadImage(#PB_Any, #PB_Compiler_Home + "Examples/Sources/Data/AlphaChannel.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(),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")

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(#ImagePopup,WindowID(0))
                EndIf
        EndSelect
    ElseIf Event = #PB_Event_Menu
        Select EventMenu()
            Case #RemoveImage
                If LastElement(Images())
                    DeleteElement(Images())
                    DrawCanvas(#MyCanvas, Images())
                EndIf
        EndSelect
    EndIf   
Until Event = #PB_Event_CloseWindow
Wenn Du es direkt mit Rechtsklick löschen möchtest, dann setzt Du an die Stelle von DisplayPopupMenu() den Menü-Code zum löschen.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
derschutzhund
Beiträge: 328
Registriert: 06.06.2013 20:37
Computerausstattung: Satellite A210-19Z, Samsung Netbook N130, VPAD10

Re: CanvasGadget

Beitrag von derschutzhund »

Hallo Danilo,

läuft!! :allright:
Jetzt ist mir noch aufgefallen, dass ich ja Sitzpläne sowohl Din-A4 hoch als auch quer machen möchte.
Dazu muss ich über einen Button die größe der CanvasFläche ändern also Breite und Höhe ändern.
Wie geht das?

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
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 »

Du nutzt z.B. 'ResizeGadget()' zusammen mit der ID des CanvasGadgets und dann änderst du die Größe entsprechend, wenn man z.B. auf einen Button drückt, den du natürlich auch vorher noch erstellen und positionieren musst.
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:Du nutzt z.B. 'ResizeGadget()' zusammen mit der ID des CanvasGadgets und dann änderst du die Größe entsprechend, wenn man z.B. auf einen Button drückt, den du natürlich auch vorher noch erstellen und positionieren musst.
Funktioniert! :allright:

Die Eigenschaften eines Elementes über die Objekteigenschaften anzusprechen und zu ändern wie in Delphi geht wohl nicht?
Es würde dann in etwa so aussehen: Canvas_0.width = 500
Hat man diese Systematik erst mal verstanden hat man sofort Zugriff auf alle Eigenschaften eines jeden Objekts!
Das ist sehr angenehm, weil man nicht verschiedene Befehle benötigt!
Bei PureBasic muss man wohl immer spezielle Befehle kennen?

Das Sitzplanprogrämmchen läuft erst mal und hat eine Größe als .exe von 271KB.
Das ist nur ca. die Hälfte der Größe im Vergleich zu meinem alten Delphiprog.
Und das obwohl ich jetzt sogar noch die pdf-Erzeugung mit eingebaut habe. Unter Delphi habe ich ein html erzeugt.
Jetzt ist es grafisch und damit auch noch viel komfortabler. :mrgreen:

Gibt es einen Befehl die Liste eines ListView Gadgets zu sortieren?
In diesem ListView befinden sich nur Vor- und Zunamen mit Leerzeichen getrennt.
Habe nichts aktuelles zu diesem Thema gefunden.
Vermutlich ist es besser wenn ich erst mal die Namen in eine Liste lade, die dann sortiere und dann erst ins ListView?

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
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 »

derschutzhund hat geschrieben:Bei PureBasic muss man wohl immer spezielle Befehle kennen?
Ja, hier funktioniert das nur mit speziellen Befehlen.
Gibt es einen Befehl die Liste eines ListView Gadgets zu sortieren?
In diesem ListView befinden sich nur Vor- und Zunamen mit Leerzeichen getrennt.
Habe nichts aktuelles zu diesem Thema gefunden.
Vermutlich ist es besser wenn ich erst mal die Namen in eine Liste lade, die dann sortiere und dann erst ins ListView?
Es gibt keinen fertigen Befehl zum Sortieren eines ListViewGadgets, aber deine Idee mit der Liste ist wohl hier die beste. Wenn du deine Liste angelegt hast, kannst du sie mittels 'SortList()' oder 'SortStructuredList()' sortieren. Beispiele dazu findest du wie immer in der Hilfe.
derschutzhund
Beiträge: 328
Registriert: 06.06.2013 20:37
Computerausstattung: Satellite A210-19Z, Samsung Netbook N130, VPAD10

Re: CanvasGadget

Beitrag von derschutzhund »

Habe jetzt mal mein Programm so geändert, dass erst mal alles vor der Ausgabe in das canvas gezeichnet wird.
Da Canvas und die Printfunktion ja fest in PureBasic eingebaut sind sollte damit die Druckausgabe auf jedem Betriebssystem funktionieren.
Jetzt mein kleines Problem: Windows alles toll, Linux geht auch allerdings kann ich da die Druckauflösung nicht ändern.
Es wird bei den Druckerparametern die Druckauflösung nicht angezeigt. Bei anderen Linuxprogrammen wird die Auflösung angezeigt und kann geändert werden. Ich habe den Eindruck, dass die Standardeinstellung 75dpi beträgt und dadurch ist die Druckqualität schlecht.
Daher die Frage, woran kann es liegen das die Druckerauflösung beim PB -Prog. nicht angezeigt wird bei anderen Progs. aber schon.

Noch eine andere Sache würde ich gerne bezüglich canvas wissen.
Gibt es eine Möglichkeit bei konstanter Größe des definierten canvas z.B. 1024 x 768 die Darstellung zu verkleinern?
Also eine Art Zoom der canvasfläche?
Satellite A210-19Z, Samsung N130, VPAD10, WinXP, Win7, PuppyLinux, PB 5.24, 5.31. 5.70
Elektronik, Mikrocontroller, CNC-Technik, 3D-Druck
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Re: CanvasGadget

Beitrag von Bisonte »

derschutzhund hat geschrieben:...
Noch eine andere Sache würde ich gerne bezüglich canvas wissen.
Gibt es eine Möglichkeit bei konstanter Größe des definierten canvas z.B. 1024 x 768 die Darstellung zu verkleinern?
Also eine Art Zoom der canvasfläche?
Das obliegt einzig und allein der Zeichnungroutine...
Ob du da nun ein Bild so gross wie das Canvas reinmalst oder das Bild vorher verkleinerst....
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
derschutzhund
Beiträge: 328
Registriert: 06.06.2013 20:37
Computerausstattung: Satellite A210-19Z, Samsung Netbook N130, VPAD10

Re: CanvasGadget

Beitrag von derschutzhund »

Bisonte hat geschrieben:
derschutzhund hat geschrieben:...
Noch eine andere Sache würde ich gerne bezüglich canvas wissen.
Gibt es eine Möglichkeit bei konstanter Größe des definierten canvas z.B. 1024 x 768 die Darstellung zu verkleinern?
Also eine Art Zoom der canvasfläche?
Das obliegt einzig und allein der Zeichnungroutine...
Ob du da nun ein Bild so gross wie das Canvas reinmalst oder das Bild vorher verkleinerst....
Vielleicht mache ich da auch einen Denkfehler aber:

Die Pixelzahl auf einem A4 -Blatt ergibt sich aus der Auflösung z.B. 300dpi und der
Breite x Höhe
Breite = 210 mm = 8,2 inch = 2460 Pixel bei 300 dpi
Höhe = 297 mm = 11,6 inch = 3480 Pixel bei 300 dpi

Wenn ich es richtig sehe wird mit der folgenden Routine das Canvas als Bild ausgedruckt?

Code: Alles auswählen

Procedure ansichtdrucken(EventType)
  Define link, susname$, BildID.i
  
  BildID.i=GetGadgetAttribute(Canvas_0,#PB_Canvas_Image)
  If PrintRequester()
    If StartPrinting("Sitzplan") ; Hier
      If StartDrawing(PrinterOutput())
        If druckformat$ = "P"     
          DrawImage(BildID,0,0,#druckbreite,#drucklange)
        Else
          DrawImage(BildID,0,0,#drucklange,#druckbreite)
        EndIf
        StopDrawing()
        StopPrinting()
      EndIf
    EndIf
  EndIf
EndProcedure
Wird also ein Canvas mit 2460 x 3480 pixel erzeugt so ist der Ausdruck auf A4 von guter Qualität jedoch kann man das gesamte Canvas nicht auf dem Monitor anzeigen und muss scrollen.
Verkleinert man das Canvas um alles auf einen Blick zu sehen so wird der Ausdruck immer schlechter!

Das ist der Grund warum eine Zoomfunktion für das canvas durchaus sinnvoll ist oder sehe ich das falsch?

Wenn ich es richtig sehe wird bei jedem Ausdruck das Canvas immer auf die Druckgröße gestreckt / gestaucht?
Satellite A210-19Z, Samsung N130, VPAD10, WinXP, Win7, PuppyLinux, PB 5.24, 5.31. 5.70
Elektronik, Mikrocontroller, CNC-Technik, 3D-Druck
Antworten