Text/Docu/ru/Controllers.odc

TextControllers

DEFINITION TextControllers;

	IMPORT Models, Views, Controllers, Properties, Containers, TextModels, TextViews;

	CONST
		noAutoScroll = 16; noAutoIndent = 17;
		none = -1;

	TYPE
		Controller = POINTER TO ABSTRACT RECORD (Containers.Controller)
			view-: TextViews.View;
			text-: TextModels.Model;
			(c: Controller) CaretPos (): INTEGER, ABSTRACT, NEW;
			(c: Controller) SetCaret (pos: INTEGER), ABSTRACT, NEW;
			(c: Controller) GetSelection (OUT beg, end: INTEGER), ABSTRACT, NEW;
			(c: Controller) SetSelection (beg, end: INTEGER), ABSTRACT, NEW
			(c: Controller) ThisView (): TextViews.View, EXTENSIBLE
		END;

		Directory = POINTER TO ABSTRACT RECORD (Containers.Directory)
			(d: Directory) NewController (opts: SET): Controller, ABSTRACT;
			(d: Directory) New (): Controller, EXTENSIBLE
		END;

		FilterPref = RECORD (Properties.Preference)
			controller: Controller;
			frame: Views.Frame;
			x, y: INTEGER;
			filter: BOOLEAN
		END;

		FilterPollCursorMsg = RECORD (Controllers.Message)
			controller: Controller;
			x, y: INTEGER;
			cursor: INTEGER;
			done: BOOLEAN
		END;

		FilterTrackMsg = RECORD (Controllers.Message)
			controller: Controller;
			x, y: INTEGER;
			modifiers: SET;
			done: BOOLEAN
		END;

		ModelMessage = ABSTRACT RECORD (Models.Message) END;

		SetCaretMsg = EXTENSIBLE RECORD (ModelMessage)
			pos: INTEGER
		END;

		SetSelectionMsg = EXTENSIBLE RECORD (ModelMessage)
			beg, end: INTEGER
		END;

	VAR dir-, stdDir-: Directory;

	PROCEDURE SetDir (d: Directory);
	PROCEDURE Install;
	PROCEDURE Focus (): Controller;
	PROCEDURE SetCaret (text: TextModels.Model; pos: INTEGER);
	PROCEDURE SetSelection (text: TextModels.Model; beg, end: INTEGER);

END TextControllers.


Модуль TextControllers определяет текстовые диспетчеры - стандартные диспетчеры для текстовых отображений, определенных в модуле TextViews.

Термин каретка означает положение в тексте, куда будет вставлен символ, введённый пользователем. Если после положения каретки есть какой-то текст, он не будет переписан. Новый символ будет вставлен между участками текста до и после каретки.

С какими атрибутами будет записан введённый символ? Если каретка находится в начале не пустого текста, то новый символ будет обладать такими же атрибутами, как первый символ текста. Иначе, если каретка находится в конце текста или ей не предшествуют пробелы, используются атрибуты предыдущего символа. В противном случае, используются атрибуты следующего символа. Если текст пуст, то используются атрибуты по умолчанию. (Любой текст, в том числе и пустой, обладают атрибутами по умолчанию и невидимой линейкой по умолчанию. См. команды Text->Make Default Attributes и Text->Make Default Ruler.)
Если при вводе символа имеется выделение, то будут использоваться атрибуты первого символа в выделении.

Для определения атрибутов, с которыми будет введён символ, можно использовать механизм свойств (см. модуль Properties). Свойства также позволяют изменить эти атрибуты, даже для пустого текста. (Однако, если положение каретки изменится, эти настройки будут потеряны. Этот механизм используется в меню Attributes.)


CONST noAutoScroll
Элемент множества опций диспетчера. Если включен, автоматическая прокрутка отображений будет выключена. Автоматическая прокрутка используется, чтобы показать каретку или то место, где были сделаны самые последние изменения.

CONST noAutoIndent
Элемент множества опций диспетчера. Его включение означает запрет автоматического введения отступов после ввода символа line.

CONST none
Возможный аргумент процедур controller.SetCaret и controller.SetSelection, означающий, что требуется убрать каретку или выделение соответственно. Более того, controller.CarPos и controller.GetSelection могут возвращать none в случае отсутствия каретки или выделения соответственно. (Отметьте, что controller.GetSelection может вернуть любую пару равных значений, указывая на отсутствие выделения.)


TYPE Controller (Containers.Controller)
ABSTRACT
Стандартные диспетчеры для текстовых отображений.

view-: TextViews.View
Отображение, с которым связан диспетчер.

text-: TextModels.Model	view # NIL => text = view.ThisModel()
Текст, выводимый отображением диспетчера; кэшируется для быстрого досутпа.

PROCEDURE (c: Controller) InitView (v: Views.View)
EXTENSIBLE
Усиленные предусловия!

Предусловия
v = NIL  #  c.view = NIL	21
c.view = NIL
	v IS TextViews.View	22

Постусловия
v # NIL
	c.view = v
	c.text = c.view.ThisModel()
v = NIL
	c.view = NIL
	c.text = NIL

PROCEDURE (c: Controller) CaretPos (): INTEGER
NEW, ABSTRACT
Текущее положение каретки, или none если она не установлена.

Постусловия
result = none  OR  0 <= result <= c.text.Length()

PROCEDURE (c: Controller) SetCaret (pos: INTEGER)
NEW, ABSTRACT
Установка каретки в положение pos, или её удаление, если pos = none.

Предусловия
pos = none  OR  0 <= pos	20
pos <= c.text.Length()	21

Постусловия
c.CarPos() = pos

PROCEDURE (c: Controller) GetSelection (VAR beg, end: INTEGER)
NEW, ABSTRACT
Получение диапазона текущего выделения [beg, end), если выделения нет, то beg = end.

Постусловия
beg = end  OR  0 <= beg <= end <= c.text.Length()

PROCEDURE (c: Controller) SetSelection (beg, end: INTEGER)
NEW, ABSTRACT
Выделение участка текста [beg, end), или снятие выделения, если beg = end.

Предусловия
beg = end  OR  0 <= beg < end <= c.text.Length()	20

Постусловия
c.GetSelection(b, e): b = beg, e = end

PROCEDURE (c: Controller) ThisView (): TextViews.View
EXTENSIBLE
Ковариантное расширение Controllers.Controller.ThisView.


TYPE Directory (Containers.Directory)
ABSTRACT
Фабрика диспетчеров.

PROCEDURE (d: Directory) NewController (opts: SET): Controller
ABSTRACT
Возвращает новый диспетчер с заданным набором опций opts.

PROCEDURE (d: Directory) New (): Controller
EXTENSIBLE
Ковариант, имя функции говорит само за себя. Возвращает диспетчер с набором опций по умолчанию (пустым).

За исключением быстродействия, равносильно:
	RETURN d.NewController({})


TYPE FilterPref (Properties.Preference)
Это сообщение использует текстовый диспетчер чтобы опросить внедренные отображения об их желании фильтровать сообщения. Опрашиваться будет ближайшее отображение, которое расположено в тексте до позиции, соответствующей координатам x, y в указанном frame. Если отображение желает фильтровать сообщения опроса курсора и слежения за мышью в данной точке, оно должно выставить filter в TRUE. Тогда диспетчер пошлёт отображению сообщение FilterPollCursorMsg, чтобы дать ему возможность определить изображение курсора. Также, диспетчер пошлёт отображению сообщение FilterTrackMsg, чтобы дать ему возможность перехватить действия диспетчера по слежению за мышью. Примером использования этого механизма фильтрации являются отображения-гиперссылки, например, из модуля StdLinks. Эти отображения-ссылки добавляют возможности гипертекстовой связи к любому тексту, причём от текстового диспетчера не требуются каких-либо знаний о гиперссылках.

controller: Controller
Диспетчер, запрашивающий предпочтения.

frame: Views.Frame
Кадр, которым в данный момент оперирует диспетчер.

x, y: INTEGER
Координаты (во фрейме) события.

filter: BOOLEAN
Устанавливается в FALSE диспетчером; должно устанавливаться в TRUE отображениями, желающими фильтровать действия по опросу курсора и слежению.


TYPE FilterPollCursorMsg (Controllers.Message)
Это сообщение диспетчер посылает отображениям, которые в ответ на запрос FilterPref указали, что они желают фильтровать действия по опросу куросора. Замечание: это сообщение посылается методу HandleCtrlMsg отображения с кадром того текстового отображения, в которое оно внедрено! Соответственно, координаты, указанные в сообщении, лежат в системе координат окружающего кадра, а не кадра самого отображения. (По сути, координаты всегда будут лежать вне кадра этого отображения - в противном случае (курсор попал внуть отображения) диспетчер не будет посылать запрос о фильтрации.)

controller: Controller
Диспетчер, пославший сообщение.

x, y: INTEGER
Координаты указателя мыши (во фрейме диспетчера).

cursor: INTEGER
Изображение курсора, которое будет показано в данной точке, если таковое имеется.

done: BOOLEAN
Если установлен, значение cursor должно переопределить выбор изображения курсора, сделанный диспетчером.


TYPE FilterTrackMsg (Controllers.Message)
Это сообщение диспетчер посылает отображениям, которые в ответ на запрос FilterPref указали, что они желают фильтровать действия слежения за курсором мыши. Замечание: это сообщение посылается методу HandleCtrlMsg отображения с кадром того текстового отображения, в которое оно внедрено! Соответственно, координаты, указанные в сообщении, лежат в системе координат окружающего кадра, а не кадра самого отображения. (По сути, координаты всегда будут лежать вне кадра этого отображения - в противном случае (курсор попал внуть отображения) диспетчер не будет посылать запрос о фильтрации.)

controller: Controller
Диспетчер, пославший сообщение.

x, y: INTEGER
Координаты указателя мыши (во фрейме диспетчера).

modifiers: SET
Клавиши модификаторы, активные в момент возникновения события в точке x, y.

done: BOOLEAN
Если установлен, диспетчер считает, что отображение успешно обработало отслеженный щелчок мыши. Если нет, диспечер задействует свою процедуру обработки, как обычно.


TYPE ModelMessage (Models.Message)
ABSTRACT
Сообщения для контроля за виртуальными расширениями модели, такими как пометки (например, каретка или выделение). Текстовая система использует эти сообщения, чтобы синхронно обновлять пометки во всех отображениях одной модели.


TYPE SetCaretMsg (ModelMessage)
EXTENSIBLE
Устанавливает каретку в отображении, показывающем текстовую модель msg.model.

pos: INTEGER
Каретка устанавливается в позицию pos.


TYPE SetSelectionMsg (ModelMessage)
EXTENSIBLE
Установка выделения в отображении, показывающем текстовую модель msg.model.

beg, end: INTEGER
Выделяется участок текста [beg, end).


VAR dir-, stdDir-: Directory	dir # NIL, stdDir # NIL, stable stdDir = d
Фабрика и стандартная фабрика диспетчеров


PROCEDURE SetDir (d: Directory)
Установка фабрики диспетчеров.

Предусловия
d # NIL	20

Постусловия
dir = d


PROCEDURE Install
Инсталлирует текущую фабрику диспетчеров в модуль TextViews.

За исключением бысродействия, равносильно:
	TextViews.SetCtrlDir(dir)

PROCEDURE Focus (): Controller
Возвращает текстовый диспечер, обладающий фокусом, если таковой есть.

За исключением бысродействия, равносильно:
	VAR v: Views.View; c: Controllers.Controller;
	v := Controllers.FocusView();
	IF (v # NIL) & (v IS TextViews.View) THEN
		c := v(TextViews.View).ThisController();
		IF (c # NIL) & (c IS Controller) THEN RETURN c(Controller)
		ELSE RETURN NIL
		END
	ELSE RETURN NIL
	END

PROCEDURE SetCaret (text: TextModels.Model; pos: INTEGER)
Устанавливает каретку в положение pos во всех отображениях, показывающих текст text.

Предусловия
text # NIL	20
pos = none  OR  0 <= pos	21
pos <= text.Length()	22

За исключением бысродействия, равносильно:
	VAR cm: SetCaretMsg;
	cm.pos := pos; Models.Broadcast(text, cm)

PROCEDURE SetSelection (text: TextModels.Model; beg, end: INTEGER)
Выделяет участок текста [beg, end) во всех отображениях, показывающих текст text.

Предусловия
text # NIL	20
beg # end
	0 <= beg	21
	beg < end	22
	end <= text.Length()	23

За исключением бысродействия, равносильно:
	VAR sm: SetSelectionMsg;
	sm.beg := beg; sm.end := end; Models.Broadcast(text, sm)