Skip to content

Commit 95f8350

Browse files
committed
Add customizability
1 parent 719f56d commit 95f8350

File tree

8 files changed

+386
-142
lines changed

8 files changed

+386
-142
lines changed

lsp_def/classes/tab.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
---@class SMODS.Tab: SMODS.GameObject
44
---@field order number Sets the order. `Tab` objects in a group are displayed left to right from lowest to highest order.
5-
---@field tab_group string The name of the group to add the tab to. Tabs in the same tab group will be displayed on the same UIBox.
5+
---@field tab_dialog string The key of the dialog to add the tab to. Tabs in the same tab dialog will be displayed when that dialog is rendered, if the tabs are visible.
66
---@field chosen? boolean Whether the tab is the one initially selected in the tab group. The leftmost (lowest order) tab with chosen set to true is the default tab.
77
---@field conditions? table<string, any> Table of conditions. This object will not draw if any condition is not `true` when evaluated.
88
---@field __call? fun(self: SMODS.Tab|table, o: SMODS.Tab|table): nil|table|SMODS.Tab
@@ -19,7 +19,7 @@
1919
---@field inject? fun(self: SMODS.Tab|table, i?: number) Called during `inject_class`. Injects the object into the game.
2020
---@field take_ownership? fun(self: SMODS.Tab|table, key: string, obj: SMODS.Tab|table, silent?: boolean): nil|table|SMODS.Tab Takes control of vanilla objects. Child class must have get_obj for this to function
2121
---@field get_obj? fun(self: SMODS.Tab|table, key: string): SMODS.Tab|table? Returns an object if one matches the `key`.
22-
---@field func? fun(self: SMODS.Tab|table) Handles generating the contents of the `Tab`. Must return a UI table starting from a G.UIT.ROOT element.
22+
---@field func? fun(self: SMODS.Tab|table): UINode Handles generating the contents of the `Tab`. Must return a UI table starting from a G.UIT.ROOT element.
2323
---@field is_visible? fun(self: SMODS.Tab|table, args: table): boolean? If undefined or nil, the tab is always visible. Otherwise must be a function that returns true if the tab should be visible. Args are the table of arguments passed to the tab group function.
2424
---@overload fun(self: SMODS.Tab): SMODS.Tab
2525
SMODS.Tab = setmetatable({}, {

lsp_def/classes/tab_dialog.lua

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---@meta
2+
3+
---@class SMODS.TabDialog: SMODS.UIBox
4+
---@field key string The key of this TabDialog. Tabs with a matching tab_dialog field will be displayed in this tab dialog.
5+
---@field g_funcs? table Array of member functions to add to G.FUNCS.
6+
---@field back_button? string Controller button for backing out of the UIBox.
7+
---@field back_colour? table HEX color fill of the back button.
8+
---@field back_delay? number Button delay for the back button.
9+
---@field back_id? string ID for the back button.
10+
---@field back_label? string Localization key for the label on the back button.
11+
---@field bg_colour? table Background color for the UIBox
12+
---@field colour? table Inner background color for the UIBox
13+
---@field minw? number The minimum width of the UIBox.
14+
---@field no_back? boolean Whether to hide the back button for the UIBox.
15+
---@field no_pip? boolean Whether to prevent the creation of a binding controller pip on the back button.
16+
---@field outline_colour? table Colour for the outline between the background and inner background.
17+
---@field padding? number Padding value around the contents of the UIBox.
18+
---@field snap_back? boolean Whether to snap the controller to the back button.
19+
---@field content_alignment? string Alignment of the tab contents within the UIBox.
20+
---@field content_minh? number Minimum height for the tab contents container.
21+
---@field content_minw? number Minimum width for the tab contents container.
22+
---@field content_padding? number The padding of the tab contents.
23+
---@field no_loop? boolean Disables shoulder buttons looping around on controllers when switching tabs.
24+
---@field no_shoulders? boolean Disables shoulder buttons on controllers from switching tabs.
25+
---@field opt_callback? boolean = nil,
26+
---@field scale? number The scale of the tab buttons.
27+
---@field snap_to_nav? boolean Whether to snap the controller to the navigation buttons (tabs)
28+
---@field tab_colour? table Background color of the tab buttons.
29+
---@field text_scale? number The scale of the text on the tab buttons.
30+
---@field __call? fun(self: SMODS.TabDialog|table, o: SMODS.TabDialog|table): nil|table|SMODS.TabDialog
31+
---@field extend? fun(self: SMODS.TabDialog|table, o: SMODS.TabDialog|table): table Primary method of creating a class.
32+
---@field check_duplicate_register? fun(self: SMODS.TabDialog|table): boolean? Ensures objects already registered will not register.
33+
---@field check_duplicate_key? fun(self: SMODS.TabDialog|table): boolean? Ensures objects with duplicate keys will not register. Checked on `__call` but not `take_ownership`. For take_ownership, the key must exist.
34+
---@field register? fun(self: SMODS.TabDialog|table) Registers the object.
35+
---@field check_dependencies? fun(self: SMODS.TabDialog|table): boolean? Returns `true` if there's no failed dependencies.
36+
---@field process_loc_text? fun(self: SMODS.TabDialog|table) Called during `inject_class`. Handles injecting loc_text.
37+
---@field send_to_subclasses? fun(self: SMODS.TabDialog|table, func: string, ...: any) Starting from this class, recusively searches for functions with the given key on all subordinate classes and run all found functions with the given arguments.
38+
---@field pre_inject_class? fun(self: SMODS.TabDialog|table) Called before `inject_class`. Injects and manages class information before object injection.
39+
---@field post_inject_class? fun(self: SMODS.TabDialog|table) Called after `inject_class`. Injects and manages class information after object injection.
40+
---@field inject_class? fun(self: SMODS.TabDialog|table) Injects all direct instances of class objects by calling `obj:inject` and `obj:process_loc_text`. Also injects anything necessary for the class itself. Only called if class has defined both `obj_table` and `obj_buffer`.
41+
---@field inject? fun(self: SMODS.TabDialog|table, i?: number) Called during `inject_class`. Injects the object into the game.
42+
---@field take_ownership? fun(self: SMODS.TabDialog|table, key: string, obj: SMODS.Tab|table, silent?: boolean): nil|table|SMODS.Tab Takes control of vanilla objects. Child class must have get_obj for this to function
43+
---@field get_obj? fun(self: SMODS.TabDialog|table, key: string): SMODS.Tab|table? Returns an object if one matches the `key`.
44+
---@field contents? fun(self: SMODS.TabDialog|table, args?: table): UINode? Generates the contents of the TabDialog. Called automatically by create_UIBox.
45+
---@field func_key? fun(self: SMODS.TabDialog|table, func_name: string): string Returns the key in G.FUNCS where this object's function of name func_name is available, if it was a member of the g_funcs array.
46+
---@field generate_infotip? fun(self: SMODS.TabDialog|table, args?: table): table? Generates an optional, dynamic infotip to display with this UIBox. The returned value should be an table contaning an array of text lines and an optional lang code.
47+
---@field create_UIBox? fun(self: SMODS.TabDialog|table, args?: table): UINode Returns the generated UIBox with the configured options.
48+
---@field filter_visible_tabs? fun(self: SMODS.TabDialog|table, args?: table): table? Returns an ordered array of tabs compatible with args.tabs of create_tabs. Called automatically by contents().
49+
---@overload fun(self: SMODS.TabDialog): SMODS.TabDialog
50+
SMODS.TabDialog = setmetatable({}, {
51+
__call = function(self)
52+
return self
53+
end
54+
})
55+
56+
---@type table<string, SMODS.TabDialog|table>
57+
SMODS.TabDialogs = {}

lsp_def/classes/uibox.lua

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---@meta
2+
3+
---@class SMODS.UIBox: SMODS.GameObject
4+
---@field key string The key of this UIBox.
5+
---@field g_funcs table Array of member functions to add to G.FUNCS.
6+
---@field back_button? string Controller button for backing out of the UIBox.
7+
---@field back_colour? table HEX color fill of the back button.
8+
---@field back_delay? number Button delay for the back button.
9+
---@field back_id? string ID for the back button.
10+
---@field back_label? string Localization key for the label on the back button.
11+
---@field bg_colour? table Background color for the UIBox
12+
---@field colour? table Inner background color for the UIBox
13+
---@field minw? number The minimum width of the UIBox.
14+
---@field no_back? boolean Whether to hide the back button for the UIBox.
15+
---@field no_pip? boolean Whether to prevent the creation of a binding controller pip on the back button.
16+
---@field outline_colour? table Colour for the outline between the background and inner background.
17+
---@field padding? number Padding value around the contents of the UIBox.
18+
---@field snap_back? boolean Whether to snap the controller to the back button.
19+
---@field __call? fun(self: SMODS.UIBox|table, o: SMODS.UIBox|table): nil|table|SMODS.UIBox
20+
---@field extend? fun(self: SMODS.UIBox|table, o: SMODS.UIBox|table): table Primary method of creating a class.
21+
---@field check_duplicate_register? fun(self: SMODS.UIBox|table): boolean? Ensures objects already registered will not register.
22+
---@field check_duplicate_key? fun(self: SMODS.UIBox|table): boolean? Ensures objects with duplicate keys will not register. Checked on `__call` but not `take_ownership`. For take_ownership, the key must exist.
23+
---@field register? fun(self: SMODS.UIBox|table) Registers the object.
24+
---@field check_dependencies? fun(self: SMODS.UIBox|table): boolean? Returns `true` if there's no failed dependencies.
25+
---@field process_loc_text? fun(self: SMODS.UIBox|table) Called during `inject_class`. Handles injecting loc_text.
26+
---@field send_to_subclasses? fun(self: SMODS.UIBox|table, func: string, ...: any) Starting from this class, recusively searches for functions with the given key on all subordinate classes and run all found functions with the given arguments.
27+
---@field pre_inject_class? fun(self: SMODS.UIBox|table) Called before `inject_class`. Injects and manages class information before object injection.
28+
---@field post_inject_class? fun(self: SMODS.UIBox|table) Called after `inject_class`. Injects and manages class information after object injection.
29+
---@field inject_class? fun(self: SMODS.UIBox|table) Injects all direct instances of class objects by calling `obj:inject` and `obj:process_loc_text`. Also injects anything necessary for the class itself. Only called if class has defined both `obj_table` and `obj_buffer`.
30+
---@field inject? fun(self: SMODS.UIBox|table, i?: number) Called during `inject_class`. Injects the object into the game.
31+
---@field take_ownership? fun(self: SMODS.UIBox|table, key: string, obj: SMODS.UIBox|table, silent?: boolean): nil|table|SMODS.UIBox Takes control of vanilla objects. Child class must have get_obj for this to function
32+
---@field get_obj? fun(self: SMODS.UIBox|table, key: string): SMODS.Tab|table? Returns an object if one matches the `key`.
33+
---@field contents fun(self: SMODS.UIBox|table, args?: table): UINode? Generates the contents of the UIBox. Called automatically by create_UIBox.
34+
---@field func_key fun(self: SMODS.UIBox|table, func_name: string): string Returns the key in G.FUNCS where this object's function of name func_name is available, if it was a member of the g_funcs array.
35+
---@field generate_infotip fun(self: SMODS.UIBox|table, args?: table): table? Generates an optional, dynamic infotip to display with this UIBox. The returned value should be an table contaning an array of text lines and an optional lang code.
36+
---@field create_UIBox fun(self: SMODS.UIBox|table, args?: table): UINode Returns the generated UIBox with the configured options.
37+
---@overload fun(self: SMODS.UIBox): SMODS.UIBox
38+
SMODS.UIBox = setmetatable({}, {
39+
__call = function(self)
40+
return self
41+
end
42+
})
43+
44+
---@type table<string, SMODS.UIBox|table>
45+
SMODS.UIBoxes = {}

src/game_object.lua

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3360,11 +3360,23 @@ Set `prefix_config.key = false` on your object instead.]]):format(obj.key), obj.
33603360

33613361
assert(load(NFS.read(SMODS.path..'src/card_draw.lua'), ('=[SMODS _ "src/card_draw.lua"]')))()
33623362

3363+
-------------------------------------------------------------------------------------------------
3364+
----- API IMPORT GameObject.UIBox
3365+
-------------------------------------------------------------------------------------------------
3366+
3367+
assert(load(NFS.read(SMODS.path..'src/ui_classes/uibox.lua'), ('=[SMODS _ "src/ui_taui_classes/uibox.lua"]')))()
3368+
3369+
-------------------------------------------------------------------------------------------------
3370+
----- API IMPORT GameObject.TabDialog
3371+
-------------------------------------------------------------------------------------------------
3372+
3373+
assert(load(NFS.read(SMODS.path..'src/ui_classes/tab_dialog.lua'), ('=[SMODS _ "src/ui_classes/tab_dialog.lua"]')))()
3374+
33633375
-------------------------------------------------------------------------------------------------
33643376
----- API IMPORT GameObject.Tab
33653377
-------------------------------------------------------------------------------------------------
33663378

3367-
assert(load(NFS.read(SMODS.path..'src/ui_tabs.lua'), ('=[SMODS _ "src/ui_tabs.lua"]')))()
3379+
assert(load(NFS.read(SMODS.path..'src/ui_classes/tab.lua'), ('=[SMODS _ "src/ui_classes/tab.lua"]')))()
33683380

33693381
-------------------------------------------------------------------------------------------------
33703382
----- INTERNAL API CODE GameObject._Loc_Post

src/ui_classes/tab.lua

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
SMODS.Tabs = {}
2+
SMODS.Tab = SMODS.GameObject:extend {
3+
obj_table = SMODS.Tabs,
4+
obj_buffer = {},
5+
required_params = {
6+
'key',
7+
'tab_dialog',
8+
'order',
9+
'func',
10+
},
11+
chosen = false,
12+
-- func = function(self) end, -- -> table
13+
-- is_visible = function(self, args) end, -- -> bool
14+
15+
set = "Tab",
16+
register = function(self)
17+
if self.registered then
18+
sendWarnMessage(('Detected duplicate register call on object %s'):format(self.key), self.set)
19+
return
20+
end
21+
SMODS.Tab.super.register(self)
22+
end,
23+
inject = function() end,
24+
post_inject_class = function(self)
25+
table.sort(self.obj_buffer, function(_self, _other) return self.obj_table[_self].order < self.obj_table[_other].order end)
26+
end,
27+
}
28+
29+
SMODS.Tab{
30+
key = 'remaining',
31+
tab_dialog = 'deck_info',
32+
order = 0,
33+
chosen = true,
34+
func = function(self)
35+
return G.UIDEF.view_deck(true)
36+
end,
37+
38+
is_visible = function(self, args)
39+
return args.show_remaining
40+
end,
41+
}
42+
43+
SMODS.Tab{
44+
key = 'full_deck',
45+
tab_dialog = 'deck_info',
46+
order = 10,
47+
func = function(self)
48+
return G.UIDEF.view_deck()
49+
end,
50+
}
51+
52+
SMODS.Tab{
53+
key = 'poker_hands',
54+
tab_dialog = 'run_info',
55+
order = 0,
56+
chosen = true,
57+
func = function(self)
58+
return create_UIBox_current_hands()
59+
end,
60+
}
61+
62+
SMODS.Tab{
63+
key = 'blinds',
64+
tab_dialog = 'run_info',
65+
order = 10,
66+
func = function(self)
67+
return G.UIDEF.current_blinds()
68+
end,
69+
}
70+
71+
SMODS.Tab{
72+
key = 'vouchers',
73+
tab_dialog = 'run_info',
74+
order = 20,
75+
func = function(self)
76+
return G.UIDEF.used_vouchers()
77+
end,
78+
}
79+
80+
SMODS.Tab{
81+
key = 'stake',
82+
tab_dialog = 'run_info',
83+
order = 30,
84+
func = function(self)
85+
return G.UIDEF.current_stake()
86+
end,
87+
is_visible = function(self, args)
88+
return G.GAME.stake > 1
89+
end,
90+
}

src/ui_classes/tab_dialog.lua

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
SMODS.TabDialogs = {}
2+
SMODS.TabDialog = SMODS.GameObject:extend {
3+
obj_table = SMODS.TabDialogs,
4+
obj_buffer = {},
5+
required_params = {
6+
'key',
7+
},
8+
9+
-- Tab-specific arguments
10+
content_alignment = nil,
11+
content_padding = nil,
12+
content_minh = nil,
13+
content_minw = nil,
14+
no_loop = nil,
15+
no_shoulders = nil,
16+
opt_callback = nil,
17+
scale = nil,
18+
snap_to_nav = nil,
19+
tab_colour = nil,
20+
text_scale = nil,
21+
-- func = function(self) end, -- -> table
22+
-- is_visible = function(self, args) end, -- -> bool
23+
24+
set = "TabDialog",
25+
26+
back_func = function(self, e)
27+
return G.FUNCS.exit_overlay_menu(e)
28+
end,
29+
30+
contents = function(self, args)
31+
args = args or {}
32+
local tabs = self:filter_visible_tabs(args or {})
33+
34+
return create_tabs{
35+
tabs = tabs,
36+
37+
no_loop = self.no_loop,
38+
no_shoulders = self.no_shoulders,
39+
padding = self.content_padding,
40+
scale = self.scale,
41+
snap_to_nav = self.snap_to_nav,
42+
tab_alignment = self.content_alignment,
43+
tab_colour = self.colour,
44+
tab_w = self.content_minw,
45+
tab_h = self.content_minh,
46+
text_scale = self.text_scale,
47+
}
48+
end,
49+
50+
-- Returns all visible tabs which belong to `tab_dialog` as an array sorted by order correctly formatted to pass to create_tabs argument args.tabs.
51+
filter_visible_tabs = function(self, args)
52+
local tabs = {}
53+
local chosen_seen = nil
54+
for _, key in ipairs(SMODS.Tab.obj_buffer) do
55+
local tab = SMODS.Tabs[key]
56+
if tab.tab_dialog == self.key and (tab.is_visible == nil or (type(tab.is_visible) == 'function' and tab:is_visible(args or {}))) then
57+
local chosen = not chosen_seen and tab.chosen or nil
58+
chosen_seen = chosen_seen or chosen
59+
tabs[#tabs+1] = {
60+
label = localize('b_' .. tab.key),
61+
order = tab.order,
62+
chosen = chosen,
63+
tab_definition_function = function() return tab:func() end,
64+
}
65+
end
66+
end
67+
68+
if #tabs == 0 then
69+
sendDebugMessage("Tab Dialog '" .. self.key .. "' returned no matching tabs.", 'SMODS.TabDialog')
70+
return nil
71+
end
72+
73+
if not chosen_seen then tabs[1].chosen = true end
74+
return tabs
75+
end,
76+
}
77+
78+
SMODS.TabDialog {
79+
key = 'deck_info',
80+
content_minh = 8,
81+
snap_to_nav = true,
82+
}
83+
84+
SMODS.TabDialog {
85+
key = 'run_info',
86+
content_minh = 8,
87+
snap_to_nav = true,
88+
}
89+
90+
function G.UIDEF.deck_info(_show_remaining)
91+
return SMODS.TabDialogs.deck_info:create_UIBox({show_remaining = _show_remaining})
92+
end
93+
94+
function G.UIDEF.run_info()
95+
return SMODS.TabDialogs.run_info:create_UIBox()
96+
end

0 commit comments

Comments
 (0)