diff --git a/repos/gems/run/leitzentrale.run b/repos/gems/run/leitzentrale.run
index 7d0278879f..731526712d 100644
--- a/repos/gems/run/leitzentrale.run
+++ b/repos/gems/run/leitzentrale.run
@@ -84,6 +84,8 @@ install_config {
report="nitpicker -> hover"/>
+
@@ -253,6 +255,8 @@ install_config {
+
+
@@ -267,6 +271,8 @@ install_config {
+
+
diff --git a/repos/gems/run/sculpt.run b/repos/gems/run/sculpt.run
index 9ab37f0627..12dae2dbbe 100644
--- a/repos/gems/run/sculpt.run
+++ b/repos/gems/run/sculpt.run
@@ -72,6 +72,8 @@ install_config {
report="nitpicker -> displays"/>
+
@@ -383,6 +385,8 @@ install_config {
+
+
@@ -433,6 +437,8 @@ install_config {
+
+
diff --git a/repos/gems/run/sculpt/leitzentrale.config b/repos/gems/run/sculpt/leitzentrale.config
index ff8aae2020..961048ed20 100644
--- a/repos/gems/run/sculpt/leitzentrale.config
+++ b/repos/gems/run/sculpt/leitzentrale.config
@@ -185,6 +185,7 @@
+
diff --git a/repos/gems/src/app/sculpt_manager/graph.h b/repos/gems/src/app/sculpt_manager/graph.h
index 028039b2c3..becb75a9ec 100644
--- a/repos/gems/src/app/sculpt_manager/graph.h
+++ b/repos/gems/src/app/sculpt_manager/graph.h
@@ -23,6 +23,7 @@
/* local includes */
#include
#include
+#include
namespace Sculpt { struct Graph; }
@@ -31,6 +32,8 @@ struct Sculpt::Graph
{
Env &_env;
+ Runtime_state &_runtime_state;
+
Storage_target const &_sculpt_partition;
Expanding_reporter _graph_dialog_reporter { _env, "dialog", "runtime_view_dialog" };
@@ -42,9 +45,18 @@ struct Sculpt::Graph
*/
Attached_rom_dataspace _runtime_config_rom { _env, "config -> managed/runtime" };
+ Attached_rom_dataspace _hover_rom { _env, "runtime_view_hover" };
+
Signal_handler _runtime_config_handler {
_env.ep(), *this, &Graph::_handle_runtime_config };
+ Signal_handler _hover_handler {
+ _env.ep(), *this, &Graph::_handle_hover };
+
+ Hoverable_item _node_button_item { };
+
+ bool _hovered = false;
+
typedef Start_name Node_name;
/**
@@ -93,10 +105,8 @@ struct Sculpt::Graph
});
}
- void _handle_runtime_config()
+ void _gen_graph_dialog()
{
- _runtime_config_rom.update();
-
Xml_node const config = _runtime_config_rom.xml();
_graph_dialog_reporter.generate([&] (Xml_generator &xml) {
@@ -107,6 +117,8 @@ struct Sculpt::Graph
Start_name const name = start.attribute_value("name", Start_name());
+ Runtime_state::Info const info = _runtime_state.info(name);
+
gen_named_node(xml, "frame", name, [&] () {
Node_name primary_dep = _primary_dependency(start);
@@ -117,10 +129,33 @@ struct Sculpt::Graph
if (primary_dep.valid())
xml.attribute("dep", primary_dep);
- gen_named_node(xml, "button", name, [&] () {
- xml.node("label", [&] () {
- xml.attribute("text", name);
+ xml.node("vbox", [&] () {
+
+ gen_named_node(xml, "button", name, [&] () {
+ _node_button_item.gen_button_attr(xml, name);
+
+ if (info.selected)
+ xml.attribute("selected", "yes");
+
+ xml.node("label", [&] () {
+ xml.attribute("text", name);
+ });
});
+
+ if (info.selected) {
+
+ String<100> const
+ ram (Capacity{info.assigned_ram - info.avail_ram}, " / ",
+ Capacity{info.assigned_ram}),
+ caps(info.assigned_caps - info.avail_caps, " / ",
+ info.assigned_caps, " caps");
+
+ gen_named_node(xml, "label", "ram", [&] () {
+ xml.attribute("text", ram); });
+
+ gen_named_node(xml, "label", "caps", [&] () {
+ xml.attribute("text", caps); });
+ }
});
});
});
@@ -129,7 +164,9 @@ struct Sculpt::Graph
Start_name const name = start.attribute_value("name", Start_name());
- bool const show_details = false;
+ Runtime_state::Info const info = _runtime_state.info(name);
+
+ bool const show_details = info.selected;
if (show_details) {
_for_each_secondary_dep(start, [&] (Start_name const &dep) {
@@ -144,11 +181,45 @@ struct Sculpt::Graph
});
}
- Graph(Env &env, Storage_target const &sculpt_partition)
+ void _handle_runtime_config()
+ {
+ _runtime_config_rom.update();
+
+ _gen_graph_dialog();
+ }
+
+ void _handle_hover()
+ {
+ _hover_rom.update();
+
+ Xml_node const hover = _hover_rom.xml();
+
+ _hovered = (hover.num_sub_nodes() != 0);
+
+ bool const changed =
+ _node_button_item.match(hover, "dialog", "depgraph", "frame", "vbox", "button", "name");
+
+ if (changed)
+ _gen_graph_dialog();
+ }
+
+ Graph(Env &env, Runtime_state &runtime_state,
+ Storage_target const &sculpt_partition)
:
- _env(env), _sculpt_partition(sculpt_partition)
+ _env(env), _runtime_state(runtime_state), _sculpt_partition(sculpt_partition)
{
_runtime_config_rom.sigh(_runtime_config_handler);
+ _hover_rom.sigh(_hover_handler);
+ }
+
+ bool hovered() const { return _hovered; }
+
+ void click()
+ {
+ if (_node_button_item._hovered.valid()) {
+ _runtime_state.toggle_selection(_node_button_item._hovered);
+ _gen_graph_dialog();
+ }
}
};
diff --git a/repos/gems/src/app/sculpt_manager/main.cc b/repos/gems/src/app/sculpt_manager/main.cc
index 9679bd4a29..b84d5e8569 100644
--- a/repos/gems/src/app/sculpt_manager/main.cc
+++ b/repos/gems/src/app/sculpt_manager/main.cc
@@ -297,6 +297,8 @@ struct Sculpt::Main : Input_event_handler,
if (_hovered_dialog == Hovered::STORAGE) _storage.dialog.click(_storage);
if (_hovered_dialog == Hovered::NETWORK) _network.dialog.click(_network);
if (_hovered_dialog == Hovered::RUNTIME) _network.dialog.click(_network);
+
+ if (_graph.hovered()) _graph.click();
}
if (ev.key_release(Input::BTN_LEFT))
@@ -377,7 +379,7 @@ struct Sculpt::Main : Input_event_handler,
** Runtime graph **
*******************/
- Graph _graph { _env, _storage._sculpt_partition };
+ Graph _graph { _env, _runtime_state, _storage._sculpt_partition };
Main(Env &env) : _env(env)
diff --git a/repos/gems/src/app/sculpt_manager/model/runtime_state.h b/repos/gems/src/app/sculpt_manager/model/runtime_state.h
index 34ee5c3c6f..f5416dc358 100644
--- a/repos/gems/src/app/sculpt_manager/model/runtime_state.h
+++ b/repos/gems/src/app/sculpt_manager/model/runtime_state.h
@@ -26,6 +26,19 @@ namespace Sculpt { class Runtime_state; }
class Sculpt::Runtime_state : public Runtime_info
{
+ public:
+
+ struct Info
+ {
+ bool selected;
+
+ unsigned long assigned_ram;
+ unsigned long avail_ram;
+
+ unsigned long assigned_caps;
+ unsigned long avail_caps;
+ };
+
private:
Allocator &_alloc;
@@ -34,6 +47,8 @@ class Sculpt::Runtime_state : public Runtime_info
{
Start_name const name;
+ Info info { false, 0, 0, 0, 0 };
+
Child(Start_name const &name) : name(name) { }
};
@@ -53,7 +68,22 @@ class Sculpt::Runtime_state : public Runtime_info
Child(node.attribute_value("name", Start_name()));
}
- void update_element(Child &, Xml_node) { }
+ void update_element(Child &child, Xml_node node)
+ {
+ if (node.has_sub_node("ram")) {
+ Xml_node const ram = node.sub_node("ram");
+ child.info.assigned_ram = max(ram.attribute_value("assigned", Number_of_bytes()),
+ ram.attribute_value("quota", Number_of_bytes()));
+ child.info.avail_ram = ram.attribute_value("avail", Number_of_bytes());
+ }
+
+ if (node.has_sub_node("caps")) {
+ Xml_node const caps = node.sub_node("caps");
+ child.info.assigned_caps = max(caps.attribute_value("assigned", 0UL),
+ caps.attribute_value("quota", 0UL));
+ child.info.avail_caps = caps.attribute_value("avail", 0UL);
+ }
+ }
static bool element_matches_xml_node(Child const &elem, Xml_node node)
{
@@ -82,6 +112,21 @@ class Sculpt::Runtime_state : public Runtime_info
result = true; });
return result;
}
+
+ Info info(Start_name const &name) const
+ {
+ Info result { .selected = false, 0, 0, 0, 0 };
+ _children.for_each([&] (Child const &child) {
+ if (child.name == name)
+ result = child.info; });
+ return result;
+ }
+
+ void toggle_selection(Start_name const &name)
+ {
+ _children.for_each([&] (Child &child) {
+ child.info.selected = (child.name == name) && !child.info.selected; });
+ }
};
#endif /* _MODEL__RUNTIME_STATE_H_ */