|
Для решения задачи попробуем
несколько сместить точку зрения. До сих
пор, реализовывалась виртуальность фигур
в рамках действий над этими фигурами.
Теперь попробуем реализовать виртуальность
действий по отношению к фигурам, ведь,
в конце концов, нам надо реализовать матрицу
из множества действий для множества фигур.
Поэтому переключающие вектора теперь извлечём
из подпрограмм, реализующих действия,
и разместим вне этих подпрограмм. Содержимым
векторов по-прежнему останутся конкретные
обработчики для конкретных фигур.
Представим это решение:
enum Figures line,
rectangle, circle
MaxFigure = circle
enum Actions Draw, Hide, Select, Drag
MaxActions = Drag
;объявляем типы
Struc tLine
|
x |
dd |
? |
; x - координата
якорной точки |
|
y |
dd |
? |
; y - координата
якорной точки |
|
x1 |
dd |
? |
; x – координата
конца линии |
|
y1 |
dd |
? |
; y – координата
конца линии |
ends tLine
TYPEDEF LineRef PTR tLine
Struc tRectangle
|
x |
dd |
? |
; x – координата
якорной точки |
|
y |
dd |
? |
; y – координата
якорной точки |
|
width |
dd |
? |
; ширина прямоугольника |
|
height |
dd |
? |
; высота прямоугольника |
ends tRectangle
TYPEDEF RectangleRef PTR tRectangle
Struc tCircle
|
x |
dd |
? |
; x – координата
якорной точки |
|
y |
dd |
? |
; y - координата
якорной точки |
|
radius |
dd |
? |
; радиус окружности |
ends tCircle
TYPEDEF CircleRef PTR tCircle
DataSeg
|
; создаём вектора-переключатели
(virtual tables) |
| Label |
vectorLine |
:dword |
|
dd |
offset |
LineDraw |
|
dd |
offset |
LineHide |
|
dd |
offset |
LineSelect |
|
dd |
offset |
CommonDrag |
| Label |
vectorRectangle |
:dword |
|
dd |
offset |
RectangleDraw |
|
dd |
offset |
RectangleHide |
|
dd |
offset |
RectangleSelect |
|
dd |
offset |
CommonDrag |
| Label |
vectorCircle |
:dword |
|
dd |
offset |
CircleDraw |
|
dd |
offset |
CircleHide |
|
dd |
offset |
CircleSelect |
|
dd |
offset |
CommonDrag |
| ;
создаём экземпляры типов, объявленных
ранее |
|
aLine |
tLine |
<20, 20, 10,
15> |
; линия |
|
aRectangle |
tRectangle |
<10, 10, 20,
20> |
; прямоугольник |
|
aCircle |
tCircle |
<20, 20, 10> |
; окружность |
CodeSeg
| Start: |
; начинаем программу |
| |
... |
| |
; рисуем линию |
| |
call [Draw *
4 + vectorLine], offset aLine |
| |
... |
| |
; прячем прямоугольник |
| |
call [Hide *
4 + vectorRectangle], offset
aRectangle |
| |
... |
| |
; выбираем окружность |
| |
call [Select
* 4 + vectorCircle], offset
aCircle |
| |
... |
Proc LineDraw
| Arg |
@@ref |
:LineRef |
|
;
рисуем линию |
|
ret |
endp LineDraw
Proc LineHide
| Arg |
@@ref |
:LineRef |
|
;
прячем линию |
|
ret |
endp LineHide
Proc LineSelect
| Arg |
@@ref |
:LineRef |
|
;
выбираем линию |
|
ret |
endp LineSelect
Proc CommonDrag
| Arg |
@@ref |
:dword |
|
;
перетаскиваем фигуру |
|
ret |
endp CommonDrag
Proc RectangleDraw
| Arg |
@@ref |
:RectangleRef |
|
;
рисуем прямоугольник |
|
ret |
endp RectangleDraw
Proc RectangleHide
| Arg |
@@ref |
:RectangleRef |
|
;
прячем прямоугольник |
|
ret |
endp RectangleHide
Proc RectangleSelect
| Arg |
@@ref |
:RectangleRef |
|
;
выбираем прямоугольник |
|
ret |
endp RectangleSelect
Proc CircleDraw
| Arg |
@@ref |
:CircleRef |
|
;
рисуем окружность |
|
ret |
endp CircleDraw
Proc CircleHide
| Arg |
@@ref |
:CircleRef |
|
;
прячем окружность |
|
ret |
endp CircleHide
Proc CircleSelect
| Arg |
@@ref |
:CircleRef |
|
;
выбираем окружность |
|
ret |
endp CircleSelect
| ... |
; продолжение
программы |
| end Start |
; завершение
программы |
|
|