X : integer; { координата X }
Y : integer; { координата Y }
Color : integer; { цвет }
Size : integer; { размер }
Angle : integer; { угол }
Focused : boolean; { режим выделения }
{!!!} procedure Paint(aColor : integer); virtual;
{ нарисовать }
{new} procedure DrawConers(aColor : integer);
{ нарисовать / стереть выделение }
{new} function GetObjectArea : integer; virtual;
public
Next : Ppset;{ указатель на следующую фигуру }
procedure Show; { показать }
procedure Hide; { стереть }
constructor Create(aX, aY, aColor : integer);
{ создать }
destructor Destroy; { удалить }
procedure Shift(dX, dY : integer); { подвинуть }
procedure SetSize(aSize : Integer); { установить размер }
function GetSize : Integer); { получить размер }
procedure Rotate(aAngle : Integer); {повернуть }
procedure SetFocus(aFocused boolean);{ установка / сброс выделения }
end;
Реализуем новые методы.
procedure TPset.SetFocus(aFocused : boolean);
begin
{ установка нового значения режима выделения }
Hide;
Focused := aFocused;
Show;
end;
procedure TPset.DrawConers(aColor : integer);
var
X1,X2,Y1,Y2,S : integer;
begin
{ рисуем выделение }
SetColor(aColor);
S := GetObjectArea;
X1 := X-S; X2 := X+S; Y1 := Y-S; Y2 := Y+S;
Line(X1,Y1,X1+3,Y1);
Line(X1,Y1,X1,Y1+3);
Line(X1,Y2,X1+3,Y2);
Line(X1,Y2,X1,Y2-3);
Line(X2,Y1,X2-3,Y1);
Line(X2,Y1,X2,Y1+3);
Line(X2,Y2,X2-3,Y2);
Line(X2,Y2,X2,Y2-3);
end;
function TPset.GetObjectArea;
begin
GetObjectArea := 5;
end;
{ TCircle }
function TCircle.GetObjectArea;
begin
GetObjectArea := Size;
end;
{ TSquare }
{ дополним следующие методы }
constructor TPset.Create;
begin
X := aX;
Y := aY;
Angle := 0;
Size := 5;
Color := aColor;
{new} Focused := false;
end;
procedure TPset.Show;
begin
{ нарисуем класс с установленным цветом }
Paint(Color);
{new} if Focused then DrawConers($E);
end;
procedure TPset.Hide;
begin
{ нарисуем класс с 0-м цветом ( стираем ) }
Paint(0);
{new} if Focused then DrawConers(0);
end;
Основная программа, оперирующая с нашими классами
Нам нужно:
1 - список фигур,который изначально пуст (=nil)
2 - указатель на выделенную фигуру { Selected }
3 – процедура добавления фигуру в список {AddObject} 4 – процедура удаления выделения фигуру{DelSelected}
5 - переместить выделение с одной фигуры на другую { SetSelected }
6 – процедура создания фигуру {CreateObject}
7 – основеая программа, связывающая все это
var
Objects : PPset; {1}
Selected : PPset; {2}
P : PPset;
procedure SetSelect(AObj : PPset); {5}
begin
{ если существует выделенная фигура - снять с нее выделение }
if Selected <> nil then Selected^.SetFocus(false);
Selected := AObj;
{ если существует новая выделенная фигура - установить на нее выделение }
if Selected <> nil then Selected^.SetFocus(true);
end;
procedure AddObject(P : PPset); {3}
begin
if Selected=nil then begin {если список пуст}
Objects := P; {создаем кольцевой список}
Objects^.Next := Objects; {из одного элемента}
end else begin
P^.Next := Selected^.Next; {иначе вставляем новую фигуру в спиок }
Selected^.Next:=P; {после выделенной}
end;
SetSelect(P); {устанавливаем выделение на новой фигуре}
end;
procedure DelSelected; {4}
var
P : PPset;
begin
if Selected<>nil then begin
Selected^.SetFocus(false);
if Selected=Selected^.Next then begin
{ если список из одного элемента }
Dispose(Selected,Destroy);
Selected := nil;
Objects := nil;
end else begin
{ иначе находим предыдущий элемент списка }
P := Selected^.Next;
while P^.Next <> Selected do P := P^.Next;
{ перенастраиваем связи }
P^.Next := Selected^.Next;
{ удаляем выделенный }
Dispose(Selected,Destroy);
{ устанавливаем выделенние на следующем элементе }
Selected := P^.Next;
Selected^.SetFocus(true);
end;
end;
end;
{ index - вид класса }
{ 0 - точка }
{ 1 - круг }
{ 2 - квадрат }
{ 3 - треугольник }
procedure CreateObject(index : integer); {6}
var
P : PPset;
Cir : PCircle;
Squ : PSquare;
Tri : PTriangle;
X,Y : Integer;
begin
randomize;
X := random(GetMaxX);
Y := random(GetMaxY);
case Index of
0 : begin
New(P,Create(X,Y,Random(GetMaxColor-1)+1));
AddObject(P);
end;
1 : begin
New(Cir,Create(X,Y,Random(GetMaxColor-1)+1,10));
AddObject(Cir);
end;
2 : begin
New(Squ,Create(X,Y,Random(GetMaxColor-1)+1,10));
AddObject(Squ);
end;
3 : begin
New(Tri,Create(X,Y,Random(GetMaxColor-1)+1,10));
AddObject(Tri);
end;
end;
end;
{ 7 } - Это основная программа
var
grDr,grMd : integer;
ch : char;
begin
grDr := Detect;
Objects := nil;
Selected := nil;
initgraph(grDr,grMd,'');
OutTextXY(10,10,' 1 - create point');
OutTextXY(10,20,' 2 - create circle');
OutTextXY(10,30,' 3 - create square');
OutTextXY(10,40,' 4 - create triangle');
OutTextXY(10,50,'<Space> - roteate');
OutTextXY(10,60,' '#25#24#27#26' - move');
OutTextXY(10,70,' <Del> - delete selected');
OutTextXY(10,80,' <Tab> - change selected');
OutTextXY(10,90,' +/- - change size');
repeat
{ перерисуем все классы в списке }
if Objects <> nil then begin
P := Selected^.Next;
repeat
P^.Show;
P := P ^.Next;
until P=Selected^.Next;
end;
{ диалог с пользователем }
ch := readkey;
if ch in ['1'..'4'] then
CreateObject(Byte(Ch)-Byte('1'))
else if Selected <> nil then
case ch of
#32 : Selected^.Rotate(10);
#09 : SetSelect(Selected^.Next);
'+' : Selected^.ChangeSize(True);
'-' : Selected^.ChangeSize(False);
#0 :
case readkey of
#72 : Selected^.Shift(0,-10);
#80 : Selected^.Shift(0,+10);
#75 : Selected^.Shift(-10,0);
#77 : Selected^.Shift(10,0);
#83 : DelSelected;
end;
end;
until ch=#27;
{ удалить все элементы списка }
if objects <> nil do begin
P := Selected^.Next;
Selected^.next := nil;
while P <> nil then begin
Objects := P^.Next;
Dispose(P);
P := Objects;
end;
end;
closegraph;
end.
16.10.99 ]DENIS RUSSESS[