mirror of
https://github.com/minetest/minetest.git
synced 2024-11-22 23:53:44 +01:00
GUITable: Scale images with display density / row height (#14709)
This commit is contained in:
parent
8ed55b3aff
commit
fcb4f258f5
@ -3248,7 +3248,7 @@ Elements
|
||||
* Types: `text`, `image`, `color`, `indent`, `tree`
|
||||
* `text`: show cell contents as text
|
||||
* `image`: cell contents are an image index, use column options to define
|
||||
images.
|
||||
images. images are scaled down to fit the row height if necessary.
|
||||
* `color`: cell contents are a ColorString and define color of following
|
||||
cell.
|
||||
* `indent`: cell contents are a number and define indentation of following
|
||||
@ -3269,7 +3269,7 @@ Elements
|
||||
* `0=<value>` sets image for image index 0
|
||||
* `1=<value>` sets image for image index 1
|
||||
* `2=<value>` sets image for image index 2
|
||||
* and so on; defined indices need not be contiguous empty or
|
||||
* and so on; defined indices need not be contiguous. empty or
|
||||
non-numeric cells are treated as `0`.
|
||||
* `color` column options:
|
||||
* `span=<value>`: number of following columns to affect
|
||||
|
@ -64,6 +64,41 @@ local inv_style_fs = [[
|
||||
list[current_player;main;.5,7;8,4]
|
||||
]]
|
||||
|
||||
-- Some textures from textures/base/pack and Devtest, with many different sizes
|
||||
-- and aspect ratios.
|
||||
local image_column = "image,0=logo.png,1=rare_controls.png,2=checkbox_16.png," ..
|
||||
"3=checkbox_32.png,4=checkbox_64.png,5=default_lava.png," ..
|
||||
"6=progress_bar.png,7=progress_bar_bg.png"
|
||||
local words = {
|
||||
"esciunt", "repudiandae", "repellat", "voluptatem", "autem", "vitae", "et",
|
||||
"minima", "quasi", "facere", "nihil", "ea", "nemo", "rem", "non", "eos",
|
||||
"laudantium", "eveniet", "veritatis",
|
||||
}
|
||||
|
||||
local reseed = math.random(2^31-1)
|
||||
math.randomseed(1337)
|
||||
|
||||
local table_content = {}
|
||||
for i = 1, 100 do
|
||||
table.insert(table_content, words[math.random(#words)])
|
||||
table.insert(table_content, words[math.random(#words)])
|
||||
table.insert(table_content, words[math.random(#words)])
|
||||
table.insert(table_content, math.random(0, 7))
|
||||
table.insert(table_content, math.random(0, 7))
|
||||
table.insert(table_content, math.random(0, 7))
|
||||
table.insert(table_content, words[math.random(#words)])
|
||||
end
|
||||
|
||||
math.randomseed(reseed)
|
||||
|
||||
local table_fs = table.concat({
|
||||
"tablecolumns[text,align=left;text,align=right;text,align=center;",
|
||||
image_column, ",align=left;",
|
||||
image_column, ",align=right;",
|
||||
image_column, ",align=center;text,align=right]",
|
||||
"table[0,0;17,12;the_table;", table.concat(table_content, ","), ";1]"
|
||||
})
|
||||
|
||||
local hypertext_basic = [[A hypertext element
|
||||
<bigger>Normal test</bigger>
|
||||
This is a normal text.
|
||||
@ -350,6 +385,10 @@ local pages = {
|
||||
"label[11,0.5;Noclip]" ..
|
||||
"container[11.5,1]" .. clip_fs:gsub("%%c", "true") .. "container_end[]",
|
||||
|
||||
-- Table
|
||||
"size[18,13]real_coordinates[true]" ..
|
||||
"container[0.5,0.5]" .. table_fs.. "container_end[]",
|
||||
|
||||
-- Hypertext
|
||||
"size[12,13]real_coordinates[true]" ..
|
||||
"container[0.5,0.5]" .. hypertext_fs .. "container_end[]",
|
||||
@ -477,7 +516,7 @@ local function show_test_formspec(pname)
|
||||
page = page()
|
||||
end
|
||||
|
||||
local fs = page .. "tabheader[0,0;11,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Window,Anim,Model,ScrollC,Sound,Background,Unsized;" .. page_id .. ";false;false]"
|
||||
local fs = page .. "tabheader[0,0;11,0.65;maintabs;Real Coord,Styles,Noclip,Table,Hypertext,Tabs,Invs,Window,Anim,Model,ScrollC,Sound,Background,Unsized;" .. page_id .. ";false;false]"
|
||||
|
||||
minetest.show_formspec(pname, "testformspec:formspec", fs)
|
||||
end
|
||||
|
@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <IGUIFont.h>
|
||||
#include "client/renderingengine.h"
|
||||
#include "debug.h"
|
||||
#include "irrlicht_changes/CGUITTFont.h"
|
||||
#include "log.h"
|
||||
#include "client/texturesource.h"
|
||||
#include "gettime.h"
|
||||
@ -227,6 +228,8 @@ void GUITable::setTable(const TableOptions &options,
|
||||
s32 content_index;
|
||||
// Next cell: Width in pixels
|
||||
s32 content_width;
|
||||
// Next cell: Image scale (only for "image" column type)
|
||||
f32 image_scale;
|
||||
// Vector of completed cells in this row
|
||||
std::vector<Cell> cells;
|
||||
// Stores colors and how long they last (maximum column index)
|
||||
@ -236,6 +239,17 @@ void GUITable::setTable(const TableOptions &options,
|
||||
};
|
||||
TempRow *rows = new TempRow[rowcount];
|
||||
|
||||
CGUITTFont *ttfont = dynamic_cast<CGUITTFont *>(m_font);
|
||||
f32 desired_image_scale = 1.0f;
|
||||
if (ttfont) {
|
||||
// This gives us the effective font size, which is chosen taking display
|
||||
// density and gui_scaling into account.
|
||||
// Since row height scales with font size, this gives better results than
|
||||
// just using display density and gui_scaling when a non-standard font
|
||||
// size is used (e.g. Android default of 14).
|
||||
desired_image_scale = std::max(1.0f, ttfont->getFontSize() / 16.0f);
|
||||
}
|
||||
|
||||
// Get em width. Pedantically speaking, the width of "M" is not
|
||||
// necessarily the same as the em width, but whatever, close enough.
|
||||
s32 em = 6;
|
||||
@ -373,8 +387,18 @@ void GUITable::setTable(const TableOptions &options,
|
||||
if (row->content_index >= 0)
|
||||
image = m_images[row->content_index];
|
||||
|
||||
row->image_scale = 1.0f;
|
||||
row->content_width = 0;
|
||||
if (image) {
|
||||
f32 max_image_scale = (f32)m_rowheight / (f32)image->getOriginalSize().Height;
|
||||
// Scale with display density and make sure it fits into the row
|
||||
row->image_scale = std::min(desired_image_scale, max_image_scale);
|
||||
// When upscaling, fractional factors would cause artifacts
|
||||
if (row->image_scale > 1.0f)
|
||||
row->image_scale = std::floor(row->image_scale);
|
||||
row->content_width = image->getOriginalSize().Width * row->image_scale;
|
||||
}
|
||||
// Get content width and update xmax
|
||||
row->content_width = image ? image->getOriginalSize().Width : 0;
|
||||
row->content_width = MYMAX(row->content_width, width);
|
||||
s32 row_xmax = row->x + padding + row->content_width;
|
||||
xmax = MYMAX(xmax, row_xmax);
|
||||
@ -384,6 +408,7 @@ void GUITable::setTable(const TableOptions &options,
|
||||
newcell.xmin = rows[i].x + padding;
|
||||
alignContent(&newcell, xmax, rows[i].content_width, align);
|
||||
newcell.content_index = rows[i].content_index;
|
||||
newcell.image_scale = rows[i].image_scale;
|
||||
rows[i].cells.push_back(newcell);
|
||||
rows[i].x = newcell.xmax;
|
||||
}
|
||||
@ -740,23 +765,23 @@ void GUITable::drawCell(const Cell *cell, video::SColor color,
|
||||
video::ITexture *image = m_images[cell->content_index];
|
||||
|
||||
if (image) {
|
||||
core::position2d<s32> dest_pos =
|
||||
row_rect.UpperLeftCorner;
|
||||
dest_pos.X += cell->xpos;
|
||||
core::rect<s32> source_rect(
|
||||
core::position2d<s32>(0, 0),
|
||||
image->getOriginalSize());
|
||||
s32 imgh = source_rect.LowerRightCorner.Y;
|
||||
core::rect<s32> dest_rect(
|
||||
0, 0,
|
||||
image->getOriginalSize().Width * cell->image_scale,
|
||||
image->getOriginalSize().Height * cell->image_scale);
|
||||
dest_rect += row_rect.UpperLeftCorner + v2s32(cell->xpos, 0);
|
||||
|
||||
s32 imgh = dest_rect.getHeight();
|
||||
s32 rowh = row_rect.getHeight();
|
||||
// Center vertically if needed
|
||||
if (imgh < rowh)
|
||||
dest_pos.Y += (rowh - imgh) / 2;
|
||||
else
|
||||
source_rect.LowerRightCorner.Y = rowh;
|
||||
dest_rect += v2s32(0, (rowh - imgh) / 2);
|
||||
|
||||
video::SColor color(255, 255, 255, 255);
|
||||
|
||||
driver->draw2DImage(image, dest_pos, source_rect,
|
||||
&client_clip, color, true);
|
||||
driver->draw2DImage(image, dest_rect, source_rect,
|
||||
&client_clip, nullptr, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,6 +166,7 @@ protected:
|
||||
video::SColor color;
|
||||
bool color_defined;
|
||||
s32 reported_column;
|
||||
f32 image_scale; // only for "image" type columns
|
||||
};
|
||||
|
||||
struct Row {
|
||||
|
Loading…
Reference in New Issue
Block a user