mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +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`
|
* Types: `text`, `image`, `color`, `indent`, `tree`
|
||||||
* `text`: show cell contents as text
|
* `text`: show cell contents as text
|
||||||
* `image`: cell contents are an image index, use column options to define
|
* `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
|
* `color`: cell contents are a ColorString and define color of following
|
||||||
cell.
|
cell.
|
||||||
* `indent`: cell contents are a number and define indentation of following
|
* `indent`: cell contents are a number and define indentation of following
|
||||||
@ -3269,7 +3269,7 @@ Elements
|
|||||||
* `0=<value>` sets image for image index 0
|
* `0=<value>` sets image for image index 0
|
||||||
* `1=<value>` sets image for image index 1
|
* `1=<value>` sets image for image index 1
|
||||||
* `2=<value>` sets image for image index 2
|
* `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`.
|
non-numeric cells are treated as `0`.
|
||||||
* `color` column options:
|
* `color` column options:
|
||||||
* `span=<value>`: number of following columns to affect
|
* `span=<value>`: number of following columns to affect
|
||||||
|
@ -64,6 +64,41 @@ local inv_style_fs = [[
|
|||||||
list[current_player;main;.5,7;8,4]
|
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
|
local hypertext_basic = [[A hypertext element
|
||||||
<bigger>Normal test</bigger>
|
<bigger>Normal test</bigger>
|
||||||
This is a normal text.
|
This is a normal text.
|
||||||
@ -350,6 +385,10 @@ local pages = {
|
|||||||
"label[11,0.5;Noclip]" ..
|
"label[11,0.5;Noclip]" ..
|
||||||
"container[11.5,1]" .. clip_fs:gsub("%%c", "true") .. "container_end[]",
|
"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
|
-- Hypertext
|
||||||
"size[12,13]real_coordinates[true]" ..
|
"size[12,13]real_coordinates[true]" ..
|
||||||
"container[0.5,0.5]" .. hypertext_fs .. "container_end[]",
|
"container[0.5,0.5]" .. hypertext_fs .. "container_end[]",
|
||||||
@ -477,7 +516,7 @@ local function show_test_formspec(pname)
|
|||||||
page = page()
|
page = page()
|
||||||
end
|
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)
|
minetest.show_formspec(pname, "testformspec:formspec", fs)
|
||||||
end
|
end
|
||||||
|
@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <IGUIFont.h>
|
#include <IGUIFont.h>
|
||||||
#include "client/renderingengine.h"
|
#include "client/renderingengine.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "irrlicht_changes/CGUITTFont.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "client/texturesource.h"
|
#include "client/texturesource.h"
|
||||||
#include "gettime.h"
|
#include "gettime.h"
|
||||||
@ -227,6 +228,8 @@ void GUITable::setTable(const TableOptions &options,
|
|||||||
s32 content_index;
|
s32 content_index;
|
||||||
// Next cell: Width in pixels
|
// Next cell: Width in pixels
|
||||||
s32 content_width;
|
s32 content_width;
|
||||||
|
// Next cell: Image scale (only for "image" column type)
|
||||||
|
f32 image_scale;
|
||||||
// Vector of completed cells in this row
|
// Vector of completed cells in this row
|
||||||
std::vector<Cell> cells;
|
std::vector<Cell> cells;
|
||||||
// Stores colors and how long they last (maximum column index)
|
// 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];
|
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
|
// Get em width. Pedantically speaking, the width of "M" is not
|
||||||
// necessarily the same as the em width, but whatever, close enough.
|
// necessarily the same as the em width, but whatever, close enough.
|
||||||
s32 em = 6;
|
s32 em = 6;
|
||||||
@ -373,8 +387,18 @@ void GUITable::setTable(const TableOptions &options,
|
|||||||
if (row->content_index >= 0)
|
if (row->content_index >= 0)
|
||||||
image = m_images[row->content_index];
|
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
|
// Get content width and update xmax
|
||||||
row->content_width = image ? image->getOriginalSize().Width : 0;
|
|
||||||
row->content_width = MYMAX(row->content_width, width);
|
row->content_width = MYMAX(row->content_width, width);
|
||||||
s32 row_xmax = row->x + padding + row->content_width;
|
s32 row_xmax = row->x + padding + row->content_width;
|
||||||
xmax = MYMAX(xmax, row_xmax);
|
xmax = MYMAX(xmax, row_xmax);
|
||||||
@ -384,6 +408,7 @@ void GUITable::setTable(const TableOptions &options,
|
|||||||
newcell.xmin = rows[i].x + padding;
|
newcell.xmin = rows[i].x + padding;
|
||||||
alignContent(&newcell, xmax, rows[i].content_width, align);
|
alignContent(&newcell, xmax, rows[i].content_width, align);
|
||||||
newcell.content_index = rows[i].content_index;
|
newcell.content_index = rows[i].content_index;
|
||||||
|
newcell.image_scale = rows[i].image_scale;
|
||||||
rows[i].cells.push_back(newcell);
|
rows[i].cells.push_back(newcell);
|
||||||
rows[i].x = newcell.xmax;
|
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];
|
video::ITexture *image = m_images[cell->content_index];
|
||||||
|
|
||||||
if (image) {
|
if (image) {
|
||||||
core::position2d<s32> dest_pos =
|
|
||||||
row_rect.UpperLeftCorner;
|
|
||||||
dest_pos.X += cell->xpos;
|
|
||||||
core::rect<s32> source_rect(
|
core::rect<s32> source_rect(
|
||||||
core::position2d<s32>(0, 0),
|
core::position2d<s32>(0, 0),
|
||||||
image->getOriginalSize());
|
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();
|
s32 rowh = row_rect.getHeight();
|
||||||
|
// Center vertically if needed
|
||||||
if (imgh < rowh)
|
if (imgh < rowh)
|
||||||
dest_pos.Y += (rowh - imgh) / 2;
|
dest_rect += v2s32(0, (rowh - imgh) / 2);
|
||||||
else
|
|
||||||
source_rect.LowerRightCorner.Y = rowh;
|
|
||||||
|
|
||||||
video::SColor color(255, 255, 255, 255);
|
driver->draw2DImage(image, dest_rect, source_rect,
|
||||||
|
&client_clip, nullptr, true);
|
||||||
driver->draw2DImage(image, dest_pos, source_rect,
|
|
||||||
&client_clip, color, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,6 +166,7 @@ protected:
|
|||||||
video::SColor color;
|
video::SColor color;
|
||||||
bool color_defined;
|
bool color_defined;
|
||||||
s32 reported_column;
|
s32 reported_column;
|
||||||
|
f32 image_scale; // only for "image" type columns
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Row {
|
struct Row {
|
||||||
|
Loading…
Reference in New Issue
Block a user