mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-07 03:40:15 +00:00
sculpt: make Popup_view::Menu reusable
This commit is contained in:
parent
9be7ce54c2
commit
b91e5353ba
82
repos/gems/src/app/sculpt_manager/model/index_menu.h
Normal file
82
repos/gems/src/app/sculpt_manager/model/index_menu.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* \brief State needed for traversing an index menu
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2023-03-21
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MODEL__INDEX_MENU_H_
|
||||||
|
#define _MODEL__INDEX_MENU_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <depot/archive.h>
|
||||||
|
|
||||||
|
/* local includes */
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
namespace Sculpt { struct Index_menu; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Sculpt::Index_menu
|
||||||
|
{
|
||||||
|
enum { MAX_LEVELS = 5 };
|
||||||
|
|
||||||
|
unsigned _level = 0;
|
||||||
|
|
||||||
|
using Name = String<64>;
|
||||||
|
using User = Depot::Archive::User;
|
||||||
|
|
||||||
|
Name _selected[MAX_LEVELS] { };
|
||||||
|
|
||||||
|
void print(Output &out) const
|
||||||
|
{
|
||||||
|
using Genode::print;
|
||||||
|
for (unsigned i = 0; i < _level; i++) {
|
||||||
|
print(out, _selected[i]);
|
||||||
|
if (i + 1 < _level)
|
||||||
|
print(out, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FN>
|
||||||
|
void _for_each_item(Xml_node const &index, FN const &fn, unsigned level) const
|
||||||
|
{
|
||||||
|
if (level == _level) {
|
||||||
|
index.for_each_sub_node(fn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
index.for_each_sub_node("index", [&] (Xml_node const &index) {
|
||||||
|
if (index.attribute_value("name", Name()) == _selected[level])
|
||||||
|
_for_each_item(index, fn, level + 1); });
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FN>
|
||||||
|
void for_each_item(Xml_node const &index, User const &user, FN const &fn) const
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The index may contain duplicates, evaluate only the first match.
|
||||||
|
*/
|
||||||
|
bool first = true;
|
||||||
|
index.for_each_sub_node("index", [&] (Xml_node const &index) {
|
||||||
|
|
||||||
|
if (index.attribute_value("user", User()) != user)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (first)
|
||||||
|
_for_each_item(index, fn, 0);
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned level() const { return _level; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _MODEL__INDEX_MENU_H_ */
|
@ -35,7 +35,7 @@ void Popup_dialog::_gen_pkg_elements(Xml_generator &xml,
|
|||||||
{
|
{
|
||||||
typedef Component::Info Info;
|
typedef Component::Info Info;
|
||||||
|
|
||||||
_gen_sub_menu_title(xml, "back", Menu::Name("Add ", Pretty(_construction_name)));
|
_gen_sub_menu_title(xml, "back", Index_menu::Name("Add ", Pretty(_construction_name)));
|
||||||
|
|
||||||
_gen_pkg_info(xml, component);
|
_gen_pkg_info(xml, component);
|
||||||
|
|
||||||
@ -186,9 +186,9 @@ void Popup_dialog::_gen_menu_elements(Xml_generator &xml, Xml_node const &depot_
|
|||||||
* Title of index
|
* Title of index
|
||||||
*/
|
*/
|
||||||
if (_state >= INDEX_SHOWN && _state < PKG_SHOWN) {
|
if (_state >= INDEX_SHOWN && _state < PKG_SHOWN) {
|
||||||
Menu::Name title("Depot ", _selected_user);
|
Index_menu::Name title("Depot ", _selected_user);
|
||||||
if (_menu._level)
|
if (_menu._level)
|
||||||
title = Menu::Name(title, " ", _menu, " ");
|
title = Index_menu::Name(title, " ", _menu, " ");
|
||||||
|
|
||||||
_gen_sub_menu_title(xml, "back", title);
|
_gen_sub_menu_title(xml, "back", title);
|
||||||
}
|
}
|
||||||
@ -204,8 +204,8 @@ void Popup_dialog::_gen_menu_elements(Xml_generator &xml, Xml_node const &depot_
|
|||||||
Hoverable_item::Id const id(cnt);
|
Hoverable_item::Id const id(cnt);
|
||||||
|
|
||||||
if (item.has_type("index")) {
|
if (item.has_type("index")) {
|
||||||
auto const name = item.attribute_value("name", Menu::Name());
|
auto const name = item.attribute_value("name", Index_menu::Name());
|
||||||
_gen_menu_entry(xml, id, Menu::Name(name, " ..."), false);
|
_gen_menu_entry(xml, id, Index_menu::Name(name, " ..."), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.has_type("pkg")) {
|
if (item.has_type("pkg")) {
|
||||||
@ -369,13 +369,13 @@ void Popup_dialog::click(Action &action)
|
|||||||
|
|
||||||
/* go one menu up */
|
/* go one menu up */
|
||||||
if (clicked == "back") {
|
if (clicked == "back") {
|
||||||
_menu._selected[_menu._level] = Menu::Name();
|
_menu._selected[_menu._level] = Index_menu::Name();
|
||||||
_menu._level--;
|
_menu._level--;
|
||||||
action.discard_construction();
|
action.discard_construction();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* enter sub menu of index */
|
/* enter sub menu of index */
|
||||||
if (_menu._level < Menu::MAX_LEVELS - 1) {
|
if (_menu._level < Index_menu::MAX_LEVELS - 1) {
|
||||||
|
|
||||||
unsigned cnt = 0;
|
unsigned cnt = 0;
|
||||||
_for_each_menu_item([&] (Xml_node item) {
|
_for_each_menu_item([&] (Xml_node item) {
|
||||||
@ -384,8 +384,8 @@ void Popup_dialog::click(Action &action)
|
|||||||
|
|
||||||
if (item.has_type("index")) {
|
if (item.has_type("index")) {
|
||||||
|
|
||||||
Menu::Name const name =
|
Index_menu::Name const name =
|
||||||
item.attribute_value("name", Menu::Name());
|
item.attribute_value("name", Index_menu::Name());
|
||||||
|
|
||||||
_menu._selected[_menu._level] = name;
|
_menu._selected[_menu._level] = name;
|
||||||
_menu._level++;
|
_menu._level++;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <model/runtime_config.h>
|
#include <model/runtime_config.h>
|
||||||
#include <model/download_queue.h>
|
#include <model/download_queue.h>
|
||||||
#include <model/nic_state.h>
|
#include <model/nic_state.h>
|
||||||
|
#include <model/index_menu.h>
|
||||||
#include <view/dialog.h>
|
#include <view/dialog.h>
|
||||||
#include <view/activatable_item.h>
|
#include <view/activatable_item.h>
|
||||||
#include <depot_query.h>
|
#include <depot_query.h>
|
||||||
@ -158,47 +159,7 @@ struct Sculpt::Popup_dialog : Dialog
|
|||||||
fn(route); }); });
|
fn(route); }); });
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Menu
|
Index_menu _menu { };
|
||||||
{
|
|
||||||
enum { MAX_LEVELS = 5 };
|
|
||||||
|
|
||||||
unsigned _level = 0;
|
|
||||||
|
|
||||||
typedef String<64> Name;
|
|
||||||
|
|
||||||
Name _selected[MAX_LEVELS] { };
|
|
||||||
|
|
||||||
void print(Output &out) const
|
|
||||||
{
|
|
||||||
using Genode::print;
|
|
||||||
for (unsigned i = 0; i < _level; i++) {
|
|
||||||
print(out, _selected[i]);
|
|
||||||
if (i + 1 < _level)
|
|
||||||
print(out, " ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename FN>
|
|
||||||
void _for_each_item(Xml_node index, FN const &fn, unsigned level) const
|
|
||||||
{
|
|
||||||
if (level == _level) {
|
|
||||||
index.for_each_sub_node(fn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
index.for_each_sub_node("index", [&] (Xml_node index) {
|
|
||||||
if (index.attribute_value("name", Name()) == _selected[level])
|
|
||||||
_for_each_item(index, fn, level + 1); });
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename FN>
|
|
||||||
void for_each_item(Xml_node index, FN const &fn) const
|
|
||||||
{
|
|
||||||
_for_each_item(index, fn, 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Menu _menu { };
|
|
||||||
|
|
||||||
Hover_result hover(Xml_node hover) override
|
Hover_result hover(Xml_node hover) override
|
||||||
{
|
{
|
||||||
@ -233,7 +194,7 @@ struct Sculpt::Popup_dialog : Dialog
|
|||||||
|
|
||||||
void _handle_index()
|
void _handle_index()
|
||||||
{
|
{
|
||||||
/* prevent modifications of index while browing it */
|
/* prevent modifications of index while browsing it */
|
||||||
if (_state >= INDEX_SHOWN)
|
if (_state >= INDEX_SHOWN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -343,22 +304,7 @@ struct Sculpt::Popup_dialog : Dialog
|
|||||||
template <typename FN>
|
template <typename FN>
|
||||||
void _for_each_menu_item(FN const &fn) const
|
void _for_each_menu_item(FN const &fn) const
|
||||||
{
|
{
|
||||||
Xml_node index = _index_rom.xml();
|
_menu.for_each_item(_index_rom.xml(), _selected_user, fn);
|
||||||
|
|
||||||
/*
|
|
||||||
* The index may contain duplicates, evaluate only the first match.
|
|
||||||
*/
|
|
||||||
bool first = true;
|
|
||||||
index.for_each_sub_node("index", [&] (Xml_node index) {
|
|
||||||
|
|
||||||
if (index.attribute_value("user", User()) != _selected_user)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (first)
|
|
||||||
_menu.for_each_item(index, fn);
|
|
||||||
|
|
||||||
first = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _gen_info_label(Xml_generator &xml, char const *name,
|
static void _gen_info_label(Xml_generator &xml, char const *name,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user