[OK] Select elements on vectorcanvas

Just starting out? Need help? Post your questions and find answers here.
User avatar
[blendman]
Enthusiast
Enthusiast
Posts: 297
Joined: Thu Apr 07, 2011 1:14 pm
Location: 3 arks
Contact:

[OK] Select elements on vectorcanvas

Post by [blendman] »

Hi

I try to select some elements on a vector canvas, but I don't understand why I can't select the red circle :

Code: Select all


Structure sShape
  name$
  selected.a
  color.i
  x.w
  y.w
  w.w
  h.w
  alpha.a
EndStructure
Global Dim shape.sshape(0), NbShape =-1

Procedure Shape_Add(x,y,w,h,color.i)
  NbShape +1
  i = nbShape
  ReDim shape.sShape(i)
  With shape(i)
    \name$ = "Shape"+Str(i)
    \alpha = 255
    \color=color
    \x=x
    \y=y
    \w=w
    \h=h
  EndWith
EndProcedure
#G_canvasVector = 0

Procedure CanvasDraw(update = 0) 
  HoveredElement = #Null
  Static Clic, shift
  
  x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
  y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
  
  If EventType() = #PB_EventType_KeyDown          
    If GetGadgetAttribute(#G_canvasVector, #PB_Canvas_Modifiers) & #PB_Canvas_Shift                            
      Shift = 1                          
    EndIf  
  ElseIf EventType() = #PB_EventType_KeyUp 
    If Not GetGadgetAttribute(#G_canvasVector, #PB_Canvas_Modifiers) & #PB_Canvas_Shift                            
      Shift = 0                        
    EndIf 
  EndIf 
  
  If EventType() = #PB_EventType_LeftButtonDown 
    Clic = 1
  ElseIf EventType() = #PB_EventType_LeftButtonUp
    clic = 0
  EndIf
  
  If EventType() = #PB_EventType_LeftButtonDown Or EventType() = #PB_EventType_LeftButtonUp Or update= 1
    If StartVectorDrawing(CanvasVectorOutput(0))
      
      SelectedShape = -1
      ; for selection
      For i=ArraySize(shape()) To 0 Step-1
        With shape(i)
          AddPathEllipse(\x, \y, \w, \h) 
          If clic=1  
            clic=0
            If IsInsidePath(x, y) 
              \selected= 1
              SelectedShape = i
              Break
            Else
              If shift = 0
                \selected= 0
              EndIf
            EndIf
          EndIf
        EndWith
      Next
      
      
      If EventType() = #PB_EventType_LeftButtonDown Or update=1
        ; TO erase the Background
        AddPathBox(0,0,GadgetWidth(0),GadgetHeight(0))
        VectorSourceColor(RGBA(200,200,200, 255))  
        FillVectorOutput() 
        AddPathBox(0,0,GadgetWidth(0),GadgetHeight(0))
        VectorSourceColor(RGBA(200,200,200, 255))  
        FillPath()
        
        
        For i=0 To ArraySize(shape())
          With shape(i)
            AddPathEllipse(\x, \y, \w, \h) 
;             If SelectedShape  = i
;               Debug \name$
;             EndIf
            If \selected 
              \alpha = 120
               Debug \name$
            Else
              \alpha = 255
            EndIf
            VectorSourceColor(RGBA(Red(\color),Green(\color),Blue(\color),\alpha))
            FillPath()  
          EndWith
        Next
      EndIf
      StopVectorDrawing()
    EndIf      
  EndIf      
EndProcedure

w = 800
h = 600
If OpenWindow(0, 0, 0, w, h, "IsInsidePath", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, w, h, #PB_Canvas_Keyboard)
  Shape_Add(200,200,400,300,RGBA(120,0,0,255))
  Shape_Add(200,200,200,100,RGBA(0,0,120,255))
  CanvasDraw(1)
  
  Repeat
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget And EventGadget() = 0 ;And EventType() = #PB_EventType_MouseMove
      CanvasDraw()
    EndIf
    
  Until Event = #PB_Event_CloseWindow
EndIf

Thank you :)
Last edited by [blendman] on Sun Jul 18, 2021 4:09 pm, edited 1 time in total.
User avatar
STARGÅTE
Addict
Addict
Posts: 2090
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Select elements on vectorcanvas

Post by STARGÅTE »

First, you have to reset the path after each element in the selection loop.
Second, you can't set clic=0 event if there was no inside path.

Code: Select all

      For i=ArraySize(shape()) To 0 Step-1
        With shape(i)
          AddPathEllipse(\x, \y, \w, \h) 
          If clic=1  
            If IsInsidePath(x, y) 
            	clic=0
              \selected= 1
              SelectedShape = i
              Break
            Else
              If shift = 0
                \selected= 0
              EndIf
            EndIf
          EndIf
          ResetPath()
        EndWith
      Next
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
User avatar
[blendman]
Enthusiast
Enthusiast
Posts: 297
Joined: Thu Apr 07, 2011 1:14 pm
Location: 3 arks
Contact:

Re: Select elements on vectorcanvas

Post by [blendman] »

HI

Thank you very much

it's almost that, bu if we select the red circle Then the blue circle (without shift =1), the two circles are selected (like we can do with shift =1).
But, we should have only the blue circle selected.

Do you know how to fixe that ?

thanks again ;)

Edit :
HI, I think I have found a solution, we don't need resetpath(), and we don't have to use break, because we have to continue to check if all element in the array can be selected or not (if another is still selected and shift = 0= :

Code: Select all


Structure sShape
  name$
  selected.a
  color.i
  x.w
  y.w
  w.w
  h.w
  alpha.a
EndStructure
Global Dim shape.sshape(0), NbShape =-1

Procedure Shape_Add(x,y,w,h,color.i)
  NbShape +1
  i = nbShape
  ReDim shape.sShape(i)
  With shape(i)
    \name$ = "Shape"+Str(i)
    \alpha = 255
    \color=color
    \x=x
    \y=y
    \w=w
    \h=h
  EndWith
EndProcedure
#G_canvasVector = 0

Procedure CanvasDraw(update = 0) 
  
  Static Clic, shift
  
  x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
  y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
  
  If EventType() = #PB_EventType_KeyDown          
    If GetGadgetAttribute(#G_canvasVector, #PB_Canvas_Modifiers) & #PB_Canvas_Shift                            
      Shift = 1                          
    EndIf  
  ElseIf EventType() = #PB_EventType_KeyUp 
    If Not GetGadgetAttribute(#G_canvasVector, #PB_Canvas_Modifiers) & #PB_Canvas_Shift                            
      Shift = 0                        
    EndIf 
  EndIf 
  
  If EventType() = #PB_EventType_LeftButtonDown 
    Clic = 1
  ElseIf EventType() = #PB_EventType_LeftButtonUp
    clic = 0
  EndIf
  
  
  If StartVectorDrawing(CanvasVectorOutput(0))
    
    If EventType() = #PB_EventType_LeftButtonDown ; Or EventType() = #PB_EventType_LeftButtonUp Or update= 1
      
      ; for selection
      For i=ArraySize(shape()) To 0 Step-1
        With shape(i)
          AddPathEllipse(\x, \y, \w, \h) 
          If shift = 0
            \selected= 0
          EndIf
          If clic=1  
            If IsInsidePath(x, y) 
              clic=0
              \selected= 1
              SelectedShape = i
            EndIf
          EndIf
        EndWith
      Next
    EndIf   
    
    If EventType() = #PB_EventType_LeftButtonDown Or update=1 Or EventType() = #PB_EventType_LeftButtonUp 
      ; TO erase the Background
      AddPathBox(0,0,GadgetWidth(0),GadgetHeight(0))
      VectorSourceColor(RGBA(200,200,200, 255))  
      FillVectorOutput() 
      AddPathBox(0,0,GadgetWidth(0),GadgetHeight(0))
      VectorSourceColor(RGBA(200,200,200, 255))  
      FillPath()
      
      For i=0 To ArraySize(shape())
        With shape(i)
          AddPathEllipse(\x, \y, \w, \h) 
          VectorSourceColor(RGBA(Red(\color),Green(\color),Blue(\color),\alpha))
          FillPath() 
          ; show selection
          If \selected 
            AddPathEllipse(\x, \y, \w, \h) 
            VectorSourceColor(RGBA(0,0,0,255))
            DashPath(1,5)  
          EndIf
        EndWith
      Next
      
    EndIf
    
    StopVectorDrawing()
    
  EndIf      
EndProcedure

w = 800
h = 600
If OpenWindow(0, 0, 0, w, h, "IsInsidePath", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, w, h, #PB_Canvas_Keyboard)
  Shape_Add(200,200,400,300,RGBA(200,100,100,255))
  Shape_Add(200,200,200,100,RGBA(100,100,200,255))
  
  For i=0 To 3
      Shape_Add(200+Random(200),200+Random(200),100,100,RGBA(Random(255),Random(255),Random(255),255))

  Next
  
  CanvasDraw(1)
  
  Repeat
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget And EventGadget() = 0 ;And EventType() = #PB_EventType_MouseMove
      CanvasDraw()
    EndIf
    
  Until Event = #PB_Event_CloseWindow
EndIf

User avatar
STARGÅTE
Addict
Addict
Posts: 2090
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Select elements on vectorcanvas

Post by STARGÅTE »

[blendman] wrote: Sun Jul 18, 2021 12:29 pmHI, I think I have found a solution, we don't need resetpath(),
In your case it is indeed not a must have. But if you do not use ResetPath, each AddPathEllipse() add an additional part into the path.
In the drawing section FillPath() resets the path automatically. This is not the case for IsInsidePath().
Further, all ellipse paths are still in the buffer when you go into the If EventType() = #PB_EventType_LeftButtonDown section.
There is no visible problem at the moment, but I just want inform you.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
User avatar
[blendman]
Enthusiast
Enthusiast
Posts: 297
Joined: Thu Apr 07, 2011 1:14 pm
Location: 3 arks
Contact:

Re: [OK] Select elements on vectorcanvas

Post by [blendman] »

In your case it is indeed not a must have. But if you do not use ResetPath, each AddPathEllipse() add an additional part into the path.
In the drawing section FillPath() resets the path automatically. This is not the case for IsInsidePath().
Further, all ellipse paths are still in the buffer when you go into the If EventType() = #PB_EventType_LeftButtonDown section.
There is no visible problem at the moment, but I just want inform you.
oh, thank you a lot for this information
I will add resetpath() for the path when I use IsInsidePath().

If I understand, it's better to have a good framerate for the application ?

Thank you a lot again.
User avatar
STARGÅTE
Addict
Addict
Posts: 2090
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: [OK] Select elements on vectorcanvas

Post by STARGÅTE »

[blendman] wrote: Sun Jul 18, 2021 5:53 pm If I understand, it's better to have a good framerate for the application ?
If you have more elements it could be relevant. Nevertheless, I would rather call it "good programing style".
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Post Reply