Change a Table Cell Property Based On a Positional Threshold
Some people wish to have their Table Cells change a certain property based on their position in the visible Table. From most use-cases it tends to be around changing the size of the elements inside the Cell.
Below you will find a download link to a sample application which demonstrates this desired behavior. Each Table Cell contains an Image and a Text Render Extension. As the Table is scrolled the Text’s Font Size, Alpha, and the Image’s Size will be dynamically adjusted. The closer to the center of the Table, the closer the property will be to the maximum value/full size assigned to it.
The implementation is a fairly simple one.
At a high level, every time the Table is scrolled, a Lua function calculates the distance between the center of each Table Cell and the center of the Table itself.
Using this delta value, it calculates a proportional value to be used for the properties (Font Size, Alpha, Image dimensions).
To explain in further detail:
When the Table’s grd.y_offset is changed (the Table is scrolled) it fires off an event called “table_offset_update”. When the Application receives this event, it calls a Lua function called cb_table_offset_update(). This function contains all the calculations and work required to make this behavior possible.
--- @param gre#context mapargs
function cb_table_offset_update(mapargs)
local data = {}
local y_pos
local percent
local alpha
local font_size
local image_width
local image_height
for i = 1, TABLE_ROWS do
y_pos = gre.get_table_cell_attrs("Layer.Table", i, 1, "y")
y_pos = y_pos["y"] + (CELL_HEIGHT / 2)
-- Clamp values outside the dimensions of the Table
if (y_pos < 0 or y_pos >= TABLE_HEIGHT) then
y_pos = 0
end
percent = 1 - (math.abs(TABLE_CENTER - y_pos) / TABLE_CENTER)
alpha = MAXIMUM_OPACITY * percent
font_size = math.min((MAX_FONT_SIZE * percent) + FONT_INCREMENTER, MAX_FONT_SIZE * percent)
font_size = math.max(font_size, 1)
image_width = IMG_MAX_WIDTH * percent
image_height = IMG_MAX_HEIGHT * percent
data[string.format("Layer.Table.text.%d.1", i)] = string.format("%0.f",alpha)
data[string.format("Layer.Table.alpha.%d.1", i)] = alpha
data[string.format("Layer.Table.fontSize.%d.1", i)] = font_size
data[string.format("Layer.Table.width.%d.1", i)] = image_width
data[string.format("Layer.Table.height.%d.1", i)] = image_height
gre.set_data(data)
end
end
To break this function down, it loops through each Cell and gets the current Y position of the center of the Cell.
for i = 1, TABLE_ROWS do
y_pos = gre.get_table_cell_attrs("Layer.Table", i, 1, "y")
y_pos = y_pos["y"] + (CELL_HEIGHT / 2)
…
Then it ensures the values being worked with are valid within the dimensions of the Table by clamping the values.
-- Clamp values outside the dimensions of the Table
if (y_pos < 0 or y_pos >= TABLE_HEIGHT) then
y_pos = 0
end
…
Then it calculates the delta between the center of the Cell and and the center of the Table.
Using this delta it calculates a percentage which represents the delta. This percentage value is from 0.0 to 1.
percent = 1 - (math.abs(TABLE_CENTER - y_pos) / TABLE_CENTER)
…
We leave the percentage in that format in order to be easily used in calculations.
At the top of the Lua file there are Global Variables which are set to the desired maximum value for each property. E.g. MAXIMUM_OPACITY is set to 255. Some of these variables are actually set in an initialize function which gets called on startup. This allows for some level of dynamism if we wished to change the dimensions of the Table and its Cells later down the road.
From here we can simply multiply the calculated percentage and each maximum value in order to determine the value to set the respective property to. Some special considerations have been made for the font size. In these calculations I preferred the way it looked when I added an extra 2px to it, this is what FONT_INCREMENTOR is for. Some use of Lua’s math library is seen here in order to ensure the value doesn’t exceed the maximum desired font size. There is also additional clamping to ensure the font doesn’t dip below a value of 1, as SBEngine does not consider this a valid value for font size.
alpha = MAXIMUM_OPACITY * percent
font_size = math.min((MAX_FONT_SIZE * percent) + FONT_INCREMENTOR, MAX_FONT_SIZE)
font_size = math.max(font_size, 1)
image_width = IMG_MAX_WIDTH * percent
image_height = IMG_MAX_HEIGHT * percent
…
And finally, set the values to the appropriate variables on the GDE.
In this case the Text is being assigned to the value being used for the Alpha, but we are truncating it to not show any decimal places.
data[string.format("Layer.Table.text.%d.1", i)] = string.format("%0.f",alpha)
data[string.format("Layer.Table.alpha.%d.1", i)] = alpha
data[string.format("Layer.Table.fontSize.%d.1", i)] = font_size
data[string.format("Layer.Table.width.%d.1", i)] = image_width
data[string.format("Layer.Table.height.%d.1", i)] = image_height
gre.set_data(data)
end
Please find the sample application here: Download Link
Comments
Please sign in to leave a comment.