《GOF设计模式—中介者 (MEDIATOR)—Delphi源码示例:字体对话框

来源:互联网 发布:复杂网络可控性 编辑:程序博客网 时间:2024/05/02 06:10

示例:字体对话框
说明:
例如,考虑一个图形用户界面中对话框的实现。对话框使用一个窗口来展现一系列的窗口组件,如按钮、菜单和输入域等。
clip_image002
FontDialogDirector可作为一个对话框中的窗口组件间的中介者。FontDialogDirector对象知道对话框中的各窗口组件,并协调它们之间的交互。它充当窗口组件间通信的中转中心。
clip_image002[5]
代码:
 clip_image002[7]
unit uFontDialog;

interface

uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, ExtCtrls, StdCtrls, Spin;

type
    TDialogDirector = class;

    {组件}
    TWidget = class
    private
        FDirector: TDialogDirector;
        FControl: TControl;
        function GetHeight: Integer;
        function GetLeft: Integer;
        function GetTop: Integer;
        function GetWidth: Integer;
        procedure SetHeight(const Value: Integer);
        procedure SetLeft(const Value: Integer);
        procedure SetParent(const Value: TWidget);
        procedure SetTop(const Value: Integer);
        procedure SetWidth(const Value: Integer);
    protected
        procedure DoMouseDown(Sender: TObject; Button: TMouseButton; Shift:
            TShiftState; X, Y: Integer);
    public
        constructor Create(ADirector: TDialogDirector);
        destructor Destroy; override;
        //---
        procedure Changed(); virtual;
        procedure HandleMouse(event: TMouseButton); virtual;
        //---
        property Left: Integer read GetLeft write SetLeft;
        property Top: Integer read GetTop write SetTop;
        property Height: Integer read GetHeight write SetHeight;
        property Width: Integer read GetWidth write SetWidth;
        property Parent: TWidget write SetParent;
    end;
    TFontDialog = class(TWidget)
    private
        FForm: TForm;
        function GetText: string;
        procedure SetText(const Value: string);
    public
        constructor Create(ADirector: TDialogDirector);
        //---
        function ShowModal: Integer;
        procedure Close;
        //---
        property Text: string read GetText write SetText;
    end;
    TLabel1 = class(TWidget)
    private
        FLabel: TLabel;
        function GetFont: TFont;
        function GetText: string;
        procedure SetText(const Value: string);
    public
        constructor Create(ADirector: TDialogDirector);
        //---
        property Text: string read GetText write SetText;
        property Font: TFont read GetFont;
    end;
    {输入域}
    TEntryField1 = class(TWidget)
    private
        FEdit: TEdit;
        function GetText: string;
        procedure SetText(const Value: string);
    public
        constructor Create(ADirector: TDialogDirector);
        //---
        procedure HandleMouse(event: TMouseButton); override;
        //---
        property Text: string read GetText write SetText;
    end;
    {列表框}
    TListBox1 = class(TWidget)
    private
        FListBox: TListBox;
        function GetSelection(): string;
        procedure SetList(const Value: TStrings);
    public
        constructor Create(ADirector: TDialogDirector);
        //---
        procedure HandleMouse(event: TMouseButton); override;
        //---
        property Selection: string read GetSelection;
        property List: TStrings write SetList;
    end;
    TPanel1 = class(TWidget)
    private
        FPanel: TPanel;
    public
        constructor Create(ADirector: TDialogDirector);
    end;
    TRadioButton1 = class(TWidget)
    private
        FRadioButton: TRadioButton;
        function GetChecked: Boolean;
        procedure SetChecked(const Value: Boolean);
        procedure SetText(const Value: string);
    public
        constructor Create(ADirector: TDialogDirector);
        //---
        procedure HandleMouse(event: TMouseButton); override;
        //---
        property Text: string write SetText;
        property Checked: Boolean read GetChecked write SetChecked;
    end;
    TSpinEdit1 = class(TWidget)
    private
        FSpinEdit: TSpinEdit;
        procedure DoChange(Sender: TObject);
        function GetValue: LongInt;
        procedure SetValue(const Value: LongInt);
    public
        constructor Create(ADirector: TDialogDirector);
        //---
        property Value: LongInt read GetValue write SetValue;
    end;
    TCheckBox1 = class(TWidget)
    private
        FCheckBox: TCheckBox;
        procedure SetText(const Value: string);
    public
        constructor Create(ADirector: TDialogDirector);
        //---
        property Text: string write SetText;
    end;
    TButton1 = class(TWidget)
    private
        FButton: TButton;
        procedure SetText(const Value: string);
    public
        constructor Create(ADirector: TDialogDirector);
        //---
        procedure HandleMouse(event: TMouseButton); override;
        //---
        property Text: string write SetText;
    end;

    {导控者}
    TDialogDirector = class
    protected
        procedure CreateWidgets(); virtual; abstract;
    public
        procedure ShowDialog(); virtual;
        procedure WidgetChanged(theChangedWidget: TWidget); virtual; abstract;
    end;
    TFontDialogDirector = class(TDialogDirector)
    private
        FFontDialog: TFontDialog;
        FFontLabel, FFamilyLabel, FWeightLabel, FSlantLabel, FSizeLabel: TLabel1;
        FFontName: TEntryField1;
        FFontList: TListBox1;
        FWeightPanel, FSlantPanel: TPanel1;
        FFontWeight1, FFontWeight2, FFontWeight3: TRadioButton1;
        FFontSlant1, FFontSlant2, FFontSlant3: TRadioButton1;
        FFontSize: TSpinEdit1;
        FCondensed: TCheckBox1;
        FOk: TButton1;
        FCancel: TButton1;
    protected
        procedure CreateWidgets; override;
    public
        destructor Destroy; override;
        //---
        procedure WidgetChanged(theChangedWidget: TWidget); override;
    end;

procedure Test;

implementation

procedure Test;
var
    ADirector: TFontDialogDirector;
begin
    ADirector := TFontDialogDirector.Create;
    ADirector.ShowDialog;
    ADirector.Free;
end;

procedure TDialogDirector.ShowDialog();
begin
    Self.CreateWidgets;
end;

constructor TWidget.Create(ADirector: TDialogDirector);
begin
    FDirector := ADirector;
end;

destructor TWidget.Destroy;
begin
    FControl.Free;
    //---
    inherited;
end;

procedure TWidget.Changed();
begin
    FDirector.WidgetChanged(self);
end;

procedure TWidget.DoMouseDown(Sender: TObject; Button: TMouseButton; Shift:
    TShiftState; X, Y: Integer);
begin
    self.HandleMouse(Button);
end;

function TWidget.GetHeight: Integer;
begin
    Result := FControl.Height;
end;

function TWidget.GetLeft: Integer;
begin
    Result := FControl.Left;
end;

function TWidget.GetTop: Integer;
begin
    Result := FControl.Top;
end;

function TWidget.GetWidth: Integer;
begin
    Result := FControl.Width;
end;

procedure TWidget.HandleMouse(event: TMouseButton);
begin
//....
end;

procedure TWidget.SetHeight(const Value: Integer);
begin
    FControl.Height := Value;
end;

procedure TWidget.SetLeft(const Value: Integer);
begin
    FControl.Left := Value;
end;

procedure TWidget.SetParent(const Value: TWidget);
begin
    FControl.Parent := TWinControl(Value.FControl);
end;

procedure TWidget.SetTop(const Value: Integer);
begin
    FControl.Top := Value;
end;

procedure TWidget.SetWidth(const Value: Integer);
begin
    FControl.Width := Value;
end;

constructor TListBox1.Create(ADirector: TDialogDirector);
begin
    inherited;
    //---
    FListBox := TListBox.Create(nil);
    FListBox.OnMouseDown := self.DoMouseDown;
    //---
    FControl := FListBox;
end;

function TListBox1.GetSelection(): string;
var
    i: Integer;
begin
    with FListBox do
    begin
        Result := '';
        for i := 0 to (Items.Count - 1) do
        begin
            if Selected[i] then
                Result := Items.Strings[i];
        end;
    end;
end;

procedure TListBox1.HandleMouse(event: TMouseButton);
begin
    if event = mbLeft then
        Self.Changed();
end;

procedure TListBox1.SetList(const Value: TStrings);
begin
    FListBox.Items := Value;
end;

constructor TEntryField1.Create(ADirector: TDialogDirector);
begin
    inherited;
    //---
    FEdit := TEdit.Create(nil);
    FControl := FEdit;
end;

function TEntryField1.GetText: string;
begin
    Result := FEdit.Text;
end;

procedure TEntryField1.HandleMouse(event: TMouseButton);
begin
//....
end;

procedure TEntryField1.SetText(const Value: string);
begin
    FEdit.Text := Value;
end;

constructor TButton1.Create(ADirector: TDialogDirector);
begin
    inherited;
    //---
    FButton := TButton.Create(nil);
    FButton.OnMouseDown := self.DoMouseDown;
    //---
    FControl := FButton;
end;

procedure TButton1.HandleMouse(event: TMouseButton);
begin
    if event = mbLeft then
        Self.Changed();
end;

procedure TButton1.SetText(const Value: string);
begin
    FButton.Caption := Value;
end;

procedure TFontDialogDirector.CreateWidgets;
const
    CNT_Left = 40;
    CNT_Height = 20;
    CNT_RowSize = 10;
var
    ATop, ALeft: Integer;
begin
    FFontDialog := TFontDialog.Create(self);
    with FFontDialog do
    begin
        Text := 'Font Chooser';
        Width := 350;
        Height := 500;
    end;
    //---
    FFontLabel := TLabel1.Create(self);
    with FFontLabel do
    begin
        Parent := FFontDialog;
        Top := 15;
        Left := 10;
        Text := 'The quick brown fox…';
        //---
        ATop := Top + Height + 20 + CNT_RowSize;
        ALeft := Left;
    end;
    //---
    FFamilyLabel := TLabel1.Create(self);
    with FFamilyLabel do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := ALeft;
        Text := 'Family';
    end;
    //---
    FFontName := TEntryField1.Create(self);
    with FFontName do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := ALeft + CNT_Left;
        Width := 250;
        //---
        ATop := Top + Height + CNT_RowSize;
    end;
    //---
    FFontList := TListBox1.Create(self);
    with FFontList do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := ALeft + CNT_Left;
        Width := 250;
        Height := 100;
        //---
        ATop := Top + Height + CNT_RowSize;
    end;
    //---
    FWeightLabel := TLabel1.Create(self);
    with FWeightLabel do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := ALeft;
        Text := 'Weight';
    end;
    //---
    FWeightPanel := TPanel1.Create(self);
    with FWeightPanel do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := ALeft + CNT_Left;
        Width := 200;
        Height := 20;
        //---
        ATop := Top + Height + CNT_RowSize;
    end;
    //---
    FFontWeight1 := TRadioButton1.Create(self);
    with FFontWeight1 do
    begin
        Parent := FWeightPanel;
        Top := 0;
        Left := 0;
        Text := 'medium';
    end;
    //---
    FFontWeight2 := TRadioButton1.Create(self);
    with FFontWeight2 do
    begin
        Parent := FWeightPanel;
        Top := 0;
        Left := FFontWeight1.Left + 60;
        Text := 'bold';
    end;
    //---
    FFontWeight3 := TRadioButton1.Create(self);
    with FFontWeight3 do
    begin
        Parent := FWeightPanel;
        Top := 0;
        Left := FFontWeight2.Left + 60;
        Text := 'demibold';
    end;
    //---
    FSlantLabel := TLabel1.Create(self);
    with FSlantLabel do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := ALeft;
        Text := 'Slant';
    end;
    //---
    FSlantPanel := TPanel1.Create(self);
    with FSlantPanel do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := ALeft + CNT_Left;
        Width := 200;
        Height := 20;
        //---
        ATop := Top + Height + CNT_RowSize;
    end;
    //---
    FFontSlant1 := TRadioButton1.Create(self);
    with FFontSlant1 do
    begin
        Parent := FSlantPanel;
        Top := 0;
        Left := 0;
        Text := 'roman';
    end;
    //---
    FFontSlant2 := TRadioButton1.Create(self);
    with FFontSlant2 do
    begin
        Parent := FSlantPanel;
        Top := 0;
        Left := FFontSlant1.Left + 60;
        Text := 'italic';
    end;
    //---
    FFontSlant3 := TRadioButton1.Create(self);
    with FFontSlant3 do
    begin
        Parent := FSlantPanel;
        Top := 0;
        Left := FFontSlant2.Left + 60;
        Text := 'oblique';
    end;
    //---
    FSizeLabel := TLabel1.Create(self);
    with FSizeLabel do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := ALeft;
        Text := 'Size';
    end;
    //---
    FFontSize := TSpinEdit1.Create(self);
    with FFontSize do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := ALeft + CNT_Left;
        Width := 50;
    end;
    //---
    FCondensed := TCheckBox1.Create(self);
    with FCondensed do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := FFontSize.Left + 60;
        Text := 'condensed';
        //---
        ATop := Top + Height + CNT_RowSize;
    end;
    //---
    FCancel := TButton1.Create(self);
    with FCancel do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := ALeft + 150;
        Text := 'Cancel';
    end;
    //---
    FOk := TButton1.Create(self);
    with FOk do
    begin
        Parent := FFontDialog;
        Top := ATop;
        Left := ALeft + 250;
        Text := 'Ok';
    end;
    //---
    FFontName.Text := '宋体';
    FFontList.List := Screen.Fonts;
    FFontWeight2.Checked := True;
    FFontWeight2.Changed;
    FFontSlant2.Checked := True;
    FFontSlant2.Changed;
    FFontSize.Value := 21;
    //---
    FFontDialog.ShowModal;
end;

destructor TFontDialogDirector.Destroy;
    //---
    procedure _FreeWidget(AWidget: TWidget);
    begin
        if AWidget <> nil then
            AWidget.Free;
    end;
begin
    _FreeWidget(FFontLabel);
    _FreeWidget(FFamilyLabel);
    _FreeWidget(FFontName);
    _FreeWidget(FFontList);
    _FreeWidget(FWeightLabel);
    _FreeWidget(FFontWeight1);
    _FreeWidget(FFontWeight2);
    _FreeWidget(FFontWeight3);
    _FreeWidget(FWeightPanel);
    _FreeWidget(FFontSlant1);
    _FreeWidget(FFontSlant2);
    _FreeWidget(FFontSlant3);
    _FreeWidget(FSlantPanel);
    _FreeWidget(FFontSize);
    _FreeWidget(FCondensed);
    _FreeWidget(FOk);
    _FreeWidget(FCancel);
    _FreeWidget(FFontDialog);
    //---
    inherited;
end;

procedure TFontDialogDirector.WidgetChanged(theChangedWidget: TWidget);
    //---
    procedure _SetFontName;
    var
        ASelection: string;
    begin
        ASelection := FFontList.Selection;
        //---
        FFontName.Text := ASelection;
        FFontLabel.Font.Name := ASelection;
    end;
begin
    if (theChangedWidget = FFontList) then
        _SetFontName
    else if (theChangedWidget = FFontWeight1) then
        FFontLabel.Font.Style := FFontLabel.Font.Style - [fsBold]
    else if (theChangedWidget = FFontWeight2) then
        FFontLabel.Font.Style := FFontLabel.Font.Style + [fsBold]
    else if (theChangedWidget = FFontWeight3) then
        FFontLabel.Font.Style := FFontLabel.Font.Style - [fsBold]
    else if (theChangedWidget = FFontSlant1) then
        FFontLabel.Font.Style := FFontLabel.Font.Style - [fsItalic]
    else if (theChangedWidget = FFontSlant2) then
        FFontLabel.Font.Style := FFontLabel.Font.Style + [fsItalic]
    else if (theChangedWidget = FFontSlant3) then
        FFontLabel.Font.Style := FFontLabel.Font.Style - [fsItalic]
    else if (theChangedWidget = FFontSize) then
        FFontLabel.Font.Size := FFontSize.Value
    else if (theChangedWidget = FOk) then
    begin
        ShowMessage('变更字体');
        FFontDialog.Close;
    end
    else if (theChangedWidget = FCancel) then
        FFontDialog.Close;
end;

procedure TFontDialog.Close;
begin
    FForm.Close;
end;

constructor TFontDialog.Create(ADirector: TDialogDirector);
begin
    inherited;
    //---
    FForm := TForm.Create(nil);
    with FForm do
    begin
        Font.Charset := GB2312_CHARSET;
        Font.Name := '宋体';
    end;
    //---
    FControl := FForm;
end;

function TFontDialog.GetText: string;
begin
    Result := FForm.Caption;
end;

procedure TFontDialog.SetText(const Value: string);
begin
    FForm.Caption := Value;
end;

constructor TLabel1.Create(ADirector: TDialogDirector);
begin
    inherited;
    //---
    FLabel := TLabel.Create(nil);
    FControl := FLabel;
end;

function TLabel1.GetFont: TFont;
begin
    Result := FLabel.Font;
end;

function TLabel1.GetText: string;
begin
    Result := FLabel.Caption;
end;

procedure TLabel1.SetText(const Value: string);
begin
    FLabel.Caption := Value;
end;

function TFontDialog.ShowModal: Integer;
begin
    Result := FForm.ShowModal;
end;

constructor TPanel1.Create(ADirector: TDialogDirector);
begin
    inherited;
    //---
    FPanel := TPanel.Create(nil);
    with FPanel do
    begin
        BevelOuter := bvNone;
        Caption := '';
    end;
    //---
    FControl := FPanel;
end;

constructor TRadioButton1.Create(ADirector: TDialogDirector);
begin
    inherited;
    //---
    FRadioButton := TRadioButton.Create(nil);
    FRadioButton.OnMouseDown := self.DoMouseDown;
    //---
    FControl := FRadioButton;
end;

function TRadioButton1.GetChecked: Boolean;
begin
    Result := FRadioButton.Checked;
end;

procedure TRadioButton1.HandleMouse(event: TMouseButton);
begin
    if event = mbLeft then
        Self.Changed();
end;

procedure TRadioButton1.SetChecked(const Value: Boolean);
begin
    FRadioButton.Checked := Value;
end;

procedure TRadioButton1.SetText(const Value: string);
begin
    FRadioButton.Caption := Value;
end;

constructor TSpinEdit1.Create(ADirector: TDialogDirector);
begin
    inherited;
    //---
    FSpinEdit := TSpinEdit.Create(nil);
    FSpinEdit.OnChange := self.DoChange;
    //---
    FControl := FSpinEdit;
end;

procedure TSpinEdit1.DoChange(Sender: TObject);
begin
    Self.Changed();
end;

function TSpinEdit1.GetValue: LongInt;
begin
    Result := FSpinEdit.Value;
end;

procedure TSpinEdit1.SetValue(const Value: LongInt);
begin
    FSpinEdit.Value := Value;
end;

constructor TCheckBox1.Create(ADirector: TDialogDirector);
begin
    inherited;
    //---
    FCheckBox := TCheckBox.Create(nil);
    FControl := FCheckBox;
end;

procedure TCheckBox1.SetText(const Value: string);
begin
    FCheckBox.Caption := Value;
end;

end.