Resizing shapes problem

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

Resizing shapes problem

Post 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.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Resizing shapes problem

Post by Mijikai »

Try this :)

Code: Select all

        If newH > 0;<- remove this   
Last edited by Mijikai on Thu Jun 20, 2019 8:25 am, edited 1 time in total.
User avatar
Demivec
Addict
Addict
Posts: 4085
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Resizing shapes problem

Post 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
wombats
Enthusiast
Enthusiast
Posts: 663
Joined: Thu Dec 29, 2011 5:03 pm

Re: Resizing shapes problem

Post 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.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Resizing shapes problem

Post 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
wombats
Enthusiast
Enthusiast
Posts: 663
Joined: Thu Dec 29, 2011 5:03 pm

Re: Resizing shapes problem

Post 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.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Resizing shapes problem

Post 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
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4635
Joined: Sun Apr 12, 2009 6:27 am

Re: Resizing shapes problem

Post 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
Last edited by RASHAD on Thu Jun 20, 2019 10:48 am, edited 1 time in total.
Egypt my love
wombats
Enthusiast
Enthusiast
Posts: 663
Joined: Thu Dec 29, 2011 5:03 pm

Re: Resizing shapes problem

Post 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
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Resizing shapes problem

Post 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.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4635
Joined: Sun Apr 12, 2009 6:27 am

Re: Resizing shapes problem

Post 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
Egypt my love
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Resizing shapes problem

Post 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.
wombats
Enthusiast
Enthusiast
Posts: 663
Joined: Thu Dec 29, 2011 5:03 pm

Re: Resizing shapes problem

Post by wombats »

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

Thanks to you all.
Post Reply