Implement wxTextCtrl::HitTest() for single line controls in wxGTK

Use Pango API to find the character at the given position.

Closes #18144.
This commit is contained in:
Vadim Zeitlin
2018-06-03 17:04:06 +02:00
parent 085e4c354a
commit 690b95646b
3 changed files with 50 additions and 4 deletions

View File

@@ -84,6 +84,7 @@ All (GUI):
wxGTK: wxGTK:
- Implement wxTextCtrl::HitTest() for single line controls.
- Fix the build with glib < 2.32 (e.g. CentOS 6). - Fix the build with glib < 2.32 (e.g. CentOS 6).
wxMSW: wxMSW:

View File

@@ -1337,7 +1337,7 @@ public:
parameter is not modified. parameter is not modified.
Please note that this function is currently only implemented in wxUniv, Please note that this function is currently only implemented in wxUniv,
wxMSW and wxGTK2 ports and always returns @c wxTE_HT_UNKNOWN in the wxMSW and wxGTK ports and always returns @c wxTE_HT_UNKNOWN in the
other ports. other ports.
@beginWxPerlOnly @beginWxPerlOnly
@@ -1363,7 +1363,7 @@ public:
parameters are not modified. parameters are not modified.
Please note that this function is currently only implemented in wxUniv, Please note that this function is currently only implemented in wxUniv,
wxMSW and wxGTK2 ports and always returns @c wxTE_HT_UNKNOWN in the wxMSW and wxGTK ports and always returns @c wxTE_HT_UNKNOWN in the
other ports. other ports.
@beginWxPerlOnly @beginWxPerlOnly

View File

@@ -1465,8 +1465,53 @@ wxTextCtrl::HitTest(const wxPoint& pt, long *pos) const
{ {
if ( !IsMultiLine() ) if ( !IsMultiLine() )
{ {
// not supported // These variables will contain the position inside PangoLayout.
return wxTE_HT_UNKNOWN; int x = pt.x,
y = pt.y;
// Get the offsets of PangoLayout inside the control.
//
// Note that contrary to what GTK+ documentation implies, the
// horizontal offset already accounts for scrolling, i.e. it will be
// negative if text is scrolled.
gint ofsX = 0,
ofsY = 0;
gtk_entry_get_layout_offsets(GTK_ENTRY(m_text), &ofsX, &ofsY);
x -= ofsX;
y -= ofsY;
// And scale the coordinates for Pango.
x *= PANGO_SCALE;
y *= PANGO_SCALE;
PangoLayout* const layout = gtk_entry_get_layout(GTK_ENTRY(m_text));
int idx = -1,
ofs = 0;
if ( !pango_layout_xy_to_index(layout, x, y, &idx, &ofs) )
{
// Try to guess why did it fail.
if ( x < 0 || y < 0 )
{
if ( pos )
*pos = 0;
return wxTE_HT_BEFORE;
}
else
{
if ( pos )
*pos = wxTextEntry::GetLastPosition();
return wxTE_HT_BEYOND;
}
}
if ( pos )
*pos = idx;
return wxTE_HT_ON_TEXT;
} }
int x, y; int x, y;