массив TRectangles в FMX - PullRequest
       34

массив TRectangles в FMX

0 голосов
/ 28 декабря 2018

Я пытаюсь расширить код этого от использования одного TRectangle до использования нескольких прямоугольников, которые можно добавить во время выполнения.В этом примере код для щелчка и перетаскивания применяется только к этому одному TRectangle Rectangle1.Мне нужно сделать его более общим, чтобы оно работало с любым прямоугольником, который я добавляю в форму (прямоугольники не появятся во время разработки).Я нашел этот код для создания пользовательского класса , и он отлично работает для создания новых прямоугольников.Я могу назначить методы, которые запускаются, когда на них нажимают, но я думаю, что это неправильный путь, чтобы идти вниз из-за того, что это отдельный класс от TForm1 ... и многие из точек данных, которые мне нужны для работы моего кода, взяты изTForm1 (положения и т.

Не знаю, с чего начать ... но сначала я думаю, что мне нужно знать, как создать массив элементов управления, к которым можно получить доступ, примерно так:

rectangles[i]->Position->X = ...

И затем иметь событиятот огонь, когда щелкают прямоугольники, который может воздействовать на этот i-й прямоугольник:

void __fastcall TForm1::rectsMouseDown(TObject *Sender, TMouseButton Button,
      TShiftState Shift, float X, float Y){
rectangles[i]->Position->X = ....
rectangles[i]->Position->Y = .....
}   

ОБНОВЛЕНИЕ 1 : я могу создать вектор TRectangles и манипулировать им черезвектор.Теперь, как я могу получить доступ к их событиям для запуска кода (например, OnClick)?Вот что у меня есть:

#include <vector>  // in my cpp file

std::vector<TRectangle*> myRects; // in my cpp file outside of any function so it is global

void __fastcall TForm1::Button3Click(TObject *Sender)
{
TRectangle *R = new TRectangle(this);
R->Parent = this;
R->Position->X = 20 + 5*myRects.size(); // slightly offset them in space
R->Position->Y = 20;
R->Tag = myRects.size()+1;  // i think this is how i will tell them apart
myRects.push_back(R);
}

Я могу переместить прямоугольник так:

void __fastcall TForm1::Button4Click(TObject *Sender)
{
myRects[1]->Position->X = 50;  // this moves rectangle number 2.
myRects[1]->Position->Y = 50;
}

ОБНОВЛЕНИЕ 2 : С направлением Реми у меня все работаетсейчас!Я добавил R->OnClick = &myRectOnClick; к своему Button3Click методу прямо над push_back.Затем я добавил следующий метод к моей TForm1.

void __fastcall TForm1::myRectOnClick(TObject *Sender)
{
 if (TRectangle *Re = dynamic_cast<TRectangle *>(Sender)) {  // make sure result of cast is not null
  ShowMessage("Rectangle " + IntToStr(Re->Tag));  // Tag is how i know which rectangle i'm dealing with
 }
} 

ОБНОВЛЕНИЕ 3 : Не уверен, что это должен быть новый вопрос ... но я добавил PopupMenu1, который я хочувызвать правой кнопкой мыши по прямоугольникам.Я включил его с R->PopupMenu = PopupMenu1 в коде Button3Click.Событие MenueItem1Click просто делает ShowMessage отображением номера прямоугольников (currentR).Ну, глобальный int currentR для прямоугольника не устанавливается, когда я просто щелкаю правой кнопкой мыши на прямоугольнике.Я должен сначала щелкнуть левой кнопкой мыши, а затем щелкнуть правой кнопкой мыши по currentR, чтобы установить этот тег прямоугольников.Ниже приведен мой код для события нажатия мыши на прямоугольнике - кажется, он должен всегда устанавливать currentR для текущего прямоугольника независимо от щелчка левой или правой кнопкой мыши.

void __fastcall TForm1::myRectOnMouseDown(TObject *Sender, TMouseButton Button,
      TShiftState Shift, float X, float Y)
{
if (TRectangle *Re = dynamic_cast<TRectangle *>(Sender)) {  // make sure result of cast is not null
   currentR = Re->Tag; // which rectangle
   if (Button == 0) {  // left mb
   fMouseIsDown = true;
   fMouseInRectAtClick.X = X;
   fMouseInRectAtClick.Y = Y;
   }
 }
}

Для ясности вот моя последняя версияButton3Click код, который помещает новый прямоугольник в форму:

void __fastcall TForm1::Button3Click(TObject *Sender)
{
TRectangle *R = new TRectangle(this);
R->Parent = this;
R->Position->X = 20 + 5*myRects.size();
R->Position->Y = 20;
R->Tag = myRects.size()+1;
R->OnMouseDown = &myRectOnMouseDown;
R->OnMouseUp = &myRectOnMouseUp;
R->OnMouseMove = &myRectOnMouseMove;
R->PopupMenu = PopupMenu1; // to get a popup menu 
myRects.push_back(R);
}
...