Page 1 of 1

Resizing shapes problem

Posted: Thu Jun 20, 2019 7:53 am
by wombats
Hi,

I'm having trouble with limiting resizing shapes to positive sizes only. In the example, it stops the shape from being resized to 0 height or below. However, when the height reaches 1, the mouse cursor loses track of the sizing handle. Does anyone know how I can make sure the mouse stays aligned with the sizing handle?

Code: Select all

EnableExplicit

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
  Structure Point : x.i : y.i : EndStructure
CompilerEndIf

Structure Box
  x.i : y.i
  w.i : h.i
  handle.Point
EndStructure

Global currentPoint.Point, lastPoint.Point, resize

Global *b.Box = AllocateStructure(Box)
With *b
  \x = 200 : \y = 150
  \w = 100 : \h = 125
  \handle\x = \x + (\w / 2)
  \handle\y = \y - 3
EndWith

Procedure DrawCanvas()
  If StartDrawing(CanvasOutput(0))
    Box(0, 0, OutputWidth(), OutputHeight(), RGB(0, 0, 0))
    Box(*b\x, *b\y, *b\w, *b\h, RGB(0, 0, 255))
    Box(*b\handle\x, *b\handle\y, 3, 3, RGB(255, 255, 255))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(50, 50, "Height: " + Str(*b\h), RGB(255, 255, 255))
    StopDrawing()
  EndIf
EndProcedure

Procedure OnCanvasEvents()
  Protected offset.Point, newY, newH
  Select EventType()
    Case #PB_EventType_MouseMove
      currentPoint\x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
      currentPoint\y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
      If resize & GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
        offset\y = currentPoint\y - lastPoint\y
        newY = *b\y : newH = *b\h
        newY + offset\y
        newH - offset\y
        If newH > 0
          *b\y = newY
          *b\h = newH
          *b\handle\y = *b\y - 3
        EndIf
        DrawCanvas()
      Else
        If currentPoint\x => *b\handle\x And currentPoint\x < *b\handle\x + 3 And
           currentPoint\y => *b\handle\y And currentPoint\y < *b\handle\y + 3
          resize = 1
          SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
        Else
          SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_Default)
        EndIf
      EndIf
      lastPoint\x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
      lastPoint\y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
    Case #PB_EventType_LeftButtonUp
      resize = 0
      SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_Default)
    Case #PB_EventType_KeyDown
      Select GetGadgetAttribute(0, #PB_Canvas_Key)
        Case #PB_Shortcut_Escape : End
      EndSelect
      DrawCanvas()
  EndSelect
EndProcedure

If OpenWindow(0, 0, 0, 640, 480, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, 640, 480, #PB_Canvas_Keyboard)
  BindGadgetEvent(0, @OnCanvasEvents(), #PB_All)
  DrawCanvas()
  SetActiveGadget(0)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Thank you.

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 8:19 am
by Mijikai
Try this :)

Code: Select all

        If newH > 0;<- remove this   

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 8:22 am
by Demivec
This is untested but I think I found a problem in OnCanvasEvents():

Code: Select all

  newY = *b\y : newH = *b\h
        newY + offset\y
        newH - offset\y ;should be using offset\x

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 8:28 am
by wombats
Thanks for the replies.
Mijikai wrote:Try this :)

Code: Select all

        If newH <> 0;<- change this
          *b\y = newY
          *b\h = newH
          *b\handle\y = *b\y - 3
        EndIf
I can't use this as I don't want the shape to be resized to negative sizes.
Demivec wrote:This is untested but I think I found a problem in OnCanvasEvents():

Code: Select all

  newY = *b\y : newH = *b\h
        newY + offset\y
        newH - offset\y ;should be using offset\x
I don't make use of offset\x in the example because that would be for sizing handles working on the width.

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 8:49 am
by Mijikai
Maybe:

Code: Select all

EnableExplicit

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
  Structure Point : x.i : y.i : EndStructure
CompilerEndIf

Structure Box
  x.i : y.i
  w.i : h.i
  handle.Point
  yy.i
EndStructure

Global currentPoint.Point, lastPoint.Point, resize

Global *b.Box = AllocateStructure(Box)
With *b
  \x = 200 : \y = 150
  \w = 100 : \h = 125
  \handle\x = \x + (\w / 2)
  \handle\y = \y - 3
EndWith

Procedure DrawCanvas()
  If StartDrawing(CanvasOutput(0))
    Box(0, 0, OutputWidth(), OutputHeight(), RGB(0, 0, 0))
    Box(*b\x, *b\y, *b\w, *b\h, RGB(0, 0, 255))
    Box(*b\handle\x, *b\handle\y, 3, 3, RGB(255, 255, 255))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(50, 50, "Height: " + Str(*b\h), RGB(255, 255, 255))
    StopDrawing()
  EndIf
EndProcedure

Procedure OnCanvasEvents()
  Protected offset.Point, newY, newH
  Select EventType()
    Case #PB_EventType_MouseMove
      currentPoint\x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
      currentPoint\y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
      If resize & GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
        offset\y = currentPoint\y - lastPoint\y
        newY = *b\y : newH = *b\h
        newY + offset\y
        newH - offset\y
        
        If newH < 0
          ;newH = 0;<- dont go smaller than 0
          If Not *b\yy
            *b\yy = *b\y
          EndIf 
        EndIf 
        
        *b\y = newY
        *b\h = newH 
        *b\handle\y = *b\y - 3
          
          
          

        
        DrawCanvas()
      Else
        If currentPoint\x => *b\handle\x And currentPoint\x < *b\handle\x + 3 And
           currentPoint\y => *b\handle\y And currentPoint\y < *b\handle\y + 3
          resize = 1
          SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
        Else
          SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_Default)
        EndIf
      EndIf
      lastPoint\x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
      lastPoint\y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
    Case #PB_EventType_LeftButtonUp
      resize = 0
      If *b\yy
        *b\handle\y = *b\yy - 3
        *b\y = *b\yy 
        *b\h * - 1
        *b\yy = 0
      EndIf 
      DrawCanvas()
      SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_Default)
    Case #PB_EventType_KeyDown
      Select GetGadgetAttribute(0, #PB_Canvas_Key)
        Case #PB_Shortcut_Escape : End
      EndSelect
      DrawCanvas()
  EndSelect
EndProcedure

If OpenWindow(0, 0, 0, 640, 480, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, 640, 480, #PB_Canvas_Keyboard)
  BindGadgetEvent(0, @OnCanvasEvents(), #PB_All)
  DrawCanvas()
  SetActiveGadget(0)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 8:53 am
by wombats
That still allows the shape to be resized to a negative height.

I'm trying to create similar behaviour to the Form editor in the IDE - it doesn't let you resize gadgets to less than 10x10.

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 9:03 am
by Mijikai
Just do this:

Code: Select all

        If newH > 9;if size > 9 change it
          *b\y = newY
          *b\h = newH 
          *b\handle\y = *b\y - 3
        Else
          PostEvent(#PB_Event_Gadget,EventWindow(),EventGadget(),#PB_EventType_LeftButtonUp);we are done!
        EndIf

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 9:09 am
by RASHAD
Hi
I hope I got you correctly
You can change the small white box to a box with the width of the rectangle

Code: Select all

EnableExplicit

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
  Structure Point : x.i : y.i : EndStructure
CompilerEndIf

Structure Box
  x.i : y.i
  w.i : h.i
  handle.Point
EndStructure

Global currentPoint.Point, lastPoint.Point, resize

Global *b.Box = AllocateStructure(Box)
With *b
  \x = 200 : \y = 150
  \w = 100 : \h = 125
  \handle\x = \x + (\w / 2)
  \handle\y = \y - 3
EndWith

Procedure DrawCanvas()
  If StartDrawing(CanvasOutput(0))
    Box(0, 0, OutputWidth(), OutputHeight(), RGB(0, 0, 0))
    Box(*b\x, *b\y, *b\w, *b\h, RGB(0, 0, 255))
    Box(*b\x, *b\handle\y+2,*b\w, 2, RGB(0, 0, 255))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(50, 50, "Height: " + Str(*b\h), RGB(255, 255, 255))
    StopDrawing()
  EndIf
  If currentPoint\x => *b\x And currentPoint\x < (*b\x+*b\w) And currentPoint\y => *b\handle\y And currentPoint\y < *b\handle\y + 3
    resize = 1
    SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
  Else
    resize = 0
    SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_Default)
  EndIf
EndProcedure

Procedure OnCanvasEvents()
  Protected offset.Point, newY, newH
  Select EventType()
    Case #PB_EventType_MouseMove
      currentPoint\x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
      currentPoint\y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
      If resize & GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
        offset\y = currentPoint\y - lastPoint\y
        newY = *b\y : newH = *b\h
        newY + offset\y
        newH - offset\y
        If newH > 0
          *b\y = newY
          *b\h = newH
          *b\handle\y = *b\y - 3
        EndIf
;         DrawCanvas()
      ;Else
;         If currentPoint\x => *b\handle\x And currentPoint\x < *b\handle\x + 3 And
;            currentPoint\y => *b\handle\y And currentPoint\y < *b\handle\y + 3
;           resize = 1
;           SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
;         Else
;           SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_Default)
;         EndIf
      EndIf
      DrawCanvas()
      lastPoint\x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
      lastPoint\y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
    Case #PB_EventType_LeftButtonUp
      resize = 0
      SetGadgetAttribute(0, #PB_Canvas_Cursor, #PB_Cursor_Default)
    Case #PB_EventType_KeyDown
      Select GetGadgetAttribute(0, #PB_Canvas_Key)
        Case #PB_Shortcut_Escape : End
      EndSelect
      DrawCanvas()
  EndSelect
EndProcedure

If OpenWindow(0, 0, 0, 640, 480, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, 640, 480, #PB_Canvas_Keyboard )
  BindGadgetEvent(0, @OnCanvasEvents(), #PB_All)
  DrawCanvas()
  SetActiveGadget(0)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 9:22 am
by wombats
Mijikai wrote:Just do this:

Code: Select all

        If newH > 9;if size > 9 change it
          *b\y = newY
          *b\h = newH 
          *b\handle\y = *b\y - 3
        Else
          PostEvent(#PB_Event_Gadget,EventWindow(),EventGadget(),#PB_EventType_LeftButtonUp);we are done!
        EndIf
Well, that works, but it's not the exact behaviour I'm looking for.
RASHAD wrote:Hi
I hope I got you correctly
You can change the small white box to a box with the width of the rectangle
Hi RASHAD. Do you mean horizontally? I don't mind the mouse cursor not being aligned horizontally as that is normal behaviour in every app. It's when it loses track of it vertically that is the problem.

Image

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 9:33 am
by #NULL
If your resizing starts with a click, store the current mouse position and the current box size. Then during the resizing get the difference from the start mouse position to the current mouse position and add/substract it to the stored box size. If valid, apply it to the actual box, but keep the stored box size as long as the resizing is still in progress.

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 9:33 am
by RASHAD
I think I made a small change while you was checking
No resize if the cursor not aligned Val & Hal to the small box

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 9:54 am
by Mijikai
This can only be fixed by an additional offsets for the mouse as long as the mouse is drawn by the system this wont work.

I tried to avoid that (second example) by pushing all negatives into the positive space
it will go beyond zero but the resulting rectangle will be corrected.

In my last snipped i just ended the process once the desired size is reached to avoid those problems.

Re: Resizing shapes problem

Posted: Thu Jun 20, 2019 10:16 am
by wombats
I managed to get the behaviour I want by following #NULL's advice.

Thanks to you all.