{ ------------------------------------------------------------- }
{ Purpose : Next Collection 6                                   }
{ By      : Bojan Nikolic                                       }
{ For     : BergSoft                                            }
{ ------------------------------------------------------------- }
{ Copyright (C) BergSoft.net 2013. All Rights Reserved.         }
{ ------------------------------------------------------------- }
{$I '..\NxSuite6.inc'}
unit NxNotebook6;

interface

uses
  { Standard }
  Classes, Types, Windows, Graphics, Controls, Messages, ImgList,
  {$IFDEF UI_TYPES}UITypes,{$ENDIF}
  { Next Standard 6 }
  NxConsts6, NxTypes6, NxIntf6, NxClasses6,
  { Next Collection 6 }
  NxCollection6;

const
  szDesignButtonsHeight = 24;

type
  TNxCustomNotebook6 = class;

  { TNxNotebookSheet6 }

  TNxNotebookSheet6 = class(TNxCollectionControl6)
  private
    FPageVisible: Boolean;
    function GetIndex: Integer;
    procedure SetIndex(const Value: Integer);
    procedure SetPageVisible(const Value: Boolean);
    function GetNotebook: TNxCustomNotebook6;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
    property Notebook: TNxCustomNotebook6 read GetNotebook;
  published
    property Align;
    property Color;
    property Ctl3D;
    property DragCursor;
    property DragKind;
    property DragMode;
    property Enabled;
    property Font;
    property Hint;
    property Index: Integer read GetIndex write SetIndex default 0;
    property Padding;
    property PageVisible: Boolean read FPageVisible write SetPageVisible default True;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property TabOrder;
    property TabStop;
  end;

  { TNxCustomNotebook6 }

  TNxSheetClass = class of TNxNotebookSheet6;

  TNxActiveChangeEvent = procedure (Sender: TObject; Sheet: TNxNotebookSheet6) of object;
  TNxActiveChangeQueryEvent = procedure (Sender: TObject; Sheet: TNxNotebookSheet6;
    var Accept: Boolean) of object;

  TNxCustomNotebook6 = class(TNxCollectionControl6)
  private
    FActivePage: TNxNotebookSheet6;
    FOnActiveChange: TNxActiveChangeEvent;
    FOnActiveChangeQuery: TNxActiveChangeQueryEvent;
    FPrevSize: TSize;
    { Property Accessors }
    function GetActivePageIndex: Integer;
    function GetCount: Integer;
    procedure SetActivePage(const Value: TNxNotebookSheet6);
    procedure SetActivePageIndex(const Value: Integer);
  protected
    procedure PageActiveChange(Sheet: TNxNotebookSheet6); virtual;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure DoActiveChange(Sheet: TNxNotebookSheet6); dynamic;
    procedure DoActiveChangeQuery(Sender: TObject; Sheet: TNxNotebookSheet6;
      var Accept: Boolean); dynamic;
    procedure DoPageAdded(Sheet: TNxNotebookSheet6); virtual;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
    { Methods }
    procedure Paint; override;
    procedure SetPageIndex(Page: TControl; const Value: Integer);
    { Windows Messages }
  public
    constructor Create(AOwner: TComponent); override;
    { Methods }
    function Add(Active: Boolean = False): TNxNotebookSheet6; overload;
    procedure Add(Sheet: TNxNotebookSheet6; Active: Boolean = False); overload;
    function GetTabSheetClass: TNxSheetClass; virtual;
    { Properties }
    property Count: Integer read GetCount;
  published
    { Properties }
    property ActivePage: TNxNotebookSheet6 read FActivePage write SetActivePage;
    property ActivePageIndex: Integer read GetActivePageIndex
      write SetActivePageIndex default 0;
    property Align;
    property Anchors;
    property Color;
    property Constraints;
    property Ctl3D;
    property DragCursor;
    property DragKind;
    property DragMode;
    property Enabled;
    property Font;
    property Hint;
    property Padding;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;

    property OnActiveChange: TNxActiveChangeEvent read FOnActiveChange write FOnActiveChange;
    property OnActiveChangeQuery: TNxActiveChangeQueryEvent read FOnActiveChangeQuery write FOnActiveChangeQuery;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseWheelDown;
    property OnMouseWheelUp;
    property OnMouseUp;
    property OnResize;
    property OnStartDrag;
  end;

  { TNxNotebook6 }

  TNxArrow = (arNone, arLeft, arRight);

  TNxNotebook6 = class(TNxCustomNotebook6)
  private
    FDesignButtons: Boolean;
    FHotArrow: TNxArrow;
    FHotButton: TNxNotebookSheet6;
    FLeftArrowState: TNxButtonState;
    FPosition: Integer;
    FPressedArrow: TNxArrow;
    FPressedButton: TNxNotebookSheet6;
    FTextMetrics: TTextMetric;
    { Property Accessors }
    function GetButtonHeight: Integer;
    function GetButtonsClientRect: TRect;
    function GetButtonsRect: TRect;
    function GetSheet(Index: Integer): TNxNotebookSheet6;
    procedure SetDesignButtons(const Value: Boolean);
    procedure SetHotArrow(const Value: TNxArrow);
    procedure SetHotButton(const Value: TNxNotebookSheet6);
    procedure SetPressedArrow(const Value: TNxArrow);
    procedure SetPressedButton(const Value: TNxNotebookSheet6);
    procedure SetPosition(const Value: Integer);
  protected
    procedure AdjustClientRect(var Rect: TRect); override;
    procedure CreateWnd; override;
    function HasArrow(Arrow: TNxArrow): Boolean;
    function IsButtonVisible(Index: Integer): Boolean;
    { Event Handlers }
    procedure DoActiveChange(Sheet: TNxNotebookSheet6); override;
    { Methods }
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure Paint; override;
    procedure PaintArrow(Arrow: TNxArrow);
    procedure PaintDesignButtons; virtual;
    { Delphi Messages }
    procedure CMDesignHitTest(var Message: TCMDesignHitTest); message CM_DESIGNHITTEST;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    { Windows Messages }
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    { Properties }
    property ButtonHeight: Integer read GetButtonHeight;
    property ButtonsClientRect: TRect read GetButtonsClientRect;
    property ButtonsRect: TRect read GetButtonsRect;
  public
    constructor Create(AOwner: TComponent); override;
    function GetArrowAtPos(X, Y: Integer): TNxArrow;
    function GetArrowRect(Arrow: TNxArrow): TRect;
    function GetButtonAtPos(X, Y: Integer): TNxNotebookSheet6;
    function GetButtonRect(Index: Integer): TRect;
    function GetButtonText(Sheet: TNxNotebookSheet6): string;
    procedure RefreshArrow(Arrow: TNxArrow);
    procedure RefreshButton(Index: Integer);
    { Properties }
    property HotArrow: TNxArrow read FHotArrow write SetHotArrow;
    property HotButton: TNxNotebookSheet6 read FHotButton write SetHotButton;
    property PressedArrow: TNxArrow read FPressedArrow write SetPressedArrow;
    property PressedButton: TNxNotebookSheet6 read FPressedButton write SetPressedButton;
    property Sheet[Index: Integer]: TNxNotebookSheet6 read GetSheet; default;
  published
    property DesignButtons: Boolean read FDesignButtons write SetDesignButtons default True;
    property Position: Integer read FPosition write SetPosition default 0;
  end;

implementation

uses
  { Standard }
  Dialogs, SysUtils, Math,
  { Next Standard 6 }
  NxGraphics6;

{ TNxNotebookSheet6 }

constructor TNxNotebookSheet6.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
    csDoubleClicks, csReplicatable];

  Align := alClient;

  { Set Fields }
  FPageVisible := True;
end;

procedure TNxNotebookSheet6.CreateParams(var Params: TCreateParams);
begin
  inherited;
  with Params do
  begin
    with WindowClass do Style := Style and not CS_HREDRAW and not CS_VREDRAW;
  end;
end;

function TNxNotebookSheet6.GetIndex: Integer;
var
  i: Integer;
begin
  Result := -1;
  if Assigned(Parent) then
    for i := 0 to Parent.ControlCount - 1 do
    begin
      if Parent.Controls[i] = Self then
      begin
        Result := i;
        Exit;
      end;

    end;
end;

function TNxNotebookSheet6.GetNotebook: TNxCustomNotebook6;
begin
  Result := nil;
  if Assigned(Parent) then
    Result := TNxCustomNotebook6(Parent);
end;

procedure TNxNotebookSheet6.Paint;
begin
  inherited;
  with Canvas do
  begin
    Brush.Color := Color;
    FillRect(ClientRect);
  end;
end;

procedure TNxNotebookSheet6.SetIndex(const Value: Integer);
begin
  if Notebook <> nil then
    if Value <> Index then
    begin
      Notebook.SetPageIndex(Self, Value);
    end;
end;

procedure TNxNotebookSheet6.SetPageVisible(const Value: Boolean);
begin
  FPageVisible := Value;
end;

{ TNxNotebook6 }

function TNxCustomNotebook6.Add(Active: Boolean = False): TNxNotebookSheet6;
begin
  Result := GetTabSheetClass.Create(Self);

  { Add to controls array }
  Add(Result, Active);
end;

procedure TNxCustomNotebook6.Add(Sheet: TNxNotebookSheet6;
  Active: Boolean = False);
begin
  if Sheet <> nil then
  begin

    { Add to controls array }
    Sheet.Parent := Self;

    Sheet.Index := Pred(Count);
    Sheet.Align := alClient;

    DoPageAdded(Sheet);

    { Set active }
    if Active then ActivePage := Sheet;
  end;
end;

constructor TNxCustomNotebook6.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle := [csAcceptsControls, csClickEvents,
    csSetCaption, csDoubleClicks, csReplicatable];
end;

procedure TNxCustomNotebook6.CreateParams(var Params: TCreateParams);
begin
  inherited;
  with Params do
  begin
    with WindowClass do Style := Style and not CS_HREDRAW and not CS_VREDRAW;
  end;
end;

procedure TNxCustomNotebook6.DoActiveChange(Sheet: TNxNotebookSheet6);
begin
  if Assigned(FOnActiveChange) then FOnActiveChange(Self, Sheet);
end;

procedure TNxCustomNotebook6.DoActiveChangeQuery(Sender: TObject; Sheet: TNxNotebookSheet6; var Accept: Boolean);
begin
  if Assigned(FOnActiveChangeQuery) then FOnActiveChangeQuery(Sender, Sheet, Accept);
end;

procedure TNxCustomNotebook6.DoPageAdded(Sheet: TNxNotebookSheet6);
begin

end;

function TNxCustomNotebook6.GetActivePageIndex: Integer;
begin
  Result := -1;

  if Assigned(FActivePage)
    then Result := FActivePage.Index;
end;

function TNxCustomNotebook6.GetCount: Integer;
var
  i: Integer;
begin
  Result := 0;

  for i := 0 to Pred(ControlCount) do
    if Controls[i] is TNxNotebookSheet6
      then Inc(Result);
end;

function TNxCustomNotebook6.GetTabSheetClass: TNxSheetClass;
begin
  Result := TNxNotebookSheet6;
end;

procedure TNxCustomNotebook6.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited;

  if AComponent = ActivePage then
  begin
    FActivePage := nil;
    Invalidate;
  end;
end;

procedure TNxCustomNotebook6.PageActiveChange(Sheet: TNxNotebookSheet6);
begin

end;

procedure TNxCustomNotebook6.Paint;
begin
  inherited;

  if not Assigned(ActivePage) then
    with Canvas do
    begin
      Brush.Color := Color;
      FillRect(ClientRect);
    end;

end;

procedure TNxCustomNotebook6.SetActivePage(const Value: TNxNotebookSheet6);
var
  Accept: Boolean;
  i: Integer;
begin
  Accept := True;

  DoActiveChangeQuery(Self, Value, Accept);

  if Accept and (Value <> FActivePage) then
  begin

    { Must be own child! }
    if Assigned(Value) and (Value.Parent <> Self)
      then Exit;

    if Assigned(FActivePage) then
    begin
      RemoveFreeNotification(FActivePage);
      PageActiveChange(FActivePage);
    end;

    FActivePage := Value;

    for i := 0 to Pred(ControlCount) do
      if (Controls[i] is TNxNotebookSheet6)
        and (Controls[i] <> FActivePage) then
        begin
          Controls[i].Visible := False;
          if csDesigning in ComponentState then
          begin
            Controls[i].Align := alNone;
            Controls[i].Height := 0;
          end;
        end;

    { Set visible }
    if Assigned(FActivePage) then
    begin
      FreeNotification(FActivePage);
      PageActiveChange(FActivePage);

      FActivePage.Visible := True;

      if csDesigning in ComponentState then
      begin
        FActivePage.Align := alClient;
      end;

      { Design-time required }
//      FActivePage.BringToFront;
    end;

    if (csDesigning in ComponentState)
      or (ActivePage = nil) then Invalidate;

    { Trigger event }
    DoActiveChange(FActivePage);
  end;

end;

procedure TNxCustomNotebook6.SetActivePageIndex(const Value: Integer);
begin
  if InRange(Value, 0, Pred(Count)) then
  begin
    ActivePage := Controls[Value] as TNxNotebookSheet6;
  end;
end;

procedure TNxCustomNotebook6.SetPageIndex(Page: TControl; const Value: Integer);
begin
  SetChildOrder(Page, Value);
  Invalidate;
end;

{ TNxNotebook6 }

procedure TNxNotebook6.AdjustClientRect(var Rect: TRect);
begin
  inherited;
  if (csDesigning in ComponentState) or FDesignButtons
    then Dec(Rect.Bottom, ButtonsRect.Bottom - ButtonsRect.Top);
end;

procedure TNxNotebook6.CMDesignHitTest(var Message: TCMDesignHitTest);
var
  SheetAtPos: TNxNotebookSheet6;
begin
  inherited;

  SheetAtPos := GetButtonAtPos(Message.XPos, Message.YPos);

  if Assigned(SheetAtPos)
    or Assigned(HotButton)
    or (GetArrowAtPos(Message.XPos, Message.YPos) <> arNone)
    or (HotArrow <> arNone)
  then
    Message.Result := 1
  else
    Message.Result := 0;

end;

procedure TNxNotebook6.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  HotArrow := arNone;
  HotButton := nil;
end;

constructor TNxNotebook6.Create(AOwner: TComponent);
begin
  inherited;
  FDesignButtons := True;
  FHotArrow := arNone;
  FHotButton := nil;
  FLeftArrowState := [];
  FPosition := 0;
  FPressedArrow := arNone;
  FPressedButton := nil;
end;

procedure TNxNotebook6.CreateWnd;
begin
  inherited;
  FTextMetrics := GetTextMetric(Canvas);

  { Adjust child ctrls. }
  Realign;
end;

procedure TNxNotebook6.DoActiveChange(Sheet: TNxNotebookSheet6);
begin
  inherited;
  if (csDesigning in ComponentState)
    or DesignButtons then Invalidate;
end;

function TNxNotebook6.GetArrowAtPos(X, Y: Integer): TNxArrow;
begin
  { Nothing }
  Result := arNone;

  if HasArrow(arLeft) and PtInRect(GetArrowRect(arLeft), Point(X, Y)) then Result := arLeft;
  if HasArrow(arRight) and PtInRect(GetArrowRect(arRight), Point(X, Y)) then Result := arRight;
end;

function TNxNotebook6.GetArrowRect(Arrow: TNxArrow): TRect;
const
  szArrowButton = 13;
var
  Y: Integer;
  Location: TPoint;
begin
  Y := ButtonsRect.Top;

  case Arrow of
    arLeft: Location := Point(0, Y);
    arRight: Location := Point(ClientWidth - szArrowButton, Y);
  end;

  Result := Bounds(Location.X, Location.Y, szArrowButton, ButtonsRect.Bottom - ButtonsRect.Top);
end;

function TNxNotebook6.GetButtonAtPos(X, Y: Integer): TNxNotebookSheet6;
var
  Pos: TPoint;
  i: Integer;
  ButtonRect: TRect;
  TextSize: TSize;
begin
  { Default }
  Result := nil;

  if PtInRect(ButtonsClientRect, Point(X, Y)) then
  begin

    { Start }
    Pos := ButtonsClientRect.TopLeft;

    { Paint buttons }
    for i := FPosition to Pred(Count) do
      if IsButtonVisible(i) then
      begin
        TextSize := GetTextSize(Canvas, GetButtonText(Sheet[i]), True);

        Inc(TextSize.cx, 16);

        ButtonRect := Bounds(Pos.X, Pos.Y, TextSize.cx, ButtonHeight);

        if PtInRect(ButtonRect, Point(X, Y)) then
        begin
          Result := Sheet[i];

          { Done }
          Exit;
        end;

        Pos.X := ButtonRect.Right;

        if Pos.X > ButtonsClientRect.Right
          then Break;

      end;

  end;

end;

function TNxNotebook6.GetButtonHeight: Integer;
begin
  Result := ButtonsRect.Bottom - ButtonsRect.Top - pdDouble * 2;
end;

function TNxNotebook6.GetButtonRect(Index: Integer): TRect;
var
  Pos: TPoint;
  i: Integer;
  ButtonRect: TRect;
  TextSize: TSize;
begin
  { Start }
  Pos := ButtonsClientRect.TopLeft;

  { Paint buttons }
  for i := FPosition to Index do
    if IsButtonVisible(i) then
    begin
      TextSize := GetTextSize(Canvas, GetButtonText(Sheet[i]), True);

      Inc(TextSize.cx, 16);

      ButtonRect := Bounds(Pos.X, Pos.Y, TextSize.cx, ButtonHeight);

      { Shift }
      Pos.X := ButtonRect.Right;

      { Outside? }
      if Pos.X > ButtonsClientRect.Right
        then Break;

    end;

  Result := ButtonRect;
end;

function TNxNotebook6.GetButtonsClientRect: TRect;
begin
  Result := ButtonsRect;

  { Arrow buttons }
  if HasArrow(arLeft)
    then Result.Left := GetArrowRect(arLeft).Right;

  if HasArrow(arRight)
    then Result.Right := GetArrowRect(arRight).Left;

  InflateRect(Result, 0, -pdDouble);

  OffsetRect(Result, pdDouble, 0);
end;

function TNxNotebook6.GetButtonsRect: TRect;
var
  FontHeight: Integer;
begin

  Canvas.Font.Assign(Font);

  FontHeight := FTextMetrics.tmAscent + 16;

  Inc(FontHeight, pdDouble * 2);

  Result := Rect(0, ClientHeight - FontHeight, ClientWidth, ClientHeight);
end;

function TNxNotebook6.GetButtonText(Sheet: TNxNotebookSheet6): string;
begin
  Result := Sheet.Name;
//  Result := IntToStr(Sheet.Index) + ': ' + Sheet.Name;
end;

function TNxNotebook6.GetSheet(Index: Integer): TNxNotebookSheet6;
begin
  Result := TNxNotebookSheet6(Controls[Index]);
end;

function TNxNotebook6.HasArrow(Arrow: TNxArrow): Boolean;

  function HasRightArrow: Boolean;
  var
    X, i: Integer;
    TextSize: TSize;
  begin
    { Default }
    Result := False;

    { Start }
    X := pdDouble;

    { Measure buttons }
    for i := FPosition to Pred(Count) do
      if IsButtonVisible(i) then
      begin
        TextSize := GetTextSize(Canvas, Sheet[i].Name, True);

        Inc(TextSize.cx, 16);

        { Shift }
        Inc(X, TextSize.cx);

        { Outside? }
        if X > ClientWidth then
        begin
          Result := True;

          Break;
        end;
      end;

  end;

begin
  case Arrow of
    arLeft: Result := FPosition > 0;
    else Result := HasRightArrow;
  end;
end;

function TNxNotebook6.IsButtonVisible(Index: Integer): Boolean;
begin
  Result := Sheet[Index].PageVisible or (csDesigning in ComponentState);
end;

procedure TNxNotebook6.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  inherited;

  if (csDesigning in ComponentState)
    or DesignButtons then
  begin
    PressedButton := GetButtonAtPos(X, Y);
    PressedArrow := GetArrowAtPos(X, Y);

    if Assigned(PressedButton)
      then ActivePage := PressedButton;
  end;

end;

procedure TNxNotebook6.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
  inherited;

  HotButton := GetButtonAtPos(X, Y);
  HotArrow := GetArrowAtPos(X, Y);
end;

procedure TNxNotebook6.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  inherited;

  if PressedArrow = arLeft
    then Position := Position - 1;

  if PressedArrow = arRight
    then Position := Position + 1;

  { 'Un-press' buttons }
  PressedArrow := arNone;
  PressedButton := nil;
end;

procedure TNxNotebook6.Paint;
begin
  inherited;

  Canvas.Font.Assign(Font);

  if (csDesigning in ComponentState)
    or FDesignButtons then
  begin

    PaintDesignButtons;

    if HasArrow(arLeft) then PaintArrow(arLeft);

    if HasArrow(arRight) then PaintArrow(arRight);
  end;

end;

procedure TNxNotebook6.PaintArrow(Arrow: TNxArrow);
var
  State: TNxButtonState;
  Location: TPoint;
begin
  { Default }
  State := [];

  if FHotArrow = Arrow
    then Include(State, bsHover);

  if FPressedArrow = Arrow
    then Include(State, bsPressed);

  DrawModernButton(Canvas, '', GetArrowRect(Arrow), State);

  Location := CenterPoint(GetArrowRect(Arrow));

  with Canvas do
  begin
    Pen.Color := $00444444;
    Brush.Color := Pen.Color;

    case Arrow of
      arLeft:
        Polygon([
          Point(Location.X - 1, Location.Y),
          Point(Location.X + 1, Location.Y - 2),
          Point(Location.X + 1, Location.Y + 2),
          Point(Location.X - 1, Location.Y)
        ]);
      arRight:
        Polygon([
          Point(Location.X + 1, Location.Y),
          Point(Location.X - 1, Location.Y - 2),
          Point(Location.X - 1, Location.Y + 2),
          Point(Location.X + 1, Location.Y)
        ]);
    end;
  end;

end;

procedure TNxNotebook6.PaintDesignButtons;
var
  i: Integer;
  Pos: TPoint;
  TextSize, ButtonSize: TSize;
  ButtonRect: TRect;
  State: TNxButtonState;
  ButtonText: string;
begin
  with Canvas do
  begin
    Brush.Color := clWindow;
    FillRect(ButtonsRect);

    { Start }
    Pos := ButtonsClientRect.TopLeft;

    { Paint buttons }
    for i := FPosition to Pred(Count) do
      if IsButtonVisible(i) then
      begin
        ButtonText := GetButtonText(Sheet[i]);

        TextSize := GetTextSize(Canvas, ButtonText, True);

        ButtonSize := TextSize;

        Inc(ButtonSize.cx, 16);

        ButtonRect := Bounds(Pos.X, Pos.Y, ButtonSize.cx, ButtonHeight);

        State := [];

        if not Sheet[i].Visible
          then Include(State, bsDisabled);

        if Sheet[i] = HotButton
          then Include(State, bsHover);

        if Sheet[i] = PressedButton
          then Include(State, bsPressed);

        if Sheet[i] = ActivePage
          then Include(State, bsSelected);

        { Turn off ClearType }
  //      SetFontQuality(Font, NONANTIALIASED_QUALITY);

        PaintToolButton(Canvas, ButtonText, ButtonRect, State);

        Pos.X := ButtonRect.Right;

        if Pos.X > ButtonsClientRect.Right
          then Break;

      end;

    { Right arrow }
//    ArrowRect := Bounds(ClientWidth - H - pdStandard, ButtonsRect.Top + pdStandard, H, H);

//    DrawModernButton(Canvas, ArrowRect, []);

  end;
end;

procedure TNxNotebook6.RefreshArrow(Arrow: TNxArrow);
begin
  case Arrow of
    arNone: ;
    arLeft,
    arRight: InvalidateControl(Handle, GetArrowRect(Arrow));
  end;
end;

procedure TNxNotebook6.RefreshButton(Index: Integer);
var
  InvalidationRect: TRect;
begin
  InvalidationRect := GetButtonRect(Index);

  IntersectRect(InvalidationRect, InvalidationRect, GetButtonsClientRect);

  InvalidateControl(Handle, InvalidationRect);
end;

procedure TNxNotebook6.SetDesignButtons(const Value: Boolean);
begin
  if Value <> FDesignButtons then
  begin
    FDesignButtons := Value;

    if not (csDesigning in ComponentState)
      then Invalidate;
  end;
end;

procedure TNxNotebook6.SetHotArrow(const Value: TNxArrow);
var
  T: TNxArrow;
begin
  if Value <> FHotArrow then
  begin
    T := FHotArrow;
    FHotArrow := Value;

    if T <> arNone then RefreshArrow(T);
    if FHotArrow <> arNone then
    begin
      HotButton := nil;

      RefreshArrow(FHotArrow);
    end;
  end;
end;

procedure TNxNotebook6.SetHotButton(const Value: TNxNotebookSheet6);
var
  T: TNxNotebookSheet6;
begin
  if Value <> FHotButton then
  begin
    T := FHotButton;

    FHotButton := Value;

    if Assigned(T) then RefreshButton(T.Index);
    if Assigned(FHotButton) then
    begin
      HotArrow := arNone;

      RefreshButton(FHotButton.Index);
    end;

  end;
end;

procedure TNxNotebook6.SetPosition(const Value: Integer);
begin
  if Value <> FPosition then
  begin
    FPosition := Value;
    if FPosition < 0 then FPosition := 0;

    Invalidate;
  end;
end;

procedure TNxNotebook6.SetPressedArrow(const Value: TNxArrow);
var
  T: TNxArrow;
begin
  if Value <> FPressedArrow then
  begin
    T := FPressedArrow;
    FPressedArrow := Value;

    if T <> arNone then RefreshArrow(T);
    if FPressedArrow <> arNone then
    begin
      PressedButton := nil;

      RefreshArrow(FPressedArrow);
    end;
  end;
end;

procedure TNxNotebook6.SetPressedButton(const Value: TNxNotebookSheet6);
var
  T: TNxNotebookSheet6;
begin
  if Value <> FPressedButton then
  begin
    T := FPressedButton;

    FPressedButton := Value;

    if Assigned(T) then RefreshButton(T.Index);
    if Assigned(FPressedButton) then RefreshButton(FPressedButton.Index);
  end;
end;

procedure TNxNotebook6.WMSize(var Message: TWMSize);
var
  InvalidationRect: TRect;
begin
  inherited;

  if ClientHeight <> FPrevSize.cy then
  begin
    InvalidationRect := ButtonsRect;

    ScrollWindowEx(Handle, 0, ClientHeight - FPrevSize.cy, @InvalidationRect, @InvalidationRect, 0, nil, SW_INVALIDATE);

    FPrevSize.cy := ClientHeight;
  end;

end;

end.
