Page 1 of 1

Resize / move Gadget with mouse

Posted: Mon Oct 10, 2011 9:19 am
by captain_skank
OK - this is going to seem like a dumb q - but it is monday :)

I have a simple form with a string gadget on it.

I can move and resize the gadget through code no probs.

But how do I do this using the mouse on a live form??

Is this even possible ??

Thanks for any pointers.

Captain_S

Re: Resize / move Gadget with mouse

Posted: Mon Oct 10, 2011 10:07 am
by deeproot
One fairly simple way, though Windows only, is to use srod's EasyVENT library - viewtopic.php?f=14&t=28810&hilit=easyvent

The documentation explains it pretty well. Don't have a code example with StringGadget but srod's splitter gadget replacement ( viewtopic.php?f=12&t=22640&hilit=easyvent+splitter+gadget ) does it with a moveable ImageGadget and the same events can be set for other gadgets .

I'm nowhere near as expert as others here, so maybe there are other suggestions, perhaps on other platforms?

Geoff.

Re: Resize / move Gadget with mouse

Posted: Mon Oct 10, 2011 11:09 am
by srod
Honestly, you are better off rolling your own solution, but... if it helps...

Code: Select all

If OpenWindow(0, 0, 0, 222, 200, "ButtonGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  hWnd = ButtonGadget(0, 10, 10, 200, 40, "Standard Button")
  SetWindowLongPtr_(hWnd, #GWL_STYLE, GetWindowLongPtr_(hWnd, #GWL_STYLE)|#WS_SIZEBOX)
  Repeat
    eventID = WaitWindowEvent()
    Select eventID
      Case #WM_LBUTTONDOWN
        If WindowFromPoint_(DesktopMouseX() + DesktopMouseY() <<32) = hWnd
          ReleaseCapture_() 
          SendMessage_(hWnd, #WM_NCLBUTTONDOWN, #HTCAPTION, 0) 
        EndIf
     EndSelect
  Until eventID = #PB_Event_CloseWindow
EndIf

Re: Resize / move Gadget with mouse

Posted: Mon Oct 10, 2011 1:17 pm
by captain_skank
Thanks for the info guys - it's given me a start.

Re: Resize / move Gadget with mouse

Posted: Mon Oct 10, 2011 2:13 pm
by Shardik
Another rather old example from the German forum from Danilo
(modified by teachco for PB 4 and with a few minor adaptions by
me) which allows to move around several different gadgets
(tested in Windows XP SP3):
http://www.purebasic.fr/german/viewtopi ... 3&start=15

Code: Select all

Structure SubClassGadget 
  hWnd.l 
  oldWndProc.l 
  mouseDown.l 
  mouseOffX.l 
  mouseOffY.l 
EndStructure 

Global NewList gadgets.SubClassGadget() 
;////////////////////////////////////////////// 

Procedure GadgetCallback(hWnd,Msg,wParam,lParam) 
  Select Msg 
    Case #WM_LBUTTONDOWN 
      ForEach gadgets() 
        If gadgets()\hWnd = hWnd 
          gadgets()\mouseOffX = lParam & $FFFF 
          gadgets()\mouseOffY = (lParam>>16) & $FFFF 
          gadgets()\mouseDown = 1 
          SetFocus_(hWnd) 
          SetCursor_(LoadCursor_(0,#IDC_SIZEALL)) 
          ProcedureReturn 0 
        EndIf 
      Next 
    Case #WM_MOUSEMOVE 
      If wParam & #MK_LBUTTON 
        ForEach gadgets() 
          If gadgets()\hWnd = hWnd And gadgets()\mouseDown 
            GetCursorPos_(p.POINT) 
            MapWindowPoints_(0,WindowID(0),@p,1) 
            x = p\x - gadgets()\mouseOffX 
            y = p\y - gadgets()\mouseOffY 
            If x < 0 : x = 0 : EndIf 
            If y < 0 : y = 0 : EndIf 
            GetClientRect_(hWnd,rect.RECT) 
            GetClientRect_(WindowID(0),rect2.RECT) 
            If x > rect2\right  - rect\right  : x = rect2\right  - rect\right  : EndIf 
            If y > rect2\bottom - rect\bottom : y = rect2\bottom - rect\bottom : EndIf 
            ResizeGadget(GetWindowLong_(hWnd,#GWL_ID),x,y,#PB_Ignore,#PB_Ignore) 
            SetCursor_(LoadCursor_(0,#IDC_SIZEALL)) 
            SetCapture_(hWnd) 
            ProcedureReturn 0 
          EndIf 
        Next 
      ElseIf wParam = 0 
        SetCursor_(LoadCursor_(0,#IDC_SIZEALL)) 
      EndIf 
    Case #WM_LBUTTONUP 
      ForEach gadgets() 
        If gadgets()\hWnd = hWnd 
          gadgets()\mouseDown = 0 
        EndIf 
      Next 
      SetCursor_(LoadCursor_(0,#IDC_SIZEALL)) 
      SetCapture_(0) 
      ProcedureReturn 0 
  EndSelect 
  ForEach gadgets() 
    If gadgets()\hWnd = hWnd 
      ProcedureReturn CallWindowProc_(gadgets()\oldWndProc,hWnd,Msg,wParam,lParam) 
    EndIf 
  Next 
EndProcedure 
;////////////////////////////////////////////// 

Procedure AddGadget(hGadget) 
  If IsGadget(hGadget) 
    hWnd = GadgetID(hGadget) ; for #PB_Any 
  Else 
    hWnd = hGadget 
  EndIf 
  If hWnd 
    LastElement(gadgets()) 
    AddElement(gadgets()) 
    gadgets()\hWnd       = hWnd 
    gadgets()\oldWndProc = SetWindowLong_(hWnd,#GWL_WNDPROC,@GadgetCallback()) 
  EndIf 
  ProcedureReturn hGadget 
EndProcedure 
;////////////////////////////////////////////// 



If OpenWindow(0,0,0,400,300,"WinDesigner",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
  AddGadget(ButtonGadget  (#PB_Any,10, 10,100,20,"Button")) 
  AddGadget(CheckBoxGadget(#PB_Any,10, 40,100,20,"Checkbox")) 
  AddGadget(ComboBoxGadget(#PB_Any,10, 80,100,20)) 
  Addgadget(SpinGadget    (#PB_Any,10,120,100,20,0,100)) 
  Addgadget(StringGadget  (#PB_Any,10,160,100,20,"Stringfield")) 
  AddGadget(TrackBarGadget(#PB_Any,10,200,100,20,0,100)) 
  
  Repeat 
    Select WaitWindowEvent() 
      Case #PB_Event_CloseWindow 
        If EventWindow()=0 
          If MessageBox_(0,"Do you really want to close this app?","WinDesigner - Close",#MB_YESNO|#MB_ICONQUESTION|#MB_DEFBUTTON2|#MB_TASKMODAL)=#IDYES 
            Break 
          EndIf 
        EndIf 
    EndSelect 
  ForEver 
EndIf

Re: Resize / move Gadget with mouse

Posted: Mon Oct 10, 2011 2:55 pm
by captain_skank
Nice find Shardik.

I wonder how it's done in Pureform - cos that allows resizing / moving of gadgets ( or are they not really gadgets ?? )

Thanks

Re: Resize / move Gadget with mouse

Posted: Tue Oct 11, 2011 12:15 pm
by charvista
Very interesting. I was wondering one step further, how can we retrieve the X,Y position of the gadget when moved?
And if they can be resized too, how to retrieve their width and height?
Thanks

Re: Resize / move Gadget with mouse

Posted: Tue Oct 11, 2011 2:40 pm
by captain_skank
Well you can use gadgetx gadgety gadgetwidth and gadget height for the active gadget.

Not tried that with this code yet.

Cheers

Re: Resize / move Gadget with mouse

Posted: Tue Oct 11, 2011 5:34 pm
by charvista
It was too easy... thanks Captain Skank. I forgot the existence of these commands.
And I tested them:

Code: Select all

OpenWindow(0,146,267,751,349,"test")
B=ButtonGadget(#PB_Any,79,106,99,27,"test")

Debug GadgetX(B)
Debug GadgetY(B)
Debug GadgetWidth(B)
Debug GadgetHeight(B)

Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow

Re: Resize / move Gadget with mouse

Posted: Tue Oct 11, 2011 7:34 pm
by USCode
Is it possible to do this in a cross-platform way?

Re: Resize / move Gadget with mouse

Posted: Tue Oct 11, 2011 8:48 pm
by srod
USCode wrote:Is it possible to do this in a cross-platform way?
If you're talking about allowing the user to move/size gadgets by dragging the cursor etc. like some kind of designer then, when thinking about cross-platform code without recourse to the various API's... tricky, especially when you throw container gadgets and the like into the mix.

Even on Windows, using just PB code (no API's) this is tricky. You can easily hack up something which will work, but the problem remains child controls of containers/scroll-areas etc. and, for one, checking when the cursor is over the edges of these child controls. Easy with API, but there are no PB commands for mapping coordinates between the various controls etc. The problem is that the various borders and the like that you can apply to containers 'upset' the window coordinates of their child controls and only API (at present) offers an accurate way of determining bounding rectangles.

However, I've been playing with the new canvas gadget and I've come to the conclusion that this offers a way out. I've thrown together some 'proof of concept' code which shows that, on Windows at least, we can do this using just PB code (no API). I reckon we can create an entire form designer using just PB code which should work quite well on Windows (it will invariably have a few 'peculiarities' mind! :) ) The question would be whether the code would function the same on Linux?

At this time, having no access to Linux, I have no idea whether it would?

Re: Resize / move Gadget with mouse

Posted: Tue Oct 11, 2011 9:18 pm
by falsam
I started this code for a mini designer.

-Mouse or Ctrl + Arrows: Resize gadget
-Mouse or Alt + Arrows: Move gadget
Click or right-Ins: popup menu
Right click to insert a gadget does not work under linux. Use the Insert key.

This tool can generate the source purebasic and save the design.

You can download it from this link.
:arrow: Tiny Visual Designer
I would be happy if this code could evolve.

PS: I use Pure Basic for a year, sorry if the code is not perfect yet. My English is bad, forgive me.

Re: Resize / move Gadget with mouse

Posted: Tue Oct 11, 2011 10:44 pm
by srod
Not a bad little program falsam, not bad at all. :)

It does highlight a lot of the problems though with trying to create a designer using just PB code (no API). For example, the fact that you have avoided containers. Also, the currently selected gadget isn't necessarily brought to the top of the z-order, a problem you can see if you overlap gadgets.

As I say, with careful use of the new canvas gadget, we can circumvent just about all of these problems - at least on Windows.

I might well continue with a little designer myself, just out of curiosity. See how far the canvas gadget can take things! :)