menu_view: add character position to hover report
When setting the <dialog> attribute 'hover_details' to "yes", the hover report features the character position of a hovered label. Issue #3607 Issue #3629
This commit is contained in:
parent
7cc4aa2a28
commit
e612f7cd7d
|
@ -88,12 +88,39 @@ struct Menu_view::Label_widget : Widget, Cursor::Glyph_position
|
||||||
/**
|
/**
|
||||||
* Cursor::Glyph_position interface
|
* Cursor::Glyph_position interface
|
||||||
*/
|
*/
|
||||||
int xpos_of_glyph(unsigned at) const override
|
int xpos_of_glyph(unsigned at) const override
|
||||||
{
|
{
|
||||||
Text const truncated_at(Cstring(_text.string(), at));
|
return _font->string_width(_text.string(), at).decimal();
|
||||||
|
}
|
||||||
|
|
||||||
return _font->string_width(truncated_at.string()).decimal();
|
unsigned _char_index_at_xpos(unsigned xpos) const
|
||||||
}
|
{
|
||||||
|
return _font->index_at_xpos(_text.string(), xpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
Hovered hovered(Point at) const override
|
||||||
|
{
|
||||||
|
Unique_id const hovered_id = Widget::hovered(at).unique_id;
|
||||||
|
|
||||||
|
if (!hovered_id.valid())
|
||||||
|
return Hovered { .unique_id = hovered_id, .detail = { } };
|
||||||
|
|
||||||
|
return { .unique_id = hovered_id,
|
||||||
|
.detail = { _char_index_at_xpos(at.x()) } };
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_hover_model(Xml_generator &xml, Point at) const override
|
||||||
|
{
|
||||||
|
if (_inner_geometry().contains(at)) {
|
||||||
|
|
||||||
|
xml.node(_type_name.string(), [&]() {
|
||||||
|
|
||||||
|
_gen_common_hover_attr(xml);
|
||||||
|
|
||||||
|
xml.attribute("at", _char_index_at_xpos(at.x()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ struct Menu_view::Main
|
||||||
|
|
||||||
Attached_dataspace _input_ds { _env.rm(), _nitpicker.input()->dataspace() };
|
Attached_dataspace _input_ds { _env.rm(), _nitpicker.input()->dataspace() };
|
||||||
|
|
||||||
Widget::Unique_id _last_reported_hovered { };
|
Widget::Hovered _last_reported_hovered { };
|
||||||
|
|
||||||
void _handle_config();
|
void _handle_config();
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ void Menu_view::Main::_update_hover_report()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget::Unique_id const new_hovered = _root_widget.hovered(_hovered_position);
|
Widget::Hovered const new_hovered = _root_widget.hovered(_hovered_position);
|
||||||
|
|
||||||
if (_last_reported_hovered != new_hovered) {
|
if (_last_reported_hovered != new_hovered) {
|
||||||
|
|
||||||
|
|
|
@ -78,11 +78,30 @@ class Menu_view::Widget : List_model<Widget>::Element
|
||||||
*/
|
*/
|
||||||
Unique_id() { }
|
Unique_id() { }
|
||||||
|
|
||||||
bool operator != (Unique_id const &other) { return other.value != value; }
|
bool operator != (Unique_id const &other) const
|
||||||
|
{
|
||||||
|
return other.value != value;
|
||||||
|
}
|
||||||
|
|
||||||
bool valid() const { return value != 0; }
|
bool valid() const { return value != 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Hovered
|
||||||
|
{
|
||||||
|
/* widget */
|
||||||
|
Unique_id unique_id;
|
||||||
|
|
||||||
|
/* widget-local detail */
|
||||||
|
using Detail = String<16>;
|
||||||
|
|
||||||
|
Detail detail;
|
||||||
|
|
||||||
|
bool operator != (Hovered const &other) const
|
||||||
|
{
|
||||||
|
return (unique_id != other.unique_id) || (detail != other.detail);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static Name node_name(Xml_node node)
|
static Name node_name(Xml_node node)
|
||||||
{
|
{
|
||||||
return node.attribute_value("name", Name(node.type()));
|
return node.attribute_value("name", Name(node.type()));
|
||||||
|
@ -90,7 +109,7 @@ class Menu_view::Widget : List_model<Widget>::Element
|
||||||
|
|
||||||
static Animated_rect::Steps motion_steps() { return { 60 }; };
|
static Animated_rect::Steps motion_steps() { return { 60 }; };
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
|
||||||
Type_name const _type_name;
|
Type_name const _type_name;
|
||||||
Name const _name;
|
Name const _name;
|
||||||
|
@ -98,8 +117,6 @@ class Menu_view::Widget : List_model<Widget>::Element
|
||||||
|
|
||||||
Unique_id const _unique_id;
|
Unique_id const _unique_id;
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
Widget_factory &_factory;
|
Widget_factory &_factory;
|
||||||
|
|
||||||
List_model<Widget> _children { };
|
List_model<Widget> _children { };
|
||||||
|
@ -169,6 +186,15 @@ class Menu_view::Widget : List_model<Widget>::Element
|
||||||
_animated_geometry.move_to(_geometry, motion_steps());
|
_animated_geometry.move_to(_geometry, motion_steps());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _gen_common_hover_attr(Xml_generator &xml) const
|
||||||
|
{
|
||||||
|
xml.attribute("name", _name.string());
|
||||||
|
xml.attribute("xpos", geometry().x1());
|
||||||
|
xml.attribute("ypos", geometry().y1());
|
||||||
|
xml.attribute("width", geometry().w());
|
||||||
|
xml.attribute("height", geometry().h());
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Margin margin { 0, 0, 0, 0 };
|
Margin margin { 0, 0, 0, 0 };
|
||||||
|
@ -233,16 +259,16 @@ class Menu_view::Widget : List_model<Widget>::Element
|
||||||
*
|
*
|
||||||
* This function is used to track changes of the hover model.
|
* This function is used to track changes of the hover model.
|
||||||
*/
|
*/
|
||||||
virtual Unique_id hovered(Point at) const
|
virtual Hovered hovered(Point at) const
|
||||||
{
|
{
|
||||||
if (!_inner_geometry().contains(at))
|
if (!_inner_geometry().contains(at))
|
||||||
return Unique_id();
|
return { };
|
||||||
|
|
||||||
Unique_id result = _unique_id;
|
Hovered result { .unique_id = _unique_id, .detail = { } };
|
||||||
_children.for_each([&] (Widget const &w) {
|
_children.for_each([&] (Widget const &w) {
|
||||||
Unique_id const id = w.hovered(at - w.geometry().p1());
|
Hovered const hovered = w.hovered(at - w.geometry().p1());
|
||||||
if (id.valid())
|
if (hovered.unique_id.valid())
|
||||||
result = id;
|
result = hovered;
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -259,11 +285,7 @@ class Menu_view::Widget : List_model<Widget>::Element
|
||||||
|
|
||||||
xml.node(_type_name.string(), [&]() {
|
xml.node(_type_name.string(), [&]() {
|
||||||
|
|
||||||
xml.attribute("name", _name.string());
|
_gen_common_hover_attr(xml);
|
||||||
xml.attribute("xpos", geometry().x1());
|
|
||||||
xml.attribute("ypos", geometry().y1());
|
|
||||||
xml.attribute("width", geometry().w());
|
|
||||||
xml.attribute("height", geometry().h());
|
|
||||||
|
|
||||||
_children.for_each([&] (Widget const &w) {
|
_children.for_each([&] (Widget const &w) {
|
||||||
w.gen_hover_model(xml, at - w.geometry().p1()); });
|
w.gen_hover_model(xml, at - w.geometry().p1()); });
|
||||||
|
|
Loading…
Reference in New Issue
Block a user