Раскрашивание одной ячейки в Delphi DrawGrid по клику и по таймеру

Я пытаюсь создать эмулятор Game of Life. Раньше я работал с StrGrid, однако это было медленнее, и мне сказали использовать DrawGrid.

Моя программа работает с двумя массивами: strArray, который содержит все значения для следующего поколения ячеек, и currentArray, который содержит все значения для текущего поколения ячеек (оба имеют тип array [1 .. 127] массива [1 . . 127] строки; я знаю, что было бы лучше использовать логический массив, но это более старая программа). По таймеру алгоритм подсчитывает количество живых ячеек вокруг каждой ячейки и присваивает ему значение в strArray, T (обозначение живой ячейки) или F (обозначение мертвой ячейки). Затем этот шаблон записывается в currentArray для использования в следующий раз, когда необходимо вычислить живые ячейки. Затем я хотел бы изменить цвет каждой ячейки на белый, если соответствующая ячейка соответствует «F» в currentArray, и изменить ее на черный, если она соответствует «T». Я также хотел бы иметь возможность покрасить ячейку, которую я нажимаю черным, и меняю ее значение в таблице данных на «T».

Однако я не знаком с вытяжными сетками и не могу найти никакой важной информации, которая имела бы для меня какой-либо смысл. Когда я использовал строковую сетку, вы могли получить доступ к содержимому каждой ячейки, используя stringgrid.cells[stringgrid.col, stringgrid.row] := 'whatever'; однако я не могу найти аналогичный метод для DrawGrid.

Подводя итог, мне нужна помощь:

  • Измените цвет ячейки в сетке внутри процедуры timer.onTick.
  • Изменение цвета ячейки в сетке, когда я нажимаю на нее.

Я надеюсь, что вы можете мне помочь. Спасибо!


person James Paterson    schedule 05.02.2014    source источник
comment
Что-то like this? [Мне интересно, почему метод InvalidateCell защищен; для TDrawGrid это могло быть полезно как общедоступное]   -  person TLama    schedule 06.02.2014
comment
@TLama: почему вы разместили этот код в pastebin вместо того, чтобы опубликовать его здесь в качестве ответа?   -  person Remy Lebeau    schedule 06.02.2014
comment
@Remy, потому что для ОП кажется более полезным объяснение, чем просто код, и мне было лень писать историю.   -  person TLama    schedule 06.02.2014


Ответы (1)


Единственная реальная разница между TDrawGrid и TStringGrid заключается в том, что TDrawGrid не хранит никаких данных ячеек, тогда как TStringGrid хранит, а также то, что вы должны рисовать все самостоятельно в TDrawGrid, тогда как TStringGrid по умолчанию рисует строки ячеек для вас (но вы также можете настроить нарисуйте клетки, если хотите). У вас есть собственные массивы для хранения данных ячеек. Используйте событие OnDrawCell, чтобы рисовать ячейки так, как вы хотите. Это дает вам Col и Row текущей ячейки. Вы должны просто получить доступ к соответствующим элементам массива и соответствующим образом установить свойства сетки Canvas, такие как ее Brush.Color и Font.Color, а затем вызвать методы Canvas.FillRect() и Canvas.TextRect() по мере необходимости.

Что касается обработки кликов, все, что вам нужно сделать, это обновить свой массив по мере необходимости, а затем Invalidate() сетку, чтобы вызвать перерисовку с использованием последних данных.

Например:

procedure TForm1.TimerTick(Sender: TObject);
begin
  // update contents of currentArray as needed...
  DrawGrid1.Invalidate;
end;

procedure TForm1.DrawGrid1Click(Sender: TObject);
begin
  if currentArray[DrawGrid1.Col][DrawGrid1.Row] <> 'T' then
  begin
    currentArray[DrawGrid1.Col][DrawGrid1.Row] := 'T';
    DrawGrid1.Invalidate;
  end;
end;

procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Longint; Rect: TRect; State: TGridDrawState);
begin
  if currentArray[ACol][ARow] = 'F' then
  begin
    DrawGrid1.Canvas.Brush.Color := clWhite;
    DrawGrid1.Canvas.Font.Color := clBlack;
  end else
  begin
    DrawGrid1.Canvas.Brush.Color := clBlack;
    DrawGrid1.Canvas.Font.Color := clWhite;
  end;
  DrawGrid1.Canvas.FillRect(Rect);
  DrawGrid1.Canvas.TextRect(Rect, Rect.Left, Rect.Top, currentArray[ACol][ARow]);
end;
person Remy Lebeau    schedule 06.02.2014