{==============================================================================

  Custom GroupBox
  Copyright (C) 2000-2001 by Evgeny Kryukov
  All rights reserved

  All contents of this file and all other files included in this archive
  are Copyright (C) 2001 Evgeny Kryukov. Use and/or distribution of
  them requires acceptance of the License Agreement.

  See License.txt for licence information

===============================================================================}

unit KsGroupBoxs;

{$I KsCommonVer.Inc}
{$T-,W-,X+,P+}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  KsUtils, KsBitmap, KsControls, KsCheckBoxs;

type

{ TKsCustomGroupBox class }

{ The TKsCustomGroupBox component represents a advanced Windows group box, used to group related controls on a form. When another control component is placed within a group box, the group box becomes the parent of that component. }
  TKsCustomGroupBox = class(TKsCustomControl)
  private
    FCaptionMargin: integer;
    procedure SetCaptionMargin(const Value: integer);
  protected
    procedure CMTextChanged(var Msg: TMessage); message CM_TEXTCHANGED;
    
    function GetBoxRect: TRect; virtual;
    procedure PaintBuffer; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Loaded; override;
  published
    property Anchors;
    property Align;
    property Blend;
    property BlendValue;
    property Caption;
    { Left margin to caption text }
    property CaptionMargin: integer read FCaptionMargin write SetCaptionMargin;
    property Font;
    property TabStop;
    property TabOrder;
    property Transparent;
  end;

implementation {===============================================================}

{ TKsCustomGroupBox }

constructor TKsCustomGroupBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCaptionMargin := 12;
  Transparent := false;

  ControlStyle := ControlStyle + [csAcceptsControls, csOpaque];
  Color := clBtnFace;
  SetBounds(0, 0, 100, 90);
end;

destructor TKsCustomGroupBox.Destroy;
begin
  inherited Destroy;
end;

procedure TKsCustomGroupBox.Loaded;
begin
  inherited;
  Invalidate;
end;

procedure TKsCustomGroupBox.CMTextChanged(var Msg: TMessage);
begin
  inherited ;
  Invalidate;
end;

{ Drawing }

function TKsCustomGroupBox.GetBoxRect: TRect;
begin
  with Buffer do
  begin
    Font.Assign(Self.Font);

    Result := Rect(3, TextHeight(Caption) div 2 + 1, FWidth - 2, FHeight - 2);
  end;
end;

procedure TKsCustomGroupBox.PaintBuffer;
var
  R, CaptionRect: TRect;
begin
  inherited ;
  
  with Buffer do
  begin
    Font.Assign(Self.Font);

    R := GetBoxRect;
    CaptionRect := Rect(FCaptionMargin, 0, FCaptionMargin + TextWidth(Caption), TextHeight(Caption));

    if not (Caption = '') then
      InflateRect(CaptionRect, 3, 0);

    { Draw Frame }
    MoveTo(R.Left, R.Top);
    LineTo(CaptionRect.Left, R.Top, KColor(clBtnHighlight));
    MoveTo(CaptionRect.Right, R.Top);
    LineTo(R.Right, R.Top, KColor(clBtnHighlight));
    LineTo(R.Right, R.Bottom, KColor(clBtnHighlight));
    LineTo(R.Left, R.Bottom, KColor(clBtnHighlight));
    LineTo(R.Left, R.Top, KColor(clBtnHighlight));

    OffsetRect(R, -1, -1);

    MoveTo(R.Left, R.Top);
    LineTo(CaptionRect.Left, R.Top, KColor(clBtnShadow));
    MoveTo(CaptionRect.Right, R.Top);
    LineTo(R.Right, R.Top, KColor(clBtnShadow));
    LineTo(R.Right, R.Bottom, KColor(clBtnShadow));
    LineTo(R.Left, R.Bottom, KColor(clBtnShadow));
    LineTo(R.Left, R.Top, KColor(clBtnShadow));

    { Draw Caption }
    DrawText(Caption, CaptionRect, DT_CENTER or DT_VCENTER or DT_SINGLELINE);
  end;
end;

procedure TKsCustomGroupBox.SetCaptionMargin(const Value: integer);
begin
  if FCaptionMargin <> Value then
  begin
    FCaptionMargin := Value;
    Invalidate;
  end;
end;

end.
