Указатель на элемент списка
Как уже отмечалось, с помощью процедуры Draw можно выводить обычный текст и выделенный текст. Попробуем использовать это обстоятельство для того, чтобы поместить в окно просмотра указатель на текущий элемент данных. Для этого добавим в TInterior еще одно поле:
type TInterior = object (TScroller) Location: Word; ……. end;
Поле Location будет хранить номер той строки,которая отождествляется с выбранной строкой и которая на экране должна выделяться цветом.Добавьте в конце метода ReadFile строку:
Location: = 0;
И измените метод Draw:
Procedure TInterior.Draw; {Выводит данные в окно просмотра} var n,k: Integer; В: TDrawBuffer; р: PString; Color: Byte; begin if Delta.Y > Location then Location: = Delta.Y; if Location > Delta.Y+pred(Size.Y) then Location: = Delta.Y+pred(Size.Y); for n: = 0 to pred(Size.Y) do begin k: = Delta.Y+n; if k=Location then Color: = GetColor(2) else Color: = GetColor(1); end end; {TInterior.Draw}
Вначале проверяется, попадает ли строка с номером, хранящимся в Location, в число выводимых строк. Если это не так, значит пользователь изменил размеры окна или сдвинул его относительно текста; в этом случае нужным образом корректируется значение Location. Такая проверка гарантирует, что в окне всегда будет выводиться текущая строка. Перед выводом очередной строки сравнивается значение ее номера с величиной Location и, если величины совпадают, строка выводится цветом 2 из палитры TScroller (темно-синими символами на сером фоне).
Создав указатель в окне, нужно предусмотреть и средства воздействия на него. Для этого нам понадобится проверять действия пользователя с мышью и клавиатурой и изменять положение указателя. Вы не забыли, что все действия программы в Turbo Vision выполняются с помощью обработчика событий? Перекроем стандартный метод HandleEvent в объекте TInterior:
type TInterior,. = object (TScroller) ……. Procedure HandleEvent(var Event: TEvent); Virtual; end; Procedure TInterior.HandleEvent(var Event: TEvent); {Обработчик событий для окна данных} var R: TPoint; begin Inherited HandleEvent(Event); case Event.What of evMouseDown: {Реакция на щелчок мышью} begin MakeLocal(MouseWhere, R){Получаем в R локальные координаты указателя мыши} Location: = Delta.Y+R.Y; Draw end; evKeyDown: {Реакция на клавиши + – } case Event.KeyCode of kbGrayMinus: if Location > Delta.Y then begin dec(Location); Draw end; kbGrayPlus: if Location < Delta.Y+pred(Size.Y) then begin inc(Location); Draw end; end end end; {TInterior.HandleEvent}
В новом методе вначале вызывается унаследованный обработчик событий TScroller.HandleEvent, с помощью которого обрабатываются все стандартные действия с окном (смещение текста, изменение размеров и т.д.). Затем обрабатываются события от нажатия кнопки мыши и от нажатия клавиш "+" и "-" из зоны цифровых клавиш (на клавиатуре ПК они выделяются серым цветом). С клавишей "+" связывается действие "Сместить указатель вниз на одну строку", с клавишей "-" – "Сместить вверх". Выбор серых клавиш "+" и "-" для смещения указателя вызван тем, что клавиши управления курсором используются для смещения окна и обрабатываются стандартным обработчиком событий.
Заметим, что нажатие кнопки мыши будет обрабатываться в TScroller.HandleEvent только в том случае, если указатель мыши находится на рамке окна или на полосах управления. Если указатель сместить внутрь окна, нажатие на кнопку мыши будет преобразовано в событие evMouseDone и передано в наш обработчик. В этом случае глобальная переменная MouseWhere содержит абсолютные координаты указателя мыши (т.е. координаты относительно левого верхнего угла экрана). Чтобы получить номер соответствующей строки текста, мы сначала с помощью оператора:
MakeLocal(MouseWhere, R);
Получаем в переменной R локальные координаты мыши относительно границ окна TScroller. Оператор:
Location: = Delta.Y+R.Y;
Устанавливает в поле Location номер той строки текста, на которой располагается указатель мыши.