Widget setFillColor always black

I’ve created a widget button and assigned color to it as part of its creation. I have no problems setting the color during the creation. eg.

 local myButton = widget.newButton(
    {
      id="myBtn",
      label="originalText",
      onEvent = changeMyColor,
      shape="rect",
      fillColor={ default={1,0,0}, over={1,0,0,0.5} },
      strokeColor={ default={1,0,0}, over={1,0,0,0.5} },
      strokeWidth=1,
      width=100,
      height=50,
      x=display.contentCenterX, 
      y=display.contentCenterY,
    }
  )

On a touch event, I would like to call a function that changes the text and the color for the widget. I have no problems changing the text using event.target:setLabel("[newTextHere]"). However, setFillColor doesn’t seem to work. It always changes the fill color to black.
eg.

local function changeMyColor(event)
  event.target.setLabel("NewText")
  event.target:setFillColor({ default={0,1,0}, over={0,1,0,0.5} })
end

After this function is called, the text changes as expected, but the fill color becomes black, despite the values representing green.

Any advice welcome.

setFillColor takes (r,g,b,a) values; by passing a table it’ll just set the color to 0.

If you want to change the over color then you’ll need to change the internal values directly as I don’t think there’s a function to set that value post button creation.

local function changeMyColor(event)
  event.target:setLabel("NewText")
  event.target._view._fillColor={ default={0,1,0}, over={0,1,0,0.5} }
end

Thank you so much, Siu.

And, oh, I feel silly. I had initially thought that was the case. But even then, when not including an ‘over’ colour, I had been passing a table anyway. ie. I had tried:
event.target:setFillColor({0,1,0})

instead of
event.target:setFillColor(0,1,0)

Simple mistake, but I had spent hours trying different variations and looking for advice online. You’ve saved my day!

1 Like

Hello,

It happens to me as well, and the documentation mentions that you can set the default and the over when adding the row, as you can see in the following example (I have it the same way and it always appears with the over on a black background, it only takes into account the alpha value of the over, not the color):

Solar2D Documentation — API Reference | type | TableViewWidget | insertRow (coronalabs.com)

-- Insert 40 rows
for i = 1, 40 do
 
    local isCategory = false
    local rowHeight = 36
    local rowColor = { default={ 1, 1, 1 }, over={ 1, 0.5, 0, 0.2 } }
    local lineColor = { 0.5, 0.5, 0.5 }
 
    -- Make some rows categories
    if ( i == 1 or i == 21 ) then
        isCategory = true
        rowHeight = 40
        rowColor = { default={ 0.8, 0.8, 0.8, 0.8 } }
        lineColor = { 1, 0, 0 }
    end
 
    -- Insert a row into the tableView
    tableView:insertRow(
        {
            isCategory = isCategory,
            rowHeight = rowHeight,
            rowColor = rowColor,
            lineColor = lineColor,
            params = {}  -- Include custom data in the row
        }
    )
end

I would appreciate it if you could help me set the start value when inserting the row.
Thank you very much.

Hi!

Looks like it’s not working for tableView as you mentioned; not sure why and couldn’t find the issue at some glance, but here’s a workaround:

-- Create the widget as usual.
local tableView = widget.newTableView({
	left = 0,
	top = 0,
	height = 330,
	width = 300,
	onRowRender = onRowRender,
	onRowTouch = onRowTouch,
	listener = scrollListener
  })

-- Add a new function to update row colors.
tableView.setRowColor = function(self_, key_, colors_, reload_)
	-- key_ : table key to update; "default" or "over"
	-- colors_ : table containing RGB or RGBA values; {R,G,B} or {R,G,B,A}
	-- reload_ : refrehses view to see row color update instantly; true, false or nil (only usable when updating "default" colors)

	local tableRows = self_._view._rows
	for i=1, #tableRows do
		if not tableRows[i].isCategory then
			tableRows[i]._rowColor[key_] = colors_
		end
	end
	if reload_ then
		self_:reloadData()
	end
end
 
-- Insert rows as usual.
for i = 1, 40 do
	local isCategory = false
	local rowHeight = 36
	local rowColor = { default={1,1,1}, over={1,0.5,0,0.2} }
	local lineColor = { 0.5, 0.5, 0.5 }

	-- Make some rows categories
	if ( i == 1 or i == 21 ) then
		isCategory = true
		rowHeight = 40
		rowColor = { default={0.8,0.8,0.8,0.8} }
		lineColor = { 1, 0, 0 }
	end

	-- Insert a row into the tableView
	tableView:insertRow({
		isCategory = isCategory,
		rowHeight = rowHeight,
		rowColor = rowColor,
		lineColor = lineColor,
		params = {}  -- Include custom data in the row
	})
end	

-- Update the "default" color for each row and force refresh to see color update immediately.
tableView:setRowColor("default", {0, 1, 1, 1}, true)

-- Update the "over" color for each row.
tableView:setRowColor( "over", { 0, 1, 0 , 1 } )

If you’re interested in changing color directly for a specific row then you can do:

-- Add function to update specific row color using setFillColor.
tableView.updateRowColor = function(self_, rowIndex_, colors_)
	if self_._view._rows[rowIndex_] then
		self_._view._rows[rowIndex_]._view._cell:setFillColor(unpack(colors_))
        self_._view._rows[rowIndex_]._rowColor["default"] = colors_ -- keeps color persistent when row is redrawn.
	end
end

-- Update row color at index 3.
tableView:updateRowColor( 3, {1, 0.5 , 1} )