mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 10:46:25 +00:00
sculpt: refine keyboard entry of new depot URL
This patch includes the system dialog in the global keyboard focus handling, supports hovering of the "Edit" and "Add" buttons, allows the use of the enter key to finish URL editing, and triggers a re-scan of depot users after adding a new one. Issue #4820
This commit is contained in:
parent
937ddd012b
commit
43d51c4499
@ -22,18 +22,21 @@
|
||||
#include <types.h>
|
||||
#include <view/network_dialog.h>
|
||||
#include <view/panel_dialog.h>
|
||||
#include <view/system_dialog.h>
|
||||
|
||||
namespace Sculpt { struct Keyboard_focus; }
|
||||
|
||||
struct Sculpt::Keyboard_focus
|
||||
{
|
||||
enum Target { INITIAL, WPA_PASSPHRASE, WM } target { INITIAL };
|
||||
enum Target { INITIAL, WPA_PASSPHRASE, SYSTEM_DIALOG, WM } target { INITIAL };
|
||||
|
||||
Expanding_reporter _focus_reporter;
|
||||
|
||||
Network_dialog const &_network_dialog;
|
||||
Wpa_passphrase &_wpa_passphrase;
|
||||
Panel_dialog::State const &_panel;
|
||||
System_dialog const &_system_dialog;
|
||||
bool const &_system_visible;
|
||||
|
||||
void update()
|
||||
{
|
||||
@ -44,6 +47,9 @@ struct Sculpt::Keyboard_focus
|
||||
if (_panel.network_visible() && _network_dialog.need_keyboard_focus_for_passphrase())
|
||||
target = WPA_PASSPHRASE;
|
||||
|
||||
if (_system_dialog.keyboard_needed() && _system_visible)
|
||||
target = SYSTEM_DIALOG;
|
||||
|
||||
if (orig_target == target)
|
||||
return;
|
||||
|
||||
@ -54,6 +60,7 @@ struct Sculpt::Keyboard_focus
|
||||
switch (target) {
|
||||
|
||||
case WPA_PASSPHRASE:
|
||||
case SYSTEM_DIALOG:
|
||||
xml.attribute("label", "manager -> input");
|
||||
break;
|
||||
|
||||
@ -68,12 +75,16 @@ struct Sculpt::Keyboard_focus
|
||||
Keyboard_focus(Env &env,
|
||||
Network_dialog const &network_dialog,
|
||||
Wpa_passphrase &wpa_passphrase,
|
||||
Panel_dialog::State const &panel)
|
||||
Panel_dialog::State const &panel,
|
||||
System_dialog const &system_dialog,
|
||||
bool const &system_visible)
|
||||
:
|
||||
_focus_reporter(env, "focus", "focus"),
|
||||
_network_dialog(network_dialog),
|
||||
_wpa_passphrase(wpa_passphrase),
|
||||
_panel(panel)
|
||||
_panel(panel),
|
||||
_system_dialog(system_dialog),
|
||||
_system_visible(system_visible)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
@ -672,7 +672,8 @@ struct Sculpt::Main : Input_event_handler,
|
||||
_try_handle_click();
|
||||
}
|
||||
|
||||
Keyboard_focus _keyboard_focus { _env, _network.dialog, _network.wpa_passphrase, *this };
|
||||
Keyboard_focus _keyboard_focus { _env, _network.dialog, _network.wpa_passphrase,
|
||||
*this, _system_dialog, _system_visible };
|
||||
|
||||
Constructible<Input::Seq_number> _clicked_seq_number { };
|
||||
Constructible<Input::Seq_number> _clacked_seq_number { };
|
||||
@ -784,11 +785,34 @@ struct Sculpt::Main : Input_event_handler,
|
||||
}
|
||||
}
|
||||
|
||||
bool _keyboard_input_consumed_by_sculpt_manager() const
|
||||
{
|
||||
return (_keyboard_focus.target == Keyboard_focus::WPA_PASSPHRASE)
|
||||
|| (_system_visible && _system_dialog.keyboard_needed());
|
||||
}
|
||||
|
||||
struct Keyboard_focus_guard
|
||||
{
|
||||
Main &_main;
|
||||
|
||||
bool const _orig = _main._keyboard_input_consumed_by_sculpt_manager();
|
||||
|
||||
Keyboard_focus_guard(Main &main) : _main(main) { }
|
||||
|
||||
~Keyboard_focus_guard()
|
||||
{
|
||||
if (_orig != _main._keyboard_input_consumed_by_sculpt_manager())
|
||||
_main._keyboard_focus.update();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Menu_view::Hover_update_handler interface
|
||||
*/
|
||||
void menu_view_hover_updated() override
|
||||
{
|
||||
Keyboard_focus_guard focus_guard { *this };
|
||||
|
||||
if (_clicked_seq_number.constructed())
|
||||
_try_handle_click();
|
||||
|
||||
@ -803,6 +827,8 @@ struct Sculpt::Main : Input_event_handler,
|
||||
{
|
||||
bool need_generate_dialog = false;
|
||||
|
||||
Keyboard_focus_guard focus_guard { *this };
|
||||
|
||||
if (ev.key_press(Input::BTN_LEFT) || ev.touch()) {
|
||||
_clicked_seq_number.construct(_global_input_seq_number);
|
||||
_try_handle_click();
|
||||
@ -822,9 +848,6 @@ struct Sculpt::Main : Input_event_handler,
|
||||
need_generate_dialog = true;
|
||||
});
|
||||
|
||||
if (ev.press())
|
||||
_keyboard_focus.update();
|
||||
|
||||
if (need_generate_dialog)
|
||||
generate_dialog();
|
||||
}
|
||||
@ -1710,6 +1733,7 @@ void Sculpt::Main::_handle_window_layout()
|
||||
|
||||
/* define window-manager focus */
|
||||
_wm_focus.generate([&] (Xml_generator &xml) {
|
||||
|
||||
_window_list.xml().for_each_sub_node("window", [&] (Xml_node win) {
|
||||
Label const label = win.attribute_value("label", Label());
|
||||
|
||||
@ -1988,6 +2012,10 @@ void Sculpt::Main::_handle_runtime_state()
|
||||
if (_index_update_queue.download_count != orig_download_count)
|
||||
_deploy.update_installation();
|
||||
|
||||
/* update depot-user selection after adding new depot URL */
|
||||
if (_system_visible)
|
||||
trigger_depot_query();
|
||||
|
||||
/*
|
||||
* The removal of an index file may have completed, re-query index
|
||||
* files to reflect this change at the depot selection menu.
|
||||
|
@ -14,6 +14,7 @@
|
||||
#ifndef _MODEL__DOWNLOAD_QUEUE_H_
|
||||
#define _MODEL__DOWNLOAD_QUEUE_H_
|
||||
|
||||
#include <depot/archive.h>
|
||||
#include <base/registry.h>
|
||||
#include <types.h>
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define _MODEL__INDEX_UPDATE_QUEUE_H_
|
||||
|
||||
#include <model/download_queue.h>
|
||||
#include <model/file_operation_queue.h>
|
||||
#include <types.h>
|
||||
|
||||
namespace Sculpt { struct Index_update_queue; }
|
||||
|
@ -49,6 +49,8 @@ struct Sculpt::Depot_users_dialog
|
||||
|
||||
bool _unfolded = false;
|
||||
|
||||
bool _selected_user_exists = false;
|
||||
|
||||
Hoverable_item _user { };
|
||||
Hoverable_item _button { };
|
||||
|
||||
@ -124,8 +126,9 @@ struct Sculpt::Depot_users_dialog
|
||||
bool const selected = (name == _selected);
|
||||
Url const url = _url(user);
|
||||
Url const label = Depot_url::from_string(url).valid() ? url : Url(name);
|
||||
bool const show_all = _unfolded || !_selected_user_exists;
|
||||
|
||||
if (!selected && !_unfolded)
|
||||
if (!selected && !show_all)
|
||||
return;
|
||||
|
||||
_gen_item(xml, name,
|
||||
@ -133,7 +136,7 @@ struct Sculpt::Depot_users_dialog
|
||||
[&] /* right */ { }
|
||||
);
|
||||
|
||||
if (_unfolded && !last)
|
||||
if (show_all && !last)
|
||||
_gen_vspacer(xml, String<64>("below ", name).string());
|
||||
}
|
||||
|
||||
@ -173,6 +176,9 @@ struct Sculpt::Depot_users_dialog
|
||||
gen_named_node(xml, "button", "add", [&] {
|
||||
if (!url_valid)
|
||||
xml.attribute("style", "unimportant");
|
||||
else
|
||||
_button.gen_hovered_attr(xml, "add");
|
||||
|
||||
xml.node("label", [&] {
|
||||
if (!url_valid)
|
||||
xml.attribute("style", "unimportant");
|
||||
@ -180,6 +186,7 @@ struct Sculpt::Depot_users_dialog
|
||||
});
|
||||
} else {
|
||||
gen_named_node(xml, "button", "edit", [&] {
|
||||
_button.gen_hovered_attr(xml, "edit");
|
||||
xml.node("label", [&] {
|
||||
xml.attribute("text", "Edit"); }); });
|
||||
}
|
||||
@ -208,12 +215,12 @@ struct Sculpt::Depot_users_dialog
|
||||
bool const last = (--remain_count == 0);
|
||||
_gen_entry(xml, user, last); });
|
||||
|
||||
if (_unfolded)
|
||||
if (_unfolded || !_selected_user_exists)
|
||||
_gen_add_entry(xml, depot_users);
|
||||
});
|
||||
});
|
||||
|
||||
if (!_unfolded && !known_pubkey) {
|
||||
if (!_unfolded && !known_pubkey && _selected_user_exists) {
|
||||
gen_named_node(xml, "button", "pubkey warning", [&] {
|
||||
xml.attribute("style", "invisible");
|
||||
xml.node("label", [&] {
|
||||
@ -240,7 +247,7 @@ struct Sculpt::Depot_users_dialog
|
||||
|
||||
void generate(Xml_generator &xml) const { _gen_selection(xml); }
|
||||
|
||||
bool unfolded() const { return _unfolded; }
|
||||
bool unfolded() const { return _unfolded || !_selected_user_exists; }
|
||||
|
||||
struct User_properties
|
||||
{
|
||||
@ -280,6 +287,7 @@ struct Sculpt::Depot_users_dialog
|
||||
_selected = user;
|
||||
select_fn(user);
|
||||
_unfolded = false;
|
||||
_selected_user_exists = true;
|
||||
_url_edit_field = _orig_edit_url;
|
||||
};
|
||||
|
||||
@ -324,6 +332,19 @@ struct Sculpt::Depot_users_dialog
|
||||
if (c.value == ' ' || c.value == '"')
|
||||
return;
|
||||
|
||||
/* respond to enter key */
|
||||
if (c.value == 10) {
|
||||
Depot_url const depot_url = _depot_url(_depot_users.xml());
|
||||
if (depot_url.valid()) {
|
||||
_action.add_depot_url(depot_url);
|
||||
_selected = depot_url.user;
|
||||
_selected_user_exists = true;
|
||||
_unfolded = false;
|
||||
_url_edit_field = _orig_edit_url;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_url_edit_field.apply(c);
|
||||
}
|
||||
|
||||
@ -335,16 +356,11 @@ struct Sculpt::Depot_users_dialog
|
||||
* If the selected depot user does not exist in the depot, show
|
||||
* list of available users.
|
||||
*/
|
||||
bool selected_user_exists = false;
|
||||
_selected_user_exists = false;
|
||||
|
||||
_depot_users.xml().for_each_sub_node([&] (Xml_node const &user) {
|
||||
if (_selected == user.attribute_value("name", User()))
|
||||
selected_user_exists = true; });
|
||||
|
||||
if (!selected_user_exists) {
|
||||
_selected = _default_user;
|
||||
_unfolded = true;
|
||||
}
|
||||
_selected_user_exists = true; });
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user