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

  Blend ScrollBar
  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 EpIIScrollBars;

{$I EpIIVer.inc}
{$T-,W-,X+,P+}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, KsUtils, KsBitmap, KsControls, KsScrollBars, EpIIStyles, EpIIVersion;

type

{ TEpScrollBar class }

  TEpScrollBar = class(TKsCustomScrollBar)
  private
    FBackground: TEpBackground;
    FBorder: TepBorder;
    FButtonBackground: TEpBackground;
    FButtonBorder: TepBorder;
    FShowGlyph: boolean;
    FGlyphColor: TColor;
    FButtonWidth: integer;
    procedure DoChange(Sender: TObject);
    procedure DrawFrameControl(R: TRect; Flags: integer);

    function GetVersion: TEpVersion;
    procedure SetVersion(const Value: TEpVersion);
    procedure SetBackground(const Value: TEpBackground);
    procedure SetBorder(const Value: TepBorder);
    procedure SetButtonBackground(const Value: TEpBackground);
    procedure SetButtonBorder(const Value: TepBorder);
    procedure SetShowGlyph(const Value: boolean);
    procedure SetGlyphColor(const Value: TColor);
    procedure SetButtonWidth(const Value: integer); { Convert colors after DrawControlFrame }
  protected
    { Overrides }
    procedure PaintBackground; 
    { ScrollBar }
    function GetBtnSize: integer; override;
    procedure DrawLeftTopBtn; override;
    procedure DrawRightBottomBtn; override;
    procedure DrawSlider; override;
    procedure DrawBackground; override;
    procedure DrawBorder; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { It's possible to draw the background for control. Based on TEpBackground class.
      See Also:
        TEpBackground
    }
    property Background: TEpBackground read FBackground write SetBackground;
    property Blend;
    property BlendValue;
    { It's possible to draw the border for control. Based on TEpBorder class.
      See Also:
        TEpBorder
    }
    property Border: TepBorder read FBorder write SetBorder;
    { It's possible to draw the button background. Based on TEpBackground class.
      See Also:
        TEpBackground
    }
    property ButtonBackground: TEpBackground read FButtonBackground write SetButtonBackground;
    { It's possible to draw the button border. Based on TEpBorder class.
      See Also:
        TEpBorder
    }
    property ButtonBorder: TepBorder read FButtonBorder write SetButtonBorder;
    { Specifies the button width. }
    property ButtonWidth: integer read FButtonWidth write SetButtonWidth;
    { Specifies the glyph color. }
    property GlyphColor: TColor read FGlyphColor write SetGlyphColor;
    property ShowButtons;
    property Kind;
    property LargeChange;
    property Max;
    property Min;
    property PageSize;
    property Position;
    { It's possible to draw the glyph on scrollbar button's. }
    property ShowGlyph: boolean read FShowGlyph write SetShowGlyph;
    property SmallChange;
    property Version: TEpVersion read GetVersion write SetVersion
      stored false;
    property OnChange;
    property OnScroll;
  end;

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

{ TEpScrollBar }

constructor TEpScrollBar.Create;
begin
  inherited Create(AOwner);
  FButtonWidth := 20;
  FShowGlyph := true;
  
  FBackground := TEpBackground.Create;
  FBackground.OnChange := DoChange;
  FBorder := TEpBorder.Create;
  FBorder.OnChange := DoChange;

  FButtonBackground := TEpBackground.Create;
  FButtonBackground.OnChange := DoChange;
  FButtonBorder := TEpBorder.Create;
  FButtonBorder.OnChange := DoChange;
end;

destructor TEpScrollBar.Destroy;
begin
  FButtonBackground.Free;
  FButtonBorder.Free;
  FBackground.Free;
  FBorder.Free;
  inherited Destroy;
end;

{ Drawing }

procedure TEpScrollBar.DrawFrameControl(R: TRect; Flags: integer);
var
  C: TKColorRec;
  i, j: integer;
  B: TKsBitmap;
begin
  B := TKsBitmap.Create;
  try
    B.SetSize(RectWidth(R), RectHeight(R));
    { Draw to B }
    Windows.DrawFrameControl(B.DC, Rect(0, 0, B.Width, B.Height), DFC_SCROLL, Flags);
    { Copy to Buffer }
    for i := 2 to B.Width - 3 do
      for j := 2 to B.Height - 3 do
      begin
        C := TKColorRec(B.Pixels[i, j]);
        if (C.R = 0) and (C.G = 0) and (C.B = 0) then
          Buffer.Pixels[R.Left + i, R.Top + j] := KColor(FGlyphColor);
      end;
  finally
    B.Free;
  end;
end;

function TEpScrollBar.GetBtnSize: integer;
begin
  Result := FButtonWidth;
end;

procedure TEpScrollBar.DrawBackground;
begin
  if FBorder = nil then Exit;

  FBackground.Draw(Buffer, GetBackgroundRect);
end;

procedure TEpScrollBar.DrawBorder;
begin
  if FBorder = nil then Exit;
  
  FBorder.Draw(Buffer, Rect(0, 0, Width, Height), 0);
end;

procedure TEpScrollBar.DrawLeftTopBtn;
var
  TmpRect: TRect;
  Flags : UINT;
begin
  if FButtonBorder = nil then Exit;

  if Kind = sbHorizontal then
    Flags := DFCS_SCROLLLEFT
  else
    Flags := DFCS_SCROLLUP;

  if LeftTopBtnPressed then
    Flags := Flags or DFCS_PUSHED or DFCS_FLAT;

  if (Enabled = false) and not (csDesigning in ComponentState) then
    Flags := Flags or DFCS_INACTIVE;

  TmpRect := GetLeftTopBtnRect;
  FButtonBackground.Draw(Buffer, TmpRect);
  FButtonBorder.Draw(Buffer, TmpRect, 0);
  { Draw Glyph }
  if FShowGlyph then
    DrawFrameControl(TmpRect, Flags);
end;

procedure TEpScrollBar.DrawRightBottomBtn;
var
  TmpRect: TRect;
  Flags : UINT;
begin
  if FButtonBorder = nil then Exit;

  if Kind = sbHorizontal then
    Flags := DFCS_SCROLLRIGHT
  else
    Flags := DFCS_SCROLLDOWN;

  if RightBottomBtnPressed then
    Flags := Flags or DFCS_PUSHED or DFCS_FLAT;

  if (Enabled = false) and not (csDesigning in ComponentState) then
    Flags := Flags or DFCS_INACTIVE;

  TmpRect := GetRightBottomBtnRect;
  FButtonBackground.Draw(Buffer, TmpRect);
  FButtonBorder.Draw(Buffer, TmpRect, 0);
  { Draw Glyph }
  if FShowGlyph then
    DrawFrameControl(TmpRect, Flags);
end;

procedure TEpScrollBar.DrawSlider;
begin
  if FButtonBorder = nil then Exit;

  FButtonBackground.Draw(Buffer, GetSliderRect);
  FButtonBorder.Draw(Buffer, GetSliderRect, 0);
end;

procedure TEpScrollBar.PaintBackground;
begin
  inherited;

  DrawBorder;
  DrawBackground;

  if ShowButtons then
  begin
    DrawLeftTopBtn;
    DrawRightBottomBtn;
  end;

  if IsSliderVizible then
  begin
    DrawSlider;

    if LeftTopAreaPressed then
      Buffer.FillRect(GetLeftTopAreaRect, ckBlack);

    if RightBottomAreaPressed then
      Buffer.FillRect(GetRightBottomAreaRect, ckBlack);
  end;
end;

procedure TEpScrollBar.DoChange(Sender: TObject);
begin
  Invalidate;
end;

{ Properties }

function TEpScrollBar.GetVersion: TEpVersion;
begin
  Result := EpVersion;
end;

procedure TEpScrollBar.SetVersion(const Value: TEpVersion);
begin
end;

procedure TEpScrollBar.SetBackground(const Value: TEpBackground);
begin
  FBackground.Assign(Value);
end;

procedure TEpScrollBar.SetBorder(const Value: TepBorder);
begin
  FBorder.Assign(Value);
  BorderWidth := FBorder.Width;
end;

procedure TEpScrollBar.SetButtonBackground(const Value: TEpBackground);
begin
  FButtonBackground.Assign(Value);
end;

procedure TEpScrollBar.SetButtonBorder(const Value: TepBorder);
begin
  FButtonBorder.Assign(Value);
end;

procedure TEpScrollBar.SetShowGlyph(const Value: boolean);
begin
  if FShowGlyph <> Value then
  begin
    FShowGlyph := Value;
    Invalidate;
  end;
end;

procedure TEpScrollBar.SetGlyphColor(const Value: TColor);
begin
  if FGlyphColor <> Value then
  begin
    FGlyphColor := Value;
    Invalidate;
  end;
end;

procedure TEpScrollBar.SetButtonWidth(const Value: integer);
begin
  if FButtonWidth <> Value then
  begin
    FButtonWidth := Value;
    Invalidate;
  end;
end;

end.

