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

0

Comments

0 comments

Please sign in to leave a comment.

Didn't find what you were looking for?

New post