mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
menu_view: add '<float>' widget
The new widget allows one to align a child widget within a larger parent widget by specifying the boolean attributes 'north', 'south', 'east', and 'west'. If none is specified, the child is centered. If opposite attributes are specified, the child is stretched.
This commit is contained in:
parent
29c6d9ee9d
commit
569741faf2
@ -38,6 +38,7 @@ namespace Menu_view {
|
||||
struct Button_widget;
|
||||
struct Label_widget;
|
||||
struct Box_layout_widget;
|
||||
struct Float_widget;
|
||||
struct Widget_factory;
|
||||
struct Main;
|
||||
|
||||
@ -563,6 +564,69 @@ struct Menu_view::Box_layout_widget : Widget
|
||||
};
|
||||
|
||||
|
||||
struct Menu_view::Float_widget : Widget
|
||||
{
|
||||
bool _north = false, _south = false, _east = false, _west = false;
|
||||
|
||||
Float_widget(Widget_factory &factory, Xml_node node, Unique_id unique_id)
|
||||
: Widget(factory, node, unique_id) { }
|
||||
|
||||
void _place_child(Widget &child)
|
||||
{
|
||||
Area const child_min = child.min_size();
|
||||
|
||||
/* space around the minimal-sized child */
|
||||
int const w_space = geometry.w() - child_min.w();
|
||||
int const h_space = geometry.h() - child_min.h();
|
||||
|
||||
/* stretch child size opposite attributes are specified */
|
||||
int const w = (_east && _west) ? geometry.w() : child_min.w();
|
||||
int const h = (_north && _south) ? geometry.h() : child_min.h();
|
||||
|
||||
/* align / center child position */
|
||||
int const x = _east ? 0 : _west ? w_space : w_space / 2;
|
||||
int const y = _north ? 0 : _south ? h_space : h_space / 2;
|
||||
|
||||
child.geometry = Rect(Point(x, y), Area(w, h));
|
||||
}
|
||||
|
||||
void update(Xml_node node) override
|
||||
{
|
||||
_update_child(node);
|
||||
|
||||
_north = node.attribute_value("north", false),
|
||||
_south = node.attribute_value("south", false),
|
||||
_east = node.attribute_value("east", false),
|
||||
_west = node.attribute_value("west", false);
|
||||
|
||||
if (Widget *child = _children.first())
|
||||
_place_child(*child);
|
||||
}
|
||||
|
||||
Area min_size() const override
|
||||
{
|
||||
/* determine minimum child size */
|
||||
Widget const * const child = _children.first();
|
||||
return child ? child->min_size() : Area(0, 0);
|
||||
}
|
||||
|
||||
void draw(Surface<Pixel_rgb888> &pixel_surface,
|
||||
Surface<Pixel_alpha8> &alpha_surface,
|
||||
Point at) const
|
||||
{
|
||||
_draw_children(pixel_surface, alpha_surface, at);
|
||||
}
|
||||
|
||||
void _layout() override
|
||||
{
|
||||
if (Widget *child = _children.first()) {
|
||||
_place_child(*child);
|
||||
child->size(child->geometry.area());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
namespace Menu_view { template <typename PT> class Scratch_surface; }
|
||||
|
||||
|
||||
@ -831,6 +895,7 @@ Menu_view::Widget_factory::create(Xml_node node)
|
||||
if (node.has_type("vbox")) w = new (alloc) Box_layout_widget (*this, node, unique_id);
|
||||
if (node.has_type("hbox")) w = new (alloc) Box_layout_widget (*this, node, unique_id);
|
||||
if (node.has_type("frame")) w = new (alloc) Frame_widget (*this, node, unique_id);
|
||||
if (node.has_type("float")) w = new (alloc) Float_widget (*this, node, unique_id);
|
||||
|
||||
if (!w) {
|
||||
Genode::error("unknown widget type '", node.type(), "'");
|
||||
|
Loading…
Reference in New Issue
Block a user