How to prevent change in a listbox selected item when users click and move mouse before mouseup - livecode

I am using the following code in a scrolling field. It works fine in both windows and android. The only problem is that the selected item changes as the mouse mouses up and down the list. I would like the original highlighted line to remain highlighted during the scroll and only change if the mouse have not moves move than 11 units(row height is 22) from initial vertical position. How do I modify this code to achieve that?
local lmousev,lvscroll,lscrolling
on mousedown
--If we don't use lscrolling the list will scroll when the mouse hovers over it
put true into lscrolling
--Set the initial vertical position of the cursor
put the mousev into lmousev
--Set the inital position of the vertical scroll
put the dgvscroll of me into lvscroll
end mousedown
on mousemove x,y
if lscrolling=true then --lscrolling is only true after mousedown so no scroll when mouse hovers over
--adjust the scroll position based on the vertical distance that the mouse has moved since mousedown
set the dgvscroll of me to lvscroll -(y - lmousev)
end if
end mousemove
on mouseUp
--stop scrolling when mouse hovers
put false into lscrolling
If abs( the mousev-lmousev)<11 then --If vertival position of mouse has not moved far from vertical position at mousedown
--selectlist command is in the group. It insert list selection into the textbox
selectlist
end if
end mouseUp
on mouserelease
--stop scrolling when mouse is release outside the listbox and there is no mouseup
put false into lscrolling
end mouserelease
The button,textbox and listbox that forms the combobox are grouped.The code to show/hide listbox and add selected to textbox is in the group script as follows:
Additional Info
local ldrop=false
on buttonclick --show/hide the listbox
--Get the name of the group,textbox & listbox.
--Naming convention required:- textboxname=txt & groupName,listboxname=lst & groupname
--Using quote as deliminater allows us to get the groupname from group "groupname"
set the itemdel to quote
put item 2 of the name of me into groupname
put "lst" & groupname into lstName
put "txt" & groupname into txtName
--status of ldrop let us know if the listbox is visible
if ldrop=false then
--show listbox
set the visible of field lstName to true
put true into ldrop
else
--hide listbox
set the visible of field lstName to false
put false into ldrop
end if
end buttonclick
on selectlist
--Get the name of the group,textbox & listbox.
--Naming convention required:- textboxname=txt & groupName,listboxname=lst & groupname
--Using quote as deliminater allows us to get the groupname from group "groupname"
set the itemdel to quote
put item 2 of the name of me into groupname
put "lst" & groupname into lstName
put "txt" & groupname into txtName
put the hilitedLine of field lstName into lhilitedLine
put line lhilitedLine of field lstName into field txtName
set the visible of field lstName to false
put false into ldrop
end selectlist

I think you have to make your own control that acts like a list so that you can control all the messages it sends and receives. You are otherwise stuck with some of those basic functions of LC's built-in controls. seems like you'd need an engine-level tweak to the control.

Related

How to find if the keyboard is covering a control

I have a code that moves a group of control when the keyboard is activated. But I only want it to run when the keyboard is covering the control that activated the keyboard. I am using the code below but it is not correctly determining when the control is hidden by the keyboard.
Stack Script
lStackSize,lStackHeight
global gBottom
on openstack
set the fullscreenmode of me to "exactFit"
put the loc of group "controls" into lStackLoc
put the effective working screenRect into lStackSize
put item 4 of lStackSize - item 2 of lStackSize into lStackHeight
end openstack
-------------------------------
on keyboardactivated
answer "control bottom" && gbottom
put the effective working screenRect into tStackSize
set itemdel to comma
put item 4 of tStackSize - item 2 of tStackSize into tStackHeight
answer "tStackHeight" && tStackHeight & return & "gbottom" && gBottom
if gbottom<tStackHeight then
answer "control Visible"
else
answer"control Hidden"
put gbottom - tStackHeight into tYMove
put item 2 of lStackLoc - tYMove into tNewLocY
put item 1 of lStackLoc & "," & tNewLocY into tStackLoc
move group "controls" to tStackLoc
end if
end keyboardactivated
---------------------------
on keyboardDeactivated
move group "controls" to lStackLoc
end keyboardDeactivated
control script
global gBottom
on openfield
put the bottom of me into gBottom
end openfield
The effective screenRect refers to the rectangle that is actually available on screen (visible the part of the screen that is really used by the app). The working screenRect is the part of the screen that isn't used by e.g. the status bar.
put the effective working screenRect into myRect
if the topleft of control x is not within myRect \
or the bottomright of control x is not within myRect then
// control x is outside the visible part of the window
end if
The working screenRect might be sufficient, but the docs specifically refer to the keyboard when discussing effective

Does the Livecode combobox support multiple column

I have linked a livecode application to a relational database. I want to use a combobox to display values related to an ID. I other program such as msaccess this is done by having combobox with 2 columns. The first is linked to the ID and set to 0 width and the second displays the related value. Is that possible in livecode?
I have a text field and a list field and I managed to get it working using the following code on rawkeyup
global strHilitedLine,strTempHilitedLine,booAfterReturn,booFirstKeyUp
on keyup -- when your press a character key
TempHilited
end keyup
on returninfield --when user press return key on keyboard
--accept the temporary hilite
put the hilitedLine of field "lstfood" into strHilitedLine
put empty into strTempHilitedLine
--set booFirstKeyUp to true so that the keyup command will know that
-- the next keyup is the first after clicking the enter/return key
put "True" into booFirstKeyUp
--clear field txtfood
put empty into fld "txtFood"
end returninfield
on enterkey --when user press enter key on mobile(code same as on returninfield)
set the hilitedLine of field "lstfood" to strTempHilitedLine
put the hilitedLine of field "lstfood" into strHilitedLine
put empty into strTempHilitedLine
put "True" into booFirstKeyUp
put empty into fld "txtFood"
end enterkey
on TempHilited
if booFirstKeyUp="True" then
--store the value of hilitedline if this is the first keyup after
-- clicking enter(see on enterkey)
put the hilitedLine of field "lstfood" into strHilitedLine
put "False" into booFirstKeyUp
end if
--set hilitedlines to the hilitedlines just after clicking enter
set the hilitedLine of field "lstfood" to strHilitedLine
-- cleartemporary hilitedlines from previous keyup
put empty into strTempHilitedLine
-- create array from field lstFood and find if the text in txtFood
-- appears at the start of any item in the array
put field "lstfood" into arrFood
filter lines of arrFood with regex pattern "^" & me into strLineText
--create new value to temporarily hilite
if the length of strHilitedLine>0 and the length of strLineText>0 then
put strHilitedLine & "," & lineoffset (strLineText ,field
"lstfood") after strTempHilitedLine
else if the length of strHilitedLine>0 then
put strHilitedLine into strTempHilitedLine
else if the length of strLineText>0 then
put lineoffset (strLineText ,field "lstfood") into strTempHilitedLine
end if
--set temporay hilite
set the hilitedLine of field "lstfood" to strTempHilitedLine
put the length of me into mylength
--Select the part of txtFood that user did to type so that it is overwritten on the next keyup
put strlinetext into field "txtFood"
select char mylength +1 to the length of me of field "txtFood"
End TempHilited
As you can see it is a long convoluted code. Happy to hear if you have a more
-- efficient way of achieving the same.
You mentioned "Store the data in a custom property, filter to include relevant lines, put the remaining data into the field" and I believe you were alluding to another method of doing it but I have not really work out how to do that
No, menu buttons don't allow for multiple columns in LiveCode. However, it is possible to make your own combobox, e.g. by using a stack panel for a menu and adding two fields to that stack. Use the properties inspector of a menu button to assign a stack as a stack panel.
I made such a stack panel, with only one column, quite some time ago:
It would be easy to make this a two-column menu: just make the field half as wide, add another field and update the hilitedLine of the field that doesn't have focus when the hilitedLine of the focused field changes. This example isn't a real stack panel, but it works pretty much the same. I open the stack hidden as a palette, set the size and location, and show it making sure that it has focus.
(The picture is from my own website; the library is in an area available to donors only).

How to refresh item in a popup menu in Livecode

I have a pop-up menu and items are read from an array and I want to refresh when I press the right mouse button. Also, is there any way to disable/enable the items of the pop-up menu?
First create a pop-up menu and give it a name, e.g. "List A". Now create a control with a mouseDown handler or add a mouseDown handler to the card script.
on mouseDown theMouseButton
if theMouseButton is 3 then
put "One item,Another item,A third item,The last item" into myList
replace comma with cr in myList
put myList into btn "List A"
popup btn "List A"
end if
end mouseDown
Set the script of the pop-up menu button to the following:
on menuPick theItem
switch theItem
case "One item"
answer "Congrats"
break
default
beep
answer "Not implented yet"
break
end switch
end menuPick
You can disable individual items by preceding them with a parenthesis:
put "One item,Another item,(A third item,The last item" into myList
This will disable the third item in the menu.
There is no need to use arrays.

mouseUp on an empty row in the Data Grid with native mobile scroller is causing an error

I'm using a native scroller for a Data Grid displaying about 700 records. When the number of visible records is small (1-2) and they do not cover the whole height of the Data Grid rectangle then when executing mouseUp on an empty row in the Data Grid I'm getting this error:
executing at 2:57:26 PM
Type Chunk: can't find background
Object: main
Line: send mouseUp to field "Label" of group "Row Template 0003" of group "dgList" of group "dgListMask" of group "DataGrid 1" of card "main"
Hint: mouseUp
The line above is a part of the scroller script in the card script enabling simple tapping on the row when not scrolling the DG:
on mouseUp
if not isScrolling then
send mouseUp to field "Label" of group "Row Template 0003" of group "dgList" of group "dgListMask" of group "DataGrid 1" of card "main"
end if
end mouseUp
To fix the error I changed it to:
on mouseUp
if gCurrentIndex = empty then -- added this line in the hope that it will fix it but it does not
exit to top -- added this line in the hope that it will fix it but it does not
else -- added this line in the hope that it will fix it but it does not
if not isScrolling then
send mouseUp to field "Label" of group "Row Template 0003" of group "dgList" of group "dgListMask" of group "DataGrid 1" of card "main"
end if
end if
end mouseUp
but it did not solve he problem.
The code in the Row Template Label is:
global gCurrentView,gCurrentLine,gCurrentIndex
on mouseUp
put the text of me into fld "foneline" of cd "oneline"
put the dgText of grp "DataGrid 1" into gCurrentView
put the dgHilitedLines of grp "DataGrid 1" into gCurrentLine
put the dgHilitedIndexes of grp "DataGrid 1" into gCurrentIndex
lock screen for visual effect
unlock screen with visual effect reveal right slow
go cd "oneline"
end mouseUp
To replicate the error follow these steps:
open the stack
click on "My Selection" button
click on OK on the message "Sorry..."
click on the grey star below the quote (select just 1 quote)
click on "Dashboard" button
click on "My Selection" button
click on the light yellow area below the quote
the Error window will show up
if this first time the error does not show then continue
click on the text quoete above the the light yellow area
click on the "Entire selection" button
click on the light yellow area below the quote - this time error will come up for sure.
The above steps may look complex but it's very simple once you see the stack which is here: DG-empty row error.zip
How to fix this error?
Not sure if gCurrentIndex has been declared as a global in the second block of code ...
global gCurrentIndex
on mouseUp
if gCurrentIndex = empty then -- added this line in the hope that it will fix it but it does not
exit to top -- added this line in the hope that it will fix it but it does not
else -- added this line in the hope that it will fix it but it does not
if not isScrolling then
send mouseUp to field "Label" of group "Row Template 0003" of group "dgList" of group "dgListMask" of group "DataGrid 1" of card "main"
end if
end if
end mouseUp
The solution was adding this block of code to the text field of the Row Template of the DG instead of to the scroller code:
if gCurrentIndex = empty then
exit to top
else
lock screen for visual effect
unlock screen with visual effect reveal right slow
go cd "oneline"
end if
Re this line:
send mouseUp to field "Label" of group "Row Template 0003" of group "dgList" of group "dgListMask" of group "DataGrid 1" of card "main"
and its alternative:
send mouseUp to field "Label"
I tested the scrolling and tapping on the row with and without this line and there is no difference, it works. I don't remember where from I got that line, probably from someone on the LC Forum. The idea was to make sure that when touching the row to scroll the DG it does not go to the card "oneline". I'll keep watching how it works now.

why check box does not move when stack is resized?

I made a stack that displays lines of text that change their width when the stack is resized.
The Category columns is changing its position on resizing but the check box does not.
What am I missing in the code? What changes have to be made?
See the code in the stack that can be downloaded here:
https://dl.dropboxusercontent.com/u/99863601/Data%20grid%20Form-variable%20line%20height%2Bcheckbox.zip
Thanks in advance.
keram
If I understand what you are trying to achieve here then in your LayoutControl handler make the following change:
-- put the rect of btn "btnCheck" of me into theFieldRect
-- put item 3 of pControlRect - 5 into item 3 of theFieldRect
-- set the rect of btn "btnCheck" of me to theFieldRect
set the left of btn "btnCheck" of me to the right of fld "cat" of me
However I think the resizing of the Cat field is wrong too. Try something like:
on LayoutControl pControlRect
set the right of btn "btnCheck" of me to item 3 of pControlRect-4
set the right of fld "Cat" of me to the left of btn "btnCheck" of me
get the rect of fld "Line" of me
put the left of fld "Cat" of me into item 3 of it
set the rect of fld "Line" of me to it
put the formattedHeight of fld "Line" of me + item 2 of it into item 4 of it
set the rect of fld "Line" of me to it
put item 4 of it into item 4 of pControlRect
set the rect of graphic "Background" of me to pControlRect
end LayoutControl
To edit the LayoutControl script you need to open the datagrid property inspector and click on the Row Behavior... button. This will present the script editor for the behavior of the row template.
Because the DataGrid doesn't have this feature. If you would use the Geometry manager, the GM propeties are not copied from the checkbox in the template to the checkboxes in the actual DG. So, the GM won't work. Perhaps you could write a script of your own that sets the right of all checkboxes to a position relative to the width of the card:
on resizeStack
lock screen
repeat with x = 1 to number of buttons
if the style of btn x is "checkbox" then
set the right of btn x to the width of this cd - 100
end if
end repeat
unlock screen
end resizeStack
Unfortunately, this doesn't work with the datagrid either, because the DG also does some (or a lot) resizing of its own.
It would be much easier to create your own.

Resources