Mouse snap to line

Just starting out? Need help? Post your questions and find answers here.
wombats
Enthusiast
Enthusiast
Posts: 664
Joined: Thu Dec 29, 2011 5:03 pm

Mouse snap to line

Post by wombats »

Hi,

It's probably ill-advised, but I'm trying to make my own list gadget in which the user can reorder the items, since drag and drop remains broken on macOS and I fear it will never work.

How can I make the mouse follow the line more accurately? It sometimes gets farther away from the mouse.

Code: Select all

EnableExplicit

Declare OnCanvasEvents()
Declare DrawItems()

Global rowH = 30

OpenWindow(0, 0, 0, 250, 300, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CanvasGadget(0, 0, 0, 250, 300)

BindGadgetEvent(0, @OnCanvasEvents(), #PB_All)

DrawItems()

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Procedure OnCanvasEvents()
  Protected mX, mY, y
  mX = GetGadgetAttribute(0, #PB_Canvas_MouseX)
  mY = GetGadgetAttribute(0, #PB_Canvas_MouseY)
  Select EventType()
    Case #PB_EventType_MouseMove
      If GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
        DrawItems()
        If StartDrawing(CanvasOutput(0))
          Box(0, mY / rowH * rowH, OutputWidth(), 2, RGBA(0, 0, 0, 255))
        EndIf
        StopDrawing()
      EndIf
    Case #PB_EventType_LeftButtonDown, #PB_EventType_LeftButtonUp
      DrawItems()
  EndSelect
EndProcedure

Procedure DrawItems()
  Protected i, x, y, txtH
  If StartDrawing(CanvasOutput(0))
    Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 255, 255))
    DrawingMode(#PB_2DDrawing_Transparent)
    txtH = TextHeight("0")
    x = 10
    For i = 0 To 15
      y = i * rowH
      DrawText(x, y + ((rowH - txtH) / 2), "Item " + i, RGB(0, 0,  0))
      y + rowH
    Next
    StopDrawing()
  EndIf
EndProcedure
User avatar
mk-soft
Always Here
Always Here
Posts: 5393
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Mouse snap to line

Post by mk-soft »

Looks good what you did... Mouse is always in the item.

Code: Select all

EnableExplicit

Declare OnCanvasEvents()
Declare DrawItems()

Global rowH = 30

OpenWindow(0, 0, 0, 250, 300, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CanvasGadget(0, 0, 0, 250, 300)

BindGadgetEvent(0, @OnCanvasEvents(), #PB_All)

DrawItems()

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Procedure OnCanvasEvents()
  Protected mX, mY, y
  mX = GetGadgetAttribute(0, #PB_Canvas_MouseX)
  mY = GetGadgetAttribute(0, #PB_Canvas_MouseY)
  Select EventType()
    Case #PB_EventType_MouseMove, #PB_EventType_LeftClick
      If GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton 
        DrawItems()
        If StartDrawing(CanvasOutput(0))
          DrawingMode(#PB_2DDrawing_Outlined)
          Box(0, mY / rowH * rowH, OutputWidth(), rowH, RGBA(0, 0, 0, 255))
        EndIf
        StopDrawing()
      EndIf
    Case #PB_EventType_LeftButtonDown, #PB_EventType_LeftButtonUp
      DrawItems()
  EndSelect
EndProcedure

Procedure DrawItems()
  Protected i, x, y, txtH
  If StartDrawing(CanvasOutput(0))
    Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 255, 255))
    DrawingMode(#PB_2DDrawing_Transparent)
    txtH = TextHeight("0")
    x = 10
    For i = 0 To 15
      y = i * rowH
      DrawText(x, y + ((rowH - txtH) / 2), "Item " + i, RGB(0, 0,  0))
      y + rowH
    Next
    StopDrawing()
  EndIf
EndProcedure
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wombats
Enthusiast
Enthusiast
Posts: 664
Joined: Thu Dec 29, 2011 5:03 pm

Re: Mouse snap to line

Post by wombats »

Thanks. Yes, it's somewhat acceptable, but it would be better if the line were nearer the cursor at all times since it's the indicator of where the user wants to insert the item they're dragging. This video of the layers window in Pixelmator shows essentially what I'm aiming for: https://imgur.com/dzuGHHb.
User avatar
mk-soft
Always Here
Always Here
Posts: 5393
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Mouse snap to line

Post by mk-soft »

I made something once.

There's still a lot to do.

Code: Select all

EnableExplicit

Declare OnCanvasEvents()
Declare DrawItems(Selection = -1)

Global rowH = 30

OpenWindow(0, 0, 0, 250, 300, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CanvasGadget(0, 0, 0, 250, 300)

BindGadgetEvent(0, @OnCanvasEvents(), #PB_All)

DrawItems()

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Procedure OnCanvasEvents()
  Protected mX, mY, sel
  mX = GetGadgetAttribute(0, #PB_Canvas_MouseX)
  mY = GetGadgetAttribute(0, #PB_Canvas_MouseY)
  sel = mY / rowH
  Select EventType()
    Case #PB_EventType_MouseMove
      If GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton 
        DrawItems(sel)
      EndIf
    Case #PB_EventType_LeftButtonDown
      DrawItems(sel)
    Case #PB_EventType_LeftButtonUp
      DrawItems(-1)
  EndSelect
EndProcedure

Procedure DrawItems(Selection = - 1)
  Protected i, x, y, txtH
  If StartDrawing(CanvasOutput(0))
    Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 255, 255))
    DrawingMode(#PB_2DDrawing_Transparent)
    txtH = TextHeight("0")
    x = 10
    For i = 0 To 15
      y = i * rowH
      If i = Selection
        DrawingMode(#PB_2DDrawing_Default)
        Box(0, y, OutputWidth(), rowH, RGBA(128, 128, 255, 255))
        DrawingMode(#PB_2DDrawing_Outlined)
        Box(0, y, OutputWidth(), rowH, RGBA(0, 0, 0, 255))
        DrawingMode(#PB_2DDrawing_Transparent)
      EndIf
      DrawText(x, y + ((rowH - txtH) / 2), "Item " + i, RGB(0, 0,  0))
      y + rowH
    Next
    StopDrawing()
  EndIf
EndProcedure
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
breeze4me
Enthusiast
Enthusiast
Posts: 523
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Mouse snap to line

Post by breeze4me »

The position of the line should be changed depending on whether the mouse pointer is located in the upper half or lower half of an item.

Code: Select all

EnableExplicit

Declare OnCanvasEvents()
Declare DrawItems()

Global rowH = 30

OpenWindow(0, 0, 0, 250, 300, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CanvasGadget(0, 0, 0, 250, 300)

BindGadgetEvent(0, @OnCanvasEvents(), #PB_All)

DrawItems()

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Procedure OnCanvasEvents()
  Protected mX, mY, y
  mX = GetGadgetAttribute(0, #PB_Canvas_MouseX)
  mY = GetGadgetAttribute(0, #PB_Canvas_MouseY)
  Select EventType()
    Case #PB_EventType_MouseMove
      If GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
        DrawItems()
        If StartDrawing(CanvasOutput(0))
          Box(0, Round(mY / rowH, #PB_Round_Nearest) * rowH, OutputWidth(), 2, RGBA(0, 0, 0, 255))
          ;Box(0, mY / rowH * rowH, OutputWidth(), 2, RGBA(0, 0, 0, 255))
        EndIf
        StopDrawing()
      EndIf
    Case #PB_EventType_LeftButtonDown, #PB_EventType_LeftButtonUp
      DrawItems()
  EndSelect
EndProcedure

Procedure DrawItems()
  Protected i, x, y, txtH
  If StartDrawing(CanvasOutput(0))
    Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 255, 255))
    DrawingMode(#PB_2DDrawing_Transparent)
    txtH = TextHeight("0")
    x = 10
    For i = 0 To 15
      y = i * rowH
      DrawText(x, y + ((rowH - txtH) / 2), "Item " + i, RGB(0, 0,  0))
      y + rowH
    Next
    StopDrawing()
  EndIf
EndProcedure
wombats
Enthusiast
Enthusiast
Posts: 664
Joined: Thu Dec 29, 2011 5:03 pm

Re: Mouse snap to line

Post by wombats »

breeze4me wrote:The position of the line should be changed depending on whether the mouse pointer is located in the upper half or lower half of an item.
Excellent. Thank you!
Post Reply