mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 02:01:38 +00:00
parent
3e24a86b87
commit
c9938e424b
@ -92,7 +92,6 @@ class Menu_view::Cursor : List_model<Cursor>::Element
|
||||
_move_to(_position_from_xml_node(node), Steps{0});
|
||||
}
|
||||
|
||||
|
||||
void draw(Surface<Pixel_rgb888> &pixel_surface,
|
||||
Surface<Pixel_alpha8> &alpha_surface,
|
||||
Point at, unsigned height) const
|
||||
@ -111,36 +110,20 @@ class Menu_view::Cursor : List_model<Cursor>::Element
|
||||
}
|
||||
}
|
||||
|
||||
struct Model_update_policy : List_model<Cursor>::Update_policy
|
||||
bool matches(Xml_node const &node) const
|
||||
{
|
||||
Widget_factory &_factory;
|
||||
Glyph_position &_glyph_position;
|
||||
return _node_name(node) == _name;
|
||||
}
|
||||
|
||||
Model_update_policy(Widget_factory &factory, Glyph_position &glyph_position)
|
||||
:
|
||||
_factory(factory), _glyph_position(glyph_position)
|
||||
{ }
|
||||
static bool type_matches(Xml_node const &node)
|
||||
{
|
||||
return node.has_type("cursor");
|
||||
}
|
||||
|
||||
void destroy_element(Cursor &c) { destroy(_factory.alloc, &c); }
|
||||
|
||||
Cursor &create_element(Xml_node node)
|
||||
{
|
||||
return *new (_factory.alloc)
|
||||
Cursor(node, _factory.animator, _glyph_position, _factory.styles);
|
||||
}
|
||||
|
||||
void update_element(Cursor &c, Xml_node node)
|
||||
{
|
||||
c._move_to(c._position_from_xml_node(node), Steps{12});
|
||||
}
|
||||
|
||||
static bool element_matches_xml_node(Cursor const &c, Xml_node node)
|
||||
{
|
||||
return node.has_type("cursor") && _node_name(node) == c._name;
|
||||
}
|
||||
|
||||
static bool node_is_element(Xml_node node) { return node.has_type("cursor"); }
|
||||
};
|
||||
void update(Xml_node const &node)
|
||||
{
|
||||
_move_to(_position_from_xml_node(node), Steps{12});
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _CURSOR_H_ */
|
||||
|
@ -442,79 +442,12 @@ struct Menu_view::Depgraph_widget : Widget
|
||||
fn(_root_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Customized model-update policy that augments the list of child widgets
|
||||
* with their graph-node topology
|
||||
*/
|
||||
struct Model_update_policy : List_model<Widget>::Update_policy
|
||||
{
|
||||
Widget::Model_update_policy &_generic_model_update_policy;
|
||||
Allocator &_alloc;
|
||||
Animator &_animator;
|
||||
Node_registry &_nodes;
|
||||
|
||||
Model_update_policy(Widget::Model_update_policy &policy,
|
||||
Allocator &alloc, Animator &animator,
|
||||
Node_registry &nodes)
|
||||
:
|
||||
_generic_model_update_policy(policy),
|
||||
_alloc(alloc), _animator(animator), _nodes(nodes)
|
||||
{ }
|
||||
|
||||
void _destroy_node(Registered_node &node)
|
||||
{
|
||||
/*
|
||||
* If a server node vanishes, disconnect all client nodes. The
|
||||
* nodes will be reconnected - if possible - after the model
|
||||
* update.
|
||||
*/
|
||||
node.for_each_dependent_node([&] (Node &dependent) {
|
||||
dependent.cut_dependencies(); });
|
||||
|
||||
Widget &w = node._widget;
|
||||
destroy(_alloc, &node);
|
||||
_generic_model_update_policy.destroy_element(w);
|
||||
}
|
||||
|
||||
void destroy_element(Widget &w)
|
||||
{
|
||||
_nodes.for_each([&] (Registered_node &node) {
|
||||
if (node.belongs_to(w))
|
||||
_destroy_node(node); });
|
||||
}
|
||||
|
||||
/* do not import <dep> nodes as widgets */
|
||||
bool node_is_element(Xml_node node) { return !node.has_type("dep"); }
|
||||
|
||||
Widget &create_element(Xml_node elem_node)
|
||||
{
|
||||
Widget &w = _generic_model_update_policy.create_element(elem_node);
|
||||
new (_alloc) Registered_node(_nodes, _alloc, w, _animator);
|
||||
return w;
|
||||
}
|
||||
|
||||
void update_element(Widget &w, Xml_node elem_node)
|
||||
{
|
||||
_generic_model_update_policy.update_element(w, elem_node);
|
||||
}
|
||||
|
||||
static bool element_matches_xml_node(Widget const &w, Xml_node node)
|
||||
{
|
||||
return Widget::Model_update_policy::element_matches_xml_node(w, node);
|
||||
}
|
||||
|
||||
} _model_update_policy { Widget::_model_update_policy,
|
||||
_factory.alloc, _factory.animator, _nodes };
|
||||
|
||||
Depgraph_widget(Widget_factory &factory, Xml_node node, Unique_id unique_id)
|
||||
:
|
||||
Widget(factory, node, unique_id)
|
||||
{ }
|
||||
|
||||
~Depgraph_widget()
|
||||
{
|
||||
_children.destroy_all_elements(_model_update_policy);
|
||||
}
|
||||
~Depgraph_widget() { _update_children(Xml_node("<empty/>")); }
|
||||
|
||||
void update(Xml_node node) override
|
||||
{
|
||||
@ -529,7 +462,49 @@ struct Menu_view::Depgraph_widget : Widget
|
||||
if (dir_name == "west") _depth_direction = { Depth_direction::WEST };
|
||||
}
|
||||
|
||||
_children.update_from_xml(_model_update_policy, node);
|
||||
_update_children(node);
|
||||
}
|
||||
|
||||
void _update_children(Xml_node const &node)
|
||||
{
|
||||
Allocator &alloc = _factory.alloc;
|
||||
|
||||
update_list_model_from_xml(_children, node,
|
||||
|
||||
/* create */
|
||||
[&] (Xml_node const &node) -> Widget &
|
||||
{
|
||||
Widget &w = _factory.create(node);
|
||||
new (alloc) Registered_node(_nodes, alloc, w, _factory.animator);
|
||||
return w;
|
||||
},
|
||||
|
||||
/* destroy */
|
||||
[&] (Widget &w)
|
||||
{
|
||||
auto destroy_node = [&] (Registered_node &node)
|
||||
{
|
||||
/*
|
||||
* If a server node vanishes, disconnect all client nodes. The
|
||||
* nodes will be reconnected - if possible - after the model
|
||||
* update.
|
||||
*/
|
||||
node.for_each_dependent_node([&] (Node &dependent) {
|
||||
dependent.cut_dependencies(); });
|
||||
|
||||
Widget &w = node._widget;
|
||||
destroy(alloc, &node);
|
||||
_factory.destroy(&w);
|
||||
};
|
||||
|
||||
_nodes.for_each([&] (Registered_node &node) {
|
||||
if (node.belongs_to(w))
|
||||
destroy_node(node); });
|
||||
},
|
||||
|
||||
/* update */
|
||||
[&] (Widget &w, Xml_node const &node) { w.update(node); }
|
||||
);
|
||||
|
||||
/*
|
||||
* Import dependencies
|
||||
|
@ -37,24 +37,47 @@ struct Menu_view::Label_widget : Widget, Cursor::Glyph_position
|
||||
int _min_width = 0;
|
||||
int _min_height = 0;
|
||||
|
||||
Cursor::Model_update_policy _cursor_update_policy;
|
||||
Text_selection::Model_update_policy _selection_update_policy;
|
||||
|
||||
List_model<Cursor> _cursors { };
|
||||
List_model<Text_selection> _selections { };
|
||||
|
||||
Label_widget(Widget_factory &factory, Xml_node node, Unique_id unique_id)
|
||||
:
|
||||
Widget(factory, node, unique_id),
|
||||
_color(factory.animator),
|
||||
_cursor_update_policy(factory, *this),
|
||||
_selection_update_policy(factory.alloc, *this)
|
||||
Widget(factory, node, unique_id), _color(factory.animator)
|
||||
{ }
|
||||
|
||||
~Label_widget()
|
||||
~Label_widget() { _update_children(Xml_node("<empty/>")); }
|
||||
|
||||
void _update_children(Xml_node const &node)
|
||||
{
|
||||
_cursors .destroy_all_elements(_cursor_update_policy);
|
||||
_selections.destroy_all_elements(_selection_update_policy);
|
||||
update_list_model_from_xml(_cursors, node,
|
||||
|
||||
/* create */
|
||||
[&] (Xml_node const &node) -> Cursor & {
|
||||
return *new (_factory.alloc)
|
||||
Cursor(node, _factory.animator, *this, _factory.styles); },
|
||||
|
||||
/* destroy */
|
||||
[&] (Cursor &cursor) { destroy(_factory.alloc, &cursor); },
|
||||
|
||||
/* update */
|
||||
[&] (Cursor &cursor, Xml_node const &node) {
|
||||
cursor.update(node); }
|
||||
);
|
||||
|
||||
update_list_model_from_xml(_selections, node,
|
||||
|
||||
/* create */
|
||||
[&] (Xml_node const &node) -> Text_selection & {
|
||||
return *new (_factory.alloc)
|
||||
Text_selection(node, *this); },
|
||||
|
||||
/* destroy */
|
||||
[&] (Text_selection &t) { destroy(_factory.alloc, &t); },
|
||||
|
||||
/* update */
|
||||
[&] (Text_selection &t, Xml_node const &node) {
|
||||
t.update(node); }
|
||||
);
|
||||
}
|
||||
|
||||
void update(Xml_node node) override
|
||||
@ -81,8 +104,7 @@ struct Menu_view::Label_widget : Widget, Cursor::Glyph_position
|
||||
_min_width = min_w_px.decimal();
|
||||
}
|
||||
|
||||
_cursors .update_from_xml(_cursor_update_policy, node);
|
||||
_selections.update_from_xml(_selection_update_policy, node);
|
||||
_update_children(node);
|
||||
}
|
||||
|
||||
Area min_size() const override
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "depgraph_widget.h"
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/sleep.h>
|
||||
#include <input/event.h>
|
||||
#include <os/reporter.h>
|
||||
#include <timer_session/connection.h>
|
||||
@ -419,27 +420,37 @@ void Menu_view::Main::_handle_frame_timer()
|
||||
}
|
||||
|
||||
|
||||
Menu_view::Widget *
|
||||
Menu_view::Widget_factory::create(Xml_node node)
|
||||
Menu_view::Widget &
|
||||
Menu_view::Widget_factory::create(Xml_node const &node)
|
||||
{
|
||||
Widget *w = nullptr;
|
||||
|
||||
Widget::Unique_id const unique_id(++_unique_id_cnt);
|
||||
|
||||
if (node.has_type("label")) w = new (alloc) Label_widget (*this, node, unique_id);
|
||||
if (node.has_type("button")) w = new (alloc) Button_widget (*this, node, unique_id);
|
||||
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 (node.has_type("depgraph")) w = new (alloc) Depgraph_widget (*this, node, unique_id);
|
||||
if (node.has_type("label")) return *new (alloc) Label_widget (*this, node, unique_id);
|
||||
if (node.has_type("button")) return *new (alloc) Button_widget (*this, node, unique_id);
|
||||
if (node.has_type("vbox")) return *new (alloc) Box_layout_widget (*this, node, unique_id);
|
||||
if (node.has_type("hbox")) return *new (alloc) Box_layout_widget (*this, node, unique_id);
|
||||
if (node.has_type("frame")) return *new (alloc) Frame_widget (*this, node, unique_id);
|
||||
if (node.has_type("float")) return *new (alloc) Float_widget (*this, node, unique_id);
|
||||
if (node.has_type("depgraph")) return *new (alloc) Depgraph_widget (*this, node, unique_id);
|
||||
|
||||
if (!w) {
|
||||
Genode::error("unknown widget type '", node.type(), "'");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* This cannot occur because the 'List_model' ensures that 'create' is only
|
||||
* called for nodes that passed 'node_type_known'.
|
||||
*/
|
||||
error("unknown widget type '", node.type(), "'");
|
||||
sleep_forever();
|
||||
}
|
||||
|
||||
return w;
|
||||
|
||||
bool Menu_view::Widget_factory::node_type_known(Xml_node const &node)
|
||||
{
|
||||
return node.has_type("label")
|
||||
|| node.has_type("button")
|
||||
|| node.has_type("vbox")
|
||||
|| node.has_type("hbox")
|
||||
|| node.has_type("frame")
|
||||
|| node.has_type("float")
|
||||
|| node.has_type("depgraph");
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,39 +87,20 @@ class Menu_view::Text_selection : List_model<Text_selection>::Element
|
||||
color);
|
||||
}
|
||||
|
||||
struct Model_update_policy : List_model<Text_selection>::Update_policy
|
||||
bool matches(Xml_node const &node) const
|
||||
{
|
||||
Allocator &_alloc;
|
||||
Glyph_position &_glyph_position;
|
||||
return _node_name(node) == _name;
|
||||
}
|
||||
|
||||
Model_update_policy(Allocator &alloc, Glyph_position &glyph_position)
|
||||
:
|
||||
_alloc(alloc), _glyph_position(glyph_position)
|
||||
{ }
|
||||
static bool type_matches(Xml_node const &node)
|
||||
{
|
||||
return node.has_type("selection");
|
||||
}
|
||||
|
||||
void destroy_element(Text_selection &t) { destroy(_alloc, &t); }
|
||||
|
||||
Text_selection &create_element(Xml_node node)
|
||||
{
|
||||
return *new (_alloc)
|
||||
Text_selection(node, _glyph_position);
|
||||
}
|
||||
|
||||
void update_element(Text_selection &t, Xml_node node)
|
||||
{
|
||||
t._range = t._range_from_xml_node(node);
|
||||
}
|
||||
|
||||
static bool element_matches_xml_node(Text_selection const &t, Xml_node node)
|
||||
{
|
||||
return node.has_type("selection") && _node_name(node) == t._name;
|
||||
}
|
||||
|
||||
static bool node_is_element(Xml_node node)
|
||||
{
|
||||
return node.has_type("selection");
|
||||
}
|
||||
};
|
||||
void update(Xml_node const &node)
|
||||
{
|
||||
_range = _range_from_xml_node(node);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _TEXT_SELECTION_ */
|
||||
|
@ -126,36 +126,22 @@ class Menu_view::Widget : List_model<Widget>::Element
|
||||
|
||||
List_model<Widget> _children { };
|
||||
|
||||
struct Model_update_policy : List_model<Widget>::Update_policy
|
||||
{
|
||||
Widget_factory &_factory;
|
||||
|
||||
Model_update_policy(Widget_factory &factory) : _factory(factory) { }
|
||||
|
||||
void destroy_element(Widget &w) { _factory.destroy(&w); }
|
||||
|
||||
Widget &create_element(Xml_node elem_node)
|
||||
{
|
||||
if (Widget *w = _factory.create(elem_node))
|
||||
return *w;
|
||||
|
||||
throw Unknown_element_type();
|
||||
}
|
||||
|
||||
void update_element(Widget &w, Xml_node node) { w.update(node); }
|
||||
|
||||
static bool element_matches_xml_node(Widget const &w, Xml_node node)
|
||||
{
|
||||
return node.has_type(w._type_name.string())
|
||||
&& Widget::node_name(node) == w._name
|
||||
&& node_version(node) == w._version;
|
||||
}
|
||||
|
||||
} _model_update_policy { _factory };
|
||||
|
||||
inline void _update_children(Xml_node node)
|
||||
{
|
||||
_children.update_from_xml(_model_update_policy, node);
|
||||
update_list_model_from_xml(_children, node,
|
||||
|
||||
/* create */
|
||||
[&] (Xml_node const &node) -> Widget & {
|
||||
return _factory.create(node); },
|
||||
|
||||
/* destroy */
|
||||
[&] (Widget &w) {
|
||||
_factory.destroy(&w); },
|
||||
|
||||
/* update */
|
||||
[&] (Widget &w, Xml_node const &node) {
|
||||
w.update(node); }
|
||||
);
|
||||
}
|
||||
|
||||
void _draw_children(Surface<Pixel_rgb888> &pixel_surface,
|
||||
@ -230,7 +216,7 @@ class Menu_view::Widget : List_model<Widget>::Element
|
||||
|
||||
virtual ~Widget()
|
||||
{
|
||||
_children.destroy_all_elements(_model_update_policy);
|
||||
_update_children(Xml_node("<empty/>"));
|
||||
}
|
||||
|
||||
bool has_name(Name const &name) const { return name == _name; }
|
||||
@ -320,6 +306,24 @@ class Menu_view::Widget : List_model<Widget>::Element
|
||||
{
|
||||
Genode::print(out, _name);
|
||||
}
|
||||
|
||||
/**
|
||||
* List_model::Element
|
||||
*/
|
||||
bool matches(Xml_node const &node) const
|
||||
{
|
||||
return node.has_type(_type_name.string())
|
||||
&& Widget::node_name(node) == _name
|
||||
&& node_version(node) == _version;
|
||||
}
|
||||
|
||||
/**
|
||||
* List_model::Element
|
||||
*/
|
||||
static bool type_matches(Xml_node const &node)
|
||||
{
|
||||
return Widget_factory::node_type_known(node);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _WIDGET_H_ */
|
||||
|
@ -44,9 +44,11 @@ class Menu_view::Widget_factory
|
||||
alloc(alloc), styles(styles), animator(animator)
|
||||
{ }
|
||||
|
||||
Widget *create(Xml_node node);
|
||||
Widget &create(Xml_node const &);
|
||||
|
||||
void destroy(Widget *widget) { Genode::destroy(alloc, widget); }
|
||||
|
||||
static bool node_type_known(Xml_node const &);
|
||||
};
|
||||
|
||||
#endif /* _WIDGET_FACTORY_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user