Получение координат клиентской области позиции символа из текстового элемента управления
Мне нужно написать функцию, которая может получить координаты экрана из положения символа в элементе управления редактированием текста. Я использую управление редактированием текста, предоставляемое платформой wxWidgets. wxTextCtrl не предоставляет никаких функций API, которые могут предоставить эту информацию. В Windows я могу получить информацию, отправив EM_POSFROMCHAR в текстовый элемент управления.
Мне интересно, как то же самое можно сделать в других средах, таких как Linux. Пока это нужно делать только на рабочем столе среды, которая работает поверх X Window System, как GNOME, KDE и XFCE. Есть ли способ сделать это? И на этих DE, кто рисует элементы управления, как текстовое редактирование? Управляется ли он X и стилизован конкретным DE?
Любая помощь будет признательна.
4 ответов:
Ну, это возможно, но вам нужно реализовать производный элемент управления
wxTextCtrl, который полагается на возможности платформы подложки для любого конкретного порта wxWidgets (wxMSW, wxGTK и т. д.).Итак, потому что вы спросили о реализации Linux. Позвольте мне объяснить, как реализовать его для wxGTK 2.9. Ниже приведено определение элемента управления
wxTextCtrlExt:#include <wx/textctrl.h> #include <wx/gdicmn.h> //----------------------------------------------------------------------------- // wxTextCtrlExt //----------------------------------------------------------------------------- class wxTextCtrlExt : public wxTextCtrl { public: wxTextCtrlExt() : wxTextCtrl() { } wxTextCtrlExt(wxWindow* parent, wxWindowID id, const wxString& value = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTE_MULTILINE, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTextCtrlNameStr) : wxTextCtrl(parent, id, value, pos, size, style, validator, name ) { } wxPoint GetPositionCoords(long pos); };И реализация wxGTK:
#include "wxTextCtrlExt.h" #include <wx/defs.h> #include <gtk/gtk.h> wxPoint wxTextCtrlExt::GetPositionCoords(long pos) { if ( IsMultiLine() ) { GtkTextView* txtView = GTK_TEXT_VIEW(m_focusWidget); GtkTextBuffer* txtBuffer = gtk_text_view_get_buffer(txtView); GtkTextIter iter; gtk_text_buffer_get_iter_at_offset(txtBuffer, &iter, pos); GdkRectangle location; // output location in buffer coordinates gtk_text_view_get_iter_location(txtView, &iter, &location); return wxPoint(location.x, location.y); } return wxPoint(0,0); }Вы также можете преобразовать координаты буфера в координаты виджета. одни:
Как вы можете видеть, эта конкретная реализация не учитывает однострочный текстовый ввод, поэтому при создании элемента управления// If we need to convert our coordinates to GdkPoint out; gtk_text_view_buffer_to_window_coords(txtView, GTK_TEXT_WINDOW_WIDGET, location.x, location.y, &out.x, &out.y ); return wxPoint(out.x, out.y);wxTextCtrlExtнеобходимо использовать стильwxTE_MULTILINE.Ну, ниже показано, как его использовать. Пусть
m_Text2- указатель на дочерний объект классаwxTextCtrlExt:Теперь мы получили координаты положения нашего персонажа вlong iCharPos = m_Text2->GetInsertionPoint(); long iCharPosMax = m_Text2->GetLastPosition(); wxPoint pos = m_Text2->GetPositionCoords(iCharPos);pos. Вот и все!Некоторые ссылки, которые могут представлять для вас интерес:
Теперь все дело в вашем втором вопросе.
- GtkTextView - Виджет, который отображает GtkTextBuffer
- GtkTextBuffer-сохраняет приписываемый текст для отображения в GtkTextView
И на этих DE, кто рисует элементы управления, как текстовое редактирование? Управляется ли он X и стилизован конкретным DE?
Это зависит от используемого порта wxWidgets. Порты wxMSW и wxGTK используют собственные элементы управления Win32 и GTK+2 соответственно. Порты на базе wxUniversal (например, wxX11, wxMGL) нарисуйте все элементы управления самим wxWidgets. X Window System не предписывает пользовательский интерфейс сам по себе. Он обеспечивает базовую структуру для построения графических сред: рисование и перемещение окон на экране и взаимодействие с мышью и клавиатурой.
Мне не совсем ясно, какая позиция персонажа ищется, но решение, скорее всего, будет включать
wxTextCtrl::XYToPosition()и/илиwxTextCtrl::PositionToXY(), но неясно, в какой системе координат должен быть выражен результат.
wxTextCtrlнаследует отwxWindow, который предлагаетwxWindow::GetPosition(). Родитель находится поwxWindow::GetParent.Между многими из них, я подозреваю, ответ легко получить.
Прошло некоторое время с момента моего последнего опыта с wxWidgets, но если вы не можете найти более простой (короткий) способ, будет ли вычисление экстента текста перед кареткой (например, с помощью wxDC:: GetTextExtent ()) возможным подходом к поиску позиции, которую вы ищете? Это даст вам позицию относительно начала текста в wxTextCtrl. Возможно, вам придется учитывать размеры границ и расстояние между границей и фактическим текстом. Если необходимо уточнить через wxTextCtrl:: HitTest()?
КСТАТИ Насчет wxStyledTextCtrl?
Рассматривали ли вы возможность выполнения бинарного поиска с помощью функции
HitTest? Не очень элегантный, но он должен быть быстрым, иHitTestреализован для wxGTK2, поэтому он должен работать.
Comments