Как осуществить выделение текста? - PullRequest
4 голосов
/ 30 декабря 2010

Мой вопрос не основан на языке или ОС. Я предполагаю, что каждая система предлагает своего рода метод TextOut (text, x, y). Я ищу некоторые руководящие принципы или статьи, как я должен осуществить выделение текста. Не удалось найти информацию об этом.

Единственное, что приходит мне в голову, это так:

Когда пользователь нажимает какую-то точку на текстовом холсте, я знаю координаты этой точки. Мне нужно рассчитать, где именно это будет в моем текстовом буфере. Итак, я начинаю с буфера и применяю к каждому символу (или блоку текста) стиль (если он есть). После этого я знаю, что после данного стиля письмо дало размер. Я добавляю его ширину и высоту к ранее вычисленным координатам X, Y. Таким образом, я пересекаю буфер, пока вычисленная позиция не достигнет точки, которую щелкнул пользователь. После того, как я достиг точки в пределах некоторого смещения, у меня есть начальная точка для выбора.

Это основная идея. Я не знаю, хорошо ли это, я хотел бы знать, как это делается на самом деле, как, например, в Firefox. Я знаю, что могу просмотреть источники, и если у меня не будет выбора, я сделаю это. Но сначала я пытаюсь найти статью об этом ...

Ответы [ 2 ]

1 голос
/ 19 августа 2013

Выбор текста присущ только элементу управления, в котором он содержится, и средствам, в которых он хранит этот текст.

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

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

Имейте в виду, что написание текстового элемента управления с нуля неприлично сложно . Для лучшей практики содержимое документа следует отделять от отображаемой информации. Причина этого в том, что сам текст необходимо будет редактировать довольно часто, поэтому такие алгоритмы, как Ropes или Gap Buffers, могут использоваться на стороне данных, чтобы обеспечить более быструю вставку вокруг каретки. Каждый раз, когда текст редактируется, он также должен отображаться, что включает в себя получение этих данных и выполнение их с помощью алгоритмов форматирования / потока, чтобы определить, как они должны отображаться пользователю. Обе эти стороны требуют много алгоритмов, которые могут раздражать, чтобы получить право.

К сожалению, использование родных функций TextOut вам не поможет. Вам нужно будет использовать методы, которые дают вам текстовые экстенты для отдельных символов, и более продвинутые (например, многострочные) элементы управления часто должны выполнять свое собственное отображение символов с использованием этой информации. Такие функции, как TextOut, не предназначены, например, для работы с мигающими вставками вставок или для выполнения постепенных обновлений текстовых макетов. Хотя некоторые функции стиля TextOut могут поддерживать перенос слов и выравнивание, они также требуют повторного рендеринга всей строки, что становится более нежелательным пропорционально количеству текста, с которым вам нужно работать в вашем элементе управления.

0 голосов
/ 30 декабря 2010

Вы думаете на гораздо более низком уровне, чем необходимо (не оскорбление. Вы думаете, что вам нужно выполнить гораздо больше работы, чем нужно). Большинство (если не все) языки с поддержкой GUI также имеют некоторую форму selectionRange, которая дает вам либо выбранную строку, либо индексы запуска и остановки в строке.

С современным языком вам никогда не придется рассчитывать пиксели и ширину символов.

Для выделения текста в Javascript, смотрите этот вопрос: Понимание того, что происходит с выделением текстовой области с помощью JavaScript

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