Я столкнулся с небольшой проблемой.
Представьте себе две вещи: форму, которая должна быть покрыта - обложка; и формы, которые будут охватывать Cover-Form-Tiles. Моя главная цель - покрыть мою обложку с черепицей. Так что это будет похоже на плитки. Я проиллюстрирую эту идею изображением ниже
Желтый цвет - обложка, коричневые формы - Плитка. На этом изображении вы можете видеть, что формы расположены слишком близко друг к другу - между ними нет свободного пространства. Это то что мне нужно.
Но когда я пытаюсь достичь такого же эффекта, я получаю неудовлетворительный результат. Он представлен на рисунке ниже
Второе изображение имеет смещение после последней плитки. Это происходит из-за разного размера формы. Я не знаю точно, какую ширину у меня будет иметь Cover-Form. Я просто разделяю всю ширину Cover-Form на три части. Но если Cover-Form имеет ширину, например, 173 пикселя, каждая из моих Tiles будет иметь ширину равной 173/3 = 57,6 пикселя, которая будет круглой до 58, но 58 * 3 = 174, и это плохо.Ошибки в расчетах позиций форм в Delphi
Код ниже работает как на втором изображении.
type
TTileArray = Array of Array of TPoint;
// This routine comes here from David's answer below and were changed by me
procedure EvenlySpacedTiles(PixelCountH, PixelCountV, TileCount: Integer; var ArrayOut: TTileArray);
var
X: Integer;
Y: Integer;
OldH: Integer;
OldV: Integer;
OldCount: Integer;
OldCount1: Integer;
TempInt: Integer;
begin
if (PixelCountH) or (PixelCountV) or(TileCount) = 0 then
Exit;
OldH := PixelCountH;
OldCount1 := TileCount;
for X:=Low(ArrayOut) to High(ArrayOut) do
begin
OldV := PixelCountV;
OldCount := TileCount;
TempInt := OldH div OldCount1;
Dec(OldH, TempInt);
Dec(OldCount1);
for Y:=Low(ArrayOut) to High(ArrayOut) do
begin
ArrayOut[X, Y] := Point(TempInt, OldV div OldCount);
Dec(OldV, ArrayOut[X, Y].Y);
Dec(OldCount);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
F: TForm;
P: TForm;
Delta: Integer;
PrevLeft: Integer;
PrevTop: Integer;
X:Integer;
Y: Integer;
Arr: TTileArray;
IncLeft: Integer;
begin
Delta := 3;
F := TForm.Create(Application);
F.BorderStyle := Forms.bsNone;
F.SetBounds(0, 0, 173, 115);
F.Position := poDesktopCenter;
F.Color := $11DFEE;
F.Show;
SetLength(Arr, Delta, Delta);
EvenlySpacedTiles(F.Width, F.Height, Delta, Arr);
PrevLeft := F.Left;
PrevTop := F.Top;
IncLeft := 0;
for X:=Low(Arr) to High(Arr) do
begin
PrevTop := F.Top;
Inc(PrevLeft, IncLeft);
for Y:=Low(Arr) to High(Arr) do
begin
P := TForm.Create(Application);
P.FormStyle := fsStayOnTop;
P.BorderStyle := Forms.bsNone;
P.Color := Random($FFFFFF);//clSkyBlue;
P.Show;
P.Width := Arr[X, Y].X;
P.Height := Arr[X, Y].Y;
P.Left := PrevLeft;
P.Top := PrevTop;
P.Canvas.Rectangle(P.ClientRect);
Inc(PrevTop, Arr[X, Y].y);
IncLeft := Arr[X, Y].X;
end;
end;
end;
Так что мой вопрос: как я могу регулировать ширину всех плитки (3 для каждой строки) независимо от ширины чехле формы в?
Заранее спасибо.
Edited
P.S. Я модифицировал некоторые части кода выше. Теперь он отлично работает даже с чрезвычайно маленькой и большой шириной Cover-Form - от 67 px. до 1237 px. Конечно, есть способ улучшить этот код, но главная цель достигнута. Я думаю, что смогу закончить вертикальное размещение плиток завтра и опубликовать эту часть там.
Во многом комментарий Дэвида дает мне представление о том, как это сделать. Спасибо, Дэвид!
P.S.S.
Я прочитал первый комментарий Дэвида по диагонали, поэтому я обновляю код для работы по-другому, но результат все еще не очень хорош. Вы можете увидеть это на картинке ниже.
Первая плитка имеет 57 px. ширина; второй - 59 px .; третья плитка - всего 31 px.
Я просто не могу понять, как правильно разместить плитки, используя алгоритм, предложенный в комментарии Дэвида.
P.S.S.S.
И снова нет результата.
Правая красная линия демонстрирует большой размер последней плитки. Каждая плитка имеет ширину 58 пикселей.
David написал (а):
173/3 = 58. 173-58 = 115. 115/2 = 58. 115-58 = 57. 57/1 = 57
Я могу рассчитать его в реальной жизни, но я не могу его реализовать в коде.
Исходный код обновлен.
P.S.S.S.S.
Процедура Дэвида не делает то, что он должен делать. Рисунок ниже иллюстрирует это.
Промежуток между первой и второй плиточками и красная линия с правой стороны, как на предыдущем рисунке.
P.S.S.S.S.S.
Ну, в это время первая часть моей задачи выполнена. Второй - добавляет больше плиток, но я не уверен, действительно ли они им нужны. И я благодарен за это David Heffernan !! Он тратит так много времени, чтобы объяснить мне некоторые вещи, и я не знаю, как сказать ему больше, чем просто «Большое спасибо». Я боюсь, я могу просто увеличить его репутацию и принять его пост в качестве ответа. Это действительно делает работу! На фото мы можем увидеть результат мне нужен
P.S.S.S.S.S.S.
Я обновил исходный код, чтобы он мог разместить плитки и вертикально.
173 не точно делится на 3. Ergo, вы не можете использовать одну и ту же ширину для каждого столбца. Вместо этого сделайте это так. Начните с пикселов Npx. Разделите Ncol, округлите. Используйте это значение для столбца 0. Вычтите это значение из Npx и теперь разделите на Ncol-1. Завершите это значение и используйте для столбца 1. Повторите, пока вы не исчерпали пиксели и столбцы. –
Кроме того, если нет веской причины, которую вы оставили для краткости, вы не будете использовать каждую плиту в отдельной форме. Вместо этого используйте фигуры или что-то еще более подходящее. – DNR
@DavidHeffernan, вы имеете в виду следующую ситуацию, верно? Предположим, у меня есть Cover-Form с шириной 173 пикселя. Я знаю, что я должен разместить три плитки в строке, поэтому я разделяю 173/3 = 57. Это ширина каждой плитки. Затем я умножаю 3 плитки на 57 и получаю 171. Я знаю, что 171 меньше 173, и в соответствии с этим я должен сделать это: 173 - 171 = 2. Это место размера после последнего Плитка, которое представлено на втором изображение, поэтому я просто увеличиваю ширину последнего TIle, чтобы полностью соответствовать Cover-Form. Что вы думаете об этом методе? – Dima