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:
parent
1713583a19
commit
582e0e718c
|
@ -78,7 +78,7 @@ class Png_image
|
||||||
_assert_non_null<Read_struct_failed>(
|
_assert_non_null<Read_struct_failed>(
|
||||||
png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0));
|
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);
|
png_set_read_fn(png_ptr, this, callback);
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ class Png_image
|
||||||
* \throw Info_failed
|
* \throw Info_failed
|
||||||
*/
|
*/
|
||||||
Png_image(Genode::Ram_allocator &ram, Genode::Region_map &rm,
|
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)
|
_ram(ram), _rm(rm), _alloc(alloc), _read_struct(data)
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -110,6 +110,9 @@ struct Menu_view::Button_widget : Widget, Animator::Item
|
||||||
_children.for_each([&] (Widget const &child) {
|
_children.for_each([&] (Widget const &child) {
|
||||||
child_min_size = child.min_size(); });
|
child_min_size = child.min_size(); });
|
||||||
|
|
||||||
|
if (!_curr_texture)
|
||||||
|
return child_min_size;
|
||||||
|
|
||||||
/* don't get smaller than the background texture */
|
/* don't get smaller than the background texture */
|
||||||
Area const texture_size = _curr_texture->size();
|
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);
|
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);
|
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) {
|
scratch.apply([&] (Surface<Opaque_pixel> &pixel, Surface<Additive_alpha> &alpha) {
|
||||||
|
|
||||||
|
if (!_curr_texture)
|
||||||
|
return;
|
||||||
|
|
||||||
if (_prev_texture && animated()) {
|
if (_prev_texture && animated()) {
|
||||||
|
|
||||||
int const blend = _blend >> 8;
|
int const blend = _blend >> 8;
|
||||||
|
|
|
@ -64,11 +64,13 @@ struct Menu_view::Frame_widget : Widget
|
||||||
Surface<Pixel_alpha8> &alpha_surface,
|
Surface<Pixel_alpha8> &alpha_surface,
|
||||||
Point at) const override
|
Point at) const override
|
||||||
{
|
{
|
||||||
Icon_painter::paint(pixel_surface, Rect(at, _animated_geometry.area()),
|
if (texture) {
|
||||||
*texture, 255);
|
Icon_painter::paint(pixel_surface, Rect(at, _animated_geometry.area()),
|
||||||
|
*texture, 255);
|
||||||
|
|
||||||
Icon_painter::paint(alpha_surface, Rect(at, _animated_geometry.area()),
|
Icon_painter::paint(alpha_surface, Rect(at, _animated_geometry.area()),
|
||||||
*texture, 255);
|
*texture, 255);
|
||||||
|
}
|
||||||
|
|
||||||
_draw_children(pixel_surface, alpha_surface, at);
|
_draw_children(pixel_surface, alpha_surface, at);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,21 +78,28 @@ class Menu_view::Style_database
|
||||||
struct Texture_entry : List<Texture_entry>::Element
|
struct Texture_entry : List<Texture_entry>::Element
|
||||||
{
|
{
|
||||||
Path const path;
|
Path const path;
|
||||||
::File png_file;
|
File_content png_file;
|
||||||
Png_image png_image;
|
Png_image png_image;
|
||||||
Texture<Pixel_rgb888> &texture;
|
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
|
* Constructor
|
||||||
*
|
*
|
||||||
* \throw Reading_failed
|
* \throw Reading_failed
|
||||||
*/
|
*/
|
||||||
Texture_entry(Ram_allocator &ram, Region_map &rm,
|
Texture_entry(Ram_allocator &ram, Region_map &rm, Allocator &alloc,
|
||||||
Allocator &alloc, Path const &path)
|
Directory const &dir, Path const &path)
|
||||||
:
|
:
|
||||||
path(path),
|
path(path),
|
||||||
png_file(path.string(), alloc),
|
png_file(alloc, dir, path.string(), File_content::Limit{256*1024}),
|
||||||
png_image(ram, rm, alloc, png_file.data<void>()),
|
png_image(ram, rm, alloc, _png_data()),
|
||||||
texture(*png_image.texture<Pixel_rgb888>())
|
texture(*png_image.texture<Pixel_rgb888>())
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
@ -153,7 +160,7 @@ class Menu_view::Style_database
|
||||||
typedef String<64> Style;
|
typedef String<64> Style;
|
||||||
Style const style = node.attribute_value("style", Style("default"));
|
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 {
|
try {
|
||||||
Texture_entry *e = new (_alloc)
|
Texture_entry *e = new (_alloc)
|
||||||
Texture_entry(_ram, _rm, _alloc, path.string());
|
Texture_entry(_ram, _rm, _alloc, _styles_dir, path.string());
|
||||||
|
|
||||||
_textures.insert(e);
|
_textures.insert(e);
|
||||||
return &e->texture;
|
return &e->texture;
|
||||||
|
|
||||||
} catch (Reading_failed) {
|
} catch (...) {
|
||||||
warning("could not read texture data from file \"", path.string(), "\"");
|
warning("could not read texture data from file \"", path.string(), "\"");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue