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

interface

uses
  { Standard }
  Classes, Types, Controls, Graphics,
  { Win32 }
  ImgList, ComCtrls,
  {$IFDEF UI_TYPES}UITypes,{$ENDIF}
  { TypeInfo }
  TypInfo,
  { Next Standard 6 }
  NxClasses6, NxIntf6, NxTypes6, NxEdit6, NxConsts6, NxPopupCtrls6, NxHTML6,
  { NextInspector 6 }
  NxAssociates6;

const
  szItemHeight = 17;
  szMinNodeHeight = 8;
  szDetailsMark = 7; { Both width & height }
  szSizeGrip = 10;
  szPreviewWidth = 28;
  IndicatorSize = 3;

type
  INxInspectorNodeView = interface;

  TNxInspectorNodeView = class;
  TNxInspectorNodeViewClass = class of TNxInspectorNodeView;

  TNxInspectorNode6 = class;
  TNxInspectorNodeClass = class of TNxInspectorNode6;

  TNxNodeNotificationKind = (ntCaptionChanged, ntCollapsed, ntExpanded, ntResized,
    ntToggle, ntLayoutChanged, ntVisibleChanged);

  INxNodeNotifyControl = interface
    ['{A0188EBA-5F71-4444-BEDF-3CF94C0D9CCD}']
    procedure NodeNotification(Node: TNxInspectorNode6; Kind: TNxNodeNotificationKind);
  end;

  { TNxInspectorNode6 Event Declarations }

  TNxCustomDrawNodeEvent = procedure (Sender: TNxInspectorNode6;
    var DrawingRect: TRect; Selected: Boolean) of object;
  TNxCustomDrawPreviewEvent = procedure (Sender: TNxInspectorNode6;
    Canvas: TCanvas; var PreviewRect: TRect) of object;
  TNxInspectorNodeNotifyEvent = procedure (Sender: TNxInspectorNode6) of object;
  TNxInspectorNodeGetTextEvent = procedure (Sender: TNxInspectorNode6;
    var Text: WideString) of object;

  { INxInspectorNodeView }
  TNxNodeViewNotifyEvent = procedure (Sender: INxInspectorNodeView) of object;

  { INxInspectorItems }
  TNxNodesChangeKind = (ncAdd, ncClear, ncDelete, ncPin);

  TNxNodesChangeEvent = procedure (Sender: TNxInspectorNode6; Kind: TNxNodesChangeKind;
    Param1, Param2: Integer) of object;

  TNxNodeAddPosition = (apFirst, apLast);
  TNxNodeIconPosition = (ipLeft, ipRight);

  TNxInspectorNodeState = set of (isEditing, ntPropertyReading);

  TNxSuffixPosition = (spAlongside, spLeft, spRight);

  TNxInspectorNodeCells = set of (icCaption, icValue);

  TNxInspectorNodeEditOptions = TNxEditOptions;
  TNxInspectorNodeOptions = set of (itoDetailsButton);
  TNxInspectorNodeStyle = set of (itExplicitChange);

  INxViewCanvas = interface
    ['{2B64C125-D182-4F04-8A5C-2E1FD6A62E53}']
    function GetCanvas: TCanvas;
    function GetHandle: THandle;
    property Canvas: TCanvas read GetCanvas;
    property Handle: THandle read GetHandle;
  end;

  INxInspectorControl = interface
    ['{3DD8FCA2-7DBD-4237-83A6-78D15B4FBE87}']
    { Property Accessors }
    function GetAssociates: TNxAssociates6;
    function GetFont: TFont;
    procedure SetNodeView(View: INxInspectorNodeView);
    { Properties }
    property Associates: TNxAssociates6 read GetAssociates;
    property Font: TFont read GetFont;
  end;

  { TNxInspectorNodes }

  TNxInspectorNodes = class
  private
    FControl: INxInspectorControl;
    FFilterText: WideString;
    FHideTopLevel: Boolean;
    FList: TList;
    FNotifications: TList;
    FOnNodeChanged: TNxInspectorNodeNotifyEvent;
    FOnNodesChanged: TNxNodesChangeEvent;
    FOwner: TComponent;
    FPinned: TList;
    FShowingCount: Integer;
    FShowingDelta: Integer;
    function GetCount: Integer;
    function GetFilterText: WideString;
    function GetHideTopLevel: Boolean;
    function GetNode(Index: Integer): TNxInspectorNode6;
    function GetNodeByName(Name: TComponentName): TNxInspectorNode6;
    function GetNotification(Index: Integer): INxNodeNotifyControl;
    function GetPinned(Index: Integer): TNxInspectorNode6;
    function GetPinnedCount: Integer;
    procedure SetFilterText(const Value: WideString);
    procedure SetHideTopLevel(const Value: Boolean);
    procedure SetNode(Index: Integer; const Value: TNxInspectorNode6);
    procedure SetParent(Node, Parent: TNxInspectorNode6; Position: TNxNodeAddPosition);
  protected
    { Event Handlers }
    procedure DoNodeChanged(Sender: TNxInspectorNode6); dynamic;
    procedure DoNodesChanged(Sender: TNxInspectorNode6; Kind: TNxNodesChangeKind;
      Param1, Param2: Integer); dynamic;
    { Methods }
    procedure MoveNode(List: TList; Node: TNxInspectorNode6;
      Index, ToIndex: Integer);
    function Recount: Integer;
    function GetNodeShowingCount(Node: TNxInspectorNode6): Integer;
    function GetPropertyText: string;
    procedure UpdateShowingCount(Value: Integer);
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
    { Methods }
    function Add(Parent: TNxInspectorNode6; NodeClass: TNxInspectorNodeClass;
      Position: TNxNodeAddPosition = apLast): TNxInspectorNode6;
    procedure AddNode(Parent, Node: TNxInspectorNode6;
      Position: TNxNodeAddPosition = apLast);
    procedure ChangeNotification(Control: INxNodeNotifyControl);
    procedure Clear;
    procedure ClearChildren(const ANode: TNxInspectorNode6);
    procedure Delete(const Index: Integer);
    function IndexOf(Node: TNxInspectorNode6): Integer;
    function Insert(Sibling: TNxInspectorNode6;
      NodeClass: TNxInspectorNodeClass): TNxInspectorNode6;
    procedure InsertNode(Sibling, Node: TNxInspectorNode6);
    procedure Notify(Node: TNxInspectorNode6; Kind: TNxNodeNotificationKind);
    { Properties }
    property Count: Integer read GetCount;
    property FilterText: WideString read GetFilterText write SetFilterText;
    property HideTopLevel: Boolean read GetHideTopLevel write SetHideTopLevel;
    property Node[Index: Integer]: TNxInspectorNode6 read GetNode write SetNode; default;
    property NodeByName[Name: TComponentName]: TNxInspectorNode6 read GetNodeByName;
    property List: TList read FList;
    property Notification[Index: Integer]: INxNodeNotifyControl read GetNotification;
    property Owner: TComponent read FOwner;
    property Pinned[Index: Integer]: TNxInspectorNode6 read GetPinned;
    property PinnedCount: Integer read GetPinnedCount;
    property ShowingCount: Integer read FShowingCount;
    property ShowingDelta: Integer read FShowingDelta;
    { Events }
    property OnNodeChanged: TNxInspectorNodeNotifyEvent read FOnNodeChanged write FOnNodeChanged;
    property OnNodesChanged: TNxNodesChangeEvent read FOnNodesChanged write FOnNodesChanged;
  end;

  INxInspectorStyle = interface(INxControlStyle)
    ['{BECBE807-10F6-406F-90E8-8FB155141CC7}']
    function GetBackgroundColor(const DefaultColor: TColor): TColor;
    function GetDividerColor: TColor;
    function GetGrayColor: TColor;
    function GetGridColor: TColor;
    function GetMarginColor(const Node: TNxInspectorNode6; const DefaultColor: TColor): TColor;
    function GetSelectionBorderColor: TColor;
    function GetSelectionColor: TColor;
    function GetSplitterColor: TColor;
    function GetTextColor(const Node: TNxInspectorNode6; Selected, Focused: Boolean): TColor;
    function GetToggleSize: TSize;
    function GetToggleStyle: TNxToggleButtonStyle;
    function GetTopLevelColor: TColor;
    procedure PaintToggle(ToggleRect: TRect; Expanded: Boolean; State: TNxButtonState);
    procedure PaintTopLevelSelection(SelectionRect: TRect);
    procedure SetGridColor(const Value: TColor);
    procedure SetSplitterColor(const Value: TColor);
    procedure SetToggleGlyphs(const Expand, Collapse: TBitmap);
    procedure SetToggleStyle(const Value: TNxToggleButtonStyle);
    procedure SetTopLevelColor(const Value: TColor);
    procedure DrawToggle(ButtonRect: TRect; Collapsed: Boolean);
    property GridColor: TColor read GetGridColor write SetGridColor;
    property SplitterColor: TColor read GetSplitterColor write SetSplitterColor;
    property ToggleStyle: TNxToggleButtonStyle read GetToggleStyle write SetToggleStyle;
    property TopLevelColor: TColor read GetTopLevelColor write SetTopLevelColor;
  end;

  { INxInspectorNodeView }

  TNxInspectorNodeEntity = set of (etCaption, etValue);

  TNxInspectorNodeViewOptions = set of (voModifiedIndicators, voSelected, voShowMargin);

  INxInspectorNodeView = interface(INxObjectView)
    ['{FC387199-FE62-4576-B161-C6D3B1A8B402}']
    { Property Accessors }
    function GetCaptionRect: TRect;
    function GetCaptionTextRect: TRect;
    function GetCaptionTextSize: TSize;
    function GetContentHeight: Integer;
    function GetContentRect: TRect;
    function GetContentWidth: Integer;
    function GetDetailsButtonRect: TRect;
    function GetDetailsButtonState: TNxButtonState;
    function GetEditRect: TRect;
    function GetImagePosition: TNxNodeIconPosition;
    function GetImages: TCustomImageList;
    function GetNode: TNxInspectorNode6;
    function GetNodeState: TNxInspectorNodeState;
    function GetMarginColor: TColor;
    function GetMarginWidth: Integer;
    function GetNonEditRect: TRect;
    function GetOnChange: TNxNodeViewNotifyEvent;
    function GetOptions: TNxInspectorNodeViewOptions;
    function GetPreviewPopup: Boolean;
    function GetSelected: Boolean;
    function GetShowMargin: Boolean;
    function GetSizeGripRect: TRect;
    function GetSplitterPosition: Integer;
    function GetTextRect: TRect;
    function GetToggleRect: TRect;
    function GetToggleStyle: TNxToggleButtonStyle;
    function GetUseTopLevelColor: Boolean;
    function GetValue: WideString;
    function GetValueRect: TRect;
    procedure SetDetailsButtonState(const Value: TNxButtonState);
    procedure SetImagePosition(const Value: TNxNodeIconPosition);
    procedure SetImages(const Value: TCustomImageList);
    procedure SetNodeState(const Value: TNxInspectorNodeState);
    procedure SetMarginColor(const Value: TColor);
    procedure SetMarginWidth(const Value: Integer);
    procedure SetOnChange(const Value: TNxNodeViewNotifyEvent);
    procedure SetOptions(const Value: TNxInspectorNodeViewOptions);
    procedure SetPreviewPopup(const Value: Boolean);
    procedure SetSelected(const Value: Boolean);
    procedure SetShowMargin(const Value: Boolean);
    procedure SetSplitterPosition(const Value: Integer);
    procedure SetToggleStyle(const Value: TNxToggleButtonStyle);
    procedure SetUseTopLevelColor(const Value: Boolean);
    { Methods }
    procedure AssignNode;
    { Assign Value to Item }
    procedure AssignValue;
    function CanCaptionFit: Boolean;
    function CanValueFit: Boolean;
    function CaptureMouse: Boolean;
    procedure Changed;
    function HasContent: Boolean;
    procedure PaintCaption;
    procedure PaintMargin;
    procedure PaintSplitter;
    procedure PaintToggle;
    procedure PaintValue;
    function PreferedSize(Entities: TNxInspectorNodeEntity = [etValue]): TSize;
    procedure Refresh; overload;
    procedure Refresh(InvalidationRect: TRect); overload;
    procedure RefreshDetailsButton;
    procedure Invalidate(IncludePadding: Boolean = False);
    procedure InvalidateIndicator;
    { Properties }
    property CaptionRect: TRect read GetCaptionRect;
    property CaptionTextSize: TSize read GetCaptionTextSize;
    property CaptionTextRect: TRect read GetCaptionTextRect;
    property ContentHeight: Integer read GetContentHeight;
    property ContentRect: TRect read GetContentRect;
    property ContentWidth: Integer read GetContentWidth;
    property DetailsButtonRect: TRect read GetDetailsButtonRect;
    property DetailsButtonState: TNxButtonState read GetDetailsButtonState write SetDetailsButtonState;
    property EditRect: TRect read GetEditRect;
    property ImagePosition: TNxNodeIconPosition read GetImagePosition write SetImagePosition;
    property Images: TCustomImageList read GetImages write SetImages;
    property Node: TNxInspectorNode6 read GetNode;
    property NodeState: TNxInspectorNodeState read GetNodeState write SetNodeState;
    property MarginColor: TColor read GetMarginColor write SetMarginColor;
    property MarginWidth: Integer read GetMarginWidth write SetMarginWidth;
    property NonEditRect: TRect read GetNonEditRect;
    property Options: TNxInspectorNodeViewOptions read GetOptions write SetOptions;
    property PreviewPopup: Boolean read GetPreviewPopup write SetPreviewPopup;
    property Selected: Boolean read GetSelected write SetSelected;
    property ShowMargin: Boolean read GetShowMargin write SetShowMargin;
    property SizeGripRect: TRect read GetSizeGripRect;
    property SplitterPosition: Integer read GetSplitterPosition write SetSplitterPosition;
    property TextRect: TRect read GetTextRect;
    property ToggleRect: TRect read GetToggleRect;
    property ToggleStyle: TNxToggleButtonStyle read GetToggleStyle write SetToggleStyle;
    property UseTopLevelColor: Boolean read GetUseTopLevelColor write SetUseTopLevelColor;
    property Value: WideString read GetValue;
    property ValueRect: TRect read GetValueRect;
    { Events }
    property OnChange: TNxNodeViewNotifyEvent read GetOnChange write SetOnChange;
  end;

  { TNxInspectorNodeView }

  TNxInspectorNodeView = class(TInterfacedObject, INxInspectorNodeView,
    INxDropDown)
  private
    { Fields }
    FCanvas: TCanvas;
    FClientRect: TRect;
    FControl: TWinControl;
    FDetailsButtonState: TNxButtonState;
    FImagePosition: TNxNodeIconPosition;
    FImages: TCustomImageList;
    FMarginColor: TColor;
    FMarginWidth: Integer;
    FNode: TNxInspectorNode6;
    FNodeState: TNxInspectorNodeState;
    FOnChange: TNxNodeViewNotifyEvent;
    FOptions: TNxInspectorNodeViewOptions;
    FOwner: INxViewComponent;
    FPreviewPopup: Boolean;
    FPreviewPopupControl: TNxPreviewPopupControl;
    FSelected: Boolean;
    FShowMargin: Boolean;
    FSplitterPosition: Integer;
    FStyle: INxControlStyle;
    FToogleStyle: TNxToggleButtonStyle;
    FUseTopLevelColor: Boolean;
    { Property Accessors }
    function GetAutoClose: Boolean;
    function GetCanvas: TCanvas;
    function GetCaptionContentRect: TRect;
    function GetCaptionPrefferedWidth: Integer;
    function GetCaptionRect: TRect;
    function GetCaptionTextRect: TRect;
    function GetCaptionTextSize: TSize;
    function GetCellsRect: TRect;
    function GetClientRect: TRect;
    function GetContentHeight: Integer;
    function GetContentWidth: Integer;
    function GetControl: TWinControl;
    function GetDetailsButtonRect: TRect;
    function GetDetailsButtonState: TNxButtonState;
    function GetDroppedDown: Boolean;
    function GetFont: TFont;
    function GetHeight: Integer;
    function GetImagePosition: TNxNodeIconPosition;
    function GetImages: TCustomImageList;
    function GetInteractiveRect: TRect;
    function GetMarginColor: TColor;
    function GetMarginWidth: Integer;
    function GetNode: TNxInspectorNode6;
    function GetNodeState: TNxInspectorNodeState;
    function GetOnChange: TNxNodeViewNotifyEvent;
    function GetOptions: TNxInspectorNodeViewOptions;
    function GetOwner: INxViewComponent;
    function GetPreviewPopup: Boolean;
    function GetPreviewRect: TRect;
    function GetSelected: Boolean;
    function GetShowMargin: Boolean;
    function GetSizeGripRect: TRect;
    function GetSplitterPosition: Integer;
    function GetStyle: INxControlStyle;
    function GetToggleRect: TRect;
    function GetToggleStyle: TNxToggleButtonStyle;
    function GetUseTopLevelColor: Boolean;
    function GetValueRect: TRect;
    procedure SetCanvas(const Value: TCanvas);
    procedure SetClientRect(const Value: TRect);
    procedure SetControl(const Value: TWinControl);
    procedure SetDetailsButtonState(const Value: TNxButtonState);
    procedure SetDroppedDown(const Value: Boolean);
    procedure SetFont(const Value: TFont);
    procedure SetImagePosition(const Value: TNxNodeIconPosition);
    procedure SetImages(const Value: TCustomImageList);
    procedure SetMarginColor(const Value: TColor);
    procedure SetMarginWidth(const Value: Integer);
    procedure SetNodeState(const Value: TNxInspectorNodeState);
    procedure SetOnChange(const Value: TNxNodeViewNotifyEvent);
    procedure SetOptions(const Value: TNxInspectorNodeViewOptions);
    procedure SetOwner(const Value: INxViewComponent);
    procedure SetPreviewPopup(const Value: Boolean);
    procedure SetSelected(const Value: Boolean);
    procedure SetShowMargin(const Value: Boolean);
    procedure SetSplitterPosition(const Value: Integer);
    procedure SetStyle(const Value: INxControlStyle);
    procedure SetToggleStyle(const Value: TNxToggleButtonStyle);
    procedure SetUseTopLevelColor(const Value: Boolean);
  protected
    procedure DoPreviewPopupHide(Sender: TObject);
    function ToObject: TObject;
    function GetAsString: WideString; virtual;
    procedure DoChange; dynamic;
    procedure DoCloseUp; dynamic;
    procedure DoSelect; dynamic;
    function DrawingIndent: Integer; virtual;
    { Virtual Methods }
    function GetContentRect: TRect; virtual;
    function GetNonEditRect: TRect; virtual;
    function MeasureTextSize: TSize; virtual;
    procedure PaintPreviewContent(Canvas: TCanvas; Dest: TRect); virtual;
    procedure SetAsString(const Value: WideString); virtual;
  public
    constructor Create(Owner: TNxInspectorNode6); virtual;
    destructor Destroy; override;
    { Methods }
    procedure Assign(Source: TObject); virtual;
    procedure AssignNode; virtual;
    procedure AssignValue; virtual;
    function CanCaptionFit: Boolean;
    function CanDispatchKey(var Key: Word): Boolean; virtual;
    function CanValueFit: Boolean; virtual;
    function CaptureMouse: Boolean; virtual;
    procedure Changed; virtual;
    procedure DrawImage(X: Integer);
    procedure DrawHtmlTextRect(Rect: TRect; Text: WideString);
    function GetEditRect: TRect; virtual;
    function GetTextRect: TRect; virtual;
    function GetValue: WideString; virtual;
    function HasContent: Boolean; virtual;
    function HasImage: Boolean;
    { Invalidation }
    procedure Invalidate(IncludePadding: Boolean = False);
    procedure InvalidateIndicator;
//    function HasPropertiesSet: Boolean;
    procedure KeyDown(var Key: Word; Shift: TShiftState); virtual;
    procedure KeyUp; overload; virtual;
    procedure KeyUp(var Key: Word; Shift: TShiftState); overload; virtual;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
    procedure MouseLeave; virtual;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); virtual;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); overload; virtual;
    procedure MouseUp; overload; virtual;
    procedure Paint; virtual;
    procedure PaintCaption; virtual;
    procedure PaintEmptyValue(ContentRect: TRect); virtual;
    procedure PaintMargin; virtual;
    procedure PaintPreview; virtual;
    procedure PaintSizeGrip; virtual;
    procedure PaintSplitter; virtual;
    procedure PaintToggle; virtual;
    procedure PaintValue; virtual;
    procedure PaintValueContent(ContentRect: TRect); virtual;
    function PreferedSize(Entities: TNxInspectorNodeEntity = [etValue]): TSize; virtual;
    procedure Refresh; overload; virtual;
    procedure Refresh(InvalidationRect: TRect); overload; virtual;
    procedure RefreshDetailsButton;
    { Properties }
    property Canvas: TCanvas read GetCanvas write SetCanvas;
    property CaptionContentRect: TRect read GetCaptionContentRect;
    property CaptionRect: TRect read GetCaptionRect;
    property CaptionTextRect: TRect read GetCaptionTextRect;
    property CaptionTextSize: TSize read GetCaptionTextSize;
    property ClientRect: TRect read GetClientRect write SetClientRect;
    property ContentHeight: Integer read GetContentHeight;
    property ContentRect: TRect read GetContentRect;
    property ContentWidth: Integer read GetContentWidth;
    property Control: TWinControl read GetControl write SetControl;
    property DetailsButtonRect: TRect read GetDetailsButtonRect;
    property DetailsButtonState: TNxButtonState read GetDetailsButtonState write SetDetailsButtonState;
    property EditRect: TRect read GetEditRect;
    property Height: Integer read GetHeight;
    property ImagePosition: TNxNodeIconPosition read GetImagePosition write SetImagePosition;
    property Images: TCustomImageList read GetImages write SetImages;
    property InteractiveRect: TRect read GetInteractiveRect;
    property MarginColor: TColor read GetMarginColor write SetMarginColor;
    property MarginWidth: Integer read GetMarginWidth write SetMarginWidth;
    property Node: TNxInspectorNode6 read GetNode;
    property NodeState: TNxInspectorNodeState read GetNodeState write SetNodeState;
    property NonEditRect: TRect read GetNonEditRect;
    property Options: TNxInspectorNodeViewOptions read GetOptions write SetOptions;
    property Owner: INxViewComponent read GetOwner write SetOwner;
    property PreviewPopup: Boolean read GetPreviewPopup write SetPreviewPopup;
    property PreviewRect: TRect read GetPreviewRect;
    property Selected: Boolean read GetSelected write SetSelected;
    property ShowMargin: Boolean read GetShowMargin write SetShowMargin;
    property SizeGripRect: TRect read GetSizeGripRect;
    property SplitterPosition: Integer read GetSplitterPosition write SetSplitterPosition;
    property Style: INxControlStyle read GetStyle write SetStyle;
    property TextRect: TRect read GetTextRect;
    property ToggleRect: TRect read GetToggleRect;
    property ToggleStyle: TNxToggleButtonStyle read GetToggleStyle write SetToggleStyle;
    property UseTopLevelColor: Boolean read GetUseTopLevelColor write SetUseTopLevelColor;
    property ValueRect: TRect read GetValueRect;
    { Events }
    property OnChange: TNxNodeViewNotifyEvent read GetOnChange write SetOnChange;
  end;

  { INxFullSizeItem }

  INxFullSizeItem = interface
    ['{AE8F9956-465A-4A86-9D9E-10D7E9AD9C7C}']
    { Property Accessors }
    function GetFullSize: Boolean;
    function GetFullSizeHeight: Integer;
    procedure SetFullSize(const Value: Boolean);
    { Properties }
    property FullSize: Boolean read GetFullSize write SetFullSize;
    property FullSizeHeight: Integer read GetFullSizeHeight;
  end;

  { TNxInspectorNode6 }

  TNxTextRender = (trPlainText, trHtml);

  TNxInspectorNode6 = class(TComponent, INxViewComponent, INxBase)
  private
    FAlignment: TAlignment;
    FAllowEmpty: Boolean;
    FAutoAssign: Boolean;
    FAutoSelect: Boolean;
    FAutoSize: Boolean;
    FBindProperty: string;
    FCaption: WideString;
    FCaptionColor: TColor;
    FCaptionDrawingOptions: TNxDrawingOptions;
    FCaptionFont: TFont;
    FCaptionTextFitHint: WideString;
    FCaptionTextRender: TNxTextRender;
    FCaptionWrapKind: TNxWrapKind;
    FCount: Integer;
    FDefaultValue: WideString;
    FEditOptions: TNxInspectorNodeEditOptions;
    FEmptyValue: WideString;
    FEnabled: Boolean;
    FExpanded: Boolean;
    FExpandLock: Boolean;
    FHideEmpty: Boolean;
    FHint: WideString;
    FImageIndex: TImageIndex;
    FImagePlaceholder: Boolean;
    FInplaceEdit: INxInplaceEdit;
    FMinHeight: Integer;
    FModified: Boolean;
    FNodeHeight: Integer;
    FNodes: TNxInspectorNodes;
    FOnCollapsed: TNxInspectorNodeNotifyEvent;
    FOnCustomDrawCaption: TNxCustomDrawNodeEvent;
    FOnCustomDrawPreview: TNxCustomDrawPreviewEvent;
    FOnDetailsClick: TNxInspectorNodeNotifyEvent;
    FOnExpanded: TNxInspectorNodeNotifyEvent;
    FOnGetValue: TNxInspectorNodeGetTextEvent;
    FOnValueChanged: TNxInspectorNodeNotifyEvent;
    FOptions: TNxInspectorNodeOptions;
    FPadding: TPadding;
    FParentCaptionFont: Boolean;
    FParentNode: TNxInspectorNode6;
    FParentValueFont: Boolean;
    FReadOnly: Boolean;
    FResizeable: Boolean;
    FSaved: Boolean;
    FShowingCount: Integer;
    FShowPreview: Boolean;
    FState: TNxInspectorNodeState;
    FStylesSheet: TNxStylesSheet6;
    FValueColor: TColor;
    FValueFont: TFont;
    FView: INxInspectorNodeView;
    FVisible: Boolean;
    FVisibleCells: TNxInspectorNodeCells;
    FWantKeys: TNxWantKeys;
    function GetAbsoluteIndex: Integer;
    function GetChildByCaption(Caption: WideString): TNxInspectorNode6;
    function GetChildCount: Integer;
    function GetFiltered: Boolean;
    function GetFirstSibling: TNxInspectorNode6;
    function GetHasChildren: Boolean;
    function GetHidden: Boolean;
    function GetIndex: Integer;
    function GetIsTopLevel: Boolean;
    function GetLastSibling: TNxInspectorNode6;
    function GetLevel: Integer;
    function GetName: TComponentName;
    function GetNextSibling: TNxInspectorNode6;
    function GetNode(Index: Integer): TNxInspectorNode6;
    function GetNodes: TNxInspectorNodes;
    function GetPinned: Boolean;
    function GetPinnedIndex: Integer;
    function GetPinnedShown: Boolean;
    function GetPrevSibling: TNxInspectorNode6;
    function GetShowing: Boolean;
    procedure SetAlignment(const Value: TAlignment);
    procedure SetAutoAssign(const Value: Boolean);
    procedure SetAutoSelect(const Value: Boolean);
    procedure SetAutoSize(const Value: Boolean);
    procedure SetBindProperty(const Value: string);
    procedure SetCaption(const Value: WideString);
    procedure SetCaptionColor(const Value: TColor);
    procedure SetCaptionDrawingOptions(const Value: TNxDrawingOptions);
    procedure SetCaptionFont(const Value: TFont);
    procedure SetCaptionTextRender(const Value: TNxTextRender);
    procedure SetCaptionWrapKind(const Value: TNxWrapKind);
    procedure SetDefaultValue(const Value: WideString);
    procedure SetEditOptions(const Value: TNxInspectorNodeEditOptions);
    procedure SetEmptyValue(const Value: WideString);
    procedure SetEnabled(const Value: Boolean);
    procedure SetExpanded(const Value: Boolean);
    procedure SetExpandLock(const Value: Boolean);
    procedure SetHideEmpty(const Value: Boolean);
    procedure SetImageIndex(const Value: TImageIndex);
    procedure SetImagePlaceholder(const Value: Boolean);
    procedure SetIndex(const Value: Integer);
    procedure SetInplaceEdit(const Value: INxInplaceEdit);
    procedure SetMinHeight(const Value: Integer);
    procedure SetModified(const Value: Boolean);
    procedure SetNodeHeight(const Value: Integer);
    procedure SetNodes(const Value: TNxInspectorNodes);
    procedure SetOptions(const Value: TNxInspectorNodeOptions);
    procedure SetPadding(const Value: TPadding);
    procedure SetParentCaptionFont(const Value: Boolean);
    procedure SetParentNode(const Value: TNxInspectorNode6);
    procedure SetParentValueFont(const Value: Boolean);
    procedure SetPinned(const Value: Boolean);
    procedure SetReadOnly(const Value: Boolean);
    procedure SetResizeable(const Value: Boolean);
    procedure SetSaved(const Value: Boolean);
    procedure SetShowPreview(const Value: Boolean);
    procedure SetStylesSheet(const Value: TNxStylesSheet6);
    procedure SetValueColor(const Value: TColor);
    procedure SetValueFont(const Value: TFont);
    procedure SetVisible(const Value: Boolean);
    procedure SetVisibleCells(const Value: TNxInspectorNodeCells);
    procedure SetWantKeys(const Value: TNxWantKeys);
  protected
    function GetPreviewText: WideString; virtual;
  protected
    FValue: WideString;
    { Event Handlers }
    procedure DoCaptionFontChange(Sender: TObject);
    procedure DoCollapsed; dynamic;
    procedure DoDetailsClick; dynamic;
    procedure DoExpanded; dynamic;
    procedure DoGetValue(var Value: WideString); dynamic;
    procedure DoPaddingChange(Sender: TObject);
    procedure DoValueChanged; dynamic;
    procedure DoValueFontChange(Sender: TObject);
    procedure DoCustomDrawCaption(DrawingRect: TRect; Selected: Boolean); dynamic;
    { Virtual Methods }
    procedure AddChild;
    procedure Changed; virtual;
    procedure RemoveChild(Shown: Boolean);
    function GetActualHeight: Integer; virtual;
    function GetDisplayText: WideString; virtual;
    function GetIndent: Integer; virtual;
    function GetNodeStyle: TNxInspectorNodeStyle; virtual;
    function GetValue: WideString; virtual;
    function GetViewClass: TNxInspectorNodeViewClass; virtual;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure Notify(Kind: TNxNodeNotificationKind);
    procedure Refresh;
    procedure RefreshCaption;
    procedure RefreshValue;
    { INxObject }
    function ToObject: TObject;
    { INxBase }
    function GetAsBoolean: Boolean; virtual;
    function GetAsDateTime: TDateTime; virtual;
    function GetAsFloat: Double; virtual;
    function GetAsInteger: Integer; virtual;
    function GetAsString: WideString; virtual;
    function GetAsUTF8String: UTF8String; virtual;
    function GetIsNull: Boolean; 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;
    procedure SetAsUTF8String(const Value: UTF8String);
    { Value }
    procedure SetValue(const Value: WideString); virtual;
    { DFM }
    procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
    procedure SetParentComponent(Value: TComponent); override;
    { Properties }
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Methods }
    procedure Assign(Source: TPersistent); override;
    procedure AssignEdit(Edit: INxInplaceEdit); virtual;
    procedure AssignProperty(TypeKind: TTypeKind); virtual;
    procedure AssignValue(Source: INxBase); virtual;
    function BeginEdit: INxInplaceEdit; virtual;
    procedure BestFit(Entities: TNxInspectorNodeEntity = [etCaption, etValue]); virtual;
    function CanEdit: Boolean; virtual;
    function CanInteract: Boolean; virtual;
    procedure ChangeValue(const Value: WideString);
    function ChildsValue(Separator: Char = ' '): WideString;
    procedure ClearChildren;
    procedure ClearState;
    function EditWidth: Integer; virtual;
    function GetParentComponent: TComponent; override;
    function HasParent: Boolean; override;
    function IsEmpty: Boolean; virtual;
    function IsDestroying: Boolean;
    procedure MoveTo(Destination: TNxInspectorNode6; Mode: TNodeAttachMode); overload;
    procedure MoveToTopLevel;
    procedure Pin;
    procedure Remove;
    procedure ShowDetails; virtual;
    procedure Unpin;
    { INxBase 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;
    property AsUTF8String: UTF8String read GetAsUTF8String write SetAsUTF8String;
    property ChildByCaption[Caption: WideString]: TNxInspectorNode6 read GetChildByCaption;
    property ChildCount: Integer read GetChildCount;
    property Count: Integer read FCount;
    property FirstSibling: TNxInspectorNode6 read GetFirstSibling;
    property HasChildren: Boolean read GetHasChildren;
    property Indent: Integer read GetIndent;
    property IsTopLevel: Boolean read GetIsTopLevel;
    property LastSibling: TNxInspectorNode6 read GetLastSibling;
    property NextSibling: TNxInspectorNode6 read GetNextSibling;
    property Node[Index: Integer]: TNxInspectorNode6 read GetNode;
    property Nodes: TNxInspectorNodes read GetNodes write SetNodes;
    property NodeStyle: TNxInspectorNodeStyle read GetNodeStyle;
    property ParentNode: TNxInspectorNode6 read FParentNode write SetParentNode;
    property PrevSibling: TNxInspectorNode6 read GetPrevSibling;
    property State: TNxInspectorNodeState read FState write FState;
    property View: INxInspectorNodeView read FView;
  published
    property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
    property AbsoluteIndex: Integer read GetAbsoluteIndex;
    property ActualHeight: Integer read GetActualHeight;
    property AllowEmpty: Boolean read FAllowEmpty write FAllowEmpty default True;
    property AutoAssign: Boolean read FAutoAssign write SetAutoAssign default False;
    property AutoSelect: Boolean read FAutoSelect write SetAutoSelect default True;
    property AutoSize: Boolean read FAutoSize write SetAutoSize default False;
    property BindProperty: string read FBindProperty write SetBindProperty;
    property Caption: WideString read FCaption write SetCaption;
    property CaptionColor: TColor read FCaptionColor write SetCaptionColor default clWindow;
    property CaptionDrawingOptions: TNxDrawingOptions read FCaptionDrawingOptions write SetCaptionDrawingOptions default [doBackground, doContent];
    property CaptionFont: TFont read FCaptionFont write SetCaptionFont;
    property CaptionTextFitHint: WideString read FCaptionTextFitHint write FCaptionTextFitHint;
    property CaptionTextRender: TNxTextRender read FCaptionTextRender write SetCaptionTextRender default trPlainText;
    property CaptionWrapKind: TNxWrapKind read FCaptionWrapKind write SetCaptionWrapKind default wkNone;
    property DefaultValue: WideString read FDefaultValue write SetDefaultValue;
    property DisplayText: WideString read GetDisplayText;
    property EditOptions: TNxInspectorNodeEditOptions read FEditOptions write SetEditOptions default [edPaste, edTyping];
    property EmptyValue: WideString read FEmptyValue write SetEmptyValue;
    property Enabled: Boolean read FEnabled write SetEnabled default True;
    property Expanded: Boolean read FExpanded write SetExpanded default True;
    property ExpandLock: Boolean read FExpandLock write SetExpandLock default False;
    property Filtered: Boolean read GetFiltered;
    property Hidden: Boolean read GetHidden;
    property HideEmpty: Boolean read FHideEmpty write SetHideEmpty default False;
    property Hint: WideString read FHint write FHint;
    property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1;
    property ImagePlaceholder: Boolean read FImagePlaceholder write SetImagePlaceholder default True;
    property Index: Integer read GetIndex write SetIndex;
    property InplaceEdit: INxInplaceEdit read FInplaceEdit write SetInplaceEdit;
    property Level: Integer read GetLevel default 0;
    property MinHeight: Integer read FMinHeight write SetMinHeight default szMinNodeHeight;
    property Modified: Boolean read FModified;
    property NodeHeight: Integer read FNodeHeight write SetNodeHeight default 0;
    property Options: TNxInspectorNodeOptions read FOptions write SetOptions default [];
    property Padding: TPadding read FPadding write SetPadding;
    property ParentCaptionFont: Boolean read FParentCaptionFont write SetParentCaptionFont default True;
    property ParentValueFont: Boolean read FParentValueFont write SetParentValueFont default True;
    property Pinned: Boolean read GetPinned write SetPinned default False;
    property PinnedIndex: Integer read GetPinnedIndex;
    property PinnedShowing: Boolean read GetPinnedShown;
    property PreviewText: WideString read GetPreviewText;
    property ReadOnly: Boolean read FReadOnly write SetReadOnly default False;
    property Resizeable: Boolean read FResizeable write SetResizeable default False;
    property Saved: Boolean read FSaved write SetSaved default False;
    property Showing: Boolean read GetShowing;
    property ShowPreview: Boolean read FShowPreview write SetShowPreview default False;
    property StylesSheet: TNxStylesSheet6 read FStylesSheet write SetStylesSheet;
    property Value: WideString read GetValue write SetValue;
    property ValueColor: TColor read FValueColor write SetValueColor default clWindow;
    property ValueFont: TFont read FValueFont write SetValueFont;
    property Visible: Boolean read FVisible write SetVisible default True;
    property VisibleCells: TNxInspectorNodeCells read FVisibleCells write SetVisibleCells default [icCaption, icValue];
    property WantKeys: TNxWantKeys read FWantKeys write SetWantKeys default [];
    { Events }
    property OnCollapsed: TNxInspectorNodeNotifyEvent read FOnCollapsed write FOnCollapsed;
    property OnCustomDrawCaption: TNxCustomDrawNodeEvent read FOnCustomDrawCaption write FOnCustomDrawCaption;
    property OnCustomDrawPreview: TNxCustomDrawPreviewEvent read FOnCustomDrawPreview write FOnCustomDrawPreview;
    property OnDetailsClick: TNxInspectorNodeNotifyEvent read FOnDetailsClick write FOnDetailsClick;
    property OnExpanded: TNxInspectorNodeNotifyEvent read FOnExpanded write FOnExpanded;
    property OnGetValue: TNxInspectorNodeGetTextEvent read FOnGetValue write FOnGetValue;
    property OnValueChanged: TNxInspectorNodeNotifyEvent read FOnValueChanged write FOnValueChanged;
  end;

implementation

uses
  SysUtils, Dialogs, Windows, Math,
  { Next Standard 6}
  NxGraphics6,
  { NextInspector 6 }
  NxInspector6, NxStylePaint6, NxInspectorStylePaint6;

function GetDefaultStyle(const Font: TFont): TNxCSSStyle;
begin
  Result.Color := Font.Color;
  Result.FontFamily := Font.Name;
  Result.FontSize := IntToStr(Font.Size);
  Result.TextAlign := taLeft;
end;

{ TNxInspectorNodes }

function TNxInspectorNodes.Add(Parent: TNxInspectorNode6;
  NodeClass: TNxInspectorNodeClass; Position: TNxNodeAddPosition): TNxInspectorNode6;
begin
  Result := NodeClass.Create(nil);

  { Add Node & set ParentNode }
  AddNode(Parent, Result, Position);
end;

procedure TNxInspectorNodes.AddNode(Parent, Node: TNxInspectorNode6;
  Position: TNxNodeAddPosition);
begin
  Node.Nodes := Self;

  { Add Node & set ParentNode }
  SetParent(Node, Parent, Position);

  { Trigger Event }
  DoNodesChanged(Node, ncAdd, 0, 0);
end;

procedure TNxInspectorNodes.ChangeNotification(Control: INxNodeNotifyControl);
begin
  FNotifications.Add(Pointer(Control));
end;

procedure TNxInspectorNodes.Clear;
var
  i: Integer;
begin
  { To be cleared too! }
  FPinned.Clear;

  for i := Pred(Count) downto 0 do
    Node[i].Free;

  UpdateShowingCount(0);

  DoNodesChanged(nil, ncClear, 0, 0);
end;

procedure TNxInspectorNodes.ClearChildren(const ANode: TNxInspectorNode6);
var
  i: Integer;
begin
  i := Succ(ANode.AbsoluteIndex);

  while i < Count do
  begin
    Node[i].RemoveChild(Node[i].Showing);
  end;
//  for i :=  to Pred(Count) do
//    if Item[i].ParentItem > Item[Index].Level then
//    begin
//      Item[i] := nil;
//    end else Break;
end;

constructor TNxInspectorNodes.Create(AOwner: TComponent);
begin
  FOwner := AOwner;
  if not Supports(AOwner, INxInspectorControl, FControl) then
  begin
    ShowMessage('Error');
  end;
  FHideTopLevel := False;
  FList := TList.Create;
  FNotifications := TList.Create;
  FPinned := TList.Create;
  FShowingCount := 0;
end;

procedure TNxInspectorNodes.Delete(const Index: Integer);
var
  Deleting: TNxInspectorNode6;
  Showing: Boolean;
begin
  Deleting := Node[Index];

  Showing := Deleting.Showing;

  { ToDo: Delete all childs }
  { ToDo: Update ShownCount of Parent }

  if Assigned(Deleting.ParentNode) then
    Deleting.ParentNode.RemoveChild(Deleting.Showing);

  FList.Delete(Index);

  if Showing then
  begin
    Dec(FShowingCount);

    { Notify }
    DoNodesChanged(Deleting, ncDelete, Index, 0);
  end;
end;

destructor TNxInspectorNodes.Destroy;
begin
  Clear;
  FreeAndNil(FList);
  FreeAndNil(FNotifications);
  FreeAndNil(FPinned);
  inherited;
end;

procedure TNxInspectorNodes.DoNodeChanged(Sender: TNxInspectorNode6);
begin
  if Assigned(FOnNodeChanged) then FOnNodeChanged(Sender);
end;

procedure TNxInspectorNodes.DoNodesChanged(Sender: TNxInspectorNode6;
  Kind: TNxNodesChangeKind; Param1, Param2: Integer);
begin
  if Assigned(FOnNodesChanged) then FOnNodesChanged(Sender, Kind, Param1, Param2);
end;

function TNxInspectorNodes.GetCount: Integer;
begin
  Result := FList.Count;
end;

function TNxInspectorNodes.GetFilterText: WideString;
begin
  Result := FFilterText;
end;

function TNxInspectorNodes.GetHideTopLevel: Boolean;
begin
  Result := FHideTopLevel;
end;

function TNxInspectorNodes.GetNode(Index: Integer): TNxInspectorNode6;
begin
  Result := TNxInspectorNode6(FList[Index]);
end;

function TNxInspectorNodes.GetNodeByName(Name: TComponentName): TNxInspectorNode6;
var
  i: Integer;
begin
  Result := nil;
  for i := 0 to Pred(Count) do
    if (CompareText(Node[i].GetName, Name) = 0) then { case-insensitive }
    begin
      Result := Node[i];
      Exit;
    end;
end;

function TNxInspectorNodes.GetNodeShowingCount(Node: TNxInspectorNode6): Integer;
var
  Index: Integer;
begin
  Result := 0;

  Index := Node.AbsoluteIndex;

  Inc(Index);

  while (Index < Count) and (Self.Node[Index].Level > Node.Level) do
  begin
    if Self.Node[Index].Showing then Inc(Result);
    Inc(Index);
  end;

end;

function TNxInspectorNodes.GetNotification(Index: Integer): INxNodeNotifyControl;
begin
  Result := INxNodeNotifyControl(FNotifications[Index]);
end;

function TNxInspectorNodes.GetPinned(Index: Integer): TNxInspectorNode6;
begin
  Result := TNxInspectorNode6(FPinned[Index]);
end;

function TNxInspectorNodes.GetPinnedCount: Integer;
begin
  Result := FPinned.Count;
end;

function TNxInspectorNodes.GetPropertyText: string;
begin
  Result := ClassName;
end;

function TNxInspectorNodes.IndexOf(Node: TNxInspectorNode6): Integer;
var
  i, ParentIndex, Level: Integer;
begin
  Result := 0;
  if Assigned(Node.ParentNode) then
  begin
    ParentIndex := Node.ParentNode.AbsoluteIndex;
    Level := Node.Level;
  end else
  begin
    ParentIndex := 0;
    Level := 0;
  end;
  for i := ParentIndex to Pred(GetCount) do
  begin
    if Self.Node[i].Level = Level then
    begin
      if Self.Node[i] = Node
        then Exit;
      Inc(Result);
    end;
  end;
end;

function TNxInspectorNodes.Insert(Sibling: TNxInspectorNode6;
  NodeClass: TNxInspectorNodeClass): TNxInspectorNode6;
begin
  Result := Add(nil, NodeClass);
  Result.MoveTo(Sibling, naInsert);
end;

procedure TNxInspectorNodes.InsertNode(
  Sibling, Node: TNxInspectorNode6);
begin
  AddNode(nil, Node);
  Node.MoveTo(Sibling, naInsert);
end;

procedure TNxInspectorNodes.MoveNode(List: TList;
  Node: TNxInspectorNode6; Index, ToIndex: Integer);
var
  i, c: Integer;
begin
  c := Node.ChildCount;
  if Index > ToIndex then
  begin
    for i := 0 to c do
    begin
      List.Move(Index + i, ToIndex + i);
    end;
  end else
  begin
    for i := 0 to c do
    begin
      List.Move(Index, ToIndex);
    end;
  end;
end;

procedure TNxInspectorNodes.Notify(Node: TNxInspectorNode6;
  Kind: TNxNodeNotificationKind);
var
  i: Integer;
begin
  for i := 0 to Pred(FNotifications.Count) do
    Notification[i].NodeNotification(Node, Kind);
end;

function TNxInspectorNodes.Recount: Integer;
var
  i, TotalCount: Integer;
  Counting: TNxInspectorNode6;

  function GetShowingCount(ANode: TNxInspectorNode6): Integer;
  begin

    { Default }
    Result := 0;

    repeat

      { Next one in array }
      Inc(i);

      if Node[i].Showing then
      begin
        Inc(TotalCount);

        Inc(Result);

        if Node[i].Expanded and Node[i].HasChildren then
        begin
          TNxInspectorNode6(Node[i]).FShowingCount := GetShowingCount(Node[i]);
        end;

      end;

      { One level back }
      if Node[i].Level = ANode.Level
        then Exit;

    until i = Pred(Count);

  end;

begin
  { Default }
  TotalCount := 0;

  { Top-level }

  i := 0;

  while i < Pred(Count) do
  begin
    Counting := Node[i];

    if Counting.Showing then
    begin
      { Inc. Shown }
      Inc(TotalCount);

      if Counting.Expanded and Counting.HasChildren
        then Counting.FShowingCount := GetShowingCount(Counting);

    end;

    { Next one }
    Inc(i);
  end;

  { ShownCount }
  Result := TotalCount;

//  ShowMessage(IntToStr(Result));
end;

procedure TNxInspectorNodes.SetFilterText(const Value: WideString);
begin
  FFilterText := Value;

  UpdateShowingCount(Recount);
end;

procedure TNxInspectorNodes.SetHideTopLevel(const Value: Boolean);
begin
  FHideTopLevel := Value;
end;

procedure TNxInspectorNodes.SetNode(Index: Integer; const Value: TNxInspectorNode6);
begin
  FList[Index] := Value;
end;

procedure TNxInspectorNodes.SetParent(Node, Parent: TNxInspectorNode6;
  Position: TNxNodeAddPosition);
var
  Pos: Integer;
begin
  if (Parent <> Node.ParentNode)
    or ((Parent = nil) and (Node.ParentNode = nil)) then
  begin

    { Node already having Parent }
    if Assigned(Node.ParentNode) then
    begin
      if Node.Showing then Dec(FShowingCount);

      Delete(Node.AbsoluteIndex);
    end;

    if Assigned(Parent) then
    begin

      case Position of
        apFirst: Pos := Succ(Parent.AbsoluteIndex);
        else Pos := Succ(Parent.AbsoluteIndex + Parent.ChildCount);
      end;

      FList.Insert(Pos, Node);

      { Increase FCount }
      Parent.AddChild;

    end else
    begin
      { Top-level Item }
      case Position of
        apFirst: FList.Insert(0, Node);
        else FList.Add(Node);
      end;
    end;

    Node.ParentNode := Parent;

    //Node.View.Canvas := Self.

    { Global count }
    if Node.Showing then Inc(FShowingCount);
  end;
end;

procedure TNxInspectorNodes.UpdateShowingCount(Value: Integer);
begin
  FShowingDelta := Value - FShowingCount;
  FShowingCount := Value;
end;

{ TNxInspectorNodeView }

procedure TNxInspectorNodeView.Assign(Source: TObject);
begin
  if Source is TNxInspectorNodeView then
  begin

  end;
end;

procedure TNxInspectorNodeView.AssignNode;
begin
  with Canvas do
  begin
    Font.Assign(Node.ValueFont);

    { Disabled Item }
    if not Node.Enabled then Font.Color := clGrayText;

    { Bold non-default values }
    if (Node.DefaultValue <> EmptyStr)
      and (Node.Value <> Node.DefaultValue) then
    begin
      Font.Style := Font.Style + [fsBold];
    end;
  end;
end;

procedure TNxInspectorNodeView.AssignValue;
begin
  { Base ItemView don't Assign Value to Item }
end;

function TNxInspectorNodeView.CanCaptionFit: Boolean;
begin
  Result := RectInRect(CaptionTextRect, Bounds(CaptionTextRect.Left, CaptionTextRect.Top, CaptionTextSize.cx, CaptionTextSize.cy));
end;

function TNxInspectorNodeView.CanDispatchKey(var Key: Word): Boolean;
begin
  Result := True;
end;

function TNxInspectorNodeView.CanValueFit: Boolean;
begin
  Result := RectInRect(TextRect, Bounds(TextRect.Left, TextRect.Top, MeasureTextSize.cx, MeasureTextSize.cy));
end;

function TNxInspectorNodeView.CaptureMouse: Boolean;
begin
  Result := False;
end;

procedure TNxInspectorNodeView.Changed;
begin
  { Update View when Item's Value is changed }
end;

constructor TNxInspectorNodeView.Create(Owner: TNxInspectorNode6);
begin
  FOwner := Owner;
  FNode := Owner;
  FPreviewPopupControl := nil;
end;

destructor TNxInspectorNodeView.Destroy;
begin
  FreeAndNil(FPreviewPopupControl);
  inherited;
end;

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

procedure TNxInspectorNodeView.DoCloseUp;
begin

end;

procedure TNxInspectorNodeView.DoPreviewPopupHide(Sender: TObject);
begin
  FPreviewPopupControl := nil;
end;

procedure TNxInspectorNodeView.DoSelect;
begin

end;

procedure TNxInspectorNodeView.DrawHtmlTextRect(Rect: TRect; Text: WideString);
var
  View: TNxHTMLView;
begin
  View := TNxHTMLView.Create;
  try
    with View do
    begin
      HTML := Text;
      DefaultStyle := GetDefaultStyle(Canvas.Font);
      StyleSheet := Node.StylesSheet;
      Operation := [hoPaint];
      PaintTo(Canvas, Rect);
    end;
  finally
    View.Free;
  end;
end;

procedure TNxInspectorNodeView.DrawImage(X: Integer);
var
  Y: Integer;
begin
  if Assigned(Images) and InRange(Node.ImageIndex, 0, Pred(Images.Count)) then
  begin
    Y := ClientRect.Top + (ClientRect.Bottom - ClientRect.Top) div 2 - (Images.Height div 2);
    Images.Draw(Canvas, X, Y, Node.ImageIndex);
  end;
end;

function TNxInspectorNodeView.DrawingIndent: Integer;
begin
  if ShowMargin then Result := MarginWidth else Result := 0;
end;

function TNxInspectorNodeView.GetAsString: WideString;
begin

end;

function TNxInspectorNodeView.GetAutoClose: Boolean;
begin
  Result := True;
end;

function TNxInspectorNodeView.GetCanvas: TCanvas;
begin
  Result := FCanvas;
end;

function TNxInspectorNodeView.GetCaptionContentRect: TRect;
begin
  Result := CaptionTextRect;

  { Expand if Value is not visible }
  if not (icValue in Node.VisibleCells) then
  begin
    Result.Right := Result.Left + CaptionTextSize.cx;
  end;

  InflateRect(Result, pdStandard, 0);
end;

function TNxInspectorNodeView.GetCaptionPrefferedWidth: Integer;
begin
  Result := 0;
  with Canvas do
  begin
    Font.Assign(Node.CaptionFont);

    { ToDo: Tweak? }
    if not Node.Pinned then Inc(Result, Node.GetIndent * MarginWidth);

    if (ImagePosition = ipLeft)
      and Assigned(Images) then
      begin
        Inc(Result, Images.Width);
        Inc(Result, pdStandard); { padding }
      end;

    if Node.Caption <> '' then
    begin
      Inc(Result, 4 + GetTextWidth(Canvas, Node.Caption, wkNone));
    end;


    if itoDetailsButton in Node.Options then
    begin
      Dec(Result, spDetails);
    end;

    if (ImagePosition = ipRight)
      and Assigned(Images) then
    begin
      Dec(Result, Images.Width + pdStandard);
    end;
  end;
end;

function TNxInspectorNodeView.GetCaptionRect: TRect;
begin
  Result := ClientRect;
  Result.Left := DrawingIndent;

  { Not Merged? }
  if icValue in Node.VisibleCells then
  begin
    Result.Right := Result.Left + SplitterPosition;
  end;
end;

function TNxInspectorNodeView.GetCaptionTextRect: TRect;
begin
  Result := CaptionRect;

  with Canvas do
  begin
    Font.Assign(Node.CaptionFont);

    { ToDo: Tweak? }
    if not Node.Pinned then Inc(Result.Left, Node.GetIndent * MarginWidth);

    if (ImagePosition = ipLeft)
      and Assigned(Images)
      and (HasImage or Node.ImagePlaceholder) then
      begin
        Inc(Result.Left, Images.Width);
        Inc(Result.Left, pdStandard); { Small padding }
      end;

    if itoDetailsButton in Node.Options then
    begin
      Dec(Result.Right, spDetails);
    end;

    if (ImagePosition = ipRight)
      and Assigned(Images)
        and (HasImage or Node.ImagePlaceholder) then
    begin
      Dec(Result.Right, Images.Width + pdStandard);
    end;

    { Add Horz Padding }
    InflateRect(Result, -pdStandard, 0);
  end;
end;

function TNxInspectorNodeView.GetCaptionTextSize: TSize;
begin
  with Canvas do
  begin
    Result := NxGraphics6.GetTextSize(Handle, CaptionTextRect, Node.Caption, Node.CaptionWrapKind);
  end;
end;

function TNxInspectorNodeView.GetCellsRect: TRect;
begin
  Result := ClientRect;
  Inc(Result.Left, DrawingIndent);
end;

function TNxInspectorNodeView.GetClientRect: TRect;
begin
  Result := FClientRect;
end;

function TNxInspectorNodeView.GetContentHeight: Integer;
begin
  Result := ContentRect.Bottom - ContentRect.Top;
end;

function TNxInspectorNodeView.GetContentRect: TRect;
begin
  Result := ValueRect;

  { Apply Padding }
  PaddingRect(Result, Node.Padding);
//  PaddingRect(Result, DeviceIndipendedPoint(Node.Padding));
end;

function TNxInspectorNodeView.GetContentWidth: Integer;
begin
  Result := ContentRect.Right - ContentRect.Left;
end;

function TNxInspectorNodeView.GetControl: TWinControl;
begin
  Result := FControl;
end;

function TNxInspectorNodeView.GetDetailsButtonRect: TRect;
begin
  Result := Rect(CaptionRect.Right - spDetails, ClientRect.Top, CaptionRect.Right, ClientRect.Bottom);
end;

function TNxInspectorNodeView.GetDetailsButtonState: TNxButtonState;
begin
  Result := FDetailsButtonState;
end;

function TNxInspectorNodeView.GetDroppedDown: Boolean;
begin
  Result := False;
end;

function TNxInspectorNodeView.GetEditRect: TRect;
begin
  Result := ContentRect;
  if Node.EditWidth > 0 then Result.Right := Result.Left + Node.EditWidth;
end;

function TNxInspectorNodeView.GetFont: TFont;
begin
  Result := Canvas.Font;
end;

function TNxInspectorNodeView.GetHeight: Integer;
begin
  Result := RectHeight(ValueRect);
end;

function TNxInspectorNodeView.GetImagePosition: TNxNodeIconPosition;
begin
  Result := FImagePosition;
end;

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

function TNxInspectorNodeView.GetInteractiveRect: TRect;
begin
  Result := ContentRect;
  Inc(Result.Left, Node.EditWidth);
end;

function TNxInspectorNodeView.GetNode: TNxInspectorNode6;
begin
  Result := FNode;// TNxInspectorNode6(Owner);
end;

function TNxInspectorNodeView.GetNodeState: TNxInspectorNodeState;
begin
  Result := FNodeState;
end;

function TNxInspectorNodeView.GetMarginColor: TColor;
begin
  Result := FMarginColor;
end;

function TNxInspectorNodeView.GetMarginWidth: Integer;
begin
  Result := FMarginWidth;
end;

function TNxInspectorNodeView.GetNonEditRect: TRect;
begin
  { Erea not occupied with InplaceEdit }
  Result := ValueRect;

  if isEditing in NodeState then
  begin

    { Exclude Edit }
    if Node.EditWidth > 0 then
    begin
      Inc(Result.Left, Node.EditWidth);
    end;
  end;
end;

function TNxInspectorNodeView.GetOnChange: TNxNodeViewNotifyEvent;
begin
  Result := FOnChange;
end;

function TNxInspectorNodeView.GetOptions: TNxInspectorNodeViewOptions;
begin
  Result := FOptions;
end;

function TNxInspectorNodeView.GetOwner: INxViewComponent;
begin
  Result := FOwner;
end;

function TNxInspectorNodeView.GetPreviewPopup: Boolean;
begin
  Result := FPreviewPopup;
end;

function TNxInspectorNodeView.GetPreviewRect: TRect;
begin
  with Result do
  begin
    Left := DrawingIndent + SplitterPosition + 1;
    Top := ClientRect.Top;
    Right := Left + szPreviewWidth;
    Bottom := ClientRect.Bottom;
  end;
end;

function TNxInspectorNodeView.GetSelected: Boolean;
begin
  Result := FSelected;
end;

function TNxInspectorNodeView.GetShowMargin: Boolean;
begin
  Result := FShowMargin;
end;

function TNxInspectorNodeView.GetSizeGripRect: TRect;
begin
  Result := Rect(ValueRect.Right - szSizeGrip, ValueRect.Bottom - szSizeGrip, ValueRect.Right, ValueRect.Bottom);
  OffsetRect(Result, -1, -1);
end;

function TNxInspectorNodeView.GetSplitterPosition: Integer;
begin
  Result := FSplitterPosition;
end;

function TNxInspectorNodeView.GetStyle: INxControlStyle;
begin
  Result := FStyle;
end;

function TNxInspectorNodeView.GetTextRect: TRect;
begin
  Result := EditRect;
end;

function TNxInspectorNodeView.GetToggleRect: TRect;
var
  ToggleSize: TSize;
  ToggleLeft, ToggleTop: Integer;
begin
  ToggleSize := INxInspectorStyle(Style).GetToggleSize;
  ToggleSize := DotToPixel(ToggleSize);

  ToggleLeft := Node.GetIndent * MarginWidth;

  Inc(ToggleLeft, MarginWidth div 2 - ToggleSize.cx div 2);

  ToggleTop := ClientRect.Top + ContentHeight div 2 - ToggleSize.cy div 2;

  Result := Rect(ToggleLeft, ToggleTop, ToggleLeft + ToggleSize.cx, ToggleTop + ToggleSize.cy);
end;

function TNxInspectorNodeView.GetToggleStyle: TNxToggleButtonStyle;
begin
  Result := FToogleStyle;
end;

function TNxInspectorNodeView.GetUseTopLevelColor: Boolean;
begin
  Result := FUseTopLevelColor;
end;

function TNxInspectorNodeView.GetValue: WideString;
begin
  { Base ItemView don't have Value }
end;

function TNxInspectorNodeView.GetValueRect: TRect;
begin
  with Result do
  begin
    Left := DrawingIndent;
    if not (Node.VisibleCells = [icValue]) then
    begin
      Inc(Left, SplitterPosition + 1);
    end;
    if Node.ShowPreview then Inc(Left, szPreviewWidth);
    Top := ClientRect.Top;
    Right := ClientRect.Right;
    Bottom := ClientRect.Bottom;
  end;
end;

function TNxInspectorNodeView.HasContent: Boolean;
begin
  Result := False;
end;

function TNxInspectorNodeView.HasImage: Boolean;
begin
  Result := InRange(Node.ImageIndex, 0, Images.Count - 1);
end;

///<summary>Invalidate value TRect</summary>
///<param name="IncludePadding">Include padding area for invalidation</param>
procedure TNxInspectorNodeView.Invalidate(IncludePadding: Boolean);
begin
  if IncludePadding then
  begin
    Refresh(ValueRect);
  end else
  begin
    if Node.ShowPreview then Refresh(PreviewRect);
    Refresh(ContentRect);
  end;
end;

procedure TNxInspectorNodeView.InvalidateIndicator;
var
  IndicatorRect: TRect;
begin
  IndicatorRect := ClientRect;
  IndicatorRect.Right := MarginWidth;
  IndicatorRect.Left := IndicatorRect.Right - IndicatorSize;
  Refresh(IndicatorRect);
end;

procedure TNxInspectorNodeView.KeyDown(var Key: Word; Shift: TShiftState);
begin

end;

procedure TNxInspectorNodeView.KeyUp;
begin

end;

procedure TNxInspectorNodeView.KeyUp(var Key: Word; Shift: TShiftState);
begin
  KeyUp; { Call overloaded }
end;

function TNxInspectorNodeView.MeasureTextSize: TSize;
begin
  Result := GetTextSize(Canvas.Handle, TextRect, Node.Value, wkNone);
end;

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

end;

procedure TNxInspectorNodeView.MouseLeave;
begin
end;

procedure TNxInspectorNodeView.MouseMove(Shift: TShiftState; X, Y: Integer);
var
  CenterPoint, ScreenPoint: TPoint;
  Dest: TRect;
begin
  if Node.ShowPreview and PreviewPopup then
    if PtInRect(PreviewRect, Point(X, Y)) then
    begin

      if not Assigned(FPreviewPopupControl) then
      begin
        FPreviewPopupControl := TNxPreviewPopupControl.Create(nil);
        FPreviewPopupControl.Width := 42;
        FPreviewPopupControl.Height := 42;
        FPreviewPopupControl.DropDown := Self;
        FPreviewPopupControl.OnHide := DoPreviewPopupHide;
      end;

      CenterPoint := CenterInRect(PreviewRect, FPreviewPopupControl.Width, FPreviewPopupControl.Height);

      ScreenPoint := Control.ClientToScreen(CenterPoint);
      FPreviewPopupControl.Popup(ScreenPoint);

      Dest := FPreviewPopupControl.ClientRect;

      PaintPreviewContent(FPreviewPopupControl.Canvas, Dest);

    end;
end;

procedure TNxInspectorNodeView.MouseUp;
begin

end;

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

end;

procedure TNxInspectorNodeView.Paint;
begin
  if ShowMargin then PaintMargin;

  if Node.VisibleCells = [] then
  begin
    Canvas.Brush.Color := clWindow;
    Canvas.FillRect(GetCellsRect);
  end;

  { Expand/Collapse Toggle Button }
  if Node.HasChildren
    and not Node.Pinned
    and not Node.ExpandLock
      then PaintToggle;

  if icCaption in Node.VisibleCells then
  begin
    PaintCaption;
  end;

  if icValue in Node.VisibleCells then
  begin
    if icCaption in Node.VisibleCells then PaintSplitter;
    if Node.ShowPreview then PaintPreview;
    PaintValue;
  end;

  { DrawFocusRect }
  if Selected and Node.IsTopLevel and UseTopLevelColor then
  begin
    INxInspectorStyle(Style).PaintTopLevelSelection(CaptionContentRect);
  end;

  PaintSizeGrip;
end;

procedure TNxInspectorNodeView.PaintCaption;
var
  ImageLeft: Integer;
  DetailsPos: TPoint;
  CaptionClientRect, TxtRect: TRect;
begin
  ImageLeft := DrawingIndent;

  with Canvas do
  begin
    CaptionClientRect := CaptionRect;

    if itoDetailsButton in Node.Options
      then Dec(CaptionClientRect.Right, spDetails);

    { Draw Background }
    if doBackground in Node.CaptionDrawingOptions then
    begin
      if Node.IsTopLevel and UseTopLevelColor
        then Brush.Color := INxInspectorStyle(Style).GetTopLevelColor
      else
      begin
        if Selected then Brush.Color := INxInspectorStyle(Style).GetSelectionColor else
        begin
          Brush.Color := INxInspectorStyle(Style).GetBackgroundColor(Node.CaptionColor);
        end;
      end;

      FillRect(CaptionClientRect);
    end;

    if doContent in Node.CaptionDrawingOptions then
    begin
      TxtRect := CaptionTextRect;

      { Caption Font }
      Font.Color := INxInspectorStyle(Style).GetTextColor(Node, Selected, Control.Focused);

      if not Node.Enabled
        then Font.Color := clGrayText;

      { Level Indent }
      Inc(ImageLeft, Node.GetIndent * MarginWidth);

      if (ImagePosition = ipLeft)
        and Assigned(Images) then
        begin
          Inc(ImageLeft, pdStandard); { Add small padding }
          DrawImage(ImageLeft);
        end;

      { Draw Details Button }
      if itoDetailsButton in Node.Options then
      begin
        Brush.Color := Node.CaptionColor;
        FillRect(DetailsButtonRect);

        { Draaw Button }
        INxInspectorStyle(Style).PaintToolButton(DetailsButtonRect, DetailsButtonState);

        { Draw Mark }
        DetailsPos := CenterInRect(DetailsButtonRect, szDetailsMark, szDetailsMark);
        DrawDetailsMark(Canvas, DetailsPos.X, DetailsPos.Y, INxInspectorStyle(Style).GetGrayColor);
      end;

      if (ImagePosition = ipRight)
        and Assigned(Images) then
        begin
          ImageLeft := CaptionTextRect.Right;
          Inc(ImageLeft, pdStandard); { Add small padding }

          DrawImage(ImageLeft);
        end;

      { Draw Caption }
      case Node.CaptionTextRender of
        trPlainText: NxGraphics6.DrawTextRect(Canvas, TxtRect, taLeftJustify, taVerticalCenter, Node.Caption, Node.CaptionWrapKind);
        trHtml: DrawHtmlTextRect(TxtRect, Node.Caption);
      end;
    end;

    if doCustom in Node.CaptionDrawingOptions then
      { Trigger Event }
      Node.DoCustomDrawCaption(CaptionRect, Selected);

  end;
end;

procedure TNxInspectorNodeView.PaintPreviewContent(Canvas: TCanvas; Dest: TRect);
begin
  if Assigned(Node.OnCustomDrawPreview)
    then Node.OnCustomDrawPreview(Node, Canvas, Dest);

  //ToDo: Event call here
end;

procedure TNxInspectorNodeView.PaintEmptyValue(ContentRect: TRect);
begin
  with Canvas do
  begin
    Font.Color := clGrayText;
    DrawTextRect(Canvas, ContentRect, Node.Alignment, taVerticalCenter, Node.EmptyValue, wkEllipsis);
  end;
end;

procedure TNxInspectorNodeView.PaintMargin;
var
  MarginRect, IndicatorRect: TRect;
begin
  MarginRect := ClientRect;
  MarginRect.Right := MarginRect.Left + MarginWidth;

  with Canvas, Style as INxInspectorStyle do
  begin
    Brush.Color := GetMarginColor(Node, MarginColor);
    FillRect(MarginRect);

    { Indicators }
    if voModifiedIndicators in Options then
    begin
//      PaintIndicator;
      IndicatorRect := MarginRect;
      IndicatorRect.Left := IndicatorRect.Right - IndicatorSize;
      if Node.Modified then
      begin
        Brush.Color := $0000d8ff;
        FillRect(IndicatorRect);
      end;
      if Node.Saved then
      begin
        Brush.Color := $003cc215;
        FillRect(IndicatorRect);
      end;
    end;

  end;
end;

procedure TNxInspectorNodeView.PaintPreview;
var
  R: TRect;
begin
  with Canvas do
  begin
    R := PreviewRect;
    Brush.Color := Node.ValueColor;
    FrameRect(R);

    InflateRect(R, -1, -1);
    Brush.Color := ColorOf(seDivider);
    FrameRect(R);

    InflateRect(R, -1, -1);
    PaintPreviewContent(Canvas, R);
  end;
end;

procedure TNxInspectorNodeView.PaintSizeGrip;
begin
  if Node.Resizeable then
  begin
    if RectIntersect(SizeGripRect, NonEditRect) then
    begin
      DrawSizeGrip(Canvas, SizeGripRect, INxInspectorStyle(Style).GetGridColor);
    end;
  end;
end;

procedure TNxInspectorNodeView.PaintSplitter;
begin
  with Canvas do
  begin
    Pen.Color := INxInspectorStyle(Style).SplitterColor;
    Polyline([
      Point(DrawingIndent + SplitterPosition, ClientRect.Top),
      Point(DrawingIndent + SplitterPosition, ClientRect.Bottom)
    ]);
  end;
end;

procedure TNxInspectorNodeView.PaintToggle;
begin
  case ToggleStyle of
    tsStyleNative, tsGlyph: INxInspectorStyle(Style).DrawToggle(ToggleRect, not Node.Expanded);
    tsSquare: PaintSquareToggle(Canvas, ToggleRect, Node.Expanded);
    tsTriangle: PaintTriangleToggle(Canvas, ToggleRect, Node.Expanded, []);
  end;
end;

procedure TNxInspectorNodeView.PaintValue;
begin
  with Canvas do
  begin
    Brush.Color := Node.ValueColor;

    if Node.IsTopLevel and UseTopLevelColor then
    begin
      Brush.Color := INxInspectorStyle(Style).GetTopLevelColor;
    end else
    begin
      Brush.Color := INxInspectorStyle(Style).GetBackgroundColor(Node.ValueColor);
    end;

    { Fill Area not occupied with InplaceEdit }
    FillRect(NonEditRect);
  end;

  if not Node.IsEmpty
    or not Node.HideEmpty then
  begin
    { Is there enough Space (?) }
    if (ContentHeight > 0) and (ContentWidth > 0) then
    begin
      { Paint node-specific content }
      PaintValueContent(ContentRect);
    end;
  end
  else PaintEmptyValue(ContentRect);

end;

procedure TNxInspectorNodeView.PaintValueContent(ContentRect: TRect);
begin
  with Canvas do
  begin
    { Init Item's properties
      into View (Font etc.) }
    AssignNode;

    if not (isEditing in NodeState) then
    begin
      Font.Color := INxInspectorStyle(Style).GetTextColor(FNode, False, False);

      { Draw Text }
      DrawTextRect(Canvas, Self.TextRect, Node.Alignment, taVerticalCenter, Node.DisplayText, wkEllipsis);
    end;

  end;
end;

function TNxInspectorNodeView.PreferedSize(Entities: TNxInspectorNodeEntity): TSize;
begin
  Result.cx := 0;
  Result.cy := 0;
  if etCaption in Entities then
  begin
    case Node.CaptionTextRender of
      trPlainText:
      begin
        Result.cy := Max(Result.cy, GetTextHeight(Canvas, ContentWidth, Node.Caption));
        Result.cx := GetCaptionPrefferedWidth;
      end;
      trHtml:
      begin

      end;
    end;
  end;
  if etValue in Entities then
  begin
    AssignNode;
    Result.cy := Max(Result.cy, GetTextHeight(Canvas, ContentWidth, Node.DisplayText));
  end;
end;

procedure TNxInspectorNodeView.Refresh(InvalidationRect: TRect);
begin
  if Assigned(Control) then InvalidateRect(Control.Handle, @InvalidationRect, False);
end;

procedure TNxInspectorNodeView.RefreshDetailsButton;
begin
  Refresh(DetailsButtonRect);
end;

procedure TNxInspectorNodeView.Refresh;
begin
  if Node.ShowPreview then Refresh(PreviewRect);
  Refresh(ContentRect);
end;

procedure TNxInspectorNodeView.SetAsString(const Value: WideString);
begin

end;

procedure TNxInspectorNodeView.SetCanvas(const Value: TCanvas);
begin
  FCanvas := Value;
end;

procedure TNxInspectorNodeView.SetClientRect(const Value: TRect);
begin
  FClientRect := Value;
end;

procedure TNxInspectorNodeView.SetControl(const Value: TWinControl);
begin
  FControl := Value;
end;

procedure TNxInspectorNodeView.SetDetailsButtonState(const Value: TNxButtonState);
begin
  FDetailsButtonState := Value;
end;

procedure TNxInspectorNodeView.SetDroppedDown(const Value: Boolean);
begin
  ShowWindow(FPreviewPopupControl.Handle, SW_HIDE);
end;

procedure TNxInspectorNodeView.SetFont(const Value: TFont);
begin

end;

procedure TNxInspectorNodeView.SetImagePosition(const Value: TNxNodeIconPosition);
begin
  FImagePosition := Value;
end;

procedure TNxInspectorNodeView.SetImages(const Value: TCustomImageList);
begin
  FImages := Value;
end;

procedure TNxInspectorNodeView.SetNodeState(const Value: TNxInspectorNodeState);
begin
  FNodeState := Value;
end;

procedure TNxInspectorNodeView.SetMarginColor(const Value: TColor);
begin
  FMarginColor := Value;
end;

procedure TNxInspectorNodeView.SetMarginWidth(const Value: Integer);
begin
  FMarginWidth := Value;
end;

procedure TNxInspectorNodeView.SetOnChange(const Value: TNxNodeViewNotifyEvent);
begin
  FOnChange := Value;
end;

procedure TNxInspectorNodeView.SetOptions(const Value: TNxInspectorNodeViewOptions);
begin
  FOptions := Value;
end;

procedure TNxInspectorNodeView.SetOwner(const Value: INxViewComponent);
begin
  FOwner := Value;
end;

procedure TNxInspectorNodeView.SetPreviewPopup(const Value: Boolean);
begin
  FPreviewPopup := Value;
end;

procedure TNxInspectorNodeView.SetSelected(const Value: Boolean);
begin
  FSelected := Value;
end;

procedure TNxInspectorNodeView.SetShowMargin(const Value: Boolean);
begin
  FShowMargin := Value;
end;

procedure TNxInspectorNodeView.SetSplitterPosition(const Value: Integer);
begin
  FSplitterPosition := Value;
end;

procedure TNxInspectorNodeView.SetStyle(const Value: INxControlStyle);
begin
  FStyle := Value;
end;

procedure TNxInspectorNodeView.SetToggleStyle(const Value: TNxToggleButtonStyle);
begin
  FToogleStyle := Value;
end;

procedure TNxInspectorNodeView.SetUseTopLevelColor(const Value: Boolean);
begin
  FUseTopLevelColor := Value;
end;

function TNxInspectorNodeView.ToObject: TObject;
begin
  Result := Self;
end;

{ TNxInspectorItem }

procedure TNxInspectorNode6.AddChild;
begin
  Inc(FCount);
  Inc(FShowingCount);
end;

procedure TNxInspectorNode6.Assign(Source: TPersistent);
begin
  if Source is TNxInspectorNode6 then
  begin
    Alignment := TNxInspectorNode6(Source).Alignment;
    AllowEmpty := TNxInspectorNode6(Source).AllowEmpty;
    AutoAssign := TNxInspectorNode6(Source).AutoAssign;
    AutoSelect := TNxInspectorNode6(Source).AutoSelect;
    AutoSize := TNxInspectorNode6(Source).AutoSize;
    BindProperty := TNxInspectorNode6(Source).BindProperty;
    Caption := TNxInspectorNode6(Source).Caption;
    CaptionColor := TNxInspectorNode6(Source).CaptionColor;
    CaptionDrawingOptions := TNxInspectorNode6(Source).CaptionDrawingOptions;
    CaptionFont.Assign(TNxInspectorNode6(Source).CaptionFont);
    CaptionWrapKind := TNxInspectorNode6(Source).CaptionWrapKind;
    EmptyValue := TNxInspectorNode6(Source).EmptyValue;
    Enabled := TNxInspectorNode6(Source).Enabled;
    Expanded := TNxInspectorNode6(Source).Expanded;
    ExpandLock := TNxInspectorNode6(Source).ExpandLock;
    HideEmpty := TNxInspectorNode6(Source).HideEmpty;
    Hint := TNxInspectorNode6(Source).Hint;
    ImageIndex := TNxInspectorNode6(Source).ImageIndex;
    ImagePlaceholder := TNxInspectorNode6(Source).ImagePlaceholder;
    InplaceEdit := TNxInspectorNode6(Source).InplaceEdit;
    MinHeight := TNxInspectorNode6(Source).MinHeight;
    NodeHeight := TNxInspectorNode6(Source).NodeHeight;
    Options := TNxInspectorNode6(Source).Options;
    Pinned := TNxInspectorNode6(Source).Pinned;
    Padding.Assign(TNxInspectorNode6(Source).Padding);
    ParentCaptionFont := TNxInspectorNode6(Source).ParentCaptionFont;
    ParentValueFont := TNxInspectorNode6(Source).ParentValueFont;
    ReadOnly := TNxInspectorNode6(Source).ReadOnly;
    Resizeable := TNxInspectorNode6(Source).Resizeable;
    ShowPreview := TNxInspectorNode6(Source).ShowPreview;
    StylesSheet := TNxInspectorNode6(Source).StylesSheet;
    Value := TNxInspectorNode6(Source).Value;
    ValueColor := TNxInspectorNode6(Source).ValueColor;
    ValueFont.Assign(TNxInspectorNode6(Source).ValueFont);
    Visible := TNxInspectorNode6(Source).Visible;
    VisibleCells := TNxInspectorNode6(Source).VisibleCells;
    WantKeys := TNxInspectorNode6(Source).WantKeys;
  end else inherited;
end;

procedure TNxInspectorNode6.AssignEdit(Edit: INxInplaceEdit);
begin
  Edit.Alignment := Alignment;
  Edit.AutoSelect := AutoSelect;
  Edit.EditOptions := EditOptions;
  Edit.Font := ValueFont;
  Edit.ReadOnly := ReadOnly;
end;

procedure TNxInspectorNode6.AssignProperty(TypeKind: TTypeKind);
begin

end;

procedure TNxInspectorNode6.AssignValue(Source: INxBase);
begin

end;

function TNxInspectorNode6.BeginEdit: INxInplaceEdit;
begin
  if CanEdit
    then Result := TNxCustomEdit6.Create(Self)
    else Result := nil;
end;

procedure TNxInspectorNode6.BestFit(Entities: TNxInspectorNodeEntity = [etCaption, etValue]);
var
  NewHeight: Integer;
begin
  if View.Canvas = nil then Exit;

  NewHeight := View.PreferedSize(Entities).cy;

  { Add Vertical Padding }
  Inc(NewHeight, Padding.Top + Padding.Bottom);

  NodeHeight := NewHeight;
end;

function TNxInspectorNode6.CanEdit: Boolean;
begin
  Result := Enabled and (icValue in VisibleCells);
end;

function TNxInspectorNode6.CanInteract: Boolean;
begin
  Result := Enabled and not ReadOnly;
end;

procedure TNxInspectorNode6.Changed;
begin
  if AutoSize then BestFit;
end;

///<summary>
///Change value, without checking if value is equal as old.
///<param>
///</param>
///</summary>
procedure TNxInspectorNode6.ChangeValue(const Value: WideString);
begin
  { Assign }
  FValue := Value;

  Changed; { BestFit & etc. }

  { Notify Nodes & Inspector }
  if Assigned(Nodes) then Nodes.DoNodeChanged(Self);

  if not (csLoading in ComponentState) then
  begin
    SetModified(True);

    { Trigger Event }
    DoValueChanged;

    View.Changed;
    View.Refresh;
  end;
end;

function TNxInspectorNode6.ChildsValue(Separator: Char): WideString;
var
  i: Integer;
begin
  for i := 0 to Pred(ChildCount) do
  begin
    Result := Result + Node[i].Value;

    if i < Pred(ChildCount) then
      Result := Result + Separator;
  end;
end;

procedure TNxInspectorNode6.ClearChildren;
var
  i: Integer;
begin
  i := Succ(AbsoluteIndex);
  while i < Count do
  begin
    if Nodes[i].HasChildren then Nodes[i].ClearChildren;
    Nodes[i].Free;
  end;
end;

procedure TNxInspectorNode6.ClearState;
begin
  SetModified(False);
  SetSaved(False);
end;

constructor TNxInspectorNode6.Create(AOwner: TComponent);
begin
  inherited;
  FAlignment := taLeftJustify;
  FAllowEmpty := True;
  FAutoAssign := False;
  FAutoSelect := True;
  FAutoSize := False;
  FCaptionColor := clWindow;
  FCaptionDrawingOptions := [doBackground, doContent];
  FCaptionFont := TFont.Create;
  FCaptionFont.OnChange := DoCaptionFontChange;
  FCaptionTextRender := trPlainText;
  FCaptionWrapKind := wkNone;
  FCount := 0;
  FEditOptions := [edPaste, edTyping];
  FEnabled := True;
  FExpanded := True;
  FExpandLock := False;
  FHideEmpty := False;
  FHint := '';
  FImageIndex := -1;
  FImagePlaceholder := True;
  FNodeHeight := 0;
  FMinHeight := szMinNodeHeight;
  FModified := False;
  FOptions := [];
  FPadding := TPadding.Create(nil);
  FPadding.SetBounds(2, 0, 2, 0);
  FPadding.OnChange := DoPaddingChange;
  FParentCaptionFont := True;
  FParentNode := nil;
  FParentValueFont := True;
  FReadOnly := False;
  FResizeable := False;
  FState := [];
  FShowingCount := 0;
  FShowPreview := False;
  FStylesSheet := nil;
  FCaptionTextFitHint := '';
  FValueColor := clWindow;
  FValueFont := TFont.Create;
  FValueFont.OnChange := DoValueFontChange;
  FView := GetViewClass.Create(Self);
  FVisible := True;
  FVisibleCells := [icCaption, icValue];
  FWantKeys := [];
end;

destructor TNxInspectorNode6.Destroy;
begin
  { Delete itself in Nodes }
  Nodes.Delete(AbsoluteIndex);

  FreeAndNil(FCaptionFont);
  FreeAndNil(FPadding);
  FreeAndNil(FValueFont);

  FInplaceEdit := nil;
  FView := nil;

  inherited;
end;

procedure TNxInspectorNode6.DoCaptionFontChange(Sender: TObject);
begin
  if not (csLoading in ComponentState) then
  begin
    ParentCaptionFont := False;
    Refresh;
  end;
end;

procedure TNxInspectorNode6.DoCollapsed;
begin
  if Assigned(FOnCollapsed) then FOnCollapsed(Self);
end;

procedure TNxInspectorNode6.DoCustomDrawCaption(DrawingRect: TRect; Selected: Boolean);
begin
  if Assigned(FOnCustomDrawCaption) then FOnCustomDrawCaption(Self, DrawingRect, Selected);
end;

procedure TNxInspectorNode6.DoDetailsClick;
begin
  if Assigned(FOnDetailsClick) then FOnDetailsClick(Self);
end;

procedure TNxInspectorNode6.DoExpanded;
begin
  if Assigned(FOnExpanded) then FOnExpanded(Self);
end;

procedure TNxInspectorNode6.DoGetValue(var Value: WideString);
begin
  if Assigned(FOnGetValue) then FOnGetValue(Self, Value);
end;

procedure TNxInspectorNode6.DoPaddingChange(Sender: TObject);
begin
  Changed;
end;

procedure TNxInspectorNode6.DoValueChanged;
begin
  if Assigned(FOnValueChanged) then FOnValueChanged(Self);
end;

procedure TNxInspectorNode6.DoValueFontChange(Sender: TObject);
begin
  { ToDo: Notify }
end;

function TNxInspectorNode6.EditWidth: Integer;
begin
  Result := 0;
end;

function TNxInspectorNode6.GetAbsoluteIndex: Integer;
begin
  Result := -1;
  if Assigned(FNodes) then Result := FNodes.FList.IndexOf(Self);
end;

function TNxInspectorNode6.GetActualHeight: Integer;
var
  Ref: INxFullSizeItem;
begin
  { Default Size }
  Result := FNodeHeight;

  { FullSize }
  if Supports(View, INxFullSizeItem, Ref) then
    if Ref.FullSize then Result := Ref.FullSizeHeight; { Calc. FullSize }
end;

function TNxInspectorNode6.GetAsBoolean: Boolean;
begin
  Result := StrToBool(FValue);
end;

function TNxInspectorNode6.GetAsDateTime: TDateTime;
begin
  Result := StrToDateTimeDef(FValue, Now);
end;

function TNxInspectorNode6.GetAsFloat: Double;
begin
  Result := StrToFloatDef(FValue, 0);
end;

function TNxInspectorNode6.GetAsInteger: Integer;
begin
  try
    Result := StrToInt(FValue);
  except
    Result := 0;
  end;
end;

function TNxInspectorNode6.GetAsString: WideString;
begin
  Result := FValue;
  DoGetValue(Result);
end;

function TNxInspectorNode6.GetAsUTF8String: UTF8String;
begin
  Result := UTF8String(AsString);
end;

function TNxInspectorNode6.GetChildByCaption(Caption: WideString): TNxInspectorNode6;
var
  i: Integer;
begin
  Result := nil;
  for i := Succ(AbsoluteIndex) to Pred(Nodes.Count) do
    if Nodes[i].Level > Level then
      if (Nodes[i].ParentNode = Self)
        and (CompareStr(Caption, Nodes[i].Caption) = CompareEqual) then
        begin
          Result := Nodes[i];
          Exit;
        end;
end;

function TNxInspectorNode6.GetChildCount: Integer;
var
  i: Integer;
begin
  Result := 0;
  i := Succ(AbsoluteIndex);;
  while (i < Nodes.Count) and (Nodes[i].Level > Level) do
  begin
    Inc(Result);
    Inc(i);
  end;
end;

procedure TNxInspectorNode6.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
  i: Integer;
begin
  for i := 0 to Pred(Count) do
    Proc(Node[i]);
end;

function TNxInspectorNode6.GetDisplayText: WideString;
begin
  Result := AsString;
end;

function TNxInspectorNode6.GetFiltered: Boolean;
begin
  Result := (Nodes.FilterText <> EmptyStr) and (Pos(UpperCase(Nodes.FilterText), UpperCase(Caption)) = 0);
end;

function TNxInspectorNode6.GetFirstSibling: TNxInspectorNode6;
var
  i: Integer;
begin
  Result := Self;
  i := AbsoluteIndex;
  while (i > 0) and (FNodes[i].Level >= Level) do
  begin
    if FNodes[i].Level = Level then Result := FNodes[i];
    Dec(i);
  end;
end;

function TNxInspectorNode6.GetHasChildren: Boolean;
begin
  Result := FCount > 0;
end;

function TNxInspectorNode6.GetHidden: Boolean;
begin
  Result := IsTopLevel and Nodes.HideTopLevel and Visible;
end;

function TNxInspectorNode6.GetIndent: Integer;
begin
  if not Pinned then { Pinned is 0 }
  begin
    Result := Level;
    if not IsTopLevel then Dec(Result);
  end
  else Result := 0;
end;

function TNxInspectorNode6.GetIndex: Integer;
begin
  Result := Nodes.IndexOf(Self);
end;

function TNxInspectorNode6.GetIsNull: Boolean;
begin
  Result := False;
end;

function TNxInspectorNode6.GetIsTopLevel: Boolean;
begin
  Result := Level = 0;
end;

function TNxInspectorNode6.GetNode(Index: Integer): TNxInspectorNode6;
var
  i, c: Integer;
begin
  c := 0;
  i := Succ(AbsoluteIndex);
  while (Nodes[i].Level > Level) and (i < Nodes.Count) do
  begin
    if Nodes[i].ParentNode = Self then
    begin
      if c = Index then
      begin
        Result := Nodes[i];
        Exit;
      end;
      Inc(c);
    end;
    inc(i);
  end;
  Result := nil;
end;

function TNxInspectorNode6.GetNodes: TNxInspectorNodes;
begin
  Result := FNodes;
end;

function TNxInspectorNode6.GetNodeStyle: TNxInspectorNodeStyle;
begin
  Result := [];
end;

function TNxInspectorNode6.GetLastSibling: TNxInspectorNode6;
var
  i: Integer;
begin
  Result := Self;
  i := Succ(AbsoluteIndex);
  while (i < FNodes.Count) and (FNodes[i].Level >= Level) do
  begin
    if FNodes[i].Level = Level then Result := FNodes[i];
    Inc(i);
  end;
end;

function TNxInspectorNode6.GetLevel: Integer;
begin
  Result := 0;
  { ParentNode is set? }
  if Assigned(ParentNode) then Result := Succ(ParentNode.Level);
end;

function TNxInspectorNode6.GetName: TComponentName;
begin
  Result := Name;
end;

function TNxInspectorNode6.GetNextSibling: TNxInspectorNode6;
var
  i: Integer;
begin
  Result := nil;
  for i := Succ(AbsoluteIndex) to Pred(FNodes.Count) do
    if FNodes[i].Level = Level then
    begin
      Result := FNodes[i];
      Break;
    end;
end;

function TNxInspectorNode6.GetPinnedIndex: Integer;
begin
  if Assigned(Nodes) then Result := Nodes.FPinned.IndexOf(Self) else Result := -1;
end;

function TNxInspectorNode6.GetPinnedShown: Boolean;
begin
  Result := Pinned and Visible;
end;

function TNxInspectorNode6.GetPreviewText: WideString;
begin
  Result := EmptyStr;
end;

function TNxInspectorNode6.GetPrevSibling: TNxInspectorNode6;
var
  i: Integer;
begin
  Result := nil;
  for i := Pred(AbsoluteIndex) downto 0 do
    if FNodes[i].Level = Level then
    begin
      Result := FNodes[i];
      Break;
    end;
end;

function TNxInspectorNode6.GetParentComponent: TComponent;
begin
  if FParentNode = nil then Result := FNodes.Owner
    else Result := FParentNode;
end;

function TNxInspectorNode6.GetPinned: Boolean;
begin
  Result := not (PinnedIndex = NotFound);
end;

function TNxInspectorNode6.GetShowing: Boolean;
begin
  { Base }
  Result := Visible and not Pinned;

  if Assigned(ParentNode) { Parent }
  then
    Result := Result and (ParentNode.Showing or ParentNode.Hidden) and ParentNode.Expanded
  else
    Result := Result and not Hidden;

  { Filter }
  Result := Result and not Filtered;
end;

function TNxInspectorNode6.GetValue: WideString;
begin
  Result := AsString;
end;

function TNxInspectorNode6.GetViewClass: TNxInspectorNodeViewClass;
begin
  Result := TNxInspectorNodeView;
end;

function TNxInspectorNode6.HasParent: Boolean;
begin
  Result := True;
end;

function TNxInspectorNode6.IsDestroying: Boolean;
begin
  Result := csDestroying in ComponentState;
end;

function TNxInspectorNode6.IsEmpty: Boolean;
begin
  Result := FValue = EmptyStr;
end;

procedure TNxInspectorNode6.MoveTo(Destination: TNxInspectorNode6;
  Mode: TNodeAttachMode);
var
  ToIndex: Integer;
  Sibling: TNxInspectorNode6;
begin
  Sibling := nil;
  ToIndex := -1;

  case Mode of
    naAdd:
    begin
      Sibling := Destination.LastSibling;
      ToIndex := Sibling.AbsoluteIndex + Sibling.ChildCount;
    end;
    naAddFirst:
    begin
      Sibling := Destination.FirstSibling;
      ToIndex := Sibling.AbsoluteIndex;
    end;
    naInsert:
    begin
      ToIndex := Destination.AbsoluteIndex;

      if ToIndex > AbsoluteIndex
        then Dec(ToIndex)
    end;
    naAddChild:
    begin
      ToIndex := Destination.AbsoluteIndex + Destination.ChildCount;

      if ToIndex < AbsoluteIndex then
        Inc(ToIndex);
    end;
    naAddChildFirst:
    begin
      ToIndex := Destination.AbsoluteIndex;

      if ToIndex < AbsoluteIndex then
        Inc(ToIndex);
    end;
  end;

  { Move Node }
  if ToIndex <> -1 then
  begin
    FNodes.MoveNode(FNodes.FList, Self, AbsoluteIndex, ToIndex);
  end;

  { ParentNode, Level & Count }
  case Mode of
    naAdd, naAddFirst:
    begin
      if Assigned(FParentNode) then Dec(FParentNode.FCount);
      if Assigned(Sibling) and Assigned(Sibling.ParentNode)
        then Inc(Sibling.ParentNode.FCount);

      FParentNode := Destination.ParentNode;

    end;
    naInsert:
    begin
      FParentNode := Destination.FParentNode;
    end;
    naAddChild, naAddChildFirst:
    begin
      if Assigned(FParentNode) then Dec(FParentNode.FCount);
      FParentNode := Destination;
      Inc(Destination.FCount);
    end;
  end;

  Notify(ntToggle);
end;

procedure TNxInspectorNode6.MoveToTopLevel;
begin
  if not IsTopLevel then MoveTo(FNodes[0], naAdd);
end;

procedure TNxInspectorNode6.Notification(AComponent: TComponent; Operation: TOperation);
var
  Intf: IInterfaceComponentReference;
begin
  inherited;
  if (Operation = opRemove) and (AComponent = FStylesSheet) then FStylesSheet := nil;
  if Operation = opRemove then
  begin
    if Supports(FInplaceEdit, IInterfaceComponentReference, Intf) then
    begin
      if Intf.GetComponent = AComponent then FInplaceEdit := nil;
    end;
  end;
end;

procedure TNxInspectorNode6.Notify(Kind: TNxNodeNotificationKind);
begin
  if Assigned(Nodes) then
  begin
//    if Shown then
//      case Kind of
//        nkToggle:
//          if Expanded
//            then FItems.UpdateShownCount(FItems.FShownCount + FShownCount)
//            else FItems.UpdateShownCount(FItems.FShownCount - FShownCount);
//      end;

    { Notify all INxNodeNotifyControls attached }
    Nodes.Notify(Self, Kind);
  end;
end;

procedure TNxInspectorNode6.Pin;
begin
  if not Pinned and Assigned(Nodes) then
  begin
    if Showing then
    begin
      Nodes.UpdateShowingCount(Nodes.FShowingCount - 1);
      Nodes.DoNodesChanged(Self, ncPin, 0, 0);
    end;
    Nodes.FPinned.Add(Self);
  end;
end;

procedure TNxInspectorNode6.Refresh;
begin
  if not (csLoading in ComponentState) then FView.Refresh;
end;

procedure TNxInspectorNode6.RefreshCaption;
begin
  Notify(ntCaptionChanged);
end;

procedure TNxInspectorNode6.RefreshValue;
begin
  if not (csLoading in ComponentState) then FView.Invalidate(True);
end;

procedure TNxInspectorNode6.Remove;
begin
  if Assigned(Nodes) then
  begin
    Nodes.Delete(AbsoluteIndex);
  end;
end;

procedure TNxInspectorNode6.RemoveChild;
begin
  if HasChildren then Dec(FCount);
end;

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

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

procedure TNxInspectorNode6.SetAsDateTime(const Value: TDateTime);
begin
  Self.Value := DateTimeToStr(Value);
end;

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

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

procedure TNxInspectorNode6.SetAsString(const Value: WideString);
begin
  if (Value <> FValue)
    or (itExplicitChange in NodeStyle) then
  begin
    ChangeValue(Value);
  end;
end;

procedure TNxInspectorNode6.SetAsUTF8String(const Value: UTF8String);
begin
  AsString := WideString(value);
end;

procedure TNxInspectorNode6.SetAutoAssign(const Value: Boolean);
begin
  FAutoAssign := Value;
end;

procedure TNxInspectorNode6.SetAutoSelect(const Value: Boolean);
begin
  FAutoSelect := Value;
end;

procedure TNxInspectorNode6.SetAutoSize(const Value: Boolean);
begin
  if Value <> FAutoSize then
  begin
    FAutoSize := Value;
    Changed; { BestFit }
  end;
end;

procedure TNxInspectorNode6.SetBindProperty(const Value: string);
var
  Ref: INxBase;
begin
  FBindProperty := Value;

  { Acquire Value }
  if Assigned(Nodes) then
  begin
    if Supports(Self, INxBase, Ref) then
      try
        { Prevent calling SetProp }
        State := State + [ntPropertyReading];

        FNodes.FControl.Associates.GetPropValue(FBindProperty, Ref);
      finally
        State := State - [ntPropertyReading];
      end;
  end;
end;

procedure TNxInspectorNode6.SetCaption(const Value: WideString);
begin
  if Value <> FCaption then
  begin
    FCaption := Value;
    Notify(ntCaptionChanged);
  end;
end;

procedure TNxInspectorNode6.SetCaptionColor(const Value: TColor);
begin
  if Value <> FCaptionColor then
  begin
    FCaptionColor := Value;
    Notify(ntCaptionChanged);
  end;
end;

procedure TNxInspectorNode6.SetCaptionDrawingOptions(const Value: TNxDrawingOptions);
begin
  FCaptionDrawingOptions := Value;
  { ToDo: Notify }
end;

procedure TNxInspectorNode6.SetCaptionFont(const Value: TFont);
begin
  FCaptionFont.OnChange := nil;
  FCaptionFont.Assign(Value);
  FCaptionFont.OnChange := DoCaptionFontChange;
  Refresh;
end;

procedure TNxInspectorNode6.SetCaptionTextRender(const Value: TNxTextRender);
begin
  if Value <> FCaptionTextRender then
  begin
    FCaptionTextRender := Value;
    Refresh;
  end;
end;

procedure TNxInspectorNode6.SetCaptionWrapKind(const Value: TNxWrapKind);
begin
  if Value <> FCaptionWrapKind then
  begin
    FCaptionWrapKind := Value;
    Refresh;
  end;
end;

procedure TNxInspectorNode6.SetDefaultValue(const Value: WideString);
begin
  FDefaultValue := Value;
end;

procedure TNxInspectorNode6.SetEditOptions(const Value: TNxInspectorNodeEditOptions);
begin
  FEditOptions := Value;
end;

procedure TNxInspectorNode6.SetEmptyValue(const Value: WideString);
begin
  if Value <> FEmptyValue then
  begin
    FEmptyValue := Value;
    Refresh;
  end;
end;

procedure TNxInspectorNode6.SetEnabled(const Value: Boolean);
begin
  if Value <> FEnabled then
  begin
    FEnabled := Value;
    Refresh;
  end;
end;

procedure TNxInspectorNode6.SetExpanded(const Value: Boolean);
begin
  if Value <> FExpanded then
  begin
    if not Value then FShowingCount := FNodes.GetNodeShowingCount(Self);

    FExpanded := Value;

    if Value then FShowingCount := FNodes.GetNodeShowingCount(Self);

    { Trigger Event }
    if FExpanded then
    begin
      if Showing then
      begin
        FNodes.UpdateShowingCount(FNodes.FShowingCount + FShowingCount);
        Notify(ntExpanded);
      end;

      DoExpanded;

    end else
    begin
      if Showing then
      begin
        FNodes.UpdateShowingCount(FNodes.FShowingCount - FShowingCount);

        Notify(ntCollapsed);
      end;

      DoCollapsed;
    end;

    Notify(ntToggle);
  end;
end;

procedure TNxInspectorNode6.SetExpandLock(const Value: Boolean);
begin
  if Value <> FExpandLock then
  begin
    FExpandLock := Value;
    RefreshCaption;
  end;
end;

procedure TNxInspectorNode6.SetHideEmpty(const Value: Boolean);
begin
  if Value <> FHideEmpty then
  begin
    FHideEmpty := Value;
    Refresh;
  end;
end;

procedure TNxInspectorNode6.SetImageIndex(const Value: TImageIndex);
begin
  if Value <> FImageIndex then
  begin
    FImageIndex := Value;
    RefreshCaption;
  end;
end;

procedure TNxInspectorNode6.SetImagePlaceholder(const Value: Boolean);
begin
  if Value <> FImagePlaceholder then
  begin
    FImagePlaceholder := Value;
    RefreshCaption;
  end;
end;

procedure TNxInspectorNode6.SetIndex(const Value: Integer);
begin
//  FParentNode.Nodes

end;

procedure TNxInspectorNode6.SetInplaceEdit(const Value: INxInplaceEdit);
var
  Ref: IInterfaceComponentReference;
begin
  FInplaceEdit := Value;

  { Control can be eventualy destroyed outside, but Node
    destructor will still try to call destructor after
    setting it to nil (because it is interface). }
  if Supports(FInplaceEdit, IInterfaceComponentReference, Ref) then
  begin
    Ref.GetComponent.FreeNotification(Self);
  end;
end;

procedure TNxInspectorNode6.SetNodeHeight(const Value: Integer);
begin
  FNodeHeight := Value;

  { Can't be smaller than FMinHeight }
  if (FNodeHeight < FMinHeight)
    and (Value <> 0) then FNodeHeight := FMinHeight;

  { ToDo: Do notification }
  Notify(ntResized);
end;

procedure TNxInspectorNode6.SetNodes(const Value: TNxInspectorNodes);
begin
  if Value <> FNodes then
  begin
    if not Assigned(Value) and Assigned(Nodes)
      then Nodes.Delete(Nodes.IndexOf(Self));

    FNodes := Value;
  end;
end;

procedure TNxInspectorNode6.SetMinHeight(const Value: Integer);
begin
  FMinHeight := Value;
end;

procedure TNxInspectorNode6.SetModified(const Value: Boolean);
begin
  if Value <> FModified then
  begin
    FModified := Value;
    if FModified then
    begin
      FSaved := False;
    end;
    View.InvalidateIndicator;
  end;
end;

procedure TNxInspectorNode6.SetOptions(const Value: TNxInspectorNodeOptions);
begin
  FOptions := Value;
end;

procedure TNxInspectorNode6.SetPadding(const Value: TPadding);
begin
  FPadding := Value;
end;

procedure TNxInspectorNode6.SetParentCaptionFont(const Value: Boolean);
begin
  FParentCaptionFont := Value;

  if FParentCaptionFont then
    if Assigned(ParentNode)
    then
      FCaptionFont.Assign(ParentNode.CaptionFont)
    else
      if Assigned(Nodes)
        then FCaptionFont.Assign(Nodes.FControl.Font);
end;

procedure TNxInspectorNode6.SetParentComponent(Value: TComponent);
var
  AParentNode: TNxInspectorNode6;
begin
  AParentNode := nil;

  if Value is TNxInspectorNode6 then
  begin
    AParentNode := Value as TNxInspectorNode6;
    FNodes := TNxInspectorNode6(Value).Nodes;
  end else
  begin
    FNodes := TNextInspector6(Value).Nodes;
  end;

  Nodes.AddNode(AParentNode, Self);
end;

procedure TNxInspectorNode6.SetParentNode(const Value: TNxInspectorNode6);
begin
  { TODO: Call MoveTo here }
  FParentNode := Value;

  ParentCaptionFont := ParentCaptionFont;
  ParentValueFont := ParentValueFont;
end;

procedure TNxInspectorNode6.SetParentValueFont(const Value: Boolean);
begin
  FParentValueFont := Value;

  if FParentValueFont then
    if Assigned(ParentNode)
    then
      FValueFont.Assign(ParentNode.ValueFont)
    else
      if Assigned(Nodes) then FValueFont.Assign(Nodes.FControl.Font);
end;

procedure TNxInspectorNode6.SetPinned(const Value: Boolean);
begin
  if Value <> Pinned then
  begin
    if Value then Pin else Unpin;
  end;
end;

procedure TNxInspectorNode6.SetReadOnly(const Value: Boolean);
begin
  FReadOnly := Value;
end;

procedure TNxInspectorNode6.SetResizeable(const Value: Boolean);
begin
  FResizeable := Value;
end;

procedure TNxInspectorNode6.SetSaved(const Value: Boolean);
begin
  if Value <> FSaved then
  begin
    if Value then
    begin
      if FModified then
      begin
        FModified := False;
        FSaved := Value;
      end;
    end
    else FSaved := Value;

    View.InvalidateIndicator;
  end;
end;

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

procedure TNxInspectorNode6.SetStylesSheet(const Value: TNxStylesSheet6);
begin
  if Value <> FStylesSheet then
  begin
    if Assigned(Value) then Value.FreeNotification(Self)
      else FStylesSheet.RemoveFreeNotification(Self);
    FStylesSheet := Value;
  end;
end;

procedure TNxInspectorNode6.SetValue(const Value: WideString);
begin
  SetAsString(Value);
end;

procedure TNxInspectorNode6.SetValueColor(const Value: TColor);
begin
  if Value <> FValueColor then
  begin
    FValueColor := Value;
    RefreshValue;
  end;
end;

procedure TNxInspectorNode6.SetValueFont(const Value: TFont);
begin
  FValueFont.OnChange := nil;
  FValueFont.Assign(Value);
  FValueFont.OnChange := DoValueFontChange;
end;

procedure TNxInspectorNode6.SetVisible(const Value: Boolean);
begin
  if Value <> FVisible then
  begin
    FVisible := Value;
    Nodes.UpdateShowingCount(Nodes.ShowingCount + IfThen(Value, 1, -1));
    Notify(ntVisibleChanged);
  end;
end;

procedure TNxInspectorNode6.SetVisibleCells(const Value: TNxInspectorNodeCells);
begin
  if Value <> FVisibleCells then
  begin
    FVisibleCells := Value;
    if not (csLoading in ComponentState) then FView.Refresh(FView.ClientRect);
  end;
end;

procedure TNxInspectorNode6.SetWantKeys(const Value: TNxWantKeys);
begin

end;

procedure TNxInspectorNode6.ShowDetails;
begin
  DoDetailsClick; { Trigger Event }
end;

function TNxInspectorNode6.ToObject: TObject;
begin
  Result := Self;
end;

procedure TNxInspectorNode6.Unpin;
begin
  if Pinned and Assigned(Nodes) then Nodes.FPinned.Delete(PinnedIndex);
end;

end.
