[v3!] TopbarPlus v3.0.0 | Construct intuitive topbar icons; customise them with themes, dropdowns, captions, labels and much more

Hi, you can achieve this with icon:lock(), icon:unlock() and the selected/deselected events. e.g:

local DEBOUNCE_TIME = 0.5
local heartbeat = game:GetService("RunService").Heartbeat
local debounceFunction = function(icon)
    heartbeat:Wait()
    icon:lock()
    wait(DEBOUNCE_TIME)
    icon:unlock()
end

icon:bindEvent("selected", debounceFunction)
icon:bindEvent("deselected", debounceFunction)

I’ll consider making this an official method in the future, thanks for the suggestion!

icon:setDebounce(0.5) -- defaults to 0
1 Like

Thanks for the help! Really appreciated!

Very nice script. I tried struggling at beginning creating topbar and always had scaling issues.

I got one question, i’m having issues with the icons. No errors in log. I used a valid asset id.

local weather = Icon.new()
weather:setRight()
weather:setOrder(4)
weather:lock()
weather:setImage(7041056258)

Try 7041056248 (its assetId) instead of 7041056258 (the websiteId)

1 Like

I really like this asset, I use on my personal projects and it’s pretty well made.

The only thing that I found kind of sad is that the syntax for Signals and things like that, could’ve been in PascalCase, just like Roblox events, so everyone’s code has similar syntax everywhere, and so that this, is consistent with Roblox naming and everything.

That is personal preference of course, and it’s not like this will change, not on this version, there’s no reason to, and would be worse, but if there was ever a v3 in the future, I feel like that could be something that could change if the team agrees on it.

For Instance, look at the difference here:

local function ToggleMenu()
    --\\ Pretend this handles menus with TweenService
end

--// camelCase:

Icon.new()
    :setCaption("Settings")
    :setLabel(123)
    :setOrder(2)
    .toggled:Connect(ToggleMenu)

--// PascalCase:

Icon.new()
    :SetCaption("Settings")
    :SetLabel(123)
    :SetOrder(2)
    .Toggled:Connect(ToggleMenu)


Other than that, I think something that could help me move away from :bindToggleItem to .toggled and mess with menus with TweenService, would be that .toggled is fired with (isToggled, icon) instead of (isToggled) only. That’s a change that wouldn’t break any code I believe. Correct me if I’m wrong though.

So you can have one function to handle all menus using less memory. I would love that!

TopbarPlus aims to follow the official Roblox Lua Styling guide which you can find here:

https://roblox.github.io/lua-style-guide/

Having a consistent formatting makes working with other open source modules/dependencies easier for everyone involved, hence most use camelCase. One notable project which doesn’t is AeroGameFramework, although this has created extra work for Sleitnick as it’s required him to convert modules like Evaera’s Promisie and various Nevemore modules (all camelCase) into PascalCase.

You’re welcome to create a fork which converts them into PascalCase although this won’t be something we maintain.

The toggled event only passes through a single argument, could you clarify what you mean by this?

2 Likes

By this I mean, that you would pass through self.isSelected, self instead of just self.isSelected.

That would mean I wouldn’t have to create a bunch of “intermediate” functions.

--\\ Here, .toggled fires with (isToggled)

local function SmoothToggleMenu(isToggled, icon)
    --\\ Pretend this uses TweenService to close and open menus.
end

local icon = Icon.new()
    :setCaption("Settings")
    :setLabel(123)
    :setOrder(1)

icon.toggled:Connect(function(isToggled)
    SmoothToggleMenu(isToggled, icon)
    --\\ Need to construct and connect a new function for every icon.
end)

And instead, I can just do this:

--\\ Here, .toggled fires with (isToggled, icon)

local function SmoothToggleMenu(isToggled, icon)
    --\\ Pretend this uses TweenService to close and open menus.
end

Icon.new()
    :setCaption("Settings")
    :setLabel(123)
    :setOrder(1)
    .toggled:Connect(SmoothToggleMenu)
    --\\ No need for constructing a new small function for every icon.

I suppose the memory use for just creating a function which calls another function with some extra arguments isn’t that big, but it’s also a question of syntax, I don’t need to set the icon to a variable, to THEN connect it.

That would make that way better organized and easier to handle.

1 Like

Ah gotcha, bindEvent does exactly this!

(It passes through (icon, ...))

local function SmoothToggleMenu(icon, isToggled)
    --\\ Pretend this uses TweenService to close and open menus.
end

Icon.new()
    :setCaption("Settings")
    :setLabel(123)
    :setOrder(1)
    :bindEvent("toggled", SmoothToggleMenu)
1 Like

Im getting an issue when a user resets after using the TopBarGui one time…

It says this after trying to open it after respawn -
image

I don’t understand one bit.

Here’s my layout -
image

It looks like you’re referencing UI objects which get destroyed because your GUIs have ResetOnSpawn set to false.

Two solutions:
1.Set ‘ResetOnSpawn’ to false for the GUIs you use with your icons
2. Move the localscript within the GUI and paste the following at the bottom:

local icons = IconController.getIcons()
for _, icon in pairs(icons) do
	IconController.clearIconOnSpawn(icon)
end
2 Likes

Hi how can i make it a gamepass for one of the topbar like when i click it the buy button will come down?

Hey there, you can achieve that with the icon ‘selected’ event and PromptGamePassPurchase:

local marketplaceService = game:GetService("MarketplaceService")
local localPlayer = game:GetService("Players").LocalPlayer

Icon.new()
    :bindEvent("selected", function(icon)
        local GAMEPASS_ID = 0
        marketplaceService:PromptGamePassPurchase(localPlayer, GAMEPASS_ID)
        icon:deselect()
    end)
1 Like

Hello, is there any way to access One Topbar button through two localscripts?

Or i could make an modulescript which will create the topbar button, then in the 2 localscripts.
Require it?

Yep you’ll want to construct and return the icon within a module, then reference that in both scripts.

Module:

local Icon = require(pathway.to.Icon.module)

return Icon.new()
    :setLabel("Hello this is an Icon")

Script 1:

local icon = require(pathway.to.moduleScript)

Script 2:

local icon = require(pathway.to.moduleScript)
2 Likes

Thank you, i didn’t know it was possible in the first place!
:grinning: :grinning:

Topbar suffers a spammy-overextension in the example place. Appears to be a confoundance between the tween and overflow behavior.
topBarConflict

I assume this is to say mouse detection is directly dictated by actual UI dimensions?
For instance, if you put your mouse right below a button that raises on mouseover, it would spam up and down, like a certain rust website I visited.

I thus make a feature request for underlying static boxes; have the flashy transition be only aesthetic in feed. (perhaps an argument, as I do understand a menu opening in size may want said growth of mouse interest while growing for cases like nested ribbon option lists)

1 Like

Good spot, that’s just missing a basic overflow hovering check, I’ll have that fixed now.

I’m not sure what you mean by this, could you provide some examples and explain it further? Thanks.

This has been fixed in the latest release:

4 Likes

Hi
I have an icon with a dropdown list. I noticed the state of icons in the dropdown gets removed when a new icon (outside the list) is clicked.
In other words: the icon under the dropdown that was selected is suddenly deselected.

Is there a way to disable this behavior?

Hi this should help:

1 Like