In my corona aplication, I've a widget button to move an image. I was able to find the onPress method, but failed to find a method to check whether the button is still pressed. So that user don't have to tap the same button over and over again for moving the image...
Code:
function move( event )
local phase = event.phase
if "began" == phase then
define_robo()
image.x=image.x+2;
end
end
local movebtn = widget.newButton
{
width = 50,
height = 50,
defaultFile = "left.png",
overFile = "left.png",
onPress = move,
}
Any help is appreciable...
If your question is that you would like to know when the user's finger is moved, or when he releases the button, you can add handlers for those events:
"moved" a finger moved on the screen.
"ended" a finger was lifted from the screen.
"began" only handles when he starts touching the screen.
So your move function would be like:
function move( event )
local phase = event.phase
if "began" == phase then
define_robo()
image.x=image.x+2;
elseif "moved" == phase then
-- your moved code
elseif "ended" == phase then
-- your ended code
end
end
-- Updated according to comment:
Use this, replacing nDelay by the delay between each move, and nTimes by the number of times you wanna do the move:
function move( event )
local phase = event.phase
if "began" == phase then
local nDelay = 1000
local nTimes = 3
define_robo()
timer.performWithDelay(nDelay, function() image.x=image.x+2 end, nTimes )
end
end
Try this:
local image = display.newRect(100,100,50,50) -- Your image
local timer_1 -- timer
local function move()
print("move...")
image.x=image.x+2;
timer_1 = timer.performWithDelay(10,move,1) -- you can set the time as per your need
end
local function stopMove()
print("stopMove...")
if(timer_1)then timer.cancel(timer_1) end
end
local movebtn = widget.newButton {
width = 50,
height = 50,
defaultFile = "obj1.png",
overFile = "obj1.png",
onPress = move, -- This will get called when you 'press' the button
onRelease = stopMove, -- This will get called when you 'release' the button
}
Keep coding................ :)
Related
I'm trying to implement ALT + TAB behaviour.
I want to know when a user is holding the ALT key.
Why does this release function not work?
awful.key(
{},
'Alt_L',
function()
altHold = true
end,
function()
altHold = false
end
),
IMPRACTICAL SOLUTION:
awful.key(
{},
'Alt_L',
function()
altHold = true
end
),
awful.key(
{'Mod1'},
'Alt_L',
nil,
function()
altHold = false
end
)
This works, but any other hotkeys with ALT no longer work.
OTHER SOLUTION:
keygrabber.run(
function (mod, key, event)
-- Stop alt-tabbing when the alt-key is released
if gears.table.hasitem(mod, "Mod1") then
if (key == "Alt_L" or key == "Escape") and event == "release" then
-- Make it visible
if key == "Escape" then
-- Cancel client selection
end
else
-- Raise clients in order to restore history
-- raise chosen client on top of all
-- restore minimized clients
end
end
keygrabber.stop()
-- Pressed tab
elseif key == "Tab" and event == "press" then
if gears.table.hasitem(mod, "Shift") then
-- Move to previous client on Shift-Tab
cyclePreview(-1)
else
-- Move to next client on each Tab-press
cyclePreview( 1)
end
end
end
end
)
This is a slightly modified version from Troglobit:
https://github.com/troglobit/awesome-switcher/blob/master/init.lua#L470-L525\
This gets called when ALT + TAB is pressed.
While holding ALT, the next TAB press calls previewCycle() function.
If ALT is released it selects the chosen client.
ESCAPE cancels the selection.
Random guess: When the key is released, the "alt" modifier is active, so you need a keybinding with Mod1 as modifier (is Alt Mod1? I'm not entirely sure). But of course, that key binding would then not react to key presses, so you need two.
I have a widget.newScrollView component and a widget.newButton in front of it. Unfortunately when i click my button it also calls my ScrollView "tap" handler. How do i stop my ScrollView from getting this event?
Here is some of the code I'm using:
local function handleButtonEvent( event )
if ( "ended" == event.phase ) then
print( "Button was pressed and released" )
end
return true; **I tried this - but it had no effect**
end
added
local button1 = widget.newButton(
{
label = "button",
onEvent = handleButtonEvent,
emboss = false,
shape = "roundedRect",
width = 400,
height = 100,
cornerRadius = 32,
fillColor = { default={1,0,0,1}, over={1,0.1,0.7,1} },
strokeColor = { default={1,0.4,0,1}, over={0.8,0.8,1,1} },
strokeWidth = 4,
fontSize=100;
}
I've got an array (planets) of display.NewImages and my handler - like this:
local planets = {};
planets[1] = display.newImage( "planetHexs/001.png", _topLeft_x, _topLeft_y);
planets[2] = display.newImage( "planetHexs/002.png", _topLeft_x, _topLeft_y + _planet_height2 );
....
local scrollView = widget.newScrollView(
{
top = 0,
left = 0,
width = display.actualContentWidth,
height = display.actualContentHeight,
scrollWidth = 0,
scrollHeight = 0,
backgroundColor = { 0, 0, 0, 0.5},
verticalScrollDisabled=true;
}
for i = 1, #planets do
local k = planets[i];
scrollView:insert( k )
end
function PlanetTapped( num )
print( "You touched the object!"..num );
end
for i = 1, #planets do
local k = planets[i];
k:addEventListener( "tap", function() PlanetTapped(i) end )
end
I get this print log:
Button was pressed and released
You touched the object2
You must return true on your event functions to prevent propagation. This essentially tells Corona that the event was handled correctly and that no more event listeners for that event should be fired. You can read more about event propagation here in the docs.
"tap" and "touch" events are handled with different listeners, so if you wish to stop taps when you touch the button, you will have add a "tap" listener to your button as well, that essentially just returns true to prevent, or block tap events to anything behind it.
button1:addEventListener("tap", function() return true end)
Since the button does not have a tap event, tap events simply go through the button, to any objects behind it which do have a "tap" event.
When I switch to another tag, a new client gets selected, but it is sometimes not a client that I have my mouse cursor over. To get a client under my mouse pointer focused, I have to either click somewhere on it, or switch to it with Mod4+j / k, or move mouse cursor out and back on that client.
I want awesome to give focus to a client that is under the mouse cursor whenever a tag is changed. How do I do that?
I found a function mouse.object_under_pointer() that finds the client I need, but I don't know when to call that function. Should I connect a handler to some particular signal? I tried connecting to various signals from Signals page on the wiki and checking with naughty.notify() if that is the right signal, but none of them were triggered when I was switching between tags.
This code did the trick, however there should be a better way to do this than setting up a huge 200 ms timer (smaller timeouts didn't properly focus some clients for me, but you can try setting a smaller one).
tag.connect_signal(
"property::selected",
function (t)
local selected = tostring(t.selected) == "false"
if selected then
local focus_timer = timer({ timeout = 0.2 })
focus_timer:connect_signal("timeout", function()
local c = awful.mouse.client_under_pointer()
if not (c == nil) then
client.focus = c
c:raise()
end
focus_timer:stop()
end)
focus_timer:start()
end
end
)
tag is this global object, so you should just place this code anywhere in your rc.lua.
Two things should be done:
First, you should remove require("awful.autofocus") from your config, so that this module no longer tries to focus some client via the focus history when you switch tags.
Then, this code works for me:
do
local pending = false
local glib = require("lgi").GLib
tag.connect_signal("property::selected", function()
if not pending then
pending = true
glib.idle_add(glib.PRIORITY_DEFAULT_IDLE, function()
pending = false
local c = mouse.current_client
if c then
client.focus = c
end
return false
end)
end
end)
end
This uses GLib directly to get a callback for when no other events are pending. This should mean that "everything else" was handled.
I know this is pretty old, but it helped me to come up with this
function focus_client_under_mouse()
gears.timer( { timeout = 0.1,
autostart = true,
single_shot = true,
callback = function()
local n = mouse.object_under_pointer()
if n ~= nil and n ~= client.focus then
client.focus = n end
end
} )
end
screen.connect_signal( "tag::history::update", focus_client_under_mouse )
What is the easiest way to make button to *.lua file?
I want to make something like : main.lua (tap button) --> scene1.lua (BACK tap button) --> main.lua
I tried something like this:
local storyboard = require ("storyboard")
local scene = storyboard.newScene()
local logo tlo = display.newImage("bg.png", 360, 640)
local zamow = display.newImage("1zamow.png", 185, 340)
local gadgety= display.newImage("2gadgety.png", 535, 340)
local facebook = display.newImage("3facebook.png", 185, 700)
local oferta = display.newImage("4oferta.png", 535, 700)
local cennik = display.newImage("5cennik.png", 185, 1060)
local kontakt = display.newImage("6kontakt.png", 535, 1060)
function cennik:touch (event)
storyboard.gotoScene("cennik", "fade", 400)
end
cennik:addEventListener( "touch", cennik )
return scene'
after that I have runtime error:
attempt to concatenate global 'sceneName' (a nil value)
I'm new one in Corona so please be nice :)
Its better to use widget for creating button. If cennik is your button image and scene1.lua is the next page, then code be written as
local storyboard = require ("storyboard")
local widget=require "widget"
local scene=storyboard.newScene()
local logotlo = display.newImage("bg.png", 360, 640)
local zamow = display.newImage("1zamow.png", 185, 340)
local gadgety= display.newImage("2gadgety.png", 535, 340)
local facebook = display.newImage("3facebook.png", 185, 700)
local oferta = display.newImage("4oferta.png", 535, 700)
local kontakt = display.newImage("6kontakt.png", 535, 1060)
local cennikBtn
local function onStartButtonRelease()
storyboard:gotoScene("scene1")
end
cennikBtn = widget.newButton {
defaultFile="5cennik.png",
onRelease=onStartButtonRelease
}
cennikBtn.x,cennikBtn.y =185, 1060
function scene:createScene(event)
local group = self.view
group:insert(logotlo)
group:insert(zamow)
group:insert(gadgety)
group:insert(facebook)
group:insert(oferta)
group:insert(kontakt)
group:insert(cennikBtn)
end
function scene:enterScene( event )
local group = self.view
end
function scene:exitScene( event )
local group = self.view
storyboard.removeScene("main")
end
function scene:destroyScene( event )
local group = self.view
end
scene:addEventListener( "createScene", scene )
scene:addEventListener( "enterScene", scene )
scene:addEventListener( "exitScene", scene )
scene:addEventListener( "destroyScene", scene )
return scene
Your code looks fine except for the ' after return scene and your event handler needs to be like this:
-- For each time you tap the image, this event gets triggered twice. Make sure you only dispatch your gotoScene once!
function cennik:touch(event)
if event.phase == "began" then
-- This happens on finger touching
elseif event.phase == "ended" then
-- This happens when the finger is lifted
storyboard.gotoScene("cennik", "fade", 400)
end
-- if you want to prevent the touch event from propagating (aka triggering other images touch event) you must return true
return true
end
I am trying to remove onEvent listener from button widget. I tried to assign nil to onEvent attribute but it didn't work and lastly I tried this:
buttonWidget : removeEventListener("touch", buttonWidget.onEvent)
I have several button like that and it just stopped all button's event listeners. What do you suggest? How can I remove the event listener for one button widget? Thanks.
Here is how I create my button widgets:
for i=0,2 do
for j=0,8 do
count=count+1
letterBtn[count] = widget.newButton{
id = alphabet[count],
left = 5+j*50,
top = H-160+i*50,
label = alphabet[count],
width = 45,
height = 45,
font = nil,
fontSize = 18,
labelColor = { default = {0,0,0}, over = {255,255,255}},
onEvent = btnOnEventHandler
};
end
end
Can you tell me how can I remove onEvent later?
Okey, I tried Button: setEnabled(false) but still it disables all buttons not just one. I already tried your second advice but it gives the same result. I am copying the rest of the code. Can you please look at it and tell me what I am missing?
local function checkLetter(e)
if(guessWord) then
for i=1, #guessWord do
local c = guessWord:sub(i,i)
if c==e.target.id then
letter[i].text = e.target.id
letterCount = letterCount +1
print("letterCount"..letterCount)
e.target:setEnabled(false)
end
end
if (letterCount == #guessWord and not hanged) then
timer.performWithDelay(500, function()
letterCount=0
rightWGuess = rightWGuess+1
for k,v in pairs(notGuessedWord) do
if v == guessWord then
notGuessedWord[k]=nil
end
end
enableButtons()
startGame() end ,1)
end
end
end
local function btnOnEventHandler(e)
if(e.phase == "began") then
checkLetter(e)
print(e.target.id)
end
return true
end
If you want to temporarily (or permanently) stop a button from responding to touch events, you can use Button:setEnabled(false).
The following worked for me for removing a listener from just 2 buttons. Button 1 and 3 stopped responding to events as expected while 2, 4, and 5 still did.
Update: To disable, you have to do it on the 'ended' phase or Corona gets confused.
widget = require 'widget'
local function btnOnEventHandler(event)
print('Event', event.target.id, event.phase)
if event.phase == 'ended' then
-- Disable the button so it can't be clicked again
-- Must disable in the end state or Corona gets
-- confused
event.target:setEnabled(false)
end
end
local buttons = {}
for i=1,5 do
buttons[i] = widget.newButton{
id = 'button' .. i,
left = display.contentCenterX - 50,
top = 60 * i,
label = 'Button ' .. i,
width = 100,
height = 50,
onEvent = btnOnEventHandler
}
end
buttons[1]:removeEventListener('touch', buttons[1].onEvent)
buttons[3]:removeEventListener('touch', buttons[3].onEvent)