menu_view: make texture handling more robust

This patch improves the robustness of menu_view when encounting missing
textures, which can happen during development when using styled buttons
and frames. With the patch, menu_view outputs diagnostic messages,
pinpointing the problem.

The patch also updates the texture handling to use the 'File_content'
utility and the VFS for obtaining PNG images.

Issue #3629
This commit is contained in:
Norman Feske 2020-02-19 17:21:42 +01:00 committed by Christian Helmuth
parent 1713583a19
commit 582e0e718c
4 changed files with 30 additions and 15 deletions

View File

@ -78,7 +78,7 @@ class Png_image
_assert_non_null<Read_struct_failed>(
png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0));
Read_struct(void *data) : data((png_bytep)data)
Read_struct(void const *data) : data((png_bytep)data)
{
png_set_read_fn(png_ptr, this, callback);
}
@ -174,7 +174,7 @@ class Png_image
* \throw Info_failed
*/
Png_image(Genode::Ram_allocator &ram, Genode::Region_map &rm,
Genode::Allocator &alloc, void *data)
Genode::Allocator &alloc, void const *data)
:
_ram(ram), _rm(rm), _alloc(alloc), _read_struct(data)
{ }

View File

@ -110,6 +110,9 @@ struct Menu_view::Button_widget : Widget, Animator::Item
_children.for_each([&] (Widget const &child) {
child_min_size = child.min_size(); });
if (!_curr_texture)
return child_min_size;
/* don't get smaller than the background texture */
Area const texture_size = _curr_texture->size();
@ -123,7 +126,7 @@ struct Menu_view::Button_widget : Widget, Animator::Item
{
static Scratch_surface scratch(_factory.alloc);
Area const texture_size = _curr_texture->size();
Area const texture_size = _curr_texture ? _curr_texture->size() : Area(0, 0);
Rect const texture_rect(Point(0, 0), texture_size);
/*
@ -133,6 +136,9 @@ struct Menu_view::Button_widget : Widget, Animator::Item
scratch.apply([&] (Surface<Opaque_pixel> &pixel, Surface<Additive_alpha> &alpha) {
if (!_curr_texture)
return;
if (_prev_texture && animated()) {
int const blend = _blend >> 8;

View File

@ -64,11 +64,13 @@ struct Menu_view::Frame_widget : Widget
Surface<Pixel_alpha8> &alpha_surface,
Point at) const override
{
Icon_painter::paint(pixel_surface, Rect(at, _animated_geometry.area()),
*texture, 255);
if (texture) {
Icon_painter::paint(pixel_surface, Rect(at, _animated_geometry.area()),
*texture, 255);
Icon_painter::paint(alpha_surface, Rect(at, _animated_geometry.area()),
*texture, 255);
Icon_painter::paint(alpha_surface, Rect(at, _animated_geometry.area()),
*texture, 255);
}
_draw_children(pixel_surface, alpha_surface, at);
}

View File

@ -78,21 +78,28 @@ class Menu_view::Style_database
struct Texture_entry : List<Texture_entry>::Element
{
Path const path;
::File png_file;
File_content png_file;
Png_image png_image;
Texture<Pixel_rgb888> &texture;
void const *_png_data()
{
void const *result = nullptr;
png_file.bytes([&] (char const *ptr, size_t) { result = ptr; });
return result;
}
/**
* Constructor
*
* \throw Reading_failed
*/
Texture_entry(Ram_allocator &ram, Region_map &rm,
Allocator &alloc, Path const &path)
Texture_entry(Ram_allocator &ram, Region_map &rm, Allocator &alloc,
Directory const &dir, Path const &path)
:
path(path),
png_file(path.string(), alloc),
png_image(ram, rm, alloc, png_file.data<void>()),
png_file(alloc, dir, path.string(), File_content::Limit{256*1024}),
png_image(ram, rm, alloc, _png_data()),
texture(*png_image.texture<Pixel_rgb888>())
{ }
};
@ -153,7 +160,7 @@ class Menu_view::Style_database
typedef String<64> Style;
Style const style = node.attribute_value("style", Style("default"));
return Path("/styles/", node.type(), "/", style, "/", name, ".png");
return Path(node.type(), "/", style, "/", name, ".png");
}
/*
@ -205,12 +212,12 @@ class Menu_view::Style_database
*/
try {
Texture_entry *e = new (_alloc)
Texture_entry(_ram, _rm, _alloc, path.string());
Texture_entry(_ram, _rm, _alloc, _styles_dir, path.string());
_textures.insert(e);
return &e->texture;
} catch (Reading_failed) {
} catch (...) {
warning("could not read texture data from file \"", path.string(), "\"");
return nullptr;
}