9. Закрыть окно для выхода из программы
В данной главе приводится описание действий оператора (пользователя) для достижения нужных результатов.
Чтобы запустить программу, нужно из папки с программой открыть файл «Editor.exe».
При запуске программы перед Вами находиться следующее окно:
Рис. 1. Вид главного окна приложения
3.2.2 Создание объекта
- Выбрать объект
- Установить его параметры с помощью ComboBox-элементов
- Установить положение объекта на плоскости путем 2-х или 3-х кликов мышкой на белой области формы
- В случае кривой Безье можно увидеть вспомогательные линии, используемые для построения объекта, щелкнув на флажке «Показать все линии». Сюрос этого флажка уберет вспомогательные линии с экрана.
3.2.3 Выделение и удаление объектов
- В ListBox’е «Все линии» выбрать различные линии. Они будут выделяться на объекте цветом выделения, который также можно интерактивно изменить
- При щелчке на объекте в списке «Объекты» будет выделена первая линия выделенного объекта в списке вверху
- При нажатии Delete выделенная линия удаляется из списка, оставляя при этом объект как единое целое. После удаления линий из объекта над ним можно произвести те же операции, что и до удаления. При удалении всех линий из объекта, он сам удаляется из списка
Для изменения параметров объекта необходимо выделить его в списке объектов и установить новые значения цветов с помощью ComboBox-элементов.
Чтобы выйти из программы, нужно нажать на кнопку с изображением крестика в правом верхнем углу окна.
Вся работа со списком объектов отображается на экране. При добавлении линии или объекта, он появляется на экране, при удалении – исчезает оттуда, при выделении – меняет цвет на цвет выделения.
1. Дейтел Х., Дейтел П. Как программировать на С++: пер. с англ. – М.: «Издательство Бином», 2003 г.
2. Кондратьева С.Д. Введение в структуры данных: лекции и упражнения по курсу. – М.: Издательство МГТУ им. Н. Э. Баумана, 2000 г.
3. Стивенс Р. Delphi. Готовые алгоритмы: Пер. с англ. – М.: Издательство ДМК Пресс, 2001.–384с.
4. Рейсдорф Кент и Хендерсон Кен Borland C++ Builder. Освой самостоятельно: [Электронный ресурс].
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <stdio.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;
//==========================================
// CLASSES FOR WORK WITH LISTS. IT-41 2007
//==========================================
//*****Structures*****
struct point {
int x,y;
};//end struct
//==========================================
//1. Abstract class Spisok
//==========================================
template <class Data> class spisok {
protected:
struct list {
Data inf;
AnsiString name;
list*next;
};//end struct list
list *top,*p;
public:
virtual void add(Data value, AnsiString name)=0;
virtual void remove(int index)=0;
virtual void change(int index, Data value)=0;
virtual int count()=0;
virtual Data getvalue(int index)=0;
virtual AnsiString getname(int index)=0;
virtual int search (AnsiString name)=0;
};//end class spisok
//==========================================
//2. CLASS STACK
//==========================================
template <class Data> class stack: public spisok <Data>{
public:
//***************CONSTRUCTORS************************
stack(){top=new list;top=NULL;}
~stack(){}
//***************OPERATIONS************************
int count(){
int i=0;
p=top;
while (p!=NULL){
i++;
p=p->next;
}//end while
return(i);
}//end stack count
void add(Data value, AnsiString name){
p=new list;
p->next=top;
p->inf=value;
p->name=name;
top=p;
}//end stack add
int search (AnsiString name){
int i=0;
p=top;
while (p!=NULL){
i++;
if (p->name==name) return(i);
}//end while
return(0);
}//end function
void remove(int index){
list*q;
p=top;
for (int i=1;i<index-1;i++) p=p->next;
q=p->next;
if (q==NULL) delete(q); else {p->next=p->next->next;delete(q);}
}//end stack remove
void change(int index, Data value){
p=top;
for (int i=1;i<index;i++) p=p->next;
p->inf=value;
}//end stack change
Data getvalue(int index){
if (index<=this->count()){
p=top;
for (int i=1;i<index;i++) p=p->next;
return(p->inf);
}//end if
}//end function
AnsiString getname(int index){
p=top;
for (int i=1;i<index;i++) p=p->next;
return(p->name);
}//end function
void clear(){
}//end function
};//end class stack
//==========================================
//3. CLASS QUEUE
//==========================================
template <class Data> class queue: public stack <Data> {
public:
queue(){top=new list;top->next=NULL;p=top;}
~queue(){}
void add(Data value, AnsiString name){
p->next=new list;
p->next->next=NULL;
p->inf=value;
p->name=name;
p=p->next;
}//end function
int count(){
int i=0;
p=top;
while (p->next!=NULL){
i++;
p=p->next;
}//end while
return(i);
}//end queue count
};//end queue class
//==========================================
//4. CLASS LINE
//==========================================
class Tline {
public:
point p1,p2;
TColor color;
bool secondary;
Tline(){color=0;secondary=0;}
~Tline(){}
void setline(point p1,point p2,long int col,bool sec);
point cut(float k);
};//end line class
//------------------------------------------
point Tline::cut(float k){
point p;
p.x=p1.x+k*(p2.x-p1.x);
p.y=p1.y+k*(p2.y-p1.y);
return(p);
}//end function
void Tline::setline(point Point1,point Point2,long int col,bool sec){
p1.x=Point1.x;p1.y=Point1.y;
p2.x=Point2.x;p2.y=Point2.y;
color=col;secondary=sec;
}//end function
//==========================================
//5. CLASS Bezie Curve
//==========================================
class BCurve {
protected:
bool show_secondary;
public:
TColor color;
AnsiString Name;
TColor scol;
float k;
Tline l1,l2;
BCurve(){}
queue <Tline> Create(float,Tline,Tline,TColor,TColor,bool,AnsiString);
queue <Tline> Load();
};//end BCurve Class
queue <Tline> BCurve::Create(float koef,Tline line1,Tline line2,TColor col, TColor colsec, bool sec, AnsiString NameOfCurve)
{
queue <Tline> L;
point p1,p2;
Tline l;
k=koef; l1=line1,l2=line2;color=col;show_secondary=sec;scol=colsec;
l1.secondary=true;l2.secondary=true;l1.color=colsec;l2.color=colsec;Name=NameOfCurve;
if (show_secondary) {L.add(l1,Name);L.add(l2,Name);}
while (!(l.p1.x==l.p2.x && l.p1.y==l.p2.y)){
p1=l1.cut(k);p2=l2.cut(k);
l.setline(p1,p2,colsec,1);
if (show_secondary) L.add(l,Name);
l2.p1=p2;p2=l.cut(k);p1=l1.p1;
l.setline(p1,p2,color,0);L.add(l,Name);
l1.p1=p2;l1.p2=l2.p1;
}//end while
return (L);
}//end function
queue <Tline> BCurve::Load(){
return(this->Create(k,l1,l2,color,scol,show_secondary,Name));
}//end function
class TRectangle {
public:
queue <Tline> Create(int x1,int y1,int x2,int y2,TColor col);
};//end rectangle class
queue <Tline> TRectangle::Create(int x1,int y1,int x2,int y2,TColor col){
queue <Tline> Lines;
Tline l1;
l1.p1.x=x1;l1.p1.y=y1;l1.p2.x=x2;l1.p2.y=y1;l1.color=col;l1.secondary=false;
Lines.add(l1,"Rectangle");
l1.p1.x=x2;l1.p1.y=y1;l1.p2.x=x2;l1.p2.y=y2;l1.color=col;l1.secondary=false;
Lines.add(l1,"Rectangle");
l1.p1.x=x2;l1.p1.y=y2;l1.p2.x=x1;l1.p2.y=y2;l1.color=col;l1.secondary=false;
Lines.add(l1,"Rectangle");
l1.p1.x=x1;l1.p1.y=y2;l1.p2.x=x1;l1.p2.y=y1;l1.color=col;l1.secondary=false;
Lines.add(l1,"Rectangle");
return (Lines);
}//end function
//=========
//Переменные
queue <Tline> LineBufer;
int n=0;
Tline l1,l2;
queue <int> Objects;
//=========
//---------------------------------------------------------------------------
__fastcall TfrmMain::TfrmMain(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void LoadLines(bool sec){
Tline l1;
int checkedItem=frmMain->ListBox1->ItemIndex;
frmMain->ListBox1->Clear();
frmMain->lstObjects->Clear();
for (int i=1;i<=LineBufer.count();i++){
l1=LineBufer.getvalue(i);
frmMain->lblPicture->Canvas->Pen->Color=l1.color;
if ((sec && l1.secondary)||!l1.secondary){
if (l1.secondary) frmMain->lblPicture->Canvas->Pen->Style=2; else frmMain->lblPicture->Canvas->Pen->Style=0;
frmMain->lblPicture->Canvas->MoveTo(l1.p1.x,l1.p1.y);
frmMain->lblPicture->Canvas->LineTo(l1.p2.x,l1.p2.y);
}//end if
frmMain->ListBox1->Items->Add(IntToStr(l1.p1.x)+";"+IntToStr(l1.p1.y)+" - "+IntToStr(l1.p2.x)+";"+IntToStr(l1.p2.y));
}//next i
frmMain->ListBox1->ItemIndex=checkedItem;
for (int i=1;i<=Objects.count();i++){
if (Objects.getvalue(i)==1)frmMain->lstObjects->Items->Add("Line (1 lines)"); else
if (Objects.getvalue(i)==4)frmMain->lstObjects->Items->Add("Rectangle (4 lines)"); else
frmMain->lstObjects->Items->Add("Bezie Curve ("+IntToStr(Objects.getvalue(i))+" lines)");
}//next i
}//end function
//---------------------------------------------------------------------------
void __fastcall TfrmMain::lblPictureMouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (cboObject->Text=="Кривая Безье"){
n++;
if (n==1) {l1.p1.x=X;l1.p1.y=Y;}
if (n==2) {l1.p2.x=X;l1.p2.y=Y;l2.p1.x=X;l2.p1.y=Y;}
if (n==3) {
BCurve CurveBufer;
queue <Tline> Lines;
int firstNumber=0;
l2.p2.x=X;l2.p2.y=Y;
Lines=CurveBufer.Create(0.25,l1,l2,clbColor->Selected,clbSecond->Selected,1,"Bezie");
n=0;
firstNumber=LineBufer.count();
for (int i=0;i<=Lines.count();i++) LineBufer.add(Lines.getvalue(i),"Bezie");
LoadLines(chkSecondary->Checked);
firstNumber=LineBufer.count()-firstNumber;
Objects.add(firstNumber,"Bezie");
lstObjects->Items->Add("Bezie Curve ("+IntToStr(firstNumber)+" lines)");
}//end if n==3
}//end if Curve
if (cboObject->Text=="Линия"){
n++;
frmMain->Canvas->Pen->Color=clbColor->Selected;
if (n==1) {l1.p1.x=X;l1.p1.y=Y;}
if (n==2) {
l1.p2.x=X;l1.p2.y=Y;
LineBufer.add(l1,"");
Objects.add(1,"Line");
LoadLines(chkSecondary->Checked);
n=0;
}//end if n==2
}//End if Line
if (cboObject->Text=="Прямоугольник"){
n++;
queue <Tline> Lines;
TRectangle Rect;
if (n==1) {l1.p1.x=X;l1.p1.y=Y;}
if (n==2) {
l1.p2.x=X;l1.p2.y=Y;
Lines=Rect.Create(l1.p1.x,l1.p1.y,l1.p2.x,l1.p2.y,clbColor->Selected);
for (int i=0;i<=Lines.count();i++) LineBufer.add(Lines.getvalue(i),"");
Objects.add(4,"Rectangle");
LoadLines(chkSecondary->Checked);
n=0;
}//end if n==2;
}//end if rectangle;
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::chkSecondaryClick(TObject *Sender)
{
frmMain->lblPicture->Refresh();
LoadLines(chkSecondary->Checked);
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::clbColorChange(TObject *Sender)
{
Tline l1;
int begin=0;
for (int i=0;i<lstObjects->ItemIndex;i++)begin+=Objects.getvalue(i);
for (int i=begin;i<=begin+Objects.getvalue(lstObjects->ItemIndex+1);i++){
l1=LineBufer.getvalue(i);
if (!l1.secondary){
l1.color=clbColor->Selected;
LineBufer.change(i,l1);
}//end if
}//next i
LoadLines(chkSecondary->Checked);
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::clbSecondChange(TObject *Sender)
{
Tline l1;
int begin=0;
for (int i=0;i<lstObjects->ItemIndex;i++)begin+=Objects.getvalue(i);
for (int i=begin;i<=begin+Objects.getvalue(lstObjects->ItemIndex+1);i++){
l1=LineBufer.getvalue(i);
if (l1.secondary){
l1.color=clbSecond->Selected;
LineBufer.change(i,l1);
}//end if
}//next i
LoadLines(chkSecondary->Checked);
}
//---------------------------------------------------------------------------
int WhichObject (int number) {
int object=0;