From 7e648246ebd892ccf1c8a0f439ab99c096d15977 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sat, 1 May 2021 00:28:11 +0200 Subject: [PATCH] Unify items list and inventory --- API.md | 6 -- init.lua | 229 ++++++++++++++++++++++--------------------- textures/i3_exit.png | Bin 0 -> 6941 bytes 3 files changed, 118 insertions(+), 117 deletions(-) create mode 100644 textures/i3_exit.png diff --git a/API.md b/API.md index 8a43e65..8a54d9f 100644 --- a/API.md +++ b/API.md @@ -27,12 +27,6 @@ i3.new_tab { fields = function(player, data, fields) 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, } ``` diff --git a/init.lua b/init.lua index b24c7d6..3a1025d 100644 --- a/init.lua +++ b/init.lua @@ -75,9 +75,6 @@ local pairs, ipairs, next, type, setmetatable, tonum, unpack, select = local vec_add, vec_mul = vector.add, vector.multiply -local ROWS = 11 -local LINES = 12 -local IPP = ROWS * LINES local MAX_FAVS = 6 local ITEM_BTN_SIZE = 1.1 @@ -142,6 +139,7 @@ local PNG = { refresh = "i3_refresh.png", visible = "i3_visible.png^\\[brighten", nonvisible = "i3_non_visible.png", + exit = "i3_exit.png", cancel_hover = "i3_cancel.png^\\[brighten", search_hover = "i3_search.png^\\[brighten", @@ -162,6 +160,7 @@ local PNG = { teleport_hover = "i3_teleport.png^\\[brighten", add_hover = "i3_add.png^\\[brighten", refresh_hover = "i3_refresh.png^\\[brighten", + exit_hover = "i3_exit.png^\\[brighten", } local fs_elements = { @@ -188,6 +187,7 @@ local styles = sprintf([[ style_type[item_image_button;bgimg_hovered=%s] style[pagenum,no_item,no_rcp;font=bold;font_size=18] + style[exit;fgimg=%s;fgimg_hovered=%s;content_offset=0] style[cancel;fgimg=%s;fgimg_hovered=%s;content_offset=0] style[search;fgimg=%s;fgimg_hovered=%s;content_offset=0] style[prev_page;fgimg=%s;fgimg_hovered=%s] @@ -203,6 +203,7 @@ local styles = sprintf([[ bgimg_pressed=i3_btn9_pressed.png;bgimg_middle=4,6] ]], PNG.slot, +PNG.exit, PNG.exit_hover, PNG.cancel, PNG.cancel_hover, PNG.search, PNG.search_hover, PNG.prev, PNG.prev_hover, @@ -1671,7 +1672,7 @@ end local function get_header(fs, data) local fav = is_fav(data.favs, data.query_item) local nfavs = #data.favs - local star_x, star_y, star_size = data.xoffset + 0.4, data.yoffset + 0.5, 0.4 + local star_x, star_y, star_size = data.xoffset + 0.4, data.yoffset + 0.2, 0.4 if nfavs < MAX_FAVS or (nfavs == MAX_FAVS and fav) then local fav_marked = fmt("i3_fav%s.png", fav and "_off" or "") @@ -1687,6 +1688,9 @@ local function get_header(fs, data) fs(fmt("tooltip[nofav;%s]", ES"Cannot mark this item. Bookmark limit reached.")) end + fs("image_button", star_x + 0.05, star_y + 0.6, star_size, star_size, "", "exit", "") + fs(fmt("tooltip[exit;%s]", ES"Back to item list")) + local desc_lim, name_lim = 33, 34 local desc = translate(data.lang_code, get_desc(data.query_item)) desc = ESC(desc) @@ -1752,7 +1756,7 @@ local function get_export_fs(fs, data, is_recipe, is_usage, max_stacks_rcp, max_ ES("Craft (x@1)", stack_fs)) end -local function get_rcp_extra(player, data, fs, panel, is_recipe, is_usage) +local function get_rcp_extra(player, fs, data, panel, is_recipe, is_usage) local rn = panel.rcp and #panel.rcp if rn then @@ -1789,6 +1793,57 @@ local function get_rcp_extra(player, data, fs, panel, is_recipe, is_usage) end end +local function get_items_fs(fs, data, creative) + local rows = 8 + local lines = creative and 12 or 9 + local ipp = rows * lines + + fs(fmt("box[%f,0.2;4.05,0.6;#bababa25]", data.xoffset + 0.3), + "set_focus[filter]", + fmt("field[%f,0.2;2.95,0.6;filter;;%s]", data.xoffset + 0.35, ESC(data.filter)), + "field_close_on_enter[filter;false]") + + fs("image_button", data.xoffset + 3.35, 0.35, 0.3, 0.3, "", "cancel", "") + fs("image_button", data.xoffset + 3.85, 0.32, 0.35, 0.35, "", "search", "") + fs("image_button", data.xoffset + 5.27, 0.3, 0.35, 0.35, "", "prev_page", "") + fs("image_button", data.xoffset + 7.45, 0.3, 0.35, 0.35, "", "next_page", "") + + data.pagemax = max(1, ceil(#data.items / ipp)) + + fs("button", data.xoffset + 5.6, 0.14, 1.88, 0.7, "pagenum", + fmt("%s / %u", clr("#ff0", data.pagenum), data.pagemax)) + + if #data.items == 0 then + local lbl = ES"No item to show" + + if next(recipe_filters) and #init_items > 0 and data.filter == "" then + lbl = ES"Collect items to reveal more recipes" + end + + fs("button", data.xoffset + 0.1, 3, 8, 1, "no_item", lbl) + end + + local first_item = (data.pagenum - 1) * ipp + local size = 0.85 + + for i = first_item, first_item + ipp - 1 do + local item = data.items[i + 1] + if not item then break end + + local X = i % rows + X = X - (X * 0.045) + data.xoffset + 0.28 + + local Y = round((i % ipp - X) / rows + 1, 0) + Y = Y - (Y * (creative and 0.11 or 0.06)) + 0.9 + + if data.query_item == item then + fs("image", X, Y, size, size, PNG.slot) + end + + fs[#fs + 1] = fmt("item_image_button", X, Y, size, size, item, fmt("%s_inv", item), "") + end +end + local function get_favs(fs, data) fs("label", data.xoffset + 0.4, data.yoffset + 0.4, ES"Bookmarks") @@ -1805,12 +1860,27 @@ local function get_favs(fs, data) end end -local function get_panels(player, data, fs) +local function get_panels(player, data, fs, full_height) local _title = {name = "title", height = 1.4} local _favs = {name = "favs", height = 2.23} + local _items = {name = "items", height = 9.41} local _recipes = {name = "recipes", rcp = data.recipes, height = 3.9} local _usages = {name = "usages", rcp = data.usages, height = 3.9} - local panels = {_title, _recipes, _usages, _favs} + local panels + + local name = player:get_player_name() + local creative = core.is_creative_enabled(name) + + if data.query_item then + panels = {_title, _recipes, _usages, _favs} + else + panels = {_items, _favs} + + if creative then + _items.height = full_height + panels = {_items} + end + end for idx = 1, #panels do local panel = panels[idx] @@ -1827,7 +1897,9 @@ local function get_panels(player, data, fs) local is_recipe, is_usage = panel.name == "recipes", panel.name == "usages" if is_recipe or is_usage then - get_rcp_extra(player, data, fs, panel, is_recipe, is_usage) + get_rcp_extra(player, fs, data, panel, is_recipe, is_usage) + elseif panel.name == "items" then + get_items_fs(fs, data, creative) elseif panel.name == "title" then get_header(fs, data) elseif panel.name == "favs" then @@ -2158,11 +2230,9 @@ local function make_fs(player, data) local full_height = 11.73 local tab = tabs[data.current_tab] - local hide_panels = tab and tab.hide_panels and tab.hide_panels(player, data) - local show_panels = data.query_item and tab and not hide_panels fs(fmt("formspec_version[%u]size[%f,%f]no_prepend[]bgcolor[#0000]", - MIN_FORMSPEC_VERSION, data.xoffset + (show_panels and 8 or 0), full_height), styles) + MIN_FORMSPEC_VERSION, data.xoffset + 8, full_height), styles) fs("bg9", 0, 0, data.xoffset, full_height, PNG.bg_full, 10) @@ -2170,11 +2240,11 @@ local function make_fs(player, data) tab.formspec(player, data, fs) end - if show_panels then - get_panels(player, data, fs) - end + get_panels(player, data, fs, full_height) - get_tabs_fs(player, data, fs, full_height) + if #tabs > 1 then + get_tabs_fs(player, data, fs, full_height) + end --get_debug_grid(data, fs, full_height) --print("make_fs()", fmt("%.2f ms", (os.clock() - start) * 1000)) @@ -2316,7 +2386,7 @@ local function reset_data(data) data.items = data.items_raw end -local function panel_fields(player, data, fields) +local function rcp_fields(player, data, fields) local name = player:get_player_name() local sb_rcp, sb_usg = fields.scrbar_rcp, fields.scrbar_usg @@ -2496,52 +2566,6 @@ local function get_inventory_fs(player, data, fs) end end -local function get_items_fs(_, data, fs) - fs("box[0.2,0.2;4.55,0.6;#bababa25]", "set_focus[filter]", - fmt("field[0.3,0.2;3.45,0.6;filter;;%s]", ESC(data.filter)), - "field_close_on_enter[filter;false]") - - fs("image_button", 3.75, 0.35, 0.3, 0.3, "", "cancel", "") - fs("image_button", 4.25, 0.32, 0.35, 0.35, "", "search", "") - fs("image_button", data.xoffset - 2.73, 0.3, 0.35, 0.35, "", "prev_page", "") - fs("image_button", data.xoffset - 0.55, 0.3, 0.35, 0.35, "", "next_page", "") - - data.pagemax = max(1, ceil(#data.items / IPP)) - - fs("button", data.xoffset - 2.4, 0.14, 1.88, 0.7, "pagenum", - fmt("%s / %u", clr("#ff0", data.pagenum), data.pagemax)) - - if #data.items == 0 then - local lbl = ES"No item to show" - - if next(recipe_filters) and #init_items > 0 and data.filter == "" then - lbl = ES"Collect items to reveal more recipes" - end - - fs("button", 0, 3, data.xoffset, 1, "no_item", lbl) - end - - local first_item = (data.pagenum - 1) * IPP - local size = 0.8 - - for i = first_item, first_item + IPP - 1 do - local item = data.items[i + 1] - if not item then break end - - local X = i % ROWS - X = X - (X * 0.098) + 0.2 - - local Y = round((i % IPP - X) / ROWS + 1, 0) - Y = Y - (Y * 0.108) + 0.05 - - if data.query_item == item then - fs("image", X, Y, size, size, PNG.slot) - end - - fs[#fs + 1] = fmt("item_image_button", X, Y, size, size, item, fmt("%s_inv", item), "") - end -end - i3.new_tab { name = "inventory", description = S"Inventory", @@ -2551,9 +2575,7 @@ i3.new_tab { local name = player:get_player_name() local sb_inv = fields.scrbar_inv - if not core.is_creative_enabled(name) then - panel_fields(player, data, fields) - end + rcp_fields(player, data, fields) if fields.skins and data.skin_id ~= tonum(fields.skins) then data.skin_id = tonum(fields.skins) @@ -2611,7 +2633,37 @@ i3.new_tab { end end - if fields.trash then + if fields.cancel then + reset_data(data) + + elseif fields.exit then + data.query_item = nil + + elseif fields.key_enter_field == "filter" or fields.search then + if fields.filter == "" then + reset_data(data) + return set_fs(player) + end + + local str = lower(fields.filter) + if data.filter == str then return end + + data.filter = str + data.pagenum = 1 + + search(data) + + elseif fields.prev_page or fields.next_page then + if data.pagemax == 1 then return end + data.pagenum = data.pagenum - (fields.prev_page and 1 or -1) + + if data.pagenum > data.pagemax then + data.pagenum = 1 + elseif data.pagenum == 0 then + data.pagenum = data.pagemax + end + + elseif fields.trash then local inv = player:get_inventory() inv:set_list("main", {}) inv:set_list("craft", {}) @@ -2651,51 +2703,6 @@ i3.new_tab { return set_fs(player) end, - - hide_panels = function(player) - local name = player:get_player_name() - return core.is_creative_enabled(name) - end, -} - -i3.new_tab { - name = "items", - description = S"Items", - formspec = get_items_fs, - - fields = function(player, data, fields) - panel_fields(player, data, fields) - - if fields.cancel then - reset_data(data) - - elseif fields.key_enter_field == "filter" or fields.search then - if fields.filter == "" then - reset_data(data) - return set_fs(player) - end - - local str = lower(fields.filter) - if data.filter == str then return end - - data.filter = str - data.pagenum = 1 - - search(data) - - elseif fields.prev_page or fields.next_page then - if data.pagemax == 1 then return end - data.pagenum = data.pagenum - (fields.prev_page and 1 or -1) - - if data.pagenum > data.pagemax then - data.pagenum = 1 - elseif data.pagenum == 0 then - data.pagenum = data.pagemax - end - end - - return set_fs(player) - end, } local trash = create_inventory("i3_trash", { diff --git a/textures/i3_exit.png b/textures/i3_exit.png new file mode 100644 index 0000000000000000000000000000000000000000..9b6c30502a3c73f12f728a7ca94f0a5fe326d985 GIT binary patch literal 6941 zcmeHLXIN9&)(*XjI3j`qhA4t)NJt2f2+|TEBSETCM?!KE0;HG(2sj{3DHaqIl_Dbw zBPc}yQ3Pp2QJMu2P!JW=QKTpW4xryja1`&IZ|*nG^WA?YPm;6ue%HI!e)n2?pOZvK z2iqm`tK=aN$P%I*-WmM06n(i|s_RLr|P=x6Wlf1s;n@nklu-)FBZa+zme&2#=_P0xIAOm)8C zX+|Q~BGP}_;uuBhYJ|m|OUkEg#g>NKyB{zNU>ObS&hnzGGARwqA>94^6w^`K_JG2_E&2{GYwqvJW2G~a#XJ_H7CSpxaN@ucZ$bW`F6;bu$b97mn_PL(@q}px3=AS z{YCmp^YswCd&ZN4y2uip?IWp=*GW!jnbO8x44srzY$T*kWA&;OkLpEdY6LM4F01)N zTIsqvMgfo1`N7fUe9VP}dg*z)w%d-t)0Vcxedv`%iO%+!&MDN!VtJxU+B%p=QkOlJ z*0Et*hrtQ&ZF+G}TXa@zxOU8WqiW&FYkqt}yr-9cm*2Cr^s+}kUeJ8|`z79XpYV|C z$pR~)lde&|e|JvsjM#=lrh;?YYm-s0;=0zin}+3WKzE{EAIFS^cxD%Mdc0fNUGH}b zck4Jtam6+JCxw|MyQQ0~Cw;vSipk>C=w4HX()2EMx|dvwywZ5eA&vJYc97PovTYlyCi%CVMGQPAb{Mb5);CaAuU+UAR|DzKX6@q4~1kHhCYD%lFgV ztTJE|oZo(>ch}KgSGtWV|CZX5=HHxuDT!Rwr;GYvMo9mKdfUF=`p8|qCtlL{2w892 z;{BBvuN3i+>pAi9ucy%MPtL}|@Vd1M(gg|aQC+NVDXW|q?dA-tw&k*UU9*{6dgWg> zX~3`a-FIum=aTQ=ZM$G>&1_nF>)Cnzvw>%|3kr`Kk3^ge*`hwgZMZ6Dp%_6tyB61y zG8~^sb|2B|RmLC=qz# zjOx~`E2|#vsf*a-Up)C-)o+*9>2f*kDaEiu&Lo2R$w9@3CDv;&DpKq21GPD7XIk%; z-7tzv8zI|urP+#4R8;qGOUq~;ZB%`pSqJT)JP)v{@1)O)ULStl6cdCX)Q%3R)@~2YOcqao# zUA+WKB5%O8Z}P*9K`rP^!KaG*dp+f=i$9KrS(su3O}#%x5mwu+PmQXHZ|HBH#o5cY zUoNrqr%FK^(5bza@7J}oS&flo2|BPkt3U!RcE@?QKD+Yj_O1+kaLr)LGc~(DC%3%g zdK)!+W><_Q>^Q477AYAR80*xFX}sLVa4f?2}?gk|uU(|lFY)v-InNeym2J9;oHBqX8G!q+XUmpN>Y zDOA3ervF6w@+oFq zYj$U9^1$^6WFIa%T;uc`fBvz%mp0G%a<-@KTJ?zK5g*L*vml+1(*k z{xw-I%aXF}+UM((CZFK5St-g1s&P{meXo+MC7cm95Qx}5hK-FQ(Z=S_Lk&F2G9!+f z+cj8fH14{mO3+tQUAF9|qfZ%B|LJ)*J?nkW8_Qn#a(`cG#ISSr){uG-6T9Yso6JhO zkEXYj)wslO?d`-ngdgX2Ir}erR=3+?pnuP!YKge;Q~5Ms4M$9?T_eSB{dN72Dp-{E zq;`T+;;BEpQKzC_%v8oF7l%5X9*!98yi+)2FFk{Q>XElvbwYY#GB1}mpsQ4xb51#X zd9pg+>Zxr}t3l0f1Jh08Z6!w?+Ly;CHd?Q4Wws^l|Iv(~;pBSg?Y@Jp@-N^W0oQJ& zPY)p!hs%xwMfWuD8VB61e}GY4ovhVWbIJnFowU0X+16k&IFmY*a??$GZL_$(qc%2j z++wD`@KkmtC)L^zI^*|nO@n2#!R_y9{@dJ&wX=8jz`MKfpl1z85kKL;RFFA1O?k74>jXbX*g&6 z*3T4R%N*v<=W}ofL}+NJK`7dQ&7~s@u~;kui9(=Ia1a6Kg|YZ#0i4BKE2LQ9zymxA zm%-sP*es}!lkCS1=9|M{;5hU%IXFro2*A$I4uowHJÅW$8KI3EyzKp~N)a3l(j z!Xg&igQFzU7i$*pvx=ae2mzUcFf>3Sn9Of1czi<0SATzL!E*&~_7Khhj~&dV0E7^L z#b3MFDJLkHx7cSe4-j^V;trzH5MWRu&x>tri6qA_HbNQc3?@fpAw(}mQYl|>oM3K{ z2t%bHfFOVg2EqfG4Zp$j8MLnp^v!&PBmWi%={0apeSaN(1Mq8S<+Vogy~pc;?Aa8Np$H66h4uEi;;hMZgs5qT_&e~wF}e7&Ls|bfp0Cg^ELL28D4QF& zox9yH0HE;yp69Q?UznW1y^hD{h7te6r2YkGwveuNpe>slw#dH=uzR7kuptF8L{dSa zqD=rtrYy+MBZmM~(Gq|Yvjy6K**q5^k{oX2LBAM-*nBOE8BM!~nS83iD^8{4cmg_MemTKbbFv zEm+&IIbmSY`t!Gkvi{cnUjP>v>=_h*#bf_n=!+o>vMf4xz?c{M!1D||9uZ&8$IodY ztepSi>vOvO7d?Q~-<|v;eZR}~U9Nwmz&`?i&#v!s{UZhb5%_y{{lCd2|MdwQV1YM! zq2TlL;i>$G;Ip^1-!@x3BwP44dljAs_Q-MUJb2(gC_TcD*dN|`T(DDyPb3j!h9$LB z+?*g zkM<=OKMHG9iIm*9xiR^d2R-gti6@*#l{-nB-Wq7MGHD^Dz3n4y3azTqM;@n6e;NrX z>t6n-+-I=TIiO->C0@W1vxF!^Bq2X}Js1xYKR7fH*I1kMXtfwpd{jJkKV&j`sbw*7 zsao4T|2B$epz50lZJA9U#tyR}_d(CRrzFsP0`Ykn@)6j*_W8o1+YC zZrpWrCOPUI0L8hyK54vAe#h*a|KNa(b_y7b~hOO9Nvdu9Ea+BMMPp@(mKyglG`jhP3X)$f_9ZYVF3(;}I`=v8VLGG3>d)94zam)9 z%v3Zp@Ac)?SfZhV*x;e=a6N6e*-a(&{N@M6C8*5O+ea17uppNbYHnLjYADqG&L|O= zWk*OHVWw62B-o$3gqyr0(NwE7uGBLct{=I)M||p)v~S>S1PsX4+$ z1#j`6)K;DGo+vl5c6;-oygPp;z7`XE*n7fZNA%jKCQ+Mfd(}rRT&j4G0@X1U$f>8@ z>z;31HkK}fM}6>-bnr-cj7kh$Vkth-vejS4)M)Nq#`*~du_KgXiNVykx(Y?fz=}{~ zxsE8uAFEPP$7tdu|A za;v-&&U~`$ln#3@>4mHuGG#+)1O%DAR*_nR4B80E;Ki8^MM*u6QhV9z@{r`7Ep=m~ xuLSf^UEZ#f{#_E`Or_}CvQiLH-pmAj5=%{2-s3v?EEvpX2$A4`FS7QH`5(1v%OwB+ literal 0 HcmV?d00001