如何在TVirtualStringTree中绘制动画水平条?

时间:2016-08-02 09:45:17

标签: delphi delphi-xe8 virtualtreeview tvirtualstringtree

我的目标是在VST

中绘制自定义动画进度条

我的目标是绘制与下图相似的结果,我尝试做这样的事情OnBeforeCellPaint

procedure TForm2.VTs1BeforeCellPaint(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
var
  NewRect : TRect;
  xOff, yOff : Integer;
  ProgressBarRect: TRect;
  Percents: Real;
  DrawProgressBar: Boolean;
begin
  //draw progress
  Percents := 10; // 40%
  // progressBar on Column 3
  begin
  // draw progressbar
    ProgressBarRect.Left := 0;
    ProgressBarRect.Top := CellRect.Top + 1;
    ProgressBarRect.Right := round((CellRect.Right - CellRect.Left) * Percents)  + CellRect.Left;
    ProgressBarRect.Bottom := CellRect.Bottom - 1;
    if (ProgressBarRect.Right - ProgressBarRect.Left) > 0 then
    begin
      TargetCanvas.Brush.Color := RGB(179,255,102);
      TargetCanvas.FillRect(ProgressBarRect);
    end;
  // ProgressBarRect
    inc(ProgressBarRect.Left);
    inc(ProgressBarRect.Top);
    dec(ProgressBarRect.Right);
    dec(ProgressBarRect.Bottom);
    if (ProgressBarRect.Right - ProgressBarRect.Left) > 0 then
    begin
      TargetCanvas.Brush.Color := RGB(221,255,187);
      TargetCanvas.FillRect(ProgressBarRect);
    end;
  end; 
end;

但是我不能做同样的结果,并采用与后面的图像相同的方法:

enter image description here

这是我编码的结果:

enter image description here

进度条正在进入不在它旁边的节点,并且它与图像中显示的设计不同,它是节点的黄色长背景,我希望它在节点的左侧并且具有相同的节点设计我上面发布的动画图片。

2 个答案:

答案 0 :(得分:2)

OnBeforeCellPaint仅在绘制单元格之前触发一次。

我使用计时器重新绘制VST以“动画”矩形。

请注意,Percents是小数,而不是百分比值,因此100%1

一个非常基本的演示如下:

private
  Percents: Real;

. . .

implementation

procedure TForm2.FormCreate(Sender: TObject);
begin
  Percents := 0;
  VirtualStringTree1.AddChild(nil);
end;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
  if Percents > 1 then
    Percents := 0
  else
    Percents := Percents + 0.025;

  VirtualStringTree1.Repaint;
end;

procedure TForm2.VirtualStringTree1BeforeCellPaint(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
const
  CPROGBARWIDTH = 30;//rect width
  CPROGBARSTEPS = 6;//how many rect is 100%
var
  r: TRect;
  h, n: Integer;
begin
  if Percents > 1 then
    Percents := 1
  else if Percents = 0 then
    Exit;//nothing to draw

  h := Round(CellRect.Height / CPROGBARSTEPS) - 1;

  r.Top := CellRect.bottom - h - 1;
  r.Left := 1;{align left}
  //r.Left := CellRect.Right - CPROGBARWIDTH - 1;{align right}
  r.Width := CPROGBARWIDTH;

  TargetCanvas.Brush.Color := clSkyBlue;

  n := Ceil(Percents * CPROGBARSTEPS);//how many rect to draw?

  while n > 0 do begin
    r.Height := h;
    TargetCanvas.FillRect(r);
    Dec(r.Top, 1 + h);
    Dec(n);
  end;
end;

八月假期奖金 AKA“动画左侧100%非动画矩形

这与问题中的动画GIF类似。

这里使用了一个嵌套例程。

procedure drawProgress(AWidth: Integer; APercent: Real; ASteps: Integer; ALeft: Integer = 1);

AWidth矩形宽度
APercent进度百分比
ASteps个完整100%进度的块数 ALeft矩形左上角点的水平坐标

procedure TForm2.VirtualStringTree1BeforeCellPaint(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);

  procedure drawProgress(AWidth: Integer; APercent: Real; ASteps: Integer; ALeft: Integer = 1);
  var
    r: TRect;
    h, n: Integer;
  begin
    if APercent > 1 then
      APercent := 1
    else if APercent = 0 then
      Exit;//nothing to draw

    h := Round(CellRect.Height / ASteps) - 1;

    r.Top := CellRect.bottom - h - 1;
    r.Left := ALeft;
    r.Width := AWidth;

    TargetCanvas.Brush.Color := clSkyBlue;

    n := Ceil(APercent * ASteps);//how many rect to draw?

    while n > 0 do begin
      r.Height := h;
      TargetCanvas.FillRect(r);
      Dec(r.Top, 1 + h);
      Dec(n);
    end;
  end;

begin
  drawProgress(10,        1, 7);
  drawProgress(30, Percents, 7, 1 + 10 + 1);
end;

答案 1 :(得分:1)

首先,你需要让你的细胞(行)高度更大。我猜你知道怎么做。

接下来,正如我在评论中所说,你使用错误的方向进行计算:

最后你不要将你的百分比除以100!

procedure TForm2.VTs1BeforeCellPaint(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
var
  NewRect : TRect;
  xOff, yOff : Integer;
  ProgressBarRect: TRect;
  Percents: Real;
  DrawProgressBar: Boolean;
begin
  //draw progress
  // Percents := 10; // 40% // for testing?
  // progressBar on Column 3
  begin
  // draw progressbar
    ProgressBarRect.Left := 0;
    ProgressBarRect.Top := round((CellRect.Top - CellRect.Bottom) * Percents/100)  + CellRect.Bottom;
    ProgressBarRect.Right := 30;
    ProgressBarRect.Bottom := CellRect.Bottom - 1;
    if (ProgressBarRect.Top - ProgressBarRect.Bottom) > 0 then
    begin
      TargetCanvas.Brush.Color := RGB(179,255,102);
      TargetCanvas.FillRect(ProgressBarRect);
    end;
  // ProgressBarRect
    inc(ProgressBarRect.Left);
    inc(ProgressBarRect.Top);
    dec(ProgressBarRect.Right);
    dec(ProgressBarRect.Bottom);
    if (ProgressBarRect.Top - ProgressBarRect.Bottom) > 0 then
    begin
      TargetCanvas.Brush.Color := RGB(221,255,187);
      TargetCanvas.FillRect(ProgressBarRect);
    end;
  end; 
end;

编辑注释

已更新,以删除修复大小为10%的测试行