Page 1 of 2

Show a Gadget selected and ready to resize manually by user

Posted: Mon Sep 24, 2007 9:35 pm
by QuimV
:D Hi,

In Visual Designer, when we insert a gadget in a Window, it appears selected and with 8 small squares around, in order to permit the user manually resize the Gadget.

My question is: How Could I do that by code?. I mean with an Gadget inserted, show it selected and with its 8 small squares, ready to permit the user manually resize the Gadget.

Thanks In advanced.

Posted: Tue Sep 25, 2007 2:34 am
by Sparkie
This may not be exactly what you are looking for but I figured I'd throw it out there just the same. It's very old code and not fully tested with all PB gadgets, so you may need to optimize it here and there. It's not fully commented but it may give you a push in the right direction. :)

Code: Select all

;...Load cursor to use for sizing
curMove = LoadCursor_(0, #IDC_SIZEALL)
;...Make our sizerbutton transparent
Global hTransBrush = GetStockObject_(#HOLLOW_BRUSH)
Global idChild, oldCallback, sizerButton, moveit
Procedure findChild()
  hwin = ChildWindowFromPoint_(WindowID(0),WindowMouseX(0), WindowMouseY(0))
  If hwin <> sizerButton
    idChild = GetDlgCtrlID_(hwin)
    If idChild = 0 
      topWin = GetTopWindow_(hwin)
      idChild = GetDlgCtrlID_(topWin)
    EndIf
    If idChild > 1
      HideGadget(1, 0)
      InvalidateRect_(sizerButton, 0, 1)
      MoveWindow_(GadgetID(1), GadgetX(idChild)-2, GadgetY(idChild)-2, GadgetWidth(idChild)+4, GadgetHeight(idChild)+4, 1)
      InvalidateRect_(GadgetID(idChild), 0, 1)
    ElseIf idChild = 1
      moveit = #False
      ResizeGadget(1, 0, 0, 5, 5)
      HideGadget(1, 1)
    EndIf
  EndIf
  If moveit = #True
    ReleaseCapture_()
    SendMessage_(sizerButton, #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
  EndIf
  ProcedureReturn idChild
EndProcedure

Procedure WinCallback(hwnd, msg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  Select msg
    Case #WM_CTLCOLORBTN 
      If lParam = sizerButton
        SetTextColor_(wParam,$000000) 
        SetBkMode_(wParam, #TRANSPARENT) 
        If StartDrawing(WindowOutput(0)) 
          DrawingMode(4) 
          Box(GadgetX(1),GadgetY(1),GadgetWidth(1),GadgetHeight(1), RGB(255, 0, 0)) 
          Box(GadgetX(1)+1,GadgetY(1)+1,GadgetWidth(1)-2,GadgetHeight(1)-2, RGB(255, 0, 0)) 
          StopDrawing() 
        EndIf 
        result=hTransBrush 
      EndIf
  EndSelect
  ProcedureReturn result
EndProcedure

Procedure sizerCallback(hwnd, msg, wParam, lParam)
  Shared prevX, prevY
  result = CallWindowProc_(oldCallback, hwnd, msg, wParam, lParam)
  Select msg
    Case #WM_LBUTTONDOWN
      moveit = #True
    Case #WM_LBUTTONUP
      moveit = #False
      ReleaseCapture_()
    Case #WM_EXITSIZEMOVE
      moveit = #False
    Case #WM_SIZING
      ResizeGadget(idChild, GadgetX(1)+2, GadgetY(1)+2, GadgetWidth(1)-4, GadgetHeight(1)-4)
    Case #WM_MOVING
      InvalidateRect_(sizerButton, 0, 1)
      ResizeGadget(idChild, GadgetX(1)+2, GadgetY(1)+2, GadgetWidth(1)-4, GadgetHeight(1)-4)
    Case #WM_GETMINMAXINFO   
      *mmi.MINMAXINFO = lParam 
      *mmi\ptMinTrackSize\x = 5 
      *mmi\ptMinTrackSize\y = 5 
  EndSelect
  ProcedureReturn result
EndProcedure

If OpenWindow(0, 0, 0, 700, 500, "Manula Gadget Sizing / Positioning", #PB_Window_SystemMenu) And CreateGadgetList(WindowID(0))
  curDef = GetClassLong_(WindowID(0), #GCL_HCURSOR)
  SetWindowCallback(@WinCallback())
  ;...The sizerbutton is the one that we are able to grip
  ;...All other gadgets move and resize as the sizerbutton does
  sizerButton = ButtonGadget(1, 0, 0, 1, 1,"",#WS_SIZEBOX)
  SetWindowLong_(sizerButton, #GWL_STYLE, GetWindowLong_(sizerButton, #GWL_STYLE)|#WS_CHILD|#WS_VISIBLE|#BS_OWNERDRAW)
  SetWindowLong_(sizerButton, #GWL_EXSTYLE, GetWindowLong_(sizerButton, #GWL_EXSTYLE)|#WS_EX_TRANSPARENT)
  SetClassLong_(GadgetID(1), #GCL_HCURSOR, curMove)
  oldCallback = SetWindowLong_(sizerButton, #GWL_WNDPROC, @sizerCallback()) 
  ExplorerTreeGadget(2, 10, 10, 200, 100, "c:\")
  ButtonGadget(3, 10, 120, 100, 40, "Button")
  ExplorerListGadget(4, 300, 10, 200, 100, "c:/")
  Frame3DGadget(5, 300, 120, 200, 100, "Hello World")
  Repeat
    event = WaitWindowEvent()
    Select event
      Case #WM_NCMOUSEMOVE 
        findChild()
      Case #WM_MOUSEMOVE
        findChild()
    EndSelect
  Until event = #PB_Event_CloseWindow
EndIf
End

Posted: Tue Sep 25, 2007 6:44 am
by QuimV
Thank You Sparkie,
It's perfect and a great start point for me.
Thanks again.

Posted: Tue Sep 25, 2007 9:55 am
by srod
Nice one sparks. Pretty cool.

Posted: Tue Sep 25, 2007 11:35 am
by Shardik
Another example demonstrating how to move gadgets inside a window of a running program you can find in a German forum post from Danilo, modified for PB4 by teachco:
http://www.purebasic.fr/german/viewtopi ... 3&start=15

DarkDragon even demonstrates for a button gadget how to change from drag mode to resize mode and change the button size during runtime (PB 3.9x):
http://www.purebasic.fr/german/viewtopi ... 3&start=13

Posted: Tue Sep 25, 2007 1:11 pm
by Sparkie
@QuimV: You are very welcome :)

@srod: Thank you :)

I came up with that code a couple of years ago whilst attempting to create my own visual designer. I scrapped the project after I realized that I rarely, if ever, use a visual designer.

Posted: Fri Oct 05, 2007 2:34 pm
by Progi1984
Is there a possibilty to move and resize a gadget manually by user with the new lib Drag'n'Drop to do that multiplateform?

Posted: Fri Oct 05, 2007 2:41 pm
by srod
Resize - no.

Move - possibly, but not without quite a bit of work. First, you'd either have to use a private drag/drop format or create your own clipboard format. Secondly, you'd undoubtedly require a visual representation of the gadget being dragged and so you'd need to declare a drag callback function.

It would be more effort than the myriad of other methods available.

Bericko's designer is crossplatform and done without the new drag/drop lib.

**EDIT : second thoughts, it probably wouldn't be that much work! :) Yes, a private drag format combined with a drag callback... Wouldn't be my first choice though!

Posted: Fri Oct 05, 2007 3:05 pm
by Progi1984
Sorry, but i don't understand all your english... :o

What are " the myriad of other methods available" for moving and resizing gadgets with multiplateform code ?

Posted: Fri Oct 05, 2007 3:21 pm
by srod
Yes I added the cross-platform remark after realising that you were seeking a cross-platform method - sorry!

Bericko's visual designer, whilst crossplatform, must still use some api (e.g. the change of cursor) but is undoubtedly using some conditional compilation. Still, I imagine he makes good use of Purebasic's 2d-drawing commands wherever possible.

I think that any crossplatform designer will still use some platform dependant code, you'll just have to use conditional compilation in order to sift out code for other platforms etc. In terms of specifics I can only comment on Windows as I don't do Linux I'm afraid!

Posted: Fri Oct 05, 2007 4:01 pm
by Progi1984
Very thank you for your comment...

I find a ggod source for moving and sizing gadgets under Windows... but not for Linux...

@Bericko but others too : If you hear that, which trick do you use for moving and sizing gadgets under Linux ?

Re: Show a Gadget selected and ready to resize manually by user

Posted: Sun Oct 25, 2009 11:05 am
by DoubleDutch
Has anyone messed with code like this, but also with a background grid and/or snap?

Re: Show a Gadget selected and ready to resize manually by user

Posted: Sun Oct 25, 2009 11:08 am
by srod
Yes.

:)

Re: Show a Gadget selected and ready to resize manually by user

Posted: Sun Oct 25, 2009 3:35 pm
by DoubleDutch
lol, any example - just to get me started. ;)

Re: Show a Gadget selected and ready to resize manually by user

Posted: Thu Mar 11, 2010 8:23 pm
by Rook Zimbabwe
Did y'all know that there is no ChildWindowFromPoint() in 4.4+ ???