diff --git a/game/engines/default/engine/ui/TextzoneList.lua b/game/engines/default/engine/ui/TextzoneList.lua index 24a35ddec8069c2645debe7ce1a7904fc57d3d22..85bb6d808175002faec3f69a59332e96dcd007ef 100644 --- a/game/engines/default/engine/ui/TextzoneList.lua +++ b/game/engines/default/engine/ui/TextzoneList.lua @@ -74,7 +74,7 @@ function _M:createItem(item, text) local old_style = self.font:getStyle() -- Handle normal text - if type(text) == "string" then + if false and type(text) == "string" then local list = text:splitLines(self.w, self.font) local scroll = 1 local max = #list @@ -109,6 +109,21 @@ function _M:createItem(item, text) -- Draw the list items local gen = self.font:draw(text:toString(), self.fw, 255, 255, 255) + for i = 1, #gen do + if gen[i].line_extra then + if gen[i].line_extra:sub(1, 7) == "linebg:" then + local color = colors[gen[i].line_extra:sub(8)] + if color then + gen[i].background = colors.simple(color) + gen[i].background[4] = 255 + else + local c = gen[i].line_extra + gen[i].background = {string.parseHex(c:sub(8, 9)), string.parseHex(c:sub(10, 11)), string.parseHex(c:sub(12, 13)), string.parseHex(c:sub(14, 15))} + end + end + end + end + local scroll = 1 local max = #gen local max_display = math.floor(self.h / self.fh) @@ -154,6 +169,11 @@ function _M:display(x, y) for i = self.scroll, max do local item = self.list[i] if not item then break end + + if item.background then + core.display.drawQuad(x, y, self.fw, self.fh, item.background[1], item.background[2], item.background[3], item.background[4]) + end + if item.is_separator then self.sep:display(x, y + (self.fh - self.sep.h) / 2) else diff --git a/game/engines/default/engine/utils.lua b/game/engines/default/engine/utils.lua index 8a51d57c64bb7942a24772fdcdbdbb9b03fe8382..c7edf150a496bbe7733bb28b1478ee24459329f2 100644 --- a/game/engines/default/engine/utils.lua +++ b/game/engines/default/engine/utils.lua @@ -211,6 +211,7 @@ function string.lpegSub(s, patt, repl) end -- Those matching patterns are used both by splitLine and drawColorString* +local Pextra = "&" * -lpeg.S"#"^1 local Puid = "UID:" * lpeg.R"09"^1 * ":" * lpeg.R"09" local Puid_cap = "UID:" * lpeg.C(lpeg.R"09"^1) * ":" * lpeg.C(lpeg.R"09") local Pcolorname = (lpeg.R"AZ" + "_")^3 @@ -236,7 +237,7 @@ function string.splitLine(str, max_width, font) local ls = str:split(lpeg.S"\n ") for i = 1, #ls do local v = ls[i] - local shortv = v:lpegSub("#" * (Puid + Pcolorcodefull + Pcolorname + Pfontstyle) * "#", "") + local shortv = v:lpegSub("#" * (Puid + Pcolorcodefull + Pcolorname + Pfontstyle + Pextra) * "#", "") local w, h = font:size(shortv) if cur_size + space_w + w < max_width then @@ -323,7 +324,7 @@ end local tmps = core.display.newSurface(1, 1) getmetatable(tmps).__index.drawColorString = function(s, font, str, x, y, r, g, b, alpha_from_texture, limit_w) - local list = str:split("#" * (Puid + Pcolorcodefull + Pcolorname + Pfontstyle) * "#", true) + local list = str:split("#" * (Puid + Pcolorcodefull + Pcolorname + Pfontstyle + Pextra) * "#", true) r = r or 255 g = g or 255 b = b or 255 @@ -337,6 +338,7 @@ getmetatable(tmps).__index.drawColorString = function(s, font, str, x, y, r, g, local col = lpeg.match("#" * lpeg.C(Pcolorname) * "#", v) local uid, mo = lpeg.match("#" * Puid_cap * "#", v) local fontstyle = lpeg.match("#" * Pfontstyle_cap * "#", v) + local extra = lpeg.match("#" * lpeg.C(Pextra) * "#", v) if nr and ng and nb then oldr, oldg, oldb = r, g, b r, g, b = nr:parseHex(), ng:parseHex(), nb:parseHex() @@ -364,6 +366,8 @@ getmetatable(tmps).__index.drawColorString = function(s, font, str, x, y, r, g, end elseif fontstyle then font:setStyle(fontstyle) + elseif extra then + -- else local w, h = font:size(v) local stop = false @@ -391,7 +395,7 @@ end getmetatable(tmps).__index.drawColorStringBlended = function(s, font, str, x, y, r, g, b, alpha_from_texture, limit_w) - local list = str:split("#" * (Puid + Pcolorcodefull + Pcolorname + Pfontstyle) * "#", true) + local list = str:split("#" * (Puid + Pcolorcodefull + Pcolorname + Pfontstyle + Pextra) * "#", true) r = r or 255 g = g or 255 b = b or 255 @@ -405,6 +409,7 @@ getmetatable(tmps).__index.drawColorStringBlended = function(s, font, str, x, y, local col = lpeg.match("#" * lpeg.C(Pcolorname) * "#", v) local uid, mo = lpeg.match("#" * Puid_cap * "#", v) local fontstyle = lpeg.match("#" * Pfontstyle_cap * "#", v) + local extra = lpeg.match("#" * lpeg.C(Pextra) * "#", v) if nr and ng and nb then oldr, oldg, oldb = r, g, b r, g, b = nr:parseHex(), ng:parseHex(), nb:parseHex() @@ -432,6 +437,8 @@ getmetatable(tmps).__index.drawColorStringBlended = function(s, font, str, x, y, end elseif fontstyle then font:setStyle(fontstyle) + elseif extra then + -- else local w, h = font:size(v) local stop = false @@ -470,7 +477,7 @@ local tmps = core.display.newFont("/data/font/Vera.ttf", 12) local word_size_cache = {} local fontoldsize = getmetatable(tmps).__index.size getmetatable(tmps).__index.size = function(font, str) - local list = str:split("#" * (Puid + Pcolorcodefull + Pcolorname + Pfontstyle) * "#", true) + local list = str:split("#" * (Puid + Pcolorcodefull + Pcolorname + Pfontstyle + Pextra) * "#", true) local mw, mh = 0, 0 local fstyle = font:getStyle() word_size_cache[font] = word_size_cache[font] or {} @@ -482,6 +489,7 @@ getmetatable(tmps).__index.size = function(font, str) local col = lpeg.match("#" * lpeg.C(Pcolorname) * "#", v) local uid, mo = lpeg.match("#" * Puid_cap * "#", v) local fontstyle = lpeg.match("#" * Pfontstyle_cap * "#", v) + local extra = lpeg.match("#" * lpeg.C(Pextra) * "#", v) if nr and ng and nb then -- Ignore elseif col then @@ -502,6 +510,8 @@ getmetatable(tmps).__index.size = function(font, str) font:setStyle(fontstyle) fstyle = fontstyle word_size_cache[font][fstyle] = word_size_cache[font][fstyle] or {} + elseif extra then + -- else local w, h if word_size_cache[font][fstyle][v] then @@ -557,13 +567,14 @@ end --- Parse a string and return a tstring function string.toTString(str) local tstr = tstring{} - local list = str:split(("#" * (Puid + Pcolorcodefull + Pcolorname + Pfontstyle) * "#") + lpeg.P"\n", true) + local list = str:split(("#" * (Puid + Pcolorcodefull + Pcolorname + Pfontstyle + Pextra) * "#") + lpeg.P"\n", true) for i = 1, #list do v = list[i] local nr, ng, nb = lpeg.match("#" * lpeg.C(Pcolorcode) * lpeg.C(Pcolorcode) * lpeg.C(Pcolorcode) * "#", v) local col = lpeg.match("#" * lpeg.C(Pcolorname) * "#", v) local uid, mo = lpeg.match("#" * Puid_cap * "#", v) local fontstyle = lpeg.match("#" * Pfontstyle_cap * "#", v) + local extra = lpeg.match("#" * lpeg.C(Pextra) * "#", v) if nr and ng and nb then tstr:add({"color", nr:parseHex(), ng:parseHex(), nb:parseHex()}) elseif col then @@ -572,6 +583,8 @@ function string.toTString(str) tstr:add({"uid", tonumber(uid)}) elseif fontstyle then tstr:add({"font", fontstyle}) + elseif extra then + tstr:add({"extra", extra:sub(2)}) elseif v == "\n" then tstr:add(true) else @@ -596,6 +609,7 @@ function tstring:toString() elseif v[1] == "color" then ret[#ret+1] = ("#%02x%02x%02x#"):format(v[2], v[3], v[4]):upper() elseif v[1] == "font" then ret[#ret+1] = "#{"..v[2].."}#" elseif v[1] == "uid" then ret[#ret+1] = "#UID:"..v[2]..":0#" + elseif v[1] == "extra" then ret[#ret+1] = "#&"..v[2].."#" end end end @@ -639,6 +653,8 @@ function tstring:splitLines(max_width, font) elseif tv == "table" and v[1] == "font" then font:setStyle(v[2]) ret[#ret+1] = v + elseif tv == "table" and v[1] == "extra" then + ret[#ret+1] = v elseif tv == "table" and v[1] == "uid" then local e = __uids[v[2]] if e and game.level then @@ -724,6 +740,8 @@ function tstring:makeLineTextures(max_width, font, no_split, r, g, b) r, g, b = v[2], v[3], v[4] elseif v[1] == "font" then font:setStyle(v[2]) + elseif v[1] == "extra" then + -- elseif v[1] == "uid" then local e = __uids[v[2]] if e then @@ -782,6 +800,8 @@ function tstring:drawOnSurface(s, max_width, max_lines, font, x, y, r, g, b, no_ r, g, b = v[2], v[3], v[4] elseif v[1] == "font" then font:setStyle(v[2]) + elseif v[1] == "extra" then + -- elseif v[1] == "uid" then local e = __uids[v[2]] if e then diff --git a/src/core_lua.c b/src/core_lua.c index 92fbfa8fa23ec8dc96e56aa22673e689fb1bb6c4..18adbb245f7057168b07bf6d4ddb86945b75fa92 100644 --- a/src/core_lua.c +++ b/src/core_lua.c @@ -486,7 +486,7 @@ static int sdl_surface_drawstring_newsurface_aa(lua_State *L) return 1; } -static font_make_texture_line(lua_State *L, SDL_Surface *s, int id, bool is_separator) +static font_make_texture_line(lua_State *L, SDL_Surface *s, int id, bool is_separator, int id_real_line, char *line_data) { lua_createtable(L, 0, 5); @@ -515,6 +515,17 @@ static font_make_texture_line(lua_State *L, SDL_Surface *s, int id, bool is_sepa lua_pushnumber(L, s->h); lua_rawset(L, -3); + lua_pushliteral(L, "line"); + lua_pushnumber(L, id_real_line); + lua_rawset(L, -3); + + if (line_data) + { + lua_pushliteral(L, "line_extra"); + lua_pushstring(L, line_data); + lua_rawset(L, -3); + } + if (is_separator) { lua_pushliteral(L, "is_separator"); @@ -549,6 +560,8 @@ static int sdl_font_draw(lua_State *L) lua_newtable(L); int nb_lines = 1; + int id_real_line = 1; + char *line_data = NULL; char *start = (char*)str, *stop = (char*)str, *next = (char*)str; int max_size = 0; int size = 0; @@ -580,13 +593,18 @@ static int sdl_font_draw(lua_State *L) if (!no_linefeed && (force_nl || (txt && (size + txt->w > max_width)))) { // Push it & reset the surface - font_make_texture_line(L, s, nb_lines, is_separator); + font_make_texture_line(L, s, nb_lines, is_separator, id_real_line, line_data); is_separator = FALSE; SDL_FillRect(s, NULL, SDL_MapRGBA(s->format, 0, 0, 0, 0)); // printf("Ending previous line at size %d\n", size); if (size > max_size) max_size = size; size = 0; nb_lines++; + if (force_nl) + { + id_real_line++; + if (line_data) { free(line_data); line_data = NULL; } + } force_nl = FALSE; } @@ -637,6 +655,11 @@ static int sdl_font_draw(lua_State *L) } lua_pop(L, 1); } + // Extra data + else if ((*(next+1) == '&')) { + if (line_data) { free(line_data); line_data = NULL; } + line_data = strndup(next + 2, codestop - (next+2)); + } // Color else { if ((codestop - (next+1) == 4) && (*(next+1) == 'L') && (*(next+2) == 'A') && (*(next+3) == 'S') && (*(next+4) == 'T')) @@ -715,12 +738,14 @@ static int sdl_font_draw(lua_State *L) next++; } - font_make_texture_line(L, s, nb_lines, is_separator); + font_make_texture_line(L, s, nb_lines, is_separator, id_real_line, line_data); if (size > max_size) max_size = size; if (txt) SDL_FreeSurface(txt); SDL_FreeSurface(s); + if (line_data) free(line_data); + lua_pushnumber(L, nb_lines); lua_pushnumber(L, max_size);