Moving and expanding Text Field Objects
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller
Moving and expanding Text Field Objects
I am wanting to be able to move around some text fields and/or resize them then depending on where they are, snap into place. I have a bunch of vertical lines (whose left edge is in an array called vertsepleft) which designate the areas where the text fields need to be bounded by. The problem is that after moving around a field and then resizing it, it will sometimes randomly move part of the way across the stack to either the left or right or shrink really small. This is frustrating as I cannot figure out why it is doing this.
Here is my code (I have several fields which are grouped together into group "LettersinFields" and where this code resides.
(I'm going to add code to make it so the fields cannot overlap and so the bottom of them line up but haven't done so yet. Also I've added a little unnecessary code in efforts to try and figure out what's wrong).
global rleft
global rright
global rwidth
global rchangepos
global lchangepos
global fldname
global itsgrabbed
global clickedonfld
global vertsepleft
on mousedown
if the first word of the name of the target = "field" then
put true into clickedonfld
put the name of the target into fldname
put the left of fldname into rleft
put the right of fldname into rright
put the width of fldname into rwidth
if rright - (item 1 of the mouseloc) < 33 then
put true into rchangepos
end if
if (item 1 of the mouseloc) - rleft < 33 then
put true into lchangepos
end if
if rright - (item 1 of the mouseloc) > 33 and (item 1 of the mouseloc) - rleft > 33 then
grab the target
put true into itsgrabbed
end if
end if
end mousedown
on mousemove
if rchangepos or lchangepos then
put item 1 of the mouseloc into tmouseloc
if rchangepos then
put tmouseloc - rright into newpos
set the width of fldname to rwidth + newpos
set the left of fldname to rleft
end if
if lchangepos then
put rleft - tmouseloc into newpos
set the width of fldname to rwidth + newpos
set the right of fldname to rright
end if
end if
end mousemove
on mouseup
makegoodwidth
end mouseup
on mouserelease
makegoodwidth
end mouserelease
on makegoodwidth
if clickedonfld then
put false into rchangepos
put false into lchangepos
put false into clickedonfld
put false into itsgrabbed
put empty into snapfield
put empty into stayleft
if the width of fldname <= 50 then
set the width of fldname to 74
end if
repeat with i = 1 to the number of lines in the keys of vertsepleft
put abs(item 1 of the mouseloc - vertsepleft) & "," after snapfield
end repeat
put itemoffset(min(snapfield),snapfield) into sdfsdf
put vertsepleft[sdfsdf] + 2 into stayleft
set the left of fldname to stayleft
repeat with i = 1 to the number of lines in the keys of vertsepleft
put abs(the right of fldname - vertsepleft) & "," after snapfield1
put vertsepleft - the right of fldname & "," after snapfield2
end repeat
set the width of fldname to the width of fldname + item (itemoffset(min(snapfield1),snapfield1)) of snapfield2
set the left of fldname to stayleft
end if
end makegoodwidth
Here is my code (I have several fields which are grouped together into group "LettersinFields" and where this code resides.
(I'm going to add code to make it so the fields cannot overlap and so the bottom of them line up but haven't done so yet. Also I've added a little unnecessary code in efforts to try and figure out what's wrong).
global rleft
global rright
global rwidth
global rchangepos
global lchangepos
global fldname
global itsgrabbed
global clickedonfld
global vertsepleft
on mousedown
if the first word of the name of the target = "field" then
put true into clickedonfld
put the name of the target into fldname
put the left of fldname into rleft
put the right of fldname into rright
put the width of fldname into rwidth
if rright - (item 1 of the mouseloc) < 33 then
put true into rchangepos
end if
if (item 1 of the mouseloc) - rleft < 33 then
put true into lchangepos
end if
if rright - (item 1 of the mouseloc) > 33 and (item 1 of the mouseloc) - rleft > 33 then
grab the target
put true into itsgrabbed
end if
end if
end mousedown
on mousemove
if rchangepos or lchangepos then
put item 1 of the mouseloc into tmouseloc
if rchangepos then
put tmouseloc - rright into newpos
set the width of fldname to rwidth + newpos
set the left of fldname to rleft
end if
if lchangepos then
put rleft - tmouseloc into newpos
set the width of fldname to rwidth + newpos
set the right of fldname to rright
end if
end if
end mousemove
on mouseup
makegoodwidth
end mouseup
on mouserelease
makegoodwidth
end mouserelease
on makegoodwidth
if clickedonfld then
put false into rchangepos
put false into lchangepos
put false into clickedonfld
put false into itsgrabbed
put empty into snapfield
put empty into stayleft
if the width of fldname <= 50 then
set the width of fldname to 74
end if
repeat with i = 1 to the number of lines in the keys of vertsepleft
put abs(item 1 of the mouseloc - vertsepleft) & "," after snapfield
end repeat
put itemoffset(min(snapfield),snapfield) into sdfsdf
put vertsepleft[sdfsdf] + 2 into stayleft
set the left of fldname to stayleft
repeat with i = 1 to the number of lines in the keys of vertsepleft
put abs(the right of fldname - vertsepleft) & "," after snapfield1
put vertsepleft - the right of fldname & "," after snapfield2
end repeat
set the width of fldname to the width of fldname + item (itemoffset(min(snapfield1),snapfield1)) of snapfield2
set the left of fldname to stayleft
end if
end makegoodwidth
-
- Livecode Opensource Backer
- Posts: 9386
- Joined: Fri Feb 19, 2010 10:17 am
- Location: Bulgaria
Re: Moving and expanding Text Field Objects
That's very difficult to understand outwith the context of the stack.
-
- VIP Livecode Opensource Backer
- Posts: 9663
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Moving and expanding Text Field Objects
What Richmond said.
The good news is that your handlers do not throw an error, but there is no way to help you without that context.
The symptoms you describe do not happen on their own. This could simply be the order in which you do things. For example, if you set the location of a control adjacent to one of those reference lines you mentioned, and then resize it, the control will expand or shrink, but still centered around the original loc. This will move it "off" of the reference line. That sort of thing.
You obviously have a good grasp of LC. Your code is verbose, but that is to be expected with new users. This is not a criticism; you will write much more compactly as you learn LC. If we can work through your current offering, I bet we can cut in half the number of required lines, and get rid of those globals. I am not being glib. That also was not a criticism. Really.
Also, please enclose your code inside the code tags ("</>"). It makes them so much more readable and accessible.
Craig
The good news is that your handlers do not throw an error, but there is no way to help you without that context.
The symptoms you describe do not happen on their own. This could simply be the order in which you do things. For example, if you set the location of a control adjacent to one of those reference lines you mentioned, and then resize it, the control will expand or shrink, but still centered around the original loc. This will move it "off" of the reference line. That sort of thing.
You obviously have a good grasp of LC. Your code is verbose, but that is to be expected with new users. This is not a criticism; you will write much more compactly as you learn LC. If we can work through your current offering, I bet we can cut in half the number of required lines, and get rid of those globals. I am not being glib. That also was not a criticism. Really.
Also, please enclose your code inside the code tags ("</>"). It makes them so much more readable and accessible.
Craig
Re: Moving and expanding Text Field Objects
would you supply us with an example of the data in array vertsepleft?
Re: Moving and expanding Text Field Objects
I have had a load of trouble with objects of all kinds when moving AND resizing.
What Craig says holds true.
The object (field) is moved by it's anchor point unless you tell it otherwise. Objects are resized around their anchor point. The left, right, top and bottom will move when resizing, so you need to resize then set the location. It looks like you're doing this in your code, but you end up doing it twice in your final code when you say:
This happens twice in the same piece of code. I am sure there is a much easier way of working out where the left and right edges should be (set the width to this value, then set the left, top, whatever- to what it needs to be.
Resize, then move...
So I would check the order too.
XdM
What Craig says holds true.
The object (field) is moved by it's anchor point unless you tell it otherwise. Objects are resized around their anchor point. The left, right, top and bottom will move when resizing, so you need to resize then set the location. It looks like you're doing this in your code, but you end up doing it twice in your final code when you say:
Code: Select all
set the left of fldname to stayleft
This happens twice in the same piece of code. I am sure there is a much easier way of working out where the left and right edges should be (set the width to this value, then set the left, top, whatever- to what it needs to be.
Resize, then move...
So I would check the order too.
XdM
Re: Moving and expanding Text Field Objects
Hi,
as Xero said. It's essential to do things in the correct order:
This grid I create at first use, save it to a custom property, and use from there.
The "moving code" of my buttons is in a behavior button shared by all moving buttons.
Still, each of them has its own "realMouseUp" handler ;-)
It's very simple - no collision detection, no size change, always adjusts to left/ top. I wrote it once to get my head wrapped around the principles - but it's well commented & may give you some ideas.
(If it doesn't work, use the "Set Behav.!" button to renew the behaviors!)
Have fun!
as Xero said. It's essential to do things in the correct order:
- Set the dimensions (using height & width)
- Determine horizontal & vertical location (using whatever suits you)
- Set horizontal location (using left or right), and vertical location (using top or bottom)
This grid I create at first use, save it to a custom property, and use from there.
The "moving code" of my buttons is in a behavior button shared by all moving buttons.
Still, each of them has its own "realMouseUp" handler ;-)
It's very simple - no collision detection, no size change, always adjusts to left/ top. I wrote it once to get my head wrapped around the principles - but it's well commented & may give you some ideas.
(If it doesn't work, use the "Set Behav.!" button to renew the behaviors!)
Have fun!
- Attachments
-
- awaGridDrag.zip
- drag around the grid ...
- (2.27 KiB) Downloaded 152 times
All code published by me here was created with Community Editions of LC (thus is GPLv3).
If you use it in closed source projects, or for the Apple AppStore, or with XCode
you'll violate some license terms - read your relevant EULAs & Licenses!
If you use it in closed source projects, or for the Apple AppStore, or with XCode
you'll violate some license terms - read your relevant EULAs & Licenses!
Re: Moving and expanding Text Field Objects
Wow thanks everyone!
And thanks AxWald! Unfortunately this forum said that I didn't have permission to view the file you posted. Is there another way for me to get this?
I'm going to see if I can get AxWald's stack, so you no need to reply more in case you want my global vertsepleft variable, here it is.
</>
put 48 into vertsepleft[1]
put 122 into vertsepleft[2]
put 269 into vertsepleft[3]
put 343 into vertsepleft[4]
put 196 into vertsepleft[5]
put 417 into vertsepleft[6]
put 491 into vertsepleft[7]
put 564 into vertsepleft[8]
put 638 into vertsepleft[9]
put 712 into vertsepleft[10]
put 786 into vertsepleft[11]
put 859 into vertsepleft[12]
put 933 into vertsepleft[13]
put 1007 into vertsepleft[14]
</>
[edit]
I just realized that one reason it may be doing that is because I didn't have it sort my numbers from lowest to highest before putting them into an array. vertsepleft[5] is way out of order.
And thanks AxWald! Unfortunately this forum said that I didn't have permission to view the file you posted. Is there another way for me to get this?
I'm going to see if I can get AxWald's stack, so you no need to reply more in case you want my global vertsepleft variable, here it is.
</>
put 48 into vertsepleft[1]
put 122 into vertsepleft[2]
put 269 into vertsepleft[3]
put 343 into vertsepleft[4]
put 196 into vertsepleft[5]
put 417 into vertsepleft[6]
put 491 into vertsepleft[7]
put 564 into vertsepleft[8]
put 638 into vertsepleft[9]
put 712 into vertsepleft[10]
put 786 into vertsepleft[11]
put 859 into vertsepleft[12]
put 933 into vertsepleft[13]
put 1007 into vertsepleft[14]
</>
[edit]
I just realized that one reason it may be doing that is because I didn't have it sort my numbers from lowest to highest before putting them into an array. vertsepleft[5] is way out of order.
Re: Moving and expanding Text Field Objects
Hmm,
I can DL the demo stack w/o problems. Anyways, it's quite simple, here's the code & how to make:
I created a stack, and 1 button (You may have more btns, too ;-)) )
Script of the card:
Here are 2 constants (kHGrid & kVGrid) - these are used to calculate the horizontal & vertical grid lines. This is done with "on makeGridArr", a handler that creates a simple grid based on the constants & the measures of the card.
The result is an array in a customProp "the cGridArr of this cd". The array has 2 keys (HVals & VVals), each a sorted list of points (0,20,40,60 ...).
"CalcNewLoc" is explained below.
The handlers in the button(s):
Another constant, "kMinMove" - this is how far we need to drag that it is considered a valid drag. The script local variables are used in the code. Then:
"MouseDown" starts the tracking, "MouseMove" moves it, "MouseUp" does more:
In my demo stack I had the btn code in a behavior, thus the buttons itself had no code of their own. If you don't do this, just copy the code into anything that needs dragging ;-)
This works with (locked!) fields as well, btw.
Have fun!
I can DL the demo stack w/o problems. Anyways, it's quite simple, here's the code & how to make:
I created a stack, and 1 button (You may have more btns, too ;-)) )
Script of the card:
Code: Select all
constant kHGrid = 20 -- measurements of grid
constant kVGrid = 20
function calcNewLoc theRect
-- at first, calculate size as you desire it
-- I don't do anything here, too lazy :)
put (item 3 of theRect) - (item 1 of theRect) into myWidth -- loading variables
put (item 4 of theRect) - (item 2 of theRect) into myHeight
put item 1 of theRect into myLeft
put item 2 of theRect into myTop
put the cGridArr of this cd into myGridArr -- load array
-- now we check for a suitable left:
-- I'm fitting the object to the grid using
-- left-to-right/ top-to-bottom orientation
repeat with i = 1 to the number of items of myGridArr["HVals"] -- calculate horizontal
if item i of myGridArr["HVals"] > myLeft then
put item i -1 of myGridArr["HVals"] into myH
exit repeat
end if
end repeat
-- now myH is the next grid to the left
repeat with i = 1 to the number of items of myGridArr["VVals"] -- calculate vertical
if item i of myGridArr["VVals"] > myTop then
put item i -1 of myGridArr["VVals"] into myV
exit repeat
end if
end repeat
-- now myV is the next grid above
-- and we adjust the new rect:
return myH & comma & myV & comma & \ -- return resulting rect
myH + myWidth & comma & myV + myHeight
end calcNewLoc
on makeGridArr -- create the basic grid
put 0 into myH
put 0 into myV
repeat -- horizontal values
if the controlKey is down then exit repeat
put myH + kHGrid into myVar
if myVar > the width of this cd then exit repeat
put myVar & comma after myHGrid
put myVar into myH
end repeat
put 0 & comma before myHGrid
delete char -1 of of myHGrid
-- you may want to add [the right of this cd] for
-- horizontal right-to-left orientation ...
repeat
if the controlKey is down then exit repeat -- vertical values
put myV + kVGrid into myVar
if myVar > the height of this cd then exit repeat
put myVar & comma after myVGrid
put myVar into myV
end repeat
put 0 & comma before myVGrid
delete char -1 of of myVGrid
-- you may want to add [the bottom of this cd] for
-- vertical bottom-to-top orientation ...
-- Or you may even want to add 2 more entries for
-- nice right-to-left/ bottom-to-top orientation ...
put myHGrid into myGridArr["HVals"]
put myVGrid into myGridArr["VVals"]
set the cGridArr of this cd to myGridArr -- create array & stash it in a cProp
end makeGridArr
The result is an array in a customProp "the cGridArr of this cd". The array has 2 keys (HVals & VVals), each a sorted list of points (0,20,40,60 ...).
"CalcNewLoc" is explained below.
The handlers in the button(s):
Code: Select all
local lastLoc, isMove
constant kMinMove = 20 -- how far to move to register?
on mouseDown
put the loc of me into lastLoc -- start monitoring
put true into isMove
set the loc of me to the mouseLoc
end mouseDown
on mouseMove
if isMove then
set the loc of me to the mouseLoc -- move it!
else
pass mouseMove
end if
end mouseMove
on mouseUp
put false into isMove -- reset monitoring
put the loc of me into myLoc
if the cGridArr of this cd is empty then makeGridArr -- make sure we have the grid!
if not (the mouseLoc is within the rect of this cd) then \ -- released outside cd rect
set the loc of me to lastLoc -- so reset it
else if ((abs(item 1 of lastLoc - item 1 of myLoc) > kMinMove) OR \ -- dragged sufficient
(abs(item 2 of lastLoc - item 2 of myLoc) > kMinMove)) then -- width, so a drag
set the rect of me to CalcNewLoc(the rect of me) -- thus ask for new loc
else -- must be a real mouseUp!
dispatch "realMouseUp" to the target -- so tell it about!
set the loc of me to lastLoc -- and reset loc
end if
end mouseUp
on realmouseUp
answer "I'm button '" & the short name of me & "', and you clicked me!"
end realmouseUp
"MouseDown" starts the tracking, "MouseMove" moves it, "MouseUp" does more:
- Stops the tracking
- creates the grid if there isn't one yet
- checks if we're within the card (else resets the btn pos)
- checks if we dragged wide enough (else resets btn pos)
- calls function "CalcNewLoc(the rect of me)" to get the new position
- sets the new position
- and if we haven't moved, determines its a real mouseUp & calls "realMouseUp" ;-)))
In my demo stack I had the btn code in a behavior, thus the buttons itself had no code of their own. If you don't do this, just copy the code into anything that needs dragging ;-)
This works with (locked!) fields as well, btw.
Have fun!
All code published by me here was created with Community Editions of LC (thus is GPLv3).
If you use it in closed source projects, or for the Apple AppStore, or with XCode
you'll violate some license terms - read your relevant EULAs & Licenses!
If you use it in closed source projects, or for the Apple AppStore, or with XCode
you'll violate some license terms - read your relevant EULAs & Licenses!