Skip to content

Commit

Permalink
feat: implement special spinner icon for menus
Browse files Browse the repository at this point in the history
Allows menus to use `spinner` as an item icon, which will display a rotating spinner. Along with a no-op command on an item and `keep_open=true`, this can be used to display placeholder menus/items that are still loading.

Extracts spinner from `BufferingIndicator` into `ass:spinner()` utility.
  • Loading branch information
tomasklaen committed Oct 28, 2022
1 parent 59ac8af commit d8fad33
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 16 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@ When command value is a string, it'll be passed to `mp.command(value)`. If it's

Menu `type` controls what happens when opening a menu when some other menu is already open. When the new menu type is different, it'll replace the currently opened menu. When it's the same, the currently open menu will simply be closed. This is used to implement toggling of menus with the same type.

`item.icon` property accepts icon names. You can pick one from here: [Google Material Icons](https://fonts.google.com/icons?selected=Material+Icons)
`item.icon` property accepts icon names. You can pick one from here: [Google Material Icons](https://fonts.google.com/icons?selected=Material+Icons)\
There is also a special icon name `spinner` which will display a rotating spinner. Along with a no-op command on an item and `keep_open=true`, this can be used to display placeholder menus/items that are still loading.

When `keep_open` is `true`, activating the item will not close the menu. This property can be defined on both menus and items, and is inherited from parent to child if child doesn't overwrite it.

Expand Down
4 changes: 1 addition & 3 deletions scripts/uosc_shared/elements/BufferingIndicator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ function BufferingIndicator:render()
ass:rect(0, 0, display.width, display.height, {color = bg, opacity = 0.3})
local size = round(30 + math.min(display.width, display.height) / 10)
local opacity = (Elements.menu and not Elements.menu.is_closing) and 0.3 or 0.8
local opts = {rotate = (state.render_last_time * 1.75 % 1) * -360, color = fg, opacity = opacity}
ass:icon(display.width / 2, display.height / 2, size, 'autorenew', opts)
request_render()
ass:spinner(display.width / 2, display.height / 2, size, {color = fg, opacity = opacity})
return ass
end

Expand Down
15 changes: 10 additions & 5 deletions scripts/uosc_shared/elements/Menu.lua
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ function Menu:on_global_mbtn_left_up()
if math.abs(distance) > 50 then
self.current.fling = {
y = self.current.scroll_y, distance = distance, time = self.drag_data[#self.drag_data].time,
easing = ease_out_quart, duration = 0.5, update_cursor = true
easing = ease_out_quart, duration = 0.5, update_cursor = true,
}
end
end
Expand Down Expand Up @@ -669,10 +669,15 @@ function Menu:render()

-- Icon
if item.icon then
ass:icon(content_bx - (icon_size / 2), item_center_y, icon_size * 1.5, item.icon, {
color = font_color, opacity = text_opacity, clip = item_clip,
shadow = 1, shadow_color = shadow_color,
})
local x, y = content_bx - (icon_size / 2), item_center_y
if item.icon == 'spinner' then
ass:spinner(x, y, icon_size * 1.5, {color = font_color, opacity = text_opacity * 0.8})
else
ass:icon(x, y, icon_size * 1.5, item.icon, {
color = font_color, opacity = text_opacity, clip = item_clip,
shadow = 1, shadow_color = shadow_color,
})
end
content_bx = content_bx - icon_size - spacing
end

Expand Down
27 changes: 20 additions & 7 deletions scripts/uosc_shared/lib/ass.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

local ass_mt = getmetatable(assdraw.ass_new())

-- Opacity
-- Opacity.
---@param opacity number|number[] Opacity of all elements, or an array of [primary, secondary, border, shadow] opacities.
---@param fraction? number Optionally adjust the above opacity by this fraction.
function ass_mt:opacity(opacity, fraction)
Expand All @@ -20,7 +20,7 @@ function ass_mt:opacity(opacity, fraction)
end
end

-- Icon
-- Icon.
---@param x number
---@param y number
---@param size number
Expand All @@ -32,7 +32,7 @@ function ass_mt:icon(x, y, size, name, opts)
self:txt(x, y, opts.align or 5, name, opts)
end

-- Text
-- Text.
-- Named `txt` because `ass.text` is a value.
---@param x number
---@param y number
Expand Down Expand Up @@ -72,7 +72,7 @@ function ass_mt:txt(x, y, align, value, opts)
self.text = self.text .. '{' .. tags .. '}' .. value
end

-- Tooltip
-- Tooltip.
---@param element {ax: number; ay: number; bx: number; by: number}
---@param value string|number
---@param opts? {size?: number; offset?: number; bold?: boolean; italic?: boolean; width_overwrite?: number, responsive?: boolean}
Expand All @@ -89,7 +89,7 @@ function ass_mt:tooltip(element, value, opts)
self:txt(clamp(margin, x, display.width - margin), y, align_top and 2 or 8, value, opts)
end

-- Rectangle
-- Rectangle.
---@param ax number
---@param ay number
---@param bx number
Expand Down Expand Up @@ -123,7 +123,7 @@ function ass_mt:rect(ax, ay, bx, by, opts)
self:draw_stop()
end

-- Circle
-- Circle.
---@param x number
---@param y number
---@param radius number
Expand All @@ -134,7 +134,7 @@ function ass_mt:circle(x, y, radius, opts)
self:rect(x - radius, y - radius, x + radius, y + radius, opts)
end

-- Texture
-- Texture.
---@param ax number
---@param ay number
---@param bx number
Expand All @@ -155,3 +155,16 @@ function ass_mt:texture(ax, ay, bx, by, char, opts)
x, y, 7, lines,
{font = 'uosc_textures', size = tile_size, color = opts.color, bold = false, opacity = opacity, clip = clip})
end

-- Rotating spinner icon.
---@param x number
---@param y number
---@param size number
---@param opts? {color?: string; opacity?: number; clip?: string; border?: number; border_color?: string;}
function ass_mt:spinner(x, y, size, opts)
opts = opts or {}
opts.rotate = (state.render_last_time * 1.75 % 1) * -360
opts.color = opts.color or fg
self:icon(x, y, size, 'autorenew', opts)
request_render()
end

0 comments on commit d8fad33

Please sign in to comment.