В этом разделе мы рассматриваем реализацию вспомогательных методов, которые были использованы в примере CapsEditor
, чтобы выполнить преобразование координат. Это методы WorldYCoordinateToLineIndex()
и LineIndexToWorldCoordinates()
, на которые мы ссылались в предыдущем разделе, а также некоторые другие методы.
Первое. LineIndexToWorldCoordinates()
получает заданный индекс строки и определяет мировые координаты верхнего левого угла строки с помощью известных ширины поля и высоты строки:
private Point LineIndexToWorldCoordinates(int index) {
Point TopLeftCorner =
new Point((int)margin, (int)(lineHeight*index + margin));
return TopLeftCorner;
}
Мы также используем метод, который делает приблизительно обратное преобразование в OnPaint()
. WorldYCoordinateToLineIndex()
определяет индекс строки, но он принимает в расчет только вертикальную мировую координату. Это связано с тем, что метод используется для определения индекса строки, соответствующего верху и низу области вырезания:
private int WorldYCoordinateToLineIndex(int у) {
if (у < margin) return -1;
return (int)((y - margin)/lineHeight);
}
Существуют еще три метода, вызываемые из процедуры обработки, которые отвечают на двойной щелчок пользователя мышью. Прежде всего — метод, определяющий индекс строки, которая выведется в заданных мировых координатах. В отличие от WorldYCoordinateToLineIndex()
этот метод берет в расчет позиции x- и y- координат. Он возвращает -1, если нет строки текста с заданными координатами.
private int WorldCocrdinatesToLineIndex(Point position) {
if (!documentHasData) return -1;
if (position.Y < margin || position.X < margin) return -1;
int index = (int) (position.Y - margin) / (int) this.lineHeight;
// проверить, что позиция находится не ниже документа
if (index >= documentLines.Count) return -1;
// теперь проверим, что горизонтальная позиция располагается
// внутри строки
TextLineInformation theLine =
(TextLineInformation)documentLines[index];
if (position.X > margin * theLine.Width)
return -1;
// все хорошо. Можно вернуть ответ.
return index;
}
Наконец, иногда необходимо делать преобразование между индексом строки и координатами страницы, а не мировыми координатами. Это делает следующий метод:
private Point LineIndexToPageCoordinates(int index) {
return LineIndexToWorldCoordinates(index) + new Size(AutoScrollPosition);
}
private int PageCoordinatesToLineIndex(Point position) {
return WorldCoordinatesToLineIndex(position - new Size(AutoScrollPosition));
}
Эти методы сами по себе не кажутся особенно интересными, они иллюстрируют общую технику, которую, по всей видимости, вам придется часто использовать. Применяя GDI+, мы иногда оказываемся в ситуации где заданы некоторые координаты (например, координаты места, где пользователь щелкнул мышью) и требуется определить, какой элемент изображен в этом месте. Или наоборот, для заданного определенного элемента вывода необходимо приблизительно определить, где он должен быть выведен. Следовательно, при создании приложений GDI+ может оказаться полезным умение написать методы, эквивалентные методам преобразований координат, проиллюстрированным здесь.
Ответ на ввод пользователя
До сих пор, за исключением пеню File в примере CapsEditor
, все, что делались в этой главе, было односторонним, так как приложение общалось с пользователем, выводя информацию на экране. Почти любое программное обеспечение работает в обоих направлениях — пользователь также может общаться с программным обеспечением. Мы собираемся теперь добавить эту возможность в CapsEditor
.
Заставить приложение GDI+ ответить на пользовательский ввод в действительности значительно проще, чем писать код для рисования на экране, и мы в главе 9 уже рассмотрели, как обрабатывать ввод пользователя. По сути для этого необходимо переопределить методы из класса Form
, которые вызываются из соответствующего обработчика событий почти так же, как вызывается OnPaint()
, когда инициируется событие Paint
.
Для случая обнаружения, когда пользователь щелкнул мышью или переместил мышь, функции которые можно будет переопределить включают следующие:
Метод | Когда вызывается |
---|---|
OnClick(EventArgs е) | Сделан щелчок мышью |
OnDoublеСlick(EventArgs е) | Сделан двойной щелчок мышью |
OnMouseDown(MouseEventArgs е) | Нажата левая кнопка мыши |
OnMouseHover(MouseEventArgs е) | Мышь остается неподвижной после перемещения |
OnMouseMove(MouseEventArgs е) | Мышь перемещается |