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

image

my topbar buttons sometimes duplicate (using the new module)
is this a bug

1 Like

Thanks for this. I does look like its a part of roblox.

1 Like

Hey, so is it possible to make the icons not selectable or deselectable with debounce? Or is there another way?

Hello.
I’m making owner-only icon but it doesn’t show me. Here’s the script.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Modules = ReplicatedStorage:WaitForChild("Modules") -- Modules folder in ReplicatedStorage
local Icon = require(Modules:WaitForChild("Icon")) -- The Icon module
local OwnerOnly = Icon.new():setEnabled(false)
local SoundService = game:GetService("SoundService") -- Our click and hover sound
local Click = SoundService:WaitForChild("Click")
local Hover = SoundService:WaitForChild("Hover") 
-- Sound IDs
-- Hover = rbxassetid://4658309128
-- Click = rbxassetid://6706935653


game.Players.PlayerAdded:Connect(function(plr)
	if plr.Name == "nojuslopro123" --[[ My roblox username--]] then
		OwnerOnly:setEnabled(true)
	end
		
	
end)

OwnerOnly:bindEvent("hoverStarted", function(icon)
	Hover:Play()
end)

OwnerOnly.selected:Connect(function()
	Click:Play()
end)

OwnerOnly.deselected:Connect(function()
	Click:Play()
end)
2 Likes

Try putting with UserId instead of username

Well it doesn’t work.

local Modules = ReplicatedStorage:WaitForChild("Modules") -- Modules folder in ReplicatedStorage
local Icon = require(Modules:WaitForChild("Icon")) -- The Icon module
local OwnerOnly = Icon.new():setEnabled(false)
local SoundService = game:GetService("SoundService") -- Our click and hover sound
local Click = SoundService:WaitForChild("Click")
local Hover = SoundService:WaitForChild("Hover") 
-- Sound IDs
-- Hover = rbxassetid://4658309128
-- Click = rbxassetid://6706935653


game.Players.PlayerAdded:Connect(function(plr)
	if plr.UserId == 1471122583 --[[ My roblox id--]] then
		OwnerOnly:setEnabled(true)
	end


end)

OwnerOnly:bindEvent("hoverStarted", function(icon)
	Hover:Play()
end)

OwnerOnly.selected:Connect(function()
	Click:Play()
end)

OwnerOnly.deselected:Connect(function()
	Click:Play()
end)

Is it right?

1 Like

You can’t use PlayerAdded to retrieve the Player on the client as the player has already loaded in.
I recommend using Players.LocalPlayer to retrieve the player.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SoundService = game:GetService("SoundService") -- Our click and hover sound
local Players = game:GetService("Players")
local Modules = ReplicatedStorage:WaitForChild("Modules") -- Modules folder in ReplicatedStorage
local Icon = require(Modules:WaitForChild("Icon")) -- The Icon module
local Player = Players.LocalPlayer --Only works on LocalScripts
local Click = SoundService:WaitForChild("Click")
local Hover = SoundService:WaitForChild("Hover") 
-- Sound IDs
-- Hover = rbxassetid://4658309128
-- Click = rbxassetid://6706935653

if Player.UserId == 1471122583 then
	local OwnerOnly = Icon.new()

	--OwnerOnly:setEnabled(true)

	OwnerOnly:bindEvent("hoverStarted", function()
		Hover:Play()
	end)

	OwnerOnly.selected:Connect(function()
		Click:Play()
	end)

	OwnerOnly.deselected:Connect(function()
		Click:Play()
	end)
end
3 Likes

It Worked, Thank You

-- dont pay attention here.

Off-topic: ok i won’t even pay any attention at that lol

See TopbarPlus v2.9.1 | Construct intuitive topbar icons; customise them with themes, dropdowns, captions, labels and much more - #148 by ForeverHD

1 Like

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