Creating button on corona using one line) but adding the function fails - mobile

Been researching but no luck. Creating a button on Corona SDK requires several lines. (Corona SDK reference here). If you create 5 buttons the code grows a lot, so I created a function that I can call with just one liner and creates the buttons I need. It works fine but can't sort the events.
cbutton = function (nbutton, tbutton, blabel, bfs, bx, by)
bfcolor={default = { 51, 51, 51, 215 }}
if tbutton == "default-1" or tbutton == "default-2" or tbutton == "default-3" then bfcolor = nil end
local button1 = widget.newButton
{
defaultFile = "assets/" .. tbutton .. ".png",
overFile = "assets/o" .. tbutton .. ".png",
label = blabel,
labelColor = bfcolor,
fontSize = bfs,
emboss = true,
onPress=botonhrPress // <-- HERE, THIS PART
}
button1.x = bx; button1.y = by
end
cbutton("b1","primary-1","Create account", 20, 160, 160)
So, here is the thing.
The code above works, it creates the button.
Using the last line, calls the function and creates the button
It used the parameters
The part that says "HERE" works, ties the event to the button
BUT, it's directly written, can't pass parameters there
Tried concatenation, a full string variable with the name of the local function, also %, &, () and {} to enclose the data, no luck. If we can work around this part then we could create buttons with just one line of code + the function posted here. Any ideas will be appreciated, thanks in advance.

Related

create multiple tabs in a loop with scrollbard in tkinter

I want to create multiple tabs in a loop with scrollbars in tkinter. Somehow the scrollbar only works in the last tab with the following code:
for i in range(ParameterTabNumber):
z=ParameterTabs[i]
FrameParametersMain=Frame(MainNotebook, background="#FFFFFF", width=200, height=150)
FrameParametersMain.pack()
MainNotebook.add(FrameParametersMain, text=str(z))
my_FrameParametersMain.append(FrameParametersMain)
canvasParameters = Canvas(FrameParametersMain, highlightthickness=0,bg='#FFFFFFF')
canvasParameters.pack(side=LEFT, fill=BOTH, expand=1)
my_CanvasParameters.append(canvasParameters)
scrollbarParameters = Scrollbar(FrameParametersMain, orient=VERTICAL, command=canvasParameters.yview)
scrollbarParameters.pack(side=RIGHT, fill=Y)
my_scrollbarParameters.append(scrollbarParameters)
FrameParameters = Frame(canvasParameters)
my_TopTabs.append(FrameParameters)
canvasParametersWidgits = Canvas(FrameParameters, highlightthickness=0,bg='#FFFFFF',width=1700, height=1000)
canvasParametersWidgits.pack()
canvasParameters.create_window((0,0), window=FrameParameters, anchor="nw")
canvasParameters.configure(yscrollcommand=scrollbarParameters.set)
canvasParameters.bind('<Configure>',lambda e: canvasParameters.configure(scrollregion = canvasParameters.bbox("all")))
Can someone help me to get this working please?
Vielen Dank.
It is because you have used same variable canvasParameters inside the lambda. You should use e.widget instead:
canvasParameters.bind('<Configure>',lambda e: e.widget.configure(scrollregion = e.widget.bbox("all")))

dragAndDrop NOT working on Chrome

I am trying to perform a Drag and Drop operation on our Angular application using Protractor Jasmine. I am able to get hold of the source item but as the test runs, the source element gets selected but nothing happens thereafter; the drag and drop operation does not take place. There are no errors shown in the console.
An interesting thing about the destination container is that the items dropped here can be resized as per user wish. Also, there is no clearly marked place/area in the destination container where the dragged item will get dropped! But the container does have an ID; though that has still not helped here.
Here is the code:
let dragAndDrop = require('html-dnd').code;
.
.
.
function dragAndDropListItems(fdIndex: number): void {
let dragElement = element.all(by.repeater('listDefinition in lists')).get(fdIndex); // Select the first repeater corresponding to the first List Item in the list
let dragElementh5 = dragElement.all(by.css('a')).get(0); // Select the first List Item
let printFD = dragElementh5.getText().then((text: string) => {
console.log(text); // Print the innerHTML text from the chosen List Item to the Console
});
let finalDrop = element.all(by.css('[id="dashboardContainerDiv"]')).get(0);
dragElement.click();
browser.actions().dragAndDrop(dragElement, finalDrop).perform();
};
I have tried using coordinate based DragNDrop operation as well but the same in every case.
Other tried options include:
//browser.executeScript(dragAndDrop, dragElement, finalDrop); // Perform the drag and drop operation
//browser.driver.actions().dragAndDrop(dragElement, finalDrop).perform();
//browser.actions().dragAndDrop(dragElement, { x: 400, y: 400 }).perform();
// browser.driver.actions().mouseDown(dragElement).mouseMove(finalDrop).mouseUp(finalDrop).perform();
Kindly suggest a solution to this issue.
#FlorentB. I have attached the Code with your scripts imported.
let JS_DRAG_DROP = require('./drag-drop.js');
function dragAndDropListItems(fdIndex: number): void {
/*
let source = driver.find_element_by_css_selector("#drag")
target = driver.find_element_by_css_selector("#drop")
driver.execute_async_script(JS_DRAG_DROP, source, target)
# drag and drop an element by offset {x:500, y:200}
source = driver.find_element_by_css_selector("#drag")
driver.execute_async_script(JS_DRAG_DROP, source, None, 500, 200)
# drag and drop an element with a delay of 101ms before the drop
source = driver.find_element_by_css_selector("#drag")
target = driver.find_element_by_css_selector("#drop")
driver.execute_async_script(JS_DRAG_DROP, source, target, 0, 0, 101)
*/
let source = element.all(by.repeater('listDefinition in
lists')).get(fdIndex); // Select the first repeater corresponding to the
first List Item in the list
let dragElementh5 = source.all(by.css('a')).get(0); // Select the first List
Item
let printFD = dragElementh5.getText().then((text: string) => {
console.log(text); // Print the innerHTML text from the chosen List Item
to the Console
});
//browser.driver.switchTo().frame('dashboardContainerDiv');
/*
let finalDropClass = element.all(by.css('[class="dashboard mb10"]')).get(0);
let finalDropCon =
finalDropClass.all(by.css('[id="dashboardContainerDiv"]')).get(0);
let finalDrop =
finalDropCon.all(by.css('[id="dashboardContainerUl"]')).get(0);
*/
let target = element.all(by.css('[id="dashboardContainerDiv"]')).get(0);
//dragElement.click();
browser.executeScript(JS_DRAG_DROP, source, target); // Perform the drag and
drop operation
//browser.actions().dragAndDrop(dragElement, finalDrop).perform();
//browser.driver.actions().dragAndDrop(dragElement, finalDrop).perform();
//browser.actions().dragAndDrop(dragElement, { x: 400, y: 400 }).perform();
// browser.driver.actions().mouseDown(dragElement).mouseMove(finalDrop).mouseUp(finalDrop).perform();
};
Try
https://github.com/html-dnd/html-dnd
Installing it and using the typescript example worked for me.

How do I declare and call a function and array in Visual FoxPro 9.0

I'm trying to write a basic function that takes the values of 5 textboxes. I want to double the value of the first 2 Boxes to replace their former values with them and save the other 3 inside of an array. Then I want a for-loop to take the values inside of the array and get their sum in a new variable, which I want to display in a seperate TextBox.
Sorry for asking such an odd question but at the job I've just started it's tradition for apprentices to solves a bunch of these problems in FoxPro.
You could paste the following code into a new PRG, e.g. by typing Modify Command into the Command Window, and then paste it there.
LOCAL oForm as Form
oForm = CREATEOBJECT("TestForm")
oForm.Show(1)
RETURN
DEFINE CLASS TestForm as Form
AutoCenter = .T.
ADD OBJECT TextBox1 as TextBox WITH Left = 20, Top = 20, Value = 1
ADD OBJECT TextBox2 as TextBox WITH Left = 20, Top = 50, Value = 2
ADD OBJECT TextBox3 as TextBox WITH Left = 20, Top = 80, Value = 3
ADD OBJECT TextBox4 as TextBox WITH Left = 20, Top = 110, Value = 4
ADD OBJECT TextBox5 as TextBox WITH Left = 20, Top = 140, Value = 5
ADD OBJECT theOtherTextBox as TextBox WITH Left = 200, Top = 20
ADD OBJECT cmdTest as CommandButton WITH Left = 200, Top = 80
PROCEDURE cmdTest.Click
Thisform.TextBox1.Value = Thisform.TextBox1.Value * 2
Thisform.TextBox2.Value = Thisform.TextBox2.Value * 2
LOCAL ARRAY laTest[3]
STORE Thisform.TextBox3.Value TO laTest[1]
STORE Thisform.TextBox4.Value TO laTest[2]
STORE Thisform.TextBox5.Value TO laTest[3]
LOCAL lnSum, lnValue
lnSum = 0
FOR lnValue = 1 TO ALEN(laTest)
lnSum = m.lnSum + laTest[m.lnValue]
ENDFOR && or alternatively
lnSum = 0
FOR EACH lnValue IN laTest
lnSum = m.lnSum + m.lnValue
ENDFOR
Thisform.theOtherTextBox.Value = m.lnSum
ENDPROC
ENDDEFINE
FWIW, the code-as-text presentation is just for the browser demo - in a real VFP project, you'd probably rather design "visual" things in the visual Form or Class designers, good luck John Doe

Gideros event showing as null after being triggered

I have got Dispatched events in my gideros game. What im not certain of, is that when i try access the event (object triggered) it returns a table that has a length of 0.
I have a letter class as below:
GridLetter = gideros.class(Sprite)
function GridLetter:init(letter)
self.image = Bitmap.new(Texture.new("GridLetters/"..letter.."Grid.png"))
self.image:setAnchorPoint(0.5, 0.5)
self.focus = false
self:updateVisualState(true)
self:addEventListener(Event.MOUSE_DOWN, self.onMouseDown, self)
end
function GridLetter:onMouseDown(event)
if self:hitTestPoint(event.x, event.y) then
self.focus = true
self:dispatchEvent(Event.new("GridLetterDown"))
event:stopPropagation()
end
end
function GridLetter:updateVisualState(state)
if state then
self:addChild(self.image)
end
end
The code that implements this class is below:
grid = Core.class(Sprite)
local letterArr = {"a","b","c","d","e","f","g","h","u","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"}
local gridboard = {{},{},{},{}}
local letterBoxArr = {{},{},{},{}}
local letterBox
function grid:init(params)
local widthOfSingle = (application:getContentWidth() / 4)
for rowCount = 1,4 do
for colCount = 1,4 do
rand = math.random(1, 26)
gridboard[rowCount][colCount] = letterArr[rand]
end
end
for rowCount = 1,4 do
for colCount = 1,4 do
letterBox = GridLetter.new(gridboard[rowCount][colCount])
letterBoxArr[rowCount][colCount] = {letterBoxItem=letterBox}
letterBoxArr[rowCount][colCount].letterBoxItem:setPosition(((widthOfSingle * colCount) - (widthOfSingle / 2)), 100 * rowCount)
letterBoxArr[rowCount][colCount].letterBoxItem.letter = gridboard[rowCount][colCount];
letterBoxArr[rowCount][colCount].letterBoxItem:addEventListener("GridLetterDown", LetterDown, self)
self:addChild(letterBoxArr[rowCount][colCount].letterBoxItem)
end
end
end
function LetterDown(event)
print(event.target.letter)
end
When i click on one of these image, the event is fired and code does run under the LetterDown event, but when trying to access the event parameter, it returns:
grid.lua:32: attempt to index field 'target' (a nil value)
stack traceback:
grid.lua:32: in function <grid.lua:31>
GridLetter.lua:15: in function <GridLetter.lua:12>
any idea or workarounds?
When replacing:
print(event.target.letter)
to
print(event.x)
It prints nil.
I appreciate your help in advance.
Regards,
Warren
This isn't an answer (I'd comment, but that strangely requires rep).
The error you're getting is because in event, there's nothing in the target field.
You could find out what's in the table by looping over it (or by using a pretty table print function, if glideros defines one/you define one yourself):
for k, v in pairs(target) do print(k, v) end
If you're not sure if target will exist all the time, you can also do something like this:
print(not event.target and "event.target does not exist" or event.target.letter)
You can read about the A and B or C construct here: http://lua-users.org/wiki/TernaryOperator
Edit: Assuming that the event you receive fires with a GridLetter object, you are not setting self.letter to anything. Perhaps setting the field will help:
function GridLetter:init(letter)
self.letter = letter -- Forgot this?
self.image = Bitmap.new(Texture.new("GridLetters/"..letter.."Grid.png"))
self.image:setAnchorPoint(0.5, 0.5)
self.focus = false
self:updateVisualState(true)
self:addEventListener(Event.MOUSE_DOWN, self.onMouseDown, self)
end
I have got it.. Someone on gideros forums helped me out, thanks to Advert as well.
So in my onMouseDown event i was assigning the .letter on the general event. So creating a local var and assigning it the event before dispatching it, the variable then keeps my assigned letter.
Hope this helps others in future!
function GridLetter:onMouseDown(event)
if self:hitTestPoint(event.x, event.y) then
self.focus = true
local e = Event.new("GridLetterDown")
e.letter = self.letter
self:dispatchEvent(e)
event:stopPropagation()
end
end
Thanks for all responses.

Stopping physics body from movement in Corona SDK

I'm learning Corona SDK and I'm making small project in that purpose.
So, my problem is next one:
I managed to create 2 physics objects and make one of them "explode" when it collides with the other one. My question is how to make other object (it has linear impulse applied) stop when it collides? Also, when it stops, it has to be removed from the screen to avoid colliding with other objects...
Here is a part with removing first object on collision:
nloDrop = function()
local nlo = display.newImageRect("nlo.png", 65, 25)
nlo.x = 35 + mRand(410) ; nlo.y = -60
physics.addBody(nlo, "dynamic", {density=1, bounce = 0, friction = 0, filter = {maskBits = 4, categoryBits = 2}})
nlo:applyLinearImpulse(0, 0.8, nlo.x, nlo.y)
nlo.isSensor = true
nlo.collision = nloCollision
nlo:addEventListener("collision", nlo)
nlo.name = "nlo"
toFront()
end
And here is 'collision' function:
function nloCollision(self, event)
if ((event.other.myName == "weaponName") then
print("funkc")
self:removeSelf()
self:removeEventListener("collision", nlo)
self = nil
if weapon ~= nil then
-- stop moving of weapon
end
end
end
Thanks!
You can make the object bodyActive false and then it will not respond to physics. You cant remove a body from physics within the active screen so its a better option to keep that object out of the screen.
I made it setting the object like local variable and making a function that deletes/removes each variable (object) after some interaction or collision.
1st function contains object creating (that is a local type under function) and applying physics to that object.
2nd function contains deleting (self:removeSelf()) that works because each object is object for itself and when deleting it, physics stuff will continue to work because new local object is going to be created.
function create(event)
local weap1 = display.newImage("weap1.png", 0, 0)
weap1.x = turret.x ; weap1.y = turret.y
weap1.rotation = turret.rotation
weap1.collision = weap1Collision
weap1:addEventListener("collision", weap1)
physics.addBody(weap1, "dynamic", {density = 1, friction = 0, bounce = 0, filter = {maskBits = 2, categoryBits = 4}})
weap1:applyLinearImpulse(forceWeap1*xComp, forceWeap1*yComp, weap1.x, weap1.y)
function weap1Collision(self,event)
if (event.other.name == "collisionObject") then
self:removeSelf()
self:removeEventListener("collision", weap1)
self = nil
end
end
local type of variable (object) makes it work.
P.S.: vanshika, thanks for your answer, it's useful ;)

Resources