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

  Blend RangeBar
  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 EpIIRangeBars;

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

interface

uses
  Classes, Controls, Windows, Graphics, Messages, KsBitmap, KsUtils, KsControls,
  KsTrackBars, KsRangeBars, EpIIStyles, EpIIVersion;

type

  TEpRangeBar = class(TKsCustomRangeBar)
  private
    FTickColor: TColor;
    FHighlightBackground: TEpBackground;
    FThumbBackground: TEpBackground;
    FBackground: TEpBackground;
    FBorder: TepBorder;
    FHighlightBorder: TepBorder;
    FThumbBorder: TepBorder;
    procedure DoChange(Sender: TObject);
    
    function GetVersion: TEpVersion;
    procedure SetVersion(const Value: TEpVersion);
    procedure SetBackground(const Value: TEpBackground);
    procedure SetBorder(const Value: TepBorder);
    procedure SetHighlightBackground(const Value: TEpBackground);
    procedure SetHighlightBorder(const Value: TepBorder);
    procedure SetThumbBackground(const Value: TEpBackground);
    procedure SetThumbBorder(const Value: TepBorder);
    procedure SetTickColor(const Value: TColor);
  protected
    { RangeBar }
    procedure DrawLowThumb(APosCoord: integer); override;
    procedure DrawHighThumb(APosCoord: integer); override;
    procedure DrawTrack(BegCoord, EndCoord, LowPosCoord, HighPosCoord: integer); override;
    procedure DrawTick(Value, Coord: integer; TopLeft: boolean); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Loaded; 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;
    { It's possible to draw the border for control. Based on TEpBorder class.
      See Also:
        TEpBorder
    }
    property Border: TepBorder read FBorder write SetBorder;
    property Blend;
    property BlendValue;
    property LineSize;
    property Max;
    property Min;
    property Orientation;
    property PageSize;
    property LowPosition;
    property HighPosition;
    property Frequency;
    { It's possible to draw the highlight background for control. Based on TEpBackground class.
      See Also:
        TEpBackground
    }
    property HighlightBackground: TEpBackground read FHighlightBackground write SetHighlightBackground;
    { It's possible to draw the highlgiht border for control. Based on TEpBorder class.
      See Also:
        TEpBorder
    }
    property HighlightBorder: TepBorder read FHighlightBorder write SetHighlightBorder;
    property HighlightInterval;
    property HighThumbVisible;
    property LowThumbVisible;
    { It's possible to draw the slider backgound. Based on TEpBackground class.
      See Also:
        TEpBackground
    }
    property ThumbBackground: TEpBackground read FThumbBackground write SetThumbBackground;
    { It's possible to draw the slider border. Based on TEpBorder class.
      See Also:
        TEpBorder
    }
    property ThumbBorder: TepBorder read FThumbBorder write SetThumbBorder;
    property ThumbWidth;
    { Specifies the tick color. }
    property TickColor: TColor read FTickColor write SetTickColor;
    property TickMarks;
    property ShowTicks;
    property Version: TEpVersion read GetVersion write SetVersion
      stored false;
    property OnLowChange;
    property OnHighChange;
  end;

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

uses Extctrls, Dialogs;

{ TEpRangeBar }

constructor TEpRangeBar.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FBackground := TEpBackground.Create;
  FBackground.OnChange := DoChange;
  FBorder := TEpBorder.Create;
  FBorder.OnChange := DoChange;

  FThumbBackground := TEpBackground.Create;
  FThumbBackground.OnChange := DoChange;
  FThumbBorder := TEpBorder.Create;
  FThumbBorder.OnChange := DoChange;

  FHighlightBackground := TEpBackground.Create;
  FHighlightBackground.OnChange := DoChange;
  FHighlightBorder := TEpBorder.Create;
  FHighlightBorder.OnChange := DoChange;
end;

destructor TEpRangeBar.Destroy;
begin
  FHighlightBackground.Free;
  FHighlightBorder.Free;
  FThumbBackground.Free;
  FThumbBorder.Free;
  FBackground.Free;
  FBorder.Free;
  inherited Destroy;
end;

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

procedure TEpRangeBar.DrawTrack(BegCoord, EndCoord, LowPosCoord,
  HighPosCoord: integer);
var
  R: TRect;
  LTrackRect, IntervalRect: TRect;
  LTopBottmMarign, LThumbWidth, LThumbHeight: integer;
begin
  if FBorder = nil then Exit;

  LThumbWidth := GetThumbWidth;

  LTopBottmMarign := GetTopBottomMargin;
  LThumbHeight := Round(LThumbWidth * CStdRngThumbRatio);

  with LTrackRect do
  begin
    if Orientation = toHorizontal then
    begin
      Top := LTopBottmMarign;
      if TickMarks = tmTopLeft then
        Top := Top + LThumbWidth div 2
      else
        Top := Top + LThumbWidth div 4;

      if ShowTicks and ((TickMarks = tmTopLeft) or (TickMarks = tmBoth)) then
        Top := Top + 4 + 1;

      if TickMarks = tmBoth then
        Bottom := Top + LThumbHeight - (LThumbWidth div 4) * 2
      else
        Bottom := Top + LThumbHeight - LThumbWidth div 2 - LThumbWidth div 4;

      Left := BegCoord;
      Right := EndCoord;

      IntervalRect.Top := Top;
      IntervalRect.Bottom := Bottom;
      IntervalRect.Left := LowPosCoord;
      IntervalRect.Right := HighPosCoord;
    end
    else
    begin
      Left := LTopBottmMarign;
      if TickMarks = tmTopLeft then
        Left := Left + LThumbWidth div 2
      else
        Left := Left + LThumbWidth div 4;

      if ShowTicks and ((TickMarks = tmTopLeft) or (TickMarks = tmBoth)) then
        Left := Left + 4 + 1;

      if TickMarks = tmBoth then
        Right := Left + LThumbHeight - (LThumbWidth div 4) * 2
      else
        Right := Left + LThumbHeight - LThumbWidth div 2 - LThumbWidth div 4;

      Top := BegCoord;
      Bottom := EndCoord;

      IntervalRect.Top := LowPosCoord;
      IntervalRect.Bottom := HighPosCoord;
      IntervalRect.Left := Left;
      IntervalRect.Right := Right;
    end;
  end;

  { Draw Background }
  R := Rect(0, 0, FWidth, FHeight);
  FBackground.Draw(Buffer, R);
  FBorder.Draw(Buffer, R, 0);

  { Draw highlight }
  if Enabled and (HighlightInterval) then
  begin
    FHighlightBackground.Draw(Buffer, IntervalRect);
    FHighlightBorder.Draw(Buffer, IntervalRect, 0);
  end;
end;

procedure TEpRangeBar.DrawHighThumb(APosCoord: integer);
var
  Bx, By: integer;
  LThumbWidth, LThumbHeight: integer;
  R: TRect;
begin
  if FThumbBorder = nil then Exit;
  if not HighThumbVisible then Exit;

  LThumbWidth := GetThumbWidth;
  LThumbHeight := Round(LThumbWidth * CStdRngThumbRatio);
  with Buffer do
    if Orientation = toHorizontal then
    begin
      Bx := APosCoord;
      By := GetTopBottomMargin;
      if ShowTicks and ((TickMarks = tmTopLeft) or (TickMarks = tmBoth)) then
        By := By + 4 + 1;

      R := Rect(Bx, By, Bx + LThumbWidth, By + LThumbHeight);
    end
    else
    begin
      { Orientation = toVertical }

      Bx := GetTopBottomMargin;
      By := APosCoord;
      if ShowTicks and ((TickMarks = tmTopLeft) or (TickMarks = tmBoth)) then
        Bx := Bx + 4 + 1;

      R := Rect(Bx, By, Bx + LThumbHeight, By + LThumbWidth);
    end;

  { Draw }
  FThumbBackground.Draw(Buffer, R);
  FThumbBorder.Draw(Buffer, R, 0);
end;

procedure TEpRangeBar.DrawLowThumb(APosCoord: integer);
var
  Bx, By: integer;
  LThumbWidth, LThumbHeight: integer;
  R: TRect;
begin
  if FThumbBorder = nil then Exit;
  if not LowThumbVisible then Exit;

  LThumbWidth := GetThumbWidth;
  LThumbHeight := Round(LThumbWidth * CStdRngThumbRatio);
  with Buffer do
    if Orientation = toHorizontal then
    begin
      Bx := APosCoord - LThumbWidth + 1;
      By := GetTopBottomMargin;
      if ShowTicks and ((TickMarks = tmTopLeft) or (TickMarks = tmBoth)) then
        By := By + 4 + 1;

      R := Rect(Bx, By, Bx + LThumbWidth, By + LThumbHeight);
    end
    else
    begin
      { Orientation = toVertical }
      Bx := GetTopBottomMargin;
      By := APosCoord - LThumbWidth + 1;
      if ShowTicks and ((TickMarks = tmTopLeft) or (TickMarks = tmBoth)) then
        Bx := Bx + 4 + 1;

      R := Rect(Bx, By, Bx + LThumbHeight, By + LThumbWidth);
    end;

  { Draw }
  FThumbBackground.Draw(Buffer, R);
  FThumbBorder.Draw(Buffer, R, 0);
end;

procedure TEpRangeBar.DrawTick(Value, Coord: integer; TopLeft: boolean);
var
  VCoord: integer;
  LThumbHeight: integer;
begin
  LThumbHeight := Round(GetThumbWidth * CStdThumbRatio);
  if TopLeft then
  begin
    VCoord := GetTopBottomMargin + 3;
    with Buffer do
    begin
      if Orientation = toHorizontal then
      begin
        MoveTo(Coord, VCoord);
        if (Value = Min) or (Value = Max) then
          LineTo(Coord, VCoord - 4, KColor(FTickColor))
        else
          LineTo(Coord, VCoord - 3, KColor(FTickColor));
      end
      else
      begin
        MoveTo(VCoord, Coord);
        if (Value = Min) or (Value = Max) then
          LineTo(VCoord - 4, Coord, KColor(FTickColor))
        else
          LineTo(VCoord - 3, Coord, KColor(FTickColor));
      end;
    end
  end
  else
  begin
    if TickMarks = tmBoth then
      VCoord := GetTopBottomMargin + 4 + 1 +
        LThumbHeight + 1
    else
      VCoord := GetTopBottomMargin + 1 +
        LThumbHeight + 1;
    with Buffer do
    begin
      if Orientation = toHorizontal then
      begin
        MoveTo(Coord, VCoord);
        if (Value = Min) or (Value = Max) then
          LineTo(Coord, VCoord + 4, KColor(FTickColor))
        else
          LineTo(Coord, VCoord + 3, KColor(FTickColor));
      end
      else
      begin
        MoveTo(VCoord, Coord);
        if (Value = Min) or (Value = Max) then
          LineTo(VCoord + 4, Coord, KColor(FTickColor))
        else
          LineTo(VCoord + 3, Coord, KColor(FTickColor));
      end;
    end;
  end;
end;

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

{ Properties }

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

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

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

procedure TEpRangeBar.SetBorder(const Value: TepBorder);
begin
  FBorder.Assign(Value);
end;

procedure TEpRangeBar.SetHighlightBackground(const Value: TEpBackground);
begin
  FHighlightBackground.Assign(Value);
end;

procedure TEpRangeBar.SetHighlightBorder(const Value: TepBorder);
begin
  FHighlightBorder.Assign(Value);
end;

procedure TEpRangeBar.SetThumbBackground(const Value: TEpBackground);
begin
  FThumbBackground.Assign(Value);
end;

procedure TEpRangeBar.SetThumbBorder(const Value: TepBorder);
begin
  FThumbBorder.Assign(Value);
end;

procedure TEpRangeBar.SetTickColor(const Value: TColor);
begin
  if FTickColor <> Value then
  begin
    FTickColor := Value;
    Invalidate;
  end;
end;

end.

