{ ------------------------------------------------------------- }
{ Purpose : Next Editors 6                                      }
{ By      : Bojan Nikolic                                       }
{ For     : BergSoft                                            }
{ ------------------------------------------------------------- }
{ Copyright (C) BergSoft.net 2021. All Rights Reserved.         }
{ ------------------------------------------------------------- }
{$I NxSuite6.inc}

unit NxEdit6;

interface

uses
  { Standard }
  Classes, Types, Windows, Messages, Graphics, ExtCtrls,
  { Controls }
  Controls, ComCtrls, StdCtrls, Forms, Dialogs, Mask, ImgList,
  {$IFDEF UI_TYPES}UITypes,{$ENDIF}
  { Next Standard 6 }
  NxConsts6, NxIntf6, NxTypes6, NxClasses6, NxControls6, NxPopupCtrls6, NxStyles6;

const
  inFastInterval = 20;
  inSlowInterval = 400;

const
  szDropDownButton = 16;
  szExecuteButton = 21;
  szPreviewWidth = 20;

const
  ControlVisible: array[Boolean] of Integer = (SW_HIDE, SW_SHOW);

type
  { INxInplaceEdit }

  INxInplaceEdit = interface
    ['{58A54A82-1A64-4225-BA8C-84ECD56A0417}']
    { Property Accessors }
    function GetOnAssignEditing: TNotifyEvent;
    function GetOnChange: TNotifyEvent;
    function GetPadding: TPadding;
    function GetShowing: Boolean;
    function GetText: string;
    procedure SetAlignment(const Value: TAlignment);
    procedure SetAutoSelect(const Value: Boolean);
    procedure SetEditOptions(const Value: TNxEditOptions);
    procedure SetOnAssignEditing(const Value: TNotifyEvent);
    procedure SetOnChange(const Value: TNotifyEvent);
    procedure SetReadOnly(const Value: Boolean);
    procedure SetText(const Value: string);
    procedure SetWantTabs(const Value: Boolean);
    { TWinControl Private }
    function GetHandle: HWND;
    procedure SetColor(const Value: TColor);
    procedure SetFont(const Value: TFont);
    procedure SetPadding(const Value: TPadding);
    { TWinControl Protected }
    procedure SetEnabled(Value: Boolean);
    procedure SetParent(AParent: TWinControl);
    { Methods }
    procedure Assign(Source: TPersistent);
    procedure AssignValue(Source: INxBase);
    procedure BeginEdit; overload;
    procedure BeginEdit(Key: WideChar); overload;
    function CanDispatchKey(Key: Word): Boolean;
    procedure EndEdit;
    function Focused: Boolean;
    procedure Free;
    procedure Hide;
    procedure SelectAll;
    procedure SetEditPadding(const Leading, Trailing: Integer);
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
    procedure SetFocus;
    procedure Show;
    { Properties }
    property Alignment: TAlignment write SetAlignment;
    property AutoSelect: Boolean write SetAutoSelect;
    property Color: TColor write SetColor;
    property EditOptions: TNxEditOptions write SetEditOptions;
    property Enabled: Boolean write SetEnabled;
    property Font: TFont write SetFont;
    property Handle: HWND read GetHandle;
    property Padding: TPadding read GetPadding write SetPadding;
    property Parent: TWinControl write SetParent;
    property ReadOnly: Boolean write SetReadOnly;
    property Showing: Boolean read GetShowing;
    property Text: string read GetText write SetText;
    property WantTabs: Boolean write SetWantTabs;

    property OnAssignEditing: TNotifyEvent read GetOnAssignEditing write SetOnAssignEditing;
    property OnChange: TNotifyEvent read GetOnChange write SetOnChange;
  end;

  { INxProperty }

  INxProperty = interface
    ['{93044DD4-80A3-46C5-A2F0-33AB76787C82}']
    function GetAsBoolean: Boolean;
    function GetAsDateTime: TDateTime;
    function GetAsFloat: Double;
    function GetAsInteger: Integer;
    function GetAsString: WideString;
    procedure SetAsBoolean(const Value: Boolean);
    procedure SetAsDateTime(const Value: TDateTime);
    procedure SetAsFloat(const Value: Double);
    procedure SetAsInteger(const Value: Integer);
    procedure SetAsString(const Value: WideString);
    { Properties }
    property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean;
    property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime;
    property AsFloat: Double read GetAsFloat write SetAsFloat;
    property AsInteger: Integer read GetAsInteger write SetAsInteger;
    property AsString: WideString read GetAsString write SetAsString;
  end;

  TEditMargins = packed record
    Leading, Trailing: Word;
  end;

  TNxValidationTriggers = set of (vtLeave, vtTyping, vtTextChanged);

  TNxStringValidateEvent = procedure (Sender: TObject; const Value: WideString;
    var Result: TNxValidationResult) of object;

  { TNxCharacterCountValidator6 }

  INxTextControl = interface
    ['{EC1B20D0-D182-43A8-BEBA-22338F85E90A}']
    function GetText: string;
    property Text: string read GetText;
  end;

  { TNxCustomEdit6 }

  TNxCustomEdit6 = class(TCustomEdit, INxInplaceEdit,
    INxTextControl, INxProperty, INxStyledControl, INxValidatable, INxPreviewDrawable, INxUserStyled)
  private
    FAlignment: TAlignment;
    FCanvas: TCanvas;
    FEditOptions: TNxEditOptions;
    FEditPadding: TEditMargins;
    FInplaceEdit: Boolean;
    FNCLButtonDown: Boolean;
    FOnAssignEditing: TNotifyEvent;
    FOnPreviewClick: TNotifyEvent;
    FOnPreviewDraw: TNxPreviewDrawEvent;
    FOnValidateEvent: TNxStringValidateEvent;
    FPadding: TPadding;
    FShowPreview: Boolean;
    FStyleOptions: TNxStyleOptions;
    FTagString: string;
    FValidationResult: TNxValidationResult;
    FValidationTriggers: TNxValidationTriggers;
    FValidator: INxValidator;
    FWantReturns: Boolean;
    FWantTabs: Boolean;
    FUserDefinedColorPalette: TNxUserDefinedColorPalette;
    { Property Accessors }
    function GetAlignment: TAlignment;
    function GetEditOptions: TNxEditOptions;
    function GetOnAssignEditing: TNotifyEvent;
    function GetOnChange: TNotifyEvent;
    function GetOnPreviewDraw: TNxPreviewDrawEvent;
    function GetPadding: TPadding;
    function GetPreviewRect: TRect;
    function GetShowing: Boolean;
    function GetStyleOptions: TNxStyleOptions;
    function GetTagString: string;
    function GetWantReturns: Boolean;
    function GetWantTabs: Boolean;
    procedure SetAlignment(const Value: TAlignment);
    procedure SetAutoSelect(const Value: Boolean);
    procedure SetColor(const Value: TColor);
    procedure SetEditOptions(const Value: TNxEditOptions);
    procedure SetEditPadding(const Leading, Trailing: Integer);
    procedure SetFont(const Value: TFont);
    procedure SetOnAssignEditing(const Value: TNotifyEvent);
    procedure SetOnChange(const Value: TNotifyEvent);
    procedure SetOnPreviewDraw(const Value: TNxPreviewDrawEvent);
    procedure SetPadding(const Value: TPadding);
    procedure SetReadOnly(const Value: Boolean);
    procedure SetShowPreview(const Value: Boolean);
    procedure SetStyleOptions(const Value: TNxStyleOptions);
    procedure SetTagString(const Value: string);
    procedure SetText(const Value: string);
    procedure SetValidationResult(const Value: TNxValidationResult);
    procedure SetWantReturns(const Value: Boolean);
    procedure SetWantTabs(const Value: Boolean);
    procedure SetUserDefinedColorPalette(
      const Value: TNxUserDefinedColorPalette);
  protected
    { INxProperty }
    function GetAsBoolean: Boolean; virtual;
    function GetAsDateTime: TDateTime; virtual;
    function GetAsFloat: Double; virtual;
    function GetAsInteger: Integer; virtual;
    function GetAsString: WideString; virtual;
    procedure SetAsBoolean(const Value: Boolean); virtual;
    procedure SetAsDateTime(const Value: TDateTime); virtual;
    procedure SetAsFloat(const Value: Double); virtual;
    procedure SetAsInteger(const Value: Integer); virtual;
    procedure SetAsString(const Value: WideString); virtual;
    { TControl }
    procedure AlignControls(AControl: TControl; var Rect: TRect); override;
    procedure Change; override;
{$IFDEF DPI_SCALING_FLAGS}
    function DefaultScalingFlags: TScalingFlags; override;
{$ENDIF}
    function GetHandle: HWND;
    function GetText: string; virtual;
    procedure SetEnabled(Value: Boolean); override;
    { Event Handlers }
    procedure DoExit; override;
    procedure DoUserDefinedColorPaletteChanged(Sender: TObject); virtual;
    procedure DoValidate(Sender: TObject; const Text: WideString; var Result: TNxValidationResult); dynamic;
    { Delphi Messages }
    procedure CMPaste(var Msg: TMessage); message WM_PASTE;
    { Virtual Methods }
    procedure BeginEdit; overload; virtual;
    procedure BeginEdit(Key: WideChar); overload; virtual;
    procedure ChangeStyle(const Value: TNxAppearanceStyle); virtual;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure CreateWnd; override;
    procedure EndEdit; virtual;
    procedure DoPaddingChange(Sender: TObject);
    function GetEditRect: TRect; virtual;
    function GetEditMargins: TEditMargins;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyUp(var Key: Word; Shift: TShiftState); override;
    { Paint }
    procedure PaintNC; virtual;
    procedure PaintNCPadding; virtual;
    procedure PaintNCValidation; virtual;
    procedure PaintPreview; virtual;
    procedure PaintPreviewContent(PreviewRect: TRect); virtual;
    procedure PaintWindow(DC: HDC); override;
    procedure RefreshPreview;
    procedure InvalidateNC;
    { Layout }
    procedure InvalidateControls;
    procedure UpdateAll;
    procedure UpdateEditRect; virtual;
    procedure UpdateNCRect; virtual;
    { Delphi Messages }
    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
    { Windows Messages }
    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
    procedure WMNCActivate(var Msg: TWMNCActivate); message WM_NCACTIVATE;
    procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
    procedure WMNCLButtonDown(var Message: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
    procedure WMNCLButtonUp(var Message: TWMNCLButtonUp); message WM_NCLBUTTONUP;
    procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
  public
    procedure Assign(Source: TPersistent); override;
    procedure AssignValue(Source: INxBase); virtual;
    function CanDispatchKey(Key: Word): Boolean; virtual;
    function CanStyle(Option: TNxStyleOption): Boolean;
    function HasValidation: Boolean;
    function Validate(const Value: WideString): TNxValidationResult;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Properties }
    property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime;
    property AsFloat: Double read GetAsFloat write SetAsFloat;
    property AsInteger: Integer read GetAsInteger write SetAsInteger;
    property AsString: WideString read GetAsString write SetAsString;
    property Canvas: TCanvas read FCanvas;
    property EditRect: TRect read GetEditRect;
    property InplaceEdit: Boolean read FInplaceEdit;
    property PreviewRect: TRect read GetPreviewRect;
  published
    property Align;
    property Alignment: TAlignment read GetAlignment write SetAlignment default taLeftJustify;
    property Anchors;
    property AutoSelect;
    property AutoSize;
    property BevelEdges;
    property BevelInner;
    property BevelKind default bkNone;
    property BevelOuter;
    property BevelWidth;
    property BiDiMode;
    property BorderStyle;
    property CharCase;
    property Color;
    property Constraints;
    property Ctl3D;
    property DoubleBuffered;
    property DragCursor;
    property DragKind;
    property DragMode;
    property EditOptions: TNxEditOptions read GetEditOptions write SetEditOptions default [edPaste, edTyping];
    property Enabled;
    property Font;
    property HideSelection;
    property ImeMode;
    property ImeName;
    property MaxLength;
{$IFDEF NUMBERS_ONLY}
    property NumbersOnly;
{$ENDIF}
    property OEMConvert;
    property Padding: TPadding read GetPadding write SetPadding;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
{$IFDEF EXT_1}
    property ParentDoubleBuffered;
{$ENDIF}
    property ParentFont;
    property ParentShowHint;
    property PasswordChar;
    property PopupMenu;
    property ReadOnly;
    property ShowHint;
    property ShowPreview: Boolean read FShowPreview write SetShowPreview default False;
    property StyleOptions: TNxStyleOptions read GetStyleOptions write SetStyleOptions
      default [soNativeStyles, soVCLStyles];
{$IFDEF STYLE_SERVICES}
    property StyleElements;
{$ENDIF}
    property TabOrder;
    property TabStop;
    property TagString: string read GetTagString write SetTagString;
    property Text;
{$IFDEF TEXT_HINT}
    property TextHint;
{$ENDIF}
{$IFDEF GESTURES}
    property Touch;
{$ENDIF}
    property Visible;
    property ValidationResult: TNxValidationResult read FValidationResult write SetValidationResult default vrUnchecked;
    property ValidationTriggers: TNxValidationTriggers read FValidationTriggers write FValidationTriggers default [];
    property Validator: INxValidator read FValidator write FValidator;
    property UserDefinedColorPalette: TNxUserDefinedColorPalette read FUserDefinedColorPalette write SetUserDefinedColorPalette;
    property WantReturns: Boolean read GetWantReturns write SetWantReturns default False;
    property WantTabs: Boolean read GetWantTabs write SetWantTabs default False;
    property OnChange;
    property OnClick;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
{$IFDEF GESTURES}
    property OnGesture;
{$ENDIF}
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
{$IFDEF EXT_1}
    property OnMouseActivate;
{$ENDIF}
    property OnMouseDown;
{$IFDEF MOUSEEVENTS}
    property OnMouseEnter;
    property OnMouseLeave;
{$ENDIF}
    property OnMouseMove;
    property OnMouseUp;
    property OnPreviewClick: TNotifyEvent read FOnPreviewClick write FOnPreviewClick;
    property OnPreviewDraw: TNxPreviewDrawEvent read FOnPreviewDraw write FOnPreviewDraw;
    property OnStartDock;
    property OnStartDrag;
    property OnValidate: TNxStringValidateEvent read FOnValidateEvent write FOnValidateEvent;
  end;

  TNxEdit6 = class(TNxCustomEdit6);

  { TNxMemo6 }

  TNxMemo6 = class(TCustomMemo, INxInplaceEdit, INxProperty)
  private
    { Private Fields }
    FAlignment: TAlignment;
    FEditOptions: TNxEditOptions;
    FOnAssignEditing: TNotifyEvent;
    FPadding: TPadding;
    FWantArrows: Boolean;
    FWantReturns: Boolean;
    FWantTabs: Boolean;
    { Property Accessors }
    function GetAlignment: TAlignment;
    function GetColor: TColor;
    function GetEditOptions: TNxEditOptions;
    function GetLinesCount: Integer;
    function GetOnAssignEditing: TNotifyEvent;
    function GetOnChange: TNotifyEvent;
    function GetPadding: TPadding;
    function GetShowing: Boolean;
    function GetText: string;
    function GetWantTabs: Boolean;
    procedure SetAlignment(const Value: TAlignment);
    procedure SetAutoSelect(const Value: Boolean);
    procedure SetColor(const Value: TColor);
    procedure SetEditOptions(const Value: TNxEditOptions);
    procedure SetEditPadding(const Leading, Trailing: Integer);
    procedure SetFont(const Value: TFont);
    procedure SetOnAssignEditing(const Value: TNotifyEvent);
    procedure SetOnChange(const Value: TNotifyEvent);
    procedure SetPadding(const Value: TPadding);
    procedure SetReadOnly(const Value: Boolean);
    procedure SetText(const Value: string);
    procedure SetWantTabs(const Value: Boolean);
  protected
    { INxProperty }
    function GetAsBoolean: Boolean; virtual;
    function GetAsDateTime: TDateTime;
    function GetAsFloat: Double; virtual;
    function GetAsInteger: Integer; virtual;
    function GetAsString: WideString; virtual;
    procedure SetAsBoolean(const Value: Boolean); virtual;
    procedure SetAsDateTime(const Value: TDateTime); virtual;
    procedure SetAsFloat(const Value: Double); virtual;
    procedure SetAsInteger(const Value: Integer); virtual;
    procedure SetAsString(const Value: WideString); virtual;
    { TControl }
    function GetEnabled: Boolean; override;
    function GetHandle: HWND;
    procedure SetEnabled(Value: Boolean); override;
    procedure BeginEdit; overload; virtual;
    procedure BeginEdit(Key: WideChar); overload; virtual;
    procedure EndEdit; virtual;
    { Windows Messages }
    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
    procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
  public
    procedure AssignValue(Source: INxBase); virtual;
    function CanDispatchKey(Key: Word): Boolean;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Properties }
    property CaretPos: TPoint read GetCaretPos write SetCaretPos;
    property LinesCount: Integer read GetLinesCount;
    property Showing: Boolean read GetShowing;
  published
    property Align;
    property Alignment: TAlignment read GetAlignment write SetAlignment default taLeftJustify;
    property Anchors;
    property AutoSelect;
    property BevelEdges;
    property BevelInner;
    property BevelKind default bkNone;
    property BevelOuter;
    property BiDiMode;
    property BorderStyle;
    property Color: TColor read GetColor write SetColor default clWindow;
    property Constraints;
    property Ctl3D;
    property DragCursor;
    property DragKind;
    property DragMode;
    property EditOptions: TNxEditOptions read GetEditOptions write SetEditOptions default [edPaste, edTyping];
    property Enabled: Boolean read GetEnabled write SetEnabled;
    property Font;
    property HideSelection;
    property ImeMode;
    property ImeName;
    property Lines;
    property MaxLength;
    property OEMConvert;
    property Padding: TPadding read GetPadding write SetPadding;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ReadOnly;
    property ScrollBars;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Text;
    property Visible;
    property WantArrows: Boolean read FWantArrows write FWantArrows default False;
    property WantReturns: Boolean read FWantReturns write FWantReturns default False;
    property WantTabs: Boolean read GetWantTabs write SetWantTabs default False;
    property WordWrap;
    property OnAssignEditing: TNotifyEvent read FOnAssignEditing write FOnAssignEditing;
    property OnChange;
    property OnClick;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDock;
    property OnStartDrag;
  end;

  { TNxNumberEdit6 }

  INxNumberEdit = interface
    ['{4DBC3530-FBE2-4C1C-B451-22F22FD5F8CB}']
    function GetMax: Double;
    function GetMin: Double;
    function GetNumericEditOptions: TNxNumericEditOptions;
    function GetPrecision: Integer;
    function GetTextAfter: WideString;
    procedure SetMax(const Value: Double);
    procedure SetMin(const Value: Double);
    procedure SetNumericEditOptions(const Value: TNxNumericEditOptions);
    procedure SetPrecision(const Value: Integer);
    procedure SetTextAfter(const Value: WideString);
    { Properties }
    property Max: Double read GetMax write SetMax;
    property Min: Double read GetMin write SetMin;
    property NumericEditOptions: TNxNumericEditOptions read GetNumericEditOptions write SetNumericEditOptions;
    property Precision: Integer read GetPrecision write SetPrecision;
    property TextAfter: WideString read GetTextAfter write SetTextAfter;
  end;

  TNxNumberEdit6 = class(TNxEdit6, INxNumberEdit)
  private
    { Private Fields }
    FAdjustToRange: Boolean;
    FHideLeadingZeros: Boolean;
    FMax: Double;
    FMin: Double;
    FNumericEditOptions: TNxNumericEditOptions;
    FPrecision: Integer;
    FTextAfter: WideString;
    { Property Accessors }
    function GetMax: Double;
    function GetMin: Double;
    function GetNumericEditOptions: TNxNumericEditOptions;
    function GetPrecision: Integer;
    function GetTextAfter: WideString;
    function GetValue: Double;
    procedure SetHideLeadingZeros(const Value: Boolean);
    procedure SetMax(const Value: Double);
    procedure SetMin(const Value: Double);
    procedure SetNumericEditOptions(const Value: TNxNumericEditOptions);
    procedure SetPrecision(const Value: Integer);
    procedure SetTextAfter(const Value: WideString);
    procedure SetValue(const Value: Double);
  protected
    { INxBase }
    function GetAsFloat: Double; override;
    function GetAsInteger: Integer; override;
    function GetAsString: WideString; override;
    procedure SetAsFloat(const Value: Double); override;
    procedure SetAsInteger(const Value: Integer); override;
    { }
    procedure AdjustValueToRange(var Value: Double);
    function CheckRange: Boolean;
    procedure EndEdit; override;
    function GetFormatedValue(AValue: Double; Append: Boolean = True): WideString;
    function GetValidText(UnCheckedText: string; AAllowSign, AAllowDecimal: Boolean): string;
    procedure SetValueToText(SendValue: Double);
    { Delphi Messages }
    procedure CMPaste(var Msg: TMessage); message WM_PASTE;
    { Windows Messages }
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Assign(Source: TPersistent); override;
    procedure AssignValue(Source: INxBase); override;
  published
    property AdjustToRange: Boolean read FAdjustToRange write FAdjustToRange default True;
    property HideLeadingZeros: Boolean read FHideLeadingZeros write SetHideLeadingZeros default False;
    property Max: Double read GetMax write SetMax;
    property Min: Double read GetMin write SetMin;
    property NumericEditOptions: TNxNumericEditOptions read FNumericEditOptions write SetNumericEditOptions default [ednDecimals, ednSigns];
    property Precision: Integer read GetPrecision write SetPrecision default 2;
    property TextAfter: WideString read GetTextAfter write SetTextAfter;
    property Value: Double read GetValue write SetValue;
  end;

  TNxSpinButton = set of (sbUp, sbDown);
  TNxSpinNotify = procedure (Sender: TObject; Buttons: TNxSpinButton) of object;

  { TNxSpinEdit6 }

  TNxSpinButtons = class(TNxUserStyledControl6)
  private
    FDelayInterval: Integer;
    FDelayTimer: TTimer;
    FHoverButtons: TNxSpinButton;
    FOnSpin: TNxSpinNotify;
    FPressedButtons: TNxSpinButton;
    FRepeatTimer: TTimer;
    FSpinButtonsStyle: TNxAppearanceStyle;
    procedure SetDelayInterval(const Value: Integer);
    procedure SetHoverButtons(const Value: TNxSpinButton);
    procedure SetPressedButtons(const Value: TNxSpinButton);
    procedure SetSpinButtonsStyle(const Value: TNxAppearanceStyle);
  protected
  	procedure Paint; override;
    procedure PaintModernStyle;
    procedure PaintNativeStyle;
    procedure PaintUserDefinedStyle;
    { Overrided Methods }
    procedure ChangeStyle(const Value: TNxAppearanceStyle); override;
{$IFDEF DPI_SCALING_FLAGS}
    function DefaultScalingFlags: TScalingFlags; override;
{$ENDIF}
    { Event Handlers }
    procedure DoDelayTimer(Sender: TObject);
    procedure DoRepeatTimer(Sender: TObject);
    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;
    { Windows Messages }
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure WMEraseBkGnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
	public
    constructor Create(AOwner: TComponent); override;
		destructor Destroy; override;
    property DelayInterval: Integer read FDelayInterval write SetDelayInterval;
    property HoverButtons: TNxSpinButton read FHoverButtons write SetHoverButtons;
    property PressedButtons: TNxSpinButton read FPressedButtons write SetPressedButtons;
    property SpinButtonsStyle: TNxAppearanceStyle read FSpinButtonsStyle write SetSpinButtonsStyle;
    property Width;
    property OnSpin: TNxSpinNotify read FOnSpin write FOnSpin;
  end;

  INxSpinEdit = interface
    ['{18309FE0-8D62-4608-BDD8-8E8B745ECC55}']
    function GetIncrement: Double;
    procedure SetIncrement(const Value: Double);
    procedure SetSpinButtons(const Value: Boolean);
    property Increment: Double read GetIncrement write SetIncrement;
    property SpinButtons: Boolean write SetSpinButtons;
  end;

  TNxSpinEdit6 = class(TNxNumberEdit6, INxSpinEdit, INxUserStyled)
  private
    FAccelerationInterval: Integer;
    FButtons: TNxSpinButtons;
    FIncrement: Double;
    FOnSpin: TNxSpinNotify;
    FSpinButtons: Boolean;
    FSpinButtonsStyle: TNxAppearanceStyle;
    FUserDefinedColorPalette: TNxUserDefinedColorPalette;
    function GetIncrement: Double;
    procedure SetAccelerationInterval(const Value: Integer);
    procedure SetIncrement(const Value: Double);
    procedure SetSpinButtons(const Value: Boolean);
    procedure SetSpinButtonsStyle(const Value: TNxAppearanceStyle);
    procedure SetUserDefinedColorPalette(const Value: TNxUserDefinedColorPalette);
  protected
    procedure CreateWnd; override;
    { Protected Methods }
    procedure ChangeStyle(const Value: TNxAppearanceStyle); override;
    { Delphi Messages }
	  procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
	  procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    { Event Handlers }
		procedure DoButtonsSpin(Sender: TObject; Buttons: TNxSpinButton); dynamic;
    procedure DoUserDefinedColorPaletteChanged(Sender: TObject); override;
    { Keyboard/Mouse Actions }
    procedure KeyPress(var Key: Char); override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    { Windows Messages }
    procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
    procedure WMKeyUP(var Message: TWMKeyUP); message WM_KEYUP;
    procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property AccelerationInterval: Integer read FAccelerationInterval write SetAccelerationInterval default inSlowInterval;
    property Increment: Double read GetIncrement write SetIncrement;
    property SpinButtons: Boolean read FSpinButtons write SetSpinButtons default True;
    property SpinButtonsStyle: TNxAppearanceStyle read FSpinButtonsStyle write SetSpinButtonsStyle default stNative;
    property UserDefinedColorPalette: TNxUserDefinedColorPalette read FUserDefinedColorPalette write SetUserDefinedColorPalette;
    property OnSpin: TNxSpinNotify read FOnSpin write FOnSpin;
  end;

  { TNxEditButton }

  INxEditButton = interface
    ['{57DD4C89-D01E-45FD-A9DB-EAD364587D52}']
    { Property Accessors }
    function GetAlign: TAlign;
    function GetAutoUp: Boolean;
    function GetCaption: WideString;
    function GetDown: Boolean;
    function GetEdit: INxInplaceEdit;
    function GetHandle: HWnd;
    function GetHover: Boolean;
    function GetLeft: Integer;
    function GetOnButtonClick: TNotifyEvent;
    function GetOnDown: TNotifyEvent;
    function GetOnUp: TNotifyEvent;
    function GetParent: TWinControl;
    function GetVisible: Boolean;
    function GetWidth: Integer;
    procedure SetAlign(const Value: TAlign);
    procedure SetAutoUp(const Value: Boolean);
    procedure SetCaption(const Value: WideString);
    procedure SetDown(const Value: Boolean);
    procedure SetEdit(const Value: INxInplaceEdit);
    procedure SetHover(const Value: Boolean);
    procedure SetLeft(const Value: Integer);
    procedure SetOnButtonClick(const Value: TNotifyEvent);
    procedure SetOnDown(const Value: TNotifyEvent);
    procedure SetOnUp(const Value: TNotifyEvent);
    procedure SetParent(AParent: TWinControl);
    procedure SetVisible(const Value: Boolean);
    procedure SetWidth(const Value: Integer);
    { Methods }
    procedure Invalidate;
    { Properties }
    property Align: TAlign read GetAlign write SetAlign;
    property AutoUp: Boolean read GetAutoUp write SetAutoUp;
    property Caption: WideString read GetCaption write SetCaption;
    property Down: Boolean read GetDown write SetDown;
    property Edit: INxInplaceEdit read GetEdit write SetEdit;
    property Handle: HWnd read GetHandle;
    property Hover: Boolean read GetHover write SetHover;
    property Left: Integer read GetLeft write SetLeft;
    property Parent: TWinControl read GetParent write SetParent;
    property Visible: Boolean read GetVisible write SetVisible;
    property Width: Integer read GetWidth write SetWidth;
    { Events }
    property OnButtonClick: TNotifyEvent read GetOnButtonClick write SetOnButtonClick;
    property OnDown: TNotifyEvent read GetOnDown write SetOnDown;
    property OnUp: TNotifyEvent read GetOnUp write SetOnUp;
  end;

  TNxEditButton = class(TNxUserStyledControl6, INxEditButton, INxUserStyled)
  private
    { Property Fields }
    FAutoUp: Boolean;
    FCaption: WideString;
    FDown: Boolean;
    FEdit: INxInplaceEdit;
    FHover: Boolean;
    FMouseDown: Boolean;
    FOnButtonClick: TNotifyEvent;
    FOnDown: TNotifyEvent;
    FOnUp: TNotifyEvent;
    FStyle: TNxAppearanceStyle;
    { Property Accessors }
    function GetAlign: TAlign;
    function GetAutoUp: Boolean;
    function GetCaption: WideString;
    function GetDown: Boolean;
    function GetEdit: INxInplaceEdit;
    function GetHandle: HWnd;
    function GetHover: Boolean;
    function GetLeft: Integer;
    function GetOnButtonClick: TNotifyEvent;
    function GetOnDown: TNotifyEvent;
    function GetOnUp: TNotifyEvent;
    function GetParent: TWinControl;
    function GetVisible: Boolean;
    function GetWidth: Integer;
    procedure SetAlign(const Value: TAlign);
    procedure SetAutoUp(const Value: Boolean);
    procedure SetCaption(const Value: WideString);
    procedure SetDown(const Value: Boolean);
    procedure SetEdit(const Value: INxInplaceEdit);
    procedure SetHover(const Value: Boolean);
    procedure SetLeft(const Value: Integer);
    procedure SetOnButtonClick(const Value: TNotifyEvent);
    procedure SetOnDown(const Value: TNotifyEvent);
    procedure SetOnUp(const Value: TNotifyEvent);
    procedure SetStyle(const Value: TNxAppearanceStyle);
    procedure SetVisible(const Value: Boolean);
    procedure SetWidth(const Value: Integer);
  protected
    procedure DoButtonClick; dynamic;
    procedure DoDown; dynamic;
    procedure DoUp; dynamic;
    { Mouse & Keyboard Actions }
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    { Painting }
    procedure Paint; override;
    procedure PaintBackground; virtual; abstract;
    { Virtual Methods }
    procedure ChangeStyle(const Value: TNxAppearanceStyle); override;
    procedure SetParent(AParent: TWinControl); override;
{$IFDEF DPI_SCALING_FLAGS}
    function DefaultScalingFlags: TScalingFlags; override;
{$ENDIF}
    { Delphi Messages }
	  procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
	  procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    { Windows Messages }
    procedure WMEraseBkGnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
  public
    constructor Create(AOwner: TComponent); override;
    { Properties }
    property AutoUp: Boolean read GetAutoUp write SetAutoUp;
    property Down: Boolean read GetDown write SetDown;
    property Edit: INxInplaceEdit read GetEdit write SetEdit;
    property Handle: HWnd read GetHandle;
    property Hover: Boolean read GetHover write SetHover;
    property Parent: TWinControl read GetParent write SetParent;
    { Events }
    property OnButtonClick: TNotifyEvent read GetOnButtonClick write SetOnButtonClick;
    property OnDown: TNotifyEvent read GetOnDown write SetOnDown;
    property OnUp: TNotifyEvent read GetOnUp write SetOnUp;
  published
    { Properties }
    property Align;
    property Anchors;
    property Caption: WideString read GetCaption write SetCaption;
    property Constraints;
    property Style: TNxAppearanceStyle read FStyle write SetStyle default stNative;
    property Visible: Boolean read GetVisible write SetVisible;
    property Width: Integer read GetWidth write SetWidth;
    { Events }
    property OnClick;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDock;
    property OnStartDrag;
  end;

  { TNxCustomButtonEdit6 }

  INxButtonEdit = interface
    ['{72798DF5-D921-41E0-856D-AB9FF32BC33B}']
    procedure SetOnButtonClick(const Value: TNotifyEvent);
  end;

  TNxCustomButtonEdit6 = class(TNxEdit6, INxButtonEdit)
  private
    FButton: INxEditButton;
    FButtonStyle: TNxAppearanceStyle;
    FButtonWidth: Integer;
    FOnButtonClick: TNotifyEvent;
    FShowButton: Boolean;
    { Property Accessors }
    procedure SetButtonStyle(const Value: TNxAppearanceStyle);
    procedure SetButtonWidth(const Value: Integer);
    procedure SetShowButton(const Value: Boolean);
  protected
    procedure CreateWnd; override;
    procedure CreateButton; virtual; abstract;
    { Property Accessors }
    procedure SetOnButtonClick(const Value: TNotifyEvent);
    { Event Handlers }
    procedure DoButtonClick(Sender: TObject); dynamic;
    procedure DoButtonDown(Sender: TObject); dynamic;
    procedure DoButtonUp(Sender: TObject); dynamic;
    { Virtual Methods }
    procedure ChangeStyle(const Value: TNxAppearanceStyle); override;
    procedure DoUserDefinedColorPaletteChanged(Sender: TObject); override;
    { Windows Messages }
    procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
    procedure WMShowWindow(var Message: TWMShowWindow); message WM_SHOWWINDOW;
  public
    procedure Assign(Source: TPersistent); override;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Properties }
    property Button: INxEditButton read FButton;
  published
    property ButtonStyle: TNxAppearanceStyle read FButtonStyle write SetButtonStyle default stNative;
    property ButtonWidth: Integer read FButtonWidth write SetButtonWidth;
    property ShowButton: Boolean read FShowButton write SetShowButton default True;
    { Events }
    property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
  end;

  { TNxButtonEdit6 }

  INxExecuteButton = interface
    ['{92CF3F17-0593-46AD-9225-324BFA4CDBD1}']
    procedure SetGlyph(const Value: TPicture);
  end;

  TNxExecuteButton6 = class(TNxEditButton, INxExecuteButton)
  private
    FGlyph: TPicture;
    procedure SetGlyph(const Value: TPicture);
  protected
    procedure DoGlyphChange(Sender: TObject);
    procedure Paint; override;
    procedure PaintBackground; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    class procedure PaintInRect(Canvas: TCanvas; Dest: TRect; Glyph: TPicture; Text: WideString);
  published
    { Properties }
    property Glyph: TPicture read FGlyph write SetGlyph;
  end;

  TNxButtonEdit6 = class(TNxCustomButtonEdit6, INxUserStyled)
  private
    FAutoText: WideString;
    FButtonCaption: WideString;
    FButtonGlyph: TPicture;
    { Property Accessors }
    procedure SetButtonGlyph(const Value: TPicture);
    procedure SetButtonCaption(const Value: WideString);
  protected
    { Event Handlers }
    procedure DoButtonClick(Sender: TObject); override;
    procedure DoButtonGlyphChange(Sender: TObject); dynamic;
    { Methods }
    procedure CreateButton; override;
  public
    procedure Assign(Source: TPersistent); override;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property AutoText: WideString read FAutoText write FAutoText;
    property ButtonWidth default szExecuteButton;
    property ButtonCaption: WideString read FButtonCaption write SetButtonCaption;
    property ButtonGlyph: TPicture read FButtonGlyph write SetButtonGlyph;
  end;

  { TNxFolderEdit6 }

  TNxFolderEdit6 = class(TNxButtonEdit6)
  private
    FRoot: string;
    FDialogCaption: string;
  public
    constructor Create(AOwner: TComponent); override;
  published
    procedure DoButtonClick(Sender: TObject); override;
    property DialogCaption: string read FDialogCaption write FDialogCaption;
    property Root: string read FRoot write FRoot;
  end;

  { TNxDropDownEdit6 }

  TNxDropDownButton6 = class(TNxEditButton)
  protected
    procedure PaintBackground; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TNxDropDownEdit6 = class(TNxCustomButtonEdit6, INxDropDown, INxDropDownNotify, INxStyledDropDown)
  private
    FAutoClose: Boolean;
    FAutoDropDown: Boolean;
    FDroppedDown: Boolean;
    FOnCloseUp: TNotifyEvent;
    FOnDropDown: TNotifyEvent;
    FOnSelect: TNotifyEvent;
    FPopupAnchor: TNxPopupAnchor;
    FPopupControl: INxPopupControl;
    FStyle: TNxDropDownStyle;
    { Property Accessors }
    function GetDroppedDown: Boolean;
    procedure SetDroppedDown(const Value: Boolean);
    procedure SetStyle(const Value: TNxDropDownStyle);
  protected
    { INxDropDown }
    procedure DoCloseUp; dynamic;
    procedure DoDrowDown; dynamic;
    procedure DoSelect; dynamic;
    function GetAutoClose: Boolean;
    { INxDropDownNotify }
    procedure SetOnDropDown(const Value: TNotifyEvent);
    { Event Handlers }
    procedure DoBeforePopup; dynamic;
    { Virtual Methods }
    procedure CreateButton; override;
    function CreatePopupControl: INxPopupControl; virtual; abstract;
    procedure Close; virtual;
    procedure DropDown; virtual;
    procedure PaintEdit; virtual;
    procedure PaintWindow(DC: HDC); override;
    { Mouse & Keyboard Methods }
    procedure DoEnter; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    { Event Handlers }
    procedure DoButtonDown(Sender: TObject); override;
    procedure DoButtonUp(Sender: TObject); override;
    { Windows Messages }

    { Delphi Messages }
    procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
    procedure WMEraseBkGnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
    procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
  public
    function CanDispatchKey(Key: Word): Boolean; override;
    constructor Create(AOwner: TComponent); override;
    { Properties }
    property AutoClose: Boolean read GetAutoClose write FAutoClose default True;
    property DroppedDown: Boolean read GetDroppedDown write SetDroppedDown default False;
    property PopupControl: INxPopupControl read FPopupControl write FPopupControl;
  published
    property AutoDropDown: Boolean read FAutoDropDown write FAutoDropDown default False;
    property PopupAnchor: TNxPopupAnchor read FPopupAnchor write FPopupAnchor default paLeft;
    property Style: TNxDropDownStyle read FStyle write SetStyle default dsDropDown;
    { Events }
    property OnCloseUp: TNotifyEvent read FOnCloseUp write FOnCloseUp;
    property OnDropDown: TNotifyEvent read FOnDropDown write FOnDropDown;
    property OnSelect: TNotifyEvent read FOnSelect write FOnSelect;
  end;

  { TNxComboBox6 }

  TNxDrawComboBoxItemEvent = procedure (Canvas: TCanvas; Index: Integer; Rect: TRect;
    State: TOwnerDrawState) of object;

  TNxComboBoxItemColorEvent = procedure (Sender: TObject; Intex: Integer; var Color: TColor;
    State: TOwnerDrawState) of object;

  TNxComboBox6 = class(TNxDropDownEdit6, INxStringsControl, INxOwnerDrawn)
  private
    { Property Fields }
    FAutoCompleteDelay: Cardinal;
    FAutoComplete: Boolean;
    FDisplayMode: TNxStringsDisplayMode;
    FDrawingOptions: TNxDrawingOptions;
    FDropDownCount: Integer;
    FFilter: string;
    FItemHeight: Integer;
    FItemIndex: Integer;
    FItems: TStrings;
    FItemsAlignment: TAlignment;
    FLastTime: Cardinal;
    FListWidth: Integer;
    FOnDrawItem: TNxDrawComboBoxItemEvent;
    FUpdatingIndex: Boolean;
    FSelectionTextColor: TColor;
    FSelectionColor: TColor;
    { Property Accessors }
    function GetAutoComplete: Boolean;
    function GetCount: Integer;
    function GetDrawingOptions: TNxDrawingOptions;
    function GetDropDownCount: Integer;
    function GetItemHeight: Integer;
    function GetItemIndex: Integer;
    function GetItems: TStrings;
    function GetItemsAlignment: TAlignment;
    function GetListWidth: Integer;
    procedure SetAutoComplete(const Value: Boolean);
    procedure SetDrawingOptions(const Value: TNxDrawingOptions);
    procedure SetDropDownCount(const Value: Integer);
    procedure SetItemHeight(const Value: Integer);
    procedure SetItemIndex(const Value: Integer);
    procedure SetItems(const Value: TStrings);
    procedure SetItemsAlignment(const Value: TAlignment);
    procedure SetListWidth(const Value: Integer);
  protected
    function GetAsInteger: Integer; override;
    procedure SetAsInteger(const Value: Integer); override;
    { Virtual Methods }
    function CreatePopupControl: INxPopupControl; override;
    function MeasureItem(const Index: Integer; const AWidth: Integer = 0): TSize;
    function PaintCell(const Index: Integer; CellRect: TRect;
      State: TOwnerDrawState): Boolean; virtual;
    procedure PaintContent(const Index: Integer; CellRect: TRect;
      State: TOwnerDrawState); virtual;
    function SelectItem(var AnItem: string): Boolean; virtual;
    procedure TryItemIndex(const Index: Integer; Select: Boolean);
    { Mouse & Keyboard }
    function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override;
    function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    { Event Handlers }
    procedure DoDrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); dynamic;
    procedure DoItemsChange(Sender: TObject); dynamic;
    { Delphi Messages }
    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
    { Windows Messages }
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Methods }
    function GetDisplayText(const Index: Integer): string;
    { Properties }
    property Count: Integer read GetCount;
  published
    property AutoComplete: Boolean read FAutoComplete write FAutoComplete default False;
    property AutoCompleteDelay: Cardinal read FAutoCompleteDelay write FAutoCompleteDelay default 750;
    property DrawingOptions: TNxDrawingOptions read GetDrawingOptions write SetDrawingOptions default [doBackground, doContent];
    property ItemHeight: Integer read GetItemHeight write SetItemHeight default szItemHeight;
    property ItemIndex: Integer read GetItemIndex write SetItemIndex default -1;
    property ItemsAlignment: TAlignment read GetItemsAlignment write SetItemsAlignment default taLeftJustify;
    property Items: TStrings read GetItems write SetItems;
    property ListWidth: Integer read FListWidth write SetListWidth default 0;
    property DisplayMode: TNxStringsDisplayMode read FDisplayMode write FDisplayMode default dmDefault;
    property DropDownCount: Integer read GetDropDownCount write SetDropDownCount default coDropDown;
    property SelectionColor: TColor read FSelectionColor write FSelectionColor default clHighlight;
    property SelectionTextColor: TColor read FSelectionTextColor write FSelectionTextColor default clHighlightText;
    property OnDrawItem: TNxDrawComboBoxItemEvent read FOnDrawItem write FOnDrawItem;
  end;

  { TNxCheckComboBox6 }

  TNxCheckEntry = class
  private
    FDisabled: Boolean;
    FHeader: Boolean;
    FState: TCheckBoxState;
    FTag: Integer;
    function GetChecked: Boolean;
    procedure SetChecked(Check: Boolean);
  public
    class function GetDefaultState: TCheckBoxState;
    property Checked: Boolean read GetChecked write SetChecked;
    property Disabled: Boolean read FDisabled write FDisabled;
    property Header: Boolean read FHeader write FHeader;
    property State: TCheckBoxState read FState write FState;
    property Tag: Integer read FTag write FTag;
  end;

  TNxCheckComboBox6 = class(TNxComboBox6, INxCheckPopupOwner)
  private
    FCheckedStrings: TStrings;
    FDelimiter: Char;
    { Property Accessors }
    function GetChecked(Index: Integer): Boolean;
    function GetEntry(Index: Integer): TNxCheckEntry;
    function GetHeader(Index: Integer): Boolean;
    function GetItemEnabled(Index: Integer): Boolean;
    function GetState(Index: Integer): TCheckBoxState;
    procedure SetChecked(Index: Integer; const Value: Boolean);
    procedure SetDelimiter(const Value: Char);
    procedure SetHeader(Index: Integer; const Value: Boolean);
    procedure SetItemEnabled(Index: Integer; const Value: Boolean);
    procedure SetState(Index: Integer; const Value: TCheckBoxState);
  protected
    function CreateCheckEntry: TNxCheckEntry;
    procedure DrawCheckBox(Canvas: TCanvas; CheckBoxRect: TRect; CheckBoxState: TCheckBoxState); virtual;
    procedure DoBeforePopup; override;
    { Overrided Methods }
    function CreatePopupControl: INxPopupControl; override;
    function PaintCell(const Index: Integer; CellRect: TRect;
      State: TOwnerDrawState): Boolean; override;
    { INxCheckPopupOwner }
    procedure CheckBoxClick(const Index: Integer);
    { Propertis }
    property Entry[Index: Integer]: TNxCheckEntry read GetEntry;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure CheckAll;
    procedure ClearAll;
    procedure UpdateCheckedStrings;
    procedure UpdateText;
    { Properties }
    property Checked[Index: Integer]: Boolean read GetChecked write SetChecked;
    property CheckedStrings: TStrings read FCheckedStrings;
    property Delimiter: Char read FDelimiter write SetDelimiter default ',';
    property ItemEnabled[Index: Integer]: Boolean read GetItemEnabled write SetItemEnabled;
    property State[Index: Integer]: TCheckBoxState read GetState write SetState;
    property Header[Index: Integer]: Boolean read GetHeader write SetHeader;
  end;

  { TNxDatePicker6 }

  TNxDatePicker6 = class(TNxDropDownEdit6, INxDatePickerOwner)
  private
    FOnCustomDrawDateColor: TNxCustomDrawDate;
    FOnGetDateColor: TNxGetDateColor;
    FSelectionDateRange: TNxDateRange;
    FStartDayOfWeek: TNxStartDayOfWeek;
    { Property Accessors }
    function GetDate: TDate;
    procedure SetDate(const Value: TDate);
    procedure SetStartDayOfWeek(const Value: TNxStartDayOfWeek);
  protected
    { Event Handlers }
    procedure DoCustomDrawDate(Sender: TObject; Date: TDateTime; DayRect: TRect); dynamic;
    procedure DoGetDateColor(Sender: TObject; Date: TDateTime; var DayColor: TColor); dynamic;
    { Keyboard }
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    { Virtual Methods }
    function CreatePopupControl: INxPopupControl; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property Date: TDate read GetDate write SetDate;
    property SelectionDateRange: TNxDateRange read FSelectionDateRange write FSelectionDateRange default drAll;
    property StartDayOfWeek: TNxStartDayOfWeek read FStartDayOfWeek write SetStartDayOfWeek default dwSystem;
    property OnCustomDrawDate: TNxCustomDrawDate read FOnCustomDrawDateColor write FOnCustomDrawDateColor;
    property OnGetDateColor: TNxGetDateColor read FOnGetDateColor write FOnGetDateColor;
  end;

  { TNxTimeEdit6 }

  TNxTimeEdit6 = class(TNxEdit6)
  private
    FAccelerationInterval: Integer;
    FButtons: TNxSpinButtons;
    FIncrement: Double;
    FSpinButtons: Boolean;
    { Property Accessors }
    procedure SetAccelerationInterval(const Value: Integer);
    procedure SetIncrement(const Value: Double);
    procedure SetSpinButtons(const Value: Boolean);
  protected
    { Event Handlers }
		procedure DoButtonsSpin(Sender: TObject; Buttons: TNxSpinButton);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Properties }
    property AccelerationInterval: Integer read FAccelerationInterval write SetAccelerationInterval default inSlowInterval;
    property Increment: Double read FIncrement write SetIncrement;
    property SpinButtons: Boolean read FSpinButtons write SetSpinButtons default True;
  end;

  { TNxTimePicker6 }

  TNxTimePicker6 = class(TNxDropDownEdit6, INxTimeControl)
  private
    FHoursText: string;
    FMinutesText: string;
    FOptions: TNxTimeShowOptions;
    { Property Accessors }
    function GetHoursText: string;
    function GetMinutesText: string;
    procedure SetHoursText(const Value: string);
    procedure SetMinutesText(const Value: string);
    procedure SetOptions(const Value: TNxTimeShowOptions);
  protected
    function CreatePopupControl: INxPopupControl; override;
    procedure DoBeforePopup; override;
    function GetAsDateTime: TDateTime; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure SetAsDateTime(const Value: TDateTime); override;
    { Messages }
    procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
    { Properties }
    property Options: TNxTimeShowOptions read FOptions write FOptions default [to24HourDay, toMinutes];
  public
    constructor Create(AOwner: TComponent); override;
  published
  	property Time: TDateTime read GetAsDateTime write SetAsDateTime;
    property HoursText: string read FHoursText write FHoursText;
    property MinutesText: string read FMinutesText write FMinutesText;
    property PopupAnchor default paRight;
  end;

  { TNxRichEdit6 }

  TNxRichEdit6 = class(TRichEdit, INxInplaceEdit)
  private
    { Private Fields }
    FAlignment: TAlignment;
    FEditOptions: TNxEditOptions;
    FOnAssignEditing: TNotifyEvent;
    FPadding: TPadding;
    FWantArrows: Boolean;
    FWantReturns: Boolean;
    FWantTabs: Boolean;
    { Property Accessors }
    function GetAlignment: TAlignment;
    function GetColor: TColor;
    function GetEditOptions: TNxEditOptions;
    function GetLinesCount: Integer;
    function GetOnAssignEditing: TNotifyEvent;
    function GetOnChange: TNotifyEvent;
    function GetPadding: TPadding;
    function GetShowing: Boolean;
    function GetText: string;
    function GetWantTabs: Boolean;
    procedure SetAlignment(const Value: TAlignment);
    procedure SetAutoSelect(const Value: Boolean);
    procedure SetColor(const Value: TColor);
    procedure SetEditOptions(const Value: TNxEditOptions);
    procedure SetEditPadding(const Leading, Trailing: Integer);
    procedure SetFont(const Value: TFont);
    procedure SetOnAssignEditing(const Value: TNotifyEvent);
    procedure SetOnChange(const Value: TNotifyEvent);
    procedure SetPadding(const Value: TPadding);
    procedure SetReadOnly(const Value: Boolean);
    procedure SetText(const Value: string);
    procedure SetWantTabs(const Value: Boolean);
  protected
    function GetAsFloat: Double; virtual;
    function GetAsInteger: Integer; virtual;
    function GetAsString: WideString; virtual;
    procedure SetAsFloat(const Value: Double); virtual;
    procedure SetAsInteger(const Value: Integer); virtual;
    procedure SetAsString(const Value: WideString); virtual;
    { TControl }
    function GetEnabled: Boolean; override;
    function GetHandle: HWND;
    procedure SetEnabled(Value: Boolean); override;
    procedure BeginEdit; overload; virtual;
    procedure BeginEdit(Key: WideChar); overload; virtual;
    procedure EndEdit; virtual;
    { Windows Messages }
    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
  public
    procedure AssignValue(Source: INxBase); virtual;
    function CanDispatchKey(Key: Word): Boolean;
    function Clone: INxInplaceEdit;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property CaretPos: TPoint read GetCaretPos write SetCaretPos;
    property LinesCount: Integer read GetLinesCount;
    property Showing: Boolean read GetShowing;
  published
    property Alignment: TAlignment read GetAlignment write SetAlignment default taLeftJustify;
    property AutoSelect;
    property Color: TColor read GetColor write SetColor default clWindow;
    property EditOptions: TNxEditOptions read GetEditOptions write SetEditOptions default [edPaste, edTyping];
    property Enabled: Boolean read GetEnabled write SetEnabled;
    property Padding: TPadding read GetPadding write SetPadding;
    property WantArrows: Boolean read FWantArrows write FWantArrows default False;
    property WantReturns: Boolean read FWantReturns write FWantReturns default False;
    property WantTabs: Boolean read GetWantTabs write SetWantTabs default False;
    property OnAssignEditing: TNotifyEvent read FOnAssignEditing write FOnAssignEditing;
  end;

  { TNxCheckBox6 }

  TNxCheckArea = (caCheckMarkAndText, caCheckMark, caClientRect);

  TNxCheckBox6 = class(TNxControl6, INxProperty)
  private
    FAlignment: TAlignment;
    FAllowGrayed: Boolean;
    FButtonState: TNxButtonState;
    FCheckArea: TNxCheckArea;
    FIndent: Integer;
    FOnChange: TNotifyEvent;
    FState: TCheckBoxState;
    FTagString: string;
    FVerticalAlignment: TVerticalAlignment;
    { Property Accessors }
    function GetCheckBoxRect: TRect;
    function GetChecked: Boolean;
    function GetTagString: string;
    function GetTextRect: TRect;
    procedure SetAlignment(const Value: TAlignment);
    procedure SetButtonState(const Value: TNxButtonState);
    procedure SetChecked(const Value: Boolean);
    procedure SetIndent(const Value: Integer);
    procedure SetState(const Value: TCheckBoxState);
    procedure SetTagString(const Value: string);
    procedure SetVerticalAlignment(const Value: TVerticalAlignment);
  protected
    { INxProperty }
    function GetAsBoolean: Boolean; virtual;
    function GetAsDateTime: TDateTime; virtual;
    function GetAsFloat: Double; virtual;
    function GetAsInteger: Integer; virtual;
    function GetAsString: WideString; virtual;
    procedure SetAsBoolean(const Value: Boolean); virtual;
    procedure SetAsDateTime(const Value: TDateTime); virtual;
    procedure SetAsFloat(const Value: Double); virtual;
    procedure SetAsInteger(const Value: Integer); virtual;
    procedure SetAsString(const Value: WideString); virtual;
    { Event Handlers }
    procedure DoChange; dynamic;
    { Methods }
    procedure DrawCheckBox(CheckBoxRect: TRect); virtual;
    function InActiveArea(X, Y: Integer): Boolean;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    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;
    { TControl }
    function CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; override;
    { TCustomControl }
    procedure Paint; override;
    { Delphi Messages }
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
    { Windows Messages }
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
    { Properties }
    property CheckBoxRect: TRect read GetCheckBoxRect;
    property TextRect: TRect read GetTextRect;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Toggle;
    { Properties }
    property ButtonState: TNxButtonState read FButtonState write SetButtonState;
  published
    property Align;
    property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
    property AllowGrayed: Boolean read FAllowGrayed write FAllowGrayed default False;
    property AutoSize;
    property Caption;
    property CheckArea: TNxCheckArea read FCheckArea write FCheckArea default caCheckMarkAndText;
    property Checked: Boolean read GetChecked write SetChecked default False;
    property Color;
    property Enabled;
    property Font;
    property Indent: Integer read FIndent write SetIndent default pdDouble;
    {$IFDEF PADDING}
    property Padding;
    {$ENDIF}
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property State: TCheckBoxState read FState write SetState default cbUnchecked;
    property TabOrder;
    property TabStop;
    property TagString: string read GetTagString write SetTagString;
    property VerticalAlignment: TVerticalAlignment read FVerticalAlignment write SetVerticalAlignment default taVerticalCenter;
    property Visible;

    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    property OnClick;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDock;
    property OnStartDrag;
  end;

  { TNxFontComboBox6 }

  TNxFontComboBox6 = class(TNxComboBox6)
  private
    FPaintInFont: Boolean;
  protected
    procedure PaintContent(const Index: Integer; CellRect: TRect;
      State: TOwnerDrawState); override;
    procedure PaintPreviewContent(PreviewRect: TRect); override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property PaintInFont: Boolean read FPaintInFont write FPaintInFont default True;
  end;

  { TNxColorComboBox6 }

  TNxColorComboBox6 = class(TNxComboBox6)
  private
    FShowNames: Boolean;
  protected
    procedure PaintContent(const Index: Integer; CellRect: TRect;
      State: TOwnerDrawState); override;
    procedure PaintPreviewContent(PreviewRect: TRect); override;
    procedure Populate; virtual;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property ShowNames: Boolean read FShowNames write FShowNames default True;
  end;

  { TNxColorPicker6 }

  TNxColorPicker6 = class(TNxDropDownEdit6, INxColorControl)
  private
    FColorKind: TNxColorKind;
    function GetColorKind: TNxColorKind;
    function GetSelectedColor: TColor;
    procedure SetSelectedColor(const Value: TColor);
  protected
    { Virtual Methods }
    function CreatePopupControl: INxPopupControl; override;
    procedure PaintPreviewContent(PreviewRect: TRect); override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property ColorKind: TNxColorKind read GetColorKind write FColorKind default ckDelphi;
    property SelectedColor: TColor read GetSelectedColor write SetSelectedColor default clNone;
  end;

  { TNxIconPicker6 }

  TNxIconPicker6 = class(TNxDropDownEdit6, INxIconPicker)
  private
    FColCount: Integer;
    FImages: TCustomImageList;
    FItemIndex: Integer;
    { Property Accessors }
    function GetColCount: Integer;
    function GetImages: TCustomImageList;
    function GetItemIndex: Integer;
    procedure SetImages(const Value: TCustomImageList);
    procedure SetItemIndex(const Value: Integer);
  protected
    { Virtual Methods }
    function CreatePopupControl: INxPopupControl; override;
    procedure PaintPreviewContent(PreviewRect: TRect); override;
    { Mouse & Keyboard }
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    function GetDisplayText(const Index: Integer): string;
  published
    property ColCount: Integer read FColCount write FColCount default 6;
    property Images: TCustomImageList read FImages write SetImages;
    property ItemIndex: Integer read GetItemIndex write SetItemIndex default -1;
  end;

  { TNxMaskEdit6 }

  TNxMaskEdit6 = class(TMaskEdit, INxInplaceEdit, INxValidatable)
  private
    FAlignment: TAlignment;
    FPadding: TPadding;
    { Property Accessors }
    function GetOnAssignEditing: TNotifyEvent;
    function GetOnChange: TNotifyEvent;
    function GetPadding: TPadding;
    function GetShowing: Boolean;
    function GetText: string;
    procedure SetAlignment(const Value: TAlignment);
    procedure SetAutoSelect(const Value: Boolean);
    procedure SetColor(const Value: TColor);
    procedure SetEditOptions(const Value: TNxEditOptions);
    procedure SetEditPadding(const Leading, Trailing: Integer);
    procedure SetFont(const Value: TFont);
    procedure SetOnAssignEditing(const Value: TNotifyEvent);
    procedure SetOnChange(const Value: TNotifyEvent);
    procedure SetPadding(const Value: TPadding);
    procedure SetReadOnly(const Value: Boolean);
    procedure SetText(const Value: string);
    procedure SetWantTabs(const Value: Boolean);
  protected
    function GetAsFloat: Double; virtual;
    function GetAsInteger: Integer; virtual;
    function GetAsString: WideString; virtual;
    procedure SetAsFloat(const Value: Double); virtual;
    procedure SetAsInteger(const Value: Integer); virtual;
    procedure SetAsString(const Value: WideString); virtual;
    { TControl }
    procedure CreateParams(var Params: TCreateParams); override;
    function GetEnabled: Boolean; override;
    function GetHandle: HWND;
    procedure SetEnabled(Value: Boolean); override;
    { TMaskEdit }
    { INxInplaceEdit }
    function CanDispatchKey(Key: Word): Boolean;
    procedure AssignValue(Source: INxBase);
    procedure BeginEdit(Key: WideChar); overload;
    procedure BeginEdit; overload;
    procedure EndEdit; virtual;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
  end;

  { TNxTagsPanel6 }

  TNxTagsPanel6 = class(TCustomControl)
  private
    FHotTagButton: Integer;
    FPressedTagButton: Integer;
    FPressedTag: Integer;
    FTags: TStrings;
    procedure SetHotTagButton(const Value: Integer);
    procedure SetTags(const Value: TStrings);
    procedure SetPressedTagButton(const Value: Integer);
  protected
    function ButtonSize: TSize;
    procedure CreateWnd; override;
    { Mouse }
    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;
    { Paint }
    procedure Paint; override;
    procedure PaintCloseButton(ButtonRect: TRect; ButtonState: TNxButtonState);
    procedure PaintTagBackground(const Index: Integer; TagRect: TRect);
    procedure PaintNativeTagBackground(const Index: Integer; TagRect: TRect);
    procedure PaintUserDefinedTagBackground(const Index: Integer; TagRect: TRect);
    { Methods }
    function GetCloseButtonColor(const AState: TNxButtonState): TColor; virtual;
    procedure UpdateWidth;
    { Delphi Messages }
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    { WinApi Messages }
    procedure WMEraseBkGnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
  public
    constructor Create(AOwner: TComponent); override;
    { Methods }
    procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;
      var Accept: Boolean); override;
    procedure DragDrop(Source: TObject; X, Y: Integer); override;
    function GetTagAtPos(const X, Y: Integer; InButton: Boolean): Integer;
    function GetTagSize(const Index: Integer): TSize;
    { Properties }
    property Tags: TStrings read FTags write SetTags;
    property HotTagButton: Integer read FHotTagButton write SetHotTagButton;
    property PressedTagButton: Integer read FPressedTagButton write SetPressedTagButton;
  end;

  TNxTagArea = (csTagArea, csEditArea);
  TNxTagStyle = (tsRectangle, tsRoundRect);

  { TNxTagsEdit6 }

  TNxGetTagColorEvent = procedure (Sender: TObject; Index: Integer;
    var FillColor: TColor; var BorderColor: TColor) of object;
  TNxTagAddEvent = procedure (Sender: TObject; var Value: WideString;
    var Accept: Boolean) of object;
  TNxTagDeleteEvent = procedure (Sender: TObject; Index: Integer;
    var Accept: Boolean) of object;

  TNxTagMouseDownEvent = procedure (Sender: TObject; Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer; Area: TNxTagArea) of object;
  TNxTagMouseMoveEvent =  procedure (Sender: TObject; Shift: TShiftState;
      X, Y: Integer; Area: TNxTagArea) of object;
  TNxTagMouseUpEvent = procedure (Sender: TObject; Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer; Area: TNxTagArea) of object;
  TNxTagDragOverEvent = procedure (Sender, Source: TObject; X, Y: Integer; State: TDragState;
      var Accept: Boolean; Area: TNxTagArea) of object;
  TNxTagDragDropEvent = procedure (Sender, Source: TObject; X, Y: Integer;
      Area: TNxTagArea) of object;

  TNxTagsEdit6 = class(TNxEdit6)
  private
    FAutoAdd: Boolean;
    FMax: Integer;
    FOnGetTabColor: TNxGetTagColorEvent;
    FOnTagAdd: TNxTagAddEvent;
    FOnTagDelete: TNxTagDeleteEvent;
    FOnTagDragDrop: TNxTagDragDropEvent;
    FOnTagDragOver: TNxTagDragOverEvent;
    FOnTagMouseDown: TNxTagMouseDownEvent;
    FOnTagMouseMove: TNxTagMouseMoveEvent;
    FOnTagMouseUp: TNxTagMouseUpEvent;
    FPanel: TNxTagsPanel6;
    FSeparators: WideString;
    FTagBorderColor: TColor;
    FTags: TStrings;
    FTagsBackgroundStyle: TNxAppearanceStyle;
    FTagsStyle: TNxTagStyle;
    procedure SetAutoAdd(const Value: Boolean);
    procedure SetMax(const Value: Integer);
    procedure SetTagBorderColor(const Value: TColor);
    procedure SetTags(const Value: TStrings);
    procedure SetTagsStyle(const Value: TNxTagStyle);
    procedure SetTagsPaintStyle(const Value: TNxAppearanceStyle);
  protected
    procedure CreateWnd; override;
    { Event Handlers }
    procedure DoGetTabColor(Index: Integer; var FillColor: TColor; var BorderColor: TColor); dynamic;
    procedure DoTagAdd(var Value: WideString; var Accept: Boolean); dynamic;
    procedure DoTagDelete(Index: Integer; var Accept: Boolean); dynamic;
    procedure DoTagsChange(Sender: TObject); dynamic;
    { Mouse }
    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 DragOver(Source: TObject; X, Y: Integer; State: TDragState;
      var Accept: Boolean); override;
    procedure DoMouseDown(Button: TMouseButton; Shift: TShiftState;
       X, Y: Integer; Area: TNxTagArea); dynamic;
    procedure DoMouseMove(Shift: TShiftState;
       X, Y: Integer; Area: TNxTagArea); dynamic;
    procedure DoMouseUp(Button: TMouseButton; Shift: TShiftState;
       X, Y: Integer; Area: TNxTagArea); dynamic;
    procedure DoDragOver(Source: TObject; X, Y: Integer; State: TDragState;
      var Accept: Boolean; Area: TNxTagArea); dynamic;
    procedure DoDragDrop(Source: TObject; X, Y: Integer; Area: TNxTagArea); dynamic;
    { Keyboard }
    procedure KeyPress(var Key: Char); override;
    { Delphi Messages }
    procedure CMPaste(var Msg: TMessage); message WM_PASTE;
    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
    { WinApi Messages }
    procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
    { Other }
    procedure UpdatePanel;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Methods }
    function AddTags: Integer;
    function SelectedTag: Integer;
    procedure DragDrop(Source: TObject; X, Y: Integer); override;
  published
    property AutoAdd: Boolean read FAutoAdd write SetAutoAdd default True;
    property Max: Integer read FMax write SetMax default 6;
    property TagBorderColor: TColor read FTagBorderColor write SetTagBorderColor default clSilver;
    property Tags: TStrings read FTags write SetTags;
    property TagsBackgroundStyle: TNxAppearanceStyle read FTagsBackgroundStyle write SetTagsPaintStyle default stNative;
    property TagsStyle: TNxTagStyle read FTagsStyle write SetTagsStyle default tsRectangle;
    property Separators: WideString read FSeparators write FSeparators;
    { Events }
    property OnGetTagColor: TNxGetTagColorEvent read FOnGetTabColor write FOnGetTabColor;
    property OnTagAdd: TNxTagAddEvent read FOnTagAdd write FOnTagAdd;
    property OnTagDelete: TNxTagDeleteEvent read FOnTagDelete write FOnTagDelete;
    property OnMouseDown: TNxTagMouseDownEvent read FOnTagMouseDown write FOnTagMouseDown;
    property OnMouseMove: TNxTagMouseMoveEvent read FOnTagMouseMove write FOnTagMouseMove;
    property OnMouseUp: TNxTagMouseUpEvent read FOnTagMouseUp write FOnTagMouseUp;
    property OnDragOver: TNxTagDragOverEvent read FOnTagDragOver write FOnTagDragOver;
    property OnDragDrop: TNxTagDragDropEvent read FOnTagDragDrop write FOnTagDragDrop;
  end;

  { TNxGridPicker6 }

  TNxGridPicker6 = class(TNxDropDownEdit6, INxGridPicker)
  private
    FColumns: TNxGridPickerColumns;
    FDropDownCount: Integer;
    FHeaderHeight: Integer;
    FListWidth: Integer;
    FOnSetValue: TNxGridPickerSetValueEvent;
    FRowHeight: Integer;
    FRowsList: TList;
    FSelectedIndex: Integer;
    function GetHeaderHeight: Integer;
    function GetListWidth: Integer;
    function GetRow(const Index: Integer): TNxListRow6;
    function GetRowHeight: Integer;
    function GetSelectedIndex: Integer;
    procedure SetColumns(const Value: TNxGridPickerColumns);
    procedure SetDropDownCount(const Value: Integer);
    procedure SetSelectedIndex(const Value: Integer);
  protected
    { Virtual Methods }
    function CreatePopupControl: INxPopupControl; override;
    { INxDictionaryDataSource }
    function GetCount: Integer;
    function GetColumn(const Index: Integer): TNxGridPickerColumn;
    function GetColCount: Integer;
    function GetDropDownCount: Integer;
    procedure DoSetValue(SelectedIndex: Integer; var Value: WideString);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function AddRow(Cells: array of WideString): TNxListRow6;
    procedure ClearRows;
    procedure DeleteRow(const Index: Integer);
    property Row[const Index: Integer]: TNxListRow6 read GetRow;
  published
    property Columns: TNxGridPickerColumns read FColumns write SetColumns;
    property DropDownCount: Integer read GetDropDownCount write SetDropDownCount;
    property HeaderHeight: Integer read GetHeaderHeight write FHeaderHeight default 18;
    property ListWidth: Integer read FListWidth write FListWidth default 0;
    property RowHeight: Integer read GetRowHeight write FRowHeight default 16;
    property SelectedIndex: Integer read FSelectedIndex write SetSelectedIndex default -1;
    { Events }
    property OnSetValue: TNxGridPickerSetValueEvent read FOnSetValue write FOnSetValue;
  end;

  { TNxTextValidator6 }

  TNxLengthRange = class(TPersistent)
  private
    FMax: Integer;
    FMin: Integer;
  public
    constructor Create;
  published
    property Max: Integer read FMax write FMax default 100;
    property Min: Integer read FMin write FMin default 0;
  end;

  TNxTextValidator6 = class(TComponent, INxValidator)
  private
    FErrorCount: Integer;
    FRequiredText: string;
    FRequiredRange: TNxLengthRange;
    procedure SetRequiredRange(const Value: TNxLengthRange);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Methods }
    function GetErrorCount: Integer;
    function Validate(const Validatable: INxValidatable): TNxValidationResult;
  published
    { Properties }
    property RequiredRange: TNxLengthRange read FRequiredRange write SetRequiredRange;
    property RequiredText: string read FRequiredText write FRequiredText;
  end;

  function InplaceEditControl(const InplaceEdit: INxInplaceEdit): TWinControl;
  function ShiftState: TShiftState;

implementation

uses
  { Standard }
  Clipbrd, SysUtils, StrUtils, DateUtils, Math,
{$WARN UNIT_PLATFORM OFF}
  FileCtrl,
{$WARN UNIT_PLATFORM ON}
  { Next Standard 6 }
  NxGraphics6,
{$IFDEF THEMES}
  UxTheme
{$ELSE}
  NxTheme6
{$ENDIF}
;

const
  AlignmentStyles: array [TAlignment] of DWORD = (ES_LEFT, ES_RIGHT, ES_CENTER);

///<summary>Returns TWinControl instance of INxInplaceEdit interface.</summary>
///<param name="InplaceEdit">Interface reference</param>
///<returns>TWinControl instane if supported, otherwise nil.</returns>
function InplaceEditControl(const InplaceEdit: INxInplaceEdit): TWinControl;
var
  Reference: IInterfaceComponentReference;
begin
  Result := nil;
  if Supports(InplaceEdit, IInterfaceComponentReference, Reference) then
  begin
    if Reference.GetComponent is TWinControl then Result := TWinControl(Reference.GetComponent);
  end;
end;

function GetItemValue(Strings: TNxStrings; Index: Integer): TString;
begin
  if Index >= 0 then
    Result := Copy(Strings[Index], Length(Strings.Names[Index]) + 2, MaxInt) else
    Result := '';
end;

function CtrlDown: Boolean;
var
  State: TKeyboardState;
begin
  GetKeyboardState(State);
  Result := ((State[vk_Control] and 128) <> 0);
end;

function ShiftDown: Boolean;
var
  State: TKeyboardState;
begin
  GetKeyboardState(State);
  Result := ((State[vk_Shift] and 128) <> 0);
end;

function AltDown: Boolean;
var
  State: TKeyboardState;
begin
  GetKeyboardState(State);
  Result := ((State[vk_Menu] and 128) <> 0);
end;

function ShiftState: TShiftState;
begin
  Result := [];
  if AltDown then Include(Result, ssAlt);
  if CtrlDown then Include(Result, ssCtrl);
  if ShiftDown then Include(Result, ssShift);
end;

function NavigationKey(Key: Word): Boolean;
begin
  Result := Key in [VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, VK_HOME, VK_END];
end;

{ Utility }

procedure DrawArrow(Canvas: TCanvas; const Dest: TRect; SortKind: TNxSortKind; AColor: TColor);
const
  ArrowWidth = 6;
  ArrowHeight = 3;
var
  ArrowPos: TPoint;
  ArrowSize: TSize;
begin
  ArrowSize := Size(ArrowWidth, ArrowHeight);
  ArrowSize := DotToPixel(ArrowSize);

  ArrowPos.X := Dest.Left + RectWidth(Dest) div 2 - ArrowSize.cx div 2;
  ArrowPos.Y := Dest.Top + RectHeight(Dest) div 2 - ArrowSize.cy div 2 - 1;

  with Canvas, ArrowPos do
  begin
    Pen.Color := AColor;
    Brush.Color := Pen.Color;
    case SortKind of
      skAscending:
        Polygon([
          Point(X, Y + ArrowSize.cy),
          Point(X + ArrowSize.cx div 2, Y),
          Point(X + ArrowSize.cx, Y + ArrowSize.cy)
        ]);
      skDescending:
        Polygon([
          Point(X, Y),
          Point(X + ArrowSize.cx div 2, Y + ArrowSize.cy),
          Point(X + ArrowSize.cx, Y)
        ]);
    end;
  end;
end;

procedure PaintUserStyledButton(Canvas: TCanvas; ButtonRect: TRect; ButtonState: TNxButtonState;
  ColorPalette: TNxUserDefinedColorPalette);
begin
  with Canvas, ColorPalette do
  begin
    Brush.Color := ButtonColor;
    if bsHover in ButtonState then Brush.Color := ButtonHoverColor;
    if bsPressed in ButtonState then Brush.Color := ButtonPressedColor;
    FillRect(ButtonRect);
  end;
end;

{ TNxCustomEdit6 }

procedure TNxCustomEdit6.AlignControls(AControl: TControl; var Rect: TRect);
begin
  inherited;
  UpdateAll;
end;

procedure TNxCustomEdit6.Assign(Source: TPersistent);
begin
  inherited;
  if Source is TNxCustomEdit6 then
  begin
    Alignment := TNxCustomEdit6(Source).Alignment;
    EditOptions := TNxCustomEdit6(Source).EditOptions;
    Padding.Assign(TNxCustomEdit6(Source).Padding);
    ShowPreview := TNxCustomEdit6(Source).ShowPreview;
    ValidationResult := TNxCustomEdit6(Source).ValidationResult;
    ValidationTriggers := TNxCustomEdit6(Source).ValidationTriggers;
    WantReturns := TNxCustomEdit6(Source).WantReturns;
    WantTabs := TNxCustomEdit6(Source).WantTabs;
  end;
end;

procedure TNxCustomEdit6.AssignValue(Source: INxBase);
begin
  AsString := Source.AsString;
end;

procedure TNxCustomEdit6.BeginEdit;
begin
  FInplaceEdit := True;
  { 8.4.2018: Added AutoSelect instead of
              SelStart := Lenght(Text). }
  AutoSelect := True;
  AutoSize := False;
  BorderStyle := bsNone;
  ParentColor := True;
  WantTabs := True;
end;

procedure TNxCustomEdit6.BeginEdit(Key: WideChar);
begin
  Text := '';

  BeginEdit; { Overloaded Method }

  AutoSelect := False;

  SendMessage(Handle, WM_CHAR, Ord(Key), 0);

  { Move Caret to last Pos. }
  SelStart := Length(Text);
end;

function TNxCustomEdit6.CanDispatchKey(Key: Word): Boolean;
begin
  { Default }
  Result := True;

  case Key of
    VK_LEFT, VK_RIGHT, VK_HOME, VK_END, VK_DELETE, VK_BACK: Result := False;
    VK_DOWN, VK_UP: Result := not (ssAlt in ShiftState);
  end;
end;

function TNxCustomEdit6.CanStyle(Option: TNxStyleOption): Boolean;
begin
  case Option of
    soVCLStyles:
    begin
      Result := False;
      if not(csDesigning in ComponentState) then
        if (soVCLStyles in FStyleOptions) then
        begin
          Result := SupportStyle([soVCLStyles]);
        end;
    end;
    soNativeStyles: Result := (soNativeStyles in FStyleOptions) and Themed;

    else Result := False;
  end;
end;

procedure TNxCustomEdit6.Change;
begin
  inherited;
  if HandleAllocated then RefreshPreview;
end;

procedure TNxCustomEdit6.ChangeStyle(const Value: TNxAppearanceStyle);
begin

end;

procedure TNxCustomEdit6.CMPaste(var Msg: TMessage);
begin
  if edPaste in EditOptions then
  begin

    inherited;
  end;
end;

procedure TNxCustomEdit6.CMTextChanged(var Message: TMessage);
begin
  inherited;
  if HandleAllocated then RefreshPreview;
  if vtTextChanged in ValidationTriggers then Validate(Text);
end;

constructor TNxCustomEdit6.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle := ControlStyle + [csAcceptsControls];

  { Init. fields }
  FAlignment := taLeftJustify;
  FCanvas := TControlCanvas.Create;
  TControlCanvas(FCanvas).Control := Self;
  FEditOptions := [edPaste, edTyping];
  FInplaceEdit := False;
  FNCLButtonDown := False;
  FPadding := TPadding.Create(Self);
  FPadding.OnChange := DoPaddingChange;
  FShowPreview := False;
  FStyleOptions := [soVCLStyles, soNativeStyles];
  FUserDefinedColorPalette := TNxUserDefinedColorPalette.Create;
  FUserDefinedColorPalette.OnChanged := DoUserDefinedColorPaletteChanged;
  FValidationResult := vrUnchecked;
  FValidationTriggers := [];
  FValidator := nil;
  FWantReturns := False;
  FWantTabs := False;
end;

procedure TNxCustomEdit6.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := Params.Style or (ES_AUTOHSCROLL or ES_AUTOVSCROLL)
  	or WS_CLIPCHILDREN or AlignmentStyles[FAlignment];
end;

procedure TNxCustomEdit6.CreateWnd;
begin
  inherited;

  { Update Editing area }
  UpdateEditRect;
end;

{$IFDEF DPI_SCALING_FLAGS}
function TNxCustomEdit6.DefaultScalingFlags: TScalingFlags;
begin
  if not InplaceEdit then Result := []
    else inherited;
end;
{$ENDIF}

destructor TNxCustomEdit6.Destroy;
begin
  FreeAndNil(FCanvas);
  FreeAndNil(FPadding);
  FreeAndNil(FUserDefinedColorPalette);
  inherited;
end;

procedure TNxCustomEdit6.DoExit;
begin
  inherited;
  if vtLeave in ValidationTriggers then Validate(Text);
end;

procedure TNxCustomEdit6.DoPaddingChange(Sender: TObject);
begin
  UpdateEditRect;
  UpdateNCRect;
end;

procedure TNxCustomEdit6.DoUserDefinedColorPaletteChanged(Sender: TObject);
begin

end;

procedure TNxCustomEdit6.DoValidate(Sender: TObject;
  const Text: WideString; var Result: TNxValidationResult);
begin
  if Assigned(FOnValidateEvent) then FOnValidateEvent(Self, Text, Result);
end;

procedure TNxCustomEdit6.EndEdit;
begin

end;

function TNxCustomEdit6.GetAlignment: TAlignment;
begin
  Result := FAlignment;
end;

function TNxCustomEdit6.GetAsBoolean: Boolean;
begin
  Result := Text = '1';
end;

function TNxCustomEdit6.GetAsDateTime: TDateTime;
begin
  Result := StrToDateTimeDef(GetAsString, 0.0);
end;

function TNxCustomEdit6.GetAsFloat: Double;
begin
  Result := StrToFloatDef(GetAsString, 0);
end;

function TNxCustomEdit6.GetAsInteger: Integer;
begin
  Result := StrToIntDef(Text, 0);
end;

function TNxCustomEdit6.GetAsString: WideString;
begin
  Result := Text;
end;

function TNxCustomEdit6.GetEditOptions: TNxEditOptions;
begin
  Result := FEditOptions;
end;

function TNxCustomEdit6.GetEditRect: TRect;
const
  IndentBorder: array[Boolean] of Integer = (0, 2);
begin
  Result := ClientRect;
  OffsetRect(Result, IndentBorder[BorderStyle = bsSingle],
    IndentBorder[BorderStyle = bsSingle]);
  OffsetRect(Result, Padding.Left, Padding.Top);

  with GetEditMargins do
  begin
    Inc(Result.Left, Leading);
    if ShowPreview then Dec(Result.Right)
      else Dec(Result.Right, Trailing);
  end;

  if ShowPreview then
  begin
    Result.Left := IndentBorder[BorderStyle = bsSingle] + szPreviewWidth + pdStandard + 1;
  end;
end;

function TNxCustomEdit6.GetHandle: HWND;
begin
  Result := inherited Handle;
end;

function TNxCustomEdit6.GetEditMargins: TEditMargins;
var
  M: LRESULT;
begin
  M := SendMessage(Handle, EM_GETMARGINS, 0, 0);
  Result.Leading := M and $0000FFFF;
  Result.Trailing := (M and $FFFF0000) shr 16;
end;

function TNxCustomEdit6.GetOnAssignEditing: TNotifyEvent;
begin
  Result := FOnAssignEditing;
end;

function TNxCustomEdit6.GetOnChange: TNotifyEvent;
begin
  Result := OnChange;
end;

function TNxCustomEdit6.GetOnPreviewDraw: TNxPreviewDrawEvent;
begin
  Result := FOnPreviewDraw;
end;

function TNxCustomEdit6.GetPadding: TPadding;
begin
  Result := FPadding;
end;

function TNxCustomEdit6.GetPreviewRect: TRect;
const
  IndentBorder: array[Boolean] of Integer = (0, 2);
begin
  GetWindowRect(Handle, Result);

  { Required }
  OffsetRect(Result, -Result.Left, -Result.Top);

  { Edit's border inflation }
  InflateRect(Result, -IndentBorder[BorderStyle = bsSingle], -IndentBorder[BorderStyle = bsSingle]);

  { Spacing inflation }
  InflateRect(Result, -1, -1);

  Result.Right := Result.Left + szPreviewWidth;
end;

function TNxCustomEdit6.GetShowing: Boolean;
begin
  Result := inherited Showing;
end;

function TNxCustomEdit6.GetStyleOptions: TNxStyleOptions;
begin
  Result := FStyleOptions;
end;

function TNxCustomEdit6.GetTagString: string;
begin
  Result := FTagString;
end;

function TNxCustomEdit6.GetText: string;
begin
  Result := Text;
end;

function TNxCustomEdit6.GetWantReturns: Boolean;
begin
  Result := FWantReturns;
end;

function TNxCustomEdit6.GetWantTabs: Boolean;
begin
  Result := FWantTabs;
end;

function TNxCustomEdit6.HasValidation: Boolean;
begin
  Result := ValidationTriggers <> [];
end;

procedure TNxCustomEdit6.InvalidateControls;
var
  i: Integer;
begin
  for i := 0 to ControlCount - 1 do Controls[i].Invalidate;
end;

procedure TNxCustomEdit6.InvalidateNC;
var
  R: TRect;
begin
  R := ClientRect;
  InflateRect(R, -1, -1);
  RedrawWindow(Handle, @R, 0, RDW_FRAME or RDW_INVALIDATE);
end;

procedure TNxCustomEdit6.KeyDown(var Key: Word; Shift: TShiftState);
begin
  if (edTyping in EditOptions)
    or NavigationKey(Key) then
  begin
    inherited;
  end;
end;

procedure TNxCustomEdit6.KeyUp(var Key: Word; Shift: TShiftState);
begin
  inherited;
  if vtTyping in ValidationTriggers then Validate(Text);
end;

procedure TNxCustomEdit6.PaintNC;
begin
  PaintNCPadding;
  if BorderStyle = bsSingle then PaintNCValidation;
end;

procedure TNxCustomEdit6.PaintNCPadding;
var
  Device: HDC;
  Pen: HPEN;
  i: Integer;
  P: array[0..2] of TPoint;
  function BorderSize: Integer;
  begin
    Result := IfThen(BorderStyle = bsSingle, 1, 0);
  end;
begin
  if BorderStyle = bsNone then Exit;
  Device := GetWindowDC(Handle);
  try
    Pen := CreatePen(PS_SOLID, 1, ColorToRGB(Color));
    try
      { Top NC Area }
      SelectObject(Device, Pen);
      for i := BorderSize to Padding.Top do
      begin
        P[0] := Point(0, i);
        P[1] := Point(ClientWidth, i);
        Polyline(Device, P, 2);
      end;
    finally
      DeleteObject(Pen);
    end;
  finally
    ReleaseDC(Handle, Device);
  end;
end;

procedure TNxCustomEdit6.PaintNCValidation;
var
  DC: HDC;
  Pen: HPEN;
  IndicatorRect: TRect;
  IndicatorColor: TColor;
begin
  case ValidationResult of
    vrValid: IndicatorColor := clValidColor;
    vrInvalid: IndicatorColor := clInvalidColor;
    else IndicatorColor := Color;
  end;

  DC := GetWindowDC(Handle);
  try
    Pen := CreatePen(PS_SOLID, 1, ColorToRGB(IndicatorColor));
    try
      IndicatorRect := Rect(0, 0, Width, Height);

      InflateRect(IndicatorRect, -1, -1);

      SelectObject(DC, Pen);
      SelectObject(DC, GetStockObject(NULL_BRUSH));

      Rectangle(DC, IndicatorRect.Left, IndicatorRect.Top,
        IndicatorRect.Right, IndicatorRect.Bottom);
    finally
      DeleteObject(Pen);
    end;
  finally
    ReleaseDC(Handle, DC);
  end;
end;

procedure TNxCustomEdit6.PaintPreview;
var
  R, R1: TRect;
begin
  R := PreviewRect;

  { Erase spacing }
  R1 := R;
  InflateRect(R1, 1, 1);
  Canvas.Brush.Color := Color;
  Canvas.FrameRect(R1);
  Canvas.Pen.Color := Color;
  Canvas.Polyline([
    Point(R1.Right, R1.Top),
    Point(R1.Right, R1.Bottom)
  ]);

  { Paint Preview border }
  Canvas.Brush.Color := clGray;
  Canvas.FrameRect(R);

  { Exclude border }
  InflateRect(R, -1, -1);

  PaintPreviewContent(R);
end;

procedure TNxCustomEdit6.PaintPreviewContent(PreviewRect: TRect);
begin
  { Event }
  if Assigned(FOnPreviewDraw) then FOnPreviewDraw(Self, PreviewRect);
end;

procedure TNxCustomEdit6.PaintWindow(DC: HDC);
begin
  inherited;

end;

procedure TNxCustomEdit6.RefreshPreview;
var
  R: TRect;
begin
  if ShowPreview then
  begin
    R := PreviewRect;
    InflateRect(R, -1, -1);
    RedrawWindow(Handle, @R, 0, RDW_FRAME or RDW_INVALIDATE);
  end;
end;

procedure TNxCustomEdit6.SetAlignment(const Value: TAlignment);
begin
  FAlignment := Value;
  RecreateWnd; { CreateParams }
end;

procedure TNxCustomEdit6.SetAsBoolean(const Value: Boolean);
begin
  AsString := BoolToStr(Value, True);
end;

procedure TNxCustomEdit6.SetAsDateTime(const Value: TDateTime);
begin
  AsString := DateTimeToStr(Value);
end;

procedure TNxCustomEdit6.SetAsFloat(const Value: Double);
begin
  AsString := FloatToStr(Value);
end;

procedure TNxCustomEdit6.SetAsInteger(const Value: Integer);
begin
  AsString := IntToStr(Value);
end;

procedure TNxCustomEdit6.SetAsString(const Value: WideString);
begin
  Text := Value;
end;

procedure TNxCustomEdit6.SetAutoSelect(const Value: Boolean);
begin
  AutoSelect := Value;
end;

procedure TNxCustomEdit6.SetColor(const Value: TColor);
begin
  inherited Color := Value;
end;

procedure TNxCustomEdit6.SetEditOptions(const Value: TNxEditOptions);
begin
  FEditOptions := Value;
end;

procedure TNxCustomEdit6.SetEditPadding(const Leading, Trailing: Integer);
begin
  FEditPadding.Leading := Leading;
  FEditPadding.Trailing := Trailing;
end;

procedure TNxCustomEdit6.SetEnabled(Value: Boolean);
begin
  inherited;
end;

procedure TNxCustomEdit6.SetFont(const Value: TFont);
begin
  Font := Value;
end;

procedure TNxCustomEdit6.SetOnAssignEditing(const Value: TNotifyEvent);
begin
  FOnAssignEditing := Value;
end;

procedure TNxCustomEdit6.SetOnChange(const Value: TNotifyEvent);
begin
  OnChange := Value;
end;

procedure TNxCustomEdit6.SetOnPreviewDraw(const Value: TNxPreviewDrawEvent);
begin
  FOnPreviewDraw := Value;
end;

procedure TNxCustomEdit6.SetPadding(const Value: TPadding);
begin
  FPadding.Assign(Value);
  FPadding.OnChange := DoPaddingChange;
end;

procedure TNxCustomEdit6.SetReadOnly(const Value: Boolean);
begin
  ReadOnly := Value;
end;

procedure TNxCustomEdit6.SetShowPreview(const Value: Boolean);
begin
  if Value <> FShowPreview then
  begin
    FShowPreview := Value;
    UpdateNCRect;
  end;
end;

procedure TNxCustomEdit6.SetStyleOptions(const Value: TNxStyleOptions);
begin
  if Value <> FStyleOptions then
  begin
    FStyleOptions := Value;
    Invalidate;
    InvalidateControls;
  end;
end;

procedure TNxCustomEdit6.SetTagString(const Value: string);
begin
  FTagString := Value;
end;

procedure TNxCustomEdit6.SetText(const Value: string);
begin
  Text := Value;
end;

procedure TNxCustomEdit6.SetUserDefinedColorPalette(
  const Value: TNxUserDefinedColorPalette);
begin
  if Value <> FUserDefinedColorPalette then
  begin
    FUserDefinedColorPalette.Assign(Value);
    DoUserDefinedColorPaletteChanged(FUserDefinedColorPalette);
  end;
end;

procedure TNxCustomEdit6.SetValidationResult(const Value: TNxValidationResult);
begin
  if Value <> FValidationResult then
  begin
    FValidationResult := Value;
    InvalidateNC;
  end;
end;

procedure TNxCustomEdit6.SetWantReturns(const Value: Boolean);
begin
  FWantReturns := Value;
end;

procedure TNxCustomEdit6.SetWantTabs(const Value: Boolean);
begin
  FWantTabs := Value;
end;

procedure TNxCustomEdit6.UpdateAll;
begin
  UpdateEditRect;
end;

procedure TNxCustomEdit6.UpdateEditRect;
var
  i, lw, rw: Integer;
begin
  if HandleAllocated then
  begin
    lw := FEditPadding.Leading;
    for i := 0 to Pred(ControlCount) do
      if Controls[i].Visible and (Controls[i].Align = alLeft) then
        Inc(lw, Controls[i].Width);

    rw := FEditPadding.Trailing;
    for i := 0 to Pred(ControlCount) do
      if Controls[i].Visible and (Controls[i].Align = alRight) then
        Inc(rw, Controls[i].Width);

    SendMessage(Handle, EM_SETMARGINS, EC_LEFTMARGIN or EC_RIGHTMARGIN,
      MAKEWPARAM(lw, rw));
  end;
end;

procedure TNxCustomEdit6.UpdateNCRect;
begin
  { Invoke WM_NCCALCSIZE }
  if HandleAllocated then
  begin
    SetWindowPos(Handle, 0, Left, Top, Width, Height, SWP_FRAMECHANGED or SWP_NOREPOSITION);
  end;
end;

function TNxCustomEdit6.Validate(const Value: WideString): TNxValidationResult;
begin
  inherited;
  Result := vrUnchecked;

  { Has Validator }
  if Assigned(Validator) then
  begin
    Result := Validator.Validate(Self as INxValidatable);
  end;

  { Event }
  DoValidate(Self, Value, Result);

  { Set Property }
  ValidationResult := Result;
end;

procedure TNxCustomEdit6.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
  inherited;
  if WantTabs then Message.Result := Message.Result or DLGC_WANTTAB
    else Message.Result := Message.Result and not DLGC_WANTTAB;
  if WantReturns then Message.Result := Message.Result or DLGC_WANTALLKEYS;
end;

procedure TNxCustomEdit6.WMNCActivate(var Msg: TWMNCActivate);
begin
  inherited;
  PaintPreview;
end;

procedure TNxCustomEdit6.WMNCCalcSize(var Message: TWMNCCalcSize);
var
  Params: PNCCalcSizeParams;
begin
  inherited;
  Params := Message.CalcSize_Params;
  with Params^ do
  begin
// It's already done in inherited
// InflateRect(rgrc[0], -Integer(BorderWidth), -Integer(BorderWidth));
    with rgrc[0] do
    begin
      Inc(Left, Padding.Left);
      if ShowPreview then Inc(Left, szPreviewWidth + pdStandard + 1);
      Inc(Top, Padding.Top);
      Dec(Right, Padding.Right);
      Dec(Bottom, Padding.Bottom);
      if HasValidation then
      begin
        InflateRect(rgrc[0], -1, -1);
      end;
    end;
  end;
end;

procedure TNxCustomEdit6.WMNCLButtonDown(var Message: TWMNCLButtonDown);
begin
  inherited;
  if PtInRect(PreviewRect, Point(Message.XCursor, Message.YCursor)) then
  begin
    FNCLButtonDown := True;
  end;
end;

procedure TNxCustomEdit6.WMNCLButtonUp(var Message: TWMNCLButtonUp);
begin
  inherited;
  if FNCLButtonDown and PtInRect(PreviewRect, Point(Message.XCursor, Message.YCursor)) then
    if Assigned(FOnPreviewClick) then FOnPreviewClick(Self);

  FNCLButtonDown := False;
end;

procedure TNxCustomEdit6.WMNCPaint(var Message: TWMNCPaint);
begin
  inherited;
  PaintNC;
  FCanvas.Lock;
  try
    FCanvas.Handle := GetWindowDC(Handle);
    try
      if ShowPreview then PaintPreview;
    finally
      FCanvas.Handle := 0;
    end;
  finally
    FCanvas.Unlock;
  end;
end;

procedure TNxCustomEdit6.WMSize(var Message: TWMSize);
begin
  inherited;

  { Update editing area }
  UpdateEditRect;
end;

{ TNxMemo6 }

procedure TNxMemo6.BeginEdit;
begin
  BorderStyle := bsNone;
  SelStart := Length(Text);
  WantArrows := True;
  WantTabs := True;
  WantReturns := True;
end;

procedure TNxMemo6.AssignValue(Source: INxBase);
begin
  Text := Source.AsString;
end;

procedure TNxMemo6.BeginEdit(Key: WideChar);
begin
  { ToDo: Add Prepare protected Method }
  BeginEdit; { Overloaded Method }

  AutoSelect := False;

  SendMessage(Handle, WM_CHAR, Ord(Key), 0);

  { Move Caret to last Pos. }
  SelStart := Length(Text);
end;

function TNxMemo6.CanDispatchKey(Key: Word): Boolean;
  function CanDispatchArrow: Boolean;
  begin
    Result := ((Key = VK_DOWN) and (CaretPos.Y >= Pred(LinesCount)))
      or ((Key = VK_UP) and (CaretPos.Y = 0));
  end;
begin
  { Default }
  Result := True;

  case Key of
    VK_RETURN: Result := not FWantReturns;
    VK_LEFT..VK_DOWN: Result := CanDispatchArrow or not FWantArrows;
  end;
end;

constructor TNxMemo6.Create(AOwner: TComponent);
begin
  inherited;
  FAlignment := taLeftJustify;
  FEditOptions := [edPaste, edTyping];
  FPadding := TPadding.Create(Self);
  FWantArrows := False;
  FWantReturns := False;
  FWantTabs := False;
end;

destructor TNxMemo6.Destroy;
begin
  FreeAndNil(FPadding);
  inherited;
end;

procedure TNxMemo6.EndEdit;
begin

end;

function TNxMemo6.GetAlignment: TAlignment;
begin
  Result := FAlignment;
end;

function TNxMemo6.GetAsBoolean: Boolean;
begin
  Result := False;
end;

function TNxMemo6.GetAsDateTime: TDateTime;
begin
  Result := 0;
end;

function TNxMemo6.GetAsFloat: Double;
begin
  Result := StrToFloatDef(GetAsString, 0);
end;

function TNxMemo6.GetAsInteger: Integer;
begin
  Result := StrToIntDef(GetAsString, 0);
end;

function TNxMemo6.GetAsString: WideString;
begin
  Result := Text;
end;

function TNxMemo6.GetColor: TColor;
begin
  Result := inherited Color;
end;

function TNxMemo6.GetEditOptions: TNxEditOptions;
begin
  Result := FEditOptions;
end;

function TNxMemo6.GetEnabled: Boolean;
begin
  Result := inherited GetEnabled;
end;

function TNxMemo6.GetHandle: HWND;
begin
  Result := inherited Handle;
end;

function TNxMemo6.GetLinesCount: Integer;
begin
  Result := 0;
  if HandleAllocated or (WindowText <> nil) then
  begin
    Result := SendMessage(Handle, EM_GETLINECOUNT, 0, 0);
    if SendMessage(Handle, EM_LINELENGTH, SendMessage(Handle,
      EM_LINEINDEX, Result - 1, 0), 0) = 0 then Dec(Result);
  end;
end;

function TNxMemo6.GetOnAssignEditing: TNotifyEvent;
begin

end;

function TNxMemo6.GetOnChange: TNotifyEvent;
begin
  Result := OnChange;
end;

function TNxMemo6.GetPadding: TPadding;
begin
  Result := FPadding;
end;

function TNxMemo6.GetShowing: Boolean;
begin
  Result := inherited Showing;
end;

function TNxMemo6.GetText: string;
begin
  Result := Text;
end;

function TNxMemo6.GetWantTabs: Boolean;
begin
  Result := FWantTabs;
end;

procedure TNxMemo6.SetAlignment(const Value: TAlignment);
begin
  FAlignment := Value;
end;

procedure TNxMemo6.SetAsBoolean(const Value: Boolean);
begin
  Text := BoolToStr(Value, True);
end;

procedure TNxMemo6.SetAsDateTime(const Value: TDateTime);
begin
  Text := DateTimeToStr(Value);
end;

procedure TNxMemo6.SetAsFloat(const Value: Double);
begin
  Text := FloatToStr(Value);
end;

procedure TNxMemo6.SetAsInteger(const Value: Integer);
begin
  Text := IntToStr(Value);
end;

procedure TNxMemo6.SetAsString(const Value: WideString);
begin
  Text := Value;
end;

procedure TNxMemo6.SetAutoSelect(const Value: Boolean);
begin
  AutoSelect := Value;
end;

procedure TNxMemo6.SetColor(const Value: TColor);
begin
  inherited Color := Value;
end;

procedure TNxMemo6.SetEditOptions(const Value: TNxEditOptions);
begin
  FEditOptions := Value;
end;

procedure TNxMemo6.SetEditPadding(const Leading, Trailing: Integer);
begin
end;

procedure TNxMemo6.SetEnabled(Value: Boolean);
begin
  inherited;
end;

procedure TNxMemo6.SetFont(const Value: TFont);
begin
  Font := Value;
end;

procedure TNxMemo6.SetOnAssignEditing(const Value: TNotifyEvent);
begin

end;

procedure TNxMemo6.SetOnChange(const Value: TNotifyEvent);
begin
  OnChange := Value;
end;

procedure TNxMemo6.SetPadding(const Value: TPadding);
begin
  FPadding.Assign(Value);
end;

procedure TNxMemo6.SetReadOnly(const Value: Boolean);
begin
  ReadOnly := Value;
end;

procedure TNxMemo6.SetText(const Value: string);
begin
  Text := Value;
end;

procedure TNxMemo6.SetWantTabs(const Value: Boolean);
begin
  FWantTabs := Value;
end;

procedure TNxMemo6.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
  inherited;
  { Arrows }
  if WantArrows then Message.Result := Message.Result or DLGC_WANTARROWS;

  { Tab Key }
  if WantTabs then Message.Result := Message.Result or DLGC_WANTTAB
    else Message.Result := Message.Result and not DLGC_WANTTAB;

  { Enter Key }
  if WantReturns then Message.Result := Message.Result or DLGC_WANTALLKEYS;
end;

procedure TNxMemo6.WMNCCalcSize(var Message: TWMNCCalcSize);
var
  Params: PNCCalcSizeParams;
begin
  inherited;
  Params := Message.CalcSize_Params;
  with Params^ do
  begin
    InflateRect(rgrc[0], -Integer(BorderWidth), -Integer(BorderWidth));
    with rgrc[0] do
    begin
      Inc(Left, Padding.Left);
      Inc(Top, Padding.Top);
      Dec(Right, Padding.Right);
      Dec(Bottom, Padding.Bottom);

      { Windows add it }
      if BorderStyle = bsNone then Dec(Left, 2);
    end;
  end;
end;

{ TNxNumberEdit6 }

procedure TNxNumberEdit6.AdjustValueToRange(var Value: Double);
begin
  if CheckRange then
  begin
    if Value > FMax then Value := FMax;
    if Value < FMin then Value := FMin;
  end;
end;

procedure TNxNumberEdit6.Assign(Source: TPersistent);
begin
  inherited;
  if Source is TNxNumberEdit6 then
  begin
    AdjustToRange := TNxNumberEdit6(Source).AdjustToRange;
    HideLeadingZeros := TNxNumberEdit6(Source).HideLeadingZeros;
    Max := TNxNumberEdit6(Source).Max;
    Min := TNxNumberEdit6(Source).Min;
    NumericEditOptions := TNxNumberEdit6(Source).NumericEditOptions;
    Precision := TNxNumberEdit6(Source).Precision;
    TextAfter := TNxNumberEdit6(Source).TextAfter;
  end;
end;

procedure TNxNumberEdit6.AssignValue(Source: INxBase);
begin
  AsFloat := Source.AsFloat;
end;

function TNxNumberEdit6.CheckRange: Boolean;
begin
  Result := (FMax <> 0) or (FMin <> 0);
end;

procedure TNxNumberEdit6.CMPaste(var Msg: TMessage);
var
  ClientText, NewText, ClipboardText: string;
  OldSelStart: Integer;
  AAllowDecimal, AAllowSigns: Boolean;
begin
  OldSelStart := SelStart;
  if Clipboard.HasFormat(CF_TEXT)
    then ClipboardText := Clipboard.AsText
      else ClipboardText := '';

  ClientText := Text;
  Delete(ClientText, SelStart + 1, SelLength);

  { Set flags and get valid text }
  AAllowDecimal := (ednDecimals in FNumericEditOptions) and (Pos(LocalSettings.DecimalSeparator, ClientText) = 0);
  AAllowSigns := (ednSigns in FNumericEditOptions) and (SelStart = 0);
  NewText := GetValidText(ClipboardText, AAllowSigns, AAllowDecimal);

  Insert(NewText, ClientText, SelStart + 1);

  Text := ClientText;
  SelStart := OldSelStart;
end;

constructor TNxNumberEdit6.Create(AOwner: TComponent);
begin
  inherited;
  FAdjustToRange := True;
  FHideLeadingZeros := False;
  FMax := 0;
  FMin := 0;
  FNumericEditOptions := [ednDecimals, ednSigns];
  FPrecision := 2;

  Value := 0;
end;

procedure TNxNumberEdit6.EndEdit;
begin
  SetValueToText(Value);
end;

function TNxNumberEdit6.GetAsFloat: Double;
begin
  Result := Value;
end;

function TNxNumberEdit6.GetAsInteger: Integer;
begin
  Result := Round(Value);
end;

function TNxNumberEdit6.GetAsString: WideString;
begin
  Result := FloatToStr(Value);
end;

function TNxNumberEdit6.GetFormatedValue(AValue: Double; Append: Boolean): WideString;
begin
  if ednDecimals in FNumericEditOptions then
  begin
    if FPrecision > 0 then
      Result := FloatToStrF(AValue, ffFixed, 18, FPrecision)
        else Result := FloatToStr(AValue);
  end else Result := FloatToStrF(AValue, ffFixed, 18, 0);

  if Append then
  begin
    { Include TextAfter }
    Result := Concat(Result, FTextAfter);
  end;

  if HideLeadingZeros then
  begin
    Result := DeleteLeadingZeros(Result);
  end;
end;

function TNxNumberEdit6.GetMax: Double;
begin
  Result := FMax;
end;

function TNxNumberEdit6.GetMin: Double;
begin
  Result := FMin;
end;

function TNxNumberEdit6.GetNumericEditOptions: TNxNumericEditOptions;
begin
  Result := FNumericEditOptions;
end;

function TNxNumberEdit6.GetPrecision: Integer;
begin
  Result := FPrecision;
end;

function TNxNumberEdit6.GetTextAfter: WideString;
begin
  Result := FTextAfter;
end;

function TNxNumberEdit6.GetValidText(UnCheckedText: string; AAllowSign, AAllowDecimal: Boolean): string;
var
  i: Integer;
  CanInc: Boolean;
  HaveDecimalSeparator: Boolean;
  BoundValue: Double;
begin
  i := 1;
  CanInc := True;
  HaveDecimalSeparator := False;
  repeat
    if CharInSet(UnCheckedText[i], ['0'..'9', LocalSettings.DecimalSeparator, '-', '+', #8]) then
    begin

      { Decimal Separator }
      if UnCheckedText[i] = LocalSettings.DecimalSeparator then
      begin
        if not AAllowDecimal or HaveDecimalSeparator then
        begin
          Delete(UnCheckedText, i, 1);
          CanInc := False;
        end;
        if not HaveDecimalSeparator then HaveDecimalSeparator := True;
      end;

      { Signs }
      if CharInSet(UnCheckedText[i], ['-', '+']) then
      begin
        if not AAllowSign or (i > 1) then
        begin
          Delete(UnCheckedText, i, 1);
          CanInc := False;
        end;

      end;

      if CanInc then Inc(i) else if not CanInc then CanInc := not CanInc;

    end else Delete(UnCheckedText, i, 1)

  until i = Length(UnCheckedText) + 1;

  if (UnCheckedText = '-') or (UnCheckedText = '+')
    then UnCheckedText := '0';

  Result := UnCheckedText;

  { Set using Max and Min }
  if Result <> '' then
  begin
    BoundValue := StrToFloat(Result);
    if FAdjustToRange then
      AdjustValueToRange(BoundValue);
  end else BoundValue := FMin;

  Result := FloatToStr(BoundValue);

  if HideLeadingZeros then
  begin
    Result := DeleteLeadingZeros(Result);
  end;
end;

function TNxNumberEdit6.GetValue: Double;
var
  ValidText: string;
begin
  if Text = EmptyStr then Result := FMin else
  begin
    ValidText := GetValidText(Text, ednSigns in FNumericEditOptions, ednDecimals in FNumericEditOptions);
    if ValidText = '' then ValidText := FloatToStr(Min);
    if TryStrToFloat(ValidText, Result) then
    begin
      if FAdjustToRange then
      begin
        AdjustValueToRange(Result);
      end;
    end else Result := FMin;
  end;
end;

procedure TNxNumberEdit6.SetAsFloat(const Value: Double);
begin
  Self.Value := Value;
end;

procedure TNxNumberEdit6.SetAsInteger(const Value: Integer);
begin
  Self.Value := Value;
end;

procedure TNxNumberEdit6.SetHideLeadingZeros(const Value: Boolean);
begin
  if Value <> FHideLeadingZeros then
  begin
    FHideLeadingZeros := Value;
    SetValueToText(Self.Value);
  end;
end;

procedure TNxNumberEdit6.SetMax(const Value: Double);
begin
  FMax := Value;
end;

procedure TNxNumberEdit6.SetMin(const Value: Double);
begin
  FMin := Value;
end;

procedure TNxNumberEdit6.SetNumericEditOptions(const Value: TNxNumericEditOptions);
begin
  if Value <> FNumericEditOptions then
  begin
    FNumericEditOptions := Value;

    { Trim decimals }
    SetValueToText(Self.Value);
  end;
end;

procedure TNxNumberEdit6.SetPrecision(const Value: Integer);
begin
  if Value <> FPrecision then
  begin
    FPrecision := Value;

    { Trim decimals }
    SetValueToText(Self.Value);
  end;
end;

procedure TNxNumberEdit6.SetTextAfter(const Value: WideString);
begin
  if Value <> FTextAfter then
  begin
    FTextAfter := Value;
    SetValueToText(Self.Value);
  end;
end;

procedure TNxNumberEdit6.SetValue(const Value: Double);
begin
  SetValueToText(Value);
end;

procedure TNxNumberEdit6.SetValueToText(SendValue: Double);
begin
  Text := GetFormatedValue(SendValue);
end;

procedure TNxNumberEdit6.WMKillFocus(var Msg: TWMKillFocus);
begin
  inherited;
  SetValueToText(Value);
end;

procedure TNxNumberEdit6.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;

end;

{ TMrSpinButtons }

constructor TNxSpinButtons.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FDelayInterval := inSlowInterval;
  FPressedButtons := [];
  FHoverButtons := [];
  FRepeatTimer := TTimer.Create(Self);
  FRepeatTimer.OnTimer := DoRepeatTimer;
  FRepeatTimer.Interval := inFastInterval;
  FRepeatTimer.Enabled := False;
  FDelayTimer := TTimer.Create(Self);
  FDelayTimer.OnTimer := DoDelayTimer;
  FDelayTimer.Interval := FDelayInterval;
  FDelayTimer.Enabled := False;
  FSpinButtonsStyle := stNative;
end;

destructor TNxSpinButtons.Destroy;
begin
  FreeAndNil(FRepeatTimer);
  FreeAndNil(FDelayTimer);
  inherited;
end;

{$IFDEF DPI_SCALING_FLAGS}
function TNxSpinButtons.DefaultScalingFlags: TScalingFlags;
begin
  Result := inherited;
end;
{$ENDIF}

procedure TNxSpinButtons.DoDelayTimer(Sender: TObject);
begin
  FRepeatTimer.Enabled := True;
end;

procedure TNxSpinButtons.DoRepeatTimer(Sender: TObject);
begin
  if Assigned(FOnSpin) then FOnSpin(Self, FPressedButtons); { spin value }
end;

procedure TNxSpinButtons.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  inherited;
  if Button = mbLeft then
  begin
    if Y < Height div 2
      then FPressedButtons := [sbUp]
      else FPressedButtons := [sbDown];
    FDelayTimer.Enabled := True;
    if Assigned(FOnSpin) then FOnSpin(Self, FPressedButtons);
    Invalidate;
  end;
end;

procedure TNxSpinButtons.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
  inherited;
  if Y < Height div 2	then HoverButtons := [sbUp] else HoverButtons := [sbDown];
end;

procedure TNxSpinButtons.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  inherited;
  FPressedButtons := [];
  FRepeatTimer.Enabled := False;
  FDelayTimer.Enabled := False;
  Invalidate;
end;

procedure TNxSpinButtons.Paint;
begin
  inherited;
  case FSpinButtonsStyle of
    stNative: PaintNativeStyle;
    stModern: PaintModernStyle;
    stUserDefined: PaintUserDefinedStyle;
  end;
end;

procedure TNxSpinButtons.PaintModernStyle;
var
  UpButtonState, DownButtonState: TNxButtonState;
  UpButtonRect, DownButtonRect: TRect;
begin
  { Up Button }
  UpButtonRect := Rect(0, 0, ClientWidth, (ClientHeight div 2));
  UpButtonState := [];
  if sbUp in FPressedButtons then Include(UpButtonState, bsPressed);
  if sbUp in FHoverButtons then Include(UpButtonState, bsHover);
  DrawModernButton(Canvas, UpButtonRect, UpButtonState);
  DrawArrow(Canvas, UpButtonRect, skAscending, clGray);

  { Down Button }
  DownButtonRect := Rect(0, ClientHeight div 2, ClientWidth, ClientHeight);
  DownButtonState := [];
  if sbDown in FPressedButtons then Include(DownButtonState, bsPressed);
  if sbDown in FHoverButtons then Include(DownButtonState, bsHover);
  DrawModernButton(Canvas, DownButtonRect, DownButtonState);
  DrawArrow(Canvas, DownButtonRect, skDescending, clGray);
end;

procedure TNxSpinButtons.PaintNativeStyle;
var
  DrawFlags, UpState, DownState: Integer;
  UpButtonRect, DownButtonRect: TRect;
  Theme: HTHEME;
begin
	if Themed then
 	begin
    Theme := OpenThemeData(TWinControl(Owner).Handle, teSpin);
    if TControl(Owner).Enabled then
    begin
      if sbUp in FPressedButtons then UpState := 3
        else if sbUp in FHoverButtons then UpState := 2
          else UpState := 1;
      if sbDown in FPressedButtons then DownState := 3
        else if sbDown in FHoverButtons then DownState := 2
          else DownState := 1;
    end else
    begin
      UpState := 4;
      DownState := 4;
    end;

    UpButtonRect := Rect(0, -1, ClientWidth + 1, (ClientHeight div 2));
    DownButtonRect := Rect(0, (ClientHeight div 2), ClientWidth + 1, ClientHeight + 1);

    DrawThemeBackground(Theme, Canvas.Handle, tcSpinUp, UpState, UpButtonRect, nil);
    DrawThemeBackground(Theme, Canvas.Handle, tcSpinDown, DownState, DownButtonRect, nil);
    CloseThemeData(Theme);
  end else
  begin
    UpButtonRect := Rect(0, -1, ClientWidth, (ClientHeight div 2));
    DownButtonRect := Rect(0, (ClientHeight div 2), ClientWidth, ClientHeight);

    DrawFlags := DFCS_SCROLLUP or DFCS_ADJUSTRECT;
    if sbUp in FPressedButtons then DrawFlags := DrawFlags or DFCS_PUSHED;
    if not TControl(Owner).Enabled then DrawFlags := DrawFlags or DFCS_INACTIVE;
    DrawFrameControl(Canvas.Handle, UpButtonRect, DFC_SCROLL, DrawFlags);

    DrawFlags := DFCS_SCROLLDOWN or DFCS_ADJUSTRECT;
    if not TControl(Owner).Enabled then DrawFlags := DrawFlags or DFCS_INACTIVE;
    if sbDown in FPressedButtons then DrawFlags := DrawFlags or DFCS_PUSHED;
    DrawFrameControl(Canvas.Handle, DownButtonRect, DFC_SCROLL, DrawFlags);
  end;
end;

procedure TNxSpinButtons.PaintUserDefinedStyle;
var
  UpButtonState, DownButtonState: TNxButtonState;
  UpButtonRect, DownButtonRect: TRect;
  procedure PaintButton(const BtnRect: TRect; const BtnState: TNxButtonState);
  begin
    with Canvas, UserDefinedColorPalette do
    begin
      Brush.Color := ButtonColor;
      if bsHover in BtnState then Brush.Color := ButtonHoverColor;
      if bsPressed in BtnState then Brush.Color := ButtonPressedColor;
      FillRect(BtnRect);
    end;
  end;
begin
  { Up Button }
  UpButtonRect := Rect(0, 0, ClientWidth, (ClientHeight div 2));
  UpButtonState := [];
  if sbUp in FPressedButtons then Include(UpButtonState, bsPressed);
  if sbUp in FHoverButtons then Include(UpButtonState, bsHover);
  PaintButton(UpButtonRect, UpButtonState);
  DrawArrow(Canvas, UpButtonRect, skAscending, UserDefinedColorPalette.GeometryColor);

  { Down Button }
  DownButtonRect := Rect(0, ClientHeight div 2, ClientWidth, ClientHeight);
  DownButtonState := [];
  if sbDown in FPressedButtons then Include(DownButtonState, bsPressed);
  if sbDown in FHoverButtons then Include(DownButtonState, bsHover);
  PaintButton(DownButtonRect, DownButtonState);
  DrawArrow(Canvas, DownButtonRect, skDescending, UserDefinedColorPalette.GeometryColor);
end;

procedure TNxSpinButtons.ChangeStyle(const Value: TNxAppearanceStyle);
begin
  SpinButtonsStyle := Value;
end;

procedure TNxSpinButtons.CMMouseLeave(var Message: TMessage);
begin
  FHoverButtons := [];
  Invalidate;
end;

procedure TNxSpinButtons.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
  Message.Result := 1;
end;

procedure TNxSpinButtons.SetDelayInterval(const Value: Integer);
begin
  FDelayInterval := Value;
  FDelayTimer.Interval := FDelayInterval;
end;

procedure TNxSpinButtons.SetHoverButtons(const Value: TNxSpinButton);
begin
  if csDesigning in ComponentState then Exit;
  if Value <> FHoverButtons then
  begin
    FHoverButtons := Value;
    Invalidate;
  end;
end;

procedure TNxSpinButtons.SetPressedButtons(const Value: TNxSpinButton);
begin
  if Value <> FPressedButtons then
  begin
    FPressedButtons := Value;
    if FPressedButtons <> [] then
    begin
      FDelayTimer.Enabled := True;
      if Assigned(FOnSpin) then FOnSpin(Self, FPressedButtons);
    end else
    begin
      FDelayTimer.Enabled := False;
      FRepeatTimer.Enabled := False;
    end;
    Invalidate;
  end;
end;

procedure TNxSpinButtons.SetSpinButtonsStyle(const Value: TNxAppearanceStyle);
begin
  if Value <> FSpinButtonsStyle then
  begin
    FSpinButtonsStyle := Value;
    Invalidate;
  end;
end;

{ TMrSpinEdit }

procedure TNxSpinEdit6.CMMouseEnter(var Message: TMessage);
begin
  FButtons.HoverButtons := [sbUp, sbDown];
end;

procedure TNxSpinEdit6.CMMouseLeave(var Message: TMessage);
begin
  FButtons.HoverButtons := [];
end;

constructor TNxSpinEdit6.Create(AOwner: TComponent);
begin
  inherited;
  FAccelerationInterval := inSlowInterval;
  FButtons := TNxSpinButtons.Create(Self);
  FButtons.Align := alRight;
  FButtons.Parent := Self;
  FButtons.Width := GetSystemMetrics(SM_CXVSCROLL);
  FButtons.Visible := True;
  FButtons.OnSpin := DoButtonsSpin;
  FIncrement := 1;
  FSpinButtons := True;
  FSpinButtonsStyle := stNative;
  FUserDefinedColorPalette := TNxUserDefinedColorPalette.Create;
  FUserDefinedColorPalette.OnChanged := DoUserDefinedColorPaletteChanged;
end;

procedure TNxSpinEdit6.CreateWnd;
begin
  inherited;
  FButtons.Left := ClientWidth;
end;

destructor TNxSpinEdit6.Destroy;
begin
  FButtons.Free;
  FUserDefinedColorPalette.Free;
  inherited;
end;

procedure TNxSpinEdit6.DoButtonsSpin(Sender: TObject; Buttons: TNxSpinButton);
var
  Delta: Integer;
begin
  { Event }
  if Assigned(FOnSpin) then FOnSpin(Self, Buttons);

  if ReadOnly then Exit;
  if not Focused and Visible then SetFocus;

  Delta := 1;

  if Buttons = [sbUp] then
  begin
    if CheckRange and (Value + FIncrement > Max) then Exit;
    Value := Value + FIncrement * Delta;
  end else
  begin
    { if no signs are allowed, negative values are not
      accepted anyway }
    if (Value = 0) and not (ednSigns in FNumericEditOptions) then Exit;
    if CheckRange and (CompareValue(Value - FIncrement, Min) = LessThanValue) then Exit;
    Value := Value - FIncrement * Delta;
  end;

  SelStart := Length(Text);

  { StdCtrls.pas }
  Modified := True;
end;

procedure TNxSpinEdit6.DoUserDefinedColorPaletteChanged(Sender: TObject);
begin
  FButtons.UserDefinedColorPalette := UserDefinedColorPalette;
end;

function TNxSpinEdit6.GetIncrement: Double;
begin
  Result := FIncrement;
end;

procedure TNxSpinEdit6.KeyPress(var Key: Char);
begin
  if CharInSet(Key, [#3, #9, #22, #24]) then
	begin
  	inherited KeyPress(Key);
	  Exit; { Clipboard keys and tab key - #9 }
	end;

  if not CharInSet(Key, ['0'..'9', LocalSettings.DecimalSeparator, '-', '+', #8, #13]) then Key := #0;

  { Decimal Separator }
  if Key = LocalSettings.DecimalSeparator then
    if ednDecimals in FNumericEditOptions then
    begin
      if (Pos(Key, Text) > 0) and (Pos(Key, SelText) = 0) then Key := #0;
    end else Key := #0;

  { Signs }
  if (Key = '-') or (Key = '+') then
    if ednSigns in FNumericEditOptions then
    begin
      if ((SelStart > 0) or (Pos('-', Text) > 0) or (Pos('+', Text) > 0))
        and ((Pos('-', SelText) = 0) and (Pos('+', SelText) = 0)) then Key := #0;
    end else Key := #0;

  if Key <> #0 then inherited KeyPress(Key);
end;

procedure TNxSpinEdit6.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  inherited;
  FButtons.Invalidate;
end;

procedure TNxSpinEdit6.SetAccelerationInterval(const Value: Integer);
begin
  FAccelerationInterval := Value;
  FButtons.DelayInterval := FAccelerationInterval;
end;

procedure TNxSpinEdit6.SetIncrement(const Value: Double);
begin
  FIncrement := Value;
end;

procedure TNxSpinEdit6.ChangeStyle(const Value: TNxAppearanceStyle);
begin
  SpinButtonsStyle := Value;
end;

procedure TNxSpinEdit6.SetSpinButtons(const Value: Boolean);
begin
  if Value <> FSpinButtons then
  begin
    FSpinButtons := Value;

    FButtons.Visible := FSpinButtons;

    if FButtons.HandleAllocated then
    begin
      { Required for design-time }
      ShowWindow(FButtons.Handle, ControlVisible[FSpinButtons]);
    end;

    { Update TRect's }
    UpdateAll;
  end;
end;

procedure TNxSpinEdit6.SetSpinButtonsStyle(const Value: TNxAppearanceStyle);
begin
  if Value <> FSpinButtonsStyle then
  begin
    FSpinButtonsStyle := Value;
    FButtons.SpinButtonsStyle := FSpinButtonsStyle;
    FButtons.UserDefinedColorPalette := UserDefinedColorPalette;
  end;
end;

procedure TNxSpinEdit6.SetUserDefinedColorPalette(
  const Value: TNxUserDefinedColorPalette);
begin
  if FUserDefinedColorPalette <> Value then
  begin
    FUserDefinedColorPalette.Assign(Value);
    FButtons.UserDefinedColorPalette := UserDefinedColorPalette;
  end;
end;

procedure TNxSpinEdit6.WMKeyDown(var Message: TWMKeyDown);
begin
  inherited;
  if SpinButtons then
    case Message.CharCode of
      VK_UP:   FButtons.PressedButtons := [sbUp];
      VK_DOWN: FButtons.PressedButtons := [sbDown];
    end;
end;

procedure TNxSpinEdit6.WMKeyUP(var Message: TWMKeyUP);
begin
  inherited;
  FButtons.PressedButtons := [];
end;

procedure TNxSpinEdit6.WMKillFocus(var Msg: TWMKillFocus);
begin
  inherited;
  if SpinButtons then FButtons.Invalidate;
end;

{ TNxEditButton }

procedure TNxEditButton.ChangeStyle(const Value: TNxAppearanceStyle);
begin
  Style := Value;
end;

procedure TNxEditButton.CMMouseEnter(var Message: TMessage);
begin
  if not (csDesigning in ComponentState) then
  begin
    Hover := True;
  end;
end;

procedure TNxEditButton.CMMouseLeave(var Message: TMessage);
begin
  if not (csDesigning in ComponentState) then
  begin
    Hover := False;
  end;
end;

constructor TNxEditButton.Create(AOwner: TComponent);
begin
  inherited;
  Supports(AOwner, INxInplaceEdit, FEdit);

  { Init Fields }
  FAutoUp := True;
  FDown := False;
  FHover := False;
  FMouseDown := False;

  { Init Properties }
  ParentFont := True;
end;

procedure TNxEditButton.DoButtonClick;
begin
  if Assigned(OnButtonClick) then FOnButtonClick(Self);
end;

procedure TNxEditButton.DoDown;
begin
  if Assigned(OnDown) then FOnDown(Self);
end;

procedure TNxEditButton.DoUp;
begin
  if Assigned(FOnUp) then FOnUp(Self);
end;

function TNxEditButton.GetAlign: TAlign;
begin
  Result := inherited Align;
end;

function TNxEditButton.GetAutoUp: Boolean;
begin
  Result := FAutoUp;
end;

function TNxEditButton.GetCaption: WideString;
begin
  Result := FCaption;
end;

function TNxEditButton.GetDown: Boolean;
begin
  Result := FDown;
end;

function TNxEditButton.GetEdit: INxInplaceEdit;
begin
  Result := FEdit;
end;

function TNxEditButton.GetHandle: HWnd;
begin
  Result := inherited Handle;
end;

function TNxEditButton.GetHover: Boolean;
begin
  Result := FHover;
end;

function TNxEditButton.GetLeft: Integer;
begin
  Result := inherited Left;
end;

function TNxEditButton.GetOnButtonClick: TNotifyEvent;
begin
  Result := FOnButtonClick;
end;

function TNxEditButton.GetOnDown: TNotifyEvent;
begin
  Result := FOnDown;
end;

function TNxEditButton.GetOnUp: TNotifyEvent;
begin
  Result := FOnUp;
end;

function TNxEditButton.GetParent: TWinControl;
begin
  Result := inherited Parent;
end;

function TNxEditButton.GetVisible: Boolean;
begin
  Result := inherited Visible;
end;

function TNxEditButton.GetWidth: Integer;
begin
  Result := inherited Width;
end;

procedure TNxEditButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited;
  Down := not Down;

  { Used in MouseUp }
  FMouseDown := True;

  { Focus Edit too! }
  if Assigned(FEdit) and FEdit.Showing then
  begin
    FEdit.SetFocus;
  end;
end;

procedure TNxEditButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited;
  if FAutoUp then Down := False;

  { Is Click? }
  if FMouseDown then
  begin
    FMouseDown := False;

    { Trigger Event }
    DoButtonClick;
  end;
end;

procedure TNxEditButton.Paint;
begin
  inherited;
  PaintBackground;
end;

procedure TNxEditButton.SetAlign(const Value: TAlign);
begin
  inherited Align := Value;
end;

procedure TNxEditButton.SetAutoUp(const Value: Boolean);
begin
  FAutoUp := Value;
end;

procedure TNxEditButton.SetCaption(const Value: WideString);
begin
  FCaption := Value;
  Invalidate;
end;

procedure TNxEditButton.SetDown(const Value: Boolean);
begin
  if Value <> FDown then
  begin
    FDown := Value;

    { Refresh }
    Refresh;

    { Trigger Event }
    if not FDown then DoUp else DoDown;
  end;
end;

procedure TNxEditButton.SetEdit(const Value: INxInplaceEdit);
begin
  FEdit := Value;
end;

procedure TNxEditButton.SetHover(const Value: Boolean);
begin
  if Value <> FHover then
  begin
    FHover := Value;

    { Refresh }
    Invalidate;
  end;
end;

procedure TNxEditButton.SetLeft(const Value: Integer);
begin
  inherited Left := Value;
end;

procedure TNxEditButton.SetOnButtonClick(const Value: TNotifyEvent);
begin
  FOnButtonClick := Value;
end;

procedure TNxEditButton.SetOnDown(const Value: TNotifyEvent);
begin
  FOnDown := Value;
end;

procedure TNxEditButton.SetOnUp(const Value: TNotifyEvent);
begin
  FOnUp := Value;
end;

procedure TNxEditButton.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);

end;

{$IFDEF DPI_SCALING_FLAGS}
function TNxEditButton.DefaultScalingFlags: TScalingFlags;
begin
  Result := inherited;
end;
{$ENDIF}

procedure TNxEditButton.SetStyle(const Value: TNxAppearanceStyle);
begin
  if Value <> FStyle then
  begin
    FStyle := Value;
    Invalidate;
  end;
end;

procedure TNxEditButton.SetVisible(const Value: Boolean);
begin
  inherited Visible := Value;
end;

procedure TNxEditButton.SetWidth(const Value: Integer);
begin
  inherited Width := Value;
end;

procedure TNxEditButton.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
  Message.Result := 1;
end;

{ TNxCustomButtonEdit6 }

procedure TNxCustomButtonEdit6.Assign(Source: TPersistent);
begin
  inherited;
  if Source is TNxCustomButtonEdit6 then
  begin
    ButtonWidth := TNxCustomButtonEdit6(Source).ButtonWidth
  end;
end;

procedure TNxCustomButtonEdit6.ChangeStyle(const Value: TNxAppearanceStyle);
begin
  ButtonStyle := Value;
end;

constructor TNxCustomButtonEdit6.Create(AOwner: TComponent);
begin
  inherited;
  { Init Fields }
  FButtonStyle := stNative;
  FShowButton := True;

  CreateButton;
  FButtonWidth := FButton.Width;

  { Init Button }
  if Assigned(FButton) then
  begin
    FButton.Align := alRight;
    FButton.Parent := Self;
    FButton.Visible := FShowButton;
    FButton.OnButtonClick := DoButtonClick;
    FButton.OnDown := DoButtonDown;
    FButton.OnUp := DoButtonUp;
  end;
end;

procedure TNxCustomButtonEdit6.CreateWnd;
begin
  inherited;
  FButton.Left := ClientWidth;
end;

destructor TNxCustomButtonEdit6.Destroy;
begin
  FButton := nil;
  inherited;
end;

procedure TNxCustomButtonEdit6.DoButtonClick(Sender: TObject);
begin
  if Assigned(FOnButtonClick) then FOnButtonClick(Self);
end;

procedure TNxCustomButtonEdit6.DoButtonDown(Sender: TObject);
begin

end;

procedure TNxCustomButtonEdit6.DoButtonUp(Sender: TObject);
begin

end;

procedure TNxCustomButtonEdit6.DoUserDefinedColorPaletteChanged(
  Sender: TObject);
var
  Styled: INxUserStyled;
begin
  if Supports(FButton, INxUserStyled, Styled) then
  begin
    Styled.UserDefinedColorPalette := UserDefinedColorPalette;
  end;
end;

procedure TNxCustomButtonEdit6.SetButtonStyle(const Value: TNxAppearanceStyle);
var
  Styled: INxUserStyled;
begin
  if Value <> FButtonStyle then
  begin
    FButtonStyle := Value;
    if Supports(FButton, INxUserStyled, Styled) then
    begin
      Styled.ChangeStyle(FButtonStyle);
      Styled.UserDefinedColorPalette := UserDefinedColorPalette;
    end;
  end;
end;

procedure TNxCustomButtonEdit6.SetButtonWidth(const Value: Integer);
begin
  if Value <> FButtonWidth then
  begin
    FButtonWidth := Value;

    { Update }
    FButton.Width := FButtonWidth;

    UpdateAll; { Edit & Button Rect }
  end;
end;

procedure TNxCustomButtonEdit6.SetOnButtonClick(const Value: TNotifyEvent);
begin
  FOnButtonClick := Value;
end;

procedure TNxCustomButtonEdit6.SetShowButton(const Value: Boolean);
begin
  if Value <> FShowButton then
  begin
    FShowButton := Value;

    FButton.Visible := FShowButton;

    { Required for design-time }
    if HandleAllocated then ShowWindow(FButton.Handle, ControlVisible[FShowButton]);

    { Update Edit Rect }
    UpdateEditRect;
  end;
end;

procedure TNxCustomButtonEdit6.WMKillFocus(var Msg: TWMKillFocus);
begin
  inherited;
  if FButton <> nil then FButton.Down := False;
end;

procedure TNxCustomButtonEdit6.WMShowWindow(var Message: TWMShowWindow);
begin
  inherited;

  { Also Call a Repaint }
  if ShowButton then UpdateEditRect;
end;

{ TNxExecuteButton }

constructor TNxExecuteButton6.Create(AOwner: TComponent);
begin
  inherited;
  FGlyph := TPicture.Create;
  FGlyph.OnChange := DoGlyphChange;
  FStyle := stNative;
  Width := szExecuteButton;
  Height := 21;
end;

destructor TNxExecuteButton6.Destroy;
begin
  FreeAndNil(FGlyph);
  inherited;
end;

procedure TNxExecuteButton6.DoGlyphChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TNxExecuteButton6.Paint;
begin
  inherited;
  Canvas.Font.Assign(Font);
  PaintInRect(Canvas, ClientRect, Glyph, Caption);
end;

procedure TNxExecuteButton6.PaintBackground;
var
  ButtonRect: TRect;
  ButtonState: TNxButtonState;
begin
  ButtonState := [];
  if Hover then Include(ButtonState, bsHover);
  if Down then Include(ButtonState, bsPressed);
  if not Parent.Enabled then Include(ButtonState, bsDisabled);

  Canvas.Brush.Color := Color;
  ButtonRect := ClientRect;

  case Style of
    stNative: TNxButtonStyle6.Paint(Canvas, Handle, ButtonRect, ButtonState, [soVCLStyles, soNativeStyles]);
    stModern: DrawModernButton(Canvas, ClientRect, ButtonState);
    stUserDefined: PaintUserStyledButton(Canvas, ButtonRect, ButtonState, UserDefinedColorPalette);
  end;
end;

class procedure TNxExecuteButton6.PaintInRect(Canvas: TCanvas; Dest: TRect; Glyph: TPicture; Text: WideString);
var
  X, Y: Integer;
  Bitmap: TBitmap;
begin
  if Assigned(Glyph)
    and Assigned(Glyph.Graphic) then
  begin
    X := Dest.Left + (RectWidth(Dest) div 2 - Glyph.Width div 2);
    Y := Dest.Top + (RectHeight(Dest) div 2 - Glyph.Height div 2);
    if Glyph.Graphic is TBitmap then
    begin
      Bitmap := Glyph.Graphic as TBitmap;
      Bitmap.Transparent := True;
      Bitmap.TransparentColor := Bitmap.Canvas.Pixels[0, Pred(Bitmap.Height)];
    end;
    Canvas.Draw(X, Y, Glyph.Graphic);
  end;
  if Text <> '' then
  begin
    DrawTextRect(Canvas, Dest, Classes.taCenter, taVerticalCenter, Text, wkEllipsis);
  end;
end;

procedure TNxExecuteButton6.SetGlyph(const Value: TPicture);
begin
  FGlyph.Assign(Value);
  if Assigned(FGlyph) then FGlyph.OnChange := DoGlyphChange;
end;

{ TNxButtonEdit }

procedure TNxButtonEdit6.Assign(Source: TPersistent);
begin
  inherited;
  if Source is TNxButtonEdit6 then
  begin
    AutoText := TNxButtonEdit6(Source).AutoText;
    ButtonCaption := TNxButtonEdit6(Source).ButtonCaption;
    ButtonGlyph.Assign(TNxButtonEdit6(Source).ButtonGlyph);
  end;
end;

constructor TNxButtonEdit6.Create(AOwner: TComponent);
begin
  inherited;
  FAutoText := EmptyStr;
  FButtonGlyph := TPicture.Create;
  FButtonGlyph.OnChange := DoButtonGlyphChange;
  FButtonWidth := szExecuteButton;
end;

procedure TNxButtonEdit6.CreateButton;
begin
  FButton := TNxExecuteButton6.Create(Self);
end;

destructor TNxButtonEdit6.Destroy;
begin
  FreeAndNil(FButtonGlyph);
  FreeAndNil(FUserDefinedColorPalette);
  inherited;
end;

procedure TNxButtonEdit6.DoButtonGlyphChange(Sender: TObject);
begin
  { Reference to TBitmap }
  (FButton as INxExecuteButton).SetGlyph(FButtonGlyph);

  { Refresh }
  FButton.Invalidate;
end;

procedure TNxButtonEdit6.DoButtonClick(Sender: TObject);
begin
  inherited;

  { Transfer }
  if FAutoText <> EmptyStr then
  begin
    Text := FAutoText;

    SelectAll;
  end;
end;

procedure TNxButtonEdit6.SetButtonCaption(const Value: WideString);
begin
  if Value <> FButtonCaption then
  begin
    FButtonCaption := Value;

    { Update }
    FButton.Caption := FButtonCaption;
  end;
end;

procedure TNxButtonEdit6.SetButtonGlyph(const Value: TPicture);
begin
  FButtonGlyph.Assign(Value);
end;

{ TNxDropDownButton }

constructor TNxDropDownButton6.Create(AOwner: TComponent);
begin
  inherited;
  Height := 19;
  Width := szDropDownButton;
end;

procedure TNxDropDownButton6.PaintBackground;
var
  ButtonState: TNxButtonState;
begin
  ButtonState := [];
  if Hover then Include(ButtonState, bsHover);
  if Down then Include(ButtonState, bsPressed);
  if not Parent.Enabled then Include(ButtonState, bsDisabled);

  case Style of
    stNative: TNxDropButtonStyledView6.Paint(Canvas, Handle, ClientRect, ButtonState,
      [soVCLStyles, soNativeStyles]);
    stModern:
    begin
      DrawModernButton(Canvas, ClientRect, ButtonState);
      DrawArrow(Canvas, ClientRect, skDescending, UserDefinedColorPalette.GeometryColor);
    end;
    stUserDefined:
    begin
      PaintUserStyledButton(Canvas, ClientRect, ButtonState, UserDefinedColorPalette);
      DrawArrow(Canvas, ClientRect, skDescending, UserDefinedColorPalette.GeometryColor);
    end;
  end;
end;

{ TNxDropDownEdit6 }

function TNxDropDownEdit6.CanDispatchKey(Key: Word): Boolean;
begin
  Result := not FDroppedDown and inherited CanDispatchKey(Key);
end;

procedure TNxDropDownEdit6.Close;
var
  Reference: IInterfaceComponentReference;
  Component: TComponent;
begin
  ReleaseCapture; { CaptureMouse }

  Component := nil;

  if Supports(FPopupControl, IInterfaceComponentReference, Reference) then
  begin
    Component := Reference.GetComponent;
    Reference := nil;
  end;

  FPopupControl := nil;

  if Assigned(Component) then Component.Free;

  { Event }
  DoCloseUp;
end;

procedure TNxDropDownEdit6.CMFontChanged(var Message: TMessage);
begin
  inherited;
  if Assigned(FPopupControl) then
    FPopupControl.Font.Assign(Font);
end;

constructor TNxDropDownEdit6.Create(AOwner: TComponent);
begin
  inherited;
  FAutoClose := True;
  FAutoDropDown := False;
  FPopupAnchor := paLeft;
  FPopupControl := nil;
  FStyle := dsDropDown;
end;

procedure TNxDropDownEdit6.CreateButton;
begin
  FButton := TNxDropDownButton6.Create(Self);

  { Don't release Button }
  FButton.AutoUp := False;
end;

procedure TNxDropDownEdit6.DoBeforePopup;
begin

end;

procedure TNxDropDownEdit6.DoButtonDown(Sender: TObject);
begin
  DroppedDown := True;
end;

procedure TNxDropDownEdit6.DoButtonUp(Sender: TObject);
begin
  DroppedDown := False;
end;

procedure TNxDropDownEdit6.DoCloseUp;
begin
  if Assigned(FOnCloseUp) then FOnCloseUp(Self);
end;

procedure TNxDropDownEdit6.DoDrowDown;
begin
  if Assigned(FOnDropDown) then FOnDropDown(Self);
end;

procedure TNxDropDownEdit6.DoEnter;
begin
  inherited;
  if FAutoDropDown then DroppedDown := True;
end;

procedure TNxDropDownEdit6.DoSelect;
begin
  if Assigned(FOnSelect) then FOnSelect(Self);
end;

procedure TNxDropDownEdit6.DropDown;
var
	ScreenPoint: TPoint;
begin
  { Don't create Popup if thirdparty
    Popup is assigned }
  if not Assigned(FPopupControl) then
  begin
    FPopupControl := CreatePopupControl;

    FPopupControl.Font.Assign(Font);
  end;

  if Assigned(FPopupControl) then
  begin
    DoBeforePopup;

    case PopupAnchor of
      paLeft: ScreenPoint := Parent.ClientToScreen(Point(BoundsRect.Left, BoundsRect.Bottom));
      paRight: ScreenPoint := Parent.ClientToScreen(Point(BoundsRect.Right, BoundsRect.Bottom));
    end;

    { Activate Popup }
    FPopupControl.Popup(ScreenPoint, PopupAnchor);

    { Event }
    DoDrowDown;
  end;
end;

function TNxDropDownEdit6.GetAutoClose: Boolean;
begin
  Result := FAutoClose;
end;

function TNxDropDownEdit6.GetDroppedDown: Boolean;
begin
  Result := FDroppedDown;
end;

procedure TNxDropDownEdit6.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited;
  if (ssAlt in Shift) and (Key in [VK_DOWN, VK_UP])
    then DroppedDown := not DroppedDown;
  if Key in [VK_RETURN, VK_ESCAPE] then DroppedDown := False;
end;

procedure TNxDropDownEdit6.PaintEdit;
var
  TextRect: TRect;
begin
  { Paint dsDropDownList style }
  with Canvas do
  begin
    Font.Assign(Self.Font);

    if Focused then
    begin
      Brush.Color := clHighlight;
      Font.Color := clHighlightText;
    end else
    begin
      Brush.Color := Color;
      Font.Color := Self.Font.Color;
    end;

    FillRect(EditRect);
  end;

  TextRect := EditRect;

  if BorderStyle = bsSingle then
  begin
    Inc(TextRect.Left, 2);
    Inc(TextRect.Top, 2);
  end;

  DrawTextRect(Canvas, TextRect, taLeftJustify, taAlignTop, Text, wkNone);
end;

procedure TNxDropDownEdit6.PaintWindow(DC: HDC);
begin

  if Style = dsDropDownList then
  begin

    FCanvas.Lock;

    try
      FCanvas.Handle := GetWindowDC(Handle);

      try
        PaintEdit;
      finally
        FCanvas.Handle := 0;
      end;

    finally
      FCanvas.Unlock;
    end;

  end

  { standard TEdit painting }
  else inherited;

end;

procedure TNxDropDownEdit6.SetDroppedDown(const Value: Boolean);
begin
  if Value <> FDroppedDown then { Avoid Recursion }
  begin
    FDroppedDown := Value;

    if Value then
      DropDown { Activate Popup }
    else
      Close; { Destroy }

    FButton.Down := FDroppedDown; { Button Appearance }

    { ToDo: }
  end;
end;

procedure TNxDropDownEdit6.SetOnDropDown(const Value: TNotifyEvent);
begin
  FOnDropDown := Value;
end;

procedure TNxDropDownEdit6.SetStyle(const Value: TNxDropDownStyle);
begin

  if Value <> FStyle then
  begin
    FStyle := Value;

    if FStyle = dsDropDown
      then
        Cursor := crDefault
      else
        Cursor := crArrow;

    { Disable typing }
    if HandleAllocated then SendMessage(Handle, EM_SETREADONLY, Ord(FStyle), 0);
  end;

end;

procedure TNxDropDownEdit6.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
  if Style = dsDropDownList then Message.Result := 1;
end;

procedure TNxDropDownEdit6.WMKillFocus(var Msg: TWMKillFocus);
begin
  inherited;
  { 1/5/13: Not needed in XE3, but D6 require it }
  if Style = dsDropDownList then Refresh;
end;

procedure TNxDropDownEdit6.WMLButtonDown(var Message: TWMLButtonDown);
begin
  inherited;
  if Style = dsDropDownList then DroppedDown := not DroppedDown;
end;

procedure TNxDropDownEdit6.WMSetFocus(var Message: TWMSetFocus);
begin
  SendMessage(Handle, EM_SETREADONLY, Ord(FStyle), 0);
  if Style = dsDropDownList then
  begin
    DestroyCaret;
    Refresh;
  end
  else inherited; { standard TEdit calls }
end;

{ TNxComboBox6 }

procedure TNxComboBox6.CMTextChanged(var Message: TMessage);
begin
  inherited;
  case DisplayMode of
    dmDefault: ItemIndex := Items.IndexOf(Text);
    else ItemIndex := -1;
  end;
end;

constructor TNxComboBox6.Create(AOwner: TComponent);
begin
  inherited;
  FAutoComplete := False;
  FAutoCompleteDelay := 750;
  FDisplayMode := dmDefault;
  FDrawingOptions := [doBackground, doContent];
  FDropDownCount := coDropDown;
  FItemHeight := szItemHeight;
  FItemIndex := -1;
  FItems := TNxStringList.Create;
  TNxStringList(FItems).OnChange := DoItemsChange;
  FItemsAlignment := taLeftJustify;
  FListWidth := 0;
  FSelectionColor := clHighlight;
  FSelectionTextColor := clHighlightText;
  FUpdatingIndex := False;
end;

function TNxComboBox6.CreatePopupControl: INxPopupControl;
begin
  Result := TNxStringsPopupControl6.Create(Self);
end;

destructor TNxComboBox6.Destroy;
begin
  FreeAndNil(FItems);
  inherited;
end;

procedure TNxComboBox6.DoDrawItem(Index: Integer; Rect: TRect;
  State: TOwnerDrawState);
begin
  if Assigned(FOnDrawItem) then FOnDrawItem(FPopupControl.Canvas, Index, Rect, State);
end;

procedure TNxComboBox6.DoItemsChange(Sender: TObject);
begin
  FItemIndex := -1;
  if Style = dsDropDownList then
  begin
    try
      { Prevent updating index in `CMTextChanged` }
      FUpdatingIndex := True;

      { Call `CMTextChanged` }
      Text := '';
    finally
      FUpdatingIndex := False;
    end;
  end;
end;

function TNxComboBox6.DoMouseWheelDown(Shift: TShiftState;
  MousePos: TPoint): Boolean;
begin
  Result := inherited DoMouseWheelDown(Shift, MousePos);

  if DroppedDown then
  begin
    (PopupControl as INxListPopup).ScrollDown;
  end
  else ItemIndex := ItemIndex + 1;
end;

function TNxComboBox6.DoMouseWheelUp(Shift: TShiftState;
  MousePos: TPoint): Boolean;
begin
  Result := inherited DoMouseWheelDown(Shift, MousePos);

  if DroppedDown then
  begin
    (PopupControl as INxListPopup).ScrollUp;
  end
  else ItemIndex := ItemIndex - 1;
end;

function TNxComboBox6.GetAsInteger: Integer;
begin
  Result := ItemIndex;
end;

function TNxComboBox6.GetAutoComplete: Boolean;
begin
  Result := FAutoComplete;
end;

function TNxComboBox6.GetCount: Integer;
begin
  Result := FItems.Count;
end;

function TNxComboBox6.GetDisplayText(const Index: Integer): string;
begin
  case DisplayMode of
    dmNameList: Result := Items.Names[Index];
    dmValueList, dmIndentList: Result := GetItemValue(Items, Index);
    else Result := Items[Index];
  end;
end;

function TNxComboBox6.GetDrawingOptions: TNxDrawingOptions;
begin
  Result := FDrawingOptions;
end;

function TNxComboBox6.GetDropDownCount: Integer;
begin
  Result := FDropDownCount;
end;

function TNxComboBox6.GetItemHeight: Integer;
begin
  Result := FItemHeight;
end;

function TNxComboBox6.GetItemIndex: Integer;
begin
  Result := FItemIndex;
end;

function TNxComboBox6.GetItems: TStrings;
begin
  Result := FItems;
end;

function TNxComboBox6.GetItemsAlignment: TAlignment;
begin
  Result := FItemsAlignment;
end;

function TNxComboBox6.GetListWidth: Integer;
begin
  Result := FListWidth;
end;

procedure TNxComboBox6.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited;
  if not(ssAlt in Shift) then
    case Key of
      VK_UP:   TryItemIndex(ItemIndex - 1, True);
      VK_DOWN: TryItemIndex(ItemIndex + 1, True);
      VK_HOME: TryItemIndex(0, True);
      VK_END:  TryItemIndex(Pred(Items.Count), True);
    end;
  if DroppedDown then
    case Key of
      VK_PRIOR, VK_NEXT: PopupControl.KeyDown(Key, Shift);
    end;
end;

procedure TNxComboBox6.KeyPress(var Key: Char);

  function HasSelectedText(var StartPos, EndPos: DWORD): Boolean;
  begin
    Result := False;
    if Style in [dsDropDown] then
    begin
      SendMessage(Self.Handle, EM_GETSEL, Integer(@StartPos), Integer(@EndPos));
      Result := EndPos > StartPos;
    end;
  end;

  procedure DeleteSelectedText;
  var
    StartPos, EndPos: DWORD;
    OldText: String;
  begin
    OldText := Text;
    SendMessage(Handle, EM_GETSEL, Integer(@StartPos), Integer(@EndPos));
    Delete(OldText, StartPos + 1, EndPos - StartPos);
    SendMessage(Handle, EM_SETSEL, -1, 0);
    Text := OldText;
    SendMessage(Handle, EM_SETSEL, 0, MakeLParam(StartPos, StartPos));
  end;

var
  StartPos: DWORD;
  EndPos: DWORD;
  OldText: String;
  SaveText: String;
  Msg : TMSG;
  LastByte: Integer;
begin
  inherited KeyPress(Key);
  if Style in [dsDropDown] then FFilter := Text else
  begin
    if GetTickCount - FLastTime >= FAutoCompleteDelay then FFilter := '';
    FLastTime := GetTickCount;
  end;
  case Ord(Key) of
    VK_ESCAPE, VK_RETURN: Exit;
    VK_TAB: if FAutoDropDown and DroppedDown then DroppedDown := False;
    VK_BACK:
      if FAutoComplete then
      begin
        if HasSelectedText(StartPos, EndPos) then DeleteSelectedText else
        begin
          if (Style in [dsDropDown]) and (Length(Text) > 0) then
          begin
            SaveText := Text;
            LastByte := StartPos;
            while ByteType(SaveText, LastByte) = mbTrailByte do Dec(LastByte);
            OldText := Copy(SaveText, 1, LastByte - 1);
            SendMessage(Handle, EM_SETSEL, -1, 0);
            Text := OldText + Copy(SaveText, EndPos + 1, MaxInt);
            SendMessage(Handle, EM_SETSEL, 0, MakeLParam(LastByte - 1, LastByte - 1));
            FFilter := Text;
          end else
          begin
            while ByteType(FFilter, Length(FFilter)) = mbTrailByte do
              Delete(FFilter, Length(FFilter), 1);
            Delete(FFilter, Length(FFilter), 1);
          end;
          Key := #0;
          Change;
        end;
      end;
    else
      if FAutoDropDown then DroppedDown := True;
      if FAutoComplete then
      begin
        if HasSelectedText(StartPos, EndPos) then SaveText := Copy(FFilter, 1, StartPos) + Key
          else SaveText := FFilter + Key;
{$WARNINGS OFF}
        if Key in LeadBytes then
{$WARNINGS ON}
        begin
          if PeekMessage(Msg, Handle, 0, 0, PM_NOREMOVE) and (Msg.Message = WM_CHAR) then
          begin
            SaveText := SaveText + Char(Msg.wParam);
            if SelectItem(SaveText) then
            begin
              PeekMessage(Msg, Handle, 0, 0, PM_REMOVE);
              Key := #0
            end;
          end;
        end else if SelectItem(SaveText) then Key := #0
      end; { FAutoComplete }
    end; { else }
end;

function TNxComboBox6.MeasureItem(const Index, AWidth: Integer): TSize;
begin
  Result := GetTextSize(Canvas.Handle, Bounds(0, 0, 0, 0), GetDisplayText(Index), wkNone);
end;

function TNxComboBox6.PaintCell(const Index: Integer; CellRect: TRect;
  State: TOwnerDrawState): Boolean;
var
  ButtonState: TNxButtonState;
begin
  { Background Layer }
  if doBackground in DrawingOptions then
    with FPopupControl.Canvas do
    begin
      ButtonState := [];
      if odSelected in State then
      begin
        Include(ButtonState, bsSelected);
        Font.Color := SelectionTextColor;
        Brush.Color := SelectionColor;
      end else
      begin
        Font.Color := clWindowText;
        Brush.Color := Self.Color;
      end;

      FillRect(CellRect);
    end;

  { Content Layer }
  if doContent in DrawingOptions
    then PaintContent(Index, CellRect, State);

  if doCustom in DrawingOptions then
  begin
    DoDrawItem(Index, CellRect, State);
  end;

  Result := True;
end;

procedure TNxComboBox6.PaintContent(const Index: Integer; CellRect: TRect;
  State: TOwnerDrawState);
begin
  Inc(CellRect.Left, pdStandard);
  FPopupControl.Canvas.Font.Assign(Font);
  DrawTextRect(PopupControl.Canvas, CellRect, ItemsAlignment, taVerticalCenter, GetDisplayText(Index), wkNone);
end;

function TNxComboBox6.SelectItem(var AnItem: string): Boolean;
var
  Index: Integer;
  ValueChange: Boolean;
begin
  if Length(AnItem) = 0 then
  begin
    Result := False;
    ItemIndex := -1;
    Change;
    Exit;
  end;
  for Index := 0 to FItems.Count - 1 do
  begin
    case Self.DisplayMode of
      dmValueList:
      begin
        if AnsiStartsText(AnItem, GetDisplayText(Index)) then
          Break;
      end;
      else
      begin
        if AnsiStartsText(AnItem, Self.FItems[Index]) then
          Break;
      end;
    end;
  end;
  If Index >= FItems.Count then Index := CB_ERR;

  Result := (Index <> CB_ERR);
  if not Result then Exit;

  ValueChange := Index <> ItemIndex;

  ItemIndex := Index;

  case Self.DisplayMode of
    dmDefault:
    begin
      AnItem := Copy(Items[Index], 1, Length(AnItem));   // make AnItem match the itemList entry
      if (Style in [dsDropDown]) then
      begin
        Text := AnItem + Copy(Items[Index], Length(AnItem) + 1, MaxInt);
        SendMessage(Handle, EM_SETSEL, Length(AnItem), MaxInt);
      end
      else
      begin
        ItemIndex := Index;
        FFilter := AnItem;
      end;

    end;
    dmNameList:
      ;
    dmValueList:
    begin
      AnItem := Copy(GetDisplayText(Index), 1, Length(AnItem));   // make AnItem match the itemList entry
      if (Style in [dsDropDown]) then
      begin
        Text := AnItem + Copy(GetDisplayText(Index), Length(AnItem) + 1, MaxInt);
        SendMessage(Handle, EM_SETSEL, Length(AnItem), MaxInt);
      end
      else
      begin
        ItemIndex := Index;
        FFilter := AnItem;
      end;

    end;
    dmIndentList: ;
  end;

  if ValueChange then
  begin
    Click;
    if Assigned(FOnSelect) then
      FOnSelect(Self)
    else
      Change;
    end;
end;

procedure TNxComboBox6.SetAsInteger(const Value: Integer);
begin
  ItemIndex := Value;
end;

procedure TNxComboBox6.SetAutoComplete(const Value: Boolean);
begin
  FAutoComplete := Value;
end;

procedure TNxComboBox6.SetDrawingOptions(const Value: TNxDrawingOptions);
begin
  FDrawingOptions := Value;
end;

procedure TNxComboBox6.SetDropDownCount(const Value: Integer);
begin
  FDropDownCount := Value;
end;

procedure TNxComboBox6.SetItemHeight(const Value: Integer);
begin
  FItemHeight := Value;
end;

procedure TNxComboBox6.SetItemIndex(const Value: Integer);
begin
  { 2nd `False` doesn't call OnSelect }
  if not FUpdatingIndex then TryItemIndex(Value, False);
end;

procedure TNxComboBox6.SetItems(const Value: TStrings);
begin
  FItems.Assign(Value);
end;

procedure TNxComboBox6.SetItemsAlignment(const Value: TAlignment);
begin
  FItemsAlignment := Value;
end;

procedure TNxComboBox6.SetListWidth(const Value: Integer);
begin
  FListWidth := Value;
end;

procedure TNxComboBox6.TryItemIndex(const Index: Integer; Select: Boolean);
begin
  { Note: -1 also not alowed }
  if InRange(Index, 0, Pred(FItems.Count))
    and (Index <> FItemIndex) then
  begin

    FItemIndex := Index;

    try
      FUpdatingIndex := True;

      { Call `CMTextChanged` }
      Text := GetDisplayText(FItemIndex);
    finally
      FUpdatingIndex := False;
    end;

    if DroppedDown then
    begin
      { Scroll, repaint etc. }
      FPopupControl.UpdatePopup;

      { Note: popup block repaint, invalidate
              also don't help (!?) }
      Refresh;
    end;

    { Call event }
    if Select then DoSelect;
  end;
end;

{ TNxCheckEntry }

function TNxCheckEntry.GetChecked: Boolean;
begin
  Result := FState = cbChecked;
end;

class function TNxCheckEntry.GetDefaultState: TCheckBoxState;
begin
  Result := cbUnchecked;
end;

procedure TNxCheckEntry.SetChecked(Check: Boolean);
begin
  if Check then FState := cbChecked else FState := cbUnchecked;
end;

{ TNxCheckComboBox6 }

procedure TNxCheckComboBox6.ClearAll;
var
  i: Integer;
begin
  for i := 0 to Pred(Items.Count) do
    if Entry[i] <> nil then
    begin
      Entry[i].Free;
      Items.Objects[i] := nil;
    end;
end;

constructor TNxCheckComboBox6.Create(AOwner: TComponent);
begin
  inherited;
  FCheckedStrings := TStringList.Create;
  FDelimiter := ',';
end;

function TNxCheckComboBox6.CreateCheckEntry: TNxCheckEntry;
begin
  Result := TNxCheckEntry.Create;
end;

function TNxCheckComboBox6.CreatePopupControl: INxPopupControl;
begin
  Result := TNxCheckPopupControl6.Create(Self);
end;

destructor TNxCheckComboBox6.Destroy;
begin
  FreeAndNil(FCheckedStrings);

  { Free Objects[] }
  ClearAll;

  inherited;
end;

procedure TNxCheckComboBox6.DoBeforePopup;
var
  i: Integer;
begin
  inherited;

  { Destroy all entries }
  ClearAll;

  UpdateCheckedStrings;

  for i := 0 to Pred(Items.Count) do
  begin
    if FCheckedStrings.IndexOf(Items[i]) > -1 then
      State[i] := cbChecked;
  end;

end;

procedure TNxCheckComboBox6.DrawCheckBox(Canvas: TCanvas; CheckBoxRect: TRect;
  CheckBoxState: TCheckBoxState);
var
  Theme: HTHEME;
  State: Integer;
begin
  if Themed then
  begin
    { Create Theme Handle }
    Theme := OpenThemeData(Handle, teButton);

    State := 0;

    case CheckBoxState of
      cbUnchecked: State := tiRadioNormal;
      cbChecked: State := tiRadioChecked;
      cbGrayed: State := tiRadioGrayed;
    end;

    { Draw CheckBox }
    DrawThemeBackground(Theme, Canvas.Handle, tcCheckBox, State, CheckBoxRect, nil);

    { Destroy Theme }
    CloseThemeData(Theme);

  end

  else

  { Classic }
  begin

    with Canvas, CheckBoxRect.TopLeft do
    begin
      Pen.Color := clBtnShadow;
      case CheckBoxState of
        cbUnchecked, cbChecked: Brush.Color := clWindow;
        cbGrayed: Brush.Color := clBtnFace;
      end;
      Rectangle(CheckBoxRect);

      if CheckBoxState <> cbUnchecked then
      begin
        Pen.Color := clWindowText;
        Polyline([Point(X + 2, Y + 4), Point(X + 4, Y + 6), Point(X + 9, Y + 1)]);
        Polyline([Point(X + 2, Y + 5), Point(X + 4, Y + 7), Point(X + 9, Y + 2)]);
        Polyline([Point(X + 2, Y + 6), Point(X + 4, Y + 8), Point(X + 9, Y + 3)]);
      end;
    end;

  end;

end;

function TNxCheckComboBox6.GetChecked(Index: Integer): Boolean;
begin
  Result := State[Index] = cbChecked;
end;

function TNxCheckComboBox6.GetEntry(Index: Integer): TNxCheckEntry;
begin
  Result := TNxCheckEntry(Items.Objects[Index]);
end;

function TNxCheckComboBox6.GetHeader(Index: Integer): Boolean;
begin
  Result := False;
  if Entry[Index] <> nil then Result := Entry[Index].Header;
end;

function TNxCheckComboBox6.GetItemEnabled(Index: Integer): Boolean;
begin
  Result := True;
  if Entry[Index] <> nil then Result := not Entry[Index].Disabled;
end;

function TNxCheckComboBox6.GetState(Index: Integer): TCheckBoxState;
begin
  Result := cbUnchecked;
  if Entry[Index] <> nil then Result := Entry[Index].State;
end;

procedure TNxCheckComboBox6.CheckAll;
var
  i: Integer;
begin
  for i := 0 to Pred(Count) do
    Checked[i] := True;
end;

procedure TNxCheckComboBox6.CheckBoxClick(const Index: Integer);
begin
  Checked[Index] := not Checked[Index];
end;

function TNxCheckComboBox6.PaintCell(const Index: Integer; CellRect: TRect;
  State: TOwnerDrawState): Boolean;
const
  BoxSize: array[Boolean] of Integer = (11, 13);
var
  CheckBoxState: TCheckBoxState;
  CheckBoxRect, Container: TRect;
  CheckBoxLocation: TPoint;
begin

  Container := CellRect;
  Container.Right := Container.Left + BoxSize[Themed] + pdDouble;

  CheckBoxLocation := PosInRect(BoxSize[Themed], BoxSize[Themed], Container, Classes.taCenter, taVerticalCenter);

  CheckBoxRect := Bounds(CheckBoxLocation.X, CheckBoxLocation.Y, BoxSize[Themed], BoxSize[Themed]);

  CheckBoxState := Self.State[Index];

  DrawCheckBox(PopupControl.Canvas, CheckBoxRect, CheckBoxState);

  CellRect.Left := Container.Right;

  { Paint text inside, shifted }
  Result := inherited PaintCell(Index, CellRect, State);
end;

procedure TNxCheckComboBox6.SetChecked(Index: Integer; const Value: Boolean);
begin
  if Items.Objects[Index] = nil then
    Items.Objects[Index] := CreateCheckEntry;

  Entry[Index].Checked := Value;

  UpdateText;
end;

procedure TNxCheckComboBox6.SetDelimiter(const Value: Char);
begin
  if Value <> FDelimiter then
  begin
    FDelimiter := Value;
    UpdateText;
  end;
end;

procedure TNxCheckComboBox6.SetHeader(Index: Integer; const Value: Boolean);
begin
  if Items.Objects[Index] = nil then
    Items.Objects[Index] := CreateCheckEntry;

  Entry[Index].Header := Value;
end;

procedure TNxCheckComboBox6.SetItemEnabled(Index: Integer;
  const Value: Boolean);
begin
  if Items.Objects[Index] = nil then
    Items.Objects[Index] := CreateCheckEntry;

  Entry[Index].Disabled := not Value;
end;

procedure TNxCheckComboBox6.SetState(Index: Integer;
  const Value: TCheckBoxState);
begin
  if Items.Objects[Index] = nil then
    Items.Objects[Index] := CreateCheckEntry;

  Entry[Index].State := Value;
end;

procedure TNxCheckComboBox6.UpdateCheckedStrings;
begin
  FCheckedStrings.Delimiter := Delimiter;
//  FCheckedStrings.StrictDelimiter := True;
  FCheckedStrings.DelimitedText := Text;
end;

procedure TNxCheckComboBox6.UpdateText;
var
  i: Integer;
  s: WideString;
begin
  s := EmptyStr;

  for i := 0 to Pred(Items.Count) do
    if State[i] = cbChecked then
    begin
      if s <> EmptyStr then s := s + Delimiter;
      s := s + GetDisplayText(i);
    end;

  Text := s;
end;

{ TNxDatePicker6 }

constructor TNxDatePicker6.Create(AOwner: TComponent);
begin
  inherited;
  FSelectionDateRange := drAll;
  FStartDayOfWeek := dwSystem;
end;

function TNxDatePicker6.CreatePopupControl: INxPopupControl;
var
  DateControl: INxDateControl;
begin
  Result := TNxDatePopupControl6.Create(Self);
  if Supports(Result, INxDateControl, DateControl) then
  begin
    DateControl.SelectionDateRange := SelectionDateRange;
    DateControl.StartDayOfWeek := StartDayOfWeek;
  end;
end;

procedure TNxDatePicker6.DoCustomDrawDate(Sender: TObject; Date: TDateTime; DayRect: TRect);
begin
  if Assigned(FOnCustomDrawDateColor) then FOnCustomDrawDateColor(Self, Date, DayRect);
end;

procedure TNxDatePicker6.DoGetDateColor(Sender: TObject; Date: TDateTime;
  var DayColor: TColor);
begin
  if Assigned(FOnGetDateColor) then FOnGetDateColor(Self, Date, DayColor);
end;

function TNxDatePicker6.GetDate: TDate;
begin
  Result := StrToDateDef(Text, Today);
end;

procedure TNxDatePicker6.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited;
  if DroppedDown then PopupControl.KeyDown(Key, Shift);
end;

procedure TNxDatePicker6.SetDate(const Value: TDate);
begin
  Text := DateToStr(Value);
end;

procedure TNxDatePicker6.SetStartDayOfWeek(const Value: TNxStartDayOfWeek);
begin
  FStartDayOfWeek := Value;
end;

{ TNxTimeEdit6 }

constructor TNxTimeEdit6.Create(AOwner: TComponent);
begin
  inherited;
  FAccelerationInterval := inSlowInterval;
  FButtons := TNxSpinButtons.Create(Self);
  FButtons.Align := alRight;
  FButtons.Parent := Self;
  FButtons.Width := GetSystemMetrics(SM_CXVSCROLL);
  FButtons.Visible := True;
  FButtons.OnSpin := DoButtonsSpin;
  FIncrement := 1;
  FSpinButtons := True;
end;

destructor TNxTimeEdit6.Destroy;
begin
  inherited;
end;

procedure TNxTimeEdit6.DoButtonsSpin(Sender: TObject; Buttons: TNxSpinButton);
begin

end;

procedure TNxTimeEdit6.SetAccelerationInterval(const Value: Integer);
begin
  FAccelerationInterval := Value;
  FButtons.DelayInterval := FAccelerationInterval;
end;

procedure TNxTimeEdit6.SetIncrement(const Value: Double);
begin
  FIncrement := Value;
end;

procedure TNxTimeEdit6.SetSpinButtons(const Value: Boolean);
begin
  if Value <> FSpinButtons then
  begin
    FSpinButtons := Value;

    FButtons.Visible := FSpinButtons;

    if FButtons.HandleAllocated then
    begin
      { Required for design-time }
      ShowWindow(FButtons.Handle, ControlVisible[FSpinButtons]);
    end;

    { Update TRect's }
    UpdateAll;
  end;
end;

{ TNxTimePicker6 }

constructor TNxTimePicker6.Create(AOwner: TComponent);
begin
  inherited;
  AsDateTime := Now;
  FHoursText := 'H';
  FMinutesText := 'M';
  FOptions := [to24HourDay, toMinutes];
  PopupAnchor := paRight;
end;

function TNxTimePicker6.CreatePopupControl: INxPopupControl;
begin
  Result := TNxTimePopupControl6.Create(Self);
end;

procedure TNxTimePicker6.DoBeforePopup;
var
  TimeControl: INxTimeControl;
begin
  inherited;
  if Supports(FPopupControl, INxTimeControl, TimeControl) then
  begin
    TimeControl.SetHoursText(HoursText);
    TimeControl.SetMinutesText(MinutesText);
    TimeControl.SetOptions(Options);
  end;
end;

function TNxTimePicker6.GetAsDateTime: TDateTime;
begin
	if (Text = '') or (Text = '0') then Result := Time
    else if not TryStrToTime(Text, Result) then Result := 0;
end;

function TNxTimePicker6.GetHoursText: string;
begin
  Result := FHoursText;
end;

function TNxTimePicker6.GetMinutesText: string;
begin
  Result := FMinutesText;
end;

procedure TNxTimePicker6.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited;
  if DroppedDown then
  begin
    if Key <> 0 then
    begin
//      with FPopupControl as TNxTimePopup do
//      begin
//        DecodeTime(GetAsDateTime, h, m, s, ms);
//        Hours := h;
//        Minutes := m;
//        SelectedTime := GetAsDateTime;
//        Invalidate;
//      end;
    end;
  end;
end;

procedure TNxTimePicker6.SetAsDateTime(const Value: TDateTime);
begin
  AsString := TimeToStr(Value);
end;

procedure TNxTimePicker6.SetHoursText(const Value: string);
begin
  FHoursText := Value;
end;

procedure TNxTimePicker6.SetMinutesText(const Value: string);
begin
  FMinutesText := Value;
end;

procedure TNxTimePicker6.SetOptions(const Value: TNxTimeShowOptions);
begin
  FOptions := Value;
end;

procedure TNxTimePicker6.WMKillFocus(var Msg: TWMKillFocus);
begin
  inherited;
  if Text <> '' then
  begin
    SetAsDateTime(StrToDateDef(Text, Time));
  end;
end;

{ TNxRichEdit6 }

procedure TNxRichEdit6.BeginEdit;
begin
  BorderStyle := bsNone;
  SelStart := Length(Text);
  WantArrows := True;
  WantTabs := True;
  WantReturns := True;
end;

procedure TNxRichEdit6.AssignValue(Source: INxBase);
begin
  Text := Source.AsString;
end;

procedure TNxRichEdit6.BeginEdit(Key: WideChar);
begin
  { ToDo: Add Prepare protected meth. }
  BeginEdit; { Overloaded Method }

  AutoSelect := False;

  SendMessage(Handle, WM_CHAR, Ord(Key), 0);

  { Move Caret to last Pos. }
  SelStart := Length(Text);
end;

function TNxRichEdit6.CanDispatchKey(Key: Word): Boolean;
  function CanDispatchArrow: Boolean;
  begin
    Result := ((Key = VK_DOWN) and (CaretPos.Y >= Pred(LinesCount)))
      or ((Key = VK_UP) and (CaretPos.Y = 0));
  end;
begin
  { Default }
  Result := True;

  case Key of
    VK_RETURN: Result := not FWantReturns;
    VK_LEFT..VK_DOWN: Result := CanDispatchArrow or not FWantArrows;
  end;
end;

function TNxRichEdit6.Clone: INxInplaceEdit;
begin

end;

constructor TNxRichEdit6.Create(AOwner: TComponent);
begin
  inherited;
  FAlignment := taLeftJustify;
  FEditOptions := [edPaste, edTyping];
  FPadding := TPadding.Create(Self);
  FWantArrows := False;
  FWantReturns := False;
  FWantTabs := False;
end;

destructor TNxRichEdit6.Destroy;
begin
  FreeAndNil(FPadding);
  inherited;
end;

procedure TNxRichEdit6.EndEdit;
begin

end;

function TNxRichEdit6.GetAlignment: TAlignment;
begin
  Result := FAlignment;
end;

function TNxRichEdit6.GetAsFloat: Double;
begin
  Result := StrToFloatDef(GetAsString, 0);
end;

function TNxRichEdit6.GetAsInteger: Integer;
begin
  Result := StrToIntDef(GetAsString, 0);
end;

function TNxRichEdit6.GetAsString: WideString;
begin
  Result := Text;
end;

function TNxRichEdit6.GetColor: TColor;
begin
  Result := inherited Color;
end;

function TNxRichEdit6.GetEditOptions: TNxEditOptions;
begin
  Result := FEditOptions;
end;

function TNxRichEdit6.GetEnabled: Boolean;
begin
  Result := inherited GetEnabled;
end;

function TNxRichEdit6.GetHandle: HWND;
begin
  Result := inherited Handle;
end;

function TNxRichEdit6.GetLinesCount: Integer;
begin
  Result := 0;
  if HandleAllocated or (WindowText <> nil) then
  begin
    Result := SendMessage(Handle, EM_GETLINECOUNT, 0, 0);
    if SendMessage(Handle, EM_LINELENGTH, SendMessage(Handle,
      EM_LINEINDEX, Result - 1, 0), 0) = 0 then Dec(Result);
  end;
end;

function TNxRichEdit6.GetOnAssignEditing: TNotifyEvent;
begin

end;

function TNxRichEdit6.GetOnChange: TNotifyEvent;
begin
  Result := OnChange;
end;

function TNxRichEdit6.GetPadding: TPadding;
begin
  Result := FPadding;
end;

function TNxRichEdit6.GetShowing: Boolean;
begin
  Result := inherited Showing;
end;

function TNxRichEdit6.GetText: string;
begin
  Result := Text;
end;

function TNxRichEdit6.GetWantTabs: Boolean;
begin
  Result := FWantTabs;
end;

procedure TNxRichEdit6.SetAlignment(const Value: TAlignment);
begin
  FAlignment := Value;
end;

procedure TNxRichEdit6.SetAsFloat(const Value: Double);
begin

end;

procedure TNxRichEdit6.SetAsInteger(const Value: Integer);
begin

end;

procedure TNxRichEdit6.SetAsString(const Value: WideString);
begin
  Text := Value;
end;

procedure TNxRichEdit6.SetAutoSelect(const Value: Boolean);
begin
  AutoSelect := Value;
end;

procedure TNxRichEdit6.SetColor(const Value: TColor);
begin
  inherited Color := Value;
end;

procedure TNxRichEdit6.SetEditOptions(const Value: TNxEditOptions);
begin
  FEditOptions := Value;
end;

procedure TNxRichEdit6.SetEditPadding(const Leading, Trailing: Integer);
begin

end;

procedure TNxRichEdit6.SetEnabled(Value: Boolean);
begin
  inherited;
end;

procedure TNxRichEdit6.SetFont(const Value: TFont);
begin
  Font := Value;
end;

procedure TNxRichEdit6.SetOnAssignEditing(const Value: TNotifyEvent);
begin

end;

procedure TNxRichEdit6.SetOnChange(const Value: TNotifyEvent);
begin
  OnChange := Value;
end;

procedure TNxRichEdit6.SetPadding(const Value: TPadding);
begin

end;

procedure TNxRichEdit6.SetReadOnly(const Value: Boolean);
begin
  ReadOnly := Value;
end;

procedure TNxRichEdit6.SetText(const Value: string);
begin
  Text := Value;
end;

procedure TNxRichEdit6.SetWantTabs(const Value: Boolean);
begin
  FWantTabs := Value;
end;

procedure TNxRichEdit6.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
  inherited;
  { Arrows }
  if WantArrows then Message.Result := Message.Result or DLGC_WANTARROWS;

  { Tab Key }
  if WantTabs then Message.Result := Message.Result or DLGC_WANTTAB
    else Message.Result := Message.Result and not DLGC_WANTTAB;

  { Enter Key }
  if WantReturns then Message.Result := Message.Result or DLGC_WANTALLKEYS;
end;

{ TNxCheckBox6 }

function TNxCheckBox6.CanAutoSize(var NewWidth, NewHeight: Integer): Boolean;
begin
  Result := True;
  NewWidth := CheckBoxRect.Left + CheckBoxRect.Right - CheckBoxRect.Left;
  if Caption <> '' then
  begin
    Inc(NewWidth, TextRect.Right - TextRect.Left + FIndent);
  end;
  NewHeight := Max(CheckBoxRect.Bottom - CheckBoxRect.Top, TextRect.Bottom - TextRect.Top);
end;

procedure TNxCheckBox6.CMMouseLeave(var Message: TMessage);
begin
  ButtonState := ButtonState - [bsHover];
end;

procedure TNxCheckBox6.CMTextChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

constructor TNxCheckBox6.Create(AOwner: TComponent);
begin
  inherited;
  FCheckArea := caCheckMarkAndText;
  FAlignment := taLeftJustify;
  FAllowGrayed := False;
  FIndent := pdDouble;
  FState := cbUnchecked;
  FTagString := EmptyStr;
  FVerticalAlignment := taVerticalCenter;

  Height := 17;
  Width := 97;
end;

procedure TNxCheckBox6.DoChange;
begin
  if Assigned(FOnChange) then FOnChange(Self);
end;

procedure TNxCheckBox6.DrawCheckBox(CheckBoxRect: TRect);
var
  Theme: HTHEME;
  State: Integer;
begin
  if Themed then
  begin
    { Create Theme Handle }
    Theme := OpenThemeData(Handle, teButton);

    State := 0;

    case Self.State of
      cbUnchecked:
        begin
          State := tiRadioNormal;
          if bsHover in ButtonState then State := tiRadioHover;
          if bsPressed in ButtonState then State := tiRadioDown;
          if bsDisabled in ButtonState then State := tiRadioDisabled;
        end;
      cbChecked:
        begin
          State := tiRadioChecked;
          if bsHover in ButtonState then State := tiRadioCheckedHover;
          if bsPressed in ButtonState then State := tiRadioCheckedDown;
          if bsDisabled in ButtonState then State := tiRadioCheckedDisabled;
        end;
      cbGrayed:
        begin
          State := tiRadioGrayed;
          if bsHover in ButtonState then State := tiRadioGrayedHover;
          if bsPressed in ButtonState then State := tiRadioGrayedDown;
          if bsDisabled in ButtonState then State := tiRadioGrayedDisabled;
        end;
    end;

    { Draw CheckBox }
    DrawThemeBackground(Theme, Canvas.Handle, tcCheckBox, State, CheckBoxRect, nil);

    { Destroy Theme }
    CloseThemeData(Theme);

  end else
  begin
    with Canvas, CheckBoxRect.TopLeft do
    begin
      if bsPressed in ButtonState
        then Brush.Color := clBtnFace
        else Brush.Color := clWindow;
      Pen.Color := clBtnShadow;
      Rectangle(CheckBoxRect);
      Pen.Color := clWindowText;
      if Checked then
      begin
        Polyline([Point(X + 2, Y + 4), Point(X + 4, Y + 6), Point(X + 9, Y + 1)]);
        Polyline([Point(X + 2, Y + 5), Point(X + 4, Y + 7), Point(X + 9, Y + 2)]);
        Polyline([Point(X + 2, Y + 6), Point(X + 4, Y + 8), Point(X + 9, Y + 3)]);
      end;
    end;
  end;

end;

function TNxCheckBox6.GetAsBoolean: Boolean;
begin
  Result := Checked;
end;

function TNxCheckBox6.GetAsDateTime: TDateTime;
begin
  Result := 0;
end;

function TNxCheckBox6.GetAsFloat: Double;
begin
  Result := IfThen(Checked, 1, 0);
end;

function TNxCheckBox6.GetAsInteger: Integer;
begin
  Result := Integer(Checked);
end;

function TNxCheckBox6.GetAsString: WideString;
begin
  Result := BoolToStr(Checked, True);
end;

function TNxCheckBox6.GetCheckBoxRect: TRect;
const
  BoxSize: array[Boolean] of Integer = (11, 13);
var
  Pos: TPoint;
  PaddingRect: TRect;
  CheckBoxSize: TSize;
begin
  PaddingRect := ClientRect;
  InflateRect(PaddingRect, -pdStandard, 0);

  CheckBoxSize := DotToPixel(Size(BoxSize[Themed], BoxSize[Themed]));

  Pos := PosInRect(CheckBoxSize.cx, CheckBoxSize.cy,
    PaddingRect, Alignment, VerticalAlignment);

  Result := Bounds(Pos.X, Pos.Y, CheckBoxSize.cx, CheckBoxSize.cy);
end;

function TNxCheckBox6.GetChecked: Boolean;
begin
  Result := State = cbChecked;
end;

function TNxCheckBox6.GetTagString: string;
begin
  Result := FTagString;
end;

function TNxCheckBox6.GetTextRect: TRect;
var
  TextSize: TSize;
begin
  { Required }
  Canvas.Font.Assign(Font);

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

  Result := Bounds(0, 0, TextSize.cx, TextSize.cy);

  { Horizontal }
  case Alignment of
    taLeftJustify,
    Classes.taCenter: OffsetRect(Result, CheckBoxRect.Right + FIndent, 0);
    taRightJustify: OffsetRect(Result, CheckBoxRect.Left - TextSize.cx - FIndent, 0);
  end;

  { Ellipsis? }
  if Result.Right > ClientWidth
    then Result.Right := ClientWidth;

  { Vertical }
  OffsetRect(Result, 0, ClientHeight div 2 - TextSize.cy div 2);
end;

function TNxCheckBox6.InActiveArea(X, Y: Integer): Boolean;
begin
  Result := False;
  case FCheckArea of
    caCheckMarkAndText: Result := PtInRect(CheckBoxRect, Point(X, Y)) or PtInRect(TextRect, Point(X, Y));
    caCheckMark: Result := PtInRect(CheckBoxRect, Point(X, Y));
    caClientRect: PtInRect(ClientRect, Point(X, Y));
  end;
end;

procedure TNxCheckBox6.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited;
  if Key = VK_SPACE then Toggle;
end;

procedure TNxCheckBox6.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  inherited;
  if not Focused then SetFocus;

  if (Button = mbLeft) and InActiveArea(X, Y) then
  begin
    ButtonState := ButtonState + [bsPressed];
  end;
end;

procedure TNxCheckBox6.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
  inherited;
  if InActiveArea(X, Y) then
  begin
    ButtonState := ButtonState + [bsHover];
  end
  else ButtonState := ButtonState - [bsHover];
end;

procedure TNxCheckBox6.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  inherited;
  if bsPressed in ButtonState then
  begin

    if InActiveArea(X, Y) then Toggle;

    ButtonState := ButtonState - [bsPressed];
  end;
end;

procedure TNxCheckBox6.Paint;
var
  CaptionRect: TRect;
begin
  inherited;

  { Caption }
  with Canvas do
  begin
    EraseBkGnd(ClientRect);

    { Check }
    DrawCheckBox(CheckBoxRect);

    CaptionRect := Self.TextRect;

    Font.Assign(Self.Font);
    if not Enabled
      then Font.Color := clGrayText;

    DrawTextRect(Canvas, CaptionRect, taLeftJustify, VerticalAlignment, Caption, wkEllipsis);
  end;

  if Focused then
    DrawFocusRect(Canvas, ClientRect);

end;

procedure TNxCheckBox6.SetAlignment(const Value: TAlignment);
begin
  if Value <> FAlignment then
  begin
    FAlignment := Value;
    Invalidate;
  end;
end;

procedure TNxCheckBox6.SetAsBoolean(const Value: Boolean);
begin
  Checked := Value;
end;

procedure TNxCheckBox6.SetAsDateTime(const Value: TDateTime);
begin

end;

procedure TNxCheckBox6.SetAsFloat(const Value: Double);
begin

end;

procedure TNxCheckBox6.SetAsInteger(const Value: Integer);
begin
  Checked := Boolean(Value);
end;

procedure TNxCheckBox6.SetAsString(const Value: WideString);
begin
  Checked := StrToBoolDef(Value, False);
end;

procedure TNxCheckBox6.SetButtonState(const Value: TNxButtonState);
begin
  if Value <> FButtonState then
  begin
    FButtonState := Value;

    { Refresh }
    InvalidateControl(Handle, CheckBoxRect);
  end;
end;

procedure TNxCheckBox6.SetChecked(const Value: Boolean);
begin
  if Value then State := cbChecked else State := cbUnchecked;
end;

procedure TNxCheckBox6.SetIndent(const Value: Integer);
begin
  if Value <> FIndent then
  begin
    FIndent := Value;
    Invalidate;
  end;
end;

procedure TNxCheckBox6.SetState(const Value: TCheckBoxState);
begin
  if FState <> Value then
  begin
    FState := Value;

    { Trigger event }
    DoChange;

    { Refresh }
    if HandleAllocated then InvalidateRect(CheckBoxRect);
  end;
end;

procedure TNxCheckBox6.SetTagString(const Value: string);
begin
  FTagString := Value;
end;

procedure TNxCheckBox6.SetVerticalAlignment(const Value: TVerticalAlignment);
begin
  if Value <> FVerticalAlignment then
  begin
    FVerticalAlignment := Value;
    Invalidate;
  end;
end;

procedure TNxCheckBox6.Toggle;
begin
  case State of
    cbUnchecked:
      if AllowGrayed then State := cbGrayed else State := cbChecked;
    cbChecked: State := cbUnchecked;
    cbGrayed: State := cbChecked;
  end;
end;

procedure TNxCheckBox6.WMKillFocus(var Msg: TWMKillFocus);
begin
  inherited;
  Invalidate;
end;

procedure TNxCheckBox6.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;
  Invalidate;
end;

{ TNxFontComboBox6 }

constructor TNxFontComboBox6.Create(AOwner: TComponent);
begin
  inherited;
  FPaintInFont := True;
  Items.Assign(Screen.Fonts);
end;

procedure TNxFontComboBox6.PaintContent(const Index: Integer;
  CellRect: TRect; State: TOwnerDrawState);
begin
  if not PaintInFont then inherited else
    with PopupControl.Canvas do
    begin
      { Padding }
      Inc(CellRect.Left, pdStandard);

      Font.Name := Items[Index];
      DrawTextRect(PopupControl.Canvas, CellRect, taLeftJustify, taVerticalCenter, Items[Index], wkNone);
    end;
end;

procedure TNxFontComboBox6.PaintPreviewContent(PreviewRect: TRect);
begin
  inherited;

  with Canvas do
  begin
    Brush.Color := clHighlight;
    Font.Size := 8;
    Font.Color := clHighlightText;
    Font.Name := Text;
    TextRect(PreviewRect, PreviewRect.Left, PreviewRect.Top, 'ab');
  end;
end;

{ TNxColorComboBox6 }

constructor TNxColorComboBox6.Create(AOwner: TComponent);
begin
  inherited;

  { Add WebColors }
  Populate;

  { Init. }
  FShowNames := True;
  ItemHeight := 19;
end;

procedure TNxColorComboBox6.PaintContent(const Index: Integer; CellRect: TRect;
  State: TOwnerDrawState);
var
  PreviewRect, TextRect: TRect;
  WebColor: string;
begin
  with PopupControl.Canvas do
  begin

    { Paint preview }
    PreviewRect := CellRect;
    InflateRect(PreviewRect, -2, -2);
    PreviewRect.Right := PreviewRect.Left + szPreviewWidth;

    Brush.Color := clGray;
    FrameRect(PreviewRect);

    { Exclude border }
    InflateRect(PreviewRect, -1, -1);

    Brush.Color := WebColorToColor(Items[Index]);
    FillRect(PreviewRect);

    { Padding }
    Inc(CellRect.Left, pdStandard);
  end;

  { Paint value }
  TextRect := CellRect;
  TextRect.Left := PreviewRect.Right + pdStandard + 1;
  DrawTextRect(PopupControl.Canvas, TextRect, taLeftJustify, taVerticalCenter, Items[Index], wkNone);

  { Paint name }
  if ShowNames then
  begin
    WebColor := WebColorName(Items[Index]);

    if WebColor <> EmptyStr then
    begin
      TextRect := CellRect;
      Dec(TextRect.Right, pdStandard);
      PopupControl.Canvas.Font.Color := IfThen(odSelected in State, clHighlightText, clGrayText);
      DrawTextRect(PopupControl.Canvas, TextRect, taRightJustify, taVerticalCenter, WebColor, wkNone);
    end;
  end;

end;

procedure TNxColorComboBox6.PaintPreviewContent(PreviewRect: TRect);
begin
  with Canvas do
  begin
    Brush.Color := StrToColor(Text);
    FillRect(PreviewRect);
  end;
end;

procedure TNxColorComboBox6.Populate;
var
  i: Integer;
  ColorName: TWebColor;
begin

  if FItems.Count = 0 then
  begin

    for i := 0 to High(WebColors) do
    begin
      ColorName := WebColors[i];
      Items.Add(ColorName[cnColorValue]);
    end;

  end;

end;

{ TNxColorPicker6 }

constructor TNxColorPicker6.Create(AOwner: TComponent);
begin
  inherited;
  FColorKind := ckDelphi;
end;

function TNxColorPicker6.CreatePopupControl: INxPopupControl;
begin
  Result := TNxColorPopupControl6.Create(Self);
end;

function TNxColorPicker6.GetColorKind: TNxColorKind;
begin
  Result := FColorKind;
end;

function TNxColorPicker6.GetSelectedColor: TColor;
begin
  { Try all conversions }
  Result := StrToColor(Text);
end;

procedure TNxColorPicker6.PaintPreviewContent(PreviewRect: TRect);
begin
  with Canvas do
  begin
    Brush.Color := StrToColor(Text);
    FillRect(PreviewRect);
  end;
end;

procedure TNxColorPicker6.SetSelectedColor(const Value: TColor);
begin
  case ColorKind of
    ckDelphi: Text := ColorToString(Value);
    ckWeb: Text := ColorToWebColor(Value);
  end;
end;

{ TNxIconPicker6 }

constructor TNxIconPicker6.Create(AOwner: TComponent);
begin
  inherited;
  FColCount := 6;
  FImages := nil;
end;

function TNxIconPicker6.CreatePopupControl: INxPopupControl;
begin
  Result := TNxIconPopupControl6.Create(Self);
end;

function TNxIconPicker6.GetColCount: Integer;
begin
  Result := FColCount;
end;

function TNxIconPicker6.GetDisplayText(const Index: Integer): string;
begin
  Result := IntToStr(Index);
end;

function TNxIconPicker6.GetImages: TCustomImageList;
begin
  Result := FImages;
end;

function TNxIconPicker6.GetItemIndex: Integer;
begin
  Result := FItemIndex;
end;

procedure TNxIconPicker6.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited;
  if DroppedDown then
    case Key of
      VK_LEFT: ItemIndex := ItemIndex - 1;
      VK_RIGHT:ItemIndex := ItemIndex + 1;
      VK_UP:   ItemIndex := ItemIndex - ColCount;
      VK_DOWN: ItemIndex := ItemIndex + ColCount;
      VK_HOME: ItemIndex := 0;
      VK_END:  if Assigned(FImages) then ItemIndex := Pred(FImages.Count);
    end
  else
    case Key of
      VK_UP:   ItemIndex := ItemIndex - 1;
      VK_DOWN: ItemIndex := ItemIndex + 1;
      VK_HOME: ItemIndex := 0;
      VK_END:  if Assigned(FImages) then ItemIndex := Pred(FImages.Count);
    end;
end;

procedure TNxIconPicker6.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited;
  if AComponent = FImages then
  begin
    FImages := nil;
    Invalidate;
  end;
end;

procedure TNxIconPicker6.PaintPreviewContent(PreviewRect: TRect);
var
  Location: TPoint;
begin
  with Canvas do
  begin
    Brush.Color := Color;
    FillRect(PreviewRect);
    if Assigned(Images) then
    begin
      Location := PosInRect(Images.Width, Images.Height, PreviewRect, Classes.taCenter, taVerticalCenter);
      Images.Draw(Canvas, Location.X, Location.Y, GetAsInteger);
    end;
  end;
end;

procedure TNxIconPicker6.SetImages(const Value: TCustomImageList);
begin
  if Value <> FImages then
  begin
    if Value = nil then FImages.RemoveFreeNotification(Self)
      else Value.FreeNotification(Self);

    FImages := Value;
  end;
end;

procedure TNxIconPicker6.SetItemIndex(const Value: Integer);
begin
  { Note: -1 also not alowed }
  if Assigned(FImages)
    and InRange(Value, 0, Pred(FImages.Count))
    and (Value <> FItemIndex) then
  begin

    FItemIndex := Value;

    Text := GetDisplayText(FItemIndex);

    if DroppedDown then
    begin
      { Scroll, repaint etc. }
      FPopupControl.UpdatePopup;

      { Note: popup block repaint, invalidate
              also don't help (!?) }
      Refresh;
    end;

  end;
end;

{ TNxMaskEdit6 }

procedure TNxMaskEdit6.AssignValue(Source: INxBase);
begin
  SetAsString(Source.AsString);
end;

function TNxMaskEdit6.CanDispatchKey(Key: Word): Boolean;
begin
  { Default }
  Result := True;

  case Key of
    VK_LEFT, VK_RIGHT, VK_HOME, VK_END, VK_DELETE, VK_BACK: Result := False;
    VK_DOWN, VK_UP: Result := not (ssAlt in ShiftState);
  end;
end;

constructor TNxMaskEdit6.Create(AOwner: TComponent);
begin
  inherited;
  FPadding := TPadding.Create(Self);
end;

destructor TNxMaskEdit6.Destroy;
begin
  FreeAndNil(FPadding);
  inherited;
end;

procedure TNxMaskEdit6.BeginEdit(Key: WideChar);
begin
  BeginEdit; { Overloaded Method }

  AutoSelect := False;

  SendMessage(Handle, WM_CHAR, Ord(Key), 0);

  { Move Caret to last Pos. }
  SelStart := Length(Text);
end;

procedure TNxMaskEdit6.BeginEdit;
begin
  AutoSize := False;
  BorderStyle := bsNone;
  SelStart := Length(Text);
end;

procedure TNxMaskEdit6.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := Params.Style or (ES_AUTOHSCROLL or ES_AUTOVSCROLL)
  	or WS_CLIPCHILDREN or AlignmentStyles[FAlignment];
end;

procedure TNxMaskEdit6.EndEdit;
begin

end;

function TNxMaskEdit6.GetAsFloat: Double;
begin
  Result := StrToFloatDef(Text, 0);
end;

function TNxMaskEdit6.GetAsInteger: Integer;
begin
  Result := StrToIntDef(Text, 0);
end;

function TNxMaskEdit6.GetAsString: WideString;
begin
  Result := Text;
end;

function TNxMaskEdit6.GetEnabled: Boolean;
begin
  Result := inherited GetEnabled;
end;

function TNxMaskEdit6.GetHandle: HWND;
begin
  Result := inherited Handle;
end;

function TNxMaskEdit6.GetOnAssignEditing: TNotifyEvent;
begin

end;

function TNxMaskEdit6.GetOnChange: TNotifyEvent;
begin

end;

function TNxMaskEdit6.GetPadding: TPadding;
begin
  Result := FPadding;
end;

function TNxMaskEdit6.GetShowing: Boolean;
begin
  Result := inherited Showing;
end;

function TNxMaskEdit6.GetText: string;
begin
  Result := inherited Text;
end;

procedure TNxMaskEdit6.SetAlignment(const Value: TAlignment);
begin
  FAlignment := Value;
  RecreateWnd;
end;

procedure TNxMaskEdit6.SetAsFloat(const Value: Double);
begin
  Text := FloatToStr(Value);
end;

procedure TNxMaskEdit6.SetAsInteger(const Value: Integer);
begin
  Text := IntToStr(Value);
end;

procedure TNxMaskEdit6.SetAsString(const Value: WideString);
begin
  Text := Value;
end;

procedure TNxMaskEdit6.SetAutoSelect(const Value: Boolean);
begin
  AutoSelect := Value;
end;

procedure TNxMaskEdit6.SetColor(const Value: TColor);
begin
  Color := Value;
end;

procedure TNxMaskEdit6.SetEditOptions(const Value: TNxEditOptions);
begin

end;

procedure TNxMaskEdit6.SetEditPadding(const Leading, Trailing: Integer);
begin

end;

procedure TNxMaskEdit6.SetEnabled(Value: Boolean);
begin
  inherited;
end;

procedure TNxMaskEdit6.SetFont(const Value: TFont);
begin
  Font := Value;
end;

procedure TNxMaskEdit6.SetOnAssignEditing(const Value: TNotifyEvent);
begin

end;

procedure TNxMaskEdit6.SetOnChange(const Value: TNotifyEvent);
begin

end;

procedure TNxMaskEdit6.SetPadding(const Value: TPadding);
begin
  FPadding.Assign(Value);
end;

procedure TNxMaskEdit6.SetReadOnly(const Value: Boolean);
begin
  ReadOnly := Value;
end;

procedure TNxMaskEdit6.SetText(const Value: string);
begin
  Text := Value;
end;

procedure TNxMaskEdit6.SetWantTabs(const Value: Boolean);
begin

end;

{ TNxTagsPanel6 }

function TNxTagsPanel6.ButtonSize: TSize;
begin
  Result := DotToPixel(Size(13, 13));
end;

procedure TNxTagsPanel6.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  HotTagButton := -1;
end;

constructor TNxTagsPanel6.Create(AOwner: TComponent);
begin
  inherited;
  ParentColor := True;
  ParentFont := True;
  FHotTagButton := -1;
  FPressedTagButton := -1;
  FPressedTag := -1;
  FTags := nil;
  Width := 0;
end;

procedure TNxTagsPanel6.CreateWnd;
begin
  inherited;
  UpdateWidth;
end;

function TNxTagsPanel6.GetCloseButtonColor(const AState: TNxButtonState): TColor;
begin
  with Owner as TNxTagsEdit6 do
    case TagsBackgroundStyle of
      stUserDefined:
      begin
        Result := UserDefinedColorPalette.GeometryColor;
        if bsHover in AState then Result := UserDefinedColorPalette.GeometryHoverColor;
        if bsPressed in AState then Result := UserDefinedColorPalette.GeometryHoverColor;
      end;
      else
      begin
        Result := clSilver;
        if bsHover in AState then Result := clBlack;
        if bsPressed in AState then Result := clMaroon;
      end;
    end;
end;

function TNxTagsPanel6.GetTagAtPos(const X, Y: Integer;
  InButton: Boolean): Integer;
var
  Location: TPoint;
  TagSize: TSize;
  TagRect, ButtonRect: TRect;
  i: Integer;
begin
  inherited;
  Result := -1;

  Location := Point(0, 0);

  { Loop & check }
  for i := 0 to Pred(Tags.Count) do
  begin
    TagSize := GetTagSize(i);
    TagRect := Bounds(Location.X, Location.Y, TagSize.cx, TagSize.cy);

    if not InButton then
    begin

      if PtInRect(TagRect, Point(X, Y)) then
      begin
        Result := i;
        Exit;
      end;

    end else
    begin

      ButtonRect := Bounds(TagRect.Right - ButtonSize.cx - pdDouble, TagRect.Top, ButtonSize.cx, ButtonSize.cy);
      OffsetRect(ButtonRect, 0, ClientHeight div 2 - ButtonSize.cy div 2);

      if PtInRect(ButtonRect, Point(X, Y)) then
      begin
        Result := i;
        Exit;
      end;
    end;

    OffsetPoint(Location, TagSize.cx + 1, 0);
  end;
end;

function TNxTagsPanel6.GetTagSize(const Index: Integer): TSize;
begin
  Canvas.Font.Assign(Font);
  Result := Size(GetTextSize(Canvas, FTags[Index], True).cx + (pdDouble * 2) + pdDouble + ButtonSize.cx,
    ClientHeight);
end;

procedure TNxTagsPanel6.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  inherited;
  if Button = mbLeft then
  begin
    PressedTagButton := GetTagAtPos(X, Y, True);
    FPressedTag := GetTagAtPos(X, Y, False);
    { Trigger event }
    with Owner as TNxTagsEdit6 do
    begin
      DoMouseDown(Button, Shift, X, Y, csTagArea);
    end;
  end;
end;

procedure TNxTagsPanel6.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
  inherited;
  HotTagButton := GetTagAtPos(X, Y, True);
  FPressedTag  := GetTagAtPos(X, Y, False);
  { Trigger event }
  with Owner as TNxTagsEdit6 do
  begin
    DoMouseMove(Shift, X, Y, csTagArea);
  end;
end;

procedure TNxTagsPanel6.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
var
  CanDelete: Boolean;
begin
  inherited;
  try
    if Button = mbLeft then
    begin

      if (GetTagAtPos(X, Y, True) = PressedTagButton)
        and InRange(PressedTagButton, 0, Pred(FTags.Count)) then
      begin

        CanDelete := True;
        with Owner as TNxTagsEdit6 do
        begin
          DoTagDelete(PressedTagButton, CanDelete);
        end;

        if CanDelete then
        begin
          Tags.Delete(PressedTagButton);
          UpdateWidth;
          FPressedTag := -1;
        end;
      end
      else FPressedTag := GetTagAtPos(X, Y, False);

    end;
    { Trigger event }
    with Owner as TNxTagsEdit6 do
    begin
      DoMouseUp(Button, Shift, X, Y, csTagArea);
    end;
  finally
    PressedTagButton := -1;
  end;
end;

procedure TNxTagsPanel6.DragOver(Source: TObject; X, Y: Integer; State: TDragState;
  var Accept: Boolean);
begin
  FPressedTag := GetTagAtPos(X, Y, False);
  with Owner as TNxTagsEdit6 do
  begin
    DoDragOver(Source, X, Y, State, Accept, csTagArea);
  end;
end;

procedure TNxTagsPanel6.DragDrop(Source: TObject; X, Y: Integer);
begin
  with Owner as TNxTagsEdit6 do
  begin
    DoDragDrop(Source, X, Y, csTagArea);
  end;
end;



procedure TNxTagsPanel6.Paint;
var
  Location: TPoint;
  TagSize: TSize;
  TagRect, TextRect, ButtonRect: TRect;
  i: Integer;
  ButtonState: TNxButtonState;
begin
  inherited;
  Location := Point(0, 0);

  { Loop & paint }
  for i := 0 to Pred(Tags.Count) do
  begin
    TagSize := GetTagSize(i);
    TagRect := Bounds(Location.X, Location.Y, TagSize.cx, TagSize.cy);

    with Canvas do
    begin
      PaintTagBackground(i, TagRect);

      { Spacing }
      Pen.Color := Color;
      Polyline([
        Point(TagRect.Right, TagRect.Top),
        Point(TagRect.Right, TagRect.Bottom)
      ]);

      { Tag Close Button }
      ButtonRect := Bounds(TagRect.Right - ButtonSize.cx - pdDouble, TagRect.Top, ButtonSize.cx, ButtonSize.cy);
      OffsetRect(ButtonRect, 0, ClientHeight div 2 - ButtonSize.cy div 2);

      ButtonState := [];
      if i = FHotTagButton then Include(ButtonState, bsHover);
      if i = FPressedTagButton then Include(ButtonState, bsPressed);
      PaintCloseButton(ButtonRect, ButtonState);
    end;

    { Text }
    TextRect := TagRect;
    InflateRect(TextRect, -pdDouble, 0);

    DrawTextRect(Canvas, TextRect, taLeftJustify, taVerticalCenter,
      FTags[i], wkNone);

    OffsetPoint(Location, TagSize.cx + 1, 0);
  end;
end;

procedure TNxTagsPanel6.PaintCloseButton(ButtonRect: TRect;
  ButtonState: TNxButtonState);
var
  Z: Integer;
  SignRect: TRect;
begin
  SignRect := ButtonRect;
  InflateRect(SignRect, -DotToPixel(pdStandard), -DotToPixel(pdStandard));
  Z := 1;
  with Canvas, SignRect do
  begin
    Pen.Color := GetCloseButtonColor(ButtonState);
    Brush.Color := Pen.Color;
    Polygon([
      Point(Left, Top + Z),
      Point(Pred(Right) - Z, Pred(Bottom)),
      Point(Pred(Right), Pred(Bottom)),
      Point(Pred(Right), Pred(Bottom) - Z),
      Point(Left + Z, Top),
      Point(Left, Top)
    ]);
    Polygon([
      Point(Pred(Right) - Z, Top),
      Point(Left, Pred(Bottom) - Z),
      Point(Left, Pred(Bottom)),
      Point(Left + Z, Pred(Bottom)),
      Point(Pred(Right), Top + Z),
      Point(Pred(Right), Top)
    ]);
  end;
end;

procedure TNxTagsPanel6.PaintNativeTagBackground(const Index: Integer;
  TagRect: TRect);
var
  FillColor, BorderColor: TColor;
begin
  with Owner as TNxTagsEdit6, Self.Canvas do
  begin
    if CanStyle(soVCLStyles) or CanStyle(soNativeStyles) then
    begin
      Brush.Color := clWhite;
      FillRect(TagRect);
      TNxToolbarStyle6.Paint(Self.Canvas, Self.Handle, TagRect, [bsHover], StyleOptions, False);
    end else
    begin
      FillColor := clBtnFace;
      BorderColor := TagBorderColor;

      { Trigger event }
      DoGetTabColor(Index, FillColor, BorderColor);

      Pen.Color := BorderColor;
      Brush.Color := FillColor;
      case TagsStyle of
        tsRectangle: Rectangle(TagRect);
        tsRoundRect: RoundRect(TagRect.Left, TagRect.Top, RectWidth(TagRect), RectHeight(TagRect), RectHeight(TagRect), RectHeight(TagRect));
      end;
    end;
  end;
end;

procedure TNxTagsPanel6.PaintTagBackground(const Index: Integer; TagRect: TRect);
begin
  with Owner as TNxTagsEdit6 do
    case TagsBackgroundStyle of
      stNative, stModern: PaintNativeTagBackground(Index, TagRect);
      stUserDefined: PaintUserDefinedTagBackground(Index, TagRect);
    end;
end;

procedure TNxTagsPanel6.PaintUserDefinedTagBackground(const Index: Integer;
  TagRect: TRect);
var
  FillColor, BorderColor: TColor;
begin
  with Owner as TNxTagsEdit6, Self.Canvas do
  begin
    FillColor := UserDefinedColorPalette.ButtonColor;
    BorderColor := TagBorderColor;

    { Trigger event }
    DoGetTabColor(Index, FillColor, BorderColor);

    Pen.Color := BorderColor;
    Brush.Color := FillColor;
    case TagsStyle of
      tsRectangle: Rectangle(TagRect);
      tsRoundRect: RoundRect(TagRect.Left, TagRect.Top, RectWidth(TagRect), RectHeight(TagRect), RectHeight(TagRect), RectHeight(TagRect));
    end;
  end;
end;

procedure TNxTagsPanel6.SetHotTagButton(const Value: Integer);
begin
  if Value <> FHotTagButton then
  begin
    FHotTagButton := Value;
    Invalidate;
  end;
end;

procedure TNxTagsPanel6.SetPressedTagButton(const Value: Integer);
begin
  if Value <> FPressedTagButton then
  begin
    FPressedTagButton := Value;
    Invalidate;
  end;
end;

procedure TNxTagsPanel6.SetTags(const Value: TStrings);
begin
  FTags := Value;
end;

procedure TNxTagsPanel6.UpdateWidth;
var
  i, W: Integer;
begin
  if HandleAllocated then
  begin
    W := 0;
    for i := 0 to Pred(FTags.Count) do
    begin
      Inc(W, GetTagSize(i).cx + 1);
    end;
    Width := W;
  end;
end;

procedure TNxTagsPanel6.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
  Message.Result := 1;
end;

{ TNxTagsEdit6 }

function TNxTagsEdit6.AddTags: Integer;
var
  Index: Integer;
  S, Tag: WideString;
  C: WideString;

  function AddTag: Boolean;
  var
    Value: WideString;
    Accept: Boolean;
  begin
    AddTag := False;

    Value := Tag;
    if Value <> '' then
    begin
      if FTags.IndexOf(Value) = -1 then
      begin
        Accept := FTags.Count < FMax;

        { Trigger event }
        DoTagAdd(Value, Accept);

        { Do add? }
        if Accept then
        begin
          FTags.Add(Value);

          AddTag := True;
          Tag := '';

          Delete(S, 1, Index);
          Index := 0;
        end;

      end;
    end;
  end;

begin

  Result := 0;
  Tag := '';
  S := Text;

  Index := 1;
  while Index <= Length(S) do
  begin
    C := S[Index];

    if (Pos(C, Separators) > 0) then
    begin
      if FTags.Count >= FMax then
      begin
        Text := S;
        Exit;
      end;

      if AddTag then Inc(Result);

      Inc(Index);
      Continue;
    end;

    Tag := Tag + C;
    Inc(Index);
  end;

  if AddTag then Inc(Result);

  Text := S;

  FPanel.UpdateWidth;
  FPanel.Refresh;
end;

function TNxTagsEdit6.SelectedTag: Integer;
begin
  Result := FPanel.FPressedTag;
end;

procedure TNxTagsEdit6.CMPaste(var Msg: TMessage);
begin
  inherited;
  if AutoAdd then AddTags;
end;

procedure TNxTagsEdit6.CMTextChanged(var Message: TMessage);
begin
  inherited;
  if AutoAdd then AddTags;
end;

constructor TNxTagsEdit6.Create(AOwner: TComponent);
begin
  inherited;
  FAutoAdd := True;
  FMax := 6;
  FTagBorderColor := clSilver;
  FTags := TStringList.Create;
  TStringList(FTags).OnChange := DoTagsChange;
  FTagsBackgroundStyle := stNative;
  FTagsStyle := tsRectangle;
  FPanel := TNxTagsPanel6.Create(Self);
  FPanel.Tags := FTags;
  FSeparators := ' ,;|';
end;

procedure TNxTagsEdit6.CreateWnd;
begin
  inherited;
  FPanel.Parent := Self;
  FPanel.Align := alLeft;
  FPanel.Visible := True;
end;

destructor TNxTagsEdit6.Destroy;
begin
  FreeAndNil(FPanel);
  FreeAndNil(FTags);
  inherited;
end;

procedure TNxTagsEdit6.DoGetTabColor(Index: Integer; var FillColor: TColor;
  var BorderColor: TColor);
begin
  if Assigned(FOnGetTabColor) then FOnGetTabColor(Self, Index, FillColor, BorderColor);
end;

procedure TNxTagsEdit6.DoTagAdd(var Value: WideString; var Accept: Boolean);
begin
  if Assigned(FOnTagAdd) then FOnTagAdd(Self, Value, Accept);
end;

procedure TNxTagsEdit6.DoTagDelete(Index: Integer; var Accept: Boolean);
begin
  if Assigned(FOnTagDelete) then FOnTagDelete(Self, Index, Accept);
end;

procedure TNxTagsEdit6.DoTagsChange(Sender: TObject);
begin
  UpdatePanel;
end;



procedure TNxTagsEdit6.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  inherited;
  if Button = mbLeft then
  begin
    { Trigger event }
    DoMouseDown(Button, Shift, X, Y, csEditArea);
  end;
end;

procedure TNxTagsEdit6.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
  inherited;
  { Trigger event }
  DoMouseMove(Shift, X, Y, csEditArea);
end;

procedure TNxTagsEdit6.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
   inherited;
   { Trigger event }
   DoMouseUp(Button, Shift, X, Y, csEditArea);
end;

procedure TNxTagsEdit6.DragOver(Source: TObject; X, Y: Integer; State: TDragState;
  var Accept: Boolean);
begin
  DoDragOver(Source, X, Y, State, Accept, csEditArea);
end;

procedure TNxTagsEdit6.DragDrop(Source: TObject; X, Y: Integer);
begin
  DoDragDrop(Source, X, Y, csEditArea);
end;

procedure TNxTagsEdit6.DoMouseDown(Button: TMouseButton; Shift: TShiftState;
   X, Y: Integer; Area: TNxTagArea);
begin
  if Assigned(FOnTagMouseDown) then FOnTagMouseDown(Self, Button, Shift, X, Y, Area);
end;

procedure TNxTagsEdit6.DoMouseMove(Shift: TShiftState;
  X, Y: Integer; Area: TNxTagArea);
begin
  if Assigned(FOnTagMouseMove) then FOnTagMouseMove(Self, Shift, X, Y, Area);
end;

procedure TNxTagsEdit6.DoMouseUp(Button: TMouseButton; Shift: TShiftState;
   X, Y: Integer; Area: TNxTagArea);
begin
  if Assigned(FOnTagMouseUp) then FOnTagMouseUp(Self, Button, Shift, X, Y, Area);
end;

procedure TNxTagsEdit6.DoDragOver(Source: TObject; X, Y: Integer; State: TDragState;
  var Accept: Boolean; Area: TNxTagArea);
begin
  if Assigned(FOnTagDragOver) then FOnTagDragOver(Self, Source, X, Y, State, Accept, Area);
end;

procedure TNxTagsEdit6.DoDragDrop(Source: TObject; X, Y: Integer; Area: TNxTagArea);
begin
  if Assigned(FOnTagDragDrop) then FOnTagDragDrop(Self, Source, X, Y, Area);
end;

procedure TNxTagsEdit6.KeyPress(var Key: Char);
begin
  inherited;
  if (Key = #8) and (Text = '') then
  begin
    if Tags.Count > 0 then
      Tags.Delete(Pred(Tags.Count));
    FPanel.UpdateWidth;
  end;

  if AutoAdd and (Pos(Key, Separators) > 0) then
  begin
    if AddTags > 0
      then Key := #0;
  end;
end;

procedure TNxTagsEdit6.SetAutoAdd(const Value: Boolean);
begin
  FAutoAdd := Value;
  if FAutoAdd then AddTags;
end;

procedure TNxTagsEdit6.SetMax(const Value: Integer);
begin
  FMax := Value;
end;

procedure TNxTagsEdit6.SetTagBorderColor(const Value: TColor);
begin
  if Value <> FTagBorderColor then
  begin
    FTagBorderColor := Value;
    Invalidate;
  end;
end;

procedure TNxTagsEdit6.SetTags(const Value: TStrings);
begin
  FTags.Assign(Value);
end;

procedure TNxTagsEdit6.SetTagsPaintStyle(const Value: TNxAppearanceStyle);
begin
  if Value <> FTagsBackgroundStyle then
  begin
    FTagsBackgroundStyle := Value;
    FPanel.Invalidate;
  end;
end;

procedure TNxTagsEdit6.SetTagsStyle(const Value: TNxTagStyle);
begin
  if Value <> FTagsStyle then
  begin
    FTagsStyle := Value;
    FPanel.Invalidate;
  end;
end;

procedure TNxTagsEdit6.UpdatePanel;
begin
  FPanel.UpdateWidth;
  FPanel.Invalidate;
end;

procedure TNxTagsEdit6.WMKillFocus(var Msg: TWMKillFocus);
begin
  inherited;
  if AutoAdd then AddTags;
end;

{ TNxGridPicker6 }

function TNxGridPicker6.AddRow(Cells: array of WideString): TNxListRow6;
var
  i: Integer;
begin
  Result := TNxListRow6.Create;
  for i := Low(Cells) to High(Cells) do
  begin
    Result.AddCell(Cells[i]);
  end;
  FRowsList.Add(Result);
end;

procedure TNxGridPicker6.ClearRows;
var
  i: Integer;
begin
  for i := 0 to Pred(FRowsList.Count) do
  begin
    Row[i].Free;
  end;
  FRowsList.Clear;
end;

constructor TNxGridPicker6.Create(AOwner: TComponent);
begin
  inherited;
  FColumns := TNxGridPickerColumns.Create(Self);
  FDropDownCount := 8;
  FHeaderHeight := 18;
  FListWidth := 0;
  FRowHeight := 16;
  FRowsList := TList.Create;
  FSelectedIndex := -1;
end;

function TNxGridPicker6.CreatePopupControl: INxPopupControl;
begin
  Result := TNxGridPopupControl.Create(Self);
end;

procedure TNxGridPicker6.DeleteRow(const Index: Integer);
begin
  Row[Index].Free;
  FRowsList.Delete(Index);
end;

destructor TNxGridPicker6.Destroy;
begin
  ClearRows;
  FreeAndNil(FColumns);
  FreeAndNil(FRowsList);
  inherited;
end;

procedure TNxGridPicker6.DoSetValue(SelectedIndex: Integer; var Value: WideString);
begin
  if Assigned(FOnSetValue) then FOnSetValue(Self, SelectedIndex, Value);
  Text := Value;
end;

function TNxGridPicker6.GetColCount: Integer;
begin
  Result := FColumns.Count;
end;

function TNxGridPicker6.GetColumn(const Index: Integer): TNxGridPickerColumn;
begin
  Result := FColumns.Items[Index];
end;

function TNxGridPicker6.GetCount: Integer;
begin
  Result := FRowsList.Count;
end;

function TNxGridPicker6.GetDropDownCount: Integer;
begin
  Result := FDropDownCount;
end;

function TNxGridPicker6.GetHeaderHeight: Integer;
begin
  Result := FHeaderHeight;
end;

function TNxGridPicker6.GetListWidth: Integer;
begin
  Result := FListWidth;
end;

function TNxGridPicker6.GetRow(const Index: Integer): TNxListRow6;
begin
  Result := TNxListRow6(FRowsList[Index]);
end;

function TNxGridPicker6.GetRowHeight: Integer;
begin
  Result := FRowHeight;
end;

function TNxGridPicker6.GetSelectedIndex: Integer;
begin
  Result := FSelectedIndex;
end;

procedure TNxGridPicker6.SetColumns(const Value: TNxGridPickerColumns);
begin
  FColumns.Assign(Value);
end;

procedure TNxGridPicker6.SetDropDownCount(const Value: Integer);
begin
  FDropDownCount := Max(0, FDropDownCount);
end;

procedure TNxGridPicker6.SetSelectedIndex(const Value: Integer);
begin
  FSelectedIndex := Value;
end;

{ TNxLengthRange }

constructor TNxLengthRange.Create;
begin
  inherited;
  FMin := 0;
  FMax := 100;
end;

{ TNxTextValidator6 }

constructor TNxTextValidator6.Create(AOwner: TComponent);
begin
  inherited;
  FErrorCount := 0;
  FRequiredRange := TNxLengthRange.Create;
  FRequiredText := '';
end;

destructor TNxTextValidator6.Destroy;
begin
  FRequiredRange.Free;
  inherited;
end;

function TNxTextValidator6.GetErrorCount: Integer;
begin
  Result := FErrorCount;
end;

procedure TNxTextValidator6.SetRequiredRange(const Value: TNxLengthRange);
begin
  FRequiredRange.Assign(Value);
end;

function TNxTextValidator6.Validate(const Validatable: INxValidatable): TNxValidationResult;
var
  TextControl: INxTextControl;
begin
  FErrorCount := 0;

  if Supports(Validatable, INxTextControl, TextControl) then
  begin
    if Length(Trim(TextControl.Text)) < RequiredRange.Min then
    begin
      Inc(FErrorCount);
    end;

    if Length(Trim(TextControl.Text)) > RequiredRange.Max then
    begin
      Inc(FErrorCount);
    end;

    if RequiredText <> EmptyStr then
    begin
      if RequiredText <> TextControl.Text then Inc(FErrorCount);
    end;
  end;

  if FErrorCount > 0 then Result := vrInvalid
    else Result := vrValid;
end;

{ TNxFolderEdit6 }

constructor TNxFolderEdit6.Create(AOwner: TComponent);
begin
  inherited;
  FDialogCaption := 'Select folder';
  FRoot := '\';
end;

procedure TNxFolderEdit6.DoButtonClick(Sender: TObject);
var
  Folder: string;
begin
  inherited;
  Folder := Text;
  if SelectDirectory(FDialogCaption, FRoot, Folder) then
  begin
    Text := Folder;
  end;
end;

end.
