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_ */