Drag to resize list fields

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
tetsuo29
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 103
Joined: Thu Jun 07, 2007 1:30 am

Drag to resize list fields

Post by tetsuo29 » Wed Nov 21, 2007 3:07 am

Hi. I'm attempting to create an interface where I have two list fields side by side. I would like the user to be able to click in the space between the two lists and then drag left or right to and have the lists widths to be resized.

What I've attempted to do, is to put a tall narrow rectangle in the space between the two fields and then have it respond to the mouseDown and dragMove messages.

They look like this:

on mouseDown
-- I set the dragdata, because the documentation led me to believe
-- it was necessary to get the rectangle to respond to dragMove messages
set the dragdata["text"] to "text being dragged"
-- the rectangle's width is 10 and so this immediately moves the rectangle
-- to be centered to the pointer, if the pointer escapes the rectangle, the drag
-- operation fails
set the left of me to the mouseH - 5
end mouseDown


on dragMove
-- again, this centers the rectangle to the pointer
set the left of me to the mouseH - 5
-- this resizes the left hand field to be one pixel away from the rectangle
set the width of field LeftSideField to the mouseH - 6
-- this gets the left hand field positioned properly again against the left
-- edge of the window
set the left of field LeftSideField to 0
-- then, I set the width of the right hand field and fix it's position
set the width of field RightSideField to width of this stack - the mouseH - 6
set the left of field RightSideField to width the mouseH - 6
end dragMove


Now, this mostly works, but not as well as I'd like. If you move the pointer too quickly (which is not hard to do), it will escape from the rectangle and your drag operation will stop and the dragMove messages will start making their way up the message path. Also, even if you drag slowly enough to avoid this, when the window is resized and the fields resize based on their geometry settings, they are no longer within one pixel of the rectangle.

I'm thinking that there has two be a better way to accomplish what I'm trying to do in Revolution. I'm hoping that someone out there will be able to set me straight. Thanks in advance. :-)

malte
Posts: 1098
Joined: Thu Feb 23, 2006 8:34 pm
Location: Ostenfeld germany
Contact:

Post by malte » Wed Nov 21, 2007 8:46 am

Hi,

I would suggest using mouseMove instead:

A basic script could look like this:

Code: Select all

on mouseDown
  set the uAllowDrag of me to true
end mouseDown

on mouseUp
  set the uAllowDrag of me to false
end mouseUp

on mouseRelease
  mouseUp
end mouseRelease

on mouseMove
  if not the uAllowDrag of me then exit mouseMove
  set the loc of me to item 1 of the mouseLoc,item 2 of the loc of me
  set the rect of fld "myField1" to the topLeft of fld "myField1", the botLeft of me
  set the rect of fld "myField2" to the topRight of me,the botright of fld "myField2"
end mouseMove
(Out of the top of my head, but should work.

Hope that helps,

Malte

malte
Posts: 1098
Joined: Thu Feb 23, 2006 8:34 pm
Location: Ostenfeld germany
Contact:

Post by malte » Wed Nov 21, 2007 8:51 am

Just read your post again.

I see you are using the geometryManager. (which is ok for simple layouts, but I would advocate against it when you are building more complex stuff), so you will need to take that into account in the divider script.

See revCacheGeometry in the dictionary.

All the best,

Malte

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Wed Nov 21, 2007 10:20 am

Hi tetsuo29,

Please, don't use the geometry manager. You will regret using it at some point.

I would follow Malte's approach and make it even more simple:

Code: Select all

on mouseDown
  repeat until the mouse is up
    set the loc of me to item 1 of the mouseLoc,item 2 of the loc of me
    set the rect of fld "myField1" to the topLeft of fld "myField1", the botLeft of me - 8
    set the rect of fld "myField2" to the topRight of me,the botright of fld "myField2" + 8
end repeat
end mouseMove
I have also added some space between the fields for the handle. The space is 16 pixels wide.

Best,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

tetsuo29
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 103
Joined: Thu Jun 07, 2007 1:30 am

Post by tetsuo29 » Wed Nov 21, 2007 11:23 am

Hey, thanks for the tips! They've been extremely helpful. :D

What I've ended up with is the following:

Code: Select all

on mouseDown
  lock cursor
  set the cursor to 31
  repeat until the mouse is up
    if item 1 of the mouseLoc > the uMinWidth of me and item 1 of the mouseLoc < the uMaxWidth of me then
      set the loc of me to item 1 of the mouseLoc,item 2 of the loc of me
      set the rect of fld the uLeftFld of me to the topLeft of fld the uLeftFld of me,the botLeft of me
      set the rect of fld the uRightFld of me to the topRight of me,the botRight of fld the uRightFld of me
      set the left of fld the uRightFldLbl of me to the left of fld the uRightFld of me - 6 
    end if
  end repeat
end mouseDown

on mouseUp
  unlock cursor
  set the cursor to arrow
end mouseUp

on mouseEnter
  lock cursor
  set the cursor to 31
end mouseEnter

on mouseLeave
  unlock cursor
  set the cursor to arrow
end mouseLeave
These:
  • uMinWidth
    uMaxWidth
    uLeftFld
    uRightFld
    uRightFldLbl
...are all custom properties of the resizer object (got that idea from Eric Chatonet of So Smart Software's similar example that someone pointed out on the mailing list).

This has really simplified the convoluted solution that I'd come up with using dragMove in both the resizer object and the stack script along with some globals for keeping track of where dragMove had been started initially.

So, about that suggestion to not use the geometry manager? What's the alternative? Code in an resize message handler? Can you point me to an example of what you recommend?

Thanks again.

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Wed Nov 21, 2007 11:30 am

For the alternative, see the simple script in my previous post.

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

tetsuo29
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 103
Joined: Thu Jun 07, 2007 1:30 am

Post by tetsuo29 » Wed Nov 21, 2007 12:11 pm

I'm sorry. I'm not being clear.

I thought you meant to not use the geometry manager at all, like for keeping the fields scaled when the window is resized. That's what I was asking about.

The code I ended up with for my splitter/resizer/divider is basically your simple example with some handlers for changing the pointer and an if/then clause for preventing resizing outside of a min/max boundary.

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Wed Nov 21, 2007 12:48 pm

tetsuo29,

Maye we still don't understand each other completely. I am indeed saying that one shoudn't use the geometry manager at all and I believe RunRev Ltd should get rid of it. Beginners are completely put off by a geometry manager that fails beyond repair when they have almost finished their first project. Advanced scripters can easily write their own ad-hoc "geometry manager".

The only good alternative is to hardcode all resizing. Maybe you are asking which messages you may use. MouseDown is one of them, resizeStack is another. There might be other handlers that you need, depending on the context. Just ask here when you get stuck.

Best,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

tetsuo29
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 103
Joined: Thu Jun 07, 2007 1:30 am

Post by tetsuo29 » Wed Nov 21, 2007 1:01 pm

Mark,

Thanks for being patient with me. I think we're starting to speak about the same thing. What I was attempting to ask about 2 posts back was an example of not using the geometry manager for resizing controls when the window/stack is resized. For instance, what would be the simplest way to scale both my left and right fields, and my resizer button inside of a stackResize method?

The left field is currently anchored only to the bottom of the stack, same for the resizer button, the right field is anchored to the bottom and right hand sides of the stack.

Any examples would be very much appreciated. Thanks again. :twisted:

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Wed Nov 21, 2007 1:26 pm

Hi tetsuo29,

As an example, lets scale one field relative to the size of a stack window. There will be a margin of 32 pixels between the field and the card borders.

Code: Select all

on resizeStack
  -- resize field
  put the topleft of fld 1 into myTL
  put (the width of this cd - 64) into myWidth
  put (the height of this cd - 64) into myHeight
  set the width of fld 1 to myWidth
  set the height of fld 1 to myHeight
  set the topleft of fld 1 to myTL
  -- now set loc other objects, e.g. a button next to the field
  set the loc of btn 1 to the loc of fld 1
  set the left of btn 1 to the right of fld 1
end resizeStack
I haven't tested this script. Please mind typos.

When you write these scripts, you have to determine the logic behind the resizing and use rect, topleft, topright, top, right et cetera to set the size and location of objects.

Best,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

Post Reply

Return to “Talking LiveCode”