Page 1 of 2

These buttons execute the same callback but they are different tables!

Posted: Wed Oct 13, 2021 9:27 am
by WAWAWA
For some reason, I have two buttons. Only one is set to quit the game, but the second one also has the same callback even tho it is not defined?

My brain is frying right now, please help me.

This is the code for the game.

Code: Select all

local Button = require('libraries.button')

Button:setFont(love.graphics.newFont(16))
function love.load()
	button1 = Button.new(
		10, 10, 200, 30, 
		{255/255, 0, 0, 100/255}, 
		{255/255, 0, 0, 255/255}, 
		{255/255, 255/255, 255/255, 255/255}, 
		"Say random text"
	)

	button2 = Button.new(
		10, 60, 200, 30, 
		{255/255, 0, 0, 100/255}, 
		{255/255, 0, 0, 255/255}, 
		{255/255, 255/255, 255/255, 255/255}, 
		"Say random text"
	)

	button1.fn1 = function()
		love.event.quit(1)
	end
end

function love.update(dt)
	button1:update()
	button2:update()
end

function love.draw()
	love.graphics.clear()
	button1:draw()
	button2:draw()
end
If you want me to show the library code, I will do so aswell.

Code: Select all

local Button = {}

function Button:setFont(font)
	self.font = font
end

function Button.new(x, y, w, h, color, highlightColor, textColor, text, fn1, fn2, fn3)
	local newButton = {
		x = x, y = y,
		w = w, h = h,
		color = color, highlightColor = highlightColor, textColor = textColor,
		text = text, fn1 = fn1, fn2 = fn2, fn3 = fn3, highlighted = false
	}

	function newButton:update()
		local x, y, w, h = self.x, self.y, self.w, self.h
		local mouseX, mouseY = love.mouse.getPosition()

		if(mouseX > x and mouseY > y and mouseX < x + w and mouseY < y + h)then
			self.highlighted = true
		else
			self.highlighted = false
		end

		if(love.mouse.isDown(1))then
			if(self.fn1)then
				self.fn1()
				love.timer.sleep(0.1)
			end
		elseif(love.mouse.isDown(2))then
			if(self.fn2)then
				self.fn2()
				love.timer.sleep(0.1)
			end
		elseif(love.mouse.isDown(3))then
			if(self.fn3)then
				self.fn3()
				love.timer.sleep(0.1)
			end
		end
	end

	function newButton:draw()
		local gameWidth = love.graphics.getWidth()
		local gameHeight = love.graphics.getHeight()
		local x, y, w, h, color1, color2, color3, highlight, text, font = self.x, self.y, self.w, self.h, self.color, self.highlightColor, self.textColor, self.highlighted, self.text, Button.font

		local textWidth = font:getWidth(text)
		local textHeight = font:getHeight(text)

		if(highlight)then
			love.graphics.setColor(color2)
		else
			love.graphics.setColor(color1)
		end

		love.graphics.rectangle('fill', x, y, w, h)

		love.graphics.setColor(color3)
		love.graphics.print(
			text, font,
			x+10,h/2
		)
	end

	return newButton
end

return Button

Re: These buttons execute the same callback but they are different tables!

Posted: Wed Oct 13, 2021 9:42 am
by BrotSagtMist
Easy, you actually forgot to check positions and have no button at all, the function is executed everywhere in the window.
I guess you actually intended to put this inside the highlight part but forgot?

Re: These buttons execute the same callback but they are different tables!

Posted: Wed Oct 13, 2021 9:43 am
by MrFariator
The issue seems to be in your buttons' update() function. You check if a button is being highlighted, but then handle the clicks as though highlighting doesn't matter. As such, what's happening is that button1 is getting clicked regardless what you click on the screen. So you'll have to do this little change:

Code: Select all

function newButton:update()
  local x, y, w, h = self.x, self.y, self.w, self.h
  local mouseX, mouseY = love.mouse.getPosition()

  if(mouseX > x and mouseY > y and mouseX < x + w and mouseY < y + h)then
    self.highlighted = true
  else
    self.highlighted = false
    -- add this here; if we aren't highlighting the button, the function should return and not do anything else
    return
  end

  if(love.mouse.isDown(1))then
    if(self.fn1)then
      self.fn1()
      love.timer.sleep(0.1)
    end
  elseif(love.mouse.isDown(2))then
    if(self.fn2)then
      self.fn2()
      love.timer.sleep(0.1)
    end
  elseif(love.mouse.isDown(3))then
    if(self.fn3)then
      self.fn3()
      love.timer.sleep(0.1)
    end
  end
end
Of course, this means that any overlapping buttons will get their callbacks executed, so you'll have to watch out for that.

Re: These buttons execute the same callback but they are different tables!

Posted: Wed Oct 13, 2021 11:26 am
by WAWAWA
BrotSagtMist wrote: Wed Oct 13, 2021 9:42 am Easy, you actually forgot to check positions and have no button at all, the function is executed everywhere in the window.
I guess you actually intended to put this inside the highlight part but forgot?
Oh gosh, I was so dumb :cry:

Re: These buttons execute the same callback but they are different tables!

Posted: Wed Oct 13, 2021 11:28 am
by WAWAWA
MrFariator wrote: Wed Oct 13, 2021 9:43 am The issue seems to be in your buttons' update() function. You check if a button is being highlighted, but then handle the clicks as though highlighting doesn't matter. As such, what's happening is that button1 is getting clicked regardless what you click on the screen. So you'll have to do this little change:

Code: Select all

function newButton:update()
  local x, y, w, h = self.x, self.y, self.w, self.h
  local mouseX, mouseY = love.mouse.getPosition()

  if(mouseX > x and mouseY > y and mouseX < x + w and mouseY < y + h)then
    self.highlighted = true
  else
    self.highlighted = false
    -- add this here; if we aren't highlighting the button, the function should return and not do anything else
    return
  end

  if(love.mouse.isDown(1))then
    if(self.fn1)then
      self.fn1()
      love.timer.sleep(0.1)
    end
  elseif(love.mouse.isDown(2))then
    if(self.fn2)then
      self.fn2()
      love.timer.sleep(0.1)
    end
  elseif(love.mouse.isDown(3))then
    if(self.fn3)then
      self.fn3()
      love.timer.sleep(0.1)
    end
  end
end
Of course, this means that any overlapping buttons will get their callbacks executed, so you'll have to watch out for that.
I am so stressed out with this game idea that I forgot to type that in.

Re: These buttons execute the same callback but they are different tables!

Posted: Wed Oct 13, 2021 11:38 am
by BrotSagtMist
Add a variable that is set true in love.mousemoved + mousepressed.
Then wrap the update in it:

Code: Select all

function love.update(dt)
 if var then
	button1:update()
	button2:update()
        var=nil
 end	
end
That saves you a bit of cpu.
It also solves double clicks more elegant.

Re: These buttons execute the same callback but they are different tables!

Posted: Thu Oct 14, 2021 5:41 am
by WAWAWA
oh gosh thanks. Right now I am making textboxes so wish me luck.

Re: These buttons execute the same callback but they are different tables!

Posted: Thu Oct 14, 2021 7:59 am
by darkfrei
Make it sense to store all functions of the object in the table?
So

Code: Select all

function new_object (x,y)
  local obj = {x=x,y=y}
  obj.functions = functions
end
So update is

Code: Select all

obj.functions:update (dt)

Re: These buttons execute the same callback but they are different tables!

Posted: Thu Oct 14, 2021 10:24 am
by WAWAWA
Hey, would you guys help me with my question at the LOVE Terminal library topic? I'll send a link. https://love2d.org/forums/viewtopic.php ... 39#p244139

Re: These buttons execute the same callback but they are different tables!

Posted: Thu Oct 14, 2021 11:54 am
by BrotSagtMist

Code: Select all

  Line="textblabla"
  --adding a letter:
  a,b=string.match(Line, "("..utf8.charpattern:rep(position)..")(.*)")
  Line=a..Letter..b
  --removing a letter:
  a,_,b=string.match(Line, "("..utf8.charpattern:rep(position-1)..")("..utf8.charpattern..")(.*)")
  Line=a..b
  --Draw cursor: 
  love.graphics.print("|", font:getWidth(a),linenumber*fontheigh)