Rework search_filter (cumulative) + API doc

This commit is contained in:
Jean-Patrick Guerrero 2021-01-23 19:49:28 +01:00
parent ab07ee4762
commit e3f183b9c8
2 changed files with 60 additions and 37 deletions

50
API.md
View File

@ -27,6 +27,12 @@ i3.new_tab {
fields = function(player, data, fields) fields = function(player, data, fields)
i3.set_fs(player) i3.set_fs(player)
end, end,
-- Determine if the recipe panels must be hidden or not (must return a boolean)
hide_panels = function(player, data)
local name = player:get_player_name()
return core.is_creative_enabled(name)
end,
} }
``` ```
@ -142,7 +148,7 @@ mode is implemented as a recipe filter.
#### `i3.add_recipe_filter(name, function(recipes, player))` #### `i3.add_recipe_filter(name, function(recipes, player))`
Adds a recipe filter with the given name. The filter function should return the Adds a recipe filter with the given `name`. The filter function returns the
recipes to be displayed, given the available recipes and an `ObjectRef` to the recipes to be displayed, given the available recipes and an `ObjectRef` to the
user. Each recipe is a table of the form returned by user. Each recipe is a table of the form returned by
`minetest.get_craft_recipe`. `minetest.get_craft_recipe`.
@ -168,7 +174,7 @@ Removes all recipe filters and adds a new one.
#### `i3.remove_recipe_filter(name)` #### `i3.remove_recipe_filter(name)`
Removes the recipe filter with the given name. Removes the recipe filter with the given `name`.
#### `i3.get_recipe_filters()` #### `i3.get_recipe_filters()`
@ -179,50 +185,40 @@ Returns a map of recipe filters, indexed by name.
### Search filters ### Search filters
Search filters are used to perform specific searches inside the search field. Search filters are used to perform specific searches inside the search field.
They can be used like so: `<optional name>+<filter name>=<value1>,<value2>,<...>` They can be used like so: `<optional_name> +<filter name>=<value1>,<value2>,<...>`
Examples: Examples:
- `+groups=cracky,crumbly`: search for groups `cracky` and `crumbly` in all items. - `+groups=cracky,crumbly`: search for groups `cracky` and `crumbly` in all items.
- `sand+groups=falling_node`: search for group `falling_node` for items which contain `sand` in their names. - `sand +groups=falling_node`: search for group `falling_node` for items which contain `sand` in their names.
Notes: Notes:
- If `optional name` is omitted, the search filter will apply to all items, without pre-filtering. - If `optional_name` is omitted, the search filter will apply to all items, without pre-filtering.
- Filters can be combined. - Filters can be combined.
- The `groups` filter is currently implemented by default. - The `groups` and `type` filters are currently implemented by default.
#### `i3.add_search_filter(name, function(item, values))` #### `i3.add_search_filter(name, function(item, values))`
Adds a search filter with the given name. Adds a search filter with the given `name`.
The search function should return a boolean value (whether the given item should be listed or not). The search function must return a boolean value (whether the given item should be listed or not).
Example function to show items which contain at least a recipe of given width(s): Example function sorting items by drawtype:
```lua ```lua
i3.add_search_filter("widths", function(item, widths) i3.add_search_filter("type", function(item, drawtype)
local has_width if drawtype == "node" then
local recipes = recipes_cache[item] return reg_nodes[item]
elseif drawtype == "item" then
if recipes then return reg_craftitems[item]
for i = 1, #recipes do elseif drawtype == "tool" then
local recipe_width = recipes[i].width return reg_tools[item]
for j = 1, #widths do
local width = tonumber(widths[j])
if width == recipe_width then
has_width = true
break
end
end
end
end end
return has_width
end) end)
``` ```
#### `i3.remove_search_filter(name)` #### `i3.remove_search_filter(name)`
Removes the search filter with the given name. Removes the search filter with the given `name`.
#### `i3.get_search_filters()` #### `i3.get_search_filters()`

View File

@ -20,6 +20,8 @@ local http = core.request_http_api()
local singleplayer = core.is_singleplayer() local singleplayer = core.is_singleplayer()
local reg_items = core.registered_items local reg_items = core.registered_items
local reg_nodes = core.registered_nodes
local reg_craftitems = core.registered_craftitems
local reg_tools = core.registered_tools local reg_tools = core.registered_tools
local reg_entities = core.registered_entities local reg_entities = core.registered_entities
local reg_aliases = core.registered_aliases local reg_aliases = core.registered_aliases
@ -749,14 +751,21 @@ local function search(data)
local def = reg_items[item] local def = reg_items[item]
local desc = lower(translate(data.lang_code, def and def.description)) or "" local desc = lower(translate(data.lang_code, def and def.description)) or ""
local search_in = fmt("%s %s", item, desc) local search_in = fmt("%s %s", item, desc)
local to_add local temp, j, to_add = {}, 1
if search_filter then if search_filter then
for filter_name, values in pairs(filters) do for filter_name, values in pairs(filters) do
if values then if values then
local func = search_filters[filter_name] local func = search_filters[filter_name]
to_add = func(item, values) and (search_filter == "" or to_add = (j > 1 and temp[item] or j == 1) and
func(item, values) and (search_filter == "" or
find(search_in, search_filter, 1, true)) find(search_in, search_filter, 1, true))
if to_add then
temp[item] = true
end
j = j + 1
end end
end end
else else
@ -1967,15 +1976,15 @@ local function get_debug_grid(data, fs, full_height)
local spacing = 0.2 local spacing = 0.2
for x = 0, data.xoffset, spacing do for x = 0, data.xoffset, spacing do
fs(fmt("box", x, 0, 0.01, full_height, "#f00")) fs(fmt("box", x, 0, 0.01, full_height, "#ff0"))
end end
for y = 0, full_height, spacing do for y = 0, full_height, spacing do
fs(fmt("box", 0, y, data.xoffset, 0.01, "#f00")) fs(fmt("box", 0, y, data.xoffset, 0.01, "#ff0"))
end end
fs(fmt("box", data.xoffset / 2, 0, 0.01, full_height, "#ff0")) fs(fmt("box", data.xoffset / 2, 0, 0.01, full_height, "#f00"))
fs(fmt("box", 0, full_height / 2, data.xoffset, 0.01, "#ff0")) fs(fmt("box", 0, full_height / 2, data.xoffset, 0.01, "#f00"))
end end
local function make_fs(player, data) local function make_fs(player, data)
@ -1995,9 +2004,13 @@ local function make_fs(player, data)
fs(fmt("bg9", 0, 0, data.xoffset, full_height, PNG.bg_full, 10)) fs(fmt("bg9", 0, 0, data.xoffset, full_height, PNG.bg_full, 10))
tabs[(data.current_tab or 1)].formspec(player, data, fs) local tab = tabs[(data.current_tab or 1)]
if data.query_item then tab.formspec(player, data, fs)
local hide_panels = tab.hide_panels and tab.hide_panels(player, data)
if data.query_item and not hide_panels then
get_panels(player, data, fs) get_panels(player, data, fs)
end end
@ -2365,6 +2378,11 @@ i3.new_tab {
return set_fs(player) return set_fs(player)
end, end,
hide_panels = function(player, data)
local name = player:get_player_name()
return core.is_creative_enabled(name)
end,
} }
i3.new_tab { i3.new_tab {
@ -2485,8 +2503,7 @@ i3.add_search_filter("groups", function(item, groups)
local def = reg_items[item] local def = reg_items[item]
local has_groups = true local has_groups = true
for i = 1, #groups do for _, group in ipairs(groups) do
local group = groups[i]
if not def.groups[group] then if not def.groups[group] then
has_groups = nil has_groups = nil
break break
@ -2496,6 +2513,16 @@ i3.add_search_filter("groups", function(item, groups)
return has_groups return has_groups
end) end)
i3.add_search_filter("type", function(item, drawtype)
if drawtype == "node" then
return reg_nodes[item]
elseif drawtype == "item" then
return reg_craftitems[item]
elseif drawtype == "tool" then
return reg_tools[item]
end
end)
--[[ As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not --[[ As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not
return the fuel, replacements and toolrepair recipes, we have to return the fuel, replacements and toolrepair recipes, we have to
override `core.register_craft` and do some reverse engineering. override `core.register_craft` and do some reverse engineering.