Каков наилучший способ реализовать буфер для элемента управления редактированием текста? - PullRequest
5 голосов
/ 12 ноября 2011

Так что я делаю пользовательский элемент управления для редактирования.Для отслеживания содержимого элемента управления редактирования я использую динамически размещаемый массив символов.

  • Теперь я знаю, что мне нужно вставлять в середину массива в определенных ситуациях, например, когда пользователь нажимает на конкретную точку.Поэтому я подумал, что вместо символьного массива я могу использовать std :: vector, поэтому я мог бы использовать функцию .insert, а также мне не пришлось бы сильно заботиться об управлении памятью.
  • Я также подумал, может быть, напрямую сохранить входной поток в массиве / векторе слов (без сохранения непрерывного буфера), поскольку моя цель в этом состоит в том, чтобы реализовать подсветку синтаксиса.было бы лучше подходить к вещам?И почему?

Ответы [ 5 ]

4 голосов
/ 12 ноября 2011

Для текстового буфера на современных компьютерах вы действительно можете просто использовать один непрерывный буфер (например, вектор), потому что процессоры достаточно быстры, чтобы сделать время вставки (операция o(n) с таким наивным подходом) все еще жизнеспособным вариантом.

В прошлом, когда компьютеры работали в тысячи раз медленнее, вместо этого был простой способ сохранить текст в буфере, но с «дырой», соответствующей позиции курсора, чтобы сделать операцию вставки o(1) и перемещение символовот одной стороны отверстия к другой, когда курсор двигался в тексте (в основном, перемещение курсора - операция o(k), где k - число пропущенных символов).

Для редактора, предназначенного для программистовтекст будет разделен на логические строки, и поэтому использование подхода, основанного на массиве указателей на строки, представляется целесообразным.Даже если это сделает некоторые операции с несколькими строками несколько раздражающими, некоторые операции на основе строк станут проще ... Нумерация строк в отображении становится тривиальной проблемой, особенно если вам не нужно реализовывать перенос строки (в любом случае это ужасно с кодом)вместо этого выбрав усечение и горизонтальную прокрутку.

4 голосов
/ 12 ноября 2011

Лучший подход - начать с системного редактирования или управления ричедитом и адаптировать его к своим потребностям. Написание собственного элемента управления для редактирования - намного больше работы, чем вы можете себе представить, включая обработку специальных возможностей, IME для языков со сложными алфавитами, копирование и вставка, полосы прокрутки, курсоры, выборки и многое другое.

Два системных элемента управления предоставляют множество точек расширения, которые должны позволить вам достичь большинства целей. Если вы действительно не строите текстовый процесс или редактор исходного кода, вы должны придерживаться предоставленных. А пользовательские элементы управления редактированием являются огромным источником ошибок. Я редко вижу тот, который работает правильно только для основных случаев.

Martyn

3 голосов
/ 11 марта 2014

При поиске того же самого тонкого я наткнулся на две страницы Википедии, которые были очень полезны:

буфер Gap для простого редактирования

Канат (структура данных) для сложного редактирования текста

3 голосов
/ 12 ноября 2011

Если вы рассматриваете что-то вроде средства просмотра исходного кода (см .: «для реализации подсветки синтаксиса») с изменяемой резервной копией, вы можете найти std::list<std::string> хорошей отправной точкой, и это может быть излишним, если строка мала.

Имея непрерывный буфер для вашего текста (например, один большой std::string или std::vector), вы будете иметь много перемещения и изменения размера во время редактирования, а также много сканирования при перемещении.Эти перемещения и изменения размера приведут к многочисленным непрерывным выделениям, инициализации буфера, перемещению и освобождению старой памяти.Это также ограничивает способ кэширования данных (если это важно).Время поиска будет немного медленнее со списком, но ваши движения и мутации будут намного быстрее, чем использование непрерывного буфера для всего файла.

std::list<std::string> имеет некоторые приятные свойства, потому что он растет и мутирует какнабор строк (например, для каждой строки или абзаца).

Этот обзор детализирует сильные стороны списка и сравнивает его с другими контейнерами: http://www.cplusplus.com/reference/stl/list/

Если вы хотите связать некоторые данные сстрока / строка, затем просто создайте список из них:

namespace MON {
class t_line {
public:
  /* ... */
private:
  std::string d_string;
  t_lexer_stuff d_lexerStuff;
};
}
2 голосов
/ 12 ноября 2011

Вам может понадобиться двойное представление, поэтому имейте как вектор символа, так и вектор слов (проблема заключается в их синхронизации).

Я предлагаю также посмотреть и, возможно, даже использовать некоторыеграфический инструментарий, источник которого находится в свободном доступе, и который можно настроить.(Я не парень по Windows, но) Я думал, например, о Qt , которая является графической библиотекой с открытым исходным кодом на C ++, работающей в Windows, Linux, MacOSX, ...

Я не могу помочь больше, потому что я не знаю, и я не использую Windows (все мои машины под Linux).

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