unit MvcPieF;
//*******************************************************
// Form for the pie chart view for example program
// demonstrating the Model/View/Controller (MVC)
// paradigm.
//*******************************************************
// Copyright (C) 1998 John Wiley & Sons, Inc.
// All rights reserved. See additional copyright
// information in Readme.txt.
//*******************************************************

interface

uses
  SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs,
  Menus, StdCtrls, ComCtrls,
  MvcModel;

const
    NUM_COLORS = 13;
type
  TPieForm = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    mnuClose: TMenuItem;
    procedure mnuCloseClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormPaint(Sender: TObject);
    procedure ShowText(x, y, angle1, angle2, r1, r2 : Single; txt : String);
    procedure FormResize(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    private
      { Private declarations }
      Colors : array [0..NUM_COLORS - 1] of TColor;

    public
      { Public declarations }
      TheModel : TMvcModel;
      TheView  : TMvcView;
  end;

var
    PieForm: TPieForm;

implementation

{$R *.DFM}

const
    PI = 3.14159265;

procedure TPieForm.mnuCloseClick(Sender: TObject);
begin
    Close;
end;

procedure TPieForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    // Destroy the view.
    TheView.Free;

    Action := caFree;
end;

// Draw the data.
procedure TPieForm.FormPaint(Sender: TObject);
var
    rect                           : TRect;
    angle1, angle2, total, percent : Single;
    margin, x, y, r1, r2           : Integer;
    x1, y1, x2, y2, x3, y3, x4, y4 : Integer;
    i                              : Integer;
begin
    // Erase the form.
    rect.Left := 0;
    rect.Top := 0;
    rect.Right := ClientWidth;
    rect.Bottom := ClientHeight;
    Canvas.Brush.Color := clSilver;
    Canvas.Brush.Style := bsSolid;
    Canvas.FillRect(rect);

    // Draw the pie chart.
    margin := 2 * Canvas.TextHeight('X');
    x := ClientWidth div 2;
    y := ClientHeight div 2;
    if (x > y) then
        r1 := y - margin
    else
        r1 := x - margin;
    if (r1 <= 0) then exit;
    x1 := x - r1;
    y1 := y - r1;
    x2 := x + r1;
    y2 := y + r1;

    r2 := r1 + margin div 2;
    total := TheModel.TotalExpenses;

    // Display the values.
    angle1 := 0;
    x3 := x + 100;
    y3 := y;
    for i := 1 to TheModel.NumValues do
    begin
        percent := TheModel.ExpenseValue(i) / total;
        angle2 := angle1 + 2 * PI * percent;
        x4 := x + Round(100 * Cos(angle2));
        y4 := y + Round(100 * Sin(angle2));

        Canvas.Brush.Color := Colors[i mod NUM_COLORS];
        Canvas.Pen.Color := Colors[i mod NUM_COLORS];
        Canvas.Pie(x1, y1, x2, y2, x4, y4, x3, y3);
        ShowText(x, y, angle1, angle2, r1, r2,
            TheModel.ExpenseName(i));

        angle1 := angle2;
        x3 := x4;
        y3 := y4;
    end;

    // Draw a circle around it all.
    Canvas.Brush.Color := clBlack;
    Canvas.Brush.Style := bsClear;
    Canvas.Pen.Color := clBlack;
    Canvas.Ellipse(x1, y1, x2, y2);
    Canvas.Brush.Style := bsSolid;
end;

// Display text for a pie chart entry.
procedure TPieForm.ShowText(x, y, angle1, angle2, r1, r2 : Single; txt : String);
var
    x1, y1, x2, y2, theta : Single;
begin
    theta := (angle1 + angle2) / 2;
    x1 := x + r1 * Cos(theta);
    y1 := y + r1 * Sin(theta);
    x2 := x + r2 * Cos(theta);
    y2 := y + r2 * Sin(theta);
    Canvas.MoveTo(Round(x1), Round(y1));
    Canvas.LineTo(Round(x2), Round(y2));

    if ((theta > PI / 2) and (theta < 3 * PI / 2)) Then
        // It's in the left half.
        x2 := x2 - Canvas.TextWidth(txt);
    y2 := y2 + Canvas.Font.Height div 2;

    Canvas.Pen.Color := clBlack;
    Canvas.Brush.Color := clSilver;
    Canvas.TextOut(Round(x2), Round(y2), txt);
end;

procedure TPieForm.FormResize(Sender: TObject);
begin
    Refresh;
end;

// Initialize the list of colors.
procedure TPieForm.FormCreate(Sender: TObject);
begin
    Colors[0]  := clYellow;
    Colors[1]  := clAqua;
    Colors[2]  := clBlack;
    Colors[3]  := clFuchsia;
    Colors[4]  := clBlue;
    Colors[5]  := clGreen;
    Colors[6]  := clDkGray;
    Colors[7]  := clLime;
    Colors[8]  := clMaroon;
    Colors[9]  := clRed;
    Colors[10] := clTeal;
    Colors[11] := clPurple;
    Colors[12] := clWhite;
end;

end.
