PureBasic Forum
http://forums.purebasic.com/english/

Resizing shapes problem
http://forums.purebasic.com/english/viewtopic.php?f=13&t=73054
Page 1 of 1

Author:  wombats [ Thu Jun 20, 2019 7:53 am ]
Post subject:  Resizing shapes problem

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:
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.

Author:  Mijikai [ Thu Jun 20, 2019 8:19 am ]
Post subject:  Re: Resizing shapes problem

Try this :)
Code:
        If newH > 0;<- remove this   

Author:  Demivec [ Thu Jun 20, 2019 8:22 am ]
Post subject:  Re: Resizing shapes problem

This is untested but I think I found a problem in OnCanvasEvents():
Code:
  newY = *b\y : newH = *b\h
        newY + offset\y
        newH - offset\y ;should be using offset\x

Author:  wombats [ Thu Jun 20, 2019 8:28 am ]
Post subject:  Re: Resizing shapes problem

Thanks for the replies.
Mijikai wrote:
Try this :)
Code:
        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:
  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.

Author:  Mijikai [ Thu Jun 20, 2019 8:49 am ]
Post subject:  Re: Resizing shapes problem

Maybe:
Code:
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

Author:  wombats [ Thu Jun 20, 2019 8:53 am ]
Post subject:  Re: Resizing shapes problem

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.

Author:  Mijikai [ Thu Jun 20, 2019 9:03 am ]
Post subject:  Re: Resizing shapes problem

Just do this:
Code:
        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

Author:  RASHAD [ Thu Jun 20, 2019 9:09 am ]
Post subject:  Re: Resizing shapes problem

Hi
I hope I got you correctly
You can change the small white box to a box with the width of the rectangle
Code:
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

Author:  wombats [ Thu Jun 20, 2019 9:22 am ]
Post subject:  Re: Resizing shapes problem

Mijikai wrote:
Just do this:
Code:
        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

Author:  #NULL [ Thu Jun 20, 2019 9:33 am ]
Post subject:  Re: Resizing shapes problem

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.

Author:  RASHAD [ Thu Jun 20, 2019 9:33 am ]
Post subject:  Re: Resizing shapes problem

I think I made a small change while you was checking
No resize if the cursor not aligned Val & Hal to the small box

Author:  Mijikai [ Thu Jun 20, 2019 9:54 am ]
Post subject:  Re: Resizing shapes problem

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.

Author:  wombats [ Thu Jun 20, 2019 10:16 am ]
Post subject:  Re: Resizing shapes problem

I managed to get the behaviour I want by following #NULL's advice.

Thanks to you all.

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/