Получение координат клиентской области позиции символа из текстового элемента управления - PullRequest
3 голосов
/ 11 апреля 2011

Мне нужно написать функцию, которая может получить экранные координаты от позиции символа в элементе управления редактированием текста. Я использую контроль редактирования текста, предоставляемый wxWidgets framework. wxTextCtrl не предоставляет никаких функций API, которые могут предоставить эту информацию. В Windows я могу получить информацию, отправив EM_POSFROMCHAR в текстовый элемент управления.

Мне интересно, как то же самое можно сделать в других средах, таких как Linux. На данный момент это должно быть сделано только в средах рабочего стола, которые работают поверх X Window System , таких как GNOME , KDE и XFCE, Есть ли способ сделать это? И на этих DE кто рисует элементы управления, такие как редактирование текста? Он управляется X и разрабатывается конкретным DE?

Любая помощь будет оценена.

Ответы [ 4 ]

3 голосов
/ 24 апреля 2011

Ну, это возможно, но вам нужно реализовать производный элемент управления 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);

Как видите, эта конкретная реализация не учитывает однострочный текст, поэтому вам нужно использовать стиль wxTE_MULTILINE при создании элемента управления wxTextCtrlExt.

Ну, ниже, как это использовать.Давайте m_Text2 будем указателем на дочерний объект класса wxTextCtrlExt:

long iCharPos = m_Text2->GetInsertionPoint();
long iCharPosMax = m_Text2->GetLastPosition();
wxPoint pos = m_Text2->GetPositionCoords(iCharPos);

Теперь мы получили координаты положения нашего персонажа в pos.Вот и все!

Некоторые ссылки, которые могут вас заинтересовать:

Теперь это все о вашем втором вопросе.

И на этих DE, кто рисует элементы управления, какредактировать текст?Управляется ли он X и разрабатывается ли конкретным DE?

Это зависит от порта wxWidgets, который вы используете.Порты wxMSW и wxGTK используют собственные элементы управления Win32 и GTK + 2 соответственно.Порты на основе wxUniversal (такие как wxX11, wxMGL) отрисовывают все элементы управления самим wxWidgets. X Window System не требует пользовательского интерфейса самостоятельно.Он обеспечивает базовую структуру для создания сред графического интерфейса: рисование и перемещение окон на экране и взаимодействие с мышью и клавиатурой.

0 голосов
/ 22 апреля 2011

Прошло много времени с моего последнего опыта работы с wxWidgets, но если вы не можете найти более простой (более короткий) способ, будет ли возможным вычисление размера текста перед кареткой (например, с помощью wxDC :: GetTextExtent ())подходить к поиску позиции вы после?Это даст вам позицию относительно начала текста в wxTextCtrl.Возможно, вам придется принять во внимание размеры границы и расстояние между границей и фактическим текстом.При необходимости уточните через wxTextCtrl :: HitTest ()?
Кстати, а как же wxStyledTextCtrl ?

0 голосов
/ 24 апреля 2011

Рассматривали ли вы бинарный поиск с использованием функции HitTest? Не очень элегантно, но должно быть быстро, и HitTest реализовано для wxGTK2, поэтому оно должно работать.

0 голосов
/ 20 апреля 2011

Мне не совсем ясно, какая позиция символа ищется, но решение, вероятно, будет включать wxTextCtrl::XYToPosition() и / или wxTextCtrl::PositionToXY(), но неясно, какая система координат результат должен быть выражен в.

wxTextCtrl наследуется от wxWindow, который предлагает wxWindow::GetPosition(). Родитель найден wxWindow::GetParent.

Я полагаю, что между многими из них ответ легко выводится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...