GUIHub ModuleScript

I made this Roblox module named GUIHub. I first designed it to make it easier to manage frame navigation within a GUI. Instead of keeping it to myself, I decided to let others use it as well. Please note that this is my first module that I’m publishing and I may not be the most experienced scripter so please give any feedback, it would be very appreciated.

Model:
GuiHub.rbxm (2.0 KB)

Code:

local hub = {}
hub.__index = hub

function hub.new(mainGui, frames)
	local self = setmetatable({}, hub)
	self.Main = mainGui
	self.Frames = frames
	self.ActiveFrames = {}
	
	for _, frame in pairs(self.Frames) do
		if frame.Visible then
			self.ActiveFrames[frame] = true
		end
	end
	
	return self
end

function hub:OpenFrame(frameName, disableOthers)
	local frame = self.Frames[frameName]
	if not frame then warn("Frame not found for "..frameName or "[no name provided]") return end
	
	if disableOthers then
		for otherFrame, _ in pairs(self.ActiveFrames) do
			if otherFrame ~= frame then
				otherFrame.Visible = false
				self.ActiveFrames[otherFrame] = nil
			end
		end
	end
	
	frame.Visible = true
	self.ActiveFrames[frame] = true
end

function hub:CloseFrame(frameName)
	local frame = self.Frames[frameName]
	if not frame then warn("Frame not found for "..frameName) return end
	
	frame.Visible = false
	self.ActiveFrames[frame] = nil
end

function hub:CloseAllFrames()
	for frame, _ in pairs(self.ActiveFrames) do
		frame.Visible = false
		self.ActiveFrames[frame] = nil
	end
end

function hub:Enter()
	self.Main.Enabled = true
end

function hub:Exit()
	self:CloseAllFrames()
	self.Main.Enabled = false
end

return hub

How to use:
After requiring the module, use .new(mainGUI, frames) make sure frames is a table of your desired frames.

Methods:
:OpenFrame(frameName, disableOthers) - Enables a specific frame, with the option to disable all others.

:CloseFrame(frameName) - Disables a specific frame.

:CloseAllFrames() - Disables all frames.

:Enter() - Enables the gui.

:Exit() - Disables the gui and all active frames.

Hi, i tested your module for a simple UI that I made:

Feedback

The video shows UI with tabs upon nested tabs, and the module makes it work with a simple API.

Having the optional disableOthers parameter in :OpenFrame() was really creative too.

The module has a small number of simple utility functions with names that provide clarity and perform their tasks without fluff. OOP is certainly one way to approach frame grouping and individual toggling, so exploring that option is good for your experience. The code is also written nicely and has clear structure :+1:

Limitations

You should get into typing and use a lot of assertions, but apart from that:

1. :Enter() and :Exit() are limited to ScreenGuis only. What if we wanted nested frames? LocalScripts within the gui that call :Exit() will disable the entire gui and stop all the code from running!!

Your module also excludes the possibility that the gui could also contain necessary buttons to toggle the frame itself, so calling :Exit() could make the toggle button invisible and never again accessible. Though I understand the module may not have been built for toggling the UI.

Video

2. frames parameter must be a dictionary in .new()? You mentioned “make sure frames is a table” when :OpenFrame() gets the frame by indexing:

function hub:OpenFrame(frameName, disableOthers)
	local frame = self.Frames[frameName]

This just confused me. We shouldn’t have to make a key for the frames parameter in .new() manually.

image

I think the module should simply use the frame’s name as a key. And if you go with this approach, also check for duplicates.

3. There is no re-entrancy protection for :OpenFrame(). If I call the method twice with the same frame name, it works when it shouldn’t. Since we’re just repeating the same action when the frame passed is already active, it’s just wasting memory executing everything in the method.

Statement

Personally, I would not use this in my projects since all it did for me was switch tabs. I understand this module was made for your UI and not as an all-rounder module. But overall, still pretty good for a module and for building experience!

1 Like

Thanks for the feedback! I’ve always struggled with tables and properly indexing them, so your advice really helped. I’ll take note of your suggestions and use them for future projects. Thank you for trying out my first module!