Ignore:
Timestamp:
Dec 30, 2018, 1:01:14 AM (5 years ago)
Author:
chronos
Message:
  • Added: Close button to window title bar.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/overos/UWindow.pas

    r21 r22  
    1919    procedure DrawArea(Rect: TRectangle; Color: TColor); override;
    2020    procedure DrawText(P: TPosition; Color: TColor; Text: string); override;
     21    function GetTextSize(Text: string): TSize; override;
    2122  end;
    2223
    2324  TWindowSide = (wsNone, wsLeft, wsTop, wsRight, wsBottom);
    2425
    25   { TWindow }
    26 
    27   TWindow = class(TControl)
     26  { TTitleBar }
     27
     28  TTitleBar = class(TControl)
     29  private
     30    FWindow: TWindow;
     31    procedure SetWindow(AValue: TWindow);
     32    procedure ButtonCloseClick(Sender: TObject);
     33    procedure ButtonMaximizeClick(Sender: TObject);
     34    procedure ButtonMinimizeClick(Sender: TObject);
     35  protected
     36    procedure SetRectangle(AValue: TRectangle); override;
    2837  public
    2938  const
    3039    TitleHeight = 32;
     40  var
     41    ButtonClose: TButton;
     42    ButtonMaximize: TButton;
     43    ButtonMinimize: TButton;
     44    constructor Create; override;
     45    destructor Destroy; override;
     46    property Window: TWindow read FWindow write SetWindow;
     47  end;
     48
     49  TMessageWindowClose = class(TMessage);
     50
     51  { TWindow }
     52
     53  TWindow = class(TControl)
     54  private
     55    FScreen: TScreen;
     56    procedure SetScreen(AValue: TScreen);
     57  protected
     58    procedure SetRectangle(AValue: TRectangle); override;
     59    procedure SetVisible(AValue: Boolean); override;
     60  public
     61  const
    3162    BorderGrabWidth = 15;
    3263  var
     64    TitleBar: TTitleBar;
    3365    Title: string;
    34     Screen: TScreen;
     66    Application: TObject; // TApplication
     67    procedure MouseButtonDown(Pos: TPosition; Button: TMouseButton); override;
     68    procedure MouseButtonUp(Pos: TPosition; Button: TMouseButton); override;
     69    procedure Close;
    3570    procedure Focus;
    3671    procedure Paint; override;
     
    3873    constructor Create; override;
    3974    destructor Destroy; override;
     75    property Screen: TScreen read FScreen write SetScreen;
    4076  end;
    4177
     
    68104implementation
    69105
     106uses
     107  UApplication;
     108
     109{ TTitleBar }
     110
     111procedure TTitleBar.SetWindow(AValue: TWindow);
     112begin
     113  if FWindow = AValue then Exit;
     114  Canvas.Free;
     115  FWindow := AValue;
     116  Canvas := TCanvasWindow.Create;
     117  TCanvasWindow(Canvas).Window := FWindow;
     118end;
     119
     120procedure TTitleBar.ButtonCloseClick(Sender: TObject);
     121begin
     122  Window.Close;
     123end;
     124
     125procedure TTitleBar.ButtonMaximizeClick(Sender: TObject);
     126begin
     127  Rectangle := TRectangle.Create(TPosition.Create(0, 0), Window.Screen.Size);
     128  Paint;
     129end;
     130
     131procedure TTitleBar.ButtonMinimizeClick(Sender: TObject);
     132begin
     133
     134end;
     135
     136procedure TTitleBar.SetRectangle(AValue: TRectangle);
     137begin
     138  inherited;
     139  ButtonClose.Rectangle := TRectangle.Create(TPosition.Create(Size.Width - TitleHeight, 4),
     140    TSize.Create(TitleHeight - 8, TitleHeight - 8));
     141  ButtonMaximize.Rectangle := TRectangle.Create(TPosition.Create(Size.Width - 2 * TitleHeight, 4),
     142    TSize.Create(TitleHeight - 8, TitleHeight - 8));
     143  ButtonMinimize.Rectangle := TRectangle.Create(TPosition.Create(Size.Width - 3 * TitleHeight, 4),
     144    TSize.Create(TitleHeight - 8, TitleHeight - 8));
     145end;
     146
     147constructor TTitleBar.Create;
     148begin
     149  inherited;
     150
     151  ButtonClose := TButton.Create;
     152  ButtonClose.Title := 'X';
     153  ButtonClose.ParentControl := Self;
     154  ButtonClose.OnClick := ButtonCloseClick;
     155  ButtonClose.Visible := True;
     156
     157  ButtonMaximize := TButton.Create;
     158  ButtonMaximize.Title := '^';
     159  ButtonMaximize.ParentControl := Self;
     160  ButtonMaximize.OnClick := ButtonMaximizeClick;
     161  ButtonMaximize.Visible := True;
     162
     163  ButtonMinimize := TButton.Create;
     164  ButtonMinimize.Title := '_';
     165  ButtonMinimize.ParentControl := Self;
     166  ButtonMinimize.OnClick := ButtonMinimizeClick;
     167  ButtonMinimize.Visible := True;
     168end;
     169
     170destructor TTitleBar.Destroy;
     171begin
     172  ButtonClose.Free;
     173  ButtonMaximize.Free;
     174  ButtonMinimize.Free;
     175  inherited Destroy;
     176end;
     177
    70178{ TCanvasWindow }
    71179
    72180procedure TCanvasWindow.DrawLine(P1, P2: TPosition; Color: TColor);
    73181begin
    74   Window.Screen.Canvas.DrawLine(P1 + Window.Rectangle.Position, P2 + Window.Rectangle.Position, Color);
     182  if Assigned(Window) and Assigned(Window.Screen) then
     183    Window.Screen.Canvas.DrawLine(P1 + Window.Position, P2 + Window.Position, Color);
    75184end;
    76185
    77186procedure TCanvasWindow.DrawArea(Rect: TRectangle; Color: TColor);
    78187begin
    79   Window.Screen.Canvas.DrawArea(TRectangle.Create(Rect.Position + Window.Rectangle.Position,
    80     Rect.Size), Color);
     188  if Assigned(Window) and Assigned(Window.Screen) then
     189    Window.Screen.Canvas.DrawArea(TRectangle.Create(Rect.Position + Window.Position,
     190      Rect.Size), Color);
    81191end;
    82192
    83193procedure TCanvasWindow.DrawText(P: TPosition; Color: TColor; Text: string);
    84194begin
    85   Window.Screen.Canvas.DrawText(P + Window.Rectangle.Position, Color, Text);
     195  if Assigned(Window) and Assigned(Window.Screen) then
     196    Window.Screen.Canvas.DrawText(P + Window.Position, Color, Text);
     197end;
     198
     199function TCanvasWindow.GetTextSize(Text: string): TSize;
     200begin
     201  if Assigned(Window) and Assigned(Window.Screen) then
     202    Result := Window.Screen.Canvas.GetTextSize(Text);
    86203end;
    87204
    88205{ TWindow }
     206
     207procedure TWindow.SetScreen(AValue: TScreen);
     208begin
     209  if FScreen = AValue then Exit;
     210  if Assigned(FScreen) then
     211    FScreen.Windows.Remove(Self);
     212  FScreen := AValue;
     213  if Assigned(FScreen) then
     214    FScreen.Windows.Add(Self);
     215end;
     216
     217procedure TWindow.SetRectangle(AValue: TRectangle);
     218begin
     219  inherited;
     220  TitleBar.Rectangle := TRectangle.Create(Position, TSize.Create(Size.Width, TitleBar.TitleHeight));
     221end;
     222
     223procedure TWindow.SetVisible(AValue: Boolean);
     224begin
     225  inherited;
     226  if not Visible and Assigned(Screen) then
     227    Screen.Paint;
     228end;
     229
     230procedure TWindow.MouseButtonDown(Pos: TPosition; Button: TMouseButton);
     231begin
     232  inherited;
     233  TitleBar.MouseButtonDown(Pos, Button);
     234end;
     235
     236procedure TWindow.MouseButtonUp(Pos: TPosition; Button: TMouseButton);
     237begin
     238  inherited;
     239  TitleBar.MouseButtonUp(Pos, Button);
     240end;
     241
     242procedure TWindow.Close;
     243begin
     244  TApplication(Application).MessageQueue.PostMessage(Self, TMessageWindowClose.Create);
     245end;
    89246
    90247procedure TWindow.Focus;
     
    98255procedure TWindow.Paint;
    99256begin
    100   Canvas.DrawArea(TRectangle.Create(TPosition.Create(0, 0), Rectangle.Size), clGray);
    101   Canvas.DrawFrame(TRectangle.Create(TPosition.Create(0, 0), Rectangle.Size), clWhite);
    102   Canvas.DrawLine(TPosition.Create(0, TitleHeight),
    103     TPosition.Create(Rectangle.Size.Width, TitleHeight), clWhite);
    104   Canvas.DrawText(TPosition.Create(8, 4), clWhite, Title);
     257  if Visible then begin
     258    Canvas.DrawArea(TRectangle.Create(TPosition.Create(0, 0), Size), clGray);
     259    Canvas.DrawFrame(TRectangle.Create(TPosition.Create(0, 0), Size), clWhite);
     260    Canvas.DrawLine(TPosition.Create(0, TitleBar.TitleHeight),
     261      TPosition.Create(Size.Width, TitleBar.TitleHeight), clWhite);
     262    Canvas.DrawText(TPosition.Create(8, 4), clWhite, Title);
     263    TitleBar.Paint;
     264  end;
    105265  inherited;
    106266end;
     
    117277  Canvas := TCanvasWindow.Create;
    118278  TCanvasWindow(Canvas).Window := Self;
     279  TitleBar := TTitleBar.Create;
     280  TitleBar.Window := Self;
     281  TitleBar.Visible := True;
    119282end;
    120283
    121284destructor TWindow.Destroy;
    122285begin
     286  Visible := False;
     287  TitleBar.Free;
     288  Screen := nil;
    123289  inherited Destroy;
    124290end;
     
    133299  for I := Windows.Count - 1 downto 0 do begin
    134300    Window := Windows[I];
    135     if TRectangle.Create(Window.Rectangle.Position - TPosition.Create(Window.BorderGrabWidth div 2, 0),
    136     TSize.Create(Window.BorderGrabWidth, Window.Rectangle.Size.Height)).Contains(Pos) then begin
     301    if TRectangle.Create(Window.Position - TPosition.Create(Window.BorderGrabWidth div 2, 0),
     302    TSize.Create(Window.BorderGrabWidth, Window.Size.Height)).Contains(Pos) then begin
    137303      GrabMousePosition := Pos;
    138304      GrabWindowRectangle := Window.Rectangle;
     
    141307      GrabActive := True;
    142308    end else
    143     if TRectangle.Create(Window.Rectangle.Position - TPosition.Create(0, Window.BorderGrabWidth div 2),
    144     TSize.Create(Window.Rectangle.Size.Width, Window.BorderGrabWidth)).Contains(Pos) then begin
     309    if TRectangle.Create(Window.Position - TPosition.Create(0, Window.BorderGrabWidth div 2),
     310    TSize.Create(Window.Size.Width, Window.BorderGrabWidth)).Contains(Pos) then begin
    145311      GrabMousePosition := Pos;
    146312      GrabWindowRectangle := Window.Rectangle;
     
    149315      GrabActive := True;
    150316    end else
    151     if TRectangle.Create(Window.Rectangle.Position + TPosition.Create(Window.Rectangle.Size.Width, 0) - TPosition.Create(Window.BorderGrabWidth div 2, 0),
    152     TSize.Create(Window.BorderGrabWidth, Window.Rectangle.Size.Height)).Contains(Pos) then begin
     317    if TRectangle.Create(Window.Position + TPosition.Create(Window.Size.Width, 0) - TPosition.Create(Window.BorderGrabWidth div 2, 0),
     318    TSize.Create(Window.BorderGrabWidth, Window.Size.Height)).Contains(Pos) then begin
    153319      GrabMousePosition := Pos;
    154320      GrabWindowRectangle := Window.Rectangle;
     
    157323      GrabActive := True;
    158324    end else
    159     if TRectangle.Create(Window.Rectangle.Position + TPosition.Create(0, Window.Rectangle.Size.Height) - TPosition.Create(0, Window.BorderGrabWidth div 2),
    160     TSize.Create(Window.Rectangle.Size.Width, Window.BorderGrabWidth)).Contains(Pos) then begin
     325    if TRectangle.Create(Window.Position + TPosition.Create(0, Window.Size.Height) - TPosition.Create(0, Window.BorderGrabWidth div 2),
     326    TSize.Create(Window.Size.Width, Window.BorderGrabWidth)).Contains(Pos) then begin
    161327      GrabMousePosition := Pos;
    162328      GrabWindowRectangle := Window.Rectangle;
     
    165331      GrabActive := True;
    166332    end else
    167     if TRectangle.Create(Window.Rectangle.Position, TSize.Create(Window.Rectangle.Size.Width, Window.TitleHeight)).Contains(Pos) then begin
     333    if TRectangle.Create(Window.Position, TSize.Create(Window.Size.Width, Window.TitleBar.TitleHeight)).Contains(Pos) then begin
    168334      GrabMousePosition := Pos;
    169335      GrabWindowRectangle := Window.Rectangle;
     
    174340    if Window.Rectangle.Contains(Pos) then begin
    175341      Window.Focus;
    176       Window.MouseButtonDown(Pos - Window.Rectangle.Position, Button);
     342      Window.MouseButtonDown(Pos - Window.Position, Button);
    177343      Break;
    178344    end;
     
    192358    Window := Windows[I];
    193359    if Window.Rectangle.Contains(Pos) then begin
    194       Window.MouseButtonUp(Pos - Window.Rectangle.Position, Button);
     360      Window.MouseButtonUp(Pos - Window.Position, Button);
    195361      Break;
    196362    end;
     
    204370  if GrabActive then begin
    205371    if GrabWindowSide = wsNone then
    206       GrabWindow.Rectangle.Position := GrabWindowRectangle.Position + (Pos - GrabMousePosition)
     372      GrabWindow.Position := GrabWindowRectangle.Position + (Pos - GrabMousePosition)
    207373    else if GrabWindowSide = wsLeft then
    208374      GrabWindow.Rectangle := TRectangle.Create(GrabWindowRectangle.Position + TPosition.Create(Pos.Left - GrabMousePosition.Left, 0),
     
    221387  for I := Windows.Count - 1 downto 0 do begin
    222388    if Windows[I].Rectangle.Contains(Pos) then begin
    223       Windows[I].MouseMove(Pos - Windows[I].Rectangle.Position);
     389      Windows[I].MouseMove(Pos - Windows[I].Position);
    224390      Break;
    225391    end;
     
    255421begin
    256422  Result := TWindow.Create;
    257   Windows.Add(Result);
    258423  Result.Screen := Self;
    259424  Result.Title := Title;
     
    265430begin
    266431  Windows := TFPGObjectList<TWindow>.Create;
     432  Windows.FreeObjects := False;
    267433  Canvas := TCanvas.Create;
    268434end;
    269435
    270436destructor TScreen.Destroy;
    271 begin
     437var
     438  I: Integer;
     439begin
     440  for I := 0 to Windows.Count - 1 do
     441    Windows[I].Free;
    272442  Windows.Free;
    273443  Canvas.Free;
Note: See TracChangeset for help on using the changeset viewer.